Commit | Line | Data |
---|---|---|
5991e154 SO |
1 | Kernel driver for lp5521 |
2 | ======================== | |
3 | ||
4 | * National Semiconductor LP5521 led driver chip | |
5 | * Datasheet: http://www.national.com/pf/LP/LP5521.html | |
6 | ||
7 | Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo | |
8 | Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) | |
9 | ||
10 | Description | |
11 | ----------- | |
12 | ||
13 | LP5521 can drive up to 3 channels. Leds can be controlled directly via | |
14 | the led class control interface. Channels have generic names: | |
15 | lp5521:channelx, where x is 0 .. 2 | |
16 | ||
17 | All three channels can be also controlled using the engine micro programs. | |
18 | More details of the instructions can be found from the public data sheet. | |
19 | ||
20 | Control interface for the engines: | |
21 | x is 1 .. 3 | |
22 | enginex_mode : disabled, load, run | |
23 | enginex_load : store program (visible only in engine load mode) | |
24 | ||
25 | Example (start to blink the channel 2 led): | |
26 | cd /sys/class/leds/lp5521:channel2/device | |
27 | echo "load" > engine3_mode | |
28 | echo "037f4d0003ff6000" > engine3_load | |
29 | echo "run" > engine3_mode | |
30 | ||
31 | stop the engine: | |
32 | echo "disabled" > engine3_mode | |
33 | ||
34 | sysfs contains a selftest entry. | |
35 | The test communicates with the chip and checks that | |
36 | the clock mode is automatically set to the requested one. | |
37 | ||
38 | Each channel has its own led current settings. | |
39 | /sys/class/leds/lp5521:channel0/led_current - RW | |
40 | /sys/class/leds/lp5521:channel0/max_current - RO | |
41 | Format: 10x mA i.e 10 means 1.0 mA | |
42 | ||
43 | example platform data: | |
44 | ||
45 | Note: chan_nr can have values between 0 and 2. | |
5ae4e8a7 KM |
46 | The name of each channel can be configurable. |
47 | If the name field is not defined, the default name will be set to 'xxxx:channelN' | |
48 | (XXXX : pdata->label or i2c client name, N : channel number) | |
5991e154 SO |
49 | |
50 | static struct lp5521_led_config lp5521_led_config[] = { | |
51 | { | |
5ae4e8a7 | 52 | .name = "red", |
5991e154 SO |
53 | .chan_nr = 0, |
54 | .led_current = 50, | |
55 | .max_current = 130, | |
56 | }, { | |
5ae4e8a7 | 57 | .name = "green", |
5991e154 SO |
58 | .chan_nr = 1, |
59 | .led_current = 0, | |
60 | .max_current = 130, | |
61 | }, { | |
5ae4e8a7 | 62 | .name = "blue", |
5991e154 SO |
63 | .chan_nr = 2, |
64 | .led_current = 0, | |
65 | .max_current = 130, | |
66 | } | |
67 | }; | |
68 | ||
69 | static int lp5521_setup(void) | |
70 | { | |
71 | /* setup HW resources */ | |
72 | } | |
73 | ||
74 | static void lp5521_release(void) | |
75 | { | |
76 | /* Release HW resources */ | |
77 | } | |
78 | ||
79 | static void lp5521_enable(bool state) | |
80 | { | |
81 | /* Control of chip enable signal */ | |
82 | } | |
83 | ||
84 | static struct lp5521_platform_data lp5521_platform_data = { | |
85 | .led_config = lp5521_led_config, | |
86 | .num_channels = ARRAY_SIZE(lp5521_led_config), | |
87 | .clock_mode = LP5521_CLOCK_EXT, | |
88 | .setup_resources = lp5521_setup, | |
89 | .release_resources = lp5521_release, | |
90 | .enable = lp5521_enable, | |
91 | }; | |
92 | ||
93 | If the current is set to 0 in the platform data, that channel is | |
94 | disabled and it is not visible in the sysfs. | |
3b49aacd KM |
95 | |
96 | The 'update_config' : CONFIG register (ADDR 08h) | |
97 | This value is platform-specific data. | |
98 | If update_config is not defined, the CONFIG register is set with | |
99 | 'LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT'. | |
100 | (Enable auto-powersave, set charge pump to auto, red to battery) | |
101 | ||
102 | example of update_config : | |
103 | ||
104 | #define LP5521_CONFIGS (LP5521_PWM_HF | LP5521_PWRSAVE_EN | \ | |
105 | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \ | |
106 | LP5521_CLK_INT) | |
107 | ||
108 | static struct lp5521_platform_data lp5521_pdata = { | |
109 | .led_config = lp5521_led_config, | |
110 | .num_channels = ARRAY_SIZE(lp5521_led_config), | |
111 | .clock_mode = LP5521_CLOCK_INT, | |
112 | .update_config = LP5521_CONFIGS, | |
113 | }; | |
011af7bc KM |
114 | |
115 | LED patterns : LP5521 has autonomous operation without external control. | |
116 | Pattern data can be defined in the platform data. | |
117 | ||
118 | example of led pattern data : | |
119 | ||
120 | /* RGB(50,5,0) 500ms on, 500ms off, infinite loop */ | |
121 | static u8 pattern_red[] = { | |
122 | 0x40, 0x32, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00, | |
123 | }; | |
124 | ||
125 | static u8 pattern_green[] = { | |
126 | 0x40, 0x05, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00, | |
127 | }; | |
128 | ||
129 | static struct lp5521_led_pattern board_led_patterns[] = { | |
130 | { | |
131 | .r = pattern_red, | |
132 | .g = pattern_green, | |
133 | .size_r = ARRAY_SIZE(pattern_red), | |
134 | .size_g = ARRAY_SIZE(pattern_green), | |
135 | }, | |
136 | }; | |
137 | ||
138 | static struct lp5521_platform_data lp5521_platform_data = { | |
139 | .led_config = lp5521_led_config, | |
140 | .num_channels = ARRAY_SIZE(lp5521_led_config), | |
141 | .clock_mode = LP5521_CLOCK_EXT, | |
142 | .patterns = board_led_patterns, | |
143 | .num_patterns = ARRAY_SIZE(board_led_patterns), | |
144 | }; | |
145 | ||
146 | Then predefined led pattern(s) can be executed via the sysfs. | |
147 | To start the pattern #1, | |
148 | # echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern | |
149 | (xxxx : i2c bus & slave address) | |
150 | To end the pattern, | |
151 | # echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern |