forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
6.7 KiB
224 lines
6.7 KiB
================================================= |
|
LP5521/LP5523/LP55231/LP5562/LP8501 Common Driver |
|
================================================= |
|
|
|
Authors: Milo(Woogyom) Kim <[email protected]> |
|
|
|
Description |
|
----------- |
|
LP5521, LP5523/55231, LP5562 and LP8501 have common features as below. |
|
|
|
Register access via the I2C |
|
Device initialization/deinitialization |
|
Create LED class devices for multiple output channels |
|
Device attributes for user-space interface |
|
Program memory for running LED patterns |
|
|
|
The LP55xx common driver provides these features using exported functions. |
|
|
|
lp55xx_init_device() / lp55xx_deinit_device() |
|
lp55xx_register_leds() / lp55xx_unregister_leds() |
|
lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs() |
|
|
|
( Driver Structure Data ) |
|
|
|
In lp55xx common driver, two different data structure is used. |
|
|
|
* lp55xx_led |
|
control multi output LED channels such as led current, channel index. |
|
* lp55xx_chip |
|
general chip control such like the I2C and platform data. |
|
|
|
For example, LP5521 has maximum 3 LED channels. |
|
LP5523/55231 has 9 output channels:: |
|
|
|
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 |
|
|
|
( Chip Dependent Code ) |
|
|
|
To support device specific configurations, special structure |
|
'lpxx_device_config' is used. |
|
|
|
- Maximum number of channels |
|
- Reset command, chip enable command |
|
- Chip specific initialization |
|
- Brightness control register access |
|
- Setting LED output current |
|
- Program memory address access for running patterns |
|
- Additional device specific attributes |
|
|
|
( Firmware Interface ) |
|
|
|
LP55xx family devices have the internal program memory for running |
|
various LED patterns. |
|
|
|
This pattern data is saved as a file in the user-land or |
|
hex byte string is written into the memory through the I2C. |
|
|
|
LP55xx common driver supports the firmware interface. |
|
|
|
LP55xx chips have three program engines. |
|
|
|
To load and run the pattern, the programming sequence is following. |
|
|
|
(1) Select an engine number (1/2/3) |
|
(2) Mode change to load |
|
(3) Write pattern data into selected area |
|
(4) Mode change to run |
|
|
|
The LP55xx common driver provides simple interfaces as below. |
|
|
|
select_engine: |
|
Select which engine is used for running program |
|
run_engine: |
|
Start program which is loaded via the firmware interface |
|
firmware: |
|
Load program data |
|
|
|
In case of LP5523, one more command is required, 'enginex_leds'. |
|
It is used for selecting LED output(s) at each engine number. |
|
In more details, please refer to 'leds-lp5523.txt'. |
|
|
|
For example, run blinking pattern in engine #1 of LP5521:: |
|
|
|
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 |
|
|
|
For example, run blinking pattern in engine #3 of LP55231 |
|
|
|
Two LEDs are configured as pattern output channels:: |
|
|
|
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 |
|
|
|
To start blinking patterns in engine #2 and #3 simultaneously:: |
|
|
|
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 |
|
|
|
Here is another example for LP5523. |
|
|
|
Full LED strings are selected by 'engine2_leds':: |
|
|
|
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 |
|
|
|
As soon as 'loading' is set to 0, registered callback is called. |
|
Inside the callback, the selected engine is loaded and memory is updated. |
|
To run programmed pattern, 'run_engine' attribute should be enabled. |
|
|
|
The pattern sequence of LP8501 is similar to LP5523. |
|
|
|
However pattern data is specific. |
|
|
|
Ex 1) Engine 1 is used:: |
|
|
|
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 |
|
|
|
Ex 2) Engine 2 and 3 are used at the same time:: |
|
|
|
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' and 'firmware_cb' ) |
|
|
|
The sequence of running the program data is common. |
|
|
|
But each device has own specific register addresses for commands. |
|
|
|
To support this, 'run_engine' and 'firmware_cb' are configurable in each driver. |
|
|
|
run_engine: |
|
Control the selected engine |
|
firmware_cb: |
|
The callback function after loading the firmware is done. |
|
|
|
Chip specific commands for loading and updating program memory. |
|
|
|
( Predefined pattern data ) |
|
|
|
Without the firmware interface, LP55xx driver provides another method for |
|
loading a LED pattern. That is 'predefined' pattern. |
|
|
|
A predefined pattern is defined in the platform data and load it(or them) |
|
via the sysfs if needed. |
|
|
|
To use the predefined pattern concept, 'patterns' and 'num_patterns' should be |
|
configured. |
|
|
|
Example of predefined pattern data:: |
|
|
|
/* 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), |
|
}; |
|
|
|
Then, mode_1 and mode_2 can be run via through the sysfs:: |
|
|
|
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 |
|
|
|
To stop running pattern:: |
|
|
|
echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
|
|
|