History

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

Linus Torvalds committed 13 years ago

Commit 2b697032 parents 30c67e9 df92d5f36 files · +1149 −220Browse files

Unified · Split

36 files
  1. Documentation/leds/00-INDEX +2 −0
  2. Documentation/leds/leds-lp5521.txt +0 −19
  3. Documentation/leds/leds-lp5562.txt +120 −0
  4. Documentation/leds/leds-lp55xx.txt +45 −1
  5. drivers/leds/Kconfig +13 −102
  6. drivers/leds/Makefile +2 −9
  7. drivers/leds/leds-asic3.c +3 −4
  8. drivers/leds/leds-atmel-pwm.c +2 −2
  9. drivers/leds/leds-bd2802.c +5 −9
  10. drivers/leds/leds-lm355x.c +2 −0
  11. drivers/leds/leds-lm3642.c +2 −0
  12. drivers/leds/leds-lp5521.c +19 −3
  13. drivers/leds/leds-lp5562.c +599 −0
  14. drivers/leds/leds-lp55xx-common.c +39 −3
  15. drivers/leds/leds-lp55xx-common.h +4 −0
  16. drivers/leds/leds-lt3593.c +3 −2
  17. drivers/leds/leds-ns2.c +29 −15
  18. drivers/leds/leds-pwm.c +42 −8
  19. drivers/leds/leds-renesas-tpu.c +2 −1
  20. drivers/leds/leds-tca6507.c +2 −2
  21. drivers/leds/leds-wm8350.c +4 −1
  22. drivers/leds/trigger/Kconfig +111 −0
  23. drivers/leds/trigger/Makefile +10 −0
  24. drivers/leds/trigger/ledtrig-backlight.c +1 −1
  25. drivers/leds/trigger/ledtrig-camera.c +57 −0
  26. drivers/leds/trigger/ledtrig-cpu.c +1 −1
  27. drivers/leds/trigger/ledtrig-default-on.c +1 −1
  28. drivers/leds/trigger/ledtrig-gpio.c +1 −1
  29. drivers/leds/trigger/ledtrig-heartbeat.c +1 −1
  30. drivers/leds/trigger/ledtrig-ide-disk.c +0 −0
  31. drivers/leds/trigger/ledtrig-oneshot.c +1 −1
  32. drivers/leds/trigger/ledtrig-timer.c +0 −1
  33. drivers/leds/trigger/ledtrig-transient.c +1 −1
  34. include/linux/leds.h +22 −11
  35. include/linux/mmc/host.h +0 −2
  36. include/linux/platform_data/leds-lp55xx.h +3 −18
