IMX6ULL驱动学习--Linux自带LED驱动

Linux自带LED驱动

  • Linux内核LED驱动
    • 内核使能LED驱动
    • LED驱动源码分析
    • 设备树节点编写
      • 设备树LED节点
    • 设备操作

Linux内核LED驱动

Linux 内核集成了LED驱动,采用platform框架,我们只需要在编译内核时选择LED驱动,在设备树文件中添加LED节点即可。

内核使能LED驱动

  • 进入Linux内核文件夹,输入如下命令进入配置菜单:
$ make menuconfig
  • 按照如下路径打开LED驱动配置项:
->Device Drivers
	->LED Support(NEW_LEDS[=y])
		->LED Support for GPIO connected LEDs

按Y使能。保存退出,然后编译内核。

LED驱动源码分析

在上面使能LED驱动后,drivers/leds/leds-gpio.c就会被编译。
leds-gpio.c中有设备匹配表如下:

static const struct of_device_id of_gpio_leds_match[] = {
	{ .compatible = "gpio-leds", },
	{	},
};

......
static struct platform_driver gpio_led_driver = {
	.probe		= gpio_led_probe,
	.remove		= gpio_led_remove,
	.driver		= {
		.name	= "leds-gpio",
		.of_match_table = of_gpio_leds_match,
	},
};
module_platform_driver(gpio_led_driver);
  • 因此设备树中的compatible属性为gpio-leds的节点都会被leds-gpio.c驱动匹配。
  • gpio_led_drivernameleds-gpio,因此在注册驱动之后,/sys/bus/platform/drivers/下会有leds-gpio驱动。
  • 其中module_platform_driver(gpio_led_driver);用于注册驱动。其定义在include/linux/platform_device.h中,如下:
#define module_platform_driver(__platform_driver) \
	module_driver(__platform_driver, platform_driver_register, \
			platform_driver_unregister)

可以看出是一个宏,依赖于module_driver()module_driver()定义在include/linux/device.h中,如下:

#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
	return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
	__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);

由此可知,将module_platform_driver(gpio_led_driver);展开后为:

static int __init gpio_led_driver_init(void)
{
	return platform_driver_register (&(gpio_led_driver));
}
module_init(gpio_led_driver_init);
static void __exit gpio_led_driver_exit(void)
{
	platform_driver_unregister (&(gpio_led_driver) );
}
module_exit(gpio_led_driver_exit);

即为platform驱动的注册和删除。

设备树节点编写

  • 创建dtsleds 节点表示LED设备,节点中可以有多个led子节点
  • dtsleds 节点的compatible必须是gpio-leds
  • 设置label属性,这个将设置为led的名字
  • 每个子节点必须设置gpios属性,表明其GPIO引脚
  • linux,default-trigger属性为LED默认功能配置,可选项有:
	backlight	:	LED作为背光 
	default-on	:	LED灯默认打开
	default-off	:	LED灯默认关闭
	heartbeat	:	LED作为心跳灯,作为系统运行提示灯
	ide-disk	:	LED作硬盘活动指示灯
	timer	:	LED周期性闪烁,由定时器驱动,闪烁频率可以修改。
  • default-state设置默认状态,可选项有: on off keep

设备树LED节点

添加dtsled节点如下:

	dtsleds {
		compatible = "gpio-leds";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_light>;

		led_red {
			label = "red";
			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
			default-state = "on";
			linux,default-trigger = "timer";
		};
	};

编译设备树,重启。

设备操作

  • 修改完设备树之后,在/sys/devices/platform/下存在dtsles设备节点,即设备树节点添加成功。
  • 进入/sys/class/leds目录中,发现有red节点,即led驱动匹配成功,通过如下指令即可调整led状态:
echo 1 > /sys/class/leds/red/brightness //打开 LED0
echo 0 > /sys/class/leds/red/brightness //关闭 LED0

你可能感兴趣的:(IMX6ULL驱动学习--Linux自带LED驱动)