基于设备树的led驱动程序

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <asm/io.h>
  7 #include <linux/cdev.h>
  8 #include <linux/device.h>
  9 #include <linux/bitmap.h>
 10 #include <asm/gpio.h>
 11 #include <linux/platform_device.h>
 12 #include <linux/slab.h>
 13 #include <linux/sched.h>
 14 #include <linux/of.h>
 15
 16 static volatile unsigned long *ledcon;
 17 static volatile unsigned long *leddat;
 18 static struct class *led_class;
 19 static unsigned int pin_th;
 20 dev_t led_dev;
 21 struct cdev *cdev;
 22
 23
 24 /* 打开led灯 */
 25 static int led_open(struct inode *inode, struct file *file)
 26 {
 27      *ledcon &= ~(0x3 << (pin_th * 2));
 28      *ledcon |= (0x1 << (pin_th * 2));
 29      *leddat &= ~(1 << pin_th);
 30      return 0;
 31 }
 32
 33 static struct file_operations led_fops = {
 34                .owner = THIS_MODULE,
 35                .open = led_open,
 36 };
 37
 38 static int led_probe(struct platform_device *pdev)
 39 {
 40    int pin_info;
 41    int phy_addr;
 42    int io_base;
 43    of_property_read_s32(pdev->dev.of_node, "pin", &pin_info);
 44    printk("pin_info = 0x%x\n", pin_info);
 45    of_property_read_s32(pdev->dev.of_node, "iobase", &io_base);
 46    printk("io_base = 0x%x\n", io_base);
 47    pin_th = pin_info & (0xffff);
 48    phy_addr = (io_base | ((pin_info>>16)<<4));
 49    ledcon = ioremap(phy_addr, 2);
 50    leddat = ledcon + 1;
 51
 52    if (alloc_chrdev_region(&led_dev, MINOR(led_dev), 1, "led"))
 53           return -1;
 54    cdev = cdev_alloc();
 55    if (!cdev)
 56           return -1;
 57    cdev_init(cdev, &led_fops);
 58    cdev_add(cdev, led_dev, 1);
 59
 60    led_class = class_create(THIS_MODULE, "led");
 61    device_create(led_class,NULL,led_dev,NULL,"led0");   // is /dev/led0
 62
 63    return 0;
 64
 65 }
 66
 67 int led_remove(struct platform_device *pdev)
 68 {
 69     device_destroy(led_class, led_dev);
 70     class_destroy(led_class);
 71     cdev_del(cdev);
 72     unregister_chrdev_region(led_dev, 1);
 73     iounmap(ledcon);
 74     return 0;
 75 }
 76
 77 static struct of_device_id led_id[] = {
 78               {.compatible = "jz2440_led"},
 79               {},
 80 };
 81
 82 static struct platform_driver led_drv = {
 83     .probe = led_probe,
 84     .remove = led_remove,
 85      .driver = {
 86         .name  = "jz2440_led",
 87         .of_match_table = led_id,
 88     },
 89 };
 90
 91 static int led_init(void)
 92 {
 93     platform_driver_register(&led_drv);
 94     return 0;
 95 }
 96
 97 static void led_exit(void)
 98 {
 99      platform_driver_unregister(&led_drv);
100 }
101
102 module_init(led_init);
103 module_exit(led_exit);
104
105 MODULE_LICENSE("GPL");

以上是驱动程序,下面是设备树dts文件:

 1 #define S3C2440_GPA(_nr)    ((0<<16) + (_nr))
 2 #define S3C2440_GPB(_nr)    ((1<<16) + (_nr))
 3 #define S3C2440_GPC(_nr)    ((2<<16) + (_nr))
 4 #define S3C2440_GPD(_nr)    ((3<<16) + (_nr))
 5 #define S3C2440_GPE(_nr)    ((4<<16) + (_nr))
 6 #define S3C2440_GPF(_nr)    ((5<<16) + (_nr))
 7 #define S3C2440_GPG(_nr)    ((6<<16) + (_nr))
 8 #define S3C2440_GPH(_nr)    ((7<<16) + (_nr))
 9 #define S3C2440_GPJ(_nr)    ((8<<16) + (_nr))
