一、按键灯的简介
最近调试一下按键灯,今天抽空顺便把的流程分析了一下。按键灯也是一种led,它的使用规则如命名一样,当按键按
下亮灯,如果一定时间不操作的话,一会会灭灯。其实这里的按键灯亮灭策略通常不是驱动来完成的,而是有用户空间来
控制。正如一句老话“驱动注重的不是策略,而是机制”;所以我们在编写驱动只需要完成led的点亮和熄灭功能即可。当
然在实际使用中我们会发现不是所有驱动都如此,有时候平台中也会添加一定的策略,这个本章不作分析。 调试按键灯,
当然首先从硬件开始。按键灯的原理图如下:
从原理图中我们发现,button-backlight是由两路ISINK控制的,ISNIK是一种类似于PWM的控制器,它可以发出类似PWM的信号,可以通过寄存器的配置
调整其占空比等参数,进入调节输出电流,从而控制led的亮度。
二、按键灯的驱动实现
1. 设备和驱动的匹配
//驱动文件中定义platform_driver
file:kernel-3.18/drivers/misc/mediatek/leds/leds_drv.c
//驱动模块的加载
//dts中定义leds 的相关节点如:red,green,blue,keyboard-backlight,button-backlight等(后面会用到)
file:kernel-3.18/arch/arm/boot/dts/rlk6737m_35g_c_m0.dts
//dts中定义和platform_device相关的节点信息
上述dts中定义按键灯leds节点配置,内核起来后会解析dts生成相关的设备,并与驱动中的driver匹配,如果匹配成功就执行下面的probe
2.leds probe 函数实现
file:kernel-3.18/drivers/misc/mediatek/leds/leds_drv.c
//后面会用到的一些结构的定义
file:kernel-3.18/drivers/misc/mediatek/leds/mt6735/leds_sw.h
file:kernel-3.18/drivers/misc/mediatek/leds/mt6735/leds.c
3.从dts中获取各种led的配置信息
4. 创建相关的设备节点
//device_create_with_groups的实现
file:kernel-3.18/drivers/base/core.c
//device_create_groups_vargs 的实现
//device_add的实现
device_add_attrs的实现这里将会调用device_add_groups,class->dev_groups 作为参数呗传入,此时节点/sys/class/leds/xxx/brightness 已经被
创建 这里的xxx 对应驱动中的red,green,button_backlight,
lcd-backlight ... 已经创建
5、属性节点的读写方法定义
file:kernel-3.18/drivers/leds/led-class.c
再看led_groups的定义如下:
当用户空间读取属性节点时候,会直接输入当前亮度值
定义brightness属性的变量
6.button-backlight 亮灯的实现
通过上面节点的 /sys/class/leds/button-backlight/brightness 写方法brightness_store的定义可知,当brightness节点被用户空间写入后,将触发
执行__led_set_brightness,我们可以通过用户空间传入的参数调节灯的亮度,这里这里的传入参数范围0~255
这里的__led_set_brightness如下定义:
file:kernel-3.18/drivers/leds/leds.h
这个函数最终会调用led_cdev->brightness_set,而 led_cdev->brightness_set在leds_drv.c 中已经被赋值过如下:
file:kernel-3.18/drivers/misc/mediatek/leds/leds_drv.c
file:kernel-3.18/drivers/misc/mediatek/leds/mt6735/leds.c
mt_mt65xx_led_set_cust的实现
file:kernel-3.18/drivers/misc/mediatek/leds/mt6735/leds.c
也就是说当用户对属性节点 /sys/class/leds/button-backlight/brightness 写入时最终调用mt_brightness_set_pmic函数,
mt_brightness_set_pmic的实现如下:
file:kernel-3.18/drivers/misc/mediatek/leds/mt6735/leds.c
上述pmic_set_register_value的操作就是对ISINK具体寄存器的操作,本文不作深入研究
三、总结
通过上述的分析,我们大致可以看出在mtk平台上leds系列的驱动流程大致如下,先在dts中定义各个led节点的配置,配
置如mode,name,data 预留给driver调用,然后创建common drver (通用驱动)对各个led统一管理,在通用驱动中各个不
同类型led 通过数组区分,common driver对各个led进行统一的设备注册,属性节点创建等。当然led的种类繁多还有充
电指示灯,呼吸灯等,在加上每种灯硬件配置不一样驱动实现方式也不同,这个需要另行分析了。