基于dts的platform驱动框架

  1. 基于dts的platform驱动框架

基于dts的platform驱动框架

在模块加载xxxdriver_init()里的platform_driver_register(& xxx_driver)

其中platform_driver_register()传入的是结构体指针 xxx_driver, of_match_table数组用来对设备进行匹配,匹配成功后会自动调用probe函数

static struct platform_driver xxx_driver = { 
     .driver = { 
     .name = "xxx", 
     .of_match_table = xxx_of_match, 
 }, 
     .probe = xxx_probe, 
     .remove = xxx_remove, 
 }; 

xxx_probe()函数里:

    /* 1、设置设备号 */
     if (xxxdev.major) {
        xxxdev.devid = MKDEV(xxxdev.major, 0);
        register_chrdev_region(xxxdev.devid, LEDDEV_CNT,LEDDEV_NAME);
    } else {
        alloc_chrdev_region(&xxxdev.devid, 0, LEDDEV_CNT,LEDDEV_NAME);
        xxxdev.major = MAJOR(xxxdev.devid);}
    /* 2、注册设备 */
    cdev_init(&xxxdev.cdev, &xxx_fops);
    cdev_add(&xxxdev.cdev, xxxdev.devid, LEDDEV_CNT); /* #define LEDDEV_CNT 1 */
     /* 3、创建类 */
     xxxdev.class = class_create(THIS_MODULE, LEDDEV_NAME); /* #define LEDDEV_NAME gpioled */
     /* 4、创建设备 */
     xxxdev.device = device_create(xxxdev.class, NULL, xxxdev.devid,NULL, LEDDEV_NAME); 
     /* 5、初始化 IO */ 
     xxxdev.node = of_find_node_by_path("/gpioled");
     xxxdev.led0 = of_get_named_gpio(xxxdev.node, "led-gpio", 0);
     gpio_request(xxxdev.led0, "led0");
     gpio_direction_output(xxxdev.led0, 1); /*设置为输出,默认高电平 */
示例代码34.2.2.5 platform驱动框架 
/* 设备结构体 */ 
1  struct xxx_dev{ 
     dev_t devid; /* 设备号 */
     struct cdev cdev; /* cdev */
     struct class *class; /* 类 */
     struct device *device; /* 设备 */
     int major; /* 主设备号 */ 
     struct device_node *node; /* LED 设备节点 */
     int led0; /* LED 灯 GPIO 标号 */
     /* 设备结构体其他具体内容 */ 
4  }; 
5 
6  struct xxx_dev xxxdev; /* 定义个设备结构体变量 */ 
7
8  static int xxx_open(struct inode *inode, struct file *filp) 
9  { 
10     /* 函数具体内容 */ 
11     return 0; 
12 } 
13 
14 static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) 
15 { 
16     /* 函数具体内容 */ 
17     return 0; 
18 } 
19 
20 /* 
21 * 字符设备驱动操作集 
22 */ 
23 static struct file_operations xxx_fops = { 
24     .owner = THIS_MODULE, 
25     .open = xxx_open, 
26     .write = xxx_write, 
27 }; 
28 
29 /* 
30 * platform驱动的probe函数 
31 * 驱动与设备匹配成功以后此函数就会执行 
32 */ 
33 static int xxx_probe(struct platform_device *dev) 
34 { 
        printk("led driver and device was matched!\r\n");
         /* 1、设置设备号 */
         if (xxxdev.major) {
             xxxdev.devid = MKDEV(xxxdev.major, 0);
             register_chrdev_region(xxxdev.devid, LEDDEV_CNT,LEDDEV_NAME);
         } else {
             alloc_chrdev_region(&xxxdev.devid, 0, LEDDEV_CNT,LEDDEV_NAME);
             xxxdev.major = MAJOR(xxxdev.devid);}

        /* 2、注册设备 */
         cdev_init(&xxxdev.cdev, &xxx_fops);
        cdev_add(&xxxdev.cdev, xxxdev.devid, LEDDEV_CNT); /* #define LEDDEV_CNT 1 */

         /* 3、创建类 */
         xxxdev.class = class_create(THIS_MODULE, LEDDEV_NAME); /* #define LEDDEV_NAME gpioled */
         if (IS_ERR(xxxdev.class)) {
             return PTR_ERR(xxxdev.class);
         }

         /* 4、创建设备 */
         xxxdev.device = device_create(xxxdev.class, NULL, xxxdev.devid,NULL, LEDDEV_NAME); 
         if (IS_ERR(xxxdev.device)) {
             return PTR_ERR(xxxdev.device);
         }

         /* 5、初始化 IO */ 
         xxxdev.node = of_find_node_by_path("/gpioled");
         if (xxxdev.node == NULL){
             printk("gpioled node nost find!\r\n");
             return -EINVAL;
         }

         xxxdev.led0 = of_get_named_gpio(xxxdev.node, "led-gpio", 0);
         if (xxxdev.led0 < 0) {
             printk("can't get led-gpio\r\n");
             return -EINVAL;
         }

         gpio_request(xxxdev.led0, "led0");
         gpio_direction_output(xxxdev.led0, 1); /*设置为输出,默认高电平 */

         return 0; 
    } 
40 
41 static int xxx_remove(struct platform_device *dev) 
42 { 
43     ...... 
44     cdev_del(&xxxdev.cdev);/* 删除cdev */ 
45     /* 函数具体内容 */ 
46     return 0; 
47 } 
48 
49 /* 匹配列表 */
50 static const struct of_device_id xxx_of_match[] = { 
51     { .compatible = "xxx-gpio" }, 
52     { /* Sentinel */ } 
53 }; 
54 
55 /* 
56 * platform平台驱动结构体 
57 */ 
58 static struct platform_driver xxx_driver = { 
59     .driver = { 
60     .name = "xxx", 
61     .of_match_table = xxx_of_match, 
62 }, 
63     .probe = xxx_probe, 
64     .remove = xxx_remove, 
65 }; 
66 
67 /* 驱动模块加载 */ 
68 static int __init xxxdriver_init(void) 
69 { 
70     return platform_driver_register(&xxx_driver); 
71 } 
72 
73 /* 驱动模块卸载 */ 
74 static void __exit xxxdriver_exit(void) 
75 { 
76     platform_driver_unregister(&xxx_driver); 
77 } 
78 
79 module_init(xxxdriver_init); 
80 module_exit(xxxdriver_exit); 
81 MODULE_LICENSE("GPL"); 
82 MODULE_AUTHOR("zuozhongkai");

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 351134995@qq.com

×

喜欢就点赞,疼爱就打赏