platform总线的匹配方式( 四 )


在使用设备树的时候驱动会通过来保存兼容性值,也就是表明此驱动兼容哪些设备 。
1 static const struct of_device_id leds_of_match[] = {2{ .compatible = "atkalpha-gpioled" }, /* 兼容属性 */3{ /* Sentinel */ }4 };5 6 MODULE_DEVICE_TABLE(of, leds_of_match);7 8 static struct platform_driver leds_platform_driver = {9.driver = {10.name = "imx6ul-led",//驱动在节点里面的名字11.of_match_table = leds_of_match,12},13.probe = leds_probe,14.remove = leds_remove,15 };
3.编写驱动
33 #define LEDDEV_CNT 1 /* 设备号长度 */34 #define LEDDEV_NAME "dtsplatled" /* 设备名字 */35 #define LEDOFF 036 #define LEDON 137 38 /* leddev 设备结构体 */39 struct leddev_dev{40 dev_t devid; /* 设备号 */41 struct cdev cdev; /* cdev */42 struct class *class; /* 类 */43 struct device *device; /* 设备 */44 int major; /* 主设备号 */ 45 struct device_node *node; /* LED 设备节点 */46 int led0; /* LED 灯 GPIO 标号 */47 };48 49 struct leddev_dev leddev; /* led 设备 */56 void led0_switch(u8 sta)57 {58 if (sta == LEDON )59 gpio_set_value(leddev.led0, 0);60 else if (sta == LEDOFF)61 gpio_set_value(leddev.led0, 1);62 }71 static int led_open(struct inode *inode, struct file *filp)72 {73 filp->private_data = http://www.kingceram.com/post/&leddev; /* 设置私有数据 */74 return 0;75 }94 printk("kernel write failed!\r\n");95 return -EFAULT;96 }97 98 ledstat = databuf[0];99 if (ledstat == LEDON) {100 led0_switch(LEDON);101 } else if (ledstat == LEDOFF) {102 led0_switch(LEDOFF);103 }104 return 0;105 }106107 /* 设备操作函数 */108 static struct file_operations led_fops = {109 .owner = THIS_MODULE,110 .open = led_open,111 .write = led_write,112 };120 static int led_probe(struct platform_device *dev)121 { 122 printk("led driver and device was matched!\r\n");123 /* 1、设置设备号 */124 if (leddev.major) {125 leddev.devid = MKDEV(leddev.major, 0);126 register_chrdev_region(leddev.devid, LEDDEV_CNT,LEDDEV_NAME);127 } else {128 alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT,LEDDEV_NAME);129 leddev.major = MAJOR(leddev.devid);130 }131132 /* 2、注册设备 */133 cdev_init(&leddev.cdev, &led_fops);134 cdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT);135136 /* 3、创建类 */137 leddev.class = class_create(THIS_MODULE, LEDDEV_NAME);138 if (IS_ERR(leddev.class)) {139 return PTR_ERR(leddev.class);140 }141142 /* 4、创建设备 */143 leddev.device = device_create(leddev.class, NULL, leddev.devid,NULL, LEDDEV_NAME);144 if (IS_ERR(leddev.device)) {145 return PTR_ERR(leddev.device);146 }147148 /* 5、初始化 IO */ 149 leddev.node = of_find_node_by_path("/gpioled");150 if (leddev.node == NULL){151 printk("gpioled node nost find!\r\n");152 return -EINVAL;153 }154 155 leddev.led0 = of_get_named_gpio(leddev.node, "led-gpio", 0);156 if (leddev.led0 < 0) {157 printk("can't get led-gpio\r\n");158 return -EINVAL;159 }160161 gpio_request(leddev.led0, "led0");162 gpio_direction_output(leddev.led0, 1); /*设置为输出,默认高电平 */163 return 0;164 }171 static int led_remove(struct platform_device *dev)172 {173 gpio_set_value(leddev.led0, 1); /* 卸载驱动的时候关闭 LED */174175 cdev_del(&leddev.cdev); /* 删除 cdev */176 unregister_chrdev_region(leddev.devid, LEDDEV_CNT);177 device_destroy(leddev.class, leddev.devid);178 class_destroy(leddev.class);179 return 0;180 }183 static const struct of_device_id led_of_match[] = {184 { .compatible = "atkalpha-gpioled" },185 { /* Sentinel */ }186 };189 static struct platform_driver led_driver = {190 .driver = {191 .name = "imx6ul-led", /* 驱动名字,用于和设备匹配 */192 .of_match_table = led_of_match, /* 设备树匹配表 */193 },194 .probe = led_probe,195 .remove = led_remove,196 };203 static int __init leddriver_init(void)204 {205 return platform_driver_register(&led_driver);206 }213 static void __exit leddriver_exit(void)214 {215 platform_driver_unregister(&led_driver);216 }217218 module_init(leddriver_init);
设置( 类型)的 name 字段为“-led”,在/sys/bus///目录下存在名为“-led”这个文件;