LP5521/LP5523/LP55231/LP5562/LP8501 通用驱动程序¶
作者:Milo(Woogyom) Kim <milo.kim@ti.com>
描述¶
LP5521、LP5523/55231、LP5562 和 LP8501 具有以下通用特性。
通过 I2C 进行寄存器访问 设备初始化/反初始化 为多个输出通道创建 LED 类设备 用于用户空间接口的设备属性 用于运行 LED 模式的程序内存
LP55xx 通用驱动程序使用导出的函数提供这些功能。
lp55xx_init_device() / lp55xx_deinit_device() lp55xx_register_leds() / lp55xx_unregister_leds() lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs()
(驱动程序结构数据)
在 lp55xx 通用驱动程序中,使用了两种不同的数据结构。
- lp55xx_led
控制多输出 LED 通道,例如 LED 电流、通道索引。
- lp55xx_chip
一般的芯片控制,例如 I2C 和平台数据。
例如,LP5521 最多有 3 个 LED 通道。LP5523/55231 有 9 个输出通道
lp55xx_chip for LP5521 ... lp55xx_led #1
lp55xx_led #2
lp55xx_led #3
lp55xx_chip for LP5523 ... lp55xx_led #1
lp55xx_led #2
.
.
lp55xx_led #9
(芯片相关代码)
为了支持特定于设备的配置,使用了特殊的结构 ‘lpxx_device_config’。
最大通道数
复位命令、芯片使能命令
特定于芯片的初始化
亮度控制寄存器访问
设置 LED 输出电流
用于运行模式的程序内存地址访问
其他特定于设备的属性
(固件接口)
LP55xx 系列设备具有用于运行各种 LED 模式的内部程序内存。
此模式数据以文件的形式保存在用户空间中,或者将十六进制字节字符串通过 I2C 写入内存。
LP55xx 通用驱动程序支持固件接口。
LP55xx 芯片有三个程序引擎。
要加载并运行模式,编程顺序如下。
选择一个引擎编号 (1/2/3)
模式更改为加载
将模式数据写入选定区域
模式更改为运行
LP55xx 通用驱动程序提供如下简单接口。
- select_engine
选择哪个引擎用于运行程序
- run_engine
启动通过固件接口加载的程序
- firmware
加载程序数据
对于 LP5523,还需要一个命令 ‘enginex_leds’。它用于在每个引擎编号处选择 LED 输出。有关更多详细信息,请参阅 ‘lp5523 的内核驱动程序’。
例如,在 LP5521 的引擎 #1 中运行闪烁模式
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5521/loading
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
echo 0 > /sys/class/firmware/lp5521/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
例如,在 LP55231 的引擎 #3 中运行闪烁模式
两个 LED 被配置为模式输出通道
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp55231/loading
echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data
echo 0 > /sys/class/firmware/lp55231/loading
echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
同时启动引擎 #2 和 #3 中的闪烁模式
for idx in 2 3
do
echo $idx > /sys/class/leds/red/device/select_engine
sleep 0.1
echo 1 > /sys/class/firmware/lp5521/loading
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
echo 0 > /sys/class/firmware/lp5521/loading
done
echo 1 > /sys/class/leds/red/device/run_engine
这是 LP5523 的另一个示例。
通过 ‘engine2_leds’ 选择完整的 LED 字符串
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5523/loading
echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data
echo 0 > /sys/class/firmware/lp5523/loading
echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
一旦 ‘loading’ 设置为 0,就会调用注册的回调函数。在回调函数内部,加载选定的引擎并更新内存。要运行已编程的模式,应启用 ‘run_engine’ 属性。
LP8501 的模式顺序与 LP5523 类似。
但是模式数据是特定的。
示例 1) 使用引擎 1
echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
示例 2) 同时使用引擎 2 和 3
echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 1 > /sys/class/leds/d1/device/run_engine
(‘run_engine’ 和 ‘firmware_cb’)
运行程序数据的顺序是通用的。
但是每个设备都有自己的特定命令寄存器地址。
为了支持这一点,‘run_engine’ 和 ‘firmware_cb’ 在每个驱动程序中都是可配置的。
- run_engine
控制选定的引擎
- firmware_cb
加载固件后执行的回调函数。
用于加载和更新程序内存的芯片特定命令。
(预定义的模式数据)
在没有固件接口的情况下,LP55xx 驱动程序提供了另一种加载 LED 模式的方法。即 ‘预定义’ 模式。
预定义的模式在平台数据中定义,并在需要时通过 sysfs 加载。
要使用预定义模式的概念,应配置 ‘patterns’ 和 ‘num_patterns’。
预定义模式数据的示例
/* mode_1: blinking data */
static const u8 mode_1[] = {
0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00,
};
/* mode_2: always on */
static const u8 mode_2[] = { 0x40, 0xFF, };
struct lp55xx_predef_pattern board_led_patterns[] = {
{
.r = mode_1,
.size_r = ARRAY_SIZE(mode_1),
},
{
.b = mode_2,
.size_b = ARRAY_SIZE(mode_2),
},
}
struct lp55xx_platform_data lp5562_pdata = {
...
.patterns = board_led_patterns,
.num_patterns = ARRAY_SIZE(board_led_patterns),
};
然后,可以通过 sysfs 运行 mode_1 和 mode_2
echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern
echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on
停止运行模式
echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern