在linux内核里已提供了连接到gpio的led设备驱动,只需要通过platform_device或设备提供相应的硬件资源即可.
使用platform_device方法可参考: http://blog.csdn.net/jklinux/article/details/73850470
内核里的leds-gpio设备驱动配置选项:
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Device Drivers -*- LED Support <*> LED Support for GPIO connected LEDs通过配置选项的帮助信息可以查出对应的设备驱动源文件: drivers/leds/leds-gpio.c
leds-gpio.c源文件里设备树相关的主要内容:
274 static struct platform_driver gpio_led_driver = {275 .probe = gpio_led_probe,276 .shutdown = gpio_led_shutdown,277 .driver = {278 .name = "leds-gpio",279 .of_match_table = of_gpio_leds_match,280 },281 }223 static const struct of_device_id of_gpio_leds_match[] = {224 { .compatible = "gpio-leds", },225 {},226 }227 228 MODULE_DEVICE_TABLE(of, of_gpio_leds_match)这两部分内容可得知,此设备驱动是一个platform_driver的对象,可通过platform_device或设备树里的设备节点来匹配。设备节点里的compatible属性值应是"gpio-leds".
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
匹配上后, 设备驱动里gpio_led_probe函数就会被触发调用. 在probe函数里就会取出设备树里提供的硬件资源.230 static int gpio_led_probe(struct platform_device *pdev)231 {232 struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev); 233 struct gpio_leds_priv *priv;234 int i, ret = 0;235 236 if (pdata && pdata->num_leds) { ... 251 } else {252 priv = gpio_leds_create(pdev); 253 if (IS_ERR(priv))254 return PTR_ERR(priv);255 }
在gpio_leds_create函数里获取设备节点的资源156 static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)157 {158 struct device *dev = &pdev->dev;159 struct fwnode_handle *child;160 struct gpio_leds_priv *priv;161 int count, ret;162 163 count = device_get_child_node_count(dev); 164 if (!count)165 return ERR_PTR(-ENODEV);166 167 priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL);168 if (!priv)169 return ERR_PTR(-ENOMEM);171 device_for_each_child_node(dev, child) { 172 struct gpio_led_data *led_dat = &priv->leds[priv->num_leds];173 struct gpio_led led = {};174 const char *state = NULL;175 struct device_node *np = to_of_node(child);176 177 ret = fwnode_property_read_string(child, "label", &led.name); 178 if (ret && IS_ENABLED(CONFIG_OF) && np)179 led.name = np->name;180 if (!led.name) {181 fwnode_handle_put(child);182 return ERR_PTR(-EINVAL);183 }184 185 led.gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child,186 GPIOD_ASIS,187 led.name);188 if (IS_ERR(led.gpiod)) { 189 fwnode_handle_put(child);190 return ERR_CAST(led.gpiod);191 }192 193 fwnode_property_read_string(child, "linux,default-trigger",194 &led.default_trigger);196 if (!fwnode_property_read_string(child, "default-state",197 &state)) {198 if (!strcmp(state, "keep"))199 led.default_state = LEDS_GPIO_DEFSTATE_KEEP;200 else if (!strcmp(state, "on"))201 led.default_state = LEDS_GPIO_DEFSTATE_ON;202 else203 led.default_state = LEDS_GPIO_DEFSTATE_OFF;204 }205 206 if (fwnode_property_present(child, "retain-state-suspended"))207 led.retain_state_suspended = 1;208 if (fwnode_property_present(child, "panic-indicator"))209 led.panic_indicator = 1;210 211 ret = create_gpio_led(&led, led_dat, dev, NULL);212 if (ret < 0) {213 fwnode_handle_put(child);214 return ERR_PTR(ret);215 }216 led_dat->cdev.dev->of_node = np;217 priv->num_leds++;218 }219 220 return priv;221 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
现板上的STATUS-LED连接到PA17, PWR-LED连接到PL10.
综上所述,关于leds-gpio设备驱动的设备树可:
myleds { compatible = "gpio-leds"; superled0 { label = "led0"; gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>; }; superled1 { label = "led1"; gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; };};
重编设备树并更新后启动系统, 然后就可以查看到myleds设备节点产生platform_device信息:^_^ / # ls /sys/bus/platform/devices/myleds/driver/ leds/ of_node/ subsystem/driver_override modalias power/ uevent^_^ / # ls /sys/bus/platform/devices/myleds/leds/ledled0/ led1/ 控制led:echo 1 > /sys/class/leds/led0/brightness echo 0 > /sys/class/leds/led0/brightness
如无法通过代码分析出设备树里应怎样描述设备,可以参考内核源码里的:Documentation/devicetree/bindings/leds/leds-gpio.txt