Documentation/leds/00-INDEX+2−0
@@ -6,6 +6,8 @@ leds-lp5521.txt · 5 unmodified lines
66 - notes on how to use the leds-lp5521 driver.
77 leds-lp5523.txt
88 - notes on how to use the leds-lp5523 driver.
9+leds-lp5562.txt
10+ - notes on how to use the leds-lp5562 driver.
911 leds-lp55xx.txt
1012 - description about lp55xx common driver.
1113 leds-lm3556.txt
Documentation/leds/leds-lp5521.txt+0−19
@@ -81,22 +81,3 @@ static struct lp55xx_platform_data lp5521_platform_data = { · 80 unmodified lines
8181
8282 If the current is set to 0 in the platform data, that channel is
8383 disabled and it is not visible in the sysfs.
84−
85−The 'update_config' : CONFIG register (ADDR 08h)
86−This value is platform-specific data.
87−If 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−
91−example 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−
97−static 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−};
Documentation/leds/leds-lp5562.txt+120−0
@@ -0,0 +1,120 @@
1+Kernel driver for LP5562
2+========================
3+
4+* TI LP5562 LED Driver
5+
6+Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7+
8+Description
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+
17+Device 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+
33+How 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+
56+How to load the predefined patterns
57+
58+ Please refer to 'leds-lp55xx.txt"
59+
60+Setting 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+
67+To configure the platform specific data, lp55xx_platform_data structure is used.
68+
69+static 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+
96+static int lp5562_setup(void)
97+{
98+ /* setup HW resources */
99+}
100+
101+static void lp5562_release(void)
102+{
103+ /* Release HW resources */
104+}
105+
106+static void lp5562_enable(bool state)
107+{
108+ /* Control of chip enable signal */
109+}
110+
111+static 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+
119+If the current is set to 0 in the platform data, that channel is
120+disabled and it is not visible in the sysfs.
Documentation/leds/leds-lp55xx.txt+45−1
@@ -5,7 +5,7 @@ Authors: Milo(Woogyom) Kim <milo.kim@ti.com> · 4 unmodified lines
55
66 Description
77 -----------
8−LP5521, LP5523/55231 have common features as below.
8+LP5521, LP5523/55231 and LP5562 have common features as below.
99
1010 Register access via the I2C
1111 Device initialization/deinitialization
@@ -116,3 +116,47 @@ To support this, 'run_engine' and 'firmware_cb' are configurable in each driver. · 104 unmodified lines
116116 run_engine : Control the selected engine
117117 firmware_cb : The callback function after loading the firmware is done.
118118 Chip specific commands for loading and updating program memory.
119+
120+( Predefined pattern data )
121+
122+Without the firmware interface, LP55xx driver provides another method for
123+loading a LED pattern. That is 'predefined' pattern.
124+A predefined pattern is defined in the platform data and load it(or them)
125+via the sysfs if needed.
126+To use the predefined pattern concept, 'patterns' and 'num_patterns' should be
127+configured.
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+
156+Then, 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+
161+To stop running pattern,
162+ echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
drivers/leds/Kconfig+13−102
@@ -194,8 +194,8 @@ config LEDS_LP3944 · 193 unmodified lines
194194 module will be called leds-lp3944.
195195
196196 config LEDS_LP55XX_COMMON
197− tristate "Common Driver for TI/National LP5521 and LP5523/55231"
198− depends on LEDS_LP5521 || LEDS_LP5523
197+ tristate "Common Driver for TI/National LP5521, LP5523/55231 and LP5562"
198+ depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562
199199 select FW_LOADER
200200 help
201201 This option supports common operations for LP5521 and LP5523/55231
@@ -222,6 +222,16 @@ config LEDS_LP5523 · 20 unmodified lines
222222 Driver provides direct control via LED class and interface for
223223 programming the engines.
224224
225+config 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+
225235 config LEDS_LP8788
226236 tristate "LED support for the TI LP8788 PMIC"
227237 depends on LEDS_CLASS
@@ -469,106 +479,7 @@ config LEDS_BLINKM · 241 unmodified lines
469479 This option enables support for the BlinkM RGB LED connected
470480 through I2C. Say Y to enable support for the BlinkM LED.
471481
472−config 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−
480482 comment "LED Triggers"
481−
482−config 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−
493−config 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−
507−config 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−
515−config 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−
524−config 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−
533−config 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−
543−config 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−
556−config 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−
563−comment "iptables trigger is under Netfilter config (LED target)"
564− depends on LEDS_TRIGGERS
565−
566−config 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.
483+source "drivers/leds/trigger/Kconfig"
573484
574485 endif # NEW_LEDS
drivers/leds/Makefile+2−9
@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o · 25 unmodified lines
2626 obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o
2727 obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
2828 obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
29+obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o
2930 obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
3031 obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
3132 obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
@@ -57,12 +58,4 @@ obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o · 25 unmodified lines
5758 obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
5859
5960 # LED Triggers
60−obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
61−obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
62−obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
63−obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
64−obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
65−obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
66−obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
67−obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
68−obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
61+obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
drivers/leds/leds-asic3.c+3−4
@@ -134,6 +134,7 @@ static int asic3_led_remove(struct platform_device *pdev) · 133 unmodified lines
134134 return mfd_cell_disable(pdev);
135135 }
136136
137+#ifdef CONFIG_PM_SLEEP
137138 static int asic3_led_suspend(struct device *dev)
138139 {
139140 struct platform_device *pdev = to_platform_device(dev);
@@ -159,11 +160,9 @@ static int asic3_led_resume(struct device *dev) · 19 unmodified lines
159160
160161 return ret;
161162 }
163+#endif
162164
163−static const struct dev_pm_ops asic3_led_pm_ops = {
164− .suspend = asic3_led_suspend,
165− .resume = asic3_led_resume,
166−};
165+static SIMPLE_DEV_PM_OPS(asic3_led_pm_ops, asic3_led_suspend, asic3_led_resume);
167166
168167 static struct platform_driver asic3_led_driver = {
169168 .probe = asic3_led_probe,
drivers/leds/leds-atmel-pwm.c+2−2
@@ -113,7 +113,7 @@ err: · 112 unmodified lines
113113 return status;
114114 }
115115
116−static int __exit pwmled_remove(struct platform_device *pdev)
116+static int pwmled_remove(struct platform_device *pdev)
117117 {
118118 const struct gpio_led_platform_data *pdata;
119119 struct pwmled *leds;
@@ -140,7 +140,7 @@ static struct platform_driver pwmled_driver = { · 20 unmodified lines
140140 },
141141 /* REVISIT add suspend() and resume() methods */
142142 .probe = pwmled_probe,
143− .remove = __exit_p(pwmled_remove),
143+ .remove = pwmled_remove,
144144 };
145145
146146 module_platform_driver(pwmled_driver);
drivers/leds/leds-bd2802.c+5−9
@@ -732,7 +732,7 @@ failed_unregister_dev_file: · 731 unmodified lines
732732 return ret;
733733 }
734734
735−static int __exit bd2802_remove(struct i2c_client *client)
735+static int bd2802_remove(struct i2c_client *client)
736736 {
737737 struct bd2802_led *led = i2c_get_clientdata(client);
738738 int i;
@@ -747,8 +747,7 @@ static int __exit bd2802_remove(struct i2c_client *client) · 8 unmodified lines
747747 return 0;
748748 }
749749
750−#ifdef CONFIG_PM
751−
750+#ifdef CONFIG_PM_SLEEP
752751 static void bd2802_restore_state(struct bd2802_led *led)
753752 {
754753 int i;
@@ -785,12 +784,9 @@ static int bd2802_resume(struct device *dev) · 30 unmodified lines
785784
786785 return 0;
787786 }
787+#endif
788788
789789 static 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
794790
795791 static const struct i2c_device_id bd2802_id[] = {
796792 { "BD2802", 0 },
@@ -801,10 +797,10 @@ MODULE_DEVICE_TABLE(i2c, bd2802_id); · 4 unmodified lines
801797 static struct i2c_driver bd2802_i2c_driver = {
802798 .driver = {
803799 .name = "BD2802",
804− .pm = BD2802_PM,
800+ .pm = &bd2802_pm,
805801 },
806802 .probe = bd2802_probe,
807− .remove = __exit_p(bd2802_remove),
803+ .remove = bd2802_remove,
808804 .id_table = bd2802_id,
809805 };
810806
drivers/leds/leds-lm355x.c+2−0
@@ -477,6 +477,7 @@ static int lm355x_probe(struct i2c_client *client, · 476 unmodified lines
477477 chip->cdev_flash.name = "flash";
478478 chip->cdev_flash.max_brightness = 16;
479479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
480+ chip->cdev_flash.default_trigger = "flash";
480481 err = led_classdev_register((struct device *)
481482 &client->dev, &chip->cdev_flash);
482483 if (err < 0)
@@ -486,6 +487,7 @@ static int lm355x_probe(struct i2c_client *client, · 3 unmodified lines
486487 chip->cdev_torch.name = "torch";
487488 chip->cdev_torch.max_brightness = 8;
488489 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
490+ chip->cdev_torch.default_trigger = "torch";
489491 err = led_classdev_register((struct device *)
490492 &client->dev, &chip->cdev_torch);
491493 if (err < 0)
drivers/leds/leds-lm3642.c+2−0
@@ -363,6 +363,7 @@ static int lm3642_probe(struct i2c_client *client, · 362 unmodified lines
363363 chip->cdev_flash.name = "flash";
364364 chip->cdev_flash.max_brightness = 16;
365365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
366+ chip->cdev_flash.default_trigger = "flash";
366367 err = led_classdev_register((struct device *)
367368 &client->dev, &chip->cdev_flash);
368369 if (err < 0) {
@@ -380,6 +381,7 @@ static int lm3642_probe(struct i2c_client *client, · 11 unmodified lines
380381 chip->cdev_torch.name = "torch";
381382 chip->cdev_torch.max_brightness = 8;
382383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
384+ chip->cdev_torch.default_trigger = "torch";
383385 err = led_classdev_register((struct device *)
384386 &client->dev, &chip->cdev_torch);
385387 if (err < 0) {
drivers/leds/leds-lp5521.c+19−3
@@ -68,6 +68,18 @@ · 67 unmodified lines
6868 #define LP5521_ENABLE_RUN_PROGRAM \
6969 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
7070
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+
7183 /* Status */
7284 #define LP5521_EXT_CLK_USED 0x08
7385
@@ -296,8 +308,11 @@ static int lp5521_post_init_device(struct lp55xx_chip *chip) · 222 unmodified lines
296308 /* Set all PWMs to direct control mode */
297309 ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
298310
299− val = chip->pdata->update_config ?
300− : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
311+ /* Update configuration for the clock setting */
312+ val = LP5521_DEFAULT_CFG;
313+ if (!lp55xx_is_extclk_used(chip))
314+ val |= LP5521_CLK_INT;
315+
301316 ret = lp55xx_write(chip, LP5521_REG_CONFIG, val);
302317 if (ret)
303318 return ret;
@@ -360,7 +375,8 @@ static ssize_t lp5521_selftest(struct device *dev, · 56 unmodified lines
360375 mutex_lock(&chip->lock);
361376 ret = lp5521_run_selftest(chip, buf);
362377 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");
364380 }
365381
366382 /* device attributes */
drivers/leds/leds-lp5562.c+599−0
@@ -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+
105+static 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+
111+static 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+
117+static 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+
130+static 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+
150+static 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+
156+static 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+
209+static 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+
257+err:
258+ dev_err(&chip->cl->dev, "wrong pattern format\n");
259+ return -EINVAL;
260+}
261+
262+static 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+
282+static 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+
314+static 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+
331+static 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 */
347+static 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+
354+static 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+
403+static 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+
431+static 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+
480+static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern);
481+static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux);
482+
483+static struct attribute *lp5562_attributes[] = {
484+ &dev_attr_led_pattern.attr,
485+ &dev_attr_engine_mux.attr,
486+ NULL,
487+};
488+
489+static const struct attribute_group lp5562_group = {
490+ .attrs = lp5562_attributes,
491+};
492+
493+/* Chip specific configurations */
494+static 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+
512+static 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+
558+err_register_sysfs:
559+ lp55xx_unregister_leds(led, chip);
560+err_register_leds:
561+ lp55xx_deinit_device(chip);
562+err_init:
563+ return ret;
564+}
565+
566+static 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+
580+static const struct i2c_device_id lp5562_id[] = {
581+ { "lp5562", 0 },
582+ { }
583+};
584+MODULE_DEVICE_TABLE(i2c, lp5562_id);
585+
586+static 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+
595+module_i2c_driver(lp5562_driver);
596+
597+MODULE_DESCRIPTION("Texas Instruments LP5562 LED Driver");
598+MODULE_AUTHOR("Milo Kim");
599+MODULE_LICENSE("GPL");
drivers/leds/leds-lp55xx-common.c+39−3
@@ -1,5 +1,5 @@
11 /*
2− * LP5521/LP5523/LP55231 Common Driver
2+ * LP5521/LP5523/LP55231/LP5562 Common Driver
33 *
44 * Copyright 2012 Texas Instruments
55 *
@@ -12,6 +12,7 @@ · 6 unmodified lines
1212 * Derived from leds-lp5521.c, leds-lp5523.c
1313 */
1414
15+#include <linux/clk.h>
1516 #include <linux/delay.h>
1617 #include <linux/firmware.h>
1718 #include <linux/i2c.h>
@@ -21,6 +22,9 @@ · 3 unmodified lines
2122
2223 #include "leds-lp55xx-common.h"
2324
25+/* External clock rate */
26+#define LP55XX_CLK_32K 32768
27+
2428 static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
2529 {
2630 return container_of(cdev, struct lp55xx_led, cdev);
@@ -80,7 +84,7 @@ static ssize_t lp55xx_show_current(struct device *dev, · 53 unmodified lines
8084 {
8185 struct lp55xx_led *led = dev_to_lp55xx_led(dev);
8286
83− return sprintf(buf, "%d\n", led->led_current);
87+ return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
8488 }
8589
8690 static ssize_t lp55xx_store_current(struct device *dev,
@@ -113,7 +117,7 @@ static ssize_t lp55xx_show_max_current(struct device *dev, · 26 unmodified lines
113117 {
114118 struct lp55xx_led *led = dev_to_lp55xx_led(dev);
115119
116− return sprintf(buf, "%d\n", led->max_current);
120+ return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
117121 }
118122
119123 static 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) · 237 unmodified lines
357361 }
358362 EXPORT_SYMBOL_GPL(lp55xx_update_bits);
359363
364+bool 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+
387+use_internal_clk:
388+ dev_info(&chip->cl->dev, "internal clock used\n");
389+ return false;
390+}
391+EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
392+
360393 int lp55xx_init_device(struct lp55xx_chip *chip)
361394 {
362395 struct lp55xx_platform_data *pdata;
@@ -421,6 +454,9 @@ void lp55xx_deinit_device(struct lp55xx_chip *chip) · 58 unmodified lines
421454 {
422455 struct lp55xx_platform_data *pdata = chip->pdata;
423456
457+ if (chip->clk)
458+ clk_disable_unprepare(chip->clk);
459+
424460 if (pdata->enable)
425461 pdata->enable(0);
426462
drivers/leds/leds-lp55xx-common.h+4−0
@@ -83,6 +83,7 @@ struct lp55xx_device_config { · 82 unmodified lines
8383 */
8484 struct lp55xx_chip {
8585 struct i2c_client *cl;
86+ struct clk *clk;
8687 struct lp55xx_platform_data *pdata;
8788 struct mutex lock; /* lock for user-space interface */
8889 int num_leds;
@@ -117,6 +118,9 @@ extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val); · 28 unmodified lines
117118 extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,
118119 u8 mask, u8 val);
119120
121+/* external clock detection */
122+extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
123+
120124 /* common device init/deinit functions */
121125 extern int lp55xx_init_device(struct lp55xx_chip *chip);
122126 extern void lp55xx_deinit_device(struct lp55xx_chip *chip);
drivers/leds/leds-lt3593.c+3−2
@@ -106,8 +106,9 @@ static int create_lt3593_led(const struct gpio_led *template, · 105 unmodified lines
106106 if (!template->retain_state_suspended)
107107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
108108
109− ret = devm_gpio_request_one(parent, template->gpio,
110− GPIOF_DIR_OUT | state, template->name);
109+ ret = devm_gpio_request_one(parent, template->gpio, state ?
110+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
111+ template->name);
111112 if (ret < 0)
112113 return ret;
113114
drivers/leds/leds-ns2.c+29−15
@@ -193,7 +193,8 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, · 192 unmodified lines
193193 enum ns2_led_modes mode;
194194
195195 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,
197198 template->name);
198199 if (ret) {
199200 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, · 2 unmodified lines
202203 }
203204
204205 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,
206208 template->name);
207209 if (ret) {
208210 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[] = { · 97 unmodified lines
306308 };
307309 #endif /* CONFIG_OF_GPIO */
308310
311+struct ns2_led_priv {
312+ int num_leds;
313+ struct ns2_led_data leds_data[];
314+};
315+
316+static 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+
309322 static int ns2_led_probe(struct platform_device *pdev)
310323 {
311324 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
312− struct ns2_led_data *leds_data;
325+ struct ns2_led_priv *priv;
313326 int i;
314327 int ret;
315328
@@ -330,21 +343,23 @@ static int ns2_led_probe(struct platform_device *pdev) · 14 unmodified lines
330343 return -EINVAL;
331344 #endif /* CONFIG_OF_GPIO */
332345
333− leds_data = devm_kzalloc(&pdev->dev, sizeof(struct ns2_led_data) *
334− pdata->num_leds, GFP_KERNEL);
335− if (!leds_data)
346+ priv = devm_kzalloc(&pdev->dev,
347+ sizeof_ns2_led_priv(pdata->num_leds), GFP_KERNEL);
348+ if (!priv)
336349 return -ENOMEM;
350+ priv->num_leds = pdata->num_leds;
337351
338− for (i = 0; i < pdata->num_leds; i++) {
339− ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]);
352+ for (i = 0; i < priv->num_leds; i++) {
353+ ret = create_ns2_led(pdev, &priv->leds_data[i],
354+ &pdata->leds[i]);
340355 if (ret < 0) {
341356 for (i = i - 1; i >= 0; i--)
342− delete_ns2_led(&leds_data[i]);
357+ delete_ns2_led(&priv->leds_data[i]);
343358 return ret;
344359 }
345360 }
346361
347− platform_set_drvdata(pdev, leds_data);
362+ platform_set_drvdata(pdev, priv);
348363
349364 return 0;
350365 }
@@ -352,13 +367,12 @@ static int ns2_led_probe(struct platform_device *pdev) · 1 unmodified line
352367 static int ns2_led_remove(struct platform_device *pdev)
353368 {
354369 int i;
355− struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
356− struct ns2_led_data *leds_data;
370+ struct ns2_led_priv *priv;
357371
358− leds_data = platform_get_drvdata(pdev);
372+ priv = platform_get_drvdata(pdev);
359373
360− for (i = 0; i < pdata->num_leds; i++)
361− delete_ns2_led(&leds_data[i]);
374+ for (i = 0; i < priv->num_leds; i++)
375+ delete_ns2_led(&priv->leds_data[i]);
362376
363377 platform_set_drvdata(pdev, NULL);
364378
drivers/leds/leds-pwm.c+42−8
@@ -23,12 +23,16 @@ · 22 unmodified lines
2323 #include <linux/pwm.h>
2424 #include <linux/leds_pwm.h>
2525 #include <linux/slab.h>
26+#include <linux/workqueue.h>
2627
2728 struct led_pwm_data {
2829 struct led_classdev cdev;
2930 struct pwm_device *pwm;
31+ struct work_struct work;
3032 unsigned int active_low;
3133 unsigned int period;
34+ int duty;
35+ bool can_sleep;
3236 };
3337
3438 struct led_pwm_priv {
@@ -36,6 +40,26 @@ struct led_pwm_priv { · 1 unmodified line
3640 struct led_pwm_data leds[0];
3741 };
3842
43+static 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+
55+static 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+
3963 static void led_pwm_set(struct led_classdev *led_cdev,
4064 enum led_brightness brightness)
4165 {
@@ -44,13 +68,12 @@ static void led_pwm_set(struct led_classdev *led_cdev, · 2 unmodified lines
4468 unsigned int max = led_dat->cdev.max_brightness;
4569 unsigned int period = led_dat->period;
4670
47− if (brightness == 0) {
48− pwm_config(led_dat->pwm, 0, period);
49− pwm_disable(led_dat->pwm);
50− } else {
51− pwm_config(led_dat->pwm, brightness * period / max, period);
52− pwm_enable(led_dat->pwm);
53− }
71+ led_dat->duty = brightness * period / max;
72+
73+ if (led_dat->can_sleep)
74+ schedule_work(&led_dat->work);
75+ else
76+ __led_pwm_set(led_dat);
5477 }
5578
5679 static 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) · 43 unmodified lines
100123 led_dat->cdev.brightness = LED_OFF;
101124 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
102125
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+
103130 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
104131 if (ret < 0) {
105132 dev_err(&pdev->dev, "failed to register for %s\n",
@@ -153,6 +180,10 @@ static int led_pwm_probe(struct platform_device *pdev) · 47 unmodified lines
153180 led_dat->cdev.max_brightness = cur_led->max_brightness;
154181 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
155182
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+
156187 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
157188 if (ret < 0)
158189 goto err;
@@ -180,8 +211,11 @@ static int led_pwm_remove(struct platform_device *pdev) · 21 unmodified lines
180211 struct led_pwm_priv *priv = platform_get_drvdata(pdev);
181212 int i;
182213
183− for (i = 0; i < priv->num_leds; i++)
214+ for (i = 0; i < priv->num_leds; i++) {
184215 led_classdev_unregister(&priv->leds[i].cdev);
216+ if (priv->leds[i].can_sleep)
217+ cancel_work_sync(&priv->leds[i].work);
218+ }
185219
186220 return 0;
187221 }
drivers/leds/leds-renesas-tpu.c+2−1
@@ -205,7 +205,8 @@ static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state, · 204 unmodified lines
205205 gpio_free(cfg->pin_gpio_fn);
206206
207207 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,
209210 cfg->name);
210211
211212 if (new_state == R_TPU_PIN_GPIO_FN)
drivers/leds/leds-tca6507.c+2−2
@@ -85,6 +85,7 @@ · 84 unmodified lines
8585 #include <linux/gpio.h>
8686 #include <linux/workqueue.h>
8787 #include <linux/leds-tca6507.h>
88+#include <linux/of.h>
8889
8990 /* LED select registers determine the source that drives LED outputs */
9091 #define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */
@@ -724,7 +725,6 @@ tca6507_led_dt_init(struct i2c_client *client) · 633 unmodified lines
724725 return ERR_PTR(-ENODEV);
725726 }
726727
727−#define of_tca6507_leds_match NULL
728728 #endif
729729
730730 static int tca6507_probe(struct i2c_client *client,
@@ -813,7 +813,7 @@ static struct i2c_driver tca6507_driver = { · 82 unmodified lines
813813 .driver = {
814814 .name = "leds-tca6507",
815815 .owner = THIS_MODULE,
816− .of_match_table = of_tca6507_leds_match,
816+ .of_match_table = of_match_ptr(of_tca6507_leds_match),
817817 },
818818 .probe = tca6507_probe,
819819 .remove = tca6507_remove,
drivers/leds/leds-wm8350.c+4−1
@@ -129,7 +129,10 @@ static void wm8350_led_disable(struct wm8350_led *led) · 128 unmodified lines
129129 ret = regulator_disable(led->isink);
130130 if (ret != 0) {
131131 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);
133136 return;
134137 }
135138
drivers/leds/trigger/Kconfig+111−0
@@ -0,0 +1,111 @@
1+menuconfig 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+
9+if LEDS_TRIGGERS
10+
11+config 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+
22+config 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+
36+config 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+
44+config 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+
53+config 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+
62+config 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+
72+config 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+
85+config 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+
92+comment "iptables trigger is under Netfilter config (LED target)"
93+ depends on LEDS_TRIGGERS
94+
95+config 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+
103+config 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+
111+endif # LEDS_TRIGGERS
drivers/leds/trigger/Makefile+10−0
@@ -0,0 +1,10 @@
1+obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
2+obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
3+obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
4+obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
5+obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
6+obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
7+obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
8+obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
9+obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
10+obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o
drivers/leds/trigger/ledtrig-backlight.crenamed from drivers/leds/ledtrig-backlight.c+1−1
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616 #include <linux/init.h>
1717 #include <linux/fb.h>
1818 #include <linux/leds.h>
19−#include "leds.h"
19+#include "../leds.h"
2020
2121 #define BLANK 1
2222 #define UNBLANK 0
drivers/leds/trigger/ledtrig-camera.c+57−0
@@ -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+
21+DEFINE_LED_TRIGGER(ledtrig_flash);
22+DEFINE_LED_TRIGGER(ledtrig_torch);
23+
24+void 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+}
30+EXPORT_SYMBOL_GPL(ledtrig_flash_ctrl);
31+
32+void 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+}
38+EXPORT_SYMBOL_GPL(ledtrig_torch_ctrl);
39+
40+static 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+}
46+module_init(ledtrig_camera_init);
47+
48+static void __exit ledtrig_camera_exit(void)
49+{
50+ led_trigger_unregister_simple(ledtrig_torch);
51+ led_trigger_unregister_simple(ledtrig_flash);
52+}
53+module_exit(ledtrig_camera_exit);
54+
55+MODULE_DESCRIPTION("LED Trigger for Camera Flash/Torch Control");
56+MODULE_AUTHOR("Milo Kim");
57+MODULE_LICENSE("GPL");
drivers/leds/trigger/ledtrig-cpu.crenamed from drivers/leds/ledtrig-cpu.c+1−1
@@ -26,7 +26,7 @@ · 25 unmodified lines
2626 #include <linux/percpu.h>
2727 #include <linux/syscore_ops.h>
2828 #include <linux/rwsem.h>
29−#include "leds.h"
29+#include "../leds.h"
3030
3131 #define MAX_NAME_LEN 8
3232
drivers/leds/trigger/ledtrig-default-on.crenamed from drivers/leds/ledtrig-default-on.c+1−1
@@ -15,7 +15,7 @@ · 14 unmodified lines
1515 #include <linux/kernel.h>
1616 #include <linux/init.h>
1717 #include <linux/leds.h>
18−#include "leds.h"
18+#include "../leds.h"
1919
2020 static void defon_trig_activate(struct led_classdev *led_cdev)
2121 {
drivers/leds/trigger/ledtrig-gpio.crenamed from drivers/leds/ledtrig-gpio.c+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717 #include <linux/workqueue.h>
1818 #include <linux/leds.h>
1919 #include <linux/slab.h>
20−#include "leds.h"
20+#include "../leds.h"
2121
2222 struct gpio_trig_data {
2323 struct led_classdev *led;
drivers/leds/trigger/ledtrig-heartbeat.crenamed from drivers/leds/ledtrig-heartbeat.c+1−1
@@ -19,7 +19,7 @@ · 18 unmodified lines
1919 #include <linux/sched.h>
2020 #include <linux/leds.h>
2121 #include <linux/reboot.h>
22−#include "leds.h"
22+#include "../leds.h"
2323
2424 static int panic_heartbeats;
2525
drivers/leds/trigger/ledtrig-ide-disk.crenamed from drivers/leds/ledtrig-ide-disk.c+0−0

File renamed without changes.

drivers/leds/trigger/ledtrig-oneshot.crenamed from drivers/leds/ledtrig-oneshot.c+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 #include <linux/ctype.h>
1919 #include <linux/slab.h>
2020 #include <linux/leds.h>
21−#include "leds.h"
21+#include "../leds.h"
2222
2323 #define DEFAULT_DELAY 100
2424
drivers/leds/trigger/ledtrig-timer.crenamed from drivers/leds/ledtrig-timer.c+0−1
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #include <linux/device.h>
1818 #include <linux/ctype.h>
1919 #include <linux/leds.h>
20−#include "leds.h"
2120
2221 static ssize_t led_delay_on_show(struct device *dev,
2322 struct device_attribute *attr, char *buf)
drivers/leds/trigger/ledtrig-transient.crenamed from drivers/leds/ledtrig-transient.c+1−1
@@ -25,7 +25,7 @@ · 24 unmodified lines
2525 #include <linux/slab.h>
2626 #include <linux/timer.h>
2727 #include <linux/leds.h>
28−#include "leds.h"
28+#include "../leds.h"
2929
3030 struct transient_trig_data {
3131 int activate;
include/linux/leds.h+22−11
@@ -142,6 +142,10 @@ extern void led_set_brightness(struct led_classdev *led_cdev, · 141 unmodified lines
142142 /*
143143 * LED Triggers
144144 */
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+
145149 #ifdef CONFIG_LEDS_TRIGGERS
146150
147151 #define TRIG_NAME_MAX 50
@@ -164,9 +168,6 @@ struct led_trigger { · 16 unmodified lines
164168 extern int led_trigger_register(struct led_trigger *trigger);
165169 extern void led_trigger_unregister(struct led_trigger *trigger);
166170
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;
170171 extern void led_trigger_register_simple(const char *name,
171172 struct led_trigger **trigger);
172173 extern void led_trigger_unregister_simple(struct led_trigger *trigger);
@@ -199,20 +200,30 @@ extern void led_trigger_rename_static(const char *name, · 26 unmodified lines
199200
200201 #else
201202
202−/* Triggers aren't active - null macros */
203−#define DEFINE_LED_TRIGGER(x)
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)
203+/* Trigger has no members */
204+struct led_trigger {};
208205
209−#endif
206+/* Trigger inline empty functions */
207+static inline void led_trigger_register_simple(const char *name,
208+ struct led_trigger **trigger) {}
209+static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {}
210+static inline void led_trigger_event(struct led_trigger *trigger,
211+ enum led_brightness event) {}
212+#endif /* CONFIG_LEDS_TRIGGERS */
210213
211214 /* Trigger specific functions */
212215 #ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
213216 extern void ledtrig_ide_activity(void);
214217 #else
215−#define ledtrig_ide_activity() do {} while(0)
218+static inline void ledtrig_ide_activity(void) {}
219+#endif
220+
221+#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE)
222+extern void ledtrig_flash_ctrl(bool on);
223+extern void ledtrig_torch_ctrl(bool on);
224+#else
225+static inline void ledtrig_flash_ctrl(bool on) {}
226+static inline void ledtrig_torch_ctrl(bool on) {}
216227 #endif
217228
218229 /*
include/linux/mmc/host.h+0−2
@@ -342,9 +342,7 @@ struct mmc_host { · 341 unmodified lines
342342
343343 mmc_pm_flag_t pm_flags; /* requested pm features */
344344
345−#ifdef CONFIG_LEDS_TRIGGERS
346345 struct led_trigger *led; /* activity led */
347−#endif
348346
349347 #ifdef CONFIG_REGULATOR
350348 bool regulator_enabled; /* regulator state */
include/linux/platform_data/leds-lp55xx.h+3−18
@@ -20,18 +20,6 @@ · 19 unmodified lines
2020 #define LP55XX_CLOCK_INT 1
2121 #define LP55XX_CLOCK_EXT 2
2222
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−
3523 struct lp55xx_led_config {
3624 const char *name;
3725 u8 chan_nr;
@@ -40,9 +28,9 @@ struct lp55xx_led_config { · 2 unmodified lines
4028 };
4129
4230 struct lp55xx_predef_pattern {
43− u8 *r;
44− u8 *g;
45− u8 *b;
31+ const u8 *r;
32+ const u8 *g;
33+ const u8 *b;
4634 u8 size_r;
4735 u8 size_g;
4836 u8 size_b;
@@ -79,9 +67,6 @@ struct lp55xx_platform_data { · 30 unmodified lines
7967 /* Predefined pattern data */
8068 struct lp55xx_predef_pattern *patterns;
8169 unsigned int num_patterns;
82−
83− /* _CONFIG register */
84− u8 update_config;
8570 };
8671
8772 #endif /* _LEDS_LP55XX_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t