10 #define S3C2440_GPK(_nr)    ((9<<16) + (_nr))
11 #define S3C2440_GPL(_nr)    ((10<<16) + (_nr))
12 #define S3C2440_GPM(_nr)    ((11<<16) + (_nr))
13
14 /dts-v1/;
15
16 / {
17     model = "SMDK2440";
18     compatible = "samsung,smdk2440";
19
20     #address-cells = <1>;
21     #size-cells = <1>;
22
23     [email protected]30000000 {
24         device_type = "memory";
25         reg =  <0x30000000 0x4000000>;
26     };
34     chosen {
35         bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
36     };
37
38
39     led {
40         compatible = "jz2440_led";
41         pin = <S3C2440_GPF(5)>;
42         iobase = <0x56000000>;
43     };
44 };

原文地址:https://www.cnblogs.com/zhu-g5may/p/10316990.html

时间: 2024-10-04 16:22:20

基于设备树的led驱动程序的相关文章

基于设备树的TQ2440的中断(1)

作者 姓名:彭东林 E-mail:[email protected] QQ:405728433 平台 板子:TQ2440 内核:Linux-4.9 u-boot: 2015.04 工具链: arm-none-linux-gnueabi-gcc 4.8.3 概述 在博文讓TQ2440也用上設備樹(1)将支持devicetree的Linux4.9移植到了tq2440上面,而在基於tiny4412的Linux內核移植 --- 实例学习中断背后的知识(1)中介绍了最新的Linux下中断的知识,下面我们再

基于设备树的controller学习(1)

作者 彭东林[email protected] 平台 TQ2440Linux-4.10.17 概述 在设备树中我们经常见到诸如"#clock-cells"."#dma-cells"."#reset-cells"."#phy-cells"."#iommu-cells"."#pwm-cells"."#hwlock-cells"."#io-channel-cell

芯灵思Sinlinx A64 linux 通过设备树写LED驱动(附参考代码,未测试)

开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB详细参数 https://m.tb.cn/h.3wMaSKm开发板交流群 641395230 全志A64设备树结构体 #include <linux/of.h> //设备树里的每个设备及每个设备子节点都用此结构体描述 struct device_node { const char *name; const char *type; phandle phandle; const char *full_name; struct p

基于设备树的controller学习(2)

作者 彭东林 [email protected] 平台 TQ2440 Linux-4.10.17 概述 上一篇大概介绍了一下demo-controller的结构,下面结合驱动分析. 正文 正文部分阅读PDF或为知笔记. 完.

基于tiny4412的Linux内核移植 -- 设备树的展开

作者信息 作者: 彭东林 邮箱:[email protected] QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4

Linux设备树(2)——设备树格式和使用

一.设备树dts文件的语法规范 1. DTS文件布局(layout) /dts-v1/; [memory reservations] // 格式为: /memreserve/ <address> <length>; / { [property definitions] [child nodes] }; (1) 特殊的.默认的属性 a. 根节点的: #address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address) #size-cell

Linux设备树语法详解

Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中,这样,如果只是硬件接口信息的变化而没有驱动逻辑的变化,驱动开发者只需要修改设备树文件信息,不需要改写驱动代码.比如在ARM Linux内,一个.dts(device tree source)文件对应一个ARM的machine,一般放置在内核的

Linux设备树语法详解【转】

本文转载自:http://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中,这样,如果只是硬件接口信息的变化而没有驱动逻辑的变化,驱动开发者只需要修改设备树文件信息,不需要改写驱动代码.比如在AR

LED驱动程序 S3C6410

这两天写了个LED驱动程序,网上也看了好多的帖子. 开始思路很清晰了,就是先看电路图,发现LED灯是接在GPM端口上的, 然后看S3C6410数据手册,先向GPMCON口写命令字,让GPM0-5设置为输出,再向GPMDAT口写数据字,在GPM0-5引脚拉低或拉高电平, 从而控制LED的亮灭. 1.电路图 很显然LED灯是接在GPM口引脚下面的 2.数据手册 3.LED驱动程序 #include <linux/module.h> #include <linux/kernel.h> #