《设备树LED模板驱动程序》
1.三种写驱动程序的方法
1.1资源和驱动在同一文件里
1.2资源用platform_device指定,驱动在platform_driver实现
1.3资源用设备树指定,驱动在platform_driver实现
以上三种的核心是file_operations结构体,不同的是指定硬件资源的方式。
2.设备树节点与platform_driver匹配
- 设备树要有compatible属性,它的值是一个字符串。
- platform_driver中要有of_match_table,其中一项的.compatible成员设置为一个字符串。
- 以上2个字符串要一致。
3.设备树节点指定资源,platform_driver获得资源
在设备树节点中添加pin属性:
#define GROUP_PIN(g,p) ((g<<16) | (p)) 100ask_led0 { compatible = “100ask,led”; pin = <GROUP_PIN(5, 3)>; };
驱动程序中,可以从platform_device中得到device_node,再用of_property_read_u32得到属性的值:
struct device_node* np = pdev->dev. of_node; int led_pin; int err = of_property_read_u32(np, “pin”, &led_pin);
4.关键代码
关键代码在 chip_demo_gpio.c,主要看里面的 platform_driver
指定了 of_match_table,它是用来跟设备树节点匹配的,如果设备树节点中有compatile 属性,并且其值等于“100as,leddrv”,就会导致probe 函数被调用。
static const struct of_device_id ask100_leds[] = { { .compatible = "100as,leddrv" }, { }, }; static struct platform_driver chip_demo_gpio_driver = { .probe = chip_demo_gpio_probe, .remove = chip_demo_gpio_remove, .driver = { .name = "100ask_led", .of_match_table = ask100_leds, }, }; static int __init chip_demo_gpio_drv_init(void) { int err; err = platform_driver_register(&chip_demo_gpio_driver); register_led_operations(&board_demo_led_opr); return 0; }