aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-06 18:41:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-06 18:41:42 -0400
commit2b69703fea185bb0ae1af78ca2da41af677b9dff (patch)
tree26b13044a0a20bed5525638d193e776f31f70af2
parent30c67e93c526639aaac90fa873800104b7c16d16 (diff)
parentdf92d5ff5e70999274f53884cc2c40ae620a109a (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds
Pull LED subsystem updates from Bryan Wu: - move LED trigger drivers into a new directory - lp55xx common driver updates - other led drivers updates and bug fixing * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds: leds: leds-asic3: switch to using SIMPLE_DEV_PM_OPS leds: leds-bd2802: add CONFIG_PM_SLEEP to suspend/resume functions leds: lp55xx: configure the clock detection leds: lp55xx: use common clock framework when external clock is used leds: leds-ns2: fix oops at module removal leds: leds-pwm: Defer led_pwm_set() if PWM can sleep leds: lp55xx: fix the sysfs read operation leds: lm355x, lm3642: support camera LED triggers for flash and torch leds: add camera LED triggers leds: trigger: use inline functions instead of macros leds: tca6507: Use of_match_ptr() macro leds: wm8350: Complain if we fail to reenable DCDC leds: renesas: set gpio_request_one() flags param correctly leds: leds-ns2: set devm_gpio_request_one() flags param correctly leds: leds-lt3593: set devm_gpio_request_one() flags param correctly leds: leds-bd2802: remove erroneous __exit annotation leds: atmel-pwm: remove erroneous __exit annotation leds: move LED trigger drivers into new subdirectory leds: add new LP5562 LED driver
-rw-r--r--Documentation/leds/00-INDEX2
-rw-r--r--Documentation/leds/leds-lp5521.txt19
-rw-r--r--Documentation/leds/leds-lp5562.txt120
-rw-r--r--Documentation/leds/leds-lp55xx.txt46
-rw-r--r--drivers/leds/Kconfig115
-rw-r--r--drivers/leds/Makefile11
-rw-r--r--drivers/leds/leds-asic3.c7
-rw-r--r--drivers/leds/leds-atmel-pwm.c4
-rw-r--r--drivers/leds/leds-bd2802.c14
-rw-r--r--drivers/leds/leds-lm355x.c2
-rw-r--r--drivers/leds/leds-lm3642.c2
-rw-r--r--drivers/leds/leds-lp5521.c22
-rw-r--r--drivers/leds/leds-lp5562.c599
-rw-r--r--drivers/leds/leds-lp55xx-common.c42
-rw-r--r--drivers/leds/leds-lp55xx-common.h4
-rw-r--r--drivers/leds/leds-lt3593.c5
-rw-r--r--drivers/leds/leds-ns2.c44
-rw-r--r--drivers/leds/leds-pwm.c50
-rw-r--r--drivers/leds/leds-renesas-tpu.c3
-rw-r--r--drivers/leds/leds-tca6507.c4
-rw-r--r--drivers/leds/leds-wm8350.c5
-rw-r--r--drivers/leds/trigger/Kconfig111
-rw-r--r--drivers/leds/trigger/Makefile10
-rw-r--r--drivers/leds/trigger/ledtrig-backlight.c (renamed from drivers/leds/ledtrig-backlight.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-camera.c57
-rw-r--r--drivers/leds/trigger/ledtrig-cpu.c (renamed from drivers/leds/ledtrig-cpu.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-default-on.c (renamed from drivers/leds/ledtrig-default-on.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-gpio.c (renamed from drivers/leds/ledtrig-gpio.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-heartbeat.c (renamed from drivers/leds/ledtrig-heartbeat.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-ide-disk.c (renamed from drivers/leds/ledtrig-ide-disk.c)0
-rw-r--r--drivers/leds/trigger/ledtrig-oneshot.c (renamed from drivers/leds/ledtrig-oneshot.c)2
-rw-r--r--drivers/leds/trigger/ledtrig-timer.c (renamed from drivers/leds/ledtrig-timer.c)1
-rw-r--r--drivers/leds/trigger/ledtrig-transient.c (renamed from drivers/leds/ledtrig-transient.c)2
-rw-r--r--include/linux/leds.h33
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/platform_data/leds-lp55xx.h21
36 files changed, 1149 insertions, 220 deletions
diff --git a/Documentation/leds/00-INDEX b/Documentation/leds/00-INDEX
index 5246090ef15c..1ecd1596633e 100644
--- a/Documentation/leds/00-INDEX
+++ b/Documentation/leds/00-INDEX
@@ -6,6 +6,8 @@ leds-lp5521.txt
6 - notes on how to use the leds-lp5521 driver. 6 - notes on how to use the leds-lp5521 driver.
7leds-lp5523.txt 7leds-lp5523.txt
8 - notes on how to use the leds-lp5523 driver. 8 - notes on how to use the leds-lp5523 driver.
9leds-lp5562.txt
10 - notes on how to use the leds-lp5562 driver.
9leds-lp55xx.txt 11leds-lp55xx.txt
10 - description about lp55xx common driver. 12 - description about lp55xx common driver.
11leds-lm3556.txt 13leds-lm3556.txt
diff --git a/Documentation/leds/leds-lp5521.txt b/Documentation/leds/leds-lp5521.txt
index 270f57196339..79e4c2e6e5e8 100644
--- a/Documentation/leds/leds-lp5521.txt
+++ b/Documentation/leds/leds-lp5521.txt
@@ -81,22 +81,3 @@ static struct lp55xx_platform_data lp5521_platform_data = {
81 81
82If the current is set to 0 in the platform data, that channel is 82If the current is set to 0 in the platform data, that channel is
83disabled and it is not visible in the sysfs. 83disabled and it is not visible in the sysfs.
84
85The 'update_config' : CONFIG register (ADDR 08h)
86This value is platform-specific data.
87If update_config is not defined, the CONFIG register is set with
88'LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT'.
89(Enable auto-powersave, set charge pump to auto, red to battery)
90
91example of update_config :
92
93#define LP5521_CONFIGS (LP5521_PWM_HF | LP5521_PWRSAVE_EN | \
94 LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \
95 LP5521_CLK_INT)
96
97static struct lp55xx_platform_data lp5521_pdata = {
98 .led_config = lp5521_led_config,
99 .num_channels = ARRAY_SIZE(lp5521_led_config),
100 .clock_mode = LP55XX_CLOCK_INT,
101 .update_config = LP5521_CONFIGS,
102};
diff --git a/Documentation/leds/leds-lp5562.txt b/Documentation/leds/leds-lp5562.txt
new file mode 100644
index 000000000000..5a823ff6b393
--- /dev/null
+++ b/Documentation/leds/leds-lp5562.txt
@@ -0,0 +1,120 @@
1Kernel driver for LP5562
2========================
3
4* TI LP5562 LED Driver
5
6Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7
8Description
9
10 LP5562 can drive up to 4 channels. R/G/B and White.
11 LEDs can be controlled directly via the led class control interface.
12
13 All four channels can be also controlled using the engine micro programs.
14 LP5562 has the internal program memory for running various LED patterns.
15 For the details, please refer to 'firmware' section in leds-lp55xx.txt
16
17Device attribute: engine_mux
18
19 3 Engines are allocated in LP5562, but the number of channel is 4.
20 Therefore each channel should be mapped to the engine number.
21 Value : RGB or W
22
23 This attribute is used for programming LED data with the firmware interface.
24 Unlike the LP5521/LP5523/55231, LP5562 has unique feature for the engine mux,
25 so additional sysfs is required.
26
27 LED Map
28 Red ... Engine 1 (fixed)
29 Green ... Engine 2 (fixed)
30 Blue ... Engine 3 (fixed)
31 White ... Engine 1 or 2 or 3 (selective)
32
33How to load the program data using engine_mux
34
35 Before loading the LP5562 program data, engine_mux should be written between
36 the engine selection and loading the firmware.
37 Engine mux has two different mode, RGB and W.
38 RGB is used for loading RGB program data, W is used for W program data.
39
40 For example, run blinking green channel pattern,
41 echo 2 > /sys/bus/i2c/devices/xxxx/select_engine # 2 is for green channel
42 echo "RGB" > /sys/bus/i2c/devices/xxxx/engine_mux # engine mux for RGB
43 echo 1 > /sys/class/firmware/lp5562/loading
44 echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
45 echo 0 > /sys/class/firmware/lp5562/loading
46 echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
47
48 To run a blinking white pattern,
49 echo 1 or 2 or 3 > /sys/bus/i2c/devices/xxxx/select_engine
50 echo "W" > /sys/bus/i2c/devices/xxxx/engine_mux
51 echo 1 > /sys/class/firmware/lp5562/loading
52 echo "4000600040FF6000" > /sys/class/firmware/lp5562/data
53 echo 0 > /sys/class/firmware/lp5562/loading
54 echo 1 > /sys/bus/i2c/devices/xxxx/run_engine
55
56How to load the predefined patterns
57
58 Please refer to 'leds-lp55xx.txt"
59
60Setting Current of Each Channel
61
62 Like LP5521 and LP5523/55231, LP5562 provides LED current settings.
63 The 'led_current' and 'max_current' are used.
64
65(Example of Platform data)
66
67To configure the platform specific data, lp55xx_platform_data structure is used.
68
69static struct lp55xx_led_config lp5562_led_config[] = {
70 {
71 .name = "R",
72 .chan_nr = 0,
73 .led_current = 20,
74 .max_current = 40,
75 },
76 {
77 .name = "G",
78 .chan_nr = 1,
79 .led_current = 20,
80 .max_current = 40,
81 },
82 {
83 .name = "B",
84 .chan_nr = 2,
85 .led_current = 20,
86 .max_current = 40,
87 },
88 {
89 .name = "W",
90 .chan_nr = 3,
91 .led_current = 20,
92 .max_current = 40,
93 },
94};
95
96static int lp5562_setup(void)
97{
98 /* setup HW resources */
99}
100
101static void lp5562_release(void)
102{
103 /* Release HW resources */
104}
105
106static void lp5562_enable(bool state)
107{
108 /* Control of chip enable signal */
109}
110
111static struct lp55xx_platform_data lp5562_platform_data = {
112 .led_config = lp5562_led_config,
113 .num_channels = ARRAY_SIZE(lp5562_led_config),
114 .setup_resources = lp5562_setup,
115 .release_resources = lp5562_release,
116 .enable = lp5562_enable,
117};
118
119If the current is set to 0 in the platform data, that channel is
120disabled and it is not visible in the sysfs.
diff --git a/Documentation/leds/leds-lp55xx.txt b/Documentation/leds/leds-lp55xx.txt
index ced41868d2d1..eec8fa2ffe4e 100644
--- a/Documentation/leds/leds-lp55xx.txt
+++ b/Documentation/leds/leds-lp55xx.txt
@@ -5,7 +5,7 @@ Authors: Milo(Woogyom) Kim <milo.kim@ti.com>
5 5
6Description 6Description
7----------- 7-----------
8LP5521, LP5523/55231 have common features as below. 8LP5521, LP5523/55231 and LP5562 have common features as below.
9 9
10 Register access via the I2C 10 Register access via the I2C
11 Device initialization/deinitialization 11 Device initialization/deinitialization
@@ -116,3 +116,47 @@ To support this, 'run_engine' and 'firmware_cb' are configurable in each driver.
116run_engine : Control the selected engine 116run_engine : Control the selected engine
117firmware_cb : The callback function after loading the firmware is done. 117firmware_cb : The callback function after loading the firmware is done.
118 Chip specific commands for loading and updating program memory. 118 Chip specific commands for loading and updating program memory.
119
120( Predefined pattern data )
121
122Without the firmware interface, LP55xx driver provides another method for
123loading a LED pattern. That is 'predefined' pattern.
124A predefined pattern is defined in the platform data and load it(or them)
125via the sysfs if needed.
126To use the predefined pattern concept, 'patterns' and 'num_patterns' should be
127configured.
128
129 Example of predefined pattern data:
130
131 /* mode_1: blinking data */
132 static const u8 mode_1[] = {
133 0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00,
134 };
135
136 /* mode_2: always on */
137 static const u8 mode_2[] = { 0x40, 0xFF, };
138
139 struct lp55xx_predef_pattern board_led_patterns[] = {
140 {
141 .r = mode_1,
142 .size_r = ARRAY_SIZE(mode_1),
143 },
144 {
145 .b = mode_2,
146 .size_b = ARRAY_SIZE(mode_2),
147 },
148 }
149
150 struct lp55xx_platform_data lp5562_pdata = {
151 ...
152 .patterns = board_led_patterns,
153 .num_patterns = ARRAY_SIZE(board_led_patterns),
154 };
155
156Then, mode_1 and mode_2 can be run via through the sysfs.
157
158 echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern
159 echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on
160
161To stop running pattern,
162 echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index ec50824c02ec..d44806d41b44 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -194,8 +194,8 @@ config LEDS_LP3944
194 module will be called leds-lp3944. 194 module will be called leds-lp3944.
195 195
196config LEDS_LP55XX_COMMON 196config LEDS_LP55XX_COMMON
197 tristate "Common Driver for TI/National LP5521 and LP5523/55231" 197 tristate "Common Driver for TI/National LP5521, LP5523/55231 and LP5562"
198 depends on LEDS_LP5521 || LEDS_LP5523 198 depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562
199 select FW_LOADER 199 select FW_LOADER
200 help 200 help
201 This option supports common operations for LP5521 and LP5523/55231 201 This option supports common operations for LP5521 and LP5523/55231
@@ -222,6 +222,16 @@ config LEDS_LP5523
222 Driver provides direct control via LED class and interface for 222 Driver provides direct control via LED class and interface for
223 programming the engines. 223 programming the engines.
224 224
225config LEDS_LP5562
226 tristate "LED Support for TI LP5562 LED driver chip"
227 depends on LEDS_CLASS && I2C
228 select LEDS_LP55XX_COMMON
229 help
230 If you say yes here you get support for TI LP5562 LED driver.
231 It is 4 channels chip with programmable engines.
232 Driver provides direct control via LED class and interface for
233 programming the engines.
234
225config LEDS_LP8788 235config LEDS_LP8788
226 tristate "LED support for the TI LP8788 PMIC" 236 tristate "LED support for the TI LP8788 PMIC"
227 depends on LEDS_CLASS 237 depends on LEDS_CLASS
@@ -469,106 +479,7 @@ config LEDS_BLINKM
469 This option enables support for the BlinkM RGB LED connected 479 This option enables support for the BlinkM RGB LED connected
470 through I2C. Say Y to enable support for the BlinkM LED. 480 through I2C. Say Y to enable support for the BlinkM LED.
471 481
472config LEDS_TRIGGERS
473 bool "LED Trigger support"
474 depends on LEDS_CLASS
475 help
476 This option enables trigger support for the leds class.
477 These triggers allow kernel events to drive the LEDs and can
478 be configured via sysfs. If unsure, say Y.
479
480comment "LED Triggers" 482comment "LED Triggers"
481 483source "drivers/leds/trigger/Kconfig"
482config LEDS_TRIGGER_TIMER
483 tristate "LED Timer Trigger"
484 depends on LEDS_TRIGGERS
485 help
486 This allows LEDs to be controlled by a programmable timer
487 via sysfs. Some LED hardware can be programmed to start
488 blinking the LED without any further software interaction.
489 For more details read Documentation/leds/leds-class.txt.
490
491 If unsure, say Y.
492
493config LEDS_TRIGGER_ONESHOT
494 tristate "LED One-shot Trigger"
495 depends on LEDS_TRIGGERS
496 help
497 This allows LEDs to blink in one-shot pulses with parameters
498 controlled via sysfs. It's useful to notify the user on
499 sporadic events, when there are no clear begin and end trap points,
500 or on dense events, where this blinks the LED at constant rate if
501 rearmed continuously.
502
503 It also shows how to use the led_blink_set_oneshot() function.
504
505 If unsure, say Y.
506
507config LEDS_TRIGGER_IDE_DISK
508 bool "LED IDE Disk Trigger"
509 depends on IDE_GD_ATA
510 depends on LEDS_TRIGGERS
511 help
512 This allows LEDs to be controlled by IDE disk activity.
513 If unsure, say Y.
514
515config LEDS_TRIGGER_HEARTBEAT
516 tristate "LED Heartbeat Trigger"
517 depends on LEDS_TRIGGERS
518 help
519 This allows LEDs to be controlled by a CPU load average.
520 The flash frequency is a hyperbolic function of the 1-minute
521 load average.
522 If unsure, say Y.
523
524config LEDS_TRIGGER_BACKLIGHT
525 tristate "LED backlight Trigger"
526 depends on LEDS_TRIGGERS
527 help
528 This allows LEDs to be controlled as a backlight device: they
529 turn off and on when the display is blanked and unblanked.
530
531 If unsure, say N.
532
533config LEDS_TRIGGER_CPU
534 bool "LED CPU Trigger"
535 depends on LEDS_TRIGGERS
536 help
537 This allows LEDs to be controlled by active CPUs. This shows
538 the active CPUs across an array of LEDs so you can see which
539 CPUs are active on the system at any given moment.
540
541 If unsure, say N.
542
543config LEDS_TRIGGER_GPIO
544 tristate "LED GPIO Trigger"
545 depends on LEDS_TRIGGERS
546 depends on GPIOLIB
547 help
548 This allows LEDs to be controlled by gpio events. It's good
549 when using gpios as switches and triggering the needed LEDs
550 from there. One use case is n810's keypad LEDs that could
551 be triggered by this trigger when user slides up to show
552 keypad.
553
554 If unsure, say N.
555
556config LEDS_TRIGGER_DEFAULT_ON
557 tristate "LED Default ON Trigger"
558 depends on LEDS_TRIGGERS
559 help
560 This allows LEDs to be initialised in the ON state.
561 If unsure, say Y.
562
563comment "iptables trigger is under Netfilter config (LED target)"
564 depends on LEDS_TRIGGERS
565
566config LEDS_TRIGGER_TRANSIENT
567 tristate "LED Transient Trigger"
568 depends on LEDS_TRIGGERS
569 help
570 This allows one time activation of a transient state on
571 GPIO/PWM based hardware.
572 If unsure, say Y.
573 484
574endif # NEW_LEDS 485endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 215e7e3b6173..ac2897732b02 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o
26obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o 26obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o
27obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o 27obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
28obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o 28obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
29obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o
29obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o 30obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
30obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o 31obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
31obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 32obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
@@ -57,12 +58,4 @@ obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
57obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o 58obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
58 59
59# LED Triggers 60# LED Triggers
60obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 61obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
61obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
62obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
63obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
64obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
65obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
66obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
67obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
68obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index b474745e001b..cf9efe421c2b 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -134,6 +134,7 @@ static int asic3_led_remove(struct platform_device *pdev)
134 return mfd_cell_disable(pdev); 134 return mfd_cell_disable(pdev);
135} 135}
136 136
137#ifdef CONFIG_PM_SLEEP
137static int asic3_led_suspend(struct device *dev) 138static int asic3_led_suspend(struct device *dev)
138{ 139{
139 struct platform_device *pdev = to_platform_device(dev); 140 struct platform_device *pdev = to_platform_device(dev);
@@ -159,11 +160,9 @@ static int asic3_led_resume(struct device *dev)
159 160
160 return ret; 161 return ret;
161} 162}
163#endif
162 164
163static const struct dev_pm_ops asic3_led_pm_ops = { 165static SIMPLE_DEV_PM_OPS(asic3_led_pm_ops, asic3_led_suspend, asic3_led_resume);
164 .suspend = asic3_led_suspend,
165 .resume = asic3_led_resume,
166};
167 166
168static struct platform_driver asic3_led_driver = { 167static struct platform_driver asic3_led_driver = {
169 .probe = asic3_led_probe, 168 .probe = asic3_led_probe,
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 386773532d95..8a39c5b20f76 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -113,7 +113,7 @@ err:
113 return status; 113 return status;
114} 114}
115 115
116static int __exit pwmled_remove(struct platform_device *pdev) 116static int pwmled_remove(struct platform_device *pdev)
117{ 117{
118 const struct gpio_led_platform_data *pdata; 118 const struct gpio_led_platform_data *pdata;
119 struct pwmled *leds; 119 struct pwmled *leds;
@@ -140,7 +140,7 @@ static struct platform_driver pwmled_driver = {
140 }, 140 },
141 /* REVISIT add suspend() and resume() methods */ 141 /* REVISIT add suspend() and resume() methods */
142 .probe = pwmled_probe, 142 .probe = pwmled_probe,
143 .remove = __exit_p(pwmled_remove), 143 .remove = pwmled_remove,
144}; 144};
145 145
146module_platform_driver(pwmled_driver); 146module_platform_driver(pwmled_driver);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 851517030cc1..2db04231a792 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -732,7 +732,7 @@ failed_unregister_dev_file:
732 return ret; 732 return ret;
733} 733}
734 734
735static int __exit bd2802_remove(struct i2c_client *client) 735static int bd2802_remove(struct i2c_client *client)
736{ 736{
737 struct bd2802_led *led = i2c_get_clientdata(client); 737 struct bd2802_led *led = i2c_get_clientdata(client);
738 int i; 738 int i;
@@ -747,8 +747,7 @@ static int __exit bd2802_remove(struct i2c_client *client)
747 return 0; 747 return 0;
748} 748}
749 749
750#ifdef CONFIG_PM 750#ifdef CONFIG_PM_SLEEP
751
752static void bd2802_restore_state(struct bd2802_led *led) 751static void bd2802_restore_state(struct bd2802_led *led)
753{ 752{
754 int i; 753 int i;
@@ -785,12 +784,9 @@ static int bd2802_resume(struct device *dev)
785 784
786 return 0; 785 return 0;
787} 786}
787#endif
788 788
789static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume); 789static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume);
790#define BD2802_PM (&bd2802_pm)
791#else /* CONFIG_PM */
792#define BD2802_PM NULL
793#endif
794 790
795static const struct i2c_device_id bd2802_id[] = { 791static const struct i2c_device_id bd2802_id[] = {
796 { "BD2802", 0 }, 792 { "BD2802", 0 },
@@ -801,10 +797,10 @@ MODULE_DEVICE_TABLE(i2c, bd2802_id);
801static struct i2c_driver bd2802_i2c_driver = { 797static struct i2c_driver bd2802_i2c_driver = {
802 .driver = { 798 .driver = {
803 .name = "BD2802", 799 .name = "BD2802",
804 .pm = BD2802_PM, 800 .pm = &bd2802_pm,
805 }, 801 },
806 .probe = bd2802_probe, 802 .probe = bd2802_probe,
807 .remove = __exit_p(bd2802_remove), 803 .remove = bd2802_remove,
808 .id_table = bd2802_id, 804 .id_table = bd2802_id,
809}; 805};
810 806
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
index 4117235ba618..d81a8e7afd6c 100644
--- a/drivers/leds/leds-lm355x.c
+++ b/drivers/leds/leds-lm355x.c
@@ -477,6 +477,7 @@ static int lm355x_probe(struct i2c_client *client,
477 chip->cdev_flash.name = "flash"; 477 chip->cdev_flash.name = "flash";
478 chip->cdev_flash.max_brightness = 16; 478 chip->cdev_flash.max_brightness = 16;
479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set; 479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
480 chip->cdev_flash.default_trigger = "flash";
480 err = led_classdev_register((struct device *) 481 err = led_classdev_register((struct device *)
481 &client->dev, &chip->cdev_flash); 482 &client->dev, &chip->cdev_flash);
482 if (err < 0) 483 if (err < 0)
@@ -486,6 +487,7 @@ static int lm355x_probe(struct i2c_client *client,
486 chip->cdev_torch.name = "torch"; 487 chip->cdev_torch.name = "torch";
487 chip->cdev_torch.max_brightness = 8; 488 chip->cdev_torch.max_brightness = 8;
488 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set; 489 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
490 chip->cdev_torch.default_trigger = "torch";
489 err = led_classdev_register((struct device *) 491 err = led_classdev_register((struct device *)
490 &client->dev, &chip->cdev_torch); 492 &client->dev, &chip->cdev_torch);
491 if (err < 0) 493 if (err < 0)
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
index 9f428d9dfe91..f361bbef2dec 100644
--- a/drivers/leds/leds-lm3642.c
+++ b/drivers/leds/leds-lm3642.c
@@ -363,6 +363,7 @@ static int lm3642_probe(struct i2c_client *client,
363 chip->cdev_flash.name = "flash"; 363 chip->cdev_flash.name = "flash";
364 chip->cdev_flash.max_brightness = 16; 364 chip->cdev_flash.max_brightness = 16;
365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set; 365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
366 chip->cdev_flash.default_trigger = "flash";
366 err = led_classdev_register((struct device *) 367 err = led_classdev_register((struct device *)
367 &client->dev, &chip->cdev_flash); 368 &client->dev, &chip->cdev_flash);
368 if (err < 0) { 369 if (err < 0) {
@@ -380,6 +381,7 @@ static int lm3642_probe(struct i2c_client *client,
380 chip->cdev_torch.name = "torch"; 381 chip->cdev_torch.name = "torch";
381 chip->cdev_torch.max_brightness = 8; 382 chip->cdev_torch.max_brightness = 8;
382 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set; 383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
384 chip->cdev_torch.default_trigger = "torch";
383 err = led_classdev_register((struct device *) 385 err = led_classdev_register((struct device *)
384 &client->dev, &chip->cdev_torch); 386 &client->dev, &chip->cdev_torch);
385 if (err < 0) { 387 if (err < 0) {
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 1001347ba70b..19752c928aa2 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -68,6 +68,18 @@
68#define LP5521_ENABLE_RUN_PROGRAM \ 68#define LP5521_ENABLE_RUN_PROGRAM \
69 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN) 69 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
70 70
71/* CONFIG register */
72#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
73#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
74#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */
75#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */
76#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */
77#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */
78#define LP5521_R_TO_BATT 0x04 /* R out: 0 = CP, 1 = Vbat */
79#define LP5521_CLK_INT 0x01 /* Internal clock */
80#define LP5521_DEFAULT_CFG \
81 (LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO)
82
71/* Status */ 83/* Status */
72#define LP5521_EXT_CLK_USED 0x08 84#define LP5521_EXT_CLK_USED 0x08
73 85
@@ -296,8 +308,11 @@ static int lp5521_post_init_device(struct lp55xx_chip *chip)
296 /* Set all PWMs to direct control mode */ 308 /* Set all PWMs to direct control mode */
297 ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 309 ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
298 310
299 val = chip->pdata->update_config ? 311 /* Update configuration for the clock setting */
300 : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); 312 val = LP5521_DEFAULT_CFG;
313 if (!lp55xx_is_extclk_used(chip))
314 val |= LP5521_CLK_INT;
315
301 ret = lp55xx_write(chip, LP5521_REG_CONFIG, val); 316 ret = lp55xx_write(chip, LP5521_REG_CONFIG, val);
302 if (ret) 317 if (ret)
303 return ret; 318 return ret;
@@ -360,7 +375,8 @@ static ssize_t lp5521_selftest(struct device *dev,
360 mutex_lock(&chip->lock); 375 mutex_lock(&chip->lock);
361 ret = lp5521_run_selftest(chip, buf); 376 ret = lp5521_run_selftest(chip, buf);
362 mutex_unlock(&chip->lock); 377 mutex_unlock(&chip->lock);
363 return sprintf(buf, "%s\n", ret ? "FAIL" : "OK"); 378
379 return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
364} 380}
365 381
366/* device attributes */ 382/* device attributes */
diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c
new file mode 100644
index 000000000000..513f2390ca2d
--- /dev/null
+++ b/drivers/leds/leds-lp5562.c
@@ -0,0 +1,599 @@
1/*
2 * LP5562 LED driver
3 *
4 * Copyright (C) 2013 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/firmware.h>
15#include <linux/i2c.h>
16#include <linux/init.h>
17#include <linux/leds.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/platform_data/leds-lp55xx.h>
21#include <linux/slab.h>
22
23#include "leds-lp55xx-common.h"
24
25#define LP5562_PROGRAM_LENGTH 32
26#define LP5562_MAX_LEDS 4
27
28/* ENABLE Register 00h */
29#define LP5562_REG_ENABLE 0x00
30#define LP5562_EXEC_ENG1_M 0x30
31#define LP5562_EXEC_ENG2_M 0x0C
32#define LP5562_EXEC_ENG3_M 0x03
33#define LP5562_EXEC_M 0x3F
34#define LP5562_MASTER_ENABLE 0x40 /* Chip master enable */
35#define LP5562_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
36#define LP5562_EXEC_RUN 0x2A
37#define LP5562_ENABLE_DEFAULT \
38 (LP5562_MASTER_ENABLE | LP5562_LOGARITHMIC_PWM)
39#define LP5562_ENABLE_RUN_PROGRAM \
40 (LP5562_ENABLE_DEFAULT | LP5562_EXEC_RUN)
41
42/* OPMODE Register 01h */
43#define LP5562_REG_OP_MODE 0x01
44#define LP5562_MODE_ENG1_M 0x30
45#define LP5562_MODE_ENG2_M 0x0C
46#define LP5562_MODE_ENG3_M 0x03
47#define LP5562_LOAD_ENG1 0x10
48#define LP5562_LOAD_ENG2 0x04
49#define LP5562_LOAD_ENG3 0x01
50#define LP5562_RUN_ENG1 0x20
51#define LP5562_RUN_ENG2 0x08
52#define LP5562_RUN_ENG3 0x02
53#define LP5562_ENG1_IS_LOADING(mode) \
54 ((mode & LP5562_MODE_ENG1_M) == LP5562_LOAD_ENG1)
55#define LP5562_ENG2_IS_LOADING(mode) \
56 ((mode & LP5562_MODE_ENG2_M) == LP5562_LOAD_ENG2)
57#define LP5562_ENG3_IS_LOADING(mode) \
58 ((mode & LP5562_MODE_ENG3_M) == LP5562_LOAD_ENG3)
59
60/* BRIGHTNESS Registers */
61#define LP5562_REG_R_PWM 0x04
62#define LP5562_REG_G_PWM 0x03
63#define LP5562_REG_B_PWM 0x02
64#define LP5562_REG_W_PWM 0x0E
65
66/* CURRENT Registers */
67#define LP5562_REG_R_CURRENT 0x07
68#define LP5562_REG_G_CURRENT 0x06
69#define LP5562_REG_B_CURRENT 0x05
70#define LP5562_REG_W_CURRENT 0x0F
71
72/* CONFIG Register 08h */
73#define LP5562_REG_CONFIG 0x08
74#define LP5562_PWM_HF 0x40
75#define LP5562_PWRSAVE_EN 0x20
76#define LP5562_CLK_INT 0x01 /* Internal clock */
77#define LP5562_DEFAULT_CFG (LP5562_PWM_HF | LP5562_PWRSAVE_EN)
78
79/* RESET Register 0Dh */
80#define LP5562_REG_RESET 0x0D
81#define LP5562_RESET 0xFF
82
83/* PROGRAM ENGINE Registers */
84#define LP5562_REG_PROG_MEM_ENG1 0x10
85#define LP5562_REG_PROG_MEM_ENG2 0x30
86#define LP5562_REG_PROG_MEM_ENG3 0x50
87
88/* LEDMAP Register 70h */
89#define LP5562_REG_ENG_SEL 0x70
90#define LP5562_ENG_SEL_PWM 0
91#define LP5562_ENG_FOR_RGB_M 0x3F
92#define LP5562_ENG_SEL_RGB 0x1B /* R:ENG1, G:ENG2, B:ENG3 */
93#define LP5562_ENG_FOR_W_M 0xC0
94#define LP5562_ENG1_FOR_W 0x40 /* W:ENG1 */
95#define LP5562_ENG2_FOR_W 0x80 /* W:ENG2 */
96#define LP5562_ENG3_FOR_W 0xC0 /* W:ENG3 */
97
98/* Program Commands */
99#define LP5562_CMD_DISABLE 0x00
100#define LP5562_CMD_LOAD 0x15
101#define LP5562_CMD_RUN 0x2A
102#define LP5562_CMD_DIRECT 0x3F
103#define LP5562_PATTERN_OFF 0
104
105static inline void lp5562_wait_opmode_done(void)
106{
107 /* operation mode change needs to be longer than 153 us */
108 usleep_range(200, 300);
109}
110
111static inline void lp5562_wait_enable_done(void)
112{
113 /* it takes more 488 us to update ENABLE register */
114 usleep_range(500, 600);
115}
116
117static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
118{
119 u8 addr[] = {
120 LP5562_REG_R_CURRENT,
121 LP5562_REG_G_CURRENT,
122 LP5562_REG_B_CURRENT,
123 LP5562_REG_W_CURRENT,
124 };
125
126 led->led_current = led_current;
127 lp55xx_write(led->chip, addr[led->chan_nr], led_current);
128}
129
130static void lp5562_load_engine(struct lp55xx_chip *chip)
131{
132 enum lp55xx_engine_index idx = chip->engine_idx;
133 u8 mask[] = {
134 [LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M,
135 [LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M,
136 [LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M,
137 };
138
139 u8 val[] = {
140 [LP55XX_ENGINE_1] = LP5562_LOAD_ENG1,
141 [LP55XX_ENGINE_2] = LP5562_LOAD_ENG2,
142 [LP55XX_ENGINE_3] = LP5562_LOAD_ENG3,
143 };
144
145 lp55xx_update_bits(chip, LP5562_REG_OP_MODE, mask[idx], val[idx]);
146
147 lp5562_wait_opmode_done();
148}
149
150static void lp5562_stop_engine(struct lp55xx_chip *chip)
151{
152 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DISABLE);
153 lp5562_wait_opmode_done();
154}
155
156static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
157{
158 int ret;
159 u8 mode;
160 u8 exec;
161
162 /* stop engine */
163 if (!start) {
164 lp55xx_write(chip, LP5562_REG_ENABLE, LP5562_ENABLE_DEFAULT);
165 lp5562_wait_enable_done();
166 lp5562_stop_engine(chip);
167 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
168 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
169 lp5562_wait_opmode_done();
170 return;
171 }
172
173 /*
174 * To run the engine,
175 * operation mode and enable register should updated at the same time
176 */
177
178 ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode);
179 if (ret)
180 return;
181
182 ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec);
183 if (ret)
184 return;
185
186 /* change operation mode to RUN only when each engine is loading */
187 if (LP5562_ENG1_IS_LOADING(mode)) {
188 mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1;
189 exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1;
190 }
191
192 if (LP5562_ENG2_IS_LOADING(mode)) {
193 mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2;
194 exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2;
195 }
196
197 if (LP5562_ENG3_IS_LOADING(mode)) {
198 mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3;
199 exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3;
200 }
201
202 lp55xx_write(chip, LP5562_REG_OP_MODE, mode);
203 lp5562_wait_opmode_done();
204
205 lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec);
206 lp5562_wait_enable_done();
207}
208
209static int lp5562_update_firmware(struct lp55xx_chip *chip,
210 const u8 *data, size_t size)
211{
212 enum lp55xx_engine_index idx = chip->engine_idx;
213 u8 pattern[LP5562_PROGRAM_LENGTH] = {0};
214 u8 addr[] = {
215 [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1,
216 [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2,
217 [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3,
218 };
219 unsigned cmd;
220 char c[3];
221 int program_size;
222 int nrchars;
223 int offset = 0;
224 int ret;
225 int i;
226
227 /* clear program memory before updating */
228 for (i = 0; i < LP5562_PROGRAM_LENGTH; i++)
229 lp55xx_write(chip, addr[idx] + i, 0);
230
231 i = 0;
232 while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) {
233 /* separate sscanfs because length is working only for %s */
234 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
235 if (ret != 1)
236 goto err;
237
238 ret = sscanf(c, "%2x", &cmd);
239 if (ret != 1)
240 goto err;
241
242 pattern[i] = (u8)cmd;
243 offset += nrchars;
244 i++;
245 }
246
247 /* Each instruction is 16bit long. Check that length is even */
248 if (i % 2)
249 goto err;
250
251 program_size = i;
252 for (i = 0; i < program_size; i++)
253 lp55xx_write(chip, addr[idx] + i, pattern[i]);
254
255 return 0;
256
257err:
258 dev_err(&chip->cl->dev, "wrong pattern format\n");
259 return -EINVAL;
260}
261
262static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
263{
264 const struct firmware *fw = chip->fw;
265
266 if (fw->size > LP5562_PROGRAM_LENGTH) {
267 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
268 fw->size);
269 return;
270 }
271
272 /*
273 * Program momery sequence
274 * 1) set engine mode to "LOAD"
275 * 2) write firmware data into program memory
276 */
277
278 lp5562_load_engine(chip);
279 lp5562_update_firmware(chip, fw->data, fw->size);
280}
281
282static int lp5562_post_init_device(struct lp55xx_chip *chip)
283{
284 int ret;
285 u8 cfg = LP5562_DEFAULT_CFG;
286
287 /* Set all PWMs to direct control mode */
288 ret = lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
289 if (ret)
290 return ret;
291
292 lp5562_wait_opmode_done();
293
294 /* Update configuration for the clock setting */
295 if (!lp55xx_is_extclk_used(chip))
296 cfg |= LP5562_CLK_INT;
297
298 ret = lp55xx_write(chip, LP5562_REG_CONFIG, cfg);
299 if (ret)
300 return ret;
301
302 /* Initialize all channels PWM to zero -> leds off */
303 lp55xx_write(chip, LP5562_REG_R_PWM, 0);
304 lp55xx_write(chip, LP5562_REG_G_PWM, 0);
305 lp55xx_write(chip, LP5562_REG_B_PWM, 0);
306 lp55xx_write(chip, LP5562_REG_W_PWM, 0);
307
308 /* Set LED map as register PWM by default */
309 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
310
311 return 0;
312}
313
314static void lp5562_led_brightness_work(struct work_struct *work)
315{
316 struct lp55xx_led *led = container_of(work, struct lp55xx_led,
317 brightness_work);
318 struct lp55xx_chip *chip = led->chip;
319 u8 addr[] = {
320 LP5562_REG_R_PWM,
321 LP5562_REG_G_PWM,
322 LP5562_REG_B_PWM,
323 LP5562_REG_W_PWM,
324 };
325
326 mutex_lock(&chip->lock);
327 lp55xx_write(chip, addr[led->chan_nr], led->brightness);
328 mutex_unlock(&chip->lock);
329}
330
331static void lp5562_write_program_memory(struct lp55xx_chip *chip,
332 u8 base, const u8 *rgb, int size)
333{
334 int i;
335
336 if (!rgb || size <= 0)
337 return;
338
339 for (i = 0; i < size; i++)
340 lp55xx_write(chip, base + i, *(rgb + i));
341
342 lp55xx_write(chip, base + i, 0);
343 lp55xx_write(chip, base + i + 1, 0);
344}
345
346/* check the size of program count */
347static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn)
348{
349 return (ptn->size_r >= LP5562_PROGRAM_LENGTH ||
350 ptn->size_g >= LP5562_PROGRAM_LENGTH ||
351 ptn->size_b >= LP5562_PROGRAM_LENGTH);
352}
353
354static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode)
355{
356 struct lp55xx_predef_pattern *ptn;
357 int i;
358
359 if (mode == LP5562_PATTERN_OFF) {
360 lp5562_run_engine(chip, false);
361 return 0;
362 }
363
364 ptn = chip->pdata->patterns + (mode - 1);
365 if (!ptn || _is_pc_overflow(ptn)) {
366 dev_err(&chip->cl->dev, "invalid pattern data\n");
367 return -EINVAL;
368 }
369
370 lp5562_stop_engine(chip);
371
372 /* Set LED map as RGB */
373 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_RGB);
374
375 /* Load engines */
376 for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
377 chip->engine_idx = i;
378 lp5562_load_engine(chip);
379 }
380
381 /* Clear program registers */
382 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1, 0);
383 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1 + 1, 0);
384 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2, 0);
385 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2 + 1, 0);
386 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3, 0);
387 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3 + 1, 0);
388
389 /* Program engines */
390 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG1,
391 ptn->r, ptn->size_r);
392 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG2,
393 ptn->g, ptn->size_g);
394 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG3,
395 ptn->b, ptn->size_b);
396
397 /* Run engines */
398 lp5562_run_engine(chip, true);
399
400 return 0;
401}
402
403static ssize_t lp5562_store_pattern(struct device *dev,
404 struct device_attribute *attr,
405 const char *buf, size_t len)
406{
407 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
408 struct lp55xx_chip *chip = led->chip;
409 struct lp55xx_predef_pattern *ptn = chip->pdata->patterns;
410 int num_patterns = chip->pdata->num_patterns;
411 unsigned long mode;
412 int ret;
413
414 ret = kstrtoul(buf, 0, &mode);
415 if (ret)
416 return ret;
417
418 if (mode > num_patterns || !ptn)
419 return -EINVAL;
420
421 mutex_lock(&chip->lock);
422 ret = lp5562_run_predef_led_pattern(chip, mode);
423 mutex_unlock(&chip->lock);
424
425 if (ret)
426 return ret;
427
428 return len;
429}
430
431static ssize_t lp5562_store_engine_mux(struct device *dev,
432 struct device_attribute *attr,
433 const char *buf, size_t len)
434{
435 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
436 struct lp55xx_chip *chip = led->chip;
437 u8 mask;
438 u8 val;
439
440 /* LED map
441 * R ... Engine 1 (fixed)
442 * G ... Engine 2 (fixed)
443 * B ... Engine 3 (fixed)
444 * W ... Engine 1 or 2 or 3
445 */
446
447 if (sysfs_streq(buf, "RGB")) {
448 mask = LP5562_ENG_FOR_RGB_M;
449 val = LP5562_ENG_SEL_RGB;
450 } else if (sysfs_streq(buf, "W")) {
451 enum lp55xx_engine_index idx = chip->engine_idx;
452
453 mask = LP5562_ENG_FOR_W_M;
454 switch (idx) {
455 case LP55XX_ENGINE_1:
456 val = LP5562_ENG1_FOR_W;
457 break;
458 case LP55XX_ENGINE_2:
459 val = LP5562_ENG2_FOR_W;
460 break;
461 case LP55XX_ENGINE_3:
462 val = LP5562_ENG3_FOR_W;
463 break;
464 default:
465 return -EINVAL;
466 }
467
468 } else {
469 dev_err(dev, "choose RGB or W\n");
470 return -EINVAL;
471 }
472
473 mutex_lock(&chip->lock);
474 lp55xx_update_bits(chip, LP5562_REG_ENG_SEL, mask, val);
475 mutex_unlock(&chip->lock);
476
477 return len;
478}
479
480static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern);
481static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux);
482
483static struct attribute *lp5562_attributes[] = {
484 &dev_attr_led_pattern.attr,
485 &dev_attr_engine_mux.attr,
486 NULL,
487};
488
489static const struct attribute_group lp5562_group = {
490 .attrs = lp5562_attributes,
491};
492
493/* Chip specific configurations */
494static struct lp55xx_device_config lp5562_cfg = {
495 .max_channel = LP5562_MAX_LEDS,
496 .reset = {
497 .addr = LP5562_REG_RESET,
498 .val = LP5562_RESET,
499 },
500 .enable = {
501 .addr = LP5562_REG_ENABLE,
502 .val = LP5562_ENABLE_DEFAULT,
503 },
504 .post_init_device = lp5562_post_init_device,
505 .set_led_current = lp5562_set_led_current,
506 .brightness_work_fn = lp5562_led_brightness_work,
507 .run_engine = lp5562_run_engine,
508 .firmware_cb = lp5562_firmware_loaded,
509 .dev_attr_group = &lp5562_group,
510};
511
512static int lp5562_probe(struct i2c_client *client,
513 const struct i2c_device_id *id)
514{
515 int ret;
516 struct lp55xx_chip *chip;
517 struct lp55xx_led *led;
518 struct lp55xx_platform_data *pdata = client->dev.platform_data;
519
520 if (!pdata) {
521 dev_err(&client->dev, "no platform data\n");
522 return -EINVAL;
523 }
524
525 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
526 if (!chip)
527 return -ENOMEM;
528
529 led = devm_kzalloc(&client->dev,
530 sizeof(*led) * pdata->num_channels, GFP_KERNEL);
531 if (!led)
532 return -ENOMEM;
533
534 chip->cl = client;
535 chip->pdata = pdata;
536 chip->cfg = &lp5562_cfg;
537
538 mutex_init(&chip->lock);
539
540 i2c_set_clientdata(client, led);
541
542 ret = lp55xx_init_device(chip);
543 if (ret)
544 goto err_init;
545
546 ret = lp55xx_register_leds(led, chip);
547 if (ret)
548 goto err_register_leds;
549
550 ret = lp55xx_register_sysfs(chip);
551 if (ret) {
552 dev_err(&client->dev, "registering sysfs failed\n");
553 goto err_register_sysfs;
554 }
555
556 return 0;
557
558err_register_sysfs:
559 lp55xx_unregister_leds(led, chip);
560err_register_leds:
561 lp55xx_deinit_device(chip);
562err_init:
563 return ret;
564}
565
566static int lp5562_remove(struct i2c_client *client)
567{
568 struct lp55xx_led *led = i2c_get_clientdata(client);
569 struct lp55xx_chip *chip = led->chip;
570
571 lp5562_stop_engine(chip);
572
573 lp55xx_unregister_sysfs(chip);
574 lp55xx_unregister_leds(led, chip);
575 lp55xx_deinit_device(chip);
576
577 return 0;
578}
579
580static const struct i2c_device_id lp5562_id[] = {
581 { "lp5562", 0 },
582 { }
583};
584MODULE_DEVICE_TABLE(i2c, lp5562_id);
585
586static struct i2c_driver lp5562_driver = {
587 .driver = {
588 .name = "lp5562",
589 },
590 .probe = lp5562_probe,
591 .remove = lp5562_remove,
592 .id_table = lp5562_id,
593};
594
595module_i2c_driver(lp5562_driver);
596
597MODULE_DESCRIPTION("Texas Instruments LP5562 LED Driver");
598MODULE_AUTHOR("Milo Kim");
599MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index d9eb84157423..ba34199dc3d9 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * LP5521/LP5523/LP55231 Common Driver 2 * LP5521/LP5523/LP55231/LP5562 Common Driver
3 * 3 *
4 * Copyright 2012 Texas Instruments 4 * Copyright 2012 Texas Instruments
5 * 5 *
@@ -12,6 +12,7 @@
12 * Derived from leds-lp5521.c, leds-lp5523.c 12 * Derived from leds-lp5521.c, leds-lp5523.c
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/firmware.h> 17#include <linux/firmware.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
@@ -21,6 +22,9 @@
21 22
22#include "leds-lp55xx-common.h" 23#include "leds-lp55xx-common.h"
23 24
25/* External clock rate */
26#define LP55XX_CLK_32K 32768
27
24static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev) 28static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
25{ 29{
26 return container_of(cdev, struct lp55xx_led, cdev); 30 return container_of(cdev, struct lp55xx_led, cdev);
@@ -80,7 +84,7 @@ static ssize_t lp55xx_show_current(struct device *dev,
80{ 84{
81 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 85 struct lp55xx_led *led = dev_to_lp55xx_led(dev);
82 86
83 return sprintf(buf, "%d\n", led->led_current); 87 return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
84} 88}
85 89
86static ssize_t lp55xx_store_current(struct device *dev, 90static ssize_t lp55xx_store_current(struct device *dev,
@@ -113,7 +117,7 @@ static ssize_t lp55xx_show_max_current(struct device *dev,
113{ 117{
114 struct lp55xx_led *led = dev_to_lp55xx_led(dev); 118 struct lp55xx_led *led = dev_to_lp55xx_led(dev);
115 119
116 return sprintf(buf, "%d\n", led->max_current); 120 return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
117} 121}
118 122
119static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current, 123static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current,
@@ -357,6 +361,35 @@ int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
357} 361}
358EXPORT_SYMBOL_GPL(lp55xx_update_bits); 362EXPORT_SYMBOL_GPL(lp55xx_update_bits);
359 363
364bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
365{
366 struct clk *clk;
367 int err;
368
369 clk = devm_clk_get(&chip->cl->dev, "32k_clk");
370 if (IS_ERR(clk))
371 goto use_internal_clk;
372
373 err = clk_prepare_enable(clk);
374 if (err)
375 goto use_internal_clk;
376
377 if (clk_get_rate(clk) != LP55XX_CLK_32K) {
378 clk_disable_unprepare(clk);
379 goto use_internal_clk;
380 }
381
382 dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K);
383
384 chip->clk = clk;
385 return true;
386
387use_internal_clk:
388 dev_info(&chip->cl->dev, "internal clock used\n");
389 return false;
390}
391EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
392
360int lp55xx_init_device(struct lp55xx_chip *chip) 393int lp55xx_init_device(struct lp55xx_chip *chip)
361{ 394{
362 struct lp55xx_platform_data *pdata; 395 struct lp55xx_platform_data *pdata;
@@ -421,6 +454,9 @@ void lp55xx_deinit_device(struct lp55xx_chip *chip)
421{ 454{
422 struct lp55xx_platform_data *pdata = chip->pdata; 455 struct lp55xx_platform_data *pdata = chip->pdata;
423 456
457 if (chip->clk)
458 clk_disable_unprepare(chip->clk);
459
424 if (pdata->enable) 460 if (pdata->enable)
425 pdata->enable(0); 461 pdata->enable(0);
426 462
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index ece4761a1302..fa6a078bf547 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -83,6 +83,7 @@ struct lp55xx_device_config {
83 */ 83 */
84struct lp55xx_chip { 84struct lp55xx_chip {
85 struct i2c_client *cl; 85 struct i2c_client *cl;
86 struct clk *clk;
86 struct lp55xx_platform_data *pdata; 87 struct lp55xx_platform_data *pdata;
87 struct mutex lock; /* lock for user-space interface */ 88 struct mutex lock; /* lock for user-space interface */
88 int num_leds; 89 int num_leds;
@@ -117,6 +118,9 @@ extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val);
117extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, 118extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,
118 u8 mask, u8 val); 119 u8 mask, u8 val);
119 120
121/* external clock detection */
122extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
123
120/* common device init/deinit functions */ 124/* common device init/deinit functions */
121extern int lp55xx_init_device(struct lp55xx_chip *chip); 125extern int lp55xx_init_device(struct lp55xx_chip *chip);
122extern void lp55xx_deinit_device(struct lp55xx_chip *chip); 126extern void lp55xx_deinit_device(struct lp55xx_chip *chip);
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index c9b9e1fec587..ca48a7d5502d 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -106,8 +106,9 @@ static int create_lt3593_led(const struct gpio_led *template,
106 if (!template->retain_state_suspended) 106 if (!template->retain_state_suspended)
107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
108 108
109 ret = devm_gpio_request_one(parent, template->gpio, 109 ret = devm_gpio_request_one(parent, template->gpio, state ?
110 GPIOF_DIR_OUT | state, template->name); 110 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
111 template->name);
111 if (ret < 0) 112 if (ret < 0)
112 return ret; 113 return ret;
113 114
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index d978171c25b4..70137b1eecf5 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -193,7 +193,8 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
193 enum ns2_led_modes mode; 193 enum ns2_led_modes mode;
194 194
195 ret = devm_gpio_request_one(&pdev->dev, template->cmd, 195 ret = devm_gpio_request_one(&pdev->dev, template->cmd,
196 GPIOF_DIR_OUT | gpio_get_value(template->cmd), 196 gpio_get_value(template->cmd) ?
197 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
197 template->name); 198 template->name);
198 if (ret) { 199 if (ret) {
199 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n", 200 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n",
@@ -202,7 +203,8 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
202 } 203 }
203 204
204 ret = devm_gpio_request_one(&pdev->dev, template->slow, 205 ret = devm_gpio_request_one(&pdev->dev, template->slow,
205 GPIOF_DIR_OUT | gpio_get_value(template->slow), 206 gpio_get_value(template->slow) ?
207 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
206 template->name); 208 template->name);
207 if (ret) { 209 if (ret) {
208 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n", 210 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n",
@@ -306,10 +308,21 @@ static const struct of_device_id of_ns2_leds_match[] = {
306}; 308};
307#endif /* CONFIG_OF_GPIO */ 309#endif /* CONFIG_OF_GPIO */
308 310
311struct ns2_led_priv {
312 int num_leds;
313 struct ns2_led_data leds_data[];
314};
315
316static inline int sizeof_ns2_led_priv(int num_leds)
317{
318 return sizeof(struct ns2_led_priv) +
319 (sizeof(struct ns2_led_data) * num_leds);
320}
321
309static int ns2_led_probe(struct platform_device *pdev) 322static int ns2_led_probe(struct platform_device *pdev)
310{ 323{
311 struct ns2_led_platform_data *pdata = pdev->dev.platform_data; 324 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
312 struct ns2_led_data *leds_data; 325 struct ns2_led_priv *priv;
313 int i; 326 int i;
314 int ret; 327 int ret;
315 328
@@ -330,21 +343,23 @@ static int ns2_led_probe(struct platform_device *pdev)
330 return -EINVAL; 343 return -EINVAL;
331#endif /* CONFIG_OF_GPIO */ 344#endif /* CONFIG_OF_GPIO */
332 345
333 leds_data = devm_kzalloc(&pdev->dev, sizeof(struct ns2_led_data) * 346 priv = devm_kzalloc(&pdev->dev,
334 pdata->num_leds, GFP_KERNEL); 347 sizeof_ns2_led_priv(pdata->num_leds), GFP_KERNEL);
335 if (!leds_data) 348 if (!priv)
336 return -ENOMEM; 349 return -ENOMEM;
350 priv->num_leds = pdata->num_leds;
337 351
338 for (i = 0; i < pdata->num_leds; i++) { 352 for (i = 0; i < priv->num_leds; i++) {
339 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]); 353 ret = create_ns2_led(pdev, &priv->leds_data[i],
354 &pdata->leds[i]);
340 if (ret < 0) { 355 if (ret < 0) {
341 for (i = i - 1; i >= 0; i--) 356 for (i = i - 1; i >= 0; i--)
342 delete_ns2_led(&leds_data[i]); 357 delete_ns2_led(&priv->leds_data[i]);
343 return ret; 358 return ret;
344 } 359 }
345 } 360 }
346 361
347 platform_set_drvdata(pdev, leds_data); 362 platform_set_drvdata(pdev, priv);
348 363
349 return 0; 364 return 0;
350} 365}
@@ -352,13 +367,12 @@ static int ns2_led_probe(struct platform_device *pdev)
352static int ns2_led_remove(struct platform_device *pdev) 367static int ns2_led_remove(struct platform_device *pdev)
353{ 368{
354 int i; 369 int i;
355 struct ns2_led_platform_data *pdata = pdev->dev.platform_data; 370 struct ns2_led_priv *priv;
356 struct ns2_led_data *leds_data;
357 371
358 leds_data = platform_get_drvdata(pdev); 372 priv = platform_get_drvdata(pdev);
359 373
360 for (i = 0; i < pdata->num_leds; i++) 374 for (i = 0; i < priv->num_leds; i++)
361 delete_ns2_led(&leds_data[i]); 375 delete_ns2_led(&priv->leds_data[i]);
362 376
363 platform_set_drvdata(pdev, NULL); 377 platform_set_drvdata(pdev, NULL);
364 378
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index a1ea5f6a8d39..faf52c005e8c 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -23,12 +23,16 @@
23#include <linux/pwm.h> 23#include <linux/pwm.h>
24#include <linux/leds_pwm.h> 24#include <linux/leds_pwm.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/workqueue.h>
26 27
27struct led_pwm_data { 28struct led_pwm_data {
28 struct led_classdev cdev; 29 struct led_classdev cdev;
29 struct pwm_device *pwm; 30 struct pwm_device *pwm;
31 struct work_struct work;
30 unsigned int active_low; 32 unsigned int active_low;
31 unsigned int period; 33 unsigned int period;
34 int duty;
35 bool can_sleep;
32}; 36};
33 37
34struct led_pwm_priv { 38struct led_pwm_priv {
@@ -36,6 +40,26 @@ struct led_pwm_priv {
36 struct led_pwm_data leds[0]; 40 struct led_pwm_data leds[0];
37}; 41};
38 42
43static void __led_pwm_set(struct led_pwm_data *led_dat)
44{
45 int new_duty = led_dat->duty;
46
47 pwm_config(led_dat->pwm, new_duty, led_dat->period);
48
49 if (new_duty == 0)
50 pwm_disable(led_dat->pwm);
51 else
52 pwm_enable(led_dat->pwm);
53}
54
55static void led_pwm_work(struct work_struct *work)
56{
57 struct led_pwm_data *led_dat =
58 container_of(work, struct led_pwm_data, work);
59
60 __led_pwm_set(led_dat);
61}
62
39static void led_pwm_set(struct led_classdev *led_cdev, 63static void led_pwm_set(struct led_classdev *led_cdev,
40 enum led_brightness brightness) 64 enum led_brightness brightness)
41{ 65{
@@ -44,13 +68,12 @@ static void led_pwm_set(struct led_classdev *led_cdev,
44 unsigned int max = led_dat->cdev.max_brightness; 68 unsigned int max = led_dat->cdev.max_brightness;
45 unsigned int period = led_dat->period; 69 unsigned int period = led_dat->period;
46 70
47 if (brightness == 0) { 71 led_dat->duty = brightness * period / max;
48 pwm_config(led_dat->pwm, 0, period); 72
49 pwm_disable(led_dat->pwm); 73 if (led_dat->can_sleep)
50 } else { 74 schedule_work(&led_dat->work);
51 pwm_config(led_dat->pwm, brightness * period / max, period); 75 else
52 pwm_enable(led_dat->pwm); 76 __led_pwm_set(led_dat);
53 }
54} 77}
55 78
56static inline size_t sizeof_pwm_leds_priv(int num_leds) 79static inline size_t sizeof_pwm_leds_priv(int num_leds)
@@ -100,6 +123,10 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
100 led_dat->cdev.brightness = LED_OFF; 123 led_dat->cdev.brightness = LED_OFF;
101 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 124 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
102 125
126 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
127 if (led_dat->can_sleep)
128 INIT_WORK(&led_dat->work, led_pwm_work);
129
103 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 130 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
104 if (ret < 0) { 131 if (ret < 0) {
105 dev_err(&pdev->dev, "failed to register for %s\n", 132 dev_err(&pdev->dev, "failed to register for %s\n",
@@ -153,6 +180,10 @@ static int led_pwm_probe(struct platform_device *pdev)
153 led_dat->cdev.max_brightness = cur_led->max_brightness; 180 led_dat->cdev.max_brightness = cur_led->max_brightness;
154 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 181 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
155 182
183 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
184 if (led_dat->can_sleep)
185 INIT_WORK(&led_dat->work, led_pwm_work);
186
156 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 187 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
157 if (ret < 0) 188 if (ret < 0)
158 goto err; 189 goto err;
@@ -180,8 +211,11 @@ static int led_pwm_remove(struct platform_device *pdev)
180 struct led_pwm_priv *priv = platform_get_drvdata(pdev); 211 struct led_pwm_priv *priv = platform_get_drvdata(pdev);
181 int i; 212 int i;
182 213
183 for (i = 0; i < priv->num_leds; i++) 214 for (i = 0; i < priv->num_leds; i++) {
184 led_classdev_unregister(&priv->leds[i].cdev); 215 led_classdev_unregister(&priv->leds[i].cdev);
216 if (priv->leds[i].can_sleep)
217 cancel_work_sync(&priv->leds[i].work);
218 }
185 219
186 return 0; 220 return 0;
187} 221}
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
index d3c2b7e68fbc..9483f1c1078d 100644
--- a/drivers/leds/leds-renesas-tpu.c
+++ b/drivers/leds/leds-renesas-tpu.c
@@ -205,7 +205,8 @@ static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state,
205 gpio_free(cfg->pin_gpio_fn); 205 gpio_free(cfg->pin_gpio_fn);
206 206
207 if (new_state == R_TPU_PIN_GPIO) 207 if (new_state == R_TPU_PIN_GPIO)
208 gpio_request_one(cfg->pin_gpio, GPIOF_DIR_OUT | !!brightness, 208 gpio_request_one(cfg->pin_gpio, !!brightness ?
209 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
209 cfg->name); 210 cfg->name);
210 211
211 if (new_state == R_TPU_PIN_GPIO_FN) 212 if (new_state == R_TPU_PIN_GPIO_FN)
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index 070ba0741b21..98fe021ba276 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -85,6 +85,7 @@
85#include <linux/gpio.h> 85#include <linux/gpio.h>
86#include <linux/workqueue.h> 86#include <linux/workqueue.h>
87#include <linux/leds-tca6507.h> 87#include <linux/leds-tca6507.h>
88#include <linux/of.h>
88 89
89/* LED select registers determine the source that drives LED outputs */ 90/* LED select registers determine the source that drives LED outputs */
90#define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */ 91#define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */
@@ -724,7 +725,6 @@ tca6507_led_dt_init(struct i2c_client *client)
724 return ERR_PTR(-ENODEV); 725 return ERR_PTR(-ENODEV);
725} 726}
726 727
727#define of_tca6507_leds_match NULL
728#endif 728#endif
729 729
730static int tca6507_probe(struct i2c_client *client, 730static int tca6507_probe(struct i2c_client *client,
@@ -813,7 +813,7 @@ static struct i2c_driver tca6507_driver = {
813 .driver = { 813 .driver = {
814 .name = "leds-tca6507", 814 .name = "leds-tca6507",
815 .owner = THIS_MODULE, 815 .owner = THIS_MODULE,
816 .of_match_table = of_tca6507_leds_match, 816 .of_match_table = of_match_ptr(of_tca6507_leds_match),
817 }, 817 },
818 .probe = tca6507_probe, 818 .probe = tca6507_probe,
819 .remove = tca6507_remove, 819 .remove = tca6507_remove,
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index ed15157c8f6c..8a181d56602d 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -129,7 +129,10 @@ static void wm8350_led_disable(struct wm8350_led *led)
129 ret = regulator_disable(led->isink); 129 ret = regulator_disable(led->isink);
130 if (ret != 0) { 130 if (ret != 0) {
131 dev_err(led->cdev.dev, "Failed to disable ISINK: %d\n", ret); 131 dev_err(led->cdev.dev, "Failed to disable ISINK: %d\n", ret);
132 regulator_enable(led->dcdc); 132 ret = regulator_enable(led->dcdc);
133 if (ret != 0)
134 dev_err(led->cdev.dev, "Failed to reenable DCDC: %d\n",
135 ret);
133 return; 136 return;
134 } 137 }
135 138
diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig
new file mode 100644
index 000000000000..49794b47b51c
--- /dev/null
+++ b/drivers/leds/trigger/Kconfig
@@ -0,0 +1,111 @@
1menuconfig LEDS_TRIGGERS
2 bool "LED Trigger support"
3 depends on LEDS_CLASS
4 help
5 This option enables trigger support for the leds class.
6 These triggers allow kernel events to drive the LEDs and can
7 be configured via sysfs. If unsure, say Y.
8
9if LEDS_TRIGGERS
10
11config LEDS_TRIGGER_TIMER
12 tristate "LED Timer Trigger"
13 depends on LEDS_TRIGGERS
14 help
15 This allows LEDs to be controlled by a programmable timer
16 via sysfs. Some LED hardware can be programmed to start
17 blinking the LED without any further software interaction.
18 For more details read Documentation/leds/leds-class.txt.
19
20 If unsure, say Y.
21
22config LEDS_TRIGGER_ONESHOT
23 tristate "LED One-shot Trigger"
24 depends on LEDS_TRIGGERS
25 help
26 This allows LEDs to blink in one-shot pulses with parameters
27 controlled via sysfs. It's useful to notify the user on
28 sporadic events, when there are no clear begin and end trap points,
29 or on dense events, where this blinks the LED at constant rate if
30 rearmed continuously.
31
32 It also shows how to use the led_blink_set_oneshot() function.
33
34 If unsure, say Y.
35
36config LEDS_TRIGGER_IDE_DISK
37 bool "LED IDE Disk Trigger"
38 depends on IDE_GD_ATA
39 depends on LEDS_TRIGGERS
40 help
41 This allows LEDs to be controlled by IDE disk activity.
42 If unsure, say Y.
43
44config LEDS_TRIGGER_HEARTBEAT
45 tristate "LED Heartbeat Trigger"
46 depends on LEDS_TRIGGERS
47 help
48 This allows LEDs to be controlled by a CPU load average.
49 The flash frequency is a hyperbolic function of the 1-minute
50 load average.
51 If unsure, say Y.
52
53config LEDS_TRIGGER_BACKLIGHT
54 tristate "LED backlight Trigger"
55 depends on LEDS_TRIGGERS
56 help
57 This allows LEDs to be controlled as a backlight device: they
58 turn off and on when the display is blanked and unblanked.
59
60 If unsure, say N.
61
62config LEDS_TRIGGER_CPU
63 bool "LED CPU Trigger"
64 depends on LEDS_TRIGGERS
65 help
66 This allows LEDs to be controlled by active CPUs. This shows
67 the active CPUs across an array of LEDs so you can see which
68 CPUs are active on the system at any given moment.
69
70 If unsure, say N.
71
72config LEDS_TRIGGER_GPIO
73 tristate "LED GPIO Trigger"
74 depends on LEDS_TRIGGERS
75 depends on GPIOLIB
76 help
77 This allows LEDs to be controlled by gpio events. It's good
78 when using gpios as switches and triggering the needed LEDs
79 from there. One use case is n810's keypad LEDs that could
80 be triggered by this trigger when user slides up to show
81 keypad.
82
83 If unsure, say N.
84
85config LEDS_TRIGGER_DEFAULT_ON
86 tristate "LED Default ON Trigger"
87 depends on LEDS_TRIGGERS
88 help
89 This allows LEDs to be initialised in the ON state.
90 If unsure, say Y.
91
92comment "iptables trigger is under Netfilter config (LED target)"
93 depends on LEDS_TRIGGERS
94
95config LEDS_TRIGGER_TRANSIENT
96 tristate "LED Transient Trigger"
97 depends on LEDS_TRIGGERS
98 help
99 This allows one time activation of a transient state on
100 GPIO/PWM based hardware.
101 If unsure, say Y.
102
103config LEDS_TRIGGER_CAMERA
104 tristate "LED Camera Flash/Torch Trigger"
105 depends on LEDS_TRIGGERS
106 help
107 This allows LEDs to be controlled as a camera flash/torch device.
108 This enables direct flash/torch on/off by the driver, kernel space.
109 If unsure, say Y.
110
111endif # LEDS_TRIGGERS
diff --git a/drivers/leds/trigger/Makefile b/drivers/leds/trigger/Makefile
new file mode 100644
index 000000000000..1abf48dacf7e
--- /dev/null
+++ b/drivers/leds/trigger/Makefile
@@ -0,0 +1,10 @@
1obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
2obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
3obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
4obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
5obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
6obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
7obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
8obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
9obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
10obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
index 027a2b15d7d8..3c9c88a07eb8 100644
--- a/drivers/leds/ledtrig-backlight.c
+++ b/drivers/leds/trigger/ledtrig-backlight.c
@@ -16,7 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/fb.h> 17#include <linux/fb.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include "leds.h" 19#include "../leds.h"
20 20
21#define BLANK 1 21#define BLANK 1
22#define UNBLANK 0 22#define UNBLANK 0
diff --git a/drivers/leds/trigger/ledtrig-camera.c b/drivers/leds/trigger/ledtrig-camera.c
new file mode 100644
index 000000000000..9bd73a8bad5c
--- /dev/null
+++ b/drivers/leds/trigger/ledtrig-camera.c
@@ -0,0 +1,57 @@
1/*
2 * Camera Flash and Torch On/Off Trigger
3 *
4 * based on ledtrig-ide-disk.c
5 *
6 * Copyright 2013 Texas Instruments
7 *
8 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/leds.h>
20
21DEFINE_LED_TRIGGER(ledtrig_flash);
22DEFINE_LED_TRIGGER(ledtrig_torch);
23
24void ledtrig_flash_ctrl(bool on)
25{
26 enum led_brightness brt = on ? LED_FULL : LED_OFF;
27
28 led_trigger_event(ledtrig_flash, brt);
29}
30EXPORT_SYMBOL_GPL(ledtrig_flash_ctrl);
31
32void ledtrig_torch_ctrl(bool on)
33{
34 enum led_brightness brt = on ? LED_FULL : LED_OFF;
35
36 led_trigger_event(ledtrig_torch, brt);
37}
38EXPORT_SYMBOL_GPL(ledtrig_torch_ctrl);
39
40static int __init ledtrig_camera_init(void)
41{
42 led_trigger_register_simple("flash", &ledtrig_flash);
43 led_trigger_register_simple("torch", &ledtrig_torch);
44 return 0;
45}
46module_init(ledtrig_camera_init);
47
48static void __exit ledtrig_camera_exit(void)
49{
50 led_trigger_unregister_simple(ledtrig_torch);
51 led_trigger_unregister_simple(ledtrig_flash);
52}
53module_exit(ledtrig_camera_exit);
54
55MODULE_DESCRIPTION("LED Trigger for Camera Flash/Torch Control");
56MODULE_AUTHOR("Milo Kim");
57MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c
index 4239b3955ff0..118335eccc56 100644
--- a/drivers/leds/ledtrig-cpu.c
+++ b/drivers/leds/trigger/ledtrig-cpu.c
@@ -26,7 +26,7 @@
26#include <linux/percpu.h> 26#include <linux/percpu.h>
27#include <linux/syscore_ops.h> 27#include <linux/syscore_ops.h>
28#include <linux/rwsem.h> 28#include <linux/rwsem.h>
29#include "leds.h" 29#include "../leds.h"
30 30
31#define MAX_NAME_LEN 8 31#define MAX_NAME_LEN 8
32 32
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/trigger/ledtrig-default-on.c
index eac1f1b1adac..81a91be8e18d 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/trigger/ledtrig-default-on.c
@@ -15,7 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include "leds.h" 18#include "../leds.h"
19 19
20static void defon_trig_activate(struct led_classdev *led_cdev) 20static void defon_trig_activate(struct led_classdev *led_cdev)
21{ 21{
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c
index 72e3ebfc281f..35812e3a37f2 100644
--- a/drivers/leds/ledtrig-gpio.c
+++ b/drivers/leds/trigger/ledtrig-gpio.c
@@ -17,7 +17,7 @@
17#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include "leds.h" 20#include "../leds.h"
21 21
22struct gpio_trig_data { 22struct gpio_trig_data {
23 struct led_classdev *led; 23 struct led_classdev *led;
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c
index 1edc7463ce83..5c8464a33172 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/trigger/ledtrig-heartbeat.c
@@ -19,7 +19,7 @@
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/leds.h> 20#include <linux/leds.h>
21#include <linux/reboot.h> 21#include <linux/reboot.h>
22#include "leds.h" 22#include "../leds.h"
23 23
24static int panic_heartbeats; 24static int panic_heartbeats;
25 25
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/trigger/ledtrig-ide-disk.c
index 2cd7c0cf5924..2cd7c0cf5924 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/trigger/ledtrig-ide-disk.c
diff --git a/drivers/leds/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c
index 2c029aa5c4f1..cb4c7466692a 100644
--- a/drivers/leds/ledtrig-oneshot.c
+++ b/drivers/leds/trigger/ledtrig-oneshot.c
@@ -18,7 +18,7 @@
18#include <linux/ctype.h> 18#include <linux/ctype.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/leds.h> 20#include <linux/leds.h>
21#include "leds.h" 21#include "../leds.h"
22 22
23#define DEFAULT_DELAY 100 23#define DEFAULT_DELAY 100
24 24
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/trigger/ledtrig-timer.c
index f774d0592204..8d09327b5719 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/trigger/ledtrig-timer.c
@@ -17,7 +17,6 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/ctype.h> 18#include <linux/ctype.h>
19#include <linux/leds.h> 19#include <linux/leds.h>
20#include "leds.h"
21 20
22static ssize_t led_delay_on_show(struct device *dev, 21static ssize_t led_delay_on_show(struct device *dev,
23 struct device_attribute *attr, char *buf) 22 struct device_attribute *attr, char *buf)
diff --git a/drivers/leds/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c
index 398f1042c43e..e5abc00bb00c 100644
--- a/drivers/leds/ledtrig-transient.c
+++ b/drivers/leds/trigger/ledtrig-transient.c
@@ -25,7 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/timer.h> 26#include <linux/timer.h>
27#include <linux/leds.h> 27#include <linux/leds.h>
28#include "leds.h" 28#include "../leds.h"
29 29
30struct transient_trig_data { 30struct transient_trig_data {
31 int activate; 31 int activate;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 0d9b5eed714e..0287ab296689 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -142,6 +142,10 @@ extern void led_set_brightness(struct led_classdev *led_cdev,
142/* 142/*
143 * LED Triggers 143 * LED Triggers
144 */ 144 */
145/* Registration functions for simple triggers */
146#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x;
147#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x;
148
145#ifdef CONFIG_LEDS_TRIGGERS 149#ifdef CONFIG_LEDS_TRIGGERS
146 150
147#define TRIG_NAME_MAX 50 151#define TRIG_NAME_MAX 50
@@ -164,9 +168,6 @@ struct led_trigger {
164extern int led_trigger_register(struct led_trigger *trigger); 168extern int led_trigger_register(struct led_trigger *trigger);
165extern void led_trigger_unregister(struct led_trigger *trigger); 169extern void led_trigger_unregister(struct led_trigger *trigger);
166 170
167/* Registration functions for simple triggers */
168#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x;
169#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x;
170extern void led_trigger_register_simple(const char *name, 171extern void led_trigger_register_simple(const char *name,
171 struct led_trigger **trigger); 172 struct led_trigger **trigger);
172extern void led_trigger_unregister_simple(struct led_trigger *trigger); 173extern void led_trigger_unregister_simple(struct led_trigger *trigger);
@@ -199,20 +200,30 @@ extern void led_trigger_rename_static(const char *name,
199 200
200#else 201#else
201 202
202/* Triggers aren't active - null macros */ 203/* Trigger has no members */
203#define DEFINE_LED_TRIGGER(x) 204struct led_trigger {};
204#define DEFINE_LED_TRIGGER_GLOBAL(x)
205#define led_trigger_register_simple(x, y) do {} while(0)
206#define led_trigger_unregister_simple(x) do {} while(0)
207#define led_trigger_event(x, y) do {} while(0)
208 205
209#endif 206/* Trigger inline empty functions */
207static inline void led_trigger_register_simple(const char *name,
208 struct led_trigger **trigger) {}
209static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
210static inline void led_trigger_event(struct led_trigger *trigger,
211 enum led_brightness event) {}
212#endif /* CONFIG_LEDS_TRIGGERS */
210 213
211/* Trigger specific functions */ 214/* Trigger specific functions */
212#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK 215#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
213extern void ledtrig_ide_activity(void); 216extern void ledtrig_ide_activity(void);
214#else 217#else
215#define ledtrig_ide_activity() do {} while(0) 218static inline void ledtrig_ide_activity(void) {}
219#endif
220
221#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE)
222extern void ledtrig_flash_ctrl(bool on);
223extern void ledtrig_torch_ctrl(bool on);
224#else
225static inline void ledtrig_flash_ctrl(bool on) {}
226static inline void ledtrig_torch_ctrl(bool on) {}
216#endif 227#endif
217 228
218/* 229/*
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 8873e8349597..e326ae2882a0 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -342,9 +342,7 @@ struct mmc_host {
342 342
343 mmc_pm_flag_t pm_flags; /* requested pm features */ 343 mmc_pm_flag_t pm_flags; /* requested pm features */
344 344
345#ifdef CONFIG_LEDS_TRIGGERS
346 struct led_trigger *led; /* activity led */ 345 struct led_trigger *led; /* activity led */
347#endif
348 346
349#ifdef CONFIG_REGULATOR 347#ifdef CONFIG_REGULATOR
350 bool regulator_enabled; /* regulator state */ 348 bool regulator_enabled; /* regulator state */
diff --git a/include/linux/platform_data/leds-lp55xx.h b/include/linux/platform_data/leds-lp55xx.h
index 1509570d5a3f..202e290faea8 100644
--- a/include/linux/platform_data/leds-lp55xx.h
+++ b/include/linux/platform_data/leds-lp55xx.h
@@ -20,18 +20,6 @@
20#define LP55XX_CLOCK_INT 1 20#define LP55XX_CLOCK_INT 1
21#define LP55XX_CLOCK_EXT 2 21#define LP55XX_CLOCK_EXT 2
22 22
23/* Bits in LP5521 CONFIG register. 'update_config' in lp55xx_platform_data */
24#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
25#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
26#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */
27#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */
28#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */
29#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */
30#define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */
31#define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */
32#define LP5521_CLK_INT 1 /* Internal clock */
33#define LP5521_CLK_AUTO 2 /* Automatic clock selection */
34
35struct lp55xx_led_config { 23struct lp55xx_led_config {
36 const char *name; 24 const char *name;
37 u8 chan_nr; 25 u8 chan_nr;
@@ -40,9 +28,9 @@ struct lp55xx_led_config {
40}; 28};
41 29
42struct lp55xx_predef_pattern { 30struct lp55xx_predef_pattern {
43 u8 *r; 31 const u8 *r;
44 u8 *g; 32 const u8 *g;
45 u8 *b; 33 const u8 *b;
46 u8 size_r; 34 u8 size_r;
47 u8 size_g; 35 u8 size_g;
48 u8 size_b; 36 u8 size_b;
@@ -79,9 +67,6 @@ struct lp55xx_platform_data {
79 /* Predefined pattern data */ 67 /* Predefined pattern data */
80 struct lp55xx_predef_pattern *patterns; 68 struct lp55xx_predef_pattern *patterns;
81 unsigned int num_patterns; 69 unsigned int num_patterns;
82
83 /* _CONFIG register */
84 u8 update_config;
85}; 70};
86 71
87#endif /* _LEDS_LP55XX_H */ 72#endif /* _LEDS_LP55XX_H */