aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/leds
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig180
-rw-r--r--drivers/leds/Makefile18
-rw-r--r--drivers/leds/dell-led.c1
-rw-r--r--drivers/leds/led-class.c124
-rw-r--r--drivers/leds/led-core.c101
-rw-r--r--drivers/leds/led-triggers.c156
-rw-r--r--drivers/leds/leds-88pm860x.c213
-rw-r--r--drivers/leds/leds-adp5520.c32
-rw-r--r--drivers/leds/leds-asic3.c74
-rw-r--r--drivers/leds/leds-atmel-pwm.c25
-rw-r--r--drivers/leds/leds-bd2802.c35
-rw-r--r--drivers/leds/leds-blinkm.c815
-rw-r--r--drivers/leds/leds-clevo-mail.c25
-rw-r--r--drivers/leds/leds-cobalt-qube.c34
-rw-r--r--drivers/leds/leds-cobalt-raq.c18
-rw-r--r--drivers/leds/leds-da903x.c37
-rw-r--r--drivers/leds/leds-da9052.c214
-rw-r--r--drivers/leds/leds-dac124s085.c17
-rw-r--r--drivers/leds/leds-fsg.c31
-rw-r--r--drivers/leds/leds-gpio.c102
-rw-r--r--drivers/leds/leds-hp6xx.c17
-rw-r--r--drivers/leds/leds-lm3530.c258
-rw-r--r--drivers/leds/leds-lm3533.c785
-rw-r--r--drivers/leds/leds-lm355x.c572
-rw-r--r--drivers/leds/leds-lm3642.c462
-rw-r--r--drivers/leds/leds-locomo.c1
-rw-r--r--drivers/leds/leds-lp3944.c30
-rw-r--r--drivers/leds/leds-lp5521.c234
-rw-r--r--drivers/leds/leds-lp5523.c161
-rw-r--r--drivers/leds/leds-lp8788.c193
-rw-r--r--drivers/leds/leds-lt3593.c54
-rw-r--r--drivers/leds/leds-max8997.c319
-rw-r--r--drivers/leds/leds-mc13783.c93
-rw-r--r--drivers/leds/leds-net48xx.c3
-rw-r--r--drivers/leds/leds-netxbig.c67
-rw-r--r--drivers/leds/leds-ns2.c161
-rw-r--r--drivers/leds/leds-ot200.c171
-rw-r--r--drivers/leds/leds-pca9532.c24
-rw-r--r--drivers/leds/leds-pca955x.c116
-rw-r--r--drivers/leds/leds-pca9633.c194
-rw-r--r--drivers/leds/leds-pwm.c26
-rw-r--r--drivers/leds/leds-rb532.c24
-rw-r--r--drivers/leds/leds-regulator.c27
-rw-r--r--drivers/leds/leds-renesas-tpu.c336
-rw-r--r--drivers/leds/leds-s3c24xx.c60
-rw-r--r--drivers/leds/leds-ss4200.c8
-rw-r--r--drivers/leds/leds-sunfire.c33
-rw-r--r--drivers/leds/leds-tca6507.c763
-rw-r--r--drivers/leds/leds-wm831x-status.c18
-rw-r--r--drivers/leds/leds-wm8350.c53
-rw-r--r--drivers/leds/leds-wrap.c3
-rw-r--r--drivers/leds/leds.h4
-rw-r--r--drivers/leds/ledtrig-backlight.c16
-rw-r--r--drivers/leds/ledtrig-cpu.c142
-rw-r--r--drivers/leds/ledtrig-default-on.c2
-rw-r--r--drivers/leds/ledtrig-gpio.c12
-rw-r--r--drivers/leds/ledtrig-heartbeat.c48
-rw-r--r--drivers/leds/ledtrig-ide-disk.c25
-rw-r--r--drivers/leds/ledtrig-oneshot.c204
-rw-r--r--drivers/leds/ledtrig-timer.c56
-rw-r--r--drivers/leds/ledtrig-transient.c237
61 files changed, 1369 insertions, 6895 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index b58bc8a14b9..7f9bed7697a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -17,7 +17,7 @@ menuconfig NEW_LEDS
17if NEW_LEDS 17if NEW_LEDS
18 18
19config LEDS_CLASS 19config LEDS_CLASS
20 tristate "LED Class Support" 20 bool "LED Class Support"
21 help 21 help
22 This option enables the led sysfs class in /sys/class/leds. You'll 22 This option enables the led sysfs class in /sys/class/leds. You'll
23 need this to do anything useful with LEDs. If unsure, say N. 23 need this to do anything useful with LEDs. If unsure, say N.
@@ -50,30 +50,6 @@ config LEDS_LM3530
50 controlled manually or using PWM input or using ambient 50 controlled manually or using PWM input or using ambient
51 light automatically. 51 light automatically.
52 52
53config LEDS_LM3533
54 tristate "LED support for LM3533"
55 depends on LEDS_CLASS
56 depends on MFD_LM3533
57 help
58 This option enables support for the LEDs on National Semiconductor /
59 TI LM3533 Lighting Power chips.
60
61 The LEDs can be controlled directly, through PWM input, or by the
62 ambient-light-sensor interface. The chip supports
63 hardware-accelerated blinking with maximum on and off periods of 9.8
64 and 77 seconds respectively.
65
66config LEDS_LM3642
67 tristate "LED support for LM3642 Chip"
68 depends on LEDS_CLASS && I2C
69 select REGMAP_I2C
70 help
71 This option enables support for LEDs connected to LM3642.
72 The LM3642 is a 4MHz fixed-frequency synchronous boost
73 converter plus 1.5A constant current driver for a high-current
74 white LED.
75
76
77config LEDS_LOCOMO 53config LEDS_LOCOMO
78 tristate "LED Support for Locomo device" 54 tristate "LED Support for Locomo device"
79 depends on LEDS_CLASS 55 depends on LEDS_CLASS
@@ -93,11 +69,18 @@ config LEDS_MIKROTIK_RB532
93config LEDS_S3C24XX 69config LEDS_S3C24XX
94 tristate "LED Support for Samsung S3C24XX GPIO LEDs" 70 tristate "LED Support for Samsung S3C24XX GPIO LEDs"
95 depends on LEDS_CLASS 71 depends on LEDS_CLASS
96 depends on ARCH_S3C24XX 72 depends on ARCH_S3C2410
97 help 73 help
98 This option enables support for LEDs connected to GPIO lines 74 This option enables support for LEDs connected to GPIO lines
99 on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. 75 on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
100 76
77config LEDS_AMS_DELTA
78 tristate "LED Support for the Amstrad Delta (E3)"
79 depends on LEDS_CLASS
80 depends on MACH_AMS_DELTA
81 help
82 This option enables support for the LEDs on Amstrad Delta (E3).
83
101config LEDS_NET48XX 84config LEDS_NET48XX
102 tristate "LED Support for Soekris net48xx series Error LED" 85 tristate "LED Support for Soekris net48xx series Error LED"
103 depends on LEDS_CLASS 86 depends on LEDS_CLASS
@@ -106,6 +89,16 @@ config LEDS_NET48XX
106 This option enables support for the Soekris net4801 and net4826 error 89 This option enables support for the Soekris net4801 and net4826 error
107 LED. 90 LED.
108 91
92config LEDS_NET5501
93 tristate "LED Support for Soekris net5501 series Error LED"
94 depends on LEDS_TRIGGERS
95 depends on X86 && GPIO_CS5535
96 select LEDS_TRIGGER_DEFAULT_ON
97 default n
98 help
99 Add support for the Soekris net5501 board (detection, error led
100 and GPIO).
101
109config LEDS_FSG 102config LEDS_FSG
110 tristate "LED Support for the Freecom FSG-3" 103 tristate "LED Support for the Freecom FSG-3"
111 depends on LEDS_CLASS 104 depends on LEDS_CLASS
@@ -120,6 +113,14 @@ config LEDS_WRAP
120 help 113 help
121 This option enables support for the PCEngines WRAP programmable LEDs. 114 This option enables support for the PCEngines WRAP programmable LEDs.
122 115
116config LEDS_ALIX2
117 tristate "LED Support for ALIX.2 and ALIX.3 series"
118 depends on LEDS_CLASS
119 depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
120 help
121 This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
122 You have to set leds-alix2.force=1 for boards with Award BIOS.
123
123config LEDS_COBALT_QUBE 124config LEDS_COBALT_QUBE
124 tristate "LED Support for the Cobalt Qube series front LED" 125 tristate "LED Support for the Cobalt Qube series front LED"
125 depends on LEDS_CLASS 126 depends on LEDS_CLASS
@@ -203,22 +204,14 @@ config LEDS_LP5521
203 programming the engines. 204 programming the engines.
204 205
205config LEDS_LP5523 206config LEDS_LP5523
206 tristate "LED Support for TI/National LP5523/55231 LED driver chip" 207 tristate "LED Support for N.S. LP5523 LED driver chip"
207 depends on LEDS_CLASS && I2C 208 depends on LEDS_CLASS && I2C
208 help 209 help
209 If you say yes here you get support for TI/National Semiconductor 210 If you say yes here you get support for the National Semiconductor
210 LP5523/55231 LED driver. 211 LP5523 LED driver. It is 9 channel chip with programmable engines.
211 It is 9 channel chip with programmable engines.
212 Driver provides direct control via LED class and interface for 212 Driver provides direct control via LED class and interface for
213 programming the engines. 213 programming the engines.
214 214
215config LEDS_LP8788
216 tristate "LED support for the TI LP8788 PMIC"
217 depends on LEDS_CLASS
218 depends on MFD_LP8788
219 help
220 This option enables support for the Keyboard LEDs on the LP8788 PMIC.
221
222config LEDS_CLEVO_MAIL 215config LEDS_CLEVO_MAIL
223 tristate "Mail LED on Clevo notebook" 216 tristate "Mail LED on Clevo notebook"
224 depends on LEDS_CLASS 217 depends on LEDS_CLASS
@@ -259,14 +252,6 @@ config LEDS_PCA955X
259 LED driver chips accessed via the I2C bus. Supported 252 LED driver chips accessed via the I2C bus. Supported
260 devices include PCA9550, PCA9551, PCA9552, and PCA9553. 253 devices include PCA9550, PCA9551, PCA9552, and PCA9553.
261 254
262config LEDS_PCA9633
263 tristate "LED support for PCA9633 I2C chip"
264 depends on LEDS_CLASS
265 depends on I2C
266 help
267 This option enables support for LEDs connected to the PCA9633
268 LED driver chip accessed via the I2C bus.
269
270config LEDS_WM831X_STATUS 255config LEDS_WM831X_STATUS
271 tristate "LED support for status LEDs on WM831x PMICs" 256 tristate "LED support for status LEDs on WM831x PMICs"
272 depends on LEDS_CLASS 257 depends on LEDS_CLASS
@@ -291,14 +276,6 @@ config LEDS_DA903X
291 This option enables support for on-chip LED drivers found 276 This option enables support for on-chip LED drivers found
292 on Dialog Semiconductor DA9030/DA9034 PMICs. 277 on Dialog Semiconductor DA9030/DA9034 PMICs.
293 278
294config LEDS_DA9052
295 tristate "Dialog DA9052/DA9053 LEDS"
296 depends on LEDS_CLASS
297 depends on PMIC_DA9052
298 help
299 This option enables support for on-chip LED drivers found
300 on Dialog Semiconductor DA9052-BC and DA9053-AA/Bx PMICs.
301
302config LEDS_DAC124S085 279config LEDS_DAC124S085
303 tristate "LED Support for DAC124S085 SPI DAC" 280 tristate "LED Support for DAC124S085 SPI DAC"
304 depends on LEDS_CLASS 281 depends on LEDS_CLASS
@@ -378,10 +355,7 @@ config LEDS_MC13783
378config LEDS_NS2 355config LEDS_NS2
379 tristate "LED support for Network Space v2 GPIO LEDs" 356 tristate "LED support for Network Space v2 GPIO LEDs"
380 depends on LEDS_CLASS 357 depends on LEDS_CLASS
381 depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || \ 358 depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
382 MACH_NETSPACE_MAX_V2 || MACH_D2NET_V2 || \
383 MACH_NETSPACE_V2_DT || MACH_INETSPACE_V2_DT || \
384 MACH_NETSPACE_MAX_V2_DT || MACH_NETSPACE_MINI_V2_DT
385 default y 359 default y
386 help 360 help
387 This option enable support for the dual-GPIO LED found on the 361 This option enable support for the dual-GPIO LED found on the
@@ -400,7 +374,7 @@ config LEDS_NETXBIG
400 374
401config LEDS_ASIC3 375config LEDS_ASIC3
402 bool "LED support for the HTC ASIC3" 376 bool "LED support for the HTC ASIC3"
403 depends on LEDS_CLASS=y 377 depends on LEDS_CLASS
404 depends on MFD_ASIC3 378 depends on MFD_ASIC3
405 default y 379 default y
406 help 380 help
@@ -409,56 +383,6 @@ config LEDS_ASIC3
409 cannot be used. This driver supports hardware blinking with an on+off 383 cannot be used. This driver supports hardware blinking with an on+off
410 period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. 384 period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700.
411 385
412config LEDS_RENESAS_TPU
413 bool "LED support for Renesas TPU"
414 depends on LEDS_CLASS=y && HAVE_CLK && GENERIC_GPIO
415 help
416 This option enables build of the LED TPU platform driver,
417 suitable to drive any TPU channel on newer Renesas SoCs.
418 The driver controls the GPIO pin connected to the LED via
419 the GPIO framework and expects the LED to be connected to
420 a pin that can be driven in both GPIO mode and using TPU
421 pin function. The latter to support brightness control.
422 Brightness control is supported but hardware blinking is not.
423
424config LEDS_TCA6507
425 tristate "LED Support for TCA6507 I2C chip"
426 depends on LEDS_CLASS && I2C
427 help
428 This option enables support for LEDs connected to TC6507
429 LED driver chips accessed via the I2C bus.
430 Driver support brightness control and hardware-assisted blinking.
431
432config LEDS_MAX8997
433 tristate "LED support for MAX8997 PMIC"
434 depends on LEDS_CLASS && MFD_MAX8997
435 help
436 This option enables support for on-chip LED drivers on
437 MAXIM MAX8997 PMIC.
438
439config LEDS_LM355x
440 tristate "LED support for LM355x Chips, LM3554 and LM3556"
441 depends on LEDS_CLASS && I2C
442 select REGMAP_I2C
443 help
444 This option enables support for LEDs connected to LM355x.
445 LM355x includes Torch, Flash and Indicator functions.
446
447config LEDS_OT200
448 tristate "LED support for the Bachmann OT200"
449 depends on LEDS_CLASS && HAS_IOMEM
450 help
451 This option enables support for the LEDs on the Bachmann OT200.
452 Say Y to enable LEDs on the Bachmann OT200.
453
454config LEDS_BLINKM
455 tristate "LED support for the BlinkM I2C RGB LED"
456 depends on LEDS_CLASS
457 depends on I2C
458 help
459 This option enables support for the BlinkM RGB LED connected
460 through I2C. Say Y to enable support for the BlinkM LED.
461
462config LEDS_TRIGGERS 386config LEDS_TRIGGERS
463 bool "LED Trigger support" 387 bool "LED Trigger support"
464 depends on LEDS_CLASS 388 depends on LEDS_CLASS
@@ -476,21 +400,7 @@ config LEDS_TRIGGER_TIMER
476 This allows LEDs to be controlled by a programmable timer 400 This allows LEDs to be controlled by a programmable timer
477 via sysfs. Some LED hardware can be programmed to start 401 via sysfs. Some LED hardware can be programmed to start
478 blinking the LED without any further software interaction. 402 blinking the LED without any further software interaction.
479 For more details read Documentation/leds/leds-class.txt. 403 For more details read Documentation/leds-class.txt.
480
481 If unsure, say Y.
482
483config LEDS_TRIGGER_ONESHOT
484 tristate "LED One-shot Trigger"
485 depends on LEDS_TRIGGERS
486 help
487 This allows LEDs to blink in one-shot pulses with parameters
488 controlled via sysfs. It's useful to notify the user on
489 sporadic events, when there are no clear begin and end trap points,
490 or on dense events, where this blinks the LED at constant rate if
491 rearmed continuously.
492
493 It also shows how to use the led_blink_set_oneshot() function.
494 404
495 If unsure, say Y. 405 If unsure, say Y.
496 406
@@ -520,16 +430,6 @@ config LEDS_TRIGGER_BACKLIGHT
520 430
521 If unsure, say N. 431 If unsure, say N.
522 432
523config LEDS_TRIGGER_CPU
524 bool "LED CPU Trigger"
525 depends on LEDS_TRIGGERS
526 help
527 This allows LEDs to be controlled by active CPUs. This shows
528 the active CPUs across an array of LEDs so you can see which
529 CPUs are active on the system at any given moment.
530
531 If unsure, say N.
532
533config LEDS_TRIGGER_GPIO 433config LEDS_TRIGGER_GPIO
534 tristate "LED GPIO Trigger" 434 tristate "LED GPIO Trigger"
535 depends on LEDS_TRIGGERS 435 depends on LEDS_TRIGGERS
@@ -550,15 +450,13 @@ config LEDS_TRIGGER_DEFAULT_ON
550 This allows LEDs to be initialised in the ON state. 450 This allows LEDs to be initialised in the ON state.
551 If unsure, say Y. 451 If unsure, say Y.
552 452
553comment "iptables trigger is under Netfilter config (LED target)" 453config LEDS_TRIGGER_SLEEP
554 depends on LEDS_TRIGGERS 454 tristate "LED Sleep Mode Trigger"
455 depends on LEDS_TRIGGERS && HAS_EARLYSUSPEND
456 help
457 This turns LEDs on when the screen is off but the cpu still running.
555 458
556config LEDS_TRIGGER_TRANSIENT 459comment "iptables trigger is under Netfilter config (LED target)"
557 tristate "LED Transient Trigger"
558 depends on LEDS_TRIGGERS 460 depends on LEDS_TRIGGERS
559 help
560 This allows one time activation of a transient state on
561 GPIO/PWM based hardware.
562 If unsure, say Y.
563 461
564endif # NEW_LEDS 462endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3fb9641b619..cb77b9bb2f9 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -10,12 +10,13 @@ obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
10obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o 10obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
11obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o 11obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
12obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o 12obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
13obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o
14obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o
15obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o 13obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
16obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o 14obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
15obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
17obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o 16obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
17obj-$(CONFIG_LEDS_NET5501) += leds-net5501.o
18obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o 18obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
19obj-$(CONFIG_LEDS_ALIX2) += leds-alix2.o
19obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o 20obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
20obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o 21obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
21obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o 22obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
@@ -25,16 +26,11 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
25obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o 26obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o
26obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o 27obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
27obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o 28obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
28obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
29obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
30obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 29obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
31obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 30obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
32obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
33obj-$(CONFIG_LEDS_FSG) += leds-fsg.o 31obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
34obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o 32obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
35obj-$(CONFIG_LEDS_PCA9633) += leds-pca9633.o
36obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o 33obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
37obj-$(CONFIG_LEDS_DA9052) += leds-da9052.o
38obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o 34obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
39obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o 35obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
40obj-$(CONFIG_LEDS_PWM) += leds-pwm.o 36obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
@@ -47,21 +43,15 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
47obj-$(CONFIG_LEDS_NS2) += leds-ns2.o 43obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
48obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o 44obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
49obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o 45obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
50obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
51obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
52obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
53obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
54 46
55# LED SPI Drivers 47# LED SPI Drivers
56obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o 48obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
57 49
58# LED Triggers 50# LED Triggers
59obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 51obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
60obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
61obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o 52obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
62obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o 53obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
63obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o 54obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
64obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o 55obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
65obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
66obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o 56obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
67obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o 57obj-$(CONFIG_LEDS_TRIGGER_SLEEP) += ledtrig-sleep.o
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c
index e5c57389efd..52590296af3 100644
--- a/drivers/leds/dell-led.c
+++ b/drivers/leds/dell-led.c
@@ -14,7 +14,6 @@
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/leds.h> 15#include <linux/leds.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/module.h>
18 17
19MODULE_AUTHOR("Louis Davis/Jim Dailey"); 18MODULE_AUTHOR("Louis Davis/Jim Dailey");
20MODULE_DESCRIPTION("Dell LED Control Driver"); 19MODULE_DESCRIPTION("Dell LED Control Driver");
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index a20752f562b..6d5628bb060 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -15,6 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/sysdev.h>
18#include <linux/timer.h> 19#include <linux/timer.h>
19#include <linux/err.h> 20#include <linux/err.h>
20#include <linux/ctype.h> 21#include <linux/ctype.h>
@@ -29,7 +30,7 @@ static void led_update_brightness(struct led_classdev *led_cdev)
29 led_cdev->brightness = led_cdev->brightness_get(led_cdev); 30 led_cdev->brightness = led_cdev->brightness_get(led_cdev);
30} 31}
31 32
32static ssize_t led_brightness_show(struct device *dev, 33static ssize_t led_brightness_show(struct device *dev,
33 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
34{ 35{
35 struct led_classdev *led_cdev = dev_get_drvdata(dev); 36 struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -44,18 +45,23 @@ static ssize_t led_brightness_store(struct device *dev,
44 struct device_attribute *attr, const char *buf, size_t size) 45 struct device_attribute *attr, const char *buf, size_t size)
45{ 46{
46 struct led_classdev *led_cdev = dev_get_drvdata(dev); 47 struct led_classdev *led_cdev = dev_get_drvdata(dev);
47 unsigned long state;
48 ssize_t ret = -EINVAL; 48 ssize_t ret = -EINVAL;
49 char *after;
50 unsigned long state = simple_strtoul(buf, &after, 10);
51 size_t count = after - buf;
49 52
50 ret = kstrtoul(buf, 10, &state); 53 if (isspace(*after))
51 if (ret) 54 count++;
52 return ret;
53 55
54 if (state == LED_OFF) 56 if (count == size) {
55 led_trigger_remove(led_cdev); 57 ret = count;
56 __led_set_brightness(led_cdev, state);
57 58
58 return size; 59 if (state == LED_OFF)
60 led_trigger_remove(led_cdev);
61 led_set_brightness(led_cdev, state);
62 }
63
64 return ret;
59} 65}
60 66
61static ssize_t led_max_brightness_show(struct device *dev, 67static ssize_t led_max_brightness_show(struct device *dev,
@@ -82,12 +88,7 @@ static void led_timer_function(unsigned long data)
82 unsigned long delay; 88 unsigned long delay;
83 89
84 if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { 90 if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
85 __led_set_brightness(led_cdev, LED_OFF); 91 led_set_brightness(led_cdev, LED_OFF);
86 return;
87 }
88
89 if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
90 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
91 return; 92 return;
92 } 93 }
93 94
@@ -105,35 +106,55 @@ static void led_timer_function(unsigned long data)
105 delay = led_cdev->blink_delay_off; 106 delay = led_cdev->blink_delay_off;
106 } 107 }
107 108
108 __led_set_brightness(led_cdev, brightness); 109 led_set_brightness(led_cdev, brightness);
109
110 /* Return in next iteration if led is in one-shot mode and we are in
111 * the final blink state so that the led is toggled each delay_on +
112 * delay_off milliseconds in worst case.
113 */
114 if (led_cdev->flags & LED_BLINK_ONESHOT) {
115 if (led_cdev->flags & LED_BLINK_INVERT) {
116 if (brightness)
117 led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
118 } else {
119 if (!brightness)
120 led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
121 }
122 }
123 110
124 mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); 111 mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
125} 112}
126 113
127static void set_brightness_delayed(struct work_struct *ws) 114static void led_stop_software_blink(struct led_classdev *led_cdev)
115{
116 /* deactivate previous settings */
117 del_timer_sync(&led_cdev->blink_timer);
118 led_cdev->blink_delay_on = 0;
119 led_cdev->blink_delay_off = 0;
120}
121
122static void led_set_software_blink(struct led_classdev *led_cdev,
123 unsigned long delay_on,
124 unsigned long delay_off)
128{ 125{
129 struct led_classdev *led_cdev = 126 int current_brightness;
130 container_of(ws, struct led_classdev, set_brightness_work); 127
128 current_brightness = led_get_brightness(led_cdev);
129 if (current_brightness)
130 led_cdev->blink_brightness = current_brightness;
131 if (!led_cdev->blink_brightness)
132 led_cdev->blink_brightness = led_cdev->max_brightness;
133
134 if (led_get_trigger_data(led_cdev) &&
135 delay_on == led_cdev->blink_delay_on &&
136 delay_off == led_cdev->blink_delay_off)
137 return;
131 138
132 led_stop_software_blink(led_cdev); 139 led_stop_software_blink(led_cdev);
133 140
134 __led_set_brightness(led_cdev, led_cdev->delayed_set_value); 141 led_cdev->blink_delay_on = delay_on;
142 led_cdev->blink_delay_off = delay_off;
143
144 /* never on - don't blink */
145 if (!delay_on)
146 return;
147
148 /* never off - just set to brightness */
149 if (!delay_off) {
150 led_set_brightness(led_cdev, led_cdev->blink_brightness);
151 return;
152 }
153
154 mod_timer(&led_cdev->blink_timer, jiffies + 1);
135} 155}
136 156
157
137/** 158/**
138 * led_classdev_suspend - suspend an led_classdev. 159 * led_classdev_suspend - suspend an led_classdev.
139 * @led_cdev: the led_classdev to suspend. 160 * @led_cdev: the led_classdev to suspend.
@@ -201,8 +222,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
201 222
202 led_update_brightness(led_cdev); 223 led_update_brightness(led_cdev);
203 224
204 INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
205
206 init_timer(&led_cdev->blink_timer); 225 init_timer(&led_cdev->blink_timer);
207 led_cdev->blink_timer.function = led_timer_function; 226 led_cdev->blink_timer.function = led_timer_function;
208 led_cdev->blink_timer.data = (unsigned long)led_cdev; 227 led_cdev->blink_timer.data = (unsigned long)led_cdev;
@@ -211,7 +230,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
211 led_trigger_set_default(led_cdev); 230 led_trigger_set_default(led_cdev);
212#endif 231#endif
213 232
214 dev_dbg(parent, "Registered led device: %s\n", 233 printk(KERN_DEBUG "Registered led device: %s\n",
215 led_cdev->name); 234 led_cdev->name);
216 235
217 return 0; 236 return 0;
@@ -233,11 +252,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
233 up_write(&led_cdev->trigger_lock); 252 up_write(&led_cdev->trigger_lock);
234#endif 253#endif
235 254
236 cancel_work_sync(&led_cdev->set_brightness_work);
237
238 /* Stop blinking */ 255 /* Stop blinking */
239 led_stop_software_blink(led_cdev); 256 led_brightness_set(led_cdev, LED_OFF);
240 led_set_brightness(led_cdev, LED_OFF);
241 257
242 device_unregister(led_cdev->dev); 258 device_unregister(led_cdev->dev);
243 259
@@ -247,6 +263,32 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
247} 263}
248EXPORT_SYMBOL_GPL(led_classdev_unregister); 264EXPORT_SYMBOL_GPL(led_classdev_unregister);
249 265
266void led_blink_set(struct led_classdev *led_cdev,
267 unsigned long *delay_on,
268 unsigned long *delay_off)
269{
270 del_timer_sync(&led_cdev->blink_timer);
271
272 if (led_cdev->blink_set &&
273 !led_cdev->blink_set(led_cdev, delay_on, delay_off))
274 return;
275
276 /* blink with 1 Hz as default if nothing specified */
277 if (!*delay_on && !*delay_off)
278 *delay_on = *delay_off = 500;
279
280 led_set_software_blink(led_cdev, *delay_on, *delay_off);
281}
282EXPORT_SYMBOL(led_blink_set);
283
284void led_brightness_set(struct led_classdev *led_cdev,
285 enum led_brightness brightness)
286{
287 led_stop_software_blink(led_cdev);
288 led_cdev->brightness_set(led_cdev, brightness);
289}
290EXPORT_SYMBOL(led_brightness_set);
291
250static int __init leds_init(void) 292static int __init leds_init(void)
251{ 293{
252 leds_class = class_create(THIS_MODULE, "leds"); 294 leds_class = class_create(THIS_MODULE, "leds");
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index ce8921a753a..016d19f5486 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -23,104 +23,3 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
23 23
24LIST_HEAD(leds_list); 24LIST_HEAD(leds_list);
25EXPORT_SYMBOL_GPL(leds_list); 25EXPORT_SYMBOL_GPL(leds_list);
26
27static void led_set_software_blink(struct led_classdev *led_cdev,
28 unsigned long delay_on,
29 unsigned long delay_off)
30{
31 int current_brightness;
32
33 current_brightness = led_get_brightness(led_cdev);
34 if (current_brightness)
35 led_cdev->blink_brightness = current_brightness;
36 if (!led_cdev->blink_brightness)
37 led_cdev->blink_brightness = led_cdev->max_brightness;
38
39 led_cdev->blink_delay_on = delay_on;
40 led_cdev->blink_delay_off = delay_off;
41
42 /* never on - don't blink */
43 if (!delay_on)
44 return;
45
46 /* never off - just set to brightness */
47 if (!delay_off) {
48 __led_set_brightness(led_cdev, led_cdev->blink_brightness);
49 return;
50 }
51
52 mod_timer(&led_cdev->blink_timer, jiffies + 1);
53}
54
55
56static void led_blink_setup(struct led_classdev *led_cdev,
57 unsigned long *delay_on,
58 unsigned long *delay_off)
59{
60 if (!(led_cdev->flags & LED_BLINK_ONESHOT) &&
61 led_cdev->blink_set &&
62 !led_cdev->blink_set(led_cdev, delay_on, delay_off))
63 return;
64
65 /* blink with 1 Hz as default if nothing specified */
66 if (!*delay_on && !*delay_off)
67 *delay_on = *delay_off = 500;
68
69 led_set_software_blink(led_cdev, *delay_on, *delay_off);
70}
71
72void led_blink_set(struct led_classdev *led_cdev,
73 unsigned long *delay_on,
74 unsigned long *delay_off)
75{
76 del_timer_sync(&led_cdev->blink_timer);
77
78 led_cdev->flags &= ~LED_BLINK_ONESHOT;
79 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
80
81 led_blink_setup(led_cdev, delay_on, delay_off);
82}
83EXPORT_SYMBOL(led_blink_set);
84
85void led_blink_set_oneshot(struct led_classdev *led_cdev,
86 unsigned long *delay_on,
87 unsigned long *delay_off,
88 int invert)
89{
90 if ((led_cdev->flags & LED_BLINK_ONESHOT) &&
91 timer_pending(&led_cdev->blink_timer))
92 return;
93
94 led_cdev->flags |= LED_BLINK_ONESHOT;
95 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
96
97 if (invert)
98 led_cdev->flags |= LED_BLINK_INVERT;
99 else
100 led_cdev->flags &= ~LED_BLINK_INVERT;
101
102 led_blink_setup(led_cdev, delay_on, delay_off);
103}
104EXPORT_SYMBOL(led_blink_set_oneshot);
105
106void led_stop_software_blink(struct led_classdev *led_cdev)
107{
108 del_timer_sync(&led_cdev->blink_timer);
109 led_cdev->blink_delay_on = 0;
110 led_cdev->blink_delay_off = 0;
111}
112EXPORT_SYMBOL_GPL(led_stop_software_blink);
113
114void led_set_brightness(struct led_classdev *led_cdev,
115 enum led_brightness brightness)
116{
117 /* delay brightness setting if need to stop soft-blink timer */
118 if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
119 led_cdev->delayed_set_value = brightness;
120 schedule_work(&led_cdev->set_brightness_work);
121 return;
122 }
123
124 __led_set_brightness(led_cdev, brightness);
125}
126EXPORT_SYMBOL(led_set_brightness);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 3c972b2f989..4bebae73334 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -17,6 +17,7 @@
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/sysdev.h>
20#include <linux/timer.h> 21#include <linux/timer.h>
21#include <linux/rwsem.h> 22#include <linux/rwsem.h>
22#include <linux/leds.h> 23#include <linux/leds.h>
@@ -99,15 +100,9 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
99EXPORT_SYMBOL_GPL(led_trigger_show); 100EXPORT_SYMBOL_GPL(led_trigger_show);
100 101
101/* Caller must ensure led_cdev->trigger_lock held */ 102/* Caller must ensure led_cdev->trigger_lock held */
102void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) 103void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
103{ 104{
104 unsigned long flags; 105 unsigned long flags;
105 char *event = NULL;
106 char *envp[2];
107 const char *name;
108
109 name = trig ? trig->name : "none";
110 event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
111 106
112 /* Remove any existing trigger */ 107 /* Remove any existing trigger */
113 if (led_cdev->trigger) { 108 if (led_cdev->trigger) {
@@ -115,27 +110,18 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
115 list_del(&led_cdev->trig_list); 110 list_del(&led_cdev->trig_list);
116 write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, 111 write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock,
117 flags); 112 flags);
118 cancel_work_sync(&led_cdev->set_brightness_work);
119 led_stop_software_blink(led_cdev);
120 if (led_cdev->trigger->deactivate) 113 if (led_cdev->trigger->deactivate)
121 led_cdev->trigger->deactivate(led_cdev); 114 led_cdev->trigger->deactivate(led_cdev);
122 led_cdev->trigger = NULL; 115 led_cdev->trigger = NULL;
123 led_set_brightness(led_cdev, LED_OFF); 116 led_brightness_set(led_cdev, LED_OFF);
124 }
125 if (trig) {
126 write_lock_irqsave(&trig->leddev_list_lock, flags);
127 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
128 write_unlock_irqrestore(&trig->leddev_list_lock, flags);
129 led_cdev->trigger = trig;
130 if (trig->activate)
131 trig->activate(led_cdev);
132 } 117 }
133 118 if (trigger) {
134 if (event) { 119 write_lock_irqsave(&trigger->leddev_list_lock, flags);
135 envp[0] = event; 120 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs);
136 envp[1] = NULL; 121 write_unlock_irqrestore(&trigger->leddev_list_lock, flags);
137 kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp); 122 led_cdev->trigger = trigger;
138 kfree(event); 123 if (trigger->activate)
124 trigger->activate(led_cdev);
139 } 125 }
140} 126}
141EXPORT_SYMBOL_GPL(led_trigger_set); 127EXPORT_SYMBOL_GPL(led_trigger_set);
@@ -166,39 +152,26 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
166} 152}
167EXPORT_SYMBOL_GPL(led_trigger_set_default); 153EXPORT_SYMBOL_GPL(led_trigger_set_default);
168 154
169void led_trigger_rename_static(const char *name, struct led_trigger *trig)
170{
171 /* new name must be on a temporary string to prevent races */
172 BUG_ON(name == trig->name);
173
174 down_write(&triggers_list_lock);
175 /* this assumes that trig->name was originaly allocated to
176 * non constant storage */
177 strcpy((char *)trig->name, name);
178 up_write(&triggers_list_lock);
179}
180EXPORT_SYMBOL_GPL(led_trigger_rename_static);
181
182/* LED Trigger Interface */ 155/* LED Trigger Interface */
183 156
184int led_trigger_register(struct led_trigger *trig) 157int led_trigger_register(struct led_trigger *trigger)
185{ 158{
186 struct led_classdev *led_cdev; 159 struct led_classdev *led_cdev;
187 struct led_trigger *_trig; 160 struct led_trigger *trig;
188 161
189 rwlock_init(&trig->leddev_list_lock); 162 rwlock_init(&trigger->leddev_list_lock);
190 INIT_LIST_HEAD(&trig->led_cdevs); 163 INIT_LIST_HEAD(&trigger->led_cdevs);
191 164
192 down_write(&triggers_list_lock); 165 down_write(&triggers_list_lock);
193 /* Make sure the trigger's name isn't already in use */ 166 /* Make sure the trigger's name isn't already in use */
194 list_for_each_entry(_trig, &trigger_list, next_trig) { 167 list_for_each_entry(trig, &trigger_list, next_trig) {
195 if (!strcmp(_trig->name, trig->name)) { 168 if (!strcmp(trig->name, trigger->name)) {
196 up_write(&triggers_list_lock); 169 up_write(&triggers_list_lock);
197 return -EEXIST; 170 return -EEXIST;
198 } 171 }
199 } 172 }
200 /* Add to the list of led triggers */ 173 /* Add to the list of led triggers */
201 list_add_tail(&trig->next_trig, &trigger_list); 174 list_add_tail(&trigger->next_trig, &trigger_list);
202 up_write(&triggers_list_lock); 175 up_write(&triggers_list_lock);
203 176
204 /* Register with any LEDs that have this as a default trigger */ 177 /* Register with any LEDs that have this as a default trigger */
@@ -206,8 +179,8 @@ int led_trigger_register(struct led_trigger *trig)
206 list_for_each_entry(led_cdev, &leds_list, node) { 179 list_for_each_entry(led_cdev, &leds_list, node) {
207 down_write(&led_cdev->trigger_lock); 180 down_write(&led_cdev->trigger_lock);
208 if (!led_cdev->trigger && led_cdev->default_trigger && 181 if (!led_cdev->trigger && led_cdev->default_trigger &&
209 !strcmp(led_cdev->default_trigger, trig->name)) 182 !strcmp(led_cdev->default_trigger, trigger->name))
210 led_trigger_set(led_cdev, trig); 183 led_trigger_set(led_cdev, trigger);
211 up_write(&led_cdev->trigger_lock); 184 up_write(&led_cdev->trigger_lock);
212 } 185 }
213 up_read(&leds_list_lock); 186 up_read(&leds_list_lock);
@@ -216,20 +189,20 @@ int led_trigger_register(struct led_trigger *trig)
216} 189}
217EXPORT_SYMBOL_GPL(led_trigger_register); 190EXPORT_SYMBOL_GPL(led_trigger_register);
218 191
219void led_trigger_unregister(struct led_trigger *trig) 192void led_trigger_unregister(struct led_trigger *trigger)
220{ 193{
221 struct led_classdev *led_cdev; 194 struct led_classdev *led_cdev;
222 195
223 /* Remove from the list of led triggers */ 196 /* Remove from the list of led triggers */
224 down_write(&triggers_list_lock); 197 down_write(&triggers_list_lock);
225 list_del(&trig->next_trig); 198 list_del(&trigger->next_trig);
226 up_write(&triggers_list_lock); 199 up_write(&triggers_list_lock);
227 200
228 /* Remove anyone actively using this trigger */ 201 /* Remove anyone actively using this trigger */
229 down_read(&leds_list_lock); 202 down_read(&leds_list_lock);
230 list_for_each_entry(led_cdev, &leds_list, node) { 203 list_for_each_entry(led_cdev, &leds_list, node) {
231 down_write(&led_cdev->trigger_lock); 204 down_write(&led_cdev->trigger_lock);
232 if (led_cdev->trigger == trig) 205 if (led_cdev->trigger == trigger)
233 led_trigger_set(led_cdev, NULL); 206 led_trigger_set(led_cdev, NULL);
234 up_write(&led_cdev->trigger_lock); 207 up_write(&led_cdev->trigger_lock);
235 } 208 }
@@ -239,96 +212,71 @@ EXPORT_SYMBOL_GPL(led_trigger_unregister);
239 212
240/* Simple LED Tigger Interface */ 213/* Simple LED Tigger Interface */
241 214
242void led_trigger_event(struct led_trigger *trig, 215void led_trigger_event(struct led_trigger *trigger,
243 enum led_brightness brightness) 216 enum led_brightness brightness)
244{ 217{
245 struct list_head *entry; 218 struct list_head *entry;
246 219
247 if (!trig) 220 if (!trigger)
248 return; 221 return;
249 222
250 read_lock(&trig->leddev_list_lock); 223 read_lock(&trigger->leddev_list_lock);
251 list_for_each(entry, &trig->led_cdevs) { 224 list_for_each(entry, &trigger->led_cdevs) {
252 struct led_classdev *led_cdev; 225 struct led_classdev *led_cdev;
253 226
254 led_cdev = list_entry(entry, struct led_classdev, trig_list); 227 led_cdev = list_entry(entry, struct led_classdev, trig_list);
255 led_set_brightness(led_cdev, brightness); 228 led_set_brightness(led_cdev, brightness);
256 } 229 }
257 read_unlock(&trig->leddev_list_lock); 230 read_unlock(&trigger->leddev_list_lock);
258} 231}
259EXPORT_SYMBOL_GPL(led_trigger_event); 232EXPORT_SYMBOL_GPL(led_trigger_event);
260 233
261static void led_trigger_blink_setup(struct led_trigger *trig, 234void led_trigger_blink(struct led_trigger *trigger,
262 unsigned long *delay_on, 235 unsigned long *delay_on,
263 unsigned long *delay_off, 236 unsigned long *delay_off)
264 int oneshot,
265 int invert)
266{ 237{
267 struct list_head *entry; 238 struct list_head *entry;
268 239
269 if (!trig) 240 if (!trigger)
270 return; 241 return;
271 242
272 read_lock(&trig->leddev_list_lock); 243 read_lock(&trigger->leddev_list_lock);
273 list_for_each(entry, &trig->led_cdevs) { 244 list_for_each(entry, &trigger->led_cdevs) {
274 struct led_classdev *led_cdev; 245 struct led_classdev *led_cdev;
275 246
276 led_cdev = list_entry(entry, struct led_classdev, trig_list); 247 led_cdev = list_entry(entry, struct led_classdev, trig_list);
277 if (oneshot) 248 led_blink_set(led_cdev, delay_on, delay_off);
278 led_blink_set_oneshot(led_cdev, delay_on, delay_off,
279 invert);
280 else
281 led_blink_set(led_cdev, delay_on, delay_off);
282 } 249 }
283 read_unlock(&trig->leddev_list_lock); 250 read_unlock(&trigger->leddev_list_lock);
284}
285
286void led_trigger_blink(struct led_trigger *trig,
287 unsigned long *delay_on,
288 unsigned long *delay_off)
289{
290 led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
291} 251}
292EXPORT_SYMBOL_GPL(led_trigger_blink); 252EXPORT_SYMBOL_GPL(led_trigger_blink);
293 253
294void led_trigger_blink_oneshot(struct led_trigger *trig,
295 unsigned long *delay_on,
296 unsigned long *delay_off,
297 int invert)
298{
299 led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
300}
301EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
302
303void led_trigger_register_simple(const char *name, struct led_trigger **tp) 254void led_trigger_register_simple(const char *name, struct led_trigger **tp)
304{ 255{
305 struct led_trigger *trig; 256 struct led_trigger *trigger;
306 int err; 257 int err;
307 258
308 trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 259 trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
309 260
310 if (trig) { 261 if (trigger) {
311 trig->name = name; 262 trigger->name = name;
312 err = led_trigger_register(trig); 263 err = led_trigger_register(trigger);
313 if (err < 0) { 264 if (err < 0)
314 kfree(trig); 265 printk(KERN_WARNING "LED trigger %s failed to register"
315 trig = NULL; 266 " (%d)\n", name, err);
316 pr_warn("LED trigger %s failed to register (%d)\n", 267 } else
317 name, err); 268 printk(KERN_WARNING "LED trigger %s failed to register"
318 } 269 " (no memory)\n", name);
319 } else { 270
320 pr_warn("LED trigger %s failed to register (no memory)\n", 271 *tp = trigger;
321 name);
322 }
323 *tp = trig;
324} 272}
325EXPORT_SYMBOL_GPL(led_trigger_register_simple); 273EXPORT_SYMBOL_GPL(led_trigger_register_simple);
326 274
327void led_trigger_unregister_simple(struct led_trigger *trig) 275void led_trigger_unregister_simple(struct led_trigger *trigger)
328{ 276{
329 if (trig) 277 if (trigger)
330 led_trigger_unregister(trig); 278 led_trigger_unregister(trigger);
331 kfree(trig); 279 kfree(trigger);
332} 280}
333EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); 281EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
334 282
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 6be2edd4117..0d4c16678ac 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,21 +12,25 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/of.h>
16#include <linux/platform_device.h> 15#include <linux/platform_device.h>
17#include <linux/i2c.h> 16#include <linux/i2c.h>
18#include <linux/leds.h> 17#include <linux/leds.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/workqueue.h> 19#include <linux/workqueue.h>
21#include <linux/mfd/88pm860x.h> 20#include <linux/mfd/88pm860x.h>
22#include <linux/module.h>
23 21
22#define LED_PWM_SHIFT (3)
24#define LED_PWM_MASK (0x1F) 23#define LED_PWM_MASK (0x1F)
25#define LED_CURRENT_MASK (0x07 << 5) 24#define LED_CURRENT_MASK (0x07 << 5)
26 25
26#define LED_BLINK_ON_MASK (0x07)
27#define LED_BLINK_MASK (0x7F) 27#define LED_BLINK_MASK (0x7F)
28 28
29#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66)
30#define LED_BLINK_ON_MIN LED_BLINK_ON(0)
31#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7)
29#define LED_ON_CONTINUOUS (0x0F << 3) 32#define LED_ON_CONTINUOUS (0x0F << 3)
33#define LED_TO_ON(x) ((x - 66) / 66)
30 34
31#define LED1_BLINK_EN (1 << 1) 35#define LED1_BLINK_EN (1 << 1)
32#define LED2_BLINK_EN (1 << 2) 36#define LED2_BLINK_EN (1 << 2)
@@ -44,27 +48,66 @@ struct pm860x_led {
44 unsigned char brightness; 48 unsigned char brightness;
45 unsigned char current_brightness; 49 unsigned char current_brightness;
46 50
47 int reg_control; 51 int blink_data;
48 int reg_blink; 52 int blink_time;
49 int blink_mask; 53 int blink_on;
54 int blink_off;
50}; 55};
51 56
52static int led_power_set(struct pm860x_chip *chip, int port, int on) 57/* return offset of color register */
58static inline int __led_off(int port)
53{ 59{
54 int ret = -EINVAL; 60 int ret = -EINVAL;
55 61
56 switch (port) { 62 switch (port) {
57 case 0: 63 case PM8606_LED1_RED:
58 case 1: 64 case PM8606_LED1_GREEN:
59 case 2: 65 case PM8606_LED1_BLUE:
60 ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) : 66 ret = port - PM8606_LED1_RED + PM8606_RGB1B;
61 pm8606_osc_disable(chip, RGB1_ENABLE);
62 break; 67 break;
63 case 3: 68 case PM8606_LED2_RED:
64 case 4: 69 case PM8606_LED2_GREEN:
65 case 5: 70 case PM8606_LED2_BLUE:
66 ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) : 71 ret = port - PM8606_LED2_RED + PM8606_RGB2B;
67 pm8606_osc_disable(chip, RGB2_ENABLE); 72 break;
73 }
74 return ret;
75}
76
77/* return offset of blink register */
78static inline int __blink_off(int port)
79{
80 int ret = -EINVAL;
81
82 switch (port) {
83 case PM8606_LED1_RED:
84 case PM8606_LED1_GREEN:
85 case PM8606_LED1_BLUE:
86 ret = PM8606_RGB1A;
87 break;
88 case PM8606_LED2_RED:
89 case PM8606_LED2_GREEN:
90 case PM8606_LED2_BLUE:
91 ret = PM8606_RGB2A;
92 break;
93 }
94 return ret;
95}
96
97static inline int __blink_ctl_mask(int port)
98{
99 int ret = -EINVAL;
100
101 switch (port) {
102 case PM8606_LED1_RED:
103 case PM8606_LED1_GREEN:
104 case PM8606_LED1_BLUE:
105 ret = LED1_BLINK_EN;
106 break;
107 case PM8606_LED2_RED:
108 case PM8606_LED2_GREEN:
109 case PM8606_LED2_BLUE:
110 ret = LED2_BLINK_EN;
68 break; 111 break;
69 } 112 }
70 return ret; 113 return ret;
@@ -76,42 +119,40 @@ static void pm860x_led_work(struct work_struct *work)
76 struct pm860x_led *led; 119 struct pm860x_led *led;
77 struct pm860x_chip *chip; 120 struct pm860x_chip *chip;
78 unsigned char buf[3]; 121 unsigned char buf[3];
79 int ret; 122 int mask, ret;
80 123
81 led = container_of(work, struct pm860x_led, work); 124 led = container_of(work, struct pm860x_led, work);
82 chip = led->chip; 125 chip = led->chip;
83 mutex_lock(&led->lock); 126 mutex_lock(&led->lock);
84 if ((led->current_brightness == 0) && led->brightness) { 127 if ((led->current_brightness == 0) && led->brightness) {
85 led_power_set(chip, led->port, 1);
86 if (led->iset) { 128 if (led->iset) {
87 pm860x_set_bits(led->i2c, led->reg_control, 129 pm860x_set_bits(led->i2c, __led_off(led->port),
88 LED_CURRENT_MASK, led->iset); 130 LED_CURRENT_MASK, led->iset);
89 } 131 }
90 pm860x_set_bits(led->i2c, led->reg_blink, 132 pm860x_set_bits(led->i2c, __blink_off(led->port),
91 LED_BLINK_MASK, LED_ON_CONTINUOUS); 133 LED_BLINK_MASK, LED_ON_CONTINUOUS);
92 pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask, 134 mask = __blink_ctl_mask(led->port);
93 led->blink_mask); 135 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
94 } 136 }
95 pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK, 137 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
96 led->brightness); 138 led->brightness);
97 139
98 if (led->brightness == 0) { 140 if (led->brightness == 0) {
99 pm860x_bulk_read(led->i2c, led->reg_control, 3, buf); 141 pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
100 ret = buf[0] & LED_PWM_MASK; 142 ret = buf[0] & LED_PWM_MASK;
101 ret |= buf[1] & LED_PWM_MASK; 143 ret |= buf[1] & LED_PWM_MASK;
102 ret |= buf[2] & LED_PWM_MASK; 144 ret |= buf[2] & LED_PWM_MASK;
103 if (ret == 0) { 145 if (ret == 0) {
104 /* unset current since no led is lighting */ 146 /* unset current since no led is lighting */
105 pm860x_set_bits(led->i2c, led->reg_control, 147 pm860x_set_bits(led->i2c, __led_off(led->port),
106 LED_CURRENT_MASK, 0); 148 LED_CURRENT_MASK, 0);
107 pm860x_set_bits(led->i2c, PM8606_WLED3B, 149 mask = __blink_ctl_mask(led->port);
108 led->blink_mask, 0); 150 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
109 led_power_set(chip, led->port, 0);
110 } 151 }
111 } 152 }
112 led->current_brightness = led->brightness; 153 led->current_brightness = led->brightness;
113 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 154 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
114 led->reg_control, led->brightness); 155 __led_off(led->port), led->brightness);
115 mutex_unlock(&led->lock); 156 mutex_unlock(&led->lock);
116} 157}
117 158
@@ -124,90 +165,40 @@ static void pm860x_led_set(struct led_classdev *cdev,
124 schedule_work(&data->work); 165 schedule_work(&data->work);
125} 166}
126 167
127#ifdef CONFIG_OF
128static int pm860x_led_dt_init(struct platform_device *pdev,
129 struct pm860x_led *data)
130{
131 struct device_node *nproot = pdev->dev.parent->of_node, *np;
132 int iset = 0;
133 if (!nproot)
134 return -ENODEV;
135 nproot = of_find_node_by_name(nproot, "leds");
136 if (!nproot) {
137 dev_err(&pdev->dev, "failed to find leds node\n");
138 return -ENODEV;
139 }
140 for_each_child_of_node(nproot, np) {
141 if (!of_node_cmp(np->name, data->name)) {
142 of_property_read_u32(np, "marvell,88pm860x-iset",
143 &iset);
144 data->iset = PM8606_LED_CURRENT(iset);
145 break;
146 }
147 }
148 return 0;
149}
150#else
151#define pm860x_led_dt_init(x, y) (-1)
152#endif
153
154static int pm860x_led_probe(struct platform_device *pdev) 168static int pm860x_led_probe(struct platform_device *pdev)
155{ 169{
156 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 170 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
157 struct pm860x_led_pdata *pdata = pdev->dev.platform_data; 171 struct pm860x_led_pdata *pdata;
158 struct pm860x_led *data; 172 struct pm860x_led *data;
159 struct resource *res; 173 struct resource *res;
160 int ret = 0; 174 int ret;
161 175
162 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL); 176 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
163 if (data == NULL) 177 if (res == NULL) {
164 return -ENOMEM; 178 dev_err(&pdev->dev, "No I/O resource!\n");
165 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control"); 179 return -EINVAL;
166 if (!res) {
167 dev_err(&pdev->dev, "No REG resource for control\n");
168 return -ENXIO;
169 } 180 }
170 data->reg_control = res->start; 181
171 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink"); 182 pdata = pdev->dev.platform_data;
172 if (!res) { 183 if (pdata == NULL) {
173 dev_err(&pdev->dev, "No REG resource for blink\n"); 184 dev_err(&pdev->dev, "No platform data!\n");
174 return -ENXIO; 185 return -EINVAL;
175 }
176 data->reg_blink = res->start;
177 memset(data->name, 0, MFD_NAME_SIZE);
178 switch (pdev->id) {
179 case 0:
180 data->blink_mask = LED1_BLINK_EN;
181 sprintf(data->name, "led0-red");
182 break;
183 case 1:
184 data->blink_mask = LED1_BLINK_EN;
185 sprintf(data->name, "led0-green");
186 break;
187 case 2:
188 data->blink_mask = LED1_BLINK_EN;
189 sprintf(data->name, "led0-blue");
190 break;
191 case 3:
192 data->blink_mask = LED2_BLINK_EN;
193 sprintf(data->name, "led1-red");
194 break;
195 case 4:
196 data->blink_mask = LED2_BLINK_EN;
197 sprintf(data->name, "led1-green");
198 break;
199 case 5:
200 data->blink_mask = LED2_BLINK_EN;
201 sprintf(data->name, "led1-blue");
202 break;
203 } 186 }
187
188 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
189 if (data == NULL)
190 return -ENOMEM;
191 strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
204 dev_set_drvdata(&pdev->dev, data); 192 dev_set_drvdata(&pdev->dev, data);
205 data->chip = chip; 193 data->chip = chip;
206 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 194 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
207 data->port = pdev->id; 195 data->iset = pdata->iset;
208 if (pm860x_led_dt_init(pdev, data)) 196 data->port = pdata->flags;
209 if (pdata) 197 if (data->port < 0) {
210 data->iset = pdata->iset; 198 dev_err(&pdev->dev, "check device failed\n");
199 kfree(data);
200 return -EINVAL;
201 }
211 202
212 data->current_brightness = 0; 203 data->current_brightness = 0;
213 data->cdev.name = data->name; 204 data->cdev.name = data->name;
@@ -218,10 +209,13 @@ static int pm860x_led_probe(struct platform_device *pdev)
218 ret = led_classdev_register(chip->dev, &data->cdev); 209 ret = led_classdev_register(chip->dev, &data->cdev);
219 if (ret < 0) { 210 if (ret < 0) {
220 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 211 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
221 return ret; 212 goto out;
222 } 213 }
223 pm860x_led_set(&data->cdev, 0); 214 pm860x_led_set(&data->cdev, 0);
224 return 0; 215 return 0;
216out:
217 kfree(data);
218 return ret;
225} 219}
226 220
227static int pm860x_led_remove(struct platform_device *pdev) 221static int pm860x_led_remove(struct platform_device *pdev)
@@ -229,6 +223,7 @@ static int pm860x_led_remove(struct platform_device *pdev)
229 struct pm860x_led *data = platform_get_drvdata(pdev); 223 struct pm860x_led *data = platform_get_drvdata(pdev);
230 224
231 led_classdev_unregister(&data->cdev); 225 led_classdev_unregister(&data->cdev);
226 kfree(data);
232 227
233 return 0; 228 return 0;
234} 229}
@@ -242,7 +237,17 @@ static struct platform_driver pm860x_led_driver = {
242 .remove = pm860x_led_remove, 237 .remove = pm860x_led_remove,
243}; 238};
244 239
245module_platform_driver(pm860x_led_driver); 240static int __devinit pm860x_led_init(void)
241{
242 return platform_driver_register(&pm860x_led_driver);
243}
244module_init(pm860x_led_init);
245
246static void __devexit pm860x_led_exit(void)
247{
248 platform_driver_unregister(&pm860x_led_driver);
249}
250module_exit(pm860x_led_exit);
246 251
247MODULE_DESCRIPTION("LED driver for Marvell PM860x"); 252MODULE_DESCRIPTION("LED driver for Marvell PM860x");
248MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 253MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index e8072abe76e..7ba4c7b5b97 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -5,10 +5,10 @@
5 * 5 *
6 * Loosely derived from leds-da903x: 6 * Loosely derived from leds-da903x:
7 * Copyright (C) 2008 Compulab, Ltd. 7 * Copyright (C) 2008 Compulab, Ltd.
8 * Mike Rapoport <mike@compulab.co.il> 8 * Mike Rapoport <mike@compulab.co.il>
9 * 9 *
10 * Copyright (C) 2006-2008 Marvell International Ltd. 10 * Copyright (C) 2006-2008 Marvell International Ltd.
11 * Eric Miao <eric.miao@marvell.com> 11 * Eric Miao <eric.miao@marvell.com>
12 * 12 *
13 * Licensed under the GPL-2 or later. 13 * Licensed under the GPL-2 or later.
14 */ 14 */
@@ -85,7 +85,7 @@ static int adp5520_led_setup(struct adp5520_led *led)
85 return ret; 85 return ret;
86} 86}
87 87
88static int adp5520_led_prepare(struct platform_device *pdev) 88static int __devinit adp5520_led_prepare(struct platform_device *pdev)
89{ 89{
90 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 90 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
91 struct device *dev = pdev->dev.parent; 91 struct device *dev = pdev->dev.parent;
@@ -101,7 +101,7 @@ static int adp5520_led_prepare(struct platform_device *pdev)
101 return ret; 101 return ret;
102} 102}
103 103
104static int adp5520_led_probe(struct platform_device *pdev) 104static int __devinit adp5520_led_probe(struct platform_device *pdev)
105{ 105{
106 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 106 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
107 struct adp5520_led *led, *led_dat; 107 struct adp5520_led *led, *led_dat;
@@ -119,8 +119,7 @@ static int adp5520_led_probe(struct platform_device *pdev)
119 return -EFAULT; 119 return -EFAULT;
120 } 120 }
121 121
122 led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds, 122 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
123 GFP_KERNEL);
124 if (led == NULL) { 123 if (led == NULL) {
125 dev_err(&pdev->dev, "failed to alloc memory\n"); 124 dev_err(&pdev->dev, "failed to alloc memory\n");
126 return -ENOMEM; 125 return -ENOMEM;
@@ -130,7 +129,7 @@ static int adp5520_led_probe(struct platform_device *pdev)
130 129
131 if (ret) { 130 if (ret) {
132 dev_err(&pdev->dev, "failed to write\n"); 131 dev_err(&pdev->dev, "failed to write\n");
133 return ret; 132 goto err_free;
134 } 133 }
135 134
136 for (i = 0; i < pdata->num_leds; ++i) { 135 for (i = 0; i < pdata->num_leds; ++i) {
@@ -180,10 +179,12 @@ err:
180 } 179 }
181 } 180 }
182 181
182err_free:
183 kfree(led);
183 return ret; 184 return ret;
184} 185}
185 186
186static int adp5520_led_remove(struct platform_device *pdev) 187static int __devexit adp5520_led_remove(struct platform_device *pdev)
187{ 188{
188 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 189 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
189 struct adp5520_led *led; 190 struct adp5520_led *led;
@@ -199,6 +200,7 @@ static int adp5520_led_remove(struct platform_device *pdev)
199 cancel_work_sync(&led[i].work); 200 cancel_work_sync(&led[i].work);
200 } 201 }
201 202
203 kfree(led);
202 return 0; 204 return 0;
203} 205}
204 206
@@ -208,10 +210,20 @@ static struct platform_driver adp5520_led_driver = {
208 .owner = THIS_MODULE, 210 .owner = THIS_MODULE,
209 }, 211 },
210 .probe = adp5520_led_probe, 212 .probe = adp5520_led_probe,
211 .remove = adp5520_led_remove, 213 .remove = __devexit_p(adp5520_led_remove),
212}; 214};
213 215
214module_platform_driver(adp5520_led_driver); 216static int __init adp5520_led_init(void)
217{
218 return platform_driver_register(&adp5520_led_driver);
219}
220module_init(adp5520_led_init);
221
222static void __exit adp5520_led_exit(void)
223{
224 platform_driver_unregister(&adp5520_led_driver);
225}
226module_exit(adp5520_led_exit);
215 227
216MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 228MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
217MODULE_DESCRIPTION("LEDS ADP5520(01) Driver"); 229MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index b474745e001..22f847c890c 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -14,7 +14,6 @@
14 14
15#include <linux/mfd/asic3.h> 15#include <linux/mfd/asic3.h>
16#include <linux/mfd/core.h> 16#include <linux/mfd/core.h>
17#include <linux/module.h>
18 17
19/* 18/*
20 * The HTC ASIC3 LED GPIOs are inputs, not outputs. 19 * The HTC ASIC3 LED GPIOs are inputs, not outputs.
@@ -92,92 +91,75 @@ static int blink_set(struct led_classdev *cdev,
92 return 0; 91 return 0;
93} 92}
94 93
95static int asic3_led_probe(struct platform_device *pdev) 94static int __devinit asic3_led_probe(struct platform_device *pdev)
96{ 95{
97 struct asic3_led *led = pdev->dev.platform_data; 96 struct asic3_led *led = pdev->dev.platform_data;
98 int ret; 97 int ret;
99 98
100 ret = mfd_cell_enable(pdev); 99 ret = mfd_cell_enable(pdev);
101 if (ret < 0) 100 if (ret < 0)
102 return ret; 101 goto ret0;
103 102
104 led->cdev = devm_kzalloc(&pdev->dev, sizeof(struct led_classdev), 103 led->cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL);
105 GFP_KERNEL);
106 if (!led->cdev) { 104 if (!led->cdev) {
107 ret = -ENOMEM; 105 ret = -ENOMEM;
108 goto out; 106 goto ret1;
109 } 107 }
110 108
111 led->cdev->name = led->name; 109 led->cdev->name = led->name;
112 led->cdev->flags = LED_CORE_SUSPENDRESUME; 110 led->cdev->default_trigger = led->default_trigger;
113 led->cdev->brightness_set = brightness_set; 111 led->cdev->brightness_set = brightness_set;
114 led->cdev->blink_set = blink_set; 112 led->cdev->blink_set = blink_set;
115 led->cdev->default_trigger = led->default_trigger;
116 113
117 ret = led_classdev_register(&pdev->dev, led->cdev); 114 ret = led_classdev_register(&pdev->dev, led->cdev);
118 if (ret < 0) 115 if (ret < 0)
119 goto out; 116 goto ret2;
120 117
121 return 0; 118 return 0;
122 119
123out: 120ret2:
121 kfree(led->cdev);
122ret1:
124 (void) mfd_cell_disable(pdev); 123 (void) mfd_cell_disable(pdev);
124ret0:
125 return ret; 125 return ret;
126} 126}
127 127
128static int asic3_led_remove(struct platform_device *pdev) 128static int __devexit asic3_led_remove(struct platform_device *pdev)
129{ 129{
130 struct asic3_led *led = pdev->dev.platform_data; 130 struct asic3_led *led = pdev->dev.platform_data;
131 131
132 led_classdev_unregister(led->cdev); 132 led_classdev_unregister(led->cdev);
133 133
134 return mfd_cell_disable(pdev); 134 kfree(led->cdev);
135}
136
137static int asic3_led_suspend(struct device *dev)
138{
139 struct platform_device *pdev = to_platform_device(dev);
140 const struct mfd_cell *cell = mfd_get_cell(pdev);
141 int ret;
142
143 ret = 0;
144 if (cell->suspend)
145 ret = (*cell->suspend)(pdev);
146
147 return ret;
148}
149
150static int asic3_led_resume(struct device *dev)
151{
152 struct platform_device *pdev = to_platform_device(dev);
153 const struct mfd_cell *cell = mfd_get_cell(pdev);
154 int ret;
155
156 ret = 0;
157 if (cell->resume)
158 ret = (*cell->resume)(pdev);
159 135
160 return ret; 136 return mfd_cell_disable(pdev);
161} 137}
162 138
163static const struct dev_pm_ops asic3_led_pm_ops = {
164 .suspend = asic3_led_suspend,
165 .resume = asic3_led_resume,
166};
167
168static struct platform_driver asic3_led_driver = { 139static struct platform_driver asic3_led_driver = {
169 .probe = asic3_led_probe, 140 .probe = asic3_led_probe,
170 .remove = asic3_led_remove, 141 .remove = __devexit_p(asic3_led_remove),
171 .driver = { 142 .driver = {
172 .name = "leds-asic3", 143 .name = "leds-asic3",
173 .owner = THIS_MODULE, 144 .owner = THIS_MODULE,
174 .pm = &asic3_led_pm_ops,
175 }, 145 },
176}; 146};
177 147
178module_platform_driver(asic3_led_driver); 148MODULE_ALIAS("platform:leds-asic3");
149
150static int __init asic3_led_init(void)
151{
152 return platform_driver_register(&asic3_led_driver);
153}
154
155static void __exit asic3_led_exit(void)
156{
157 platform_driver_unregister(&asic3_led_driver);
158}
159
160module_init(asic3_led_init);
161module_exit(asic3_led_exit);
179 162
180MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); 163MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
181MODULE_DESCRIPTION("HTC ASIC3 LED driver"); 164MODULE_DESCRIPTION("HTC ASIC3 LED driver");
182MODULE_LICENSE("GPL"); 165MODULE_LICENSE("GPL");
183MODULE_ALIAS("platform:leds-asic3");
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 386773532d9..c941d906bba 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -4,7 +4,6 @@
4#include <linux/io.h> 4#include <linux/io.h>
5#include <linux/atmel_pwm.h> 5#include <linux/atmel_pwm.h>
6#include <linux/slab.h> 6#include <linux/slab.h>
7#include <linux/module.h>
8 7
9 8
10struct pwmled { 9struct pwmled {
@@ -35,7 +34,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
35 * NOTE: we reuse the platform_data structure of GPIO leds, 34 * NOTE: we reuse the platform_data structure of GPIO leds,
36 * but repurpose its "gpio" number as a PWM channel number. 35 * but repurpose its "gpio" number as a PWM channel number.
37 */ 36 */
38static int pwmled_probe(struct platform_device *pdev) 37static int __init pwmled_probe(struct platform_device *pdev)
39{ 38{
40 const struct gpio_led_platform_data *pdata; 39 const struct gpio_led_platform_data *pdata;
41 struct pwmled *leds; 40 struct pwmled *leds;
@@ -46,8 +45,7 @@ static int pwmled_probe(struct platform_device *pdev)
46 if (!pdata || pdata->num_leds < 1) 45 if (!pdata || pdata->num_leds < 1)
47 return -ENODEV; 46 return -ENODEV;
48 47
49 leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds), 48 leds = kcalloc(pdata->num_leds, sizeof(*leds), GFP_KERNEL);
50 GFP_KERNEL);
51 if (!leds) 49 if (!leds)
52 return -ENOMEM; 50 return -ENOMEM;
53 51
@@ -109,6 +107,7 @@ err:
109 pwm_channel_free(&leds[i].pwmc); 107 pwm_channel_free(&leds[i].pwmc);
110 } 108 }
111 } 109 }
110 kfree(leds);
112 111
113 return status; 112 return status;
114} 113}
@@ -129,22 +128,34 @@ static int __exit pwmled_remove(struct platform_device *pdev)
129 pwm_channel_free(&led->pwmc); 128 pwm_channel_free(&led->pwmc);
130 } 129 }
131 130
131 kfree(leds);
132 platform_set_drvdata(pdev, NULL); 132 platform_set_drvdata(pdev, NULL);
133 return 0; 133 return 0;
134} 134}
135 135
136/* work with hotplug and coldplug */
137MODULE_ALIAS("platform:leds-atmel-pwm");
138
136static struct platform_driver pwmled_driver = { 139static struct platform_driver pwmled_driver = {
137 .driver = { 140 .driver = {
138 .name = "leds-atmel-pwm", 141 .name = "leds-atmel-pwm",
139 .owner = THIS_MODULE, 142 .owner = THIS_MODULE,
140 }, 143 },
141 /* REVISIT add suspend() and resume() methods */ 144 /* REVISIT add suspend() and resume() methods */
142 .probe = pwmled_probe,
143 .remove = __exit_p(pwmled_remove), 145 .remove = __exit_p(pwmled_remove),
144}; 146};
145 147
146module_platform_driver(pwmled_driver); 148static int __init modinit(void)
149{
150 return platform_driver_probe(&pwmled_driver, pwmled_probe);
151}
152module_init(modinit);
153
154static void __exit modexit(void)
155{
156 platform_driver_unregister(&pwmled_driver);
157}
158module_exit(modexit);
147 159
148MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness"); 160MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
149MODULE_LICENSE("GPL"); 161MODULE_LICENSE("GPL");
150MODULE_ALIAS("platform:leds-atmel-pwm");
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 851517030cc..ea2185531f8 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -26,8 +26,8 @@
26#define BD2802_LED_OFFSET 0xa 26#define BD2802_LED_OFFSET 0xa
27#define BD2802_COLOR_OFFSET 0x3 27#define BD2802_COLOR_OFFSET 0x3
28 28
29#define BD2802_REG_CLKSETUP 0x00 29#define BD2802_REG_CLKSETUP 0x00
30#define BD2802_REG_CONTROL 0x01 30#define BD2802_REG_CONTROL 0x01
31#define BD2802_REG_HOURSETUP 0x02 31#define BD2802_REG_HOURSETUP 0x02
32#define BD2802_REG_CURRENT1SETUP 0x03 32#define BD2802_REG_CURRENT1SETUP 0x03
33#define BD2802_REG_CURRENT2SETUP 0x04 33#define BD2802_REG_CURRENT2SETUP 0x04
@@ -93,7 +93,7 @@ struct bd2802_led {
93 * In ADF mode, user can set registers of BD2802GU directly, 93 * In ADF mode, user can set registers of BD2802GU directly,
94 * therefore BD2802GU doesn't enter reset state. 94 * therefore BD2802GU doesn't enter reset state.
95 */ 95 */
96 int adf_on; 96 int adf_on;
97 97
98 enum led_ids led_id; 98 enum led_ids led_id;
99 enum led_colors color; 99 enum led_colors color;
@@ -328,7 +328,7 @@ static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
328 int ret; \ 328 int ret; \
329 if (!count) \ 329 if (!count) \
330 return -EINVAL; \ 330 return -EINVAL; \
331 ret = kstrtoul(buf, 16, &val); \ 331 ret = strict_strtoul(buf, 16, &val); \
332 if (ret) \ 332 if (ret) \
333 return ret; \ 333 return ret; \
334 down_write(&led->rwsem); \ 334 down_write(&led->rwsem); \
@@ -492,7 +492,7 @@ static ssize_t bd2802_store_##attr_name(struct device *dev, \
492 int ret; \ 492 int ret; \
493 if (!count) \ 493 if (!count) \
494 return -EINVAL; \ 494 return -EINVAL; \
495 ret = kstrtoul(buf, 16, &val); \ 495 ret = strict_strtoul(buf, 16, &val); \
496 if (ret) \ 496 if (ret) \
497 return ret; \ 497 return ret; \
498 down_write(&led->rwsem); \ 498 down_write(&led->rwsem); \
@@ -670,14 +670,14 @@ static void bd2802_unregister_led_classdev(struct bd2802_led *led)
670 led_classdev_unregister(&led->cdev_led1r); 670 led_classdev_unregister(&led->cdev_led1r);
671} 671}
672 672
673static int bd2802_probe(struct i2c_client *client, 673static int __devinit bd2802_probe(struct i2c_client *client,
674 const struct i2c_device_id *id) 674 const struct i2c_device_id *id)
675{ 675{
676 struct bd2802_led *led; 676 struct bd2802_led *led;
677 struct bd2802_led_platform_data *pdata; 677 struct bd2802_led_platform_data *pdata;
678 int ret, i; 678 int ret, i;
679 679
680 led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL); 680 led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
681 if (!led) { 681 if (!led) {
682 dev_err(&client->dev, "failed to allocate driver data\n"); 682 dev_err(&client->dev, "failed to allocate driver data\n");
683 return -ENOMEM; 683 return -ENOMEM;
@@ -688,7 +688,8 @@ static int bd2802_probe(struct i2c_client *client,
688 i2c_set_clientdata(client, led); 688 i2c_set_clientdata(client, led);
689 689
690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */ 690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
691 gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB"); 691 gpio_request(pdata->reset_gpio, "RGB_RESETB");
692 gpio_direction_output(pdata->reset_gpio, 1);
692 693
693 /* Tacss = min 0.1ms */ 694 /* Tacss = min 0.1ms */
694 udelay(100); 695 udelay(100);
@@ -697,7 +698,7 @@ static int bd2802_probe(struct i2c_client *client,
697 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00); 698 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
698 if (ret < 0) { 699 if (ret < 0) {
699 dev_err(&client->dev, "failed to detect device\n"); 700 dev_err(&client->dev, "failed to detect device\n");
700 return ret; 701 goto failed_free;
701 } else 702 } else
702 dev_info(&client->dev, "return 0x%02x\n", ret); 703 dev_info(&client->dev, "return 0x%02x\n", ret);
703 704
@@ -729,6 +730,9 @@ static int bd2802_probe(struct i2c_client *client,
729failed_unregister_dev_file: 730failed_unregister_dev_file:
730 for (i--; i >= 0; i--) 731 for (i--; i >= 0; i--)
731 device_remove_file(&led->client->dev, bd2802_attributes[i]); 732 device_remove_file(&led->client->dev, bd2802_attributes[i]);
733failed_free:
734 kfree(led);
735
732 return ret; 736 return ret;
733} 737}
734 738
@@ -743,6 +747,7 @@ static int __exit bd2802_remove(struct i2c_client *client)
743 bd2802_disable_adv_conf(led); 747 bd2802_disable_adv_conf(led);
744 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) 748 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
745 device_remove_file(&led->client->dev, bd2802_attributes[i]); 749 device_remove_file(&led->client->dev, bd2802_attributes[i]);
750 kfree(led);
746 751
747 return 0; 752 return 0;
748} 753}
@@ -808,7 +813,17 @@ static struct i2c_driver bd2802_i2c_driver = {
808 .id_table = bd2802_id, 813 .id_table = bd2802_id,
809}; 814};
810 815
811module_i2c_driver(bd2802_i2c_driver); 816static int __init bd2802_init(void)
817{
818 return i2c_add_driver(&bd2802_i2c_driver);
819}
820module_init(bd2802_init);
821
822static void __exit bd2802_exit(void)
823{
824 i2c_del_driver(&bd2802_i2c_driver);
825}
826module_exit(bd2802_exit);
812 827
813MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); 828MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
814MODULE_DESCRIPTION("BD2802 LED driver"); 829MODULE_DESCRIPTION("BD2802 LED driver");
diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c
deleted file mode 100644
index a502678cc7f..00000000000
--- a/drivers/leds/leds-blinkm.c
+++ /dev/null
@@ -1,815 +0,0 @@
1/*
2 * leds-blinkm.c
3 * (c) Jan-Simon Möller (dl9pf@gmx.de)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/err.h>
26#include <linux/mutex.h>
27#include <linux/sysfs.h>
28#include <linux/printk.h>
29#include <linux/pm_runtime.h>
30#include <linux/leds.h>
31#include <linux/delay.h>
32
33/* Addresses to scan - BlinkM is on 0x09 by default*/
34static const unsigned short normal_i2c[] = { 0x09, I2C_CLIENT_END };
35
36static int blinkm_transfer_hw(struct i2c_client *client, int cmd);
37static int blinkm_test_run(struct i2c_client *client);
38
39struct blinkm_led {
40 struct i2c_client *i2c_client;
41 struct led_classdev led_cdev;
42 int id;
43 atomic_t active;
44};
45
46struct blinkm_work {
47 struct blinkm_led *blinkm_led;
48 struct work_struct work;
49};
50
51#define cdev_to_blmled(c) container_of(c, struct blinkm_led, led_cdev)
52#define work_to_blmwork(c) container_of(c, struct blinkm_work, work)
53
54struct blinkm_data {
55 struct i2c_client *i2c_client;
56 struct mutex update_lock;
57 /* used for led class interface */
58 struct blinkm_led blinkm_leds[3];
59 /* used for "blinkm" sysfs interface */
60 u8 red; /* color red */
61 u8 green; /* color green */
62 u8 blue; /* color blue */
63 /* next values to use for transfer */
64 u8 next_red; /* color red */
65 u8 next_green; /* color green */
66 u8 next_blue; /* color blue */
67 /* internal use */
68 u8 args[7]; /* set of args for transmission */
69 u8 i2c_addr; /* i2c addr */
70 u8 fw_ver; /* firmware version */
71 /* used, but not from userspace */
72 u8 hue; /* HSB hue */
73 u8 saturation; /* HSB saturation */
74 u8 brightness; /* HSB brightness */
75 u8 next_hue; /* HSB hue */
76 u8 next_saturation; /* HSB saturation */
77 u8 next_brightness; /* HSB brightness */
78 /* currently unused / todo */
79 u8 fade_speed; /* fade speed 1 - 255 */
80 s8 time_adjust; /* time adjust -128 - 127 */
81 u8 fade:1; /* fade on = 1, off = 0 */
82 u8 rand:1; /* rand fade mode on = 1 */
83 u8 script_id; /* script ID */
84 u8 script_repeats; /* repeats of script */
85 u8 script_startline; /* line to start */
86};
87
88/* Colors */
89#define RED 0
90#define GREEN 1
91#define BLUE 2
92
93/* mapping command names to cmd chars - see datasheet */
94#define BLM_GO_RGB 0
95#define BLM_FADE_RGB 1
96#define BLM_FADE_HSB 2
97#define BLM_FADE_RAND_RGB 3
98#define BLM_FADE_RAND_HSB 4
99#define BLM_PLAY_SCRIPT 5
100#define BLM_STOP_SCRIPT 6
101#define BLM_SET_FADE_SPEED 7
102#define BLM_SET_TIME_ADJ 8
103#define BLM_GET_CUR_RGB 9
104#define BLM_WRITE_SCRIPT_LINE 10
105#define BLM_READ_SCRIPT_LINE 11
106#define BLM_SET_SCRIPT_LR 12 /* Length & Repeats */
107#define BLM_SET_ADDR 13
108#define BLM_GET_ADDR 14
109#define BLM_GET_FW_VER 15
110#define BLM_SET_STARTUP_PARAM 16
111
112/* BlinkM Commands
113 * as extracted out of the datasheet:
114 *
115 * cmdchar = command (ascii)
116 * cmdbyte = command in hex
117 * nr_args = number of arguments (to send)
118 * nr_ret = number of return values (to read)
119 * dir = direction (0 = read, 1 = write, 2 = both)
120 *
121 */
122static const struct {
123 char cmdchar;
124 u8 cmdbyte;
125 u8 nr_args;
126 u8 nr_ret;
127 u8 dir:2;
128} blinkm_cmds[17] = {
129 /* cmdchar, cmdbyte, nr_args, nr_ret, dir */
130 { 'n', 0x6e, 3, 0, 1},
131 { 'c', 0x63, 3, 0, 1},
132 { 'h', 0x68, 3, 0, 1},
133 { 'C', 0x43, 3, 0, 1},
134 { 'H', 0x48, 3, 0, 1},
135 { 'p', 0x70, 3, 0, 1},
136 { 'o', 0x6f, 0, 0, 1},
137 { 'f', 0x66, 1, 0, 1},
138 { 't', 0x74, 1, 0, 1},
139 { 'g', 0x67, 0, 3, 0},
140 { 'W', 0x57, 7, 0, 1},
141 { 'R', 0x52, 2, 5, 2},
142 { 'L', 0x4c, 3, 0, 1},
143 { 'A', 0x41, 4, 0, 1},
144 { 'a', 0x61, 0, 1, 0},
145 { 'Z', 0x5a, 0, 1, 0},
146 { 'B', 0x42, 5, 0, 1},
147};
148
149static ssize_t show_color_common(struct device *dev, char *buf, int color)
150{
151 struct i2c_client *client;
152 struct blinkm_data *data;
153 int ret;
154
155 client = to_i2c_client(dev);
156 data = i2c_get_clientdata(client);
157
158 ret = blinkm_transfer_hw(client, BLM_GET_CUR_RGB);
159 if (ret < 0)
160 return ret;
161 switch (color) {
162 case RED:
163 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->red);
164 break;
165 case GREEN:
166 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->green);
167 break;
168 case BLUE:
169 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->blue);
170 break;
171 default:
172 return -EINVAL;
173 }
174 return -EINVAL;
175}
176
177static int store_color_common(struct device *dev, const char *buf, int color)
178{
179 struct i2c_client *client;
180 struct blinkm_data *data;
181 int ret;
182 u8 value;
183
184 client = to_i2c_client(dev);
185 data = i2c_get_clientdata(client);
186
187 ret = kstrtou8(buf, 10, &value);
188 if (ret < 0) {
189 dev_err(dev, "BlinkM: value too large!\n");
190 return ret;
191 }
192
193 switch (color) {
194 case RED:
195 data->next_red = value;
196 break;
197 case GREEN:
198 data->next_green = value;
199 break;
200 case BLUE:
201 data->next_blue = value;
202 break;
203 default:
204 return -EINVAL;
205 }
206
207 dev_dbg(dev, "next_red = %d, next_green = %d, next_blue = %d\n",
208 data->next_red, data->next_green, data->next_blue);
209
210 /* if mode ... */
211 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
212 if (ret < 0) {
213 dev_err(dev, "BlinkM: can't set RGB\n");
214 return ret;
215 }
216 return 0;
217}
218
219static ssize_t show_red(struct device *dev, struct device_attribute *attr,
220 char *buf)
221{
222 return show_color_common(dev, buf, RED);
223}
224
225static ssize_t store_red(struct device *dev, struct device_attribute *attr,
226 const char *buf, size_t count)
227{
228 int ret;
229
230 ret = store_color_common(dev, buf, RED);
231 if (ret < 0)
232 return ret;
233 return count;
234}
235
236static DEVICE_ATTR(red, S_IRUGO | S_IWUSR, show_red, store_red);
237
238static ssize_t show_green(struct device *dev, struct device_attribute *attr,
239 char *buf)
240{
241 return show_color_common(dev, buf, GREEN);
242}
243
244static ssize_t store_green(struct device *dev, struct device_attribute *attr,
245 const char *buf, size_t count)
246{
247
248 int ret;
249
250 ret = store_color_common(dev, buf, GREEN);
251 if (ret < 0)
252 return ret;
253 return count;
254}
255
256static DEVICE_ATTR(green, S_IRUGO | S_IWUSR, show_green, store_green);
257
258static ssize_t show_blue(struct device *dev, struct device_attribute *attr,
259 char *buf)
260{
261 return show_color_common(dev, buf, BLUE);
262}
263
264static ssize_t store_blue(struct device *dev, struct device_attribute *attr,
265 const char *buf, size_t count)
266{
267 int ret;
268
269 ret = store_color_common(dev, buf, BLUE);
270 if (ret < 0)
271 return ret;
272 return count;
273}
274
275static DEVICE_ATTR(blue, S_IRUGO | S_IWUSR, show_blue, store_blue);
276
277static ssize_t show_test(struct device *dev, struct device_attribute *attr,
278 char *buf)
279{
280 return scnprintf(buf, PAGE_SIZE,
281 "#Write into test to start test sequence!#\n");
282}
283
284static ssize_t store_test(struct device *dev, struct device_attribute *attr,
285 const char *buf, size_t count)
286{
287
288 struct i2c_client *client;
289 int ret;
290 client = to_i2c_client(dev);
291
292 /*test */
293 ret = blinkm_test_run(client);
294 if (ret < 0)
295 return ret;
296
297 return count;
298}
299
300static DEVICE_ATTR(test, S_IRUGO | S_IWUSR, show_test, store_test);
301
302/* TODO: HSB, fade, timeadj, script ... */
303
304static struct attribute *blinkm_attrs[] = {
305 &dev_attr_red.attr,
306 &dev_attr_green.attr,
307 &dev_attr_blue.attr,
308 &dev_attr_test.attr,
309 NULL,
310};
311
312static struct attribute_group blinkm_group = {
313 .name = "blinkm",
314 .attrs = blinkm_attrs,
315};
316
317static int blinkm_write(struct i2c_client *client, int cmd, u8 *arg)
318{
319 int result;
320 int i;
321 int arglen = blinkm_cmds[cmd].nr_args;
322 /* write out cmd to blinkm - always / default step */
323 result = i2c_smbus_write_byte(client, blinkm_cmds[cmd].cmdbyte);
324 if (result < 0)
325 return result;
326 /* no args to write out */
327 if (arglen == 0)
328 return 0;
329
330 for (i = 0; i < arglen; i++) {
331 /* repeat for arglen */
332 result = i2c_smbus_write_byte(client, arg[i]);
333 if (result < 0)
334 return result;
335 }
336 return 0;
337}
338
339static int blinkm_read(struct i2c_client *client, int cmd, u8 *arg)
340{
341 int result;
342 int i;
343 int retlen = blinkm_cmds[cmd].nr_ret;
344 for (i = 0; i < retlen; i++) {
345 /* repeat for retlen */
346 result = i2c_smbus_read_byte(client);
347 if (result < 0)
348 return result;
349 arg[i] = result;
350 }
351
352 return 0;
353}
354
355static int blinkm_transfer_hw(struct i2c_client *client, int cmd)
356{
357 /* the protocol is simple but non-standard:
358 * e.g. cmd 'g' (= 0x67) for "get device address"
359 * - which defaults to 0x09 - would be the sequence:
360 * a) write 0x67 to the device (byte write)
361 * b) read the value (0x09) back right after (byte read)
362 *
363 * Watch out for "unfinished" sequences (i.e. not enough reads
364 * or writes after a command. It will make the blinkM misbehave.
365 * Sequence is key here.
366 */
367
368 /* args / return are in private data struct */
369 struct blinkm_data *data = i2c_get_clientdata(client);
370
371 /* We start hardware transfers which are not to be
372 * mixed with other commands. Aquire a lock now. */
373 if (mutex_lock_interruptible(&data->update_lock) < 0)
374 return -EAGAIN;
375
376 /* switch cmd - usually write before reads */
377 switch (cmd) {
378 case BLM_FADE_RAND_RGB:
379 case BLM_GO_RGB:
380 case BLM_FADE_RGB:
381 data->args[0] = data->next_red;
382 data->args[1] = data->next_green;
383 data->args[2] = data->next_blue;
384 blinkm_write(client, cmd, data->args);
385 data->red = data->args[0];
386 data->green = data->args[1];
387 data->blue = data->args[2];
388 break;
389 case BLM_FADE_HSB:
390 case BLM_FADE_RAND_HSB:
391 data->args[0] = data->next_hue;
392 data->args[1] = data->next_saturation;
393 data->args[2] = data->next_brightness;
394 blinkm_write(client, cmd, data->args);
395 data->hue = data->next_hue;
396 data->saturation = data->next_saturation;
397 data->brightness = data->next_brightness;
398 break;
399 case BLM_PLAY_SCRIPT:
400 data->args[0] = data->script_id;
401 data->args[1] = data->script_repeats;
402 data->args[2] = data->script_startline;
403 blinkm_write(client, cmd, data->args);
404 break;
405 case BLM_STOP_SCRIPT:
406 blinkm_write(client, cmd, NULL);
407 break;
408 case BLM_GET_CUR_RGB:
409 data->args[0] = data->red;
410 data->args[1] = data->green;
411 data->args[2] = data->blue;
412 blinkm_write(client, cmd, NULL);
413 blinkm_read(client, cmd, data->args);
414 data->red = data->args[0];
415 data->green = data->args[1];
416 data->blue = data->args[2];
417 break;
418 case BLM_GET_ADDR:
419 data->args[0] = data->i2c_addr;
420 blinkm_write(client, cmd, NULL);
421 blinkm_read(client, cmd, data->args);
422 data->i2c_addr = data->args[0];
423 break;
424 case BLM_SET_TIME_ADJ:
425 case BLM_SET_FADE_SPEED:
426 case BLM_READ_SCRIPT_LINE:
427 case BLM_WRITE_SCRIPT_LINE:
428 case BLM_SET_SCRIPT_LR:
429 case BLM_SET_ADDR:
430 case BLM_GET_FW_VER:
431 case BLM_SET_STARTUP_PARAM:
432 dev_err(&client->dev,
433 "BlinkM: cmd %d not implemented yet.\n", cmd);
434 break;
435 default:
436 dev_err(&client->dev, "BlinkM: unknown command %d\n", cmd);
437 mutex_unlock(&data->update_lock);
438 return -EINVAL;
439 } /* end switch(cmd) */
440
441 /* transfers done, unlock */
442 mutex_unlock(&data->update_lock);
443 return 0;
444}
445
446static void led_work(struct work_struct *work)
447{
448 int ret;
449 struct blinkm_led *led;
450 struct blinkm_data *data ;
451 struct blinkm_work *blm_work = work_to_blmwork(work);
452
453 led = blm_work->blinkm_led;
454 data = i2c_get_clientdata(led->i2c_client);
455 ret = blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB);
456 atomic_dec(&led->active);
457 dev_dbg(&led->i2c_client->dev,
458 "# DONE # next_red = %d, next_green = %d,"
459 " next_blue = %d, active = %d\n",
460 data->next_red, data->next_green,
461 data->next_blue, atomic_read(&led->active));
462 kfree(blm_work);
463}
464
465static int blinkm_led_common_set(struct led_classdev *led_cdev,
466 enum led_brightness value, int color)
467{
468 /* led_brightness is 0, 127 or 255 - we just use it here as-is */
469 struct blinkm_led *led = cdev_to_blmled(led_cdev);
470 struct blinkm_data *data = i2c_get_clientdata(led->i2c_client);
471 struct blinkm_work *bl_work;
472
473 switch (color) {
474 case RED:
475 /* bail out if there's no change */
476 if (data->next_red == (u8) value)
477 return 0;
478 /* we assume a quite fast sequence here ([off]->on->off)
479 * think of network led trigger - we cannot blink that fast, so
480 * in case we already have a off->on->off transition queued up,
481 * we refuse to queue up more.
482 * Revisit: fast-changing brightness. */
483 if (atomic_read(&led->active) > 1)
484 return 0;
485 data->next_red = (u8) value;
486 break;
487 case GREEN:
488 /* bail out if there's no change */
489 if (data->next_green == (u8) value)
490 return 0;
491 /* we assume a quite fast sequence here ([off]->on->off)
492 * Revisit: fast-changing brightness. */
493 if (atomic_read(&led->active) > 1)
494 return 0;
495 data->next_green = (u8) value;
496 break;
497 case BLUE:
498 /* bail out if there's no change */
499 if (data->next_blue == (u8) value)
500 return 0;
501 /* we assume a quite fast sequence here ([off]->on->off)
502 * Revisit: fast-changing brightness. */
503 if (atomic_read(&led->active) > 1)
504 return 0;
505 data->next_blue = (u8) value;
506 break;
507
508 default:
509 dev_err(&led->i2c_client->dev, "BlinkM: unknown color.\n");
510 return -EINVAL;
511 }
512
513 bl_work = kzalloc(sizeof(*bl_work), GFP_ATOMIC);
514 if (!bl_work)
515 return -ENOMEM;
516
517 atomic_inc(&led->active);
518 dev_dbg(&led->i2c_client->dev,
519 "#TO_SCHED# next_red = %d, next_green = %d,"
520 " next_blue = %d, active = %d\n",
521 data->next_red, data->next_green,
522 data->next_blue, atomic_read(&led->active));
523
524 /* a fresh work _item_ for each change */
525 bl_work->blinkm_led = led;
526 INIT_WORK(&bl_work->work, led_work);
527 /* queue work in own queue for easy sync on exit*/
528 schedule_work(&bl_work->work);
529
530 return 0;
531}
532
533static void blinkm_led_red_set(struct led_classdev *led_cdev,
534 enum led_brightness value)
535{
536 blinkm_led_common_set(led_cdev, value, RED);
537}
538
539static void blinkm_led_green_set(struct led_classdev *led_cdev,
540 enum led_brightness value)
541{
542 blinkm_led_common_set(led_cdev, value, GREEN);
543}
544
545static void blinkm_led_blue_set(struct led_classdev *led_cdev,
546 enum led_brightness value)
547{
548 blinkm_led_common_set(led_cdev, value, BLUE);
549}
550
551static void blinkm_init_hw(struct i2c_client *client)
552{
553 int ret;
554 ret = blinkm_transfer_hw(client, BLM_STOP_SCRIPT);
555 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
556}
557
558static int blinkm_test_run(struct i2c_client *client)
559{
560 int ret;
561 struct blinkm_data *data = i2c_get_clientdata(client);
562
563 data->next_red = 0x01;
564 data->next_green = 0x05;
565 data->next_blue = 0x10;
566 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
567 if (ret < 0)
568 return ret;
569 msleep(2000);
570
571 data->next_red = 0x25;
572 data->next_green = 0x10;
573 data->next_blue = 0x31;
574 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
575 if (ret < 0)
576 return ret;
577 msleep(2000);
578
579 data->next_hue = 0x50;
580 data->next_saturation = 0x10;
581 data->next_brightness = 0x20;
582 ret = blinkm_transfer_hw(client, BLM_FADE_HSB);
583 if (ret < 0)
584 return ret;
585 msleep(2000);
586
587 return 0;
588}
589
590/* Return 0 if detection is successful, -ENODEV otherwise */
591static int blinkm_detect(struct i2c_client *client, struct i2c_board_info *info)
592{
593 struct i2c_adapter *adapter = client->adapter;
594 int ret;
595 int count = 99;
596 u8 tmpargs[7];
597
598 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
599 | I2C_FUNC_SMBUS_WORD_DATA
600 | I2C_FUNC_SMBUS_WRITE_BYTE))
601 return -ENODEV;
602
603 /* Now, we do the remaining detection. Simple for now. */
604 /* We might need more guards to protect other i2c slaves */
605
606 /* make sure the blinkM is balanced (read/writes) */
607 while (count > 0) {
608 ret = blinkm_write(client, BLM_GET_ADDR, NULL);
609 usleep_range(5000, 10000);
610 ret = blinkm_read(client, BLM_GET_ADDR, tmpargs);
611 usleep_range(5000, 10000);
612 if (tmpargs[0] == 0x09)
613 count = 0;
614 count--;
615 }
616
617 /* Step 1: Read BlinkM address back - cmd_char 'a' */
618 ret = blinkm_write(client, BLM_GET_ADDR, NULL);
619 if (ret < 0)
620 return ret;
621 usleep_range(20000, 30000); /* allow a small delay */
622 ret = blinkm_read(client, BLM_GET_ADDR, tmpargs);
623 if (ret < 0)
624 return ret;
625
626 if (tmpargs[0] != 0x09) {
627 dev_err(&client->dev, "enodev DEV ADDR = 0x%02X\n", tmpargs[0]);
628 return -ENODEV;
629 }
630
631 strlcpy(info->type, "blinkm", I2C_NAME_SIZE);
632 return 0;
633}
634
635static int blinkm_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)
637{
638 struct blinkm_data *data;
639 struct blinkm_led *led[3];
640 int err, i;
641 char blinkm_led_name[28];
642
643 data = devm_kzalloc(&client->dev,
644 sizeof(struct blinkm_data), GFP_KERNEL);
645 if (!data) {
646 err = -ENOMEM;
647 goto exit;
648 }
649
650 data->i2c_addr = 0x09;
651 data->i2c_addr = 0x08;
652 /* i2c addr - use fake addr of 0x08 initially (real is 0x09) */
653 data->fw_ver = 0xfe;
654 /* firmware version - use fake until we read real value
655 * (currently broken - BlinkM confused!) */
656 data->script_id = 0x01;
657 data->i2c_client = client;
658
659 i2c_set_clientdata(client, data);
660 mutex_init(&data->update_lock);
661
662 /* Register sysfs hooks */
663 err = sysfs_create_group(&client->dev.kobj, &blinkm_group);
664 if (err < 0) {
665 dev_err(&client->dev, "couldn't register sysfs group\n");
666 goto exit;
667 }
668
669 for (i = 0; i < 3; i++) {
670 /* RED = 0, GREEN = 1, BLUE = 2 */
671 led[i] = &data->blinkm_leds[i];
672 led[i]->i2c_client = client;
673 led[i]->id = i;
674 led[i]->led_cdev.max_brightness = 255;
675 led[i]->led_cdev.flags = LED_CORE_SUSPENDRESUME;
676 atomic_set(&led[i]->active, 0);
677 switch (i) {
678 case RED:
679 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
680 "blinkm-%d-%d-red",
681 client->adapter->nr,
682 client->addr);
683 led[i]->led_cdev.name = blinkm_led_name;
684 led[i]->led_cdev.brightness_set = blinkm_led_red_set;
685 err = led_classdev_register(&client->dev,
686 &led[i]->led_cdev);
687 if (err < 0) {
688 dev_err(&client->dev,
689 "couldn't register LED %s\n",
690 led[i]->led_cdev.name);
691 goto failred;
692 }
693 break;
694 case GREEN:
695 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
696 "blinkm-%d-%d-green",
697 client->adapter->nr,
698 client->addr);
699 led[i]->led_cdev.name = blinkm_led_name;
700 led[i]->led_cdev.brightness_set = blinkm_led_green_set;
701 err = led_classdev_register(&client->dev,
702 &led[i]->led_cdev);
703 if (err < 0) {
704 dev_err(&client->dev,
705 "couldn't register LED %s\n",
706 led[i]->led_cdev.name);
707 goto failgreen;
708 }
709 break;
710 case BLUE:
711 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
712 "blinkm-%d-%d-blue",
713 client->adapter->nr,
714 client->addr);
715 led[i]->led_cdev.name = blinkm_led_name;
716 led[i]->led_cdev.brightness_set = blinkm_led_blue_set;
717 err = led_classdev_register(&client->dev,
718 &led[i]->led_cdev);
719 if (err < 0) {
720 dev_err(&client->dev,
721 "couldn't register LED %s\n",
722 led[i]->led_cdev.name);
723 goto failblue;
724 }
725 break;
726 } /* end switch */
727 } /* end for */
728
729 /* Initialize the blinkm */
730 blinkm_init_hw(client);
731
732 return 0;
733
734failblue:
735 led_classdev_unregister(&led[GREEN]->led_cdev);
736
737failgreen:
738 led_classdev_unregister(&led[RED]->led_cdev);
739
740failred:
741 sysfs_remove_group(&client->dev.kobj, &blinkm_group);
742exit:
743 return err;
744}
745
746static int blinkm_remove(struct i2c_client *client)
747{
748 struct blinkm_data *data = i2c_get_clientdata(client);
749 int ret = 0;
750 int i;
751
752 /* make sure no workqueue entries are pending */
753 for (i = 0; i < 3; i++) {
754 flush_scheduled_work();
755 led_classdev_unregister(&data->blinkm_leds[i].led_cdev);
756 }
757
758 /* reset rgb */
759 data->next_red = 0x00;
760 data->next_green = 0x00;
761 data->next_blue = 0x00;
762 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
763 if (ret < 0)
764 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
765
766 /* reset hsb */
767 data->next_hue = 0x00;
768 data->next_saturation = 0x00;
769 data->next_brightness = 0x00;
770 ret = blinkm_transfer_hw(client, BLM_FADE_HSB);
771 if (ret < 0)
772 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
773
774 /* red fade to off */
775 data->next_red = 0xff;
776 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
777 if (ret < 0)
778 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
779
780 /* off */
781 data->next_red = 0x00;
782 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
783 if (ret < 0)
784 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
785
786 sysfs_remove_group(&client->dev.kobj, &blinkm_group);
787 return 0;
788}
789
790static const struct i2c_device_id blinkm_id[] = {
791 {"blinkm", 0},
792 {}
793};
794
795MODULE_DEVICE_TABLE(i2c, blinkm_id);
796
797 /* This is the driver that will be inserted */
798static struct i2c_driver blinkm_driver = {
799 .class = I2C_CLASS_HWMON,
800 .driver = {
801 .name = "blinkm",
802 },
803 .probe = blinkm_probe,
804 .remove = blinkm_remove,
805 .id_table = blinkm_id,
806 .detect = blinkm_detect,
807 .address_list = normal_i2c,
808};
809
810module_i2c_driver(blinkm_driver);
811
812MODULE_AUTHOR("Jan-Simon Moeller <dl9pf@gmx.de>");
813MODULE_DESCRIPTION("BlinkM RGB LED driver");
814MODULE_LICENSE("GPL");
815
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index 6a8405df76a..a498135a4e8 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -1,4 +1,3 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2 1
3#include <linux/module.h> 2#include <linux/module.h>
4 3
@@ -19,7 +18,7 @@ MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
19MODULE_DESCRIPTION("Clevo mail LED driver"); 18MODULE_DESCRIPTION("Clevo mail LED driver");
20MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
21 20
22static bool __initdata nodetect; 21static unsigned int __initdata nodetect;
23module_param_named(nodetect, nodetect, bool, 0); 22module_param_named(nodetect, nodetect, bool, 0);
24MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection"); 23MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection");
25 24
@@ -27,12 +26,12 @@ static struct platform_device *pdev;
27 26
28static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id) 27static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
29{ 28{
30 pr_info("'%s' found\n", id->ident); 29 printk(KERN_INFO KBUILD_MODNAME ": '%s' found\n", id->ident);
31 return 1; 30 return 1;
32} 31}
33 32
34/* 33/*
35 * struct clevo_mail_led_dmi_table - List of known good models 34 * struct mail_led_whitelist - List of known good models
36 * 35 *
37 * Contains the known good models this driver is compatible with. 36 * Contains the known good models this driver is compatible with.
38 * When adding a new model try to be as strict as possible. This 37 * When adding a new model try to be as strict as possible. This
@@ -40,7 +39,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
40 * detected as working, but in reality it is not) as low as 39 * detected as working, but in reality it is not) as low as
41 * possible. 40 * possible.
42 */ 41 */
43static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = { 42static struct dmi_system_id __initdata mail_led_whitelist[] = {
44 { 43 {
45 .callback = clevo_mail_led_dmi_callback, 44 .callback = clevo_mail_led_dmi_callback,
46 .ident = "Clevo D410J", 45 .ident = "Clevo D410J",
@@ -60,10 +59,11 @@ static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = {
60 }, 59 },
61 { 60 {
62 .callback = clevo_mail_led_dmi_callback, 61 .callback = clevo_mail_led_dmi_callback,
63 .ident = "Clevo M5x0V", 62 .ident = "Positivo Mobile",
64 .matches = { 63 .matches = {
65 DMI_MATCH(DMI_BOARD_VENDOR, "CLEVO Co. "), 64 DMI_MATCH(DMI_BOARD_VENDOR, "CLEVO Co. "),
66 DMI_MATCH(DMI_BOARD_NAME, "M5X0V "), 65 DMI_MATCH(DMI_BOARD_NAME, "M5X0V "),
66 DMI_MATCH(DMI_PRODUCT_NAME, "Positivo Mobile"),
67 DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198") 67 DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198")
68 } 68 }
69 }, 69 },
@@ -89,7 +89,6 @@ static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = {
89 }, 89 },
90 { } 90 { }
91}; 91};
92MODULE_DEVICE_TABLE(dmi, clevo_mail_led_dmi_table);
93 92
94static void clevo_mail_led_set(struct led_classdev *led_cdev, 93static void clevo_mail_led_set(struct led_classdev *led_cdev,
95 enum led_brightness value) 94 enum led_brightness value)
@@ -136,7 +135,8 @@ static int clevo_mail_led_blink(struct led_classdev *led_cdev,
136 status = 0; 135 status = 0;
137 136
138 } else { 137 } else {
139 pr_debug("clevo_mail_led_blink(..., %lu, %lu)," 138 printk(KERN_DEBUG KBUILD_MODNAME
139 ": clevo_mail_led_blink(..., %lu, %lu),"
140 " returning -EINVAL (unsupported)\n", 140 " returning -EINVAL (unsupported)\n",
141 *delay_on, *delay_off); 141 *delay_on, *delay_off);
142 } 142 }
@@ -153,7 +153,7 @@ static struct led_classdev clevo_mail_led = {
153 .flags = LED_CORE_SUSPENDRESUME, 153 .flags = LED_CORE_SUSPENDRESUME,
154}; 154};
155 155
156static int clevo_mail_led_probe(struct platform_device *pdev) 156static int __devinit clevo_mail_led_probe(struct platform_device *pdev)
157{ 157{
158 return led_classdev_register(&pdev->dev, &clevo_mail_led); 158 return led_classdev_register(&pdev->dev, &clevo_mail_led);
159} 159}
@@ -180,10 +180,10 @@ static int __init clevo_mail_led_init(void)
180 180
181 /* Check with the help of DMI if we are running on supported hardware */ 181 /* Check with the help of DMI if we are running on supported hardware */
182 if (!nodetect) { 182 if (!nodetect) {
183 count = dmi_check_system(clevo_mail_led_dmi_table); 183 count = dmi_check_system(mail_led_whitelist);
184 } else { 184 } else {
185 count = 1; 185 count = 1;
186 pr_err("Skipping DMI detection. " 186 printk(KERN_ERR KBUILD_MODNAME ": Skipping DMI detection. "
187 "If the driver works on your hardware please " 187 "If the driver works on your hardware please "
188 "report model and the output of dmidecode in tracker " 188 "report model and the output of dmidecode in tracker "
189 "at http://sourceforge.net/projects/clevo-mailled/\n"); 189 "at http://sourceforge.net/projects/clevo-mailled/\n");
@@ -197,7 +197,8 @@ static int __init clevo_mail_led_init(void)
197 error = platform_driver_probe(&clevo_mail_led_driver, 197 error = platform_driver_probe(&clevo_mail_led_driver,
198 clevo_mail_led_probe); 198 clevo_mail_led_probe);
199 if (error) { 199 if (error) {
200 pr_err("Can't probe platform driver\n"); 200 printk(KERN_ERR KBUILD_MODNAME
201 ": Can't probe platform driver\n");
201 platform_device_unregister(pdev); 202 platform_device_unregister(pdev);
202 } 203 }
203 } else 204 } else
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index 8abcb66db01..da5fb016b1a 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -34,7 +34,7 @@ static struct led_classdev qube_front_led = {
34 .default_trigger = "default-on", 34 .default_trigger = "default-on",
35}; 35};
36 36
37static int cobalt_qube_led_probe(struct platform_device *pdev) 37static int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
38{ 38{
39 struct resource *res; 39 struct resource *res;
40 int retval; 40 int retval;
@@ -43,7 +43,7 @@ static int cobalt_qube_led_probe(struct platform_device *pdev)
43 if (!res) 43 if (!res)
44 return -EBUSY; 44 return -EBUSY;
45 45
46 led_port = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 46 led_port = ioremap(res->start, resource_size(res));
47 if (!led_port) 47 if (!led_port)
48 return -ENOMEM; 48 return -ENOMEM;
49 49
@@ -52,38 +52,54 @@ static int cobalt_qube_led_probe(struct platform_device *pdev)
52 52
53 retval = led_classdev_register(&pdev->dev, &qube_front_led); 53 retval = led_classdev_register(&pdev->dev, &qube_front_led);
54 if (retval) 54 if (retval)
55 goto err_null; 55 goto err_iounmap;
56 56
57 return 0; 57 return 0;
58 58
59err_null: 59err_iounmap:
60 iounmap(led_port);
60 led_port = NULL; 61 led_port = NULL;
61 62
62 return retval; 63 return retval;
63} 64}
64 65
65static int cobalt_qube_led_remove(struct platform_device *pdev) 66static int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
66{ 67{
67 led_classdev_unregister(&qube_front_led); 68 led_classdev_unregister(&qube_front_led);
68 69
69 if (led_port) 70 if (led_port) {
71 iounmap(led_port);
70 led_port = NULL; 72 led_port = NULL;
73 }
71 74
72 return 0; 75 return 0;
73} 76}
74 77
78/* work with hotplug and coldplug */
79MODULE_ALIAS("platform:cobalt-qube-leds");
80
75static struct platform_driver cobalt_qube_led_driver = { 81static struct platform_driver cobalt_qube_led_driver = {
76 .probe = cobalt_qube_led_probe, 82 .probe = cobalt_qube_led_probe,
77 .remove = cobalt_qube_led_remove, 83 .remove = __devexit_p(cobalt_qube_led_remove),
78 .driver = { 84 .driver = {
79 .name = "cobalt-qube-leds", 85 .name = "cobalt-qube-leds",
80 .owner = THIS_MODULE, 86 .owner = THIS_MODULE,
81 }, 87 },
82}; 88};
83 89
84module_platform_driver(cobalt_qube_led_driver); 90static int __init cobalt_qube_led_init(void)
91{
92 return platform_driver_register(&cobalt_qube_led_driver);
93}
94
95static void __exit cobalt_qube_led_exit(void)
96{
97 platform_driver_unregister(&cobalt_qube_led_driver);
98}
99
100module_init(cobalt_qube_led_init);
101module_exit(cobalt_qube_led_exit);
85 102
86MODULE_LICENSE("GPL"); 103MODULE_LICENSE("GPL");
87MODULE_DESCRIPTION("Front LED support for Cobalt Server"); 104MODULE_DESCRIPTION("Front LED support for Cobalt Server");
88MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 105MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
89MODULE_ALIAS("platform:cobalt-qube-leds");
diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c
index 001088b3137..438d4838463 100644
--- a/drivers/leds/leds-cobalt-raq.c
+++ b/drivers/leds/leds-cobalt-raq.c
@@ -24,7 +24,6 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/export.h>
28 27
29#define LED_WEB 0x04 28#define LED_WEB 0x04
30#define LED_POWER_OFF 0x08 29#define LED_POWER_OFF 0x08
@@ -76,7 +75,7 @@ static struct led_classdev raq_power_off_led = {
76 .default_trigger = "power-off", 75 .default_trigger = "power-off",
77}; 76};
78 77
79static int cobalt_raq_led_probe(struct platform_device *pdev) 78static int __devinit cobalt_raq_led_probe(struct platform_device *pdev)
80{ 79{
81 struct resource *res; 80 struct resource *res;
82 int retval; 81 int retval;
@@ -85,13 +84,13 @@ static int cobalt_raq_led_probe(struct platform_device *pdev)
85 if (!res) 84 if (!res)
86 return -EBUSY; 85 return -EBUSY;
87 86
88 led_port = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 87 led_port = ioremap(res->start, resource_size(res));
89 if (!led_port) 88 if (!led_port)
90 return -ENOMEM; 89 return -ENOMEM;
91 90
92 retval = led_classdev_register(&pdev->dev, &raq_power_off_led); 91 retval = led_classdev_register(&pdev->dev, &raq_power_off_led);
93 if (retval) 92 if (retval)
94 goto err_null; 93 goto err_iounmap;
95 94
96 retval = led_classdev_register(&pdev->dev, &raq_web_led); 95 retval = led_classdev_register(&pdev->dev, &raq_web_led);
97 if (retval) 96 if (retval)
@@ -102,26 +101,29 @@ static int cobalt_raq_led_probe(struct platform_device *pdev)
102err_unregister: 101err_unregister:
103 led_classdev_unregister(&raq_power_off_led); 102 led_classdev_unregister(&raq_power_off_led);
104 103
105err_null: 104err_iounmap:
105 iounmap(led_port);
106 led_port = NULL; 106 led_port = NULL;
107 107
108 return retval; 108 return retval;
109} 109}
110 110
111static int cobalt_raq_led_remove(struct platform_device *pdev) 111static int __devexit cobalt_raq_led_remove(struct platform_device *pdev)
112{ 112{
113 led_classdev_unregister(&raq_power_off_led); 113 led_classdev_unregister(&raq_power_off_led);
114 led_classdev_unregister(&raq_web_led); 114 led_classdev_unregister(&raq_web_led);
115 115
116 if (led_port) 116 if (led_port) {
117 iounmap(led_port);
117 led_port = NULL; 118 led_port = NULL;
119 }
118 120
119 return 0; 121 return 0;
120} 122}
121 123
122static struct platform_driver cobalt_raq_led_driver = { 124static struct platform_driver cobalt_raq_led_driver = {
123 .probe = cobalt_raq_led_probe, 125 .probe = cobalt_raq_led_probe,
124 .remove = cobalt_raq_led_remove, 126 .remove = __devexit_p(cobalt_raq_led_remove),
125 .driver = { 127 .driver = {
126 .name = "cobalt-raq-leds", 128 .name = "cobalt-raq-leds",
127 .owner = THIS_MODULE, 129 .owner = THIS_MODULE,
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index c263a21db82..f28931cf678 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -2,10 +2,10 @@
2 * LEDs driver for Dialog Semiconductor DA9030/DA9034 2 * LEDs driver for Dialog Semiconductor DA9030/DA9034
3 * 3 *
4 * Copyright (C) 2008 Compulab, Ltd. 4 * Copyright (C) 2008 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il> 5 * Mike Rapoport <mike@compulab.co.il>
6 * 6 *
7 * Copyright (C) 2006-2008 Marvell International Ltd. 7 * Copyright (C) 2006-2008 Marvell International Ltd.
8 * Eric Miao <eric.miao@marvell.com> 8 * Eric Miao <eric.miao@marvell.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of the GNU General Public License version 2 as
@@ -85,13 +85,13 @@ static void da903x_led_set(struct led_classdev *led_cdev,
85 enum led_brightness value) 85 enum led_brightness value)
86{ 86{
87 struct da903x_led *led; 87 struct da903x_led *led;
88 88
89 led = container_of(led_cdev, struct da903x_led, cdev); 89 led = container_of(led_cdev, struct da903x_led, cdev);
90 led->new_brightness = value; 90 led->new_brightness = value;
91 schedule_work(&led->work); 91 schedule_work(&led->work);
92} 92}
93 93
94static int da903x_led_probe(struct platform_device *pdev) 94static int __devinit da903x_led_probe(struct platform_device *pdev)
95{ 95{
96 struct led_info *pdata = pdev->dev.platform_data; 96 struct led_info *pdata = pdev->dev.platform_data;
97 struct da903x_led *led; 97 struct da903x_led *led;
@@ -108,7 +108,7 @@ static int da903x_led_probe(struct platform_device *pdev)
108 return -EINVAL; 108 return -EINVAL;
109 } 109 }
110 110
111 led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL); 111 led = kzalloc(sizeof(struct da903x_led), GFP_KERNEL);
112 if (led == NULL) { 112 if (led == NULL) {
113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id); 113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
114 return -ENOMEM; 114 return -ENOMEM;
@@ -129,18 +129,23 @@ static int da903x_led_probe(struct platform_device *pdev)
129 ret = led_classdev_register(led->master, &led->cdev); 129 ret = led_classdev_register(led->master, &led->cdev);
130 if (ret) { 130 if (ret) {
131 dev_err(&pdev->dev, "failed to register LED %d\n", id); 131 dev_err(&pdev->dev, "failed to register LED %d\n", id);
132 return ret; 132 goto err;
133 } 133 }
134 134
135 platform_set_drvdata(pdev, led); 135 platform_set_drvdata(pdev, led);
136 return 0; 136 return 0;
137
138err:
139 kfree(led);
140 return ret;
137} 141}
138 142
139static int da903x_led_remove(struct platform_device *pdev) 143static int __devexit da903x_led_remove(struct platform_device *pdev)
140{ 144{
141 struct da903x_led *led = platform_get_drvdata(pdev); 145 struct da903x_led *led = platform_get_drvdata(pdev);
142 146
143 led_classdev_unregister(&led->cdev); 147 led_classdev_unregister(&led->cdev);
148 kfree(led);
144 return 0; 149 return 0;
145} 150}
146 151
@@ -150,13 +155,23 @@ static struct platform_driver da903x_led_driver = {
150 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
151 }, 156 },
152 .probe = da903x_led_probe, 157 .probe = da903x_led_probe,
153 .remove = da903x_led_remove, 158 .remove = __devexit_p(da903x_led_remove),
154}; 159};
155 160
156module_platform_driver(da903x_led_driver); 161static int __init da903x_led_init(void)
162{
163 return platform_driver_register(&da903x_led_driver);
164}
165module_init(da903x_led_init);
166
167static void __exit da903x_led_exit(void)
168{
169 platform_driver_unregister(&da903x_led_driver);
170}
171module_exit(da903x_led_exit);
157 172
158MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034"); 173MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
159MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); 174MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
160MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 175 "Mike Rapoport <mike@compulab.co.il>");
161MODULE_LICENSE("GPL"); 176MODULE_LICENSE("GPL");
162MODULE_ALIAS("platform:da903x-led"); 177MODULE_ALIAS("platform:da903x-led");
diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c
deleted file mode 100644
index efec43344e9..00000000000
--- a/drivers/leds/leds-da9052.c
+++ /dev/null
@@ -1,214 +0,0 @@
1/*
2 * LED Driver for Dialog DA9052 PMICs.
3 *
4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/leds.h>
20#include <linux/workqueue.h>
21#include <linux/slab.h>
22
23#include <linux/mfd/da9052/reg.h>
24#include <linux/mfd/da9052/da9052.h>
25#include <linux/mfd/da9052/pdata.h>
26
27#define DA9052_OPENDRAIN_OUTPUT 2
28#define DA9052_SET_HIGH_LVL_OUTPUT (1 << 3)
29#define DA9052_MASK_UPPER_NIBBLE 0xF0
30#define DA9052_MASK_LOWER_NIBBLE 0x0F
31#define DA9052_NIBBLE_SHIFT 4
32#define DA9052_MAX_BRIGHTNESS 0x5f
33
34struct da9052_led {
35 struct led_classdev cdev;
36 struct work_struct work;
37 struct da9052 *da9052;
38 unsigned char led_index;
39 unsigned char id;
40 int brightness;
41};
42
43static unsigned char led_reg[] = {
44 DA9052_LED_CONT_4_REG,
45 DA9052_LED_CONT_5_REG,
46};
47
48static int da9052_set_led_brightness(struct da9052_led *led)
49{
50 u8 val;
51 int error;
52
53 val = (led->brightness & 0x7f) | DA9052_LED_CONT_DIM;
54
55 error = da9052_reg_write(led->da9052, led_reg[led->led_index], val);
56 if (error < 0)
57 dev_err(led->da9052->dev, "Failed to set led brightness, %d\n",
58 error);
59 return error;
60}
61
62static void da9052_led_work(struct work_struct *work)
63{
64 struct da9052_led *led = container_of(work, struct da9052_led, work);
65
66 da9052_set_led_brightness(led);
67}
68
69static void da9052_led_set(struct led_classdev *led_cdev,
70 enum led_brightness value)
71{
72 struct da9052_led *led;
73
74 led = container_of(led_cdev, struct da9052_led, cdev);
75 led->brightness = value;
76 schedule_work(&led->work);
77}
78
79static int da9052_configure_leds(struct da9052 *da9052)
80{
81 int error;
82 unsigned char register_value = DA9052_OPENDRAIN_OUTPUT
83 | DA9052_SET_HIGH_LVL_OUTPUT;
84
85 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG,
86 DA9052_MASK_LOWER_NIBBLE,
87 register_value);
88
89 if (error < 0) {
90 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n",
91 error);
92 return error;
93 }
94
95 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG,
96 DA9052_MASK_UPPER_NIBBLE,
97 register_value << DA9052_NIBBLE_SHIFT);
98 if (error < 0)
99 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n",
100 error);
101
102 return error;
103}
104
105static int da9052_led_probe(struct platform_device *pdev)
106{
107 struct da9052_pdata *pdata;
108 struct da9052 *da9052;
109 struct led_platform_data *pled;
110 struct da9052_led *led = NULL;
111 int error = -ENODEV;
112 int i;
113
114 da9052 = dev_get_drvdata(pdev->dev.parent);
115 pdata = da9052->dev->platform_data;
116 if (pdata == NULL) {
117 dev_err(&pdev->dev, "No platform data\n");
118 goto err;
119 }
120
121 pled = pdata->pled;
122 if (pled == NULL) {
123 dev_err(&pdev->dev, "No platform data for LED\n");
124 goto err;
125 }
126
127 led = devm_kzalloc(&pdev->dev,
128 sizeof(struct da9052_led) * pled->num_leds,
129 GFP_KERNEL);
130 if (led == NULL) {
131 dev_err(&pdev->dev, "Failed to alloc memory\n");
132 error = -ENOMEM;
133 goto err;
134 }
135
136 for (i = 0; i < pled->num_leds; i++) {
137 led[i].cdev.name = pled->leds[i].name;
138 led[i].cdev.brightness_set = da9052_led_set;
139 led[i].cdev.brightness = LED_OFF;
140 led[i].cdev.max_brightness = DA9052_MAX_BRIGHTNESS;
141 led[i].brightness = LED_OFF;
142 led[i].led_index = pled->leds[i].flags;
143 led[i].da9052 = dev_get_drvdata(pdev->dev.parent);
144 INIT_WORK(&led[i].work, da9052_led_work);
145
146 error = led_classdev_register(pdev->dev.parent, &led[i].cdev);
147 if (error) {
148 dev_err(&pdev->dev, "Failed to register led %d\n",
149 led[i].led_index);
150 goto err_register;
151 }
152
153 error = da9052_set_led_brightness(&led[i]);
154 if (error) {
155 dev_err(&pdev->dev, "Unable to init led %d\n",
156 led[i].led_index);
157 continue;
158 }
159 }
160 error = da9052_configure_leds(led->da9052);
161 if (error) {
162 dev_err(&pdev->dev, "Failed to configure GPIO LED%d\n", error);
163 goto err_register;
164 }
165
166 platform_set_drvdata(pdev, led);
167
168 return 0;
169
170err_register:
171 for (i = i - 1; i >= 0; i--) {
172 led_classdev_unregister(&led[i].cdev);
173 cancel_work_sync(&led[i].work);
174 }
175err:
176 return error;
177}
178
179static int da9052_led_remove(struct platform_device *pdev)
180{
181 struct da9052_led *led = platform_get_drvdata(pdev);
182 struct da9052_pdata *pdata;
183 struct da9052 *da9052;
184 struct led_platform_data *pled;
185 int i;
186
187 da9052 = dev_get_drvdata(pdev->dev.parent);
188 pdata = da9052->dev->platform_data;
189 pled = pdata->pled;
190
191 for (i = 0; i < pled->num_leds; i++) {
192 led[i].brightness = 0;
193 da9052_set_led_brightness(&led[i]);
194 led_classdev_unregister(&led[i].cdev);
195 cancel_work_sync(&led[i].work);
196 }
197
198 return 0;
199}
200
201static struct platform_driver da9052_led_driver = {
202 .driver = {
203 .name = "da9052-leds",
204 .owner = THIS_MODULE,
205 },
206 .probe = da9052_led_probe,
207 .remove = da9052_led_remove,
208};
209
210module_platform_driver(da9052_led_driver);
211
212MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>");
213MODULE_DESCRIPTION("LED driver for Dialog DA9052 PMIC");
214MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
index 1f9d8e62d37..31cf0d60a9a 100644
--- a/drivers/leds/leds-dac124s085.c
+++ b/drivers/leds/leds-dac124s085.c
@@ -69,7 +69,7 @@ static int dac124s085_probe(struct spi_device *spi)
69 struct dac124s085_led *led; 69 struct dac124s085_led *led;
70 int i, ret; 70 int i, ret;
71 71
72 dac = devm_kzalloc(&spi->dev, sizeof(*dac), GFP_KERNEL); 72 dac = kzalloc(sizeof(*dac), GFP_KERNEL);
73 if (!dac) 73 if (!dac)
74 return -ENOMEM; 74 return -ENOMEM;
75 75
@@ -102,6 +102,7 @@ eledcr:
102 led_classdev_unregister(&dac->leds[i].ldev); 102 led_classdev_unregister(&dac->leds[i].ldev);
103 103
104 spi_set_drvdata(spi, NULL); 104 spi_set_drvdata(spi, NULL);
105 kfree(dac);
105 return ret; 106 return ret;
106} 107}
107 108
@@ -116,6 +117,7 @@ static int dac124s085_remove(struct spi_device *spi)
116 } 117 }
117 118
118 spi_set_drvdata(spi, NULL); 119 spi_set_drvdata(spi, NULL);
120 kfree(dac);
119 121
120 return 0; 122 return 0;
121} 123}
@@ -129,7 +131,18 @@ static struct spi_driver dac124s085_driver = {
129 }, 131 },
130}; 132};
131 133
132module_spi_driver(dac124s085_driver); 134static int __init dac124s085_leds_init(void)
135{
136 return spi_register_driver(&dac124s085_driver);
137}
138
139static void __exit dac124s085_leds_exit(void)
140{
141 spi_unregister_driver(&dac124s085_driver);
142}
143
144module_init(dac124s085_leds_init);
145module_exit(dac124s085_leds_exit);
133 146
134MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); 147MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
135MODULE_DESCRIPTION("DAC124S085 LED driver"); 148MODULE_DESCRIPTION("DAC124S085 LED driver");
diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c
index b4d5a44cc41..d11d05be0de 100644
--- a/drivers/leds/leds-fsg.c
+++ b/drivers/leds/leds-fsg.c
@@ -19,9 +19,8 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/leds.h> 21#include <linux/leds.h>
22#include <linux/module.h>
23#include <linux/io.h>
24#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <asm/io.h>
25 24
26#define FSG_LED_WLAN_BIT 0 25#define FSG_LED_WLAN_BIT 0
27#define FSG_LED_WAN_BIT 1 26#define FSG_LED_WAN_BIT 1
@@ -149,10 +148,11 @@ static int fsg_led_probe(struct platform_device *pdev)
149 int ret; 148 int ret;
150 149
151 /* Map the LED chip select address space */ 150 /* Map the LED chip select address space */
152 latch_address = (unsigned short *) devm_ioremap(&pdev->dev, 151 latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
153 IXP4XX_EXP_BUS_BASE(2), 512); 152 if (!latch_address) {
154 if (!latch_address) 153 ret = -ENOMEM;
155 return -ENOMEM; 154 goto failremap;
155 }
156 156
157 latch_value = 0xffff; 157 latch_value = 0xffff;
158 *latch_address = latch_value; 158 *latch_address = latch_value;
@@ -194,6 +194,8 @@ static int fsg_led_probe(struct platform_device *pdev)
194 failwan: 194 failwan:
195 led_classdev_unregister(&fsg_wlan_led); 195 led_classdev_unregister(&fsg_wlan_led);
196 failwlan: 196 failwlan:
197 iounmap(latch_address);
198 failremap:
197 199
198 return ret; 200 return ret;
199} 201}
@@ -207,6 +209,8 @@ static int fsg_led_remove(struct platform_device *pdev)
207 led_classdev_unregister(&fsg_sync_led); 209 led_classdev_unregister(&fsg_sync_led);
208 led_classdev_unregister(&fsg_ring_led); 210 led_classdev_unregister(&fsg_ring_led);
209 211
212 iounmap(latch_address);
213
210 return 0; 214 return 0;
211} 215}
212 216
@@ -219,7 +223,20 @@ static struct platform_driver fsg_led_driver = {
219 }, 223 },
220}; 224};
221 225
222module_platform_driver(fsg_led_driver); 226
227static int __init fsg_led_init(void)
228{
229 return platform_driver_register(&fsg_led_driver);
230}
231
232static void __exit fsg_led_exit(void)
233{
234 platform_driver_unregister(&fsg_led_driver);
235}
236
237
238module_init(fsg_led_init);
239module_exit(fsg_led_exit);
223 240
224MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>"); 241MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
225MODULE_DESCRIPTION("Freecom FSG-3 LED driver"); 242MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index a0d931bcb37..3d8bc327a68 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -13,15 +13,13 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/gpio.h>
17#include <linux/leds.h> 16#include <linux/leds.h>
18#include <linux/of_platform.h> 17#include <linux/of_platform.h>
19#include <linux/of_gpio.h> 18#include <linux/of_gpio.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/workqueue.h> 20#include <linux/workqueue.h>
22#include <linux/module.h> 21
23#include <linux/pinctrl/consumer.h> 22#include <asm/gpio.h>
24#include <linux/err.h>
25 23
26struct gpio_led_data { 24struct gpio_led_data {
27 struct led_classdev cdev; 25 struct led_classdev cdev;
@@ -92,7 +90,7 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
92 delay_on, delay_off); 90 delay_on, delay_off);
93} 91}
94 92
95static int create_gpio_led(const struct gpio_led *template, 93static int __devinit create_gpio_led(const struct gpio_led *template,
96 struct gpio_led_data *led_dat, struct device *parent, 94 struct gpio_led_data *led_dat, struct device *parent,
97 int (*blink_set)(unsigned, int, unsigned long *, unsigned long *)) 95 int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
98{ 96{
@@ -102,11 +100,15 @@ static int create_gpio_led(const struct gpio_led *template,
102 100
103 /* skip leds that aren't available */ 101 /* skip leds that aren't available */
104 if (!gpio_is_valid(template->gpio)) { 102 if (!gpio_is_valid(template->gpio)) {
105 dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n", 103 printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n",
106 template->gpio, template->name); 104 template->gpio, template->name);
107 return 0; 105 return 0;
108 } 106 }
109 107
108 ret = gpio_request(template->gpio, template->name);
109 if (ret < 0)
110 return ret;
111
110 led_dat->cdev.name = template->name; 112 led_dat->cdev.name = template->name;
111 led_dat->cdev.default_trigger = template->default_trigger; 113 led_dat->cdev.default_trigger = template->default_trigger;
112 led_dat->gpio = template->gpio; 114 led_dat->gpio = template->gpio;
@@ -119,27 +121,27 @@ static int create_gpio_led(const struct gpio_led *template,
119 } 121 }
120 led_dat->cdev.brightness_set = gpio_led_set; 122 led_dat->cdev.brightness_set = gpio_led_set;
121 if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) 123 if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
122 state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low; 124 state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low;
123 else 125 else
124 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); 126 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
125 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; 127 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
126 if (!template->retain_state_suspended) 128 if (!template->retain_state_suspended)
127 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 129 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
128 130
129 ret = devm_gpio_request_one(parent, template->gpio, 131 ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
130 (led_dat->active_low ^ state) ?
131 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
132 template->name);
133 if (ret < 0) 132 if (ret < 0)
134 return ret; 133 goto err;
135 134
136 INIT_WORK(&led_dat->work, gpio_led_work); 135 INIT_WORK(&led_dat->work, gpio_led_work);
137 136
138 ret = led_classdev_register(parent, &led_dat->cdev); 137 ret = led_classdev_register(parent, &led_dat->cdev);
139 if (ret < 0) 138 if (ret < 0)
140 return ret; 139 goto err;
141 140
142 return 0; 141 return 0;
142err:
143 gpio_free(led_dat->gpio);
144 return ret;
143} 145}
144 146
145static void delete_gpio_led(struct gpio_led_data *led) 147static void delete_gpio_led(struct gpio_led_data *led)
@@ -148,6 +150,7 @@ static void delete_gpio_led(struct gpio_led_data *led)
148 return; 150 return;
149 led_classdev_unregister(&led->cdev); 151 led_classdev_unregister(&led->cdev);
150 cancel_work_sync(&led->work); 152 cancel_work_sync(&led->work);
153 gpio_free(led->gpio);
151} 154}
152 155
153struct gpio_leds_priv { 156struct gpio_leds_priv {
@@ -163,25 +166,21 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
163 166
164/* Code to create from OpenFirmware platform devices */ 167/* Code to create from OpenFirmware platform devices */
165#ifdef CONFIG_OF_GPIO 168#ifdef CONFIG_OF_GPIO
166static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 169static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
167{ 170{
168 struct device_node *np = pdev->dev.of_node, *child; 171 struct device_node *np = pdev->dev.of_node, *child;
169 struct gpio_leds_priv *priv; 172 struct gpio_leds_priv *priv;
170 int count, ret; 173 int count = 0, ret;
171 174
172 /* count LEDs in this device, so we know how much to allocate */ 175 /* count LEDs in this device, so we know how much to allocate */
173 count = of_get_child_count(np);
174 if (!count)
175 return ERR_PTR(-ENODEV);
176
177 for_each_child_of_node(np, child) 176 for_each_child_of_node(np, child)
178 if (of_get_gpio(child, 0) == -EPROBE_DEFER) 177 count++;
179 return ERR_PTR(-EPROBE_DEFER); 178 if (!count)
179 return NULL;
180 180
181 priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), 181 priv = kzalloc(sizeof_gpio_leds_priv(count), GFP_KERNEL);
182 GFP_KERNEL);
183 if (!priv) 182 if (!priv)
184 return ERR_PTR(-ENOMEM); 183 return NULL;
185 184
186 for_each_child_of_node(np, child) { 185 for_each_child_of_node(np, child) {
187 struct gpio_led led = {}; 186 struct gpio_led led = {};
@@ -216,7 +215,8 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
216err: 215err:
217 for (count = priv->num_leds - 2; count >= 0; count--) 216 for (count = priv->num_leds - 2; count >= 0; count--)
218 delete_gpio_led(&priv->leds[count]); 217 delete_gpio_led(&priv->leds[count]);
219 return ERR_PTR(-ENODEV); 218 kfree(priv);
219 return NULL;
220} 220}
221 221
222static const struct of_device_id of_gpio_leds_match[] = { 222static const struct of_device_id of_gpio_leds_match[] = {
@@ -224,29 +224,23 @@ static const struct of_device_id of_gpio_leds_match[] = {
224 {}, 224 {},
225}; 225};
226#else /* CONFIG_OF_GPIO */ 226#else /* CONFIG_OF_GPIO */
227static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 227static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev)
228{ 228{
229 return ERR_PTR(-ENODEV); 229 return NULL;
230} 230}
231#define of_gpio_leds_match NULL
231#endif /* CONFIG_OF_GPIO */ 232#endif /* CONFIG_OF_GPIO */
232 233
233 234
234static int gpio_led_probe(struct platform_device *pdev) 235static int __devinit gpio_led_probe(struct platform_device *pdev)
235{ 236{
236 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 237 struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
237 struct gpio_leds_priv *priv; 238 struct gpio_leds_priv *priv;
238 struct pinctrl *pinctrl;
239 int i, ret = 0; 239 int i, ret = 0;
240 240
241 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
242 if (IS_ERR(pinctrl))
243 dev_warn(&pdev->dev,
244 "pins are not configured from the driver\n");
245
246 if (pdata && pdata->num_leds) { 241 if (pdata && pdata->num_leds) {
247 priv = devm_kzalloc(&pdev->dev, 242 priv = kzalloc(sizeof_gpio_leds_priv(pdata->num_leds),
248 sizeof_gpio_leds_priv(pdata->num_leds), 243 GFP_KERNEL);
249 GFP_KERNEL);
250 if (!priv) 244 if (!priv)
251 return -ENOMEM; 245 return -ENOMEM;
252 246
@@ -259,13 +253,14 @@ static int gpio_led_probe(struct platform_device *pdev)
259 /* On failure: unwind the led creations */ 253 /* On failure: unwind the led creations */
260 for (i = i - 1; i >= 0; i--) 254 for (i = i - 1; i >= 0; i--)
261 delete_gpio_led(&priv->leds[i]); 255 delete_gpio_led(&priv->leds[i]);
256 kfree(priv);
262 return ret; 257 return ret;
263 } 258 }
264 } 259 }
265 } else { 260 } else {
266 priv = gpio_leds_create_of(pdev); 261 priv = gpio_leds_create_of(pdev);
267 if (IS_ERR(priv)) 262 if (!priv)
268 return PTR_ERR(priv); 263 return -ENODEV;
269 } 264 }
270 265
271 platform_set_drvdata(pdev, priv); 266 platform_set_drvdata(pdev, priv);
@@ -273,32 +268,45 @@ static int gpio_led_probe(struct platform_device *pdev)
273 return 0; 268 return 0;
274} 269}
275 270
276static int gpio_led_remove(struct platform_device *pdev) 271static int __devexit gpio_led_remove(struct platform_device *pdev)
277{ 272{
278 struct gpio_leds_priv *priv = platform_get_drvdata(pdev); 273 struct gpio_leds_priv *priv = dev_get_drvdata(&pdev->dev);
279 int i; 274 int i;
280 275
281 for (i = 0; i < priv->num_leds; i++) 276 for (i = 0; i < priv->num_leds; i++)
282 delete_gpio_led(&priv->leds[i]); 277 delete_gpio_led(&priv->leds[i]);
283 278
284 platform_set_drvdata(pdev, NULL); 279 dev_set_drvdata(&pdev->dev, NULL);
280 kfree(priv);
285 281
286 return 0; 282 return 0;
287} 283}
288 284
289static struct platform_driver gpio_led_driver = { 285static struct platform_driver gpio_led_driver = {
290 .probe = gpio_led_probe, 286 .probe = gpio_led_probe,
291 .remove = gpio_led_remove, 287 .remove = __devexit_p(gpio_led_remove),
292 .driver = { 288 .driver = {
293 .name = "leds-gpio", 289 .name = "leds-gpio",
294 .owner = THIS_MODULE, 290 .owner = THIS_MODULE,
295 .of_match_table = of_match_ptr(of_gpio_leds_match), 291 .of_match_table = of_gpio_leds_match,
296 }, 292 },
297}; 293};
298 294
299module_platform_driver(gpio_led_driver); 295MODULE_ALIAS("platform:leds-gpio");
296
297static int __init gpio_led_init(void)
298{
299 return platform_driver_register(&gpio_led_driver);
300}
301
302static void __exit gpio_led_exit(void)
303{
304 platform_driver_unregister(&gpio_led_driver);
305}
306
307module_init(gpio_led_init);
308module_exit(gpio_led_exit);
300 309
301MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>"); 310MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
302MODULE_DESCRIPTION("GPIO LED driver"); 311MODULE_DESCRIPTION("GPIO LED driver");
303MODULE_LICENSE("GPL"); 312MODULE_LICENSE("GPL");
304MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index 366b6055e33..bcfbd3a60ea 100644
--- a/drivers/leds/leds-hp6xx.c
+++ b/drivers/leds/leds-hp6xx.c
@@ -79,6 +79,9 @@ static int hp6xxled_remove(struct platform_device *pdev)
79 return 0; 79 return 0;
80} 80}
81 81
82/* work with hotplug and coldplug */
83MODULE_ALIAS("platform:hp6xx-led");
84
82static struct platform_driver hp6xxled_driver = { 85static struct platform_driver hp6xxled_driver = {
83 .probe = hp6xxled_probe, 86 .probe = hp6xxled_probe,
84 .remove = hp6xxled_remove, 87 .remove = hp6xxled_remove,
@@ -88,9 +91,19 @@ static struct platform_driver hp6xxled_driver = {
88 }, 91 },
89}; 92};
90 93
91module_platform_driver(hp6xxled_driver); 94static int __init hp6xxled_init(void)
95{
96 return platform_driver_register(&hp6xxled_driver);
97}
98
99static void __exit hp6xxled_exit(void)
100{
101 platform_driver_unregister(&hp6xxled_driver);
102}
103
104module_init(hp6xxled_init);
105module_exit(hp6xxled_exit);
92 106
93MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 107MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
94MODULE_DESCRIPTION("HP Jornada 6xx LED driver"); 108MODULE_DESCRIPTION("HP Jornada 6xx LED driver");
95MODULE_LICENSE("GPL"); 109MODULE_LICENSE("GPL");
96MODULE_ALIAS("platform:hp6xx-led");
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 21414548383..3dd7090a9a9 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -18,7 +18,6 @@
18#include <linux/led-lm3530.h> 18#include <linux/led-lm3530.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
21#include <linux/module.h>
22 21
23#define LM3530_LED_DEV "lcd-backlight" 22#define LM3530_LED_DEV "lcd-backlight"
24#define LM3530_NAME "lm3530-led" 23#define LM3530_NAME "lm3530-led"
@@ -26,6 +25,7 @@
26#define LM3530_GEN_CONFIG 0x10 25#define LM3530_GEN_CONFIG 0x10
27#define LM3530_ALS_CONFIG 0x20 26#define LM3530_ALS_CONFIG 0x20
28#define LM3530_BRT_RAMP_RATE 0x30 27#define LM3530_BRT_RAMP_RATE 0x30
28#define LM3530_ALS_ZONE_REG 0x40
29#define LM3530_ALS_IMP_SELECT 0x41 29#define LM3530_ALS_IMP_SELECT 0x41
30#define LM3530_BRT_CTRL_REG 0xA0 30#define LM3530_BRT_CTRL_REG 0xA0
31#define LM3530_ALS_ZB0_REG 0x60 31#define LM3530_ALS_ZB0_REG 0x60
@@ -37,7 +37,7 @@
37#define LM3530_ALS_Z2T_REG 0x72 37#define LM3530_ALS_Z2T_REG 0x72
38#define LM3530_ALS_Z3T_REG 0x73 38#define LM3530_ALS_Z3T_REG 0x73
39#define LM3530_ALS_Z4T_REG 0x74 39#define LM3530_ALS_Z4T_REG 0x74
40#define LM3530_REG_MAX 14 40#define LM3530_REG_MAX 15
41 41
42/* General Control Register */ 42/* General Control Register */
43#define LM3530_EN_I2C_SHIFT (0) 43#define LM3530_EN_I2C_SHIFT (0)
@@ -79,9 +79,6 @@
79#define LM3530_DEF_ZT_3 (0x33) 79#define LM3530_DEF_ZT_3 (0x33)
80#define LM3530_DEF_ZT_4 (0x19) 80#define LM3530_DEF_ZT_4 (0x19)
81 81
82/* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */
83#define MAX_BRIGHTNESS (127)
84
85struct lm3530_mode_map { 82struct lm3530_mode_map {
86 const char *mode; 83 const char *mode;
87 enum lm3530_mode mode_val; 84 enum lm3530_mode mode_val;
@@ -113,22 +110,11 @@ struct lm3530_data {
113 bool enable; 110 bool enable;
114}; 111};
115 112
116/*
117 * struct lm3530_als_data
118 * @config : value of ALS configuration register
119 * @imp_sel : value of ALS resistor select register
120 * @zone : values of ALS ZB(Zone Boundary) registers
121 */
122struct lm3530_als_data {
123 u8 config;
124 u8 imp_sel;
125 u8 zones[LM3530_ALS_ZB_MAX];
126};
127
128static const u8 lm3530_reg[LM3530_REG_MAX] = { 113static const u8 lm3530_reg[LM3530_REG_MAX] = {
129 LM3530_GEN_CONFIG, 114 LM3530_GEN_CONFIG,
130 LM3530_ALS_CONFIG, 115 LM3530_ALS_CONFIG,
131 LM3530_BRT_RAMP_RATE, 116 LM3530_BRT_RAMP_RATE,
117 LM3530_ALS_ZONE_REG,
132 LM3530_ALS_IMP_SELECT, 118 LM3530_ALS_IMP_SELECT,
133 LM3530_BRT_CTRL_REG, 119 LM3530_BRT_CTRL_REG,
134 LM3530_ALS_ZB0_REG, 120 LM3530_ALS_ZB0_REG,
@@ -150,100 +136,91 @@ static int lm3530_get_mode_from_str(const char *str)
150 if (sysfs_streq(str, mode_map[i].mode)) 136 if (sysfs_streq(str, mode_map[i].mode))
151 return mode_map[i].mode_val; 137 return mode_map[i].mode_val;
152 138
153 return -EINVAL; 139 return -1;
154} 140}
155 141
156static void lm3530_als_configure(struct lm3530_platform_data *pdata, 142static int lm3530_init_registers(struct lm3530_data *drvdata)
157 struct lm3530_als_data *als)
158{ 143{
144 int ret = 0;
159 int i; 145 int i;
146 u8 gen_config;
147 u8 als_config = 0;
148 u8 brt_ramp;
149 u8 als_imp_sel = 0;
150 u8 brightness;
151 u8 reg_val[LM3530_REG_MAX];
152 u8 zones[LM3530_ALS_ZB_MAX];
160 u32 als_vmin, als_vmax, als_vstep; 153 u32 als_vmin, als_vmax, als_vstep;
154 struct lm3530_platform_data *pltfm = drvdata->pdata;
155 struct i2c_client *client = drvdata->client;
161 156
162 if (pdata->als_vmax == 0) { 157 gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
163 pdata->als_vmin = 0; 158 ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
164 pdata->als_vmax = LM3530_ALS_WINDOW_mV;
165 }
166
167 als_vmin = pdata->als_vmin;
168 als_vmax = pdata->als_vmax;
169 159
170 if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV) 160 if (drvdata->mode == LM3530_BL_MODE_MANUAL ||
171 pdata->als_vmax = als_vmax = als_vmin + LM3530_ALS_WINDOW_mV; 161 drvdata->mode == LM3530_BL_MODE_ALS)
162 gen_config |= (LM3530_ENABLE_I2C);
172 163
173 /* n zone boundary makes n+1 zones */ 164 if (drvdata->mode == LM3530_BL_MODE_ALS) {
174 als_vstep = (als_vmax - als_vmin) / (LM3530_ALS_ZB_MAX + 1); 165 if (pltfm->als_vmax == 0) {
166 pltfm->als_vmin = als_vmin = 0;
167 pltfm->als_vmin = als_vmax = LM3530_ALS_WINDOW_mV;
168 }
175 169
176 for (i = 0; i < LM3530_ALS_ZB_MAX; i++) 170 als_vmin = pltfm->als_vmin;
177 als->zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) + 171 als_vmax = pltfm->als_vmax;
178 als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
179 172
180 als->config = 173 if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
181 (pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) | 174 pltfm->als_vmax = als_vmax =
182 (LM3530_ENABLE_ALS) | 175 als_vmin + LM3530_ALS_WINDOW_mV;
183 (pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
184 176
185 als->imp_sel = 177 /* n zone boundary makes n+1 zones */
186 (pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) | 178 als_vstep = (als_vmax - als_vmin) / (LM3530_ALS_ZB_MAX + 1);
187 (pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
188}
189 179
190static int lm3530_init_registers(struct lm3530_data *drvdata) 180 for (i = 0; i < LM3530_ALS_ZB_MAX; i++)
191{ 181 zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) +
192 int ret = 0; 182 als_vstep + (i * als_vstep)) * LED_FULL)
193 int i; 183 / 1000;
194 u8 gen_config;
195 u8 brt_ramp;
196 u8 brightness;
197 u8 reg_val[LM3530_REG_MAX];
198 struct lm3530_platform_data *pdata = drvdata->pdata;
199 struct i2c_client *client = drvdata->client;
200 struct lm3530_pwm_data *pwm = &pdata->pwm_data;
201 struct lm3530_als_data als;
202 184
203 memset(&als, 0, sizeof(struct lm3530_als_data)); 185 als_config =
186 (pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
187 (LM3530_ENABLE_ALS) |
188 (pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT);
204 189
205 gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | 190 als_imp_sel =
206 ((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT); 191 (pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
192 (pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
207 193
208 switch (drvdata->mode) {
209 case LM3530_BL_MODE_MANUAL:
210 gen_config |= LM3530_ENABLE_I2C;
211 break;
212 case LM3530_BL_MODE_ALS:
213 gen_config |= LM3530_ENABLE_I2C;
214 lm3530_als_configure(pdata, &als);
215 break;
216 case LM3530_BL_MODE_PWM:
217 gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE |
218 (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
219 break;
220 } 194 }
221 195
222 brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | 196 if (drvdata->mode == LM3530_BL_MODE_PWM)
223 (pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); 197 gen_config |= (LM3530_ENABLE_PWM) |
198 (pltfm->pwm_pol_hi << LM3530_PWM_POL_SHIFT) |
199 (LM3530_ENABLE_PWM_SIMPLE);
200
201 brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
202 (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
224 203
225 if (drvdata->brightness) 204 if (drvdata->brightness)
226 brightness = drvdata->brightness; 205 brightness = drvdata->brightness;
227 else 206 else
228 brightness = drvdata->brightness = pdata->brt_val; 207 brightness = drvdata->brightness = pltfm->brt_val;
229
230 if (brightness > drvdata->led_dev.max_brightness)
231 brightness = drvdata->led_dev.max_brightness;
232 208
233 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */ 209 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */
234 reg_val[1] = als.config; /* LM3530_ALS_CONFIG */ 210 reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
235 reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */ 211 reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */
236 reg_val[3] = als.imp_sel; /* LM3530_ALS_IMP_SELECT */ 212 reg_val[3] = 0x00; /* LM3530_ALS_ZONE_REG */
237 reg_val[4] = brightness; /* LM3530_BRT_CTRL_REG */ 213 reg_val[4] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */
238 reg_val[5] = als.zones[0]; /* LM3530_ALS_ZB0_REG */ 214 reg_val[5] = brightness; /* LM3530_BRT_CTRL_REG */
239 reg_val[6] = als.zones[1]; /* LM3530_ALS_ZB1_REG */ 215 reg_val[6] = zones[0]; /* LM3530_ALS_ZB0_REG */
240 reg_val[7] = als.zones[2]; /* LM3530_ALS_ZB2_REG */ 216 reg_val[7] = zones[1]; /* LM3530_ALS_ZB1_REG */
241 reg_val[8] = als.zones[3]; /* LM3530_ALS_ZB3_REG */ 217 reg_val[8] = zones[2]; /* LM3530_ALS_ZB2_REG */
242 reg_val[9] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */ 218 reg_val[9] = zones[3]; /* LM3530_ALS_ZB3_REG */
243 reg_val[10] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */ 219 reg_val[10] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */
244 reg_val[11] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */ 220 reg_val[11] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */
245 reg_val[12] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ 221 reg_val[12] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */
246 reg_val[13] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ 222 reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */
223 reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
247 224
248 if (!drvdata->enable) { 225 if (!drvdata->enable) {
249 ret = regulator_enable(drvdata->regulator); 226 ret = regulator_enable(drvdata->regulator);
@@ -256,15 +233,6 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
256 } 233 }
257 234
258 for (i = 0; i < LM3530_REG_MAX; i++) { 235 for (i = 0; i < LM3530_REG_MAX; i++) {
259 /* do not update brightness register when pwm mode */
260 if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
261 drvdata->mode == LM3530_BL_MODE_PWM) {
262 if (pwm->pwm_set_intensity)
263 pwm->pwm_set_intensity(reg_val[i],
264 drvdata->led_dev.max_brightness);
265 continue;
266 }
267
268 ret = i2c_smbus_write_byte_data(client, 236 ret = i2c_smbus_write_byte_data(client,
269 lm3530_reg[i], reg_val[i]); 237 lm3530_reg[i], reg_val[i]);
270 if (ret) 238 if (ret)
@@ -280,9 +248,6 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
280 int err; 248 int err;
281 struct lm3530_data *drvdata = 249 struct lm3530_data *drvdata =
282 container_of(led_cdev, struct lm3530_data, led_dev); 250 container_of(led_cdev, struct lm3530_data, led_dev);
283 struct lm3530_platform_data *pdata = drvdata->pdata;
284 struct lm3530_pwm_data *pwm = &pdata->pwm_data;
285 u8 max_brightness = led_cdev->max_brightness;
286 251
287 switch (drvdata->mode) { 252 switch (drvdata->mode) {
288 case LM3530_BL_MODE_MANUAL: 253 case LM3530_BL_MODE_MANUAL:
@@ -298,12 +263,12 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
298 263
299 /* set the brightness in brightness control register*/ 264 /* set the brightness in brightness control register*/
300 err = i2c_smbus_write_byte_data(drvdata->client, 265 err = i2c_smbus_write_byte_data(drvdata->client,
301 LM3530_BRT_CTRL_REG, brt_val); 266 LM3530_BRT_CTRL_REG, brt_val / 2);
302 if (err) 267 if (err)
303 dev_err(&drvdata->client->dev, 268 dev_err(&drvdata->client->dev,
304 "Unable to set brightness: %d\n", err); 269 "Unable to set brightness: %d\n", err);
305 else 270 else
306 drvdata->brightness = brt_val; 271 drvdata->brightness = brt_val / 2;
307 272
308 if (brt_val == 0) { 273 if (brt_val == 0) {
309 err = regulator_disable(drvdata->regulator); 274 err = regulator_disable(drvdata->regulator);
@@ -316,8 +281,6 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
316 case LM3530_BL_MODE_ALS: 281 case LM3530_BL_MODE_ALS:
317 break; 282 break;
318 case LM3530_BL_MODE_PWM: 283 case LM3530_BL_MODE_PWM:
319 if (pwm->pwm_set_intensity)
320 pwm->pwm_set_intensity(brt_val, max_brightness);
321 break; 284 break;
322 default: 285 default:
323 break; 286 break;
@@ -327,11 +290,11 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
327static ssize_t lm3530_mode_get(struct device *dev, 290static ssize_t lm3530_mode_get(struct device *dev,
328 struct device_attribute *attr, char *buf) 291 struct device_attribute *attr, char *buf)
329{ 292{
330 struct led_classdev *led_cdev = dev_get_drvdata(dev); 293 struct i2c_client *client = container_of(
331 struct lm3530_data *drvdata; 294 dev->parent, struct i2c_client, dev);
295 struct lm3530_data *drvdata = i2c_get_clientdata(client);
332 int i, len = 0; 296 int i, len = 0;
333 297
334 drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
335 for (i = 0; i < ARRAY_SIZE(mode_map); i++) 298 for (i = 0; i < ARRAY_SIZE(mode_map); i++)
336 if (drvdata->mode == mode_map[i].mode_val) 299 if (drvdata->mode == mode_map[i].mode_val)
337 len += sprintf(buf + len, "[%s] ", mode_map[i].mode); 300 len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
@@ -346,26 +309,26 @@ static ssize_t lm3530_mode_get(struct device *dev,
346static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute 309static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
347 *attr, const char *buf, size_t size) 310 *attr, const char *buf, size_t size)
348{ 311{
349 struct led_classdev *led_cdev = dev_get_drvdata(dev); 312 int err;
350 struct lm3530_data *drvdata; 313 struct i2c_client *client = container_of(
351 struct lm3530_pwm_data *pwm; 314 dev->parent, struct i2c_client, dev);
352 u8 max_brightness; 315 struct lm3530_data *drvdata = i2c_get_clientdata(client);
353 int mode, err; 316 int mode;
354 317
355 drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
356 pwm = &drvdata->pdata->pwm_data;
357 max_brightness = led_cdev->max_brightness;
358 mode = lm3530_get_mode_from_str(buf); 318 mode = lm3530_get_mode_from_str(buf);
359 if (mode < 0) { 319 if (mode < 0) {
360 dev_err(dev, "Invalid mode\n"); 320 dev_err(dev, "Invalid mode\n");
361 return mode; 321 return -EINVAL;
362 } 322 }
363 323
364 drvdata->mode = mode; 324 if (mode == LM3530_BL_MODE_MANUAL)
365 325 drvdata->mode = LM3530_BL_MODE_MANUAL;
366 /* set pwm to low if unnecessary */ 326 else if (mode == LM3530_BL_MODE_ALS)
367 if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity) 327 drvdata->mode = LM3530_BL_MODE_ALS;
368 pwm->pwm_set_intensity(0, max_brightness); 328 else if (mode == LM3530_BL_MODE_PWM) {
329 dev_err(dev, "PWM mode not supported\n");
330 return -EINVAL;
331 }
369 332
370 err = lm3530_init_registers(drvdata); 333 err = lm3530_init_registers(drvdata);
371 if (err) { 334 if (err) {
@@ -377,7 +340,7 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
377} 340}
378static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); 341static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
379 342
380static int lm3530_probe(struct i2c_client *client, 343static int __devinit lm3530_probe(struct i2c_client *client,
381 const struct i2c_device_id *id) 344 const struct i2c_device_id *id)
382{ 345{
383 struct lm3530_platform_data *pdata = client->dev.platform_data; 346 struct lm3530_platform_data *pdata = client->dev.platform_data;
@@ -386,24 +349,28 @@ static int lm3530_probe(struct i2c_client *client,
386 349
387 if (pdata == NULL) { 350 if (pdata == NULL) {
388 dev_err(&client->dev, "platform data required\n"); 351 dev_err(&client->dev, "platform data required\n");
389 return -ENODEV; 352 err = -ENODEV;
353 goto err_out;
390 } 354 }
391 355
392 /* BL mode */ 356 /* BL mode */
393 if (pdata->mode > LM3530_BL_MODE_PWM) { 357 if (pdata->mode > LM3530_BL_MODE_PWM) {
394 dev_err(&client->dev, "Illegal Mode request\n"); 358 dev_err(&client->dev, "Illegal Mode request\n");
395 return -EINVAL; 359 err = -EINVAL;
360 goto err_out;
396 } 361 }
397 362
398 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 363 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
399 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n"); 364 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n");
400 return -EIO; 365 err = -EIO;
366 goto err_out;
401 } 367 }
402 368
403 drvdata = devm_kzalloc(&client->dev, sizeof(struct lm3530_data), 369 drvdata = kzalloc(sizeof(struct lm3530_data), GFP_KERNEL);
404 GFP_KERNEL); 370 if (drvdata == NULL) {
405 if (drvdata == NULL) 371 err = -ENOMEM;
406 return -ENOMEM; 372 goto err_out;
373 }
407 374
408 drvdata->mode = pdata->mode; 375 drvdata->mode = pdata->mode;
409 drvdata->client = client; 376 drvdata->client = client;
@@ -412,16 +379,15 @@ static int lm3530_probe(struct i2c_client *client,
412 drvdata->enable = false; 379 drvdata->enable = false;
413 drvdata->led_dev.name = LM3530_LED_DEV; 380 drvdata->led_dev.name = LM3530_LED_DEV;
414 drvdata->led_dev.brightness_set = lm3530_brightness_set; 381 drvdata->led_dev.brightness_set = lm3530_brightness_set;
415 drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
416 382
417 i2c_set_clientdata(client, drvdata); 383 i2c_set_clientdata(client, drvdata);
418 384
419 drvdata->regulator = devm_regulator_get(&client->dev, "vin"); 385 drvdata->regulator = regulator_get(&client->dev, "vin");
420 if (IS_ERR(drvdata->regulator)) { 386 if (IS_ERR(drvdata->regulator)) {
421 dev_err(&client->dev, "regulator get failed\n"); 387 dev_err(&client->dev, "regulator get failed\n");
422 err = PTR_ERR(drvdata->regulator); 388 err = PTR_ERR(drvdata->regulator);
423 drvdata->regulator = NULL; 389 drvdata->regulator = NULL;
424 return err; 390 goto err_regulator_get;
425 } 391 }
426 392
427 if (drvdata->pdata->brt_val) { 393 if (drvdata->pdata->brt_val) {
@@ -429,13 +395,15 @@ static int lm3530_probe(struct i2c_client *client,
429 if (err < 0) { 395 if (err < 0) {
430 dev_err(&client->dev, 396 dev_err(&client->dev,
431 "Register Init failed: %d\n", err); 397 "Register Init failed: %d\n", err);
432 return err; 398 err = -ENODEV;
399 goto err_reg_init;
433 } 400 }
434 } 401 }
435 err = led_classdev_register(&client->dev, &drvdata->led_dev); 402 err = led_classdev_register(&client->dev, &drvdata->led_dev);
436 if (err < 0) { 403 if (err < 0) {
437 dev_err(&client->dev, "Register led class failed: %d\n", err); 404 dev_err(&client->dev, "Register led class failed: %d\n", err);
438 return err; 405 err = -ENODEV;
406 goto err_class_register;
439 } 407 }
440 408
441 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode); 409 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
@@ -449,10 +417,17 @@ static int lm3530_probe(struct i2c_client *client,
449 417
450err_create_file: 418err_create_file:
451 led_classdev_unregister(&drvdata->led_dev); 419 led_classdev_unregister(&drvdata->led_dev);
420err_class_register:
421err_reg_init:
422 regulator_put(drvdata->regulator);
423err_regulator_get:
424 i2c_set_clientdata(client, NULL);
425 kfree(drvdata);
426err_out:
452 return err; 427 return err;
453} 428}
454 429
455static int lm3530_remove(struct i2c_client *client) 430static int __devexit lm3530_remove(struct i2c_client *client)
456{ 431{
457 struct lm3530_data *drvdata = i2c_get_clientdata(client); 432 struct lm3530_data *drvdata = i2c_get_clientdata(client);
458 433
@@ -460,7 +435,9 @@ static int lm3530_remove(struct i2c_client *client)
460 435
461 if (drvdata->enable) 436 if (drvdata->enable)
462 regulator_disable(drvdata->regulator); 437 regulator_disable(drvdata->regulator);
438 regulator_put(drvdata->regulator);
463 led_classdev_unregister(&drvdata->led_dev); 439 led_classdev_unregister(&drvdata->led_dev);
440 kfree(drvdata);
464 return 0; 441 return 0;
465} 442}
466 443
@@ -480,7 +457,18 @@ static struct i2c_driver lm3530_i2c_driver = {
480 }, 457 },
481}; 458};
482 459
483module_i2c_driver(lm3530_i2c_driver); 460static int __init lm3530_init(void)
461{
462 return i2c_add_driver(&lm3530_i2c_driver);
463}
464
465static void __exit lm3530_exit(void)
466{
467 i2c_del_driver(&lm3530_i2c_driver);
468}
469
470module_init(lm3530_init);
471module_exit(lm3530_exit);
484 472
485MODULE_DESCRIPTION("Back Light driver for LM3530"); 473MODULE_DESCRIPTION("Back Light driver for LM3530");
486MODULE_LICENSE("GPL v2"); 474MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
deleted file mode 100644
index bbf24d038a7..00000000000
--- a/drivers/leds/leds-lm3533.c
+++ /dev/null
@@ -1,785 +0,0 @@
1/*
2 * leds-lm3533.c -- LM3533 LED driver
3 *
4 * Copyright (C) 2011-2012 Texas Instruments
5 *
6 * Author: Johan Hovold <jhovold@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/leds.h>
17#include <linux/mfd/core.h>
18#include <linux/mutex.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/workqueue.h>
22
23#include <linux/mfd/lm3533.h>
24
25
26#define LM3533_LVCTRLBANK_MIN 2
27#define LM3533_LVCTRLBANK_MAX 5
28#define LM3533_LVCTRLBANK_COUNT 4
29#define LM3533_RISEFALLTIME_MAX 7
30#define LM3533_ALS_CHANNEL_LV_MIN 1
31#define LM3533_ALS_CHANNEL_LV_MAX 2
32
33#define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b
34#define LM3533_REG_PATTERN_ENABLE 0x28
35#define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71
36#define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72
37#define LM3533_REG_PATTERN_RISETIME_BASE 0x74
38#define LM3533_REG_PATTERN_FALLTIME_BASE 0x75
39
40#define LM3533_REG_PATTERN_STEP 0x10
41
42#define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04
43#define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02
44#define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01
45
46#define LM3533_LED_FLAG_PATTERN_ENABLE 1
47
48
49struct lm3533_led {
50 struct lm3533 *lm3533;
51 struct lm3533_ctrlbank cb;
52 struct led_classdev cdev;
53 int id;
54
55 struct mutex mutex;
56 unsigned long flags;
57
58 struct work_struct work;
59 u8 new_brightness;
60};
61
62
63static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev)
64{
65 return container_of(cdev, struct lm3533_led, cdev);
66}
67
68static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led)
69{
70 return led->id + 2;
71}
72
73static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base)
74{
75 return base + led->id;
76}
77
78static inline u8 lm3533_led_get_pattern(struct lm3533_led *led)
79{
80 return led->id;
81}
82
83static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
84 u8 base)
85{
86 return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP;
87}
88
89static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
90{
91 u8 mask;
92 u8 val;
93 int pattern;
94 int state;
95 int ret = 0;
96
97 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable);
98
99 mutex_lock(&led->mutex);
100
101 state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
102 if ((enable && state) || (!enable && !state))
103 goto out;
104
105 pattern = lm3533_led_get_pattern(led);
106 mask = 1 << (2 * pattern);
107
108 if (enable)
109 val = mask;
110 else
111 val = 0;
112
113 ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
114 if (ret) {
115 dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
116 pattern, enable);
117 goto out;
118 }
119
120 __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
121out:
122 mutex_unlock(&led->mutex);
123
124 return ret;
125}
126
127static void lm3533_led_work(struct work_struct *work)
128{
129 struct lm3533_led *led = container_of(work, struct lm3533_led, work);
130
131 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, led->new_brightness);
132
133 if (led->new_brightness == 0)
134 lm3533_led_pattern_enable(led, 0); /* disable blink */
135
136 lm3533_ctrlbank_set_brightness(&led->cb, led->new_brightness);
137}
138
139static void lm3533_led_set(struct led_classdev *cdev,
140 enum led_brightness value)
141{
142 struct lm3533_led *led = to_lm3533_led(cdev);
143
144 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value);
145
146 led->new_brightness = value;
147 schedule_work(&led->work);
148}
149
150static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
151{
152 struct lm3533_led *led = to_lm3533_led(cdev);
153 u8 val;
154 int ret;
155
156 ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
157 if (ret)
158 return ret;
159
160 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val);
161
162 return val;
163}
164
165/* Pattern generator defines (delays in us). */
166#define LM3533_LED_DELAY1_VMIN 0x00
167#define LM3533_LED_DELAY2_VMIN 0x3d
168#define LM3533_LED_DELAY3_VMIN 0x80
169
170#define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1)
171#define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1)
172#define LM3533_LED_DELAY3_VMAX 0xff
173
174#define LM3533_LED_DELAY1_TMIN 16384U
175#define LM3533_LED_DELAY2_TMIN 1130496U
176#define LM3533_LED_DELAY3_TMIN 10305536U
177
178#define LM3533_LED_DELAY1_TMAX 999424U
179#define LM3533_LED_DELAY2_TMAX 9781248U
180#define LM3533_LED_DELAY3_TMAX 76890112U
181
182/* t_step = (t_max - t_min) / (v_max - v_min) */
183#define LM3533_LED_DELAY1_TSTEP 16384
184#define LM3533_LED_DELAY2_TSTEP 131072
185#define LM3533_LED_DELAY3_TSTEP 524288
186
187/* Delay limits for hardware accelerated blinking (in ms). */
188#define LM3533_LED_DELAY_ON_MAX \
189 ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000)
190#define LM3533_LED_DELAY_OFF_MAX \
191 ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000)
192
193/*
194 * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step
195 * size of t_step, where
196 *
197 * t_step = (t_max - t_min) / (v_max - v_min)
198 *
199 * and updates *t to reflect the mapped value.
200 */
201static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step,
202 u8 v_min, u8 v_max)
203{
204 unsigned val;
205
206 val = (*t + t_step / 2 - t_min) / t_step + v_min;
207
208 *t = t_step * (val - v_min) + t_min;
209
210 return (u8)val;
211}
212
213/*
214 * Returns time code corresponding to *delay (in ms) and updates *delay to
215 * reflect actual hardware delay.
216 *
217 * Hardware supports 256 discrete delay times, divided into three groups with
218 * the following ranges and step-sizes:
219 *
220 * [ 16, 999] [0x00, 0x3e] step 16 ms
221 * [ 1130, 9781] [0x3d, 0x7f] step 131 ms
222 * [10306, 76890] [0x80, 0xff] step 524 ms
223 *
224 * Note that delay group 3 is only available for delay_off.
225 */
226static u8 lm3533_led_get_hw_delay(unsigned *delay)
227{
228 unsigned t;
229 u8 val;
230
231 t = *delay * 1000;
232
233 if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) {
234 t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX);
235 val = time_to_val(&t, LM3533_LED_DELAY3_TMIN,
236 LM3533_LED_DELAY3_TSTEP,
237 LM3533_LED_DELAY3_VMIN,
238 LM3533_LED_DELAY3_VMAX);
239 } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) {
240 t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX);
241 val = time_to_val(&t, LM3533_LED_DELAY2_TMIN,
242 LM3533_LED_DELAY2_TSTEP,
243 LM3533_LED_DELAY2_VMIN,
244 LM3533_LED_DELAY2_VMAX);
245 } else {
246 t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX);
247 val = time_to_val(&t, LM3533_LED_DELAY1_TMIN,
248 LM3533_LED_DELAY1_TSTEP,
249 LM3533_LED_DELAY1_VMIN,
250 LM3533_LED_DELAY1_VMAX);
251 }
252
253 *delay = (t + 500) / 1000;
254
255 return val;
256}
257
258/*
259 * Set delay register base to *delay (in ms) and update *delay to reflect
260 * actual hardware delay used.
261 */
262static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
263 unsigned long *delay)
264{
265 unsigned t;
266 u8 val;
267 u8 reg;
268 int ret;
269
270 t = (unsigned)*delay;
271
272 /* Delay group 3 is only available for low time (delay off). */
273 if (base != LM3533_REG_PATTERN_LOW_TIME_BASE)
274 t = min(t, LM3533_LED_DELAY2_TMAX / 1000);
275
276 val = lm3533_led_get_hw_delay(&t);
277
278 dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
279 *delay, t, val);
280 reg = lm3533_led_get_pattern_reg(led, base);
281 ret = lm3533_write(led->lm3533, reg, val);
282 if (ret)
283 dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
284
285 *delay = t;
286
287 return ret;
288}
289
290static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
291{
292 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
293}
294
295static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t)
296{
297 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t);
298}
299
300static int lm3533_led_blink_set(struct led_classdev *cdev,
301 unsigned long *delay_on,
302 unsigned long *delay_off)
303{
304 struct lm3533_led *led = to_lm3533_led(cdev);
305 int ret;
306
307 dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__,
308 *delay_on, *delay_off);
309
310 if (*delay_on > LM3533_LED_DELAY_ON_MAX ||
311 *delay_off > LM3533_LED_DELAY_OFF_MAX)
312 return -EINVAL;
313
314 if (*delay_on == 0 && *delay_off == 0) {
315 *delay_on = 500;
316 *delay_off = 500;
317 }
318
319 ret = lm3533_led_delay_on_set(led, delay_on);
320 if (ret)
321 return ret;
322
323 ret = lm3533_led_delay_off_set(led, delay_off);
324 if (ret)
325 return ret;
326
327 return lm3533_led_pattern_enable(led, 1);
328}
329
330static ssize_t show_id(struct device *dev,
331 struct device_attribute *attr, char *buf)
332{
333 struct led_classdev *led_cdev = dev_get_drvdata(dev);
334 struct lm3533_led *led = to_lm3533_led(led_cdev);
335
336 return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
337}
338
339/*
340 * Pattern generator rise/fall times:
341 *
342 * 0 - 2048 us (default)
343 * 1 - 262 ms
344 * 2 - 524 ms
345 * 3 - 1.049 s
346 * 4 - 2.097 s
347 * 5 - 4.194 s
348 * 6 - 8.389 s
349 * 7 - 16.78 s
350 */
351static ssize_t show_risefalltime(struct device *dev,
352 struct device_attribute *attr,
353 char *buf, u8 base)
354{
355 struct led_classdev *led_cdev = dev_get_drvdata(dev);
356 struct lm3533_led *led = to_lm3533_led(led_cdev);
357 ssize_t ret;
358 u8 reg;
359 u8 val;
360
361 reg = lm3533_led_get_pattern_reg(led, base);
362 ret = lm3533_read(led->lm3533, reg, &val);
363 if (ret)
364 return ret;
365
366 return scnprintf(buf, PAGE_SIZE, "%x\n", val);
367}
368
369static ssize_t show_risetime(struct device *dev,
370 struct device_attribute *attr, char *buf)
371{
372 return show_risefalltime(dev, attr, buf,
373 LM3533_REG_PATTERN_RISETIME_BASE);
374}
375
376static ssize_t show_falltime(struct device *dev,
377 struct device_attribute *attr, char *buf)
378{
379 return show_risefalltime(dev, attr, buf,
380 LM3533_REG_PATTERN_FALLTIME_BASE);
381}
382
383static ssize_t store_risefalltime(struct device *dev,
384 struct device_attribute *attr,
385 const char *buf, size_t len, u8 base)
386{
387 struct led_classdev *led_cdev = dev_get_drvdata(dev);
388 struct lm3533_led *led = to_lm3533_led(led_cdev);
389 u8 val;
390 u8 reg;
391 int ret;
392
393 if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX)
394 return -EINVAL;
395
396 reg = lm3533_led_get_pattern_reg(led, base);
397 ret = lm3533_write(led->lm3533, reg, val);
398 if (ret)
399 return ret;
400
401 return len;
402}
403
404static ssize_t store_risetime(struct device *dev,
405 struct device_attribute *attr,
406 const char *buf, size_t len)
407{
408 return store_risefalltime(dev, attr, buf, len,
409 LM3533_REG_PATTERN_RISETIME_BASE);
410}
411
412static ssize_t store_falltime(struct device *dev,
413 struct device_attribute *attr,
414 const char *buf, size_t len)
415{
416 return store_risefalltime(dev, attr, buf, len,
417 LM3533_REG_PATTERN_FALLTIME_BASE);
418}
419
420static ssize_t show_als_channel(struct device *dev,
421 struct device_attribute *attr, char *buf)
422{
423 struct led_classdev *led_cdev = dev_get_drvdata(dev);
424 struct lm3533_led *led = to_lm3533_led(led_cdev);
425 unsigned channel;
426 u8 reg;
427 u8 val;
428 int ret;
429
430 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
431 ret = lm3533_read(led->lm3533, reg, &val);
432 if (ret)
433 return ret;
434
435 channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
436
437 return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
438}
439
440static ssize_t store_als_channel(struct device *dev,
441 struct device_attribute *attr,
442 const char *buf, size_t len)
443{
444 struct led_classdev *led_cdev = dev_get_drvdata(dev);
445 struct lm3533_led *led = to_lm3533_led(led_cdev);
446 unsigned channel;
447 u8 reg;
448 u8 val;
449 u8 mask;
450 int ret;
451
452 if (kstrtouint(buf, 0, &channel))
453 return -EINVAL;
454
455 if (channel < LM3533_ALS_CHANNEL_LV_MIN ||
456 channel > LM3533_ALS_CHANNEL_LV_MAX)
457 return -EINVAL;
458
459 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
460 mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
461 val = channel - 1;
462
463 ret = lm3533_update(led->lm3533, reg, val, mask);
464 if (ret)
465 return ret;
466
467 return len;
468}
469
470static ssize_t show_als_en(struct device *dev,
471 struct device_attribute *attr, char *buf)
472{
473 struct led_classdev *led_cdev = dev_get_drvdata(dev);
474 struct lm3533_led *led = to_lm3533_led(led_cdev);
475 bool enable;
476 u8 reg;
477 u8 val;
478 int ret;
479
480 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
481 ret = lm3533_read(led->lm3533, reg, &val);
482 if (ret)
483 return ret;
484
485 enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
486
487 return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
488}
489
490static ssize_t store_als_en(struct device *dev,
491 struct device_attribute *attr,
492 const char *buf, size_t len)
493{
494 struct led_classdev *led_cdev = dev_get_drvdata(dev);
495 struct lm3533_led *led = to_lm3533_led(led_cdev);
496 unsigned enable;
497 u8 reg;
498 u8 mask;
499 u8 val;
500 int ret;
501
502 if (kstrtouint(buf, 0, &enable))
503 return -EINVAL;
504
505 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
506 mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
507
508 if (enable)
509 val = mask;
510 else
511 val = 0;
512
513 ret = lm3533_update(led->lm3533, reg, val, mask);
514 if (ret)
515 return ret;
516
517 return len;
518}
519
520static ssize_t show_linear(struct device *dev,
521 struct device_attribute *attr, char *buf)
522{
523 struct led_classdev *led_cdev = dev_get_drvdata(dev);
524 struct lm3533_led *led = to_lm3533_led(led_cdev);
525 u8 reg;
526 u8 val;
527 int linear;
528 int ret;
529
530 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
531 ret = lm3533_read(led->lm3533, reg, &val);
532 if (ret)
533 return ret;
534
535 if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK)
536 linear = 1;
537 else
538 linear = 0;
539
540 return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
541}
542
543static ssize_t store_linear(struct device *dev,
544 struct device_attribute *attr,
545 const char *buf, size_t len)
546{
547 struct led_classdev *led_cdev = dev_get_drvdata(dev);
548 struct lm3533_led *led = to_lm3533_led(led_cdev);
549 unsigned long linear;
550 u8 reg;
551 u8 mask;
552 u8 val;
553 int ret;
554
555 if (kstrtoul(buf, 0, &linear))
556 return -EINVAL;
557
558 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
559 mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
560
561 if (linear)
562 val = mask;
563 else
564 val = 0;
565
566 ret = lm3533_update(led->lm3533, reg, val, mask);
567 if (ret)
568 return ret;
569
570 return len;
571}
572
573static ssize_t show_pwm(struct device *dev,
574 struct device_attribute *attr,
575 char *buf)
576{
577 struct led_classdev *led_cdev = dev_get_drvdata(dev);
578 struct lm3533_led *led = to_lm3533_led(led_cdev);
579 u8 val;
580 int ret;
581
582 ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
583 if (ret)
584 return ret;
585
586 return scnprintf(buf, PAGE_SIZE, "%u\n", val);
587}
588
589static ssize_t store_pwm(struct device *dev,
590 struct device_attribute *attr,
591 const char *buf, size_t len)
592{
593 struct led_classdev *led_cdev = dev_get_drvdata(dev);
594 struct lm3533_led *led = to_lm3533_led(led_cdev);
595 u8 val;
596 int ret;
597
598 if (kstrtou8(buf, 0, &val))
599 return -EINVAL;
600
601 ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
602 if (ret)
603 return ret;
604
605 return len;
606}
607
608static LM3533_ATTR_RW(als_channel);
609static LM3533_ATTR_RW(als_en);
610static LM3533_ATTR_RW(falltime);
611static LM3533_ATTR_RO(id);
612static LM3533_ATTR_RW(linear);
613static LM3533_ATTR_RW(pwm);
614static LM3533_ATTR_RW(risetime);
615
616static struct attribute *lm3533_led_attributes[] = {
617 &dev_attr_als_channel.attr,
618 &dev_attr_als_en.attr,
619 &dev_attr_falltime.attr,
620 &dev_attr_id.attr,
621 &dev_attr_linear.attr,
622 &dev_attr_pwm.attr,
623 &dev_attr_risetime.attr,
624 NULL,
625};
626
627static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
628 struct attribute *attr, int n)
629{
630 struct device *dev = container_of(kobj, struct device, kobj);
631 struct led_classdev *led_cdev = dev_get_drvdata(dev);
632 struct lm3533_led *led = to_lm3533_led(led_cdev);
633 umode_t mode = attr->mode;
634
635 if (attr == &dev_attr_als_channel.attr ||
636 attr == &dev_attr_als_en.attr) {
637 if (!led->lm3533->have_als)
638 mode = 0;
639 }
640
641 return mode;
642};
643
644static struct attribute_group lm3533_led_attribute_group = {
645 .is_visible = lm3533_led_attr_is_visible,
646 .attrs = lm3533_led_attributes
647};
648
649static int lm3533_led_setup(struct lm3533_led *led,
650 struct lm3533_led_platform_data *pdata)
651{
652 int ret;
653
654 ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
655 if (ret)
656 return ret;
657
658 return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
659}
660
661static int lm3533_led_probe(struct platform_device *pdev)
662{
663 struct lm3533 *lm3533;
664 struct lm3533_led_platform_data *pdata;
665 struct lm3533_led *led;
666 int ret;
667
668 dev_dbg(&pdev->dev, "%s\n", __func__);
669
670 lm3533 = dev_get_drvdata(pdev->dev.parent);
671 if (!lm3533)
672 return -EINVAL;
673
674 pdata = pdev->dev.platform_data;
675 if (!pdata) {
676 dev_err(&pdev->dev, "no platform data\n");
677 return -EINVAL;
678 }
679
680 if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
681 dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
682 return -EINVAL;
683 }
684
685 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
686 if (!led)
687 return -ENOMEM;
688
689 led->lm3533 = lm3533;
690 led->cdev.name = pdata->name;
691 led->cdev.default_trigger = pdata->default_trigger;
692 led->cdev.brightness_set = lm3533_led_set;
693 led->cdev.brightness_get = lm3533_led_get;
694 led->cdev.blink_set = lm3533_led_blink_set;
695 led->cdev.brightness = LED_OFF;
696 led->id = pdev->id;
697
698 mutex_init(&led->mutex);
699 INIT_WORK(&led->work, lm3533_led_work);
700
701 /* The class framework makes a callback to get brightness during
702 * registration so use parent device (for error reporting) until
703 * registered.
704 */
705 led->cb.lm3533 = lm3533;
706 led->cb.id = lm3533_led_get_ctrlbank_id(led);
707 led->cb.dev = lm3533->dev;
708
709 platform_set_drvdata(pdev, led);
710
711 ret = led_classdev_register(pdev->dev.parent, &led->cdev);
712 if (ret) {
713 dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
714 return ret;
715 }
716
717 led->cb.dev = led->cdev.dev;
718
719 ret = sysfs_create_group(&led->cdev.dev->kobj,
720 &lm3533_led_attribute_group);
721 if (ret < 0) {
722 dev_err(&pdev->dev, "failed to create sysfs attributes\n");
723 goto err_unregister;
724 }
725
726 ret = lm3533_led_setup(led, pdata);
727 if (ret)
728 goto err_sysfs_remove;
729
730 ret = lm3533_ctrlbank_enable(&led->cb);
731 if (ret)
732 goto err_sysfs_remove;
733
734 return 0;
735
736err_sysfs_remove:
737 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
738err_unregister:
739 led_classdev_unregister(&led->cdev);
740 flush_work(&led->work);
741
742 return ret;
743}
744
745static int lm3533_led_remove(struct platform_device *pdev)
746{
747 struct lm3533_led *led = platform_get_drvdata(pdev);
748
749 dev_dbg(&pdev->dev, "%s\n", __func__);
750
751 lm3533_ctrlbank_disable(&led->cb);
752 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
753 led_classdev_unregister(&led->cdev);
754 flush_work(&led->work);
755
756 return 0;
757}
758
759static void lm3533_led_shutdown(struct platform_device *pdev)
760{
761
762 struct lm3533_led *led = platform_get_drvdata(pdev);
763
764 dev_dbg(&pdev->dev, "%s\n", __func__);
765
766 lm3533_ctrlbank_disable(&led->cb);
767 lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
768 flush_work(&led->work);
769}
770
771static struct platform_driver lm3533_led_driver = {
772 .driver = {
773 .name = "lm3533-leds",
774 .owner = THIS_MODULE,
775 },
776 .probe = lm3533_led_probe,
777 .remove = lm3533_led_remove,
778 .shutdown = lm3533_led_shutdown,
779};
780module_platform_driver(lm3533_led_driver);
781
782MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
783MODULE_DESCRIPTION("LM3533 LED driver");
784MODULE_LICENSE("GPL");
785MODULE_ALIAS("platform:lm3533-leds");
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
deleted file mode 100644
index 65d79284c48..00000000000
--- a/drivers/leds/leds-lm355x.c
+++ /dev/null
@@ -1,572 +0,0 @@
1/*
2* Simple driver for Texas Instruments LM355x LED Flash driver chip
3* Copyright (C) 2012 Texas Instruments
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License version 2 as
7* published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/delay.h>
12#include <linux/i2c.h>
13#include <linux/gpio.h>
14#include <linux/leds.h>
15#include <linux/slab.h>
16#include <linux/platform_device.h>
17#include <linux/fs.h>
18#include <linux/regmap.h>
19#include <linux/workqueue.h>
20#include <linux/platform_data/leds-lm355x.h>
21
22enum lm355x_type {
23 CHIP_LM3554 = 0,
24 CHIP_LM3556,
25};
26
27enum lm355x_regs {
28 REG_FLAG = 0,
29 REG_TORCH_CFG,
30 REG_TORCH_CTRL,
31 REG_STROBE_CFG,
32 REG_FLASH_CTRL,
33 REG_INDI_CFG,
34 REG_INDI_CTRL,
35 REG_OPMODE,
36 REG_MAX,
37};
38
39/* operation mode */
40enum lm355x_mode {
41 MODE_SHDN = 0,
42 MODE_INDIC,
43 MODE_TORCH,
44 MODE_FLASH
45};
46
47/* register map info. */
48struct lm355x_reg_data {
49 u8 regno;
50 u8 mask;
51 u8 shift;
52};
53
54struct lm355x_chip_data {
55 struct device *dev;
56 enum lm355x_type type;
57
58 struct led_classdev cdev_flash;
59 struct led_classdev cdev_torch;
60 struct led_classdev cdev_indicator;
61
62 struct work_struct work_flash;
63 struct work_struct work_torch;
64 struct work_struct work_indicator;
65
66 u8 br_flash;
67 u8 br_torch;
68 u8 br_indicator;
69
70 struct lm355x_platform_data *pdata;
71 struct regmap *regmap;
72 struct mutex lock;
73
74 unsigned int last_flag;
75 struct lm355x_reg_data *regs;
76};
77
78/* specific indicator function for lm3556 */
79enum lm3556_indic_pulse_time {
80 PULSE_TIME_0_MS = 0,
81 PULSE_TIME_32_MS,
82 PULSE_TIME_64_MS,
83 PULSE_TIME_92_MS,
84 PULSE_TIME_128_MS,
85 PULSE_TIME_160_MS,
86 PULSE_TIME_196_MS,
87 PULSE_TIME_224_MS,
88 PULSE_TIME_256_MS,
89 PULSE_TIME_288_MS,
90 PULSE_TIME_320_MS,
91 PULSE_TIME_352_MS,
92 PULSE_TIME_384_MS,
93 PULSE_TIME_416_MS,
94 PULSE_TIME_448_MS,
95 PULSE_TIME_480_MS,
96};
97
98enum lm3556_indic_n_blank {
99 INDIC_N_BLANK_0 = 0,
100 INDIC_N_BLANK_1,
101 INDIC_N_BLANK_2,
102 INDIC_N_BLANK_3,
103 INDIC_N_BLANK_4,
104 INDIC_N_BLANK_5,
105 INDIC_N_BLANK_6,
106 INDIC_N_BLANK_7,
107 INDIC_N_BLANK_8,
108 INDIC_N_BLANK_9,
109 INDIC_N_BLANK_10,
110 INDIC_N_BLANK_11,
111 INDIC_N_BLANK_12,
112 INDIC_N_BLANK_13,
113 INDIC_N_BLANK_14,
114 INDIC_N_BLANK_15,
115};
116
117enum lm3556_indic_period {
118 INDIC_PERIOD_0 = 0,
119 INDIC_PERIOD_1,
120 INDIC_PERIOD_2,
121 INDIC_PERIOD_3,
122 INDIC_PERIOD_4,
123 INDIC_PERIOD_5,
124 INDIC_PERIOD_6,
125 INDIC_PERIOD_7,
126};
127
128#define INDIC_PATTERN_SIZE 4
129
130struct indicator {
131 u8 blinking;
132 u8 period_cnt;
133};
134
135/* indicator pattern data only for lm3556 */
136static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
137 [0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
138 [1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
139 [2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
140 [3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
141};
142
143static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
144 [REG_FLAG] = {0xD0, 0xBF, 0},
145 [REG_TORCH_CFG] = {0xE0, 0x80, 7},
146 [REG_TORCH_CTRL] = {0xA0, 0x38, 3},
147 [REG_STROBE_CFG] = {0xE0, 0x04, 2},
148 [REG_FLASH_CTRL] = {0xB0, 0x78, 3},
149 [REG_INDI_CFG] = {0xE0, 0x08, 3},
150 [REG_INDI_CTRL] = {0xA0, 0xC0, 6},
151 [REG_OPMODE] = {0xA0, 0x03, 0},
152};
153
154static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
155 [REG_FLAG] = {0x0B, 0xFF, 0},
156 [REG_TORCH_CFG] = {0x0A, 0x10, 4},
157 [REG_TORCH_CTRL] = {0x09, 0x70, 4},
158 [REG_STROBE_CFG] = {0x0A, 0x20, 5},
159 [REG_FLASH_CTRL] = {0x09, 0x0F, 0},
160 [REG_INDI_CFG] = {0xFF, 0xFF, 0},
161 [REG_INDI_CTRL] = {0x09, 0x70, 4},
162 [REG_OPMODE] = {0x0A, 0x03, 0},
163};
164
165static char lm355x_name[][I2C_NAME_SIZE] = {
166 [CHIP_LM3554] = LM3554_NAME,
167 [CHIP_LM3556] = LM3556_NAME,
168};
169
170/* chip initialize */
171static int lm355x_chip_init(struct lm355x_chip_data *chip)
172{
173 int ret;
174 unsigned int reg_val;
175 struct lm355x_platform_data *pdata = chip->pdata;
176
177 /* input and output pins configuration */
178 switch (chip->type) {
179 case CHIP_LM3554:
180 reg_val = pdata->pin_tx2 | pdata->ntc_pin;
181 ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
182 if (ret < 0)
183 goto out;
184 reg_val = pdata->pass_mode;
185 ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
186 if (ret < 0)
187 goto out;
188 break;
189
190 case CHIP_LM3556:
191 reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode;
192 ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
193 if (ret < 0)
194 goto out;
195 break;
196 default:
197 return -ENODATA;
198 }
199
200 return ret;
201out:
202 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
203 return ret;
204}
205
206/* chip control */
207static void lm355x_control(struct lm355x_chip_data *chip,
208 u8 brightness, enum lm355x_mode opmode)
209{
210 int ret;
211 unsigned int reg_val;
212 struct lm355x_platform_data *pdata = chip->pdata;
213 struct lm355x_reg_data *preg = chip->regs;
214
215 ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
216 if (ret < 0)
217 goto out;
218 if (chip->last_flag & preg[REG_FLAG].mask)
219 dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
220 lm355x_name[chip->type],
221 chip->last_flag & preg[REG_FLAG].mask);
222 /* brightness 0 means shutdown */
223 if (!brightness)
224 opmode = MODE_SHDN;
225
226 switch (opmode) {
227 case MODE_TORCH:
228 ret =
229 regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
230 preg[REG_TORCH_CTRL].mask,
231 (brightness - 1)
232 << preg[REG_TORCH_CTRL].shift);
233 if (ret < 0)
234 goto out;
235
236 if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
237 ret =
238 regmap_update_bits(chip->regmap,
239 preg[REG_TORCH_CFG].regno,
240 preg[REG_TORCH_CFG].mask,
241 0x01 <<
242 preg[REG_TORCH_CFG].shift);
243 if (ret < 0)
244 goto out;
245 opmode = MODE_SHDN;
246 dev_info(chip->dev,
247 "torch brt is set - ext. torch pin mode\n");
248 }
249 break;
250
251 case MODE_FLASH:
252
253 ret =
254 regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
255 preg[REG_FLASH_CTRL].mask,
256 (brightness - 1)
257 << preg[REG_FLASH_CTRL].shift);
258 if (ret < 0)
259 goto out;
260
261 if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
262 if (chip->type == CHIP_LM3554)
263 reg_val = 0x00;
264 else
265 reg_val = 0x01;
266 ret =
267 regmap_update_bits(chip->regmap,
268 preg[REG_STROBE_CFG].regno,
269 preg[REG_STROBE_CFG].mask,
270 reg_val <<
271 preg[REG_STROBE_CFG].shift);
272 if (ret < 0)
273 goto out;
274 opmode = MODE_SHDN;
275 dev_info(chip->dev,
276 "flash brt is set - ext. strobe pin mode\n");
277 }
278 break;
279
280 case MODE_INDIC:
281 ret =
282 regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
283 preg[REG_INDI_CTRL].mask,
284 (brightness - 1)
285 << preg[REG_INDI_CTRL].shift);
286 if (ret < 0)
287 goto out;
288
289 if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
290 ret =
291 regmap_update_bits(chip->regmap,
292 preg[REG_INDI_CFG].regno,
293 preg[REG_INDI_CFG].mask,
294 0x01 <<
295 preg[REG_INDI_CFG].shift);
296 if (ret < 0)
297 goto out;
298 opmode = MODE_SHDN;
299 }
300 break;
301 case MODE_SHDN:
302 break;
303 default:
304 return;
305 }
306 /* operation mode control */
307 ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
308 preg[REG_OPMODE].mask,
309 opmode << preg[REG_OPMODE].shift);
310 if (ret < 0)
311 goto out;
312 return;
313out:
314 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
315 return;
316}
317
318/* torch */
319static void lm355x_deferred_torch_brightness_set(struct work_struct *work)
320{
321 struct lm355x_chip_data *chip =
322 container_of(work, struct lm355x_chip_data, work_torch);
323
324 mutex_lock(&chip->lock);
325 lm355x_control(chip, chip->br_torch, MODE_TORCH);
326 mutex_unlock(&chip->lock);
327}
328
329static void lm355x_torch_brightness_set(struct led_classdev *cdev,
330 enum led_brightness brightness)
331{
332 struct lm355x_chip_data *chip =
333 container_of(cdev, struct lm355x_chip_data, cdev_torch);
334
335 chip->br_torch = brightness;
336 schedule_work(&chip->work_torch);
337}
338
339/* flash */
340static void lm355x_deferred_strobe_brightness_set(struct work_struct *work)
341{
342 struct lm355x_chip_data *chip =
343 container_of(work, struct lm355x_chip_data, work_flash);
344
345 mutex_lock(&chip->lock);
346 lm355x_control(chip, chip->br_flash, MODE_FLASH);
347 mutex_unlock(&chip->lock);
348}
349
350static void lm355x_strobe_brightness_set(struct led_classdev *cdev,
351 enum led_brightness brightness)
352{
353 struct lm355x_chip_data *chip =
354 container_of(cdev, struct lm355x_chip_data, cdev_flash);
355
356 chip->br_flash = brightness;
357 schedule_work(&chip->work_flash);
358}
359
360/* indicator */
361static void lm355x_deferred_indicator_brightness_set(struct work_struct *work)
362{
363 struct lm355x_chip_data *chip =
364 container_of(work, struct lm355x_chip_data, work_indicator);
365
366 mutex_lock(&chip->lock);
367 lm355x_control(chip, chip->br_indicator, MODE_INDIC);
368 mutex_unlock(&chip->lock);
369}
370
371static void lm355x_indicator_brightness_set(struct led_classdev *cdev,
372 enum led_brightness brightness)
373{
374 struct lm355x_chip_data *chip =
375 container_of(cdev, struct lm355x_chip_data, cdev_indicator);
376
377 chip->br_indicator = brightness;
378 schedule_work(&chip->work_indicator);
379}
380
381/* indicator pattern only for lm3556*/
382static ssize_t lm3556_indicator_pattern_store(struct device *dev,
383 struct device_attribute *devAttr,
384 const char *buf, size_t size)
385{
386 ssize_t ret;
387 struct led_classdev *led_cdev = dev_get_drvdata(dev);
388 struct lm355x_chip_data *chip =
389 container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
390 unsigned int state;
391
392 ret = kstrtouint(buf, 10, &state);
393 if (ret)
394 goto out;
395 if (state > INDIC_PATTERN_SIZE - 1)
396 state = INDIC_PATTERN_SIZE - 1;
397
398 ret = regmap_write(chip->regmap, 0x04,
399 indicator_pattern[state].blinking);
400 if (ret < 0)
401 goto out;
402
403 ret = regmap_write(chip->regmap, 0x05,
404 indicator_pattern[state].period_cnt);
405 if (ret < 0)
406 goto out;
407
408 return size;
409out:
410 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
411 return ret;
412}
413
414static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);
415
416static const struct regmap_config lm355x_regmap = {
417 .reg_bits = 8,
418 .val_bits = 8,
419 .max_register = 0xFF,
420};
421
422/* module initialize */
423static int lm355x_probe(struct i2c_client *client,
424 const struct i2c_device_id *id)
425{
426 struct lm355x_platform_data *pdata = client->dev.platform_data;
427 struct lm355x_chip_data *chip;
428
429 int err;
430
431 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
432 dev_err(&client->dev, "i2c functionality check fail.\n");
433 return -EOPNOTSUPP;
434 }
435
436 if (pdata == NULL) {
437 dev_err(&client->dev, "needs Platform Data.\n");
438 return -ENODATA;
439 }
440
441 chip = devm_kzalloc(&client->dev,
442 sizeof(struct lm355x_chip_data), GFP_KERNEL);
443 if (!chip)
444 return -ENOMEM;
445
446 chip->dev = &client->dev;
447 chip->type = id->driver_data;
448 switch (id->driver_data) {
449 case CHIP_LM3554:
450 chip->regs = lm3554_regs;
451 break;
452 case CHIP_LM3556:
453 chip->regs = lm3556_regs;
454 break;
455 default:
456 return -ENOSYS;
457 }
458 chip->pdata = pdata;
459
460 chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
461 if (IS_ERR(chip->regmap)) {
462 err = PTR_ERR(chip->regmap);
463 dev_err(&client->dev,
464 "Failed to allocate register map: %d\n", err);
465 return err;
466 }
467
468 mutex_init(&chip->lock);
469 i2c_set_clientdata(client, chip);
470
471 err = lm355x_chip_init(chip);
472 if (err < 0)
473 goto err_out;
474
475 /* flash */
476 INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set);
477 chip->cdev_flash.name = "flash";
478 chip->cdev_flash.max_brightness = 16;
479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
480 err = led_classdev_register((struct device *)
481 &client->dev, &chip->cdev_flash);
482 if (err < 0)
483 goto err_out;
484 /* torch */
485 INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set);
486 chip->cdev_torch.name = "torch";
487 chip->cdev_torch.max_brightness = 8;
488 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
489 err = led_classdev_register((struct device *)
490 &client->dev, &chip->cdev_torch);
491 if (err < 0)
492 goto err_create_torch_file;
493 /* indicator */
494 INIT_WORK(&chip->work_indicator,
495 lm355x_deferred_indicator_brightness_set);
496 chip->cdev_indicator.name = "indicator";
497 if (id->driver_data == CHIP_LM3554)
498 chip->cdev_indicator.max_brightness = 4;
499 else
500 chip->cdev_indicator.max_brightness = 8;
501 chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
502 err = led_classdev_register((struct device *)
503 &client->dev, &chip->cdev_indicator);
504 if (err < 0)
505 goto err_create_indicator_file;
506 /* indicator pattern control only for LM3554 */
507 if (id->driver_data == CHIP_LM3556) {
508 err =
509 device_create_file(chip->cdev_indicator.dev,
510 &dev_attr_pattern);
511 if (err < 0)
512 goto err_create_pattern_file;
513 }
514
515 dev_info(&client->dev, "%s is initialized\n",
516 lm355x_name[id->driver_data]);
517 return 0;
518
519err_create_pattern_file:
520 led_classdev_unregister(&chip->cdev_indicator);
521err_create_indicator_file:
522 led_classdev_unregister(&chip->cdev_torch);
523err_create_torch_file:
524 led_classdev_unregister(&chip->cdev_flash);
525err_out:
526 return err;
527}
528
529static int lm355x_remove(struct i2c_client *client)
530{
531 struct lm355x_chip_data *chip = i2c_get_clientdata(client);
532 struct lm355x_reg_data *preg = chip->regs;
533
534 regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
535 if (chip->type == CHIP_LM3556)
536 device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
537 led_classdev_unregister(&chip->cdev_indicator);
538 flush_work(&chip->work_indicator);
539 led_classdev_unregister(&chip->cdev_torch);
540 flush_work(&chip->work_torch);
541 led_classdev_unregister(&chip->cdev_flash);
542 flush_work(&chip->work_flash);
543 dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);
544
545 return 0;
546}
547
548static const struct i2c_device_id lm355x_id[] = {
549 {LM3554_NAME, CHIP_LM3554},
550 {LM3556_NAME, CHIP_LM3556},
551 {}
552};
553
554MODULE_DEVICE_TABLE(i2c, lm355x_id);
555
556static struct i2c_driver lm355x_i2c_driver = {
557 .driver = {
558 .name = LM355x_NAME,
559 .owner = THIS_MODULE,
560 .pm = NULL,
561 },
562 .probe = lm355x_probe,
563 .remove = lm355x_remove,
564 .id_table = lm355x_id,
565};
566
567module_i2c_driver(lm355x_i2c_driver);
568
569MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
570MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
571MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
572MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
deleted file mode 100644
index 07b3dde9061..00000000000
--- a/drivers/leds/leds-lm3642.c
+++ /dev/null
@@ -1,462 +0,0 @@
1/*
2* Simple driver for Texas Instruments LM3642 LED Flash driver chip
3* Copyright (C) 2012 Texas Instruments
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License version 2 as
7* published by the Free Software Foundation.
8*
9*/
10#include <linux/module.h>
11#include <linux/delay.h>
12#include <linux/i2c.h>
13#include <linux/leds.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <linux/fs.h>
17#include <linux/regmap.h>
18#include <linux/workqueue.h>
19#include <linux/platform_data/leds-lm3642.h>
20
21#define REG_FILT_TIME (0x0)
22#define REG_IVFM_MODE (0x1)
23#define REG_TORCH_TIME (0x6)
24#define REG_FLASH (0x8)
25#define REG_I_CTRL (0x9)
26#define REG_ENABLE (0xA)
27#define REG_FLAG (0xB)
28#define REG_MAX (0xB)
29
30#define UVLO_EN_SHIFT (7)
31#define IVM_D_TH_SHIFT (2)
32#define TORCH_RAMP_UP_TIME_SHIFT (3)
33#define TORCH_RAMP_DN_TIME_SHIFT (0)
34#define INDUCTOR_I_LIMIT_SHIFT (6)
35#define FLASH_RAMP_TIME_SHIFT (3)
36#define FLASH_TOUT_TIME_SHIFT (0)
37#define TORCH_I_SHIFT (4)
38#define FLASH_I_SHIFT (0)
39#define IVFM_SHIFT (7)
40#define TX_PIN_EN_SHIFT (6)
41#define STROBE_PIN_EN_SHIFT (5)
42#define TORCH_PIN_EN_SHIFT (4)
43#define MODE_BITS_SHIFT (0)
44
45#define UVLO_EN_MASK (0x1)
46#define IVM_D_TH_MASK (0x7)
47#define TORCH_RAMP_UP_TIME_MASK (0x7)
48#define TORCH_RAMP_DN_TIME_MASK (0x7)
49#define INDUCTOR_I_LIMIT_MASK (0x1)
50#define FLASH_RAMP_TIME_MASK (0x7)
51#define FLASH_TOUT_TIME_MASK (0x7)
52#define TORCH_I_MASK (0x7)
53#define FLASH_I_MASK (0xF)
54#define IVFM_MASK (0x1)
55#define TX_PIN_EN_MASK (0x1)
56#define STROBE_PIN_EN_MASK (0x1)
57#define TORCH_PIN_EN_MASK (0x1)
58#define MODE_BITS_MASK (0x73)
59#define EX_PIN_CONTROL_MASK (0x71)
60#define EX_PIN_ENABLE_MASK (0x70)
61
62enum lm3642_mode {
63 MODES_STASNDBY = 0,
64 MODES_INDIC,
65 MODES_TORCH,
66 MODES_FLASH
67};
68
69struct lm3642_chip_data {
70 struct device *dev;
71
72 struct led_classdev cdev_flash;
73 struct led_classdev cdev_torch;
74 struct led_classdev cdev_indicator;
75
76 struct work_struct work_flash;
77 struct work_struct work_torch;
78 struct work_struct work_indicator;
79
80 u8 br_flash;
81 u8 br_torch;
82 u8 br_indicator;
83
84 enum lm3642_torch_pin_enable torch_pin;
85 enum lm3642_strobe_pin_enable strobe_pin;
86 enum lm3642_tx_pin_enable tx_pin;
87
88 struct lm3642_platform_data *pdata;
89 struct regmap *regmap;
90 struct mutex lock;
91
92 unsigned int last_flag;
93};
94
95/* chip initialize */
96static int lm3642_chip_init(struct lm3642_chip_data *chip)
97{
98 int ret;
99 struct lm3642_platform_data *pdata = chip->pdata;
100
101 /* set enable register */
102 ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK,
103 pdata->tx_pin);
104 if (ret < 0)
105 dev_err(chip->dev, "Failed to update REG_ENABLE Register\n");
106 return ret;
107}
108
109/* chip control */
110static int lm3642_control(struct lm3642_chip_data *chip,
111 u8 brightness, enum lm3642_mode opmode)
112{
113 int ret;
114
115 ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
116 if (ret < 0) {
117 dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
118 goto out;
119 }
120
121 if (chip->last_flag)
122 dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
123
124 /* brightness 0 means off-state */
125 if (!brightness)
126 opmode = MODES_STASNDBY;
127
128 switch (opmode) {
129 case MODES_TORCH:
130 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
131 TORCH_I_MASK << TORCH_I_SHIFT,
132 (brightness - 1) << TORCH_I_SHIFT);
133
134 if (chip->torch_pin)
135 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
136 break;
137
138 case MODES_FLASH:
139 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
140 FLASH_I_MASK << FLASH_I_SHIFT,
141 (brightness - 1) << FLASH_I_SHIFT);
142
143 if (chip->strobe_pin)
144 opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT);
145 break;
146
147 case MODES_INDIC:
148 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
149 TORCH_I_MASK << TORCH_I_SHIFT,
150 (brightness - 1) << TORCH_I_SHIFT);
151 break;
152
153 case MODES_STASNDBY:
154
155 break;
156
157 default:
158 return ret;
159 }
160 if (ret < 0) {
161 dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
162 goto out;
163 }
164
165 if (chip->tx_pin)
166 opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT);
167
168 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
169 MODE_BITS_MASK << MODE_BITS_SHIFT,
170 opmode << MODE_BITS_SHIFT);
171out:
172 return ret;
173}
174
175/* torch */
176
177/* torch pin config for lm3642*/
178static ssize_t lm3642_torch_pin_store(struct device *dev,
179 struct device_attribute *devAttr,
180 const char *buf, size_t size)
181{
182 ssize_t ret;
183 struct led_classdev *led_cdev = dev_get_drvdata(dev);
184 struct lm3642_chip_data *chip =
185 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
186 unsigned int state;
187
188 ret = kstrtouint(buf, 10, &state);
189 if (ret)
190 goto out_strtoint;
191 if (state != 0)
192 state = 0x01 << TORCH_PIN_EN_SHIFT;
193
194 chip->torch_pin = state;
195 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
196 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT,
197 state);
198 if (ret < 0)
199 goto out;
200
201 return size;
202out:
203 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
204 return ret;
205out_strtoint:
206 dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
207 return ret;
208}
209
210static DEVICE_ATTR(torch_pin, S_IWUSR, NULL, lm3642_torch_pin_store);
211
212static void lm3642_deferred_torch_brightness_set(struct work_struct *work)
213{
214 struct lm3642_chip_data *chip =
215 container_of(work, struct lm3642_chip_data, work_torch);
216
217 mutex_lock(&chip->lock);
218 lm3642_control(chip, chip->br_torch, MODES_TORCH);
219 mutex_unlock(&chip->lock);
220}
221
222static void lm3642_torch_brightness_set(struct led_classdev *cdev,
223 enum led_brightness brightness)
224{
225 struct lm3642_chip_data *chip =
226 container_of(cdev, struct lm3642_chip_data, cdev_torch);
227
228 chip->br_torch = brightness;
229 schedule_work(&chip->work_torch);
230}
231
232/* flash */
233
234/* strobe pin config for lm3642*/
235static ssize_t lm3642_strobe_pin_store(struct device *dev,
236 struct device_attribute *devAttr,
237 const char *buf, size_t size)
238{
239 ssize_t ret;
240 struct led_classdev *led_cdev = dev_get_drvdata(dev);
241 struct lm3642_chip_data *chip =
242 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
243 unsigned int state;
244
245 ret = kstrtouint(buf, 10, &state);
246 if (ret)
247 goto out_strtoint;
248 if (state != 0)
249 state = 0x01 << STROBE_PIN_EN_SHIFT;
250
251 chip->strobe_pin = state;
252 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
253 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT,
254 state);
255 if (ret < 0)
256 goto out;
257
258 return size;
259out:
260 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
261 return ret;
262out_strtoint:
263 dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
264 return ret;
265}
266
267static DEVICE_ATTR(strobe_pin, S_IWUSR, NULL, lm3642_strobe_pin_store);
268
269static void lm3642_deferred_strobe_brightness_set(struct work_struct *work)
270{
271 struct lm3642_chip_data *chip =
272 container_of(work, struct lm3642_chip_data, work_flash);
273
274 mutex_lock(&chip->lock);
275 lm3642_control(chip, chip->br_flash, MODES_FLASH);
276 mutex_unlock(&chip->lock);
277}
278
279static void lm3642_strobe_brightness_set(struct led_classdev *cdev,
280 enum led_brightness brightness)
281{
282 struct lm3642_chip_data *chip =
283 container_of(cdev, struct lm3642_chip_data, cdev_flash);
284
285 chip->br_flash = brightness;
286 schedule_work(&chip->work_flash);
287}
288
289/* indicator */
290static void lm3642_deferred_indicator_brightness_set(struct work_struct *work)
291{
292 struct lm3642_chip_data *chip =
293 container_of(work, struct lm3642_chip_data, work_indicator);
294
295 mutex_lock(&chip->lock);
296 lm3642_control(chip, chip->br_indicator, MODES_INDIC);
297 mutex_unlock(&chip->lock);
298}
299
300static void lm3642_indicator_brightness_set(struct led_classdev *cdev,
301 enum led_brightness brightness)
302{
303 struct lm3642_chip_data *chip =
304 container_of(cdev, struct lm3642_chip_data, cdev_indicator);
305
306 chip->br_indicator = brightness;
307 schedule_work(&chip->work_indicator);
308}
309
310static const struct regmap_config lm3642_regmap = {
311 .reg_bits = 8,
312 .val_bits = 8,
313 .max_register = REG_MAX,
314};
315
316static int lm3642_probe(struct i2c_client *client,
317 const struct i2c_device_id *id)
318{
319 struct lm3642_platform_data *pdata = client->dev.platform_data;
320 struct lm3642_chip_data *chip;
321
322 int err;
323
324 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
325 dev_err(&client->dev, "i2c functionality check fail.\n");
326 return -EOPNOTSUPP;
327 }
328
329 if (pdata == NULL) {
330 dev_err(&client->dev, "needs Platform Data.\n");
331 return -ENODATA;
332 }
333
334 chip = devm_kzalloc(&client->dev,
335 sizeof(struct lm3642_chip_data), GFP_KERNEL);
336 if (!chip)
337 return -ENOMEM;
338
339 chip->dev = &client->dev;
340 chip->pdata = pdata;
341
342 chip->tx_pin = pdata->tx_pin;
343 chip->torch_pin = pdata->torch_pin;
344 chip->strobe_pin = pdata->strobe_pin;
345
346 chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap);
347 if (IS_ERR(chip->regmap)) {
348 err = PTR_ERR(chip->regmap);
349 dev_err(&client->dev, "Failed to allocate register map: %d\n",
350 err);
351 return err;
352 }
353
354 mutex_init(&chip->lock);
355 i2c_set_clientdata(client, chip);
356
357 err = lm3642_chip_init(chip);
358 if (err < 0)
359 goto err_out;
360
361 /* flash */
362 INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set);
363 chip->cdev_flash.name = "flash";
364 chip->cdev_flash.max_brightness = 16;
365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
366 err = led_classdev_register((struct device *)
367 &client->dev, &chip->cdev_flash);
368 if (err < 0) {
369 dev_err(chip->dev, "failed to register flash\n");
370 goto err_out;
371 }
372 err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
373 if (err < 0) {
374 dev_err(chip->dev, "failed to create strobe-pin file\n");
375 goto err_create_flash_pin_file;
376 }
377
378 /* torch */
379 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
380 chip->cdev_torch.name = "torch";
381 chip->cdev_torch.max_brightness = 8;
382 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
383 err = led_classdev_register((struct device *)
384 &client->dev, &chip->cdev_torch);
385 if (err < 0) {
386 dev_err(chip->dev, "failed to register torch\n");
387 goto err_create_torch_file;
388 }
389 err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
390 if (err < 0) {
391 dev_err(chip->dev, "failed to create torch-pin file\n");
392 goto err_create_torch_pin_file;
393 }
394
395 /* indicator */
396 INIT_WORK(&chip->work_indicator,
397 lm3642_deferred_indicator_brightness_set);
398 chip->cdev_indicator.name = "indicator";
399 chip->cdev_indicator.max_brightness = 8;
400 chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set;
401 err = led_classdev_register((struct device *)
402 &client->dev, &chip->cdev_indicator);
403 if (err < 0) {
404 dev_err(chip->dev, "failed to register indicator\n");
405 goto err_create_indicator_file;
406 }
407
408 dev_info(&client->dev, "LM3642 is initialized\n");
409 return 0;
410
411err_create_indicator_file:
412 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
413err_create_torch_pin_file:
414 led_classdev_unregister(&chip->cdev_torch);
415err_create_torch_file:
416 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
417err_create_flash_pin_file:
418 led_classdev_unregister(&chip->cdev_flash);
419err_out:
420 return err;
421}
422
423static int lm3642_remove(struct i2c_client *client)
424{
425 struct lm3642_chip_data *chip = i2c_get_clientdata(client);
426
427 led_classdev_unregister(&chip->cdev_indicator);
428 flush_work(&chip->work_indicator);
429 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
430 led_classdev_unregister(&chip->cdev_torch);
431 flush_work(&chip->work_torch);
432 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
433 led_classdev_unregister(&chip->cdev_flash);
434 flush_work(&chip->work_flash);
435 regmap_write(chip->regmap, REG_ENABLE, 0);
436 return 0;
437}
438
439static const struct i2c_device_id lm3642_id[] = {
440 {LM3642_NAME, 0},
441 {}
442};
443
444MODULE_DEVICE_TABLE(i2c, lm3642_id);
445
446static struct i2c_driver lm3642_i2c_driver = {
447 .driver = {
448 .name = LM3642_NAME,
449 .owner = THIS_MODULE,
450 .pm = NULL,
451 },
452 .probe = lm3642_probe,
453 .remove = lm3642_remove,
454 .id_table = lm3642_id,
455};
456
457module_i2c_driver(lm3642_i2c_driver);
458
459MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642");
460MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
461MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
462MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 80ba048889d..1f7c10f6b7f 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/device.h> 13#include <linux/device.h>
15#include <linux/leds.h> 14#include <linux/leds.h>
16 15
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index 0c4386e656c..9010c054615 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -86,7 +86,7 @@ static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value)
86 86
87 tmp = i2c_smbus_read_byte_data(client, reg); 87 tmp = i2c_smbus_read_byte_data(client, reg);
88 if (tmp < 0) 88 if (tmp < 0)
89 return tmp; 89 return -EINVAL;
90 90
91 *value = tmp; 91 *value = tmp;
92 92
@@ -374,7 +374,7 @@ exit:
374 return err; 374 return err;
375} 375}
376 376
377static int lp3944_probe(struct i2c_client *client, 377static int __devinit lp3944_probe(struct i2c_client *client,
378 const struct i2c_device_id *id) 378 const struct i2c_device_id *id)
379{ 379{
380 struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; 380 struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data;
@@ -393,8 +393,7 @@ static int lp3944_probe(struct i2c_client *client,
393 return -ENODEV; 393 return -ENODEV;
394 } 394 }
395 395
396 data = devm_kzalloc(&client->dev, sizeof(struct lp3944_data), 396 data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL);
397 GFP_KERNEL);
398 if (!data) 397 if (!data)
399 return -ENOMEM; 398 return -ENOMEM;
400 399
@@ -404,14 +403,16 @@ static int lp3944_probe(struct i2c_client *client,
404 mutex_init(&data->lock); 403 mutex_init(&data->lock);
405 404
406 err = lp3944_configure(client, data, lp3944_pdata); 405 err = lp3944_configure(client, data, lp3944_pdata);
407 if (err < 0) 406 if (err < 0) {
407 kfree(data);
408 return err; 408 return err;
409 }
409 410
410 dev_info(&client->dev, "lp3944 enabled\n"); 411 dev_info(&client->dev, "lp3944 enabled\n");
411 return 0; 412 return 0;
412} 413}
413 414
414static int lp3944_remove(struct i2c_client *client) 415static int __devexit lp3944_remove(struct i2c_client *client)
415{ 416{
416 struct lp3944_platform_data *pdata = client->dev.platform_data; 417 struct lp3944_platform_data *pdata = client->dev.platform_data;
417 struct lp3944_data *data = i2c_get_clientdata(client); 418 struct lp3944_data *data = i2c_get_clientdata(client);
@@ -430,6 +431,8 @@ static int lp3944_remove(struct i2c_client *client)
430 break; 431 break;
431 } 432 }
432 433
434 kfree(data);
435
433 return 0; 436 return 0;
434} 437}
435 438
@@ -446,11 +449,22 @@ static struct i2c_driver lp3944_driver = {
446 .name = "lp3944", 449 .name = "lp3944",
447 }, 450 },
448 .probe = lp3944_probe, 451 .probe = lp3944_probe,
449 .remove = lp3944_remove, 452 .remove = __devexit_p(lp3944_remove),
450 .id_table = lp3944_id, 453 .id_table = lp3944_id,
451}; 454};
452 455
453module_i2c_driver(lp3944_driver); 456static int __init lp3944_module_init(void)
457{
458 return i2c_add_driver(&lp3944_driver);
459}
460
461static void __exit lp3944_module_exit(void)
462{
463 i2c_del_driver(&lp3944_driver);
464}
465
466module_init(lp3944_module_init);
467module_exit(lp3944_module_exit);
454 468
455MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 469MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
456MODULE_DESCRIPTION("LP3944 Fun Light Chip"); 470MODULE_DESCRIPTION("LP3944 Fun Light Chip");
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index cb8a5220200..9fc122c81f0 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -81,20 +81,22 @@
81#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */ 81#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */
82#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ 82#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
83#define LP5521_EXEC_RUN 0x2A 83#define LP5521_EXEC_RUN 0x2A
84#define LP5521_ENABLE_DEFAULT \ 84
85 (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM) 85/* Bits in CONFIG register */
86#define LP5521_ENABLE_RUN_PROGRAM \ 86#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
87 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN) 87#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
88#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */
89#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */
90#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */
91#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */
92#define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */
93#define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */
94#define LP5521_CLK_INT 1 /* Internal clock */
95#define LP5521_CLK_AUTO 2 /* Automatic clock selection */
88 96
89/* Status */ 97/* Status */
90#define LP5521_EXT_CLK_USED 0x08 98#define LP5521_EXT_CLK_USED 0x08
91 99
92/* default R channel current register value */
93#define LP5521_REG_R_CURR_DEFAULT 0xAF
94
95/* Pattern Mode */
96#define PATTERN_OFF 0
97
98struct lp5521_engine { 100struct lp5521_engine {
99 int id; 101 int id;
100 u8 mode; 102 u8 mode;
@@ -152,7 +154,7 @@ static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf)
152 154
153 ret = i2c_smbus_read_byte_data(client, reg); 155 ret = i2c_smbus_read_byte_data(client, reg);
154 if (ret < 0) 156 if (ret < 0)
155 return ret; 157 return -EIO;
156 158
157 *buf = ret; 159 *buf = ret;
158 return 0; 160 return 0;
@@ -173,14 +175,14 @@ static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode)
173 mode = LP5521_CMD_DIRECT; 175 mode = LP5521_CMD_DIRECT;
174 176
175 ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); 177 ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state);
176 if (ret < 0)
177 return ret;
178 178
179 /* set mode only for this engine */ 179 /* set mode only for this engine */
180 engine_state &= ~(engine->engine_mask); 180 engine_state &= ~(engine->engine_mask);
181 mode &= engine->engine_mask; 181 mode &= engine->engine_mask;
182 engine_state |= mode; 182 engine_state |= mode;
183 return lp5521_write(client, LP5521_REG_OP_MODE, engine_state); 183 ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state);
184
185 return ret;
184} 186}
185 187
186static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) 188static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
@@ -193,14 +195,9 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
193 195
194 /* move current engine to direct mode and remember the state */ 196 /* move current engine to direct mode and remember the state */
195 ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); 197 ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
196 if (ret)
197 return ret;
198
199 /* Mode change requires min 500 us delay. 1 - 2 ms with margin */ 198 /* Mode change requires min 500 us delay. 1 - 2 ms with margin */
200 usleep_range(1000, 2000); 199 usleep_range(1000, 2000);
201 ret = lp5521_read(client, LP5521_REG_OP_MODE, &mode); 200 ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode);
202 if (ret)
203 return ret;
204 201
205 /* For loading, all the engines to load mode */ 202 /* For loading, all the engines to load mode */
206 lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 203 lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
@@ -216,7 +213,8 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
216 LP5521_PROG_MEM_SIZE, 213 LP5521_PROG_MEM_SIZE,
217 pattern); 214 pattern);
218 215
219 return lp5521_write(client, LP5521_REG_OP_MODE, mode); 216 ret |= lp5521_write(client, LP5521_REG_OP_MODE, mode);
217 return ret;
220} 218}
221 219
222static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) 220static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr)
@@ -240,16 +238,15 @@ static int lp5521_configure(struct i2c_client *client)
240{ 238{
241 struct lp5521_chip *chip = i2c_get_clientdata(client); 239 struct lp5521_chip *chip = i2c_get_clientdata(client);
242 int ret; 240 int ret;
243 u8 cfg;
244 241
245 lp5521_init_engine(chip); 242 lp5521_init_engine(chip);
246 243
247 /* Set all PWMs to direct control mode */ 244 /* Set all PWMs to direct control mode */
248 ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 245 ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
249 246
250 cfg = chip->pdata->update_config ? 247 /* Enable auto-powersave, set charge pump to auto, red to battery */
251 : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); 248 ret |= lp5521_write(client, LP5521_REG_CONFIG,
252 ret |= lp5521_write(client, LP5521_REG_CONFIG, cfg); 249 LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
253 250
254 /* Initialize all channels PWM to zero -> leds off */ 251 /* Initialize all channels PWM to zero -> leds off */
255 ret |= lp5521_write(client, LP5521_REG_R_PWM, 0); 252 ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
@@ -258,7 +255,8 @@ static int lp5521_configure(struct i2c_client *client)
258 255
259 /* Set engines are set to run state when OP_MODE enables engines */ 256 /* Set engines are set to run state when OP_MODE enables engines */
260 ret |= lp5521_write(client, LP5521_REG_ENABLE, 257 ret |= lp5521_write(client, LP5521_REG_ENABLE,
261 LP5521_ENABLE_RUN_PROGRAM); 258 LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
259 LP5521_EXEC_RUN);
262 /* enable takes 500us. 1 - 2 ms leaves some margin */ 260 /* enable takes 500us. 1 - 2 ms leaves some margin */
263 usleep_range(1000, 2000); 261 usleep_range(1000, 2000);
264 262
@@ -309,7 +307,8 @@ static int lp5521_detect(struct i2c_client *client)
309 int ret; 307 int ret;
310 u8 buf; 308 u8 buf;
311 309
312 ret = lp5521_write(client, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT); 310 ret = lp5521_write(client, LP5521_REG_ENABLE,
311 LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
313 if (ret) 312 if (ret)
314 return ret; 313 return ret;
315 /* enable takes 500us. 1 - 2 ms leaves some margin */ 314 /* enable takes 500us. 1 - 2 ms leaves some margin */
@@ -317,7 +316,7 @@ static int lp5521_detect(struct i2c_client *client)
317 ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); 316 ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
318 if (ret) 317 if (ret)
319 return ret; 318 return ret;
320 if (buf != LP5521_ENABLE_DEFAULT) 319 if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM))
321 return -ENODEV; 320 return -ENODEV;
322 321
323 return 0; 322 return 0;
@@ -502,7 +501,7 @@ static ssize_t store_current(struct device *dev,
502 ssize_t ret; 501 ssize_t ret;
503 unsigned long curr; 502 unsigned long curr;
504 503
505 if (kstrtoul(buf, 0, &curr)) 504 if (strict_strtoul(buf, 0, &curr))
506 return -EINVAL; 505 return -EINVAL;
507 506
508 if (curr > led->max_current) 507 if (curr > led->max_current)
@@ -534,97 +533,6 @@ static ssize_t lp5521_selftest(struct device *dev,
534 return sprintf(buf, "%s\n", ret ? "FAIL" : "OK"); 533 return sprintf(buf, "%s\n", ret ? "FAIL" : "OK");
535} 534}
536 535
537static void lp5521_clear_program_memory(struct i2c_client *cl)
538{
539 int i;
540 u8 rgb_mem[] = {
541 LP5521_REG_R_PROG_MEM,
542 LP5521_REG_G_PROG_MEM,
543 LP5521_REG_B_PROG_MEM,
544 };
545
546 for (i = 0; i < ARRAY_SIZE(rgb_mem); i++) {
547 lp5521_write(cl, rgb_mem[i], 0);
548 lp5521_write(cl, rgb_mem[i] + 1, 0);
549 }
550}
551
552static void lp5521_write_program_memory(struct i2c_client *cl,
553 u8 base, u8 *rgb, int size)
554{
555 int i;
556
557 if (!rgb || size <= 0)
558 return;
559
560 for (i = 0; i < size; i++)
561 lp5521_write(cl, base + i, *(rgb + i));
562
563 lp5521_write(cl, base + i, 0);
564 lp5521_write(cl, base + i + 1, 0);
565}
566
567static inline struct lp5521_led_pattern *lp5521_get_pattern
568 (struct lp5521_chip *chip, u8 offset)
569{
570 struct lp5521_led_pattern *ptn;
571 ptn = chip->pdata->patterns + (offset - 1);
572 return ptn;
573}
574
575static void lp5521_run_led_pattern(int mode, struct lp5521_chip *chip)
576{
577 struct lp5521_led_pattern *ptn;
578 struct i2c_client *cl = chip->client;
579 int num_patterns = chip->pdata->num_patterns;
580
581 if (mode > num_patterns || !(chip->pdata->patterns))
582 return;
583
584 if (mode == PATTERN_OFF) {
585 lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
586 usleep_range(1000, 2000);
587 lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
588 } else {
589 ptn = lp5521_get_pattern(chip, mode);
590 if (!ptn)
591 return;
592
593 lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
594 usleep_range(1000, 2000);
595
596 lp5521_clear_program_memory(cl);
597
598 lp5521_write_program_memory(cl, LP5521_REG_R_PROG_MEM,
599 ptn->r, ptn->size_r);
600 lp5521_write_program_memory(cl, LP5521_REG_G_PROG_MEM,
601 ptn->g, ptn->size_g);
602 lp5521_write_program_memory(cl, LP5521_REG_B_PROG_MEM,
603 ptn->b, ptn->size_b);
604
605 lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_RUN);
606 usleep_range(1000, 2000);
607 lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
608 }
609}
610
611static ssize_t store_led_pattern(struct device *dev,
612 struct device_attribute *attr,
613 const char *buf, size_t len)
614{
615 struct lp5521_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
616 unsigned long val;
617 int ret;
618
619 ret = kstrtoul(buf, 16, &val);
620 if (ret)
621 return ret;
622
623 lp5521_run_led_pattern(val, chip);
624
625 return len;
626}
627
628/* led class device attributes */ 536/* led class device attributes */
629static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current); 537static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
630static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); 538static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
@@ -650,7 +558,6 @@ static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
650static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load); 558static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
651static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load); 559static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
652static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); 560static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
653static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, store_led_pattern);
654 561
655static struct attribute *lp5521_attributes[] = { 562static struct attribute *lp5521_attributes[] = {
656 &dev_attr_engine1_mode.attr, 563 &dev_attr_engine1_mode.attr,
@@ -660,7 +567,6 @@ static struct attribute *lp5521_attributes[] = {
660 &dev_attr_engine1_load.attr, 567 &dev_attr_engine1_load.attr,
661 &dev_attr_engine2_load.attr, 568 &dev_attr_engine2_load.attr,
662 &dev_attr_engine3_load.attr, 569 &dev_attr_engine3_load.attr,
663 &dev_attr_led_pattern.attr,
664 NULL 570 NULL
665}; 571};
666 572
@@ -687,7 +593,7 @@ static void lp5521_unregister_sysfs(struct i2c_client *client)
687 &lp5521_led_attribute_group); 593 &lp5521_led_attribute_group);
688} 594}
689 595
690static int lp5521_init_led(struct lp5521_led *led, 596static int __devinit lp5521_init_led(struct lp5521_led *led,
691 struct i2c_client *client, 597 struct i2c_client *client,
692 int chan, struct lp5521_platform_data *pdata) 598 int chan, struct lp5521_platform_data *pdata)
693{ 599{
@@ -711,15 +617,10 @@ static int lp5521_init_led(struct lp5521_led *led,
711 return -EINVAL; 617 return -EINVAL;
712 } 618 }
713 619
714 led->cdev.brightness_set = lp5521_set_brightness; 620 snprintf(name, sizeof(name), "%s:channel%d",
715 if (pdata->led_config[chan].name) {
716 led->cdev.name = pdata->led_config[chan].name;
717 } else {
718 snprintf(name, sizeof(name), "%s:channel%d",
719 pdata->label ?: client->name, chan); 621 pdata->label ?: client->name, chan);
720 led->cdev.name = name; 622 led->cdev.brightness_set = lp5521_set_brightness;
721 } 623 led->cdev.name = name;
722
723 res = led_classdev_register(dev, &led->cdev); 624 res = led_classdev_register(dev, &led->cdev);
724 if (res < 0) { 625 if (res < 0) {
725 dev_err(dev, "couldn't register led on channel %d\n", chan); 626 dev_err(dev, "couldn't register led on channel %d\n", chan);
@@ -736,15 +637,14 @@ static int lp5521_init_led(struct lp5521_led *led,
736 return 0; 637 return 0;
737} 638}
738 639
739static int lp5521_probe(struct i2c_client *client, 640static int __devinit lp5521_probe(struct i2c_client *client,
740 const struct i2c_device_id *id) 641 const struct i2c_device_id *id)
741{ 642{
742 struct lp5521_chip *chip; 643 struct lp5521_chip *chip;
743 struct lp5521_platform_data *pdata; 644 struct lp5521_platform_data *pdata;
744 int ret, i, led; 645 int ret, i, led;
745 u8 buf;
746 646
747 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 647 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
748 if (!chip) 648 if (!chip)
749 return -ENOMEM; 649 return -ENOMEM;
750 650
@@ -755,7 +655,8 @@ static int lp5521_probe(struct i2c_client *client,
755 655
756 if (!pdata) { 656 if (!pdata) {
757 dev_err(&client->dev, "no platform data\n"); 657 dev_err(&client->dev, "no platform data\n");
758 return -EINVAL; 658 ret = -EINVAL;
659 goto fail1;
759 } 660 }
760 661
761 mutex_init(&chip->lock); 662 mutex_init(&chip->lock);
@@ -765,7 +666,7 @@ static int lp5521_probe(struct i2c_client *client,
765 if (pdata->setup_resources) { 666 if (pdata->setup_resources) {
766 ret = pdata->setup_resources(); 667 ret = pdata->setup_resources();
767 if (ret < 0) 668 if (ret < 0)
768 return ret; 669 goto fail1;
769 } 670 }
770 671
771 if (pdata->enable) { 672 if (pdata->enable) {
@@ -780,27 +681,6 @@ static int lp5521_probe(struct i2c_client *client,
780 * Exact value is not available. 10 - 20ms 681 * Exact value is not available. 10 - 20ms
781 * appears to be enough for reset. 682 * appears to be enough for reset.
782 */ 683 */
783
784 /*
785 * Make sure that the chip is reset by reading back the r channel
786 * current reg. This is dummy read is required on some platforms -
787 * otherwise further access to the R G B channels in the
788 * LP5521_REG_ENABLE register will not have any effect - strange!
789 */
790 ret = lp5521_read(client, LP5521_REG_R_CURRENT, &buf);
791 if (ret) {
792 dev_err(&client->dev, "error in resetting chip\n");
793 goto fail2;
794 }
795 if (buf != LP5521_REG_R_CURR_DEFAULT) {
796 dev_err(&client->dev,
797 "unexpected data in register (expected 0x%x got 0x%x)\n",
798 LP5521_REG_R_CURR_DEFAULT, buf);
799 ret = -EINVAL;
800 goto fail2;
801 }
802 usleep_range(10000, 20000);
803
804 ret = lp5521_detect(client); 684 ret = lp5521_detect(client);
805 685
806 if (ret) { 686 if (ret) {
@@ -813,7 +693,7 @@ static int lp5521_probe(struct i2c_client *client,
813 ret = lp5521_configure(client); 693 ret = lp5521_configure(client);
814 if (ret < 0) { 694 if (ret < 0) {
815 dev_err(&client->dev, "error configuring chip\n"); 695 dev_err(&client->dev, "error configuring chip\n");
816 goto fail1; 696 goto fail2;
817 } 697 }
818 698
819 /* Initialize leds */ 699 /* Initialize leds */
@@ -828,7 +708,7 @@ static int lp5521_probe(struct i2c_client *client,
828 ret = lp5521_init_led(&chip->leds[led], client, i, pdata); 708 ret = lp5521_init_led(&chip->leds[led], client, i, pdata);
829 if (ret) { 709 if (ret) {
830 dev_err(&client->dev, "error initializing leds\n"); 710 dev_err(&client->dev, "error initializing leds\n");
831 goto fail2; 711 goto fail3;
832 } 712 }
833 chip->num_leds++; 713 chip->num_leds++;
834 714
@@ -846,28 +726,29 @@ static int lp5521_probe(struct i2c_client *client,
846 ret = lp5521_register_sysfs(client); 726 ret = lp5521_register_sysfs(client);
847 if (ret) { 727 if (ret) {
848 dev_err(&client->dev, "registering sysfs failed\n"); 728 dev_err(&client->dev, "registering sysfs failed\n");
849 goto fail2; 729 goto fail3;
850 } 730 }
851 return ret; 731 return ret;
852fail2: 732fail3:
853 for (i = 0; i < chip->num_leds; i++) { 733 for (i = 0; i < chip->num_leds; i++) {
854 led_classdev_unregister(&chip->leds[i].cdev); 734 led_classdev_unregister(&chip->leds[i].cdev);
855 cancel_work_sync(&chip->leds[i].brightness_work); 735 cancel_work_sync(&chip->leds[i].brightness_work);
856 } 736 }
857fail1: 737fail2:
858 if (pdata->enable) 738 if (pdata->enable)
859 pdata->enable(0); 739 pdata->enable(0);
860 if (pdata->release_resources) 740 if (pdata->release_resources)
861 pdata->release_resources(); 741 pdata->release_resources();
742fail1:
743 kfree(chip);
862 return ret; 744 return ret;
863} 745}
864 746
865static int lp5521_remove(struct i2c_client *client) 747static int __devexit lp5521_remove(struct i2c_client *client)
866{ 748{
867 struct lp5521_chip *chip = i2c_get_clientdata(client); 749 struct lp5521_chip *chip = i2c_get_clientdata(client);
868 int i; 750 int i;
869 751
870 lp5521_run_led_pattern(PATTERN_OFF, chip);
871 lp5521_unregister_sysfs(client); 752 lp5521_unregister_sysfs(client);
872 753
873 for (i = 0; i < chip->num_leds; i++) { 754 for (i = 0; i < chip->num_leds; i++) {
@@ -879,6 +760,7 @@ static int lp5521_remove(struct i2c_client *client)
879 chip->pdata->enable(0); 760 chip->pdata->enable(0);
880 if (chip->pdata->release_resources) 761 if (chip->pdata->release_resources)
881 chip->pdata->release_resources(); 762 chip->pdata->release_resources();
763 kfree(chip);
882 return 0; 764 return 0;
883} 765}
884 766
@@ -893,11 +775,29 @@ static struct i2c_driver lp5521_driver = {
893 .name = "lp5521", 775 .name = "lp5521",
894 }, 776 },
895 .probe = lp5521_probe, 777 .probe = lp5521_probe,
896 .remove = lp5521_remove, 778 .remove = __devexit_p(lp5521_remove),
897 .id_table = lp5521_id, 779 .id_table = lp5521_id,
898}; 780};
899 781
900module_i2c_driver(lp5521_driver); 782static int __init lp5521_init(void)
783{
784 int ret;
785
786 ret = i2c_add_driver(&lp5521_driver);
787
788 if (ret < 0)
789 printk(KERN_ALERT "Adding lp5521 driver failed\n");
790
791 return ret;
792}
793
794static void __exit lp5521_exit(void)
795{
796 i2c_del_driver(&lp5521_driver);
797}
798
799module_init(lp5521_init);
800module_exit(lp5521_exit);
901 801
902MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); 802MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
903MODULE_DESCRIPTION("LP5521 LED engine"); 803MODULE_DESCRIPTION("LP5521 LED engine");
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 7f5be8948cd..5971e309b23 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -104,11 +104,6 @@
104#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) 104#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led)))
105#define SHIFT_MASK(id) (((id) - 1) * 2) 105#define SHIFT_MASK(id) (((id) - 1) * 2)
106 106
107enum lp5523_chip_id {
108 LP5523,
109 LP55231,
110};
111
112struct lp5523_engine { 107struct lp5523_engine {
113 int id; 108 int id;
114 u8 mode; 109 u8 mode;
@@ -155,9 +150,9 @@ static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
155 leds[led->id]); 150 leds[led->id]);
156} 151}
157 152
158static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode); 153static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
159static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode); 154static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
160static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern); 155static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern);
161 156
162static void lp5523_led_brightness_work(struct work_struct *work); 157static void lp5523_led_brightness_work(struct work_struct *work);
163 158
@@ -171,7 +166,7 @@ static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf)
171 s32 ret = i2c_smbus_read_byte_data(client, reg); 166 s32 ret = i2c_smbus_read_byte_data(client, reg);
172 167
173 if (ret < 0) 168 if (ret < 0)
174 return ret; 169 return -EIO;
175 170
176 *buf = ret; 171 *buf = ret;
177 return 0; 172 return 0;
@@ -182,7 +177,7 @@ static int lp5523_detect(struct i2c_client *client)
182 int ret; 177 int ret;
183 u8 buf; 178 u8 buf;
184 179
185 ret = lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); 180 ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40);
186 if (ret) 181 if (ret)
187 return ret; 182 return ret;
188 ret = lp5523_read(client, LP5523_REG_ENABLE, &buf); 183 ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
@@ -201,7 +196,7 @@ static int lp5523_configure(struct i2c_client *client)
201 u8 status; 196 u8 status;
202 197
203 /* one pattern per engine setting led mux start and stop addresses */ 198 /* one pattern per engine setting led mux start and stop addresses */
204 static const u8 pattern[][LP5523_PROGRAM_LENGTH] = { 199 u8 pattern[][LP5523_PROGRAM_LENGTH] = {
205 { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, 200 { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
206 { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, 201 { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
207 { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, 202 { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
@@ -248,10 +243,7 @@ static int lp5523_configure(struct i2c_client *client)
248 243
249 /* Let the programs run for couple of ms and check the engine status */ 244 /* Let the programs run for couple of ms and check the engine status */
250 usleep_range(3000, 6000); 245 usleep_range(3000, 6000);
251 ret = lp5523_read(client, LP5523_REG_STATUS, &status); 246 lp5523_read(client, LP5523_REG_STATUS, &status);
252 if (ret < 0)
253 return ret;
254
255 status &= LP5523_ENG_STATUS_MASK; 247 status &= LP5523_ENG_STATUS_MASK;
256 248
257 if (status == LP5523_ENG_STATUS_MASK) { 249 if (status == LP5523_ENG_STATUS_MASK) {
@@ -309,7 +301,7 @@ static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux)
309 return ret; 301 return ret;
310} 302}
311 303
312static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern) 304static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern)
313{ 305{
314 struct lp5523_chip *chip = engine_to_lp5523(engine); 306 struct lp5523_chip *chip = engine_to_lp5523(engine);
315 struct i2c_client *client = chip->client; 307 struct i2c_client *client = chip->client;
@@ -346,8 +338,7 @@ static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
346{ 338{
347 int i; 339 int i;
348 u16 tmp_mux = 0; 340 u16 tmp_mux = 0;
349 341 len = len < LP5523_LEDS ? len : LP5523_LEDS;
350 len = min_t(int, len, LP5523_LEDS);
351 for (i = 0; i < len; i++) { 342 for (i = 0; i < len; i++) {
352 switch (buf[i]) { 343 switch (buf[i]) {
353 case '1': 344 case '1':
@@ -467,16 +458,10 @@ static ssize_t lp5523_selftest(struct device *dev,
467 LP5523_EN_LEDTEST | 16); 458 LP5523_EN_LEDTEST | 16);
468 usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */ 459 usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
469 ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); 460 ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
470 if (ret < 0)
471 goto fail;
472
473 if (!(status & LP5523_LEDTEST_DONE)) 461 if (!(status & LP5523_LEDTEST_DONE))
474 usleep_range(3000, 6000); /* Was not ready. Wait little bit */ 462 usleep_range(3000, 6000); /* Was not ready. Wait little bit */
475 463
476 ret = lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); 464 ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
477 if (ret < 0)
478 goto fail;
479
480 vdd--; /* There may be some fluctuation in measurement */ 465 vdd--; /* There may be some fluctuation in measurement */
481 466
482 for (i = 0; i < LP5523_LEDS; i++) { 467 for (i = 0; i < LP5523_LEDS; i++) {
@@ -498,14 +483,9 @@ static ssize_t lp5523_selftest(struct device *dev,
498 /* ADC conversion time is 2.7 ms typically */ 483 /* ADC conversion time is 2.7 ms typically */
499 usleep_range(3000, 6000); 484 usleep_range(3000, 6000);
500 ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); 485 ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
501 if (ret < 0)
502 goto fail;
503
504 if (!(status & LP5523_LEDTEST_DONE)) 486 if (!(status & LP5523_LEDTEST_DONE))
505 usleep_range(3000, 6000);/* Was not ready. Wait. */ 487 usleep_range(3000, 6000);/* Was not ready. Wait. */
506 ret = lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); 488 ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
507 if (ret < 0)
508 goto fail;
509 489
510 if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) 490 if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
511 pos += sprintf(buf + pos, "LED %d FAIL\n", i); 491 pos += sprintf(buf + pos, "LED %d FAIL\n", i);
@@ -566,9 +546,6 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
566 unsigned cmd; 546 unsigned cmd;
567 u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; 547 u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
568 548
569 if (engine->mode != LP5523_CMD_LOAD)
570 return -EINVAL;
571
572 while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) { 549 while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
573 /* separate sscanfs because length is working only for %s */ 550 /* separate sscanfs because length is working only for %s */
574 ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); 551 ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
@@ -586,7 +563,12 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
586 goto fail; 563 goto fail;
587 564
588 mutex_lock(&chip->lock); 565 mutex_lock(&chip->lock);
589 ret = lp5523_load_program(engine, pattern); 566
567 if (engine->mode == LP5523_CMD_LOAD)
568 ret = lp5523_load_program(engine, pattern);
569 else
570 ret = -EINVAL;
571
590 mutex_unlock(&chip->lock); 572 mutex_unlock(&chip->lock);
591 573
592 if (ret) { 574 if (ret) {
@@ -710,7 +692,7 @@ static ssize_t store_current(struct device *dev,
710 ssize_t ret; 692 ssize_t ret;
711 unsigned long curr; 693 unsigned long curr;
712 694
713 if (kstrtoul(buf, 0, &curr)) 695 if (strict_strtoul(buf, 0, &curr))
714 return -EINVAL; 696 return -EINVAL;
715 697
716 if (curr > led->max_current) 698 if (curr > led->max_current)
@@ -773,7 +755,6 @@ static struct attribute *lp5523_attributes[] = {
773 &dev_attr_engine2_leds.attr, 755 &dev_attr_engine2_leds.attr,
774 &dev_attr_engine3_load.attr, 756 &dev_attr_engine3_load.attr,
775 &dev_attr_engine3_leds.attr, 757 &dev_attr_engine3_leds.attr,
776 NULL,
777}; 758};
778 759
779static const struct attribute_group lp5523_group = { 760static const struct attribute_group lp5523_group = {
@@ -808,28 +789,26 @@ static void lp5523_unregister_sysfs(struct i2c_client *client)
808/*--------------------------------------------------------------*/ 789/*--------------------------------------------------------------*/
809/* Set chip operating mode */ 790/* Set chip operating mode */
810/*--------------------------------------------------------------*/ 791/*--------------------------------------------------------------*/
811static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode) 792static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
812{ 793{
794 int ret = 0;
795
813 /* if in that mode already do nothing, except for run */ 796 /* if in that mode already do nothing, except for run */
814 if (mode == engine->mode && mode != LP5523_CMD_RUN) 797 if (mode == engine->mode && mode != LP5523_CMD_RUN)
815 return; 798 return 0;
816 799
817 switch (mode) { 800 if (mode == LP5523_CMD_RUN) {
818 case LP5523_CMD_RUN: 801 ret = lp5523_run_program(engine);
819 lp5523_run_program(engine); 802 } else if (mode == LP5523_CMD_LOAD) {
820 break;
821 case LP5523_CMD_LOAD:
822 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); 803 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
823 lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); 804 lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
824 break; 805 } else if (mode == LP5523_CMD_DISABLED) {
825 case LP5523_CMD_DISABLED:
826 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); 806 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
827 break;
828 default:
829 return;
830 } 807 }
831 808
832 engine->mode = mode; 809 engine->mode = mode;
810
811 return ret;
833} 812}
834 813
835/*--------------------------------------------------------------*/ 814/*--------------------------------------------------------------*/
@@ -847,9 +826,8 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
847 return 0; 826 return 0;
848} 827}
849 828
850static int lp5523_init_led(struct lp5523_led *led, struct device *dev, 829static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
851 int chan, struct lp5523_platform_data *pdata, 830 int chan, struct lp5523_platform_data *pdata)
852 const char *chip_name)
853{ 831{
854 char name[32]; 832 char name[32];
855 int res; 833 int res;
@@ -868,14 +846,10 @@ static int lp5523_init_led(struct lp5523_led *led, struct device *dev,
868 return -EINVAL; 846 return -EINVAL;
869 } 847 }
870 848
871 if (pdata->led_config[chan].name) { 849 snprintf(name, sizeof(name), "%s:channel%d",
872 led->cdev.name = pdata->led_config[chan].name; 850 pdata->label ?: "lp5523", chan);
873 } else {
874 snprintf(name, sizeof(name), "%s:channel%d",
875 pdata->label ? : chip_name, chan);
876 led->cdev.name = name;
877 }
878 851
852 led->cdev.name = name;
879 led->cdev.brightness_set = lp5523_set_brightness; 853 led->cdev.brightness_set = lp5523_set_brightness;
880 res = led_classdev_register(dev, &led->cdev); 854 res = led_classdev_register(dev, &led->cdev);
881 if (res < 0) { 855 if (res < 0) {
@@ -896,14 +870,16 @@ static int lp5523_init_led(struct lp5523_led *led, struct device *dev,
896 return 0; 870 return 0;
897} 871}
898 872
899static int lp5523_probe(struct i2c_client *client, 873static struct i2c_driver lp5523_driver;
874
875static int __devinit lp5523_probe(struct i2c_client *client,
900 const struct i2c_device_id *id) 876 const struct i2c_device_id *id)
901{ 877{
902 struct lp5523_chip *chip; 878 struct lp5523_chip *chip;
903 struct lp5523_platform_data *pdata; 879 struct lp5523_platform_data *pdata;
904 int ret, i, led; 880 int ret, i, led;
905 881
906 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 882 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
907 if (!chip) 883 if (!chip)
908 return -ENOMEM; 884 return -ENOMEM;
909 885
@@ -914,7 +890,8 @@ static int lp5523_probe(struct i2c_client *client,
914 890
915 if (!pdata) { 891 if (!pdata) {
916 dev_err(&client->dev, "no platform data\n"); 892 dev_err(&client->dev, "no platform data\n");
917 return -EINVAL; 893 ret = -EINVAL;
894 goto fail1;
918 } 895 }
919 896
920 mutex_init(&chip->lock); 897 mutex_init(&chip->lock);
@@ -924,7 +901,7 @@ static int lp5523_probe(struct i2c_client *client,
924 if (pdata->setup_resources) { 901 if (pdata->setup_resources) {
925 ret = pdata->setup_resources(); 902 ret = pdata->setup_resources();
926 if (ret < 0) 903 if (ret < 0)
927 return ret; 904 goto fail1;
928 } 905 }
929 906
930 if (pdata->enable) { 907 if (pdata->enable) {
@@ -941,22 +918,22 @@ static int lp5523_probe(struct i2c_client *client,
941 */ 918 */
942 ret = lp5523_detect(client); 919 ret = lp5523_detect(client);
943 if (ret) 920 if (ret)
944 goto fail1; 921 goto fail2;
945 922
946 dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 923 dev_info(&client->dev, "LP5523 Programmable led chip found\n");
947 924
948 /* Initialize engines */ 925 /* Initialize engines */
949 for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { 926 for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
950 ret = lp5523_init_engine(&chip->engines[i], i + 1); 927 ret = lp5523_init_engine(&chip->engines[i], i + 1);
951 if (ret) { 928 if (ret) {
952 dev_err(&client->dev, "error initializing engine\n"); 929 dev_err(&client->dev, "error initializing engine\n");
953 goto fail1; 930 goto fail2;
954 } 931 }
955 } 932 }
956 ret = lp5523_configure(client); 933 ret = lp5523_configure(client);
957 if (ret < 0) { 934 if (ret < 0) {
958 dev_err(&client->dev, "error configuring chip\n"); 935 dev_err(&client->dev, "error configuring chip\n");
959 goto fail1; 936 goto fail2;
960 } 937 }
961 938
962 /* Initialize leds */ 939 /* Initialize leds */
@@ -968,14 +945,10 @@ static int lp5523_probe(struct i2c_client *client,
968 if (pdata->led_config[i].led_current == 0) 945 if (pdata->led_config[i].led_current == 0)
969 continue; 946 continue;
970 947
971 INIT_WORK(&chip->leds[led].brightness_work, 948 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
972 lp5523_led_brightness_work);
973
974 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata,
975 id->name);
976 if (ret) { 949 if (ret) {
977 dev_err(&client->dev, "error initializing leds\n"); 950 dev_err(&client->dev, "error initializing leds\n");
978 goto fail2; 951 goto fail3;
979 } 952 }
980 chip->num_leds++; 953 chip->num_leds++;
981 954
@@ -985,25 +958,30 @@ static int lp5523_probe(struct i2c_client *client,
985 LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, 958 LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
986 chip->leds[led].led_current); 959 chip->leds[led].led_current);
987 960
961 INIT_WORK(&(chip->leds[led].brightness_work),
962 lp5523_led_brightness_work);
963
988 led++; 964 led++;
989 } 965 }
990 966
991 ret = lp5523_register_sysfs(client); 967 ret = lp5523_register_sysfs(client);
992 if (ret) { 968 if (ret) {
993 dev_err(&client->dev, "registering sysfs failed\n"); 969 dev_err(&client->dev, "registering sysfs failed\n");
994 goto fail2; 970 goto fail3;
995 } 971 }
996 return ret; 972 return ret;
997fail2: 973fail3:
998 for (i = 0; i < chip->num_leds; i++) { 974 for (i = 0; i < chip->num_leds; i++) {
999 led_classdev_unregister(&chip->leds[i].cdev); 975 led_classdev_unregister(&chip->leds[i].cdev);
1000 flush_work(&chip->leds[i].brightness_work); 976 cancel_work_sync(&chip->leds[i].brightness_work);
1001 } 977 }
1002fail1: 978fail2:
1003 if (pdata->enable) 979 if (pdata->enable)
1004 pdata->enable(0); 980 pdata->enable(0);
1005 if (pdata->release_resources) 981 if (pdata->release_resources)
1006 pdata->release_resources(); 982 pdata->release_resources();
983fail1:
984 kfree(chip);
1007 return ret; 985 return ret;
1008} 986}
1009 987
@@ -1012,26 +990,23 @@ static int lp5523_remove(struct i2c_client *client)
1012 struct lp5523_chip *chip = i2c_get_clientdata(client); 990 struct lp5523_chip *chip = i2c_get_clientdata(client);
1013 int i; 991 int i;
1014 992
1015 /* Disable engine mode */
1016 lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
1017
1018 lp5523_unregister_sysfs(client); 993 lp5523_unregister_sysfs(client);
1019 994
1020 for (i = 0; i < chip->num_leds; i++) { 995 for (i = 0; i < chip->num_leds; i++) {
1021 led_classdev_unregister(&chip->leds[i].cdev); 996 led_classdev_unregister(&chip->leds[i].cdev);
1022 flush_work(&chip->leds[i].brightness_work); 997 cancel_work_sync(&chip->leds[i].brightness_work);
1023 } 998 }
1024 999
1025 if (chip->pdata->enable) 1000 if (chip->pdata->enable)
1026 chip->pdata->enable(0); 1001 chip->pdata->enable(0);
1027 if (chip->pdata->release_resources) 1002 if (chip->pdata->release_resources)
1028 chip->pdata->release_resources(); 1003 chip->pdata->release_resources();
1004 kfree(chip);
1029 return 0; 1005 return 0;
1030} 1006}
1031 1007
1032static const struct i2c_device_id lp5523_id[] = { 1008static const struct i2c_device_id lp5523_id[] = {
1033 { "lp5523", LP5523 }, 1009 { "lp5523", 0 },
1034 { "lp55231", LP55231 },
1035 { } 1010 { }
1036}; 1011};
1037 1012
@@ -1039,14 +1014,32 @@ MODULE_DEVICE_TABLE(i2c, lp5523_id);
1039 1014
1040static struct i2c_driver lp5523_driver = { 1015static struct i2c_driver lp5523_driver = {
1041 .driver = { 1016 .driver = {
1042 .name = "lp5523x", 1017 .name = "lp5523",
1043 }, 1018 },
1044 .probe = lp5523_probe, 1019 .probe = lp5523_probe,
1045 .remove = lp5523_remove, 1020 .remove = lp5523_remove,
1046 .id_table = lp5523_id, 1021 .id_table = lp5523_id,
1047}; 1022};
1048 1023
1049module_i2c_driver(lp5523_driver); 1024static int __init lp5523_init(void)
1025{
1026 int ret;
1027
1028 ret = i2c_add_driver(&lp5523_driver);
1029
1030 if (ret < 0)
1031 printk(KERN_ALERT "Adding lp5523 driver failed\n");
1032
1033 return ret;
1034}
1035
1036static void __exit lp5523_exit(void)
1037{
1038 i2c_del_driver(&lp5523_driver);
1039}
1040
1041module_init(lp5523_init);
1042module_exit(lp5523_exit);
1050 1043
1051MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>"); 1044MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
1052MODULE_DESCRIPTION("LP5523 LED engine"); 1045MODULE_DESCRIPTION("LP5523 LED engine");
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c
deleted file mode 100644
index 4353942c5fd..00000000000
--- a/drivers/leds/leds-lp8788.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/*
2 * TI LP8788 MFD - keyled driver
3 *
4 * Copyright 2012 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
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <linux/mutex.h>
20#include <linux/mfd/lp8788.h>
21#include <linux/mfd/lp8788-isink.h>
22
23#define MAX_BRIGHTNESS LP8788_ISINK_MAX_PWM
24#define DEFAULT_LED_NAME "keyboard-backlight"
25
26struct lp8788_led {
27 struct lp8788 *lp;
28 struct mutex lock;
29 struct work_struct work;
30 struct led_classdev led_dev;
31 enum lp8788_isink_number isink_num;
32 enum led_brightness brightness;
33 int on;
34};
35
36struct lp8788_led_config {
37 enum lp8788_isink_scale scale;
38 enum lp8788_isink_number num;
39 int iout;
40};
41
42static struct lp8788_led_config default_led_config = {
43 .scale = LP8788_ISINK_SCALE_100mA,
44 .num = LP8788_ISINK_3,
45 .iout = 0,
46};
47
48static int lp8788_led_init_device(struct lp8788_led *led,
49 struct lp8788_led_platform_data *pdata)
50{
51 struct lp8788_led_config *cfg = &default_led_config;
52 u8 addr, mask, val;
53 int ret;
54
55 if (pdata) {
56 cfg->scale = pdata->scale;
57 cfg->num = pdata->num;
58 cfg->iout = pdata->iout_code;
59 }
60
61 led->isink_num = cfg->num;
62
63 /* scale configuration */
64 addr = LP8788_ISINK_CTRL;
65 mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
66 val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
67 ret = lp8788_update_bits(led->lp, addr, mask, val);
68 if (ret)
69 return ret;
70
71 /* current configuration */
72 addr = lp8788_iout_addr[cfg->num];
73 mask = lp8788_iout_mask[cfg->num];
74 val = cfg->iout;
75
76 return lp8788_update_bits(led->lp, addr, mask, val);
77}
78
79static void lp8788_led_enable(struct lp8788_led *led,
80 enum lp8788_isink_number num, int on)
81{
82 u8 mask = 1 << num;
83 u8 val = on << num;
84
85 if (lp8788_update_bits(led->lp, LP8788_ISINK_CTRL, mask, val))
86 return;
87
88 led->on = on;
89}
90
91static void lp8788_led_work(struct work_struct *work)
92{
93 struct lp8788_led *led = container_of(work, struct lp8788_led, work);
94 enum lp8788_isink_number num = led->isink_num;
95 int enable;
96 u8 val = led->brightness;
97
98 mutex_lock(&led->lock);
99
100 switch (num) {
101 case LP8788_ISINK_1:
102 case LP8788_ISINK_2:
103 case LP8788_ISINK_3:
104 lp8788_write_byte(led->lp, lp8788_pwm_addr[num], val);
105 break;
106 default:
107 mutex_unlock(&led->lock);
108 return;
109 }
110
111 enable = (val > 0) ? 1 : 0;
112 if (enable != led->on)
113 lp8788_led_enable(led, num, enable);
114
115 mutex_unlock(&led->lock);
116}
117
118static void lp8788_brightness_set(struct led_classdev *led_cdev,
119 enum led_brightness brt_val)
120{
121 struct lp8788_led *led =
122 container_of(led_cdev, struct lp8788_led, led_dev);
123
124 led->brightness = brt_val;
125 schedule_work(&led->work);
126}
127
128static int lp8788_led_probe(struct platform_device *pdev)
129{
130 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
131 struct lp8788_led_platform_data *led_pdata;
132 struct lp8788_led *led;
133 int ret;
134
135 led = devm_kzalloc(lp->dev, sizeof(struct lp8788_led), GFP_KERNEL);
136 if (!led)
137 return -ENOMEM;
138
139 led->lp = lp;
140 led->led_dev.max_brightness = MAX_BRIGHTNESS;
141 led->led_dev.brightness_set = lp8788_brightness_set;
142
143 led_pdata = lp->pdata ? lp->pdata->led_pdata : NULL;
144
145 if (!led_pdata || !led_pdata->name)
146 led->led_dev.name = DEFAULT_LED_NAME;
147 else
148 led->led_dev.name = led_pdata->name;
149
150 mutex_init(&led->lock);
151 INIT_WORK(&led->work, lp8788_led_work);
152
153 platform_set_drvdata(pdev, led);
154
155 ret = lp8788_led_init_device(led, led_pdata);
156 if (ret) {
157 dev_err(lp->dev, "led init device err: %d\n", ret);
158 return ret;
159 }
160
161 ret = led_classdev_register(lp->dev, &led->led_dev);
162 if (ret) {
163 dev_err(lp->dev, "led register err: %d\n", ret);
164 return ret;
165 }
166
167 return 0;
168}
169
170static int lp8788_led_remove(struct platform_device *pdev)
171{
172 struct lp8788_led *led = platform_get_drvdata(pdev);
173
174 led_classdev_unregister(&led->led_dev);
175 flush_work(&led->work);
176
177 return 0;
178}
179
180static struct platform_driver lp8788_led_driver = {
181 .probe = lp8788_led_probe,
182 .remove = lp8788_led_remove,
183 .driver = {
184 .name = LP8788_DEV_KEYLED,
185 .owner = THIS_MODULE,
186 },
187};
188module_platform_driver(lp8788_led_driver);
189
190MODULE_DESCRIPTION("Texas Instruments LP8788 Keyboard LED Driver");
191MODULE_AUTHOR("Milo Kim");
192MODULE_LICENSE("GPL");
193MODULE_ALIAS("platform:lp8788-keyled");
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index c9b9e1fec58..2579678f97a 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -24,7 +24,6 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/module.h>
28 27
29struct lt3593_led_data { 28struct lt3593_led_data {
30 struct led_classdev cdev; 29 struct led_classdev cdev;
@@ -82,18 +81,22 @@ static void lt3593_led_set(struct led_classdev *led_cdev,
82 schedule_work(&led_dat->work); 81 schedule_work(&led_dat->work);
83} 82}
84 83
85static int create_lt3593_led(const struct gpio_led *template, 84static int __devinit create_lt3593_led(const struct gpio_led *template,
86 struct lt3593_led_data *led_dat, struct device *parent) 85 struct lt3593_led_data *led_dat, struct device *parent)
87{ 86{
88 int ret, state; 87 int ret, state;
89 88
90 /* skip leds on GPIOs that aren't available */ 89 /* skip leds on GPIOs that aren't available */
91 if (!gpio_is_valid(template->gpio)) { 90 if (!gpio_is_valid(template->gpio)) {
92 dev_info(parent, "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n", 91 printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n",
93 KBUILD_MODNAME, template->gpio, template->name); 92 KBUILD_MODNAME, template->gpio, template->name);
94 return 0; 93 return 0;
95 } 94 }
96 95
96 ret = gpio_request(template->gpio, template->name);
97 if (ret < 0)
98 return ret;
99
97 led_dat->cdev.name = template->name; 100 led_dat->cdev.name = template->name;
98 led_dat->cdev.default_trigger = template->default_trigger; 101 led_dat->cdev.default_trigger = template->default_trigger;
99 led_dat->gpio = template->gpio; 102 led_dat->gpio = template->gpio;
@@ -106,21 +109,24 @@ static int create_lt3593_led(const struct gpio_led *template,
106 if (!template->retain_state_suspended) 109 if (!template->retain_state_suspended)
107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 110 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
108 111
109 ret = devm_gpio_request_one(parent, template->gpio, 112 ret = gpio_direction_output(led_dat->gpio, state);
110 GPIOF_DIR_OUT | state, template->name);
111 if (ret < 0) 113 if (ret < 0)
112 return ret; 114 goto err;
113 115
114 INIT_WORK(&led_dat->work, lt3593_led_work); 116 INIT_WORK(&led_dat->work, lt3593_led_work);
115 117
116 ret = led_classdev_register(parent, &led_dat->cdev); 118 ret = led_classdev_register(parent, &led_dat->cdev);
117 if (ret < 0) 119 if (ret < 0)
118 return ret; 120 goto err;
119 121
120 dev_info(parent, "%s: registered LT3593 LED '%s' at GPIO %d\n", 122 printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n",
121 KBUILD_MODNAME, template->name, template->gpio); 123 KBUILD_MODNAME, template->name, template->gpio);
122 124
123 return 0; 125 return 0;
126
127err:
128 gpio_free(led_dat->gpio);
129 return ret;
124} 130}
125 131
126static void delete_lt3593_led(struct lt3593_led_data *led) 132static void delete_lt3593_led(struct lt3593_led_data *led)
@@ -130,9 +136,10 @@ static void delete_lt3593_led(struct lt3593_led_data *led)
130 136
131 led_classdev_unregister(&led->cdev); 137 led_classdev_unregister(&led->cdev);
132 cancel_work_sync(&led->work); 138 cancel_work_sync(&led->work);
139 gpio_free(led->gpio);
133} 140}
134 141
135static int lt3593_led_probe(struct platform_device *pdev) 142static int __devinit lt3593_led_probe(struct platform_device *pdev)
136{ 143{
137 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 144 struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
138 struct lt3593_led_data *leds_data; 145 struct lt3593_led_data *leds_data;
@@ -141,9 +148,8 @@ static int lt3593_led_probe(struct platform_device *pdev)
141 if (!pdata) 148 if (!pdata)
142 return -EBUSY; 149 return -EBUSY;
143 150
144 leds_data = devm_kzalloc(&pdev->dev, 151 leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds,
145 sizeof(struct lt3593_led_data) * pdata->num_leds, 152 GFP_KERNEL);
146 GFP_KERNEL);
147 if (!leds_data) 153 if (!leds_data)
148 return -ENOMEM; 154 return -ENOMEM;
149 155
@@ -162,10 +168,12 @@ err:
162 for (i = i - 1; i >= 0; i--) 168 for (i = i - 1; i >= 0; i--)
163 delete_lt3593_led(&leds_data[i]); 169 delete_lt3593_led(&leds_data[i]);
164 170
171 kfree(leds_data);
172
165 return ret; 173 return ret;
166} 174}
167 175
168static int lt3593_led_remove(struct platform_device *pdev) 176static int __devexit lt3593_led_remove(struct platform_device *pdev)
169{ 177{
170 int i; 178 int i;
171 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 179 struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
@@ -176,21 +184,35 @@ static int lt3593_led_remove(struct platform_device *pdev)
176 for (i = 0; i < pdata->num_leds; i++) 184 for (i = 0; i < pdata->num_leds; i++)
177 delete_lt3593_led(&leds_data[i]); 185 delete_lt3593_led(&leds_data[i]);
178 186
187 kfree(leds_data);
188
179 return 0; 189 return 0;
180} 190}
181 191
182static struct platform_driver lt3593_led_driver = { 192static struct platform_driver lt3593_led_driver = {
183 .probe = lt3593_led_probe, 193 .probe = lt3593_led_probe,
184 .remove = lt3593_led_remove, 194 .remove = __devexit_p(lt3593_led_remove),
185 .driver = { 195 .driver = {
186 .name = "leds-lt3593", 196 .name = "leds-lt3593",
187 .owner = THIS_MODULE, 197 .owner = THIS_MODULE,
188 }, 198 },
189}; 199};
190 200
191module_platform_driver(lt3593_led_driver); 201MODULE_ALIAS("platform:leds-lt3593");
202
203static int __init lt3593_led_init(void)
204{
205 return platform_driver_register(&lt3593_led_driver);
206}
207
208static void __exit lt3593_led_exit(void)
209{
210 platform_driver_unregister(&lt3593_led_driver);
211}
212
213module_init(lt3593_led_init);
214module_exit(lt3593_led_exit);
192 215
193MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 216MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
194MODULE_DESCRIPTION("LED driver for LT3593 controllers"); 217MODULE_DESCRIPTION("LED driver for LT3593 controllers");
195MODULE_LICENSE("GPL"); 218MODULE_LICENSE("GPL");
196MODULE_ALIAS("platform:leds-lt3593");
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
deleted file mode 100644
index f449a8bdddc..00000000000
--- a/drivers/leds/leds-max8997.c
+++ /dev/null
@@ -1,319 +0,0 @@
1/*
2 * leds-max8997.c - LED class driver for MAX8997 LEDs.
3 *
4 * Copyright (C) 2011 Samsung Electronics
5 * Donggeun Kim <dg77.kim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/err.h>
15#include <linux/slab.h>
16#include <linux/workqueue.h>
17#include <linux/leds.h>
18#include <linux/mfd/max8997.h>
19#include <linux/mfd/max8997-private.h>
20#include <linux/platform_device.h>
21
22#define MAX8997_LED_FLASH_SHIFT 3
23#define MAX8997_LED_FLASH_CUR_MASK 0xf8
24#define MAX8997_LED_MOVIE_SHIFT 4
25#define MAX8997_LED_MOVIE_CUR_MASK 0xf0
26
27#define MAX8997_LED_FLASH_MAX_BRIGHTNESS 0x1f
28#define MAX8997_LED_MOVIE_MAX_BRIGHTNESS 0xf
29#define MAX8997_LED_NONE_MAX_BRIGHTNESS 0
30
31#define MAX8997_LED0_FLASH_MASK 0x1
32#define MAX8997_LED0_FLASH_PIN_MASK 0x5
33#define MAX8997_LED0_MOVIE_MASK 0x8
34#define MAX8997_LED0_MOVIE_PIN_MASK 0x28
35
36#define MAX8997_LED1_FLASH_MASK 0x2
37#define MAX8997_LED1_FLASH_PIN_MASK 0x6
38#define MAX8997_LED1_MOVIE_MASK 0x10
39#define MAX8997_LED1_MOVIE_PIN_MASK 0x30
40
41#define MAX8997_LED_BOOST_ENABLE_MASK (1 << 6)
42
43struct max8997_led {
44 struct max8997_dev *iodev;
45 struct led_classdev cdev;
46 bool enabled;
47 int id;
48 enum max8997_led_mode led_mode;
49 struct mutex mutex;
50};
51
52static void max8997_led_set_mode(struct max8997_led *led,
53 enum max8997_led_mode mode)
54{
55 int ret;
56 struct i2c_client *client = led->iodev->i2c;
57 u8 mask = 0, val;
58
59 switch (mode) {
60 case MAX8997_FLASH_MODE:
61 mask = MAX8997_LED1_FLASH_MASK | MAX8997_LED0_FLASH_MASK;
62 val = led->id ?
63 MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
64 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
65 break;
66 case MAX8997_MOVIE_MODE:
67 mask = MAX8997_LED1_MOVIE_MASK | MAX8997_LED0_MOVIE_MASK;
68 val = led->id ?
69 MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
70 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
71 break;
72 case MAX8997_FLASH_PIN_CONTROL_MODE:
73 mask = MAX8997_LED1_FLASH_PIN_MASK |
74 MAX8997_LED0_FLASH_PIN_MASK;
75 val = led->id ?
76 MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
77 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
78 break;
79 case MAX8997_MOVIE_PIN_CONTROL_MODE:
80 mask = MAX8997_LED1_MOVIE_PIN_MASK |
81 MAX8997_LED0_MOVIE_PIN_MASK;
82 val = led->id ?
83 MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
84 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
85 break;
86 default:
87 led->cdev.max_brightness = MAX8997_LED_NONE_MAX_BRIGHTNESS;
88 break;
89 }
90
91 if (mask) {
92 ret = max8997_update_reg(client, MAX8997_REG_LEN_CNTL, val,
93 mask);
94 if (ret)
95 dev_err(led->iodev->dev,
96 "failed to update register(%d)\n", ret);
97 }
98
99 led->led_mode = mode;
100}
101
102static void max8997_led_enable(struct max8997_led *led, bool enable)
103{
104 int ret;
105 struct i2c_client *client = led->iodev->i2c;
106 u8 val = 0, mask = MAX8997_LED_BOOST_ENABLE_MASK;
107
108 if (led->enabled == enable)
109 return;
110
111 val = enable ? MAX8997_LED_BOOST_ENABLE_MASK : 0;
112
113 ret = max8997_update_reg(client, MAX8997_REG_BOOST_CNTL, val, mask);
114 if (ret)
115 dev_err(led->iodev->dev,
116 "failed to update register(%d)\n", ret);
117
118 led->enabled = enable;
119}
120
121static void max8997_led_set_current(struct max8997_led *led,
122 enum led_brightness value)
123{
124 int ret;
125 struct i2c_client *client = led->iodev->i2c;
126 u8 val = 0, mask = 0, reg = 0;
127
128 switch (led->led_mode) {
129 case MAX8997_FLASH_MODE:
130 case MAX8997_FLASH_PIN_CONTROL_MODE:
131 val = value << MAX8997_LED_FLASH_SHIFT;
132 mask = MAX8997_LED_FLASH_CUR_MASK;
133 reg = led->id ? MAX8997_REG_FLASH2_CUR : MAX8997_REG_FLASH1_CUR;
134 break;
135 case MAX8997_MOVIE_MODE:
136 case MAX8997_MOVIE_PIN_CONTROL_MODE:
137 val = value << MAX8997_LED_MOVIE_SHIFT;
138 mask = MAX8997_LED_MOVIE_CUR_MASK;
139 reg = MAX8997_REG_MOVIE_CUR;
140 break;
141 default:
142 break;
143 }
144
145 if (mask) {
146 ret = max8997_update_reg(client, reg, val, mask);
147 if (ret)
148 dev_err(led->iodev->dev,
149 "failed to update register(%d)\n", ret);
150 }
151}
152
153static void max8997_led_brightness_set(struct led_classdev *led_cdev,
154 enum led_brightness value)
155{
156 struct max8997_led *led =
157 container_of(led_cdev, struct max8997_led, cdev);
158
159 if (value) {
160 max8997_led_set_current(led, value);
161 max8997_led_enable(led, true);
162 } else {
163 max8997_led_set_current(led, value);
164 max8997_led_enable(led, false);
165 }
166}
167
168static ssize_t max8997_led_show_mode(struct device *dev,
169 struct device_attribute *attr, char *buf)
170{
171 struct led_classdev *led_cdev = dev_get_drvdata(dev);
172 struct max8997_led *led =
173 container_of(led_cdev, struct max8997_led, cdev);
174 ssize_t ret = 0;
175
176 mutex_lock(&led->mutex);
177
178 switch (led->led_mode) {
179 case MAX8997_FLASH_MODE:
180 ret += sprintf(buf, "FLASH\n");
181 break;
182 case MAX8997_MOVIE_MODE:
183 ret += sprintf(buf, "MOVIE\n");
184 break;
185 case MAX8997_FLASH_PIN_CONTROL_MODE:
186 ret += sprintf(buf, "FLASH_PIN_CONTROL\n");
187 break;
188 case MAX8997_MOVIE_PIN_CONTROL_MODE:
189 ret += sprintf(buf, "MOVIE_PIN_CONTROL\n");
190 break;
191 default:
192 ret += sprintf(buf, "NONE\n");
193 break;
194 }
195
196 mutex_unlock(&led->mutex);
197
198 return ret;
199}
200
201static ssize_t max8997_led_store_mode(struct device *dev,
202 struct device_attribute *attr,
203 const char *buf, size_t size)
204{
205 struct led_classdev *led_cdev = dev_get_drvdata(dev);
206 struct max8997_led *led =
207 container_of(led_cdev, struct max8997_led, cdev);
208 enum max8997_led_mode mode;
209
210 mutex_lock(&led->mutex);
211
212 if (!strncmp(buf, "FLASH_PIN_CONTROL", 17))
213 mode = MAX8997_FLASH_PIN_CONTROL_MODE;
214 else if (!strncmp(buf, "MOVIE_PIN_CONTROL", 17))
215 mode = MAX8997_MOVIE_PIN_CONTROL_MODE;
216 else if (!strncmp(buf, "FLASH", 5))
217 mode = MAX8997_FLASH_MODE;
218 else if (!strncmp(buf, "MOVIE", 5))
219 mode = MAX8997_MOVIE_MODE;
220 else
221 mode = MAX8997_NONE;
222
223 max8997_led_set_mode(led, mode);
224
225 mutex_unlock(&led->mutex);
226
227 return size;
228}
229
230static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode);
231
232static int max8997_led_probe(struct platform_device *pdev)
233{
234 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
235 struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
236 struct max8997_led *led;
237 char name[20];
238 int ret = 0;
239
240 if (pdata == NULL) {
241 dev_err(&pdev->dev, "no platform data\n");
242 return -ENODEV;
243 }
244
245 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
246 if (led == NULL)
247 return -ENOMEM;
248
249 led->id = pdev->id;
250 snprintf(name, sizeof(name), "max8997-led%d", pdev->id);
251
252 led->cdev.name = name;
253 led->cdev.brightness_set = max8997_led_brightness_set;
254 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
255 led->cdev.brightness = 0;
256 led->iodev = iodev;
257
258 /* initialize mode and brightness according to platform_data */
259 if (pdata->led_pdata) {
260 u8 mode = 0, brightness = 0;
261
262 mode = pdata->led_pdata->mode[led->id];
263 brightness = pdata->led_pdata->brightness[led->id];
264
265 max8997_led_set_mode(led, pdata->led_pdata->mode[led->id]);
266
267 if (brightness > led->cdev.max_brightness)
268 brightness = led->cdev.max_brightness;
269 max8997_led_set_current(led, brightness);
270 led->cdev.brightness = brightness;
271 } else {
272 max8997_led_set_mode(led, MAX8997_NONE);
273 max8997_led_set_current(led, 0);
274 }
275
276 mutex_init(&led->mutex);
277
278 platform_set_drvdata(pdev, led);
279
280 ret = led_classdev_register(&pdev->dev, &led->cdev);
281 if (ret < 0)
282 return ret;
283
284 ret = device_create_file(led->cdev.dev, &dev_attr_mode);
285 if (ret != 0) {
286 dev_err(&pdev->dev,
287 "failed to create file: %d\n", ret);
288 led_classdev_unregister(&led->cdev);
289 return ret;
290 }
291
292 return 0;
293}
294
295static int max8997_led_remove(struct platform_device *pdev)
296{
297 struct max8997_led *led = platform_get_drvdata(pdev);
298
299 device_remove_file(led->cdev.dev, &dev_attr_mode);
300 led_classdev_unregister(&led->cdev);
301
302 return 0;
303}
304
305static struct platform_driver max8997_led_driver = {
306 .driver = {
307 .name = "max8997-led",
308 .owner = THIS_MODULE,
309 },
310 .probe = max8997_led_probe,
311 .remove = max8997_led_remove,
312};
313
314module_platform_driver(max8997_led_driver);
315
316MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
317MODULE_DESCRIPTION("MAX8997 LED driver");
318MODULE_LICENSE("GPL");
319MODULE_ALIAS("platform:max8997-led");
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index e942adaa750..f369e56d654 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -21,13 +21,13 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/leds.h> 22#include <linux/leds.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/mfd/mc13xxx.h> 24#include <linux/mfd/mc13783.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26 26
27struct mc13783_led { 27struct mc13783_led {
28 struct led_classdev cdev; 28 struct led_classdev cdev;
29 struct work_struct work; 29 struct work_struct work;
30 struct mc13xxx *master; 30 struct mc13783 *master;
31 enum led_brightness new_brightness; 31 enum led_brightness new_brightness;
32 int id; 32 int id;
33}; 33};
@@ -111,11 +111,11 @@ static void mc13783_led_work(struct work_struct *work)
111 break; 111 break;
112 } 112 }
113 113
114 mc13xxx_lock(led->master); 114 mc13783_lock(led->master);
115 115
116 mc13xxx_reg_rmw(led->master, reg, mask, value); 116 mc13783_reg_rmw(led->master, reg, mask, value);
117 117
118 mc13xxx_unlock(led->master); 118 mc13783_unlock(led->master);
119} 119}
120 120
121static void mc13783_led_set(struct led_classdev *led_cdev, 121static void mc13783_led_set(struct led_classdev *led_cdev,
@@ -128,7 +128,7 @@ static void mc13783_led_set(struct led_classdev *led_cdev,
128 schedule_work(&led->work); 128 schedule_work(&led->work);
129} 129}
130 130
131static int mc13783_led_setup(struct mc13783_led *led, int max_current) 131static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
132{ 132{
133 int shift = 0; 133 int shift = 0;
134 int mask = 0; 134 int mask = 0;
@@ -172,23 +172,23 @@ static int mc13783_led_setup(struct mc13783_led *led, int max_current)
172 break; 172 break;
173 } 173 }
174 174
175 mc13xxx_lock(led->master); 175 mc13783_lock(led->master);
176 176
177 ret = mc13xxx_reg_rmw(led->master, reg, mask << shift, 177 ret = mc13783_reg_rmw(led->master, reg, mask << shift,
178 value << shift); 178 value << shift);
179 179
180 mc13xxx_unlock(led->master); 180 mc13783_unlock(led->master);
181 return ret; 181 return ret;
182} 182}
183 183
184static int mc13783_leds_prepare(struct platform_device *pdev) 184static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
185{ 185{
186 struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 186 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
187 struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent); 187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
188 int ret = 0; 188 int ret = 0;
189 int reg = 0; 189 int reg = 0;
190 190
191 mc13xxx_lock(dev); 191 mc13783_lock(dev);
192 192
193 if (pdata->flags & MC13783_LED_TC1HALF) 193 if (pdata->flags & MC13783_LED_TC1HALF)
194 reg |= MC13783_LED_C1_TC1HALF_BIT; 194 reg |= MC13783_LED_C1_TC1HALF_BIT;
@@ -196,7 +196,7 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
196 if (pdata->flags & MC13783_LED_SLEWLIMTC) 196 if (pdata->flags & MC13783_LED_SLEWLIMTC)
197 reg |= MC13783_LED_Cx_SLEWLIM_BIT; 197 reg |= MC13783_LED_Cx_SLEWLIM_BIT;
198 198
199 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg); 199 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
200 if (ret) 200 if (ret)
201 goto out; 201 goto out;
202 202
@@ -206,7 +206,7 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
206 if (pdata->flags & MC13783_LED_SLEWLIMBL) 206 if (pdata->flags & MC13783_LED_SLEWLIMBL)
207 reg |= MC13783_LED_Cx_SLEWLIM_BIT; 207 reg |= MC13783_LED_Cx_SLEWLIM_BIT;
208 208
209 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg); 209 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
210 if (ret) 210 if (ret)
211 goto out; 211 goto out;
212 212
@@ -216,7 +216,7 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
216 if (pdata->flags & MC13783_LED_TRIODE_TC1) 216 if (pdata->flags & MC13783_LED_TRIODE_TC1)
217 reg |= MC13783_LED_Cx_TRIODE_TC_BIT; 217 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
218 218
219 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg); 219 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
220 if (ret) 220 if (ret)
221 goto out; 221 goto out;
222 222
@@ -226,7 +226,7 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
226 if (pdata->flags & MC13783_LED_TRIODE_TC2) 226 if (pdata->flags & MC13783_LED_TRIODE_TC2)
227 reg |= MC13783_LED_Cx_TRIODE_TC_BIT; 227 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
228 228
229 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg); 229 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
230 if (ret) 230 if (ret)
231 goto out; 231 goto out;
232 232
@@ -236,7 +236,7 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
236 if (pdata->flags & MC13783_LED_TRIODE_TC3) 236 if (pdata->flags & MC13783_LED_TRIODE_TC3)
237 reg |= MC13783_LED_Cx_TRIODE_TC_BIT; 237 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
238 238
239 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg); 239 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
240 if (ret) 240 if (ret)
241 goto out; 241 goto out;
242 242
@@ -255,17 +255,17 @@ static int mc13783_leds_prepare(struct platform_device *pdev)
255 reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) << 255 reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
256 MC13783_LED_C0_ABREF; 256 MC13783_LED_C0_ABREF;
257 257
258 ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg); 258 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
259 259
260out: 260out:
261 mc13xxx_unlock(dev); 261 mc13783_unlock(dev);
262 return ret; 262 return ret;
263} 263}
264 264
265static int mc13783_led_probe(struct platform_device *pdev) 265static int __devinit mc13783_led_probe(struct platform_device *pdev)
266{ 266{
267 struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 267 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
268 struct mc13xxx_led_platform_data *led_cur; 268 struct mc13783_led_platform_data *led_cur;
269 struct mc13783_led *led, *led_dat; 269 struct mc13783_led *led, *led_dat;
270 int ret, i; 270 int ret, i;
271 int init_led = 0; 271 int init_led = 0;
@@ -275,13 +275,12 @@ static int mc13783_led_probe(struct platform_device *pdev)
275 return -ENODEV; 275 return -ENODEV;
276 } 276 }
277 277
278 if (pdata->num_leds < 1 || pdata->num_leds > (MC13783_LED_MAX + 1)) { 278 if (pdata->num_leds < 1 || pdata->num_leds > MC13783_LED_MAX) {
279 dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds); 279 dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds);
280 return -EINVAL; 280 return -EINVAL;
281 } 281 }
282 282
283 led = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*led), 283 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
284 GFP_KERNEL);
285 if (led == NULL) { 284 if (led == NULL) {
286 dev_err(&pdev->dev, "failed to alloc memory\n"); 285 dev_err(&pdev->dev, "failed to alloc memory\n");
287 return -ENOMEM; 286 return -ENOMEM;
@@ -290,7 +289,7 @@ static int mc13783_led_probe(struct platform_device *pdev)
290 ret = mc13783_leds_prepare(pdev); 289 ret = mc13783_leds_prepare(pdev);
291 if (ret) { 290 if (ret) {
292 dev_err(&pdev->dev, "unable to init led driver\n"); 291 dev_err(&pdev->dev, "unable to init led driver\n");
293 return ret; 292 goto err_free;
294 } 293 }
295 294
296 for (i = 0; i < pdata->num_leds; i++) { 295 for (i = 0; i < pdata->num_leds; i++) {
@@ -345,14 +344,16 @@ err_register:
345 cancel_work_sync(&led[i].work); 344 cancel_work_sync(&led[i].work);
346 } 345 }
347 346
347err_free:
348 kfree(led);
348 return ret; 349 return ret;
349} 350}
350 351
351static int mc13783_led_remove(struct platform_device *pdev) 352static int __devexit mc13783_led_remove(struct platform_device *pdev)
352{ 353{
353 struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 354 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
354 struct mc13783_led *led = platform_get_drvdata(pdev); 355 struct mc13783_led *led = platform_get_drvdata(pdev);
355 struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent); 356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
356 int i; 357 int i;
357 358
358 for (i = 0; i < pdata->num_leds; i++) { 359 for (i = 0; i < pdata->num_leds; i++) {
@@ -360,18 +361,18 @@ static int mc13783_led_remove(struct platform_device *pdev)
360 cancel_work_sync(&led[i].work); 361 cancel_work_sync(&led[i].work);
361 } 362 }
362 363
363 mc13xxx_lock(dev); 364 mc13783_lock(dev);
364 365
365 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0); 366 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
366 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0); 367 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
367 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0); 368 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
368 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0); 369 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
369 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0); 370 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
370 mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0); 371 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
371 372
372 mc13xxx_unlock(dev); 373 mc13783_unlock(dev);
373 374
374 platform_set_drvdata(pdev, NULL); 375 kfree(led);
375 return 0; 376 return 0;
376} 377}
377 378
@@ -381,10 +382,20 @@ static struct platform_driver mc13783_led_driver = {
381 .owner = THIS_MODULE, 382 .owner = THIS_MODULE,
382 }, 383 },
383 .probe = mc13783_led_probe, 384 .probe = mc13783_led_probe,
384 .remove = mc13783_led_remove, 385 .remove = __devexit_p(mc13783_led_remove),
385}; 386};
386 387
387module_platform_driver(mc13783_led_driver); 388static int __init mc13783_led_init(void)
389{
390 return platform_driver_register(&mc13783_led_driver);
391}
392module_init(mc13783_led_init);
393
394static void __exit mc13783_led_exit(void)
395{
396 platform_driver_unregister(&mc13783_led_driver);
397}
398module_exit(mc13783_led_exit);
388 399
389MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC"); 400MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC");
390MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>"); 401MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
index 27d06c52824..93987a12da4 100644
--- a/drivers/leds/leds-net48xx.c
+++ b/drivers/leds/leds-net48xx.c
@@ -15,10 +15,9 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/leds.h> 16#include <linux/leds.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/io.h> 18#include <asm/io.h>
19#include <linux/nsc_gpio.h> 19#include <linux/nsc_gpio.h>
20#include <linux/scx200_gpio.h> 20#include <linux/scx200_gpio.h>
21#include <linux/module.h>
22 21
23#define DRVNAME "net48xx-led" 22#define DRVNAME "net48xx-led"
24#define NET48XX_ERROR_LED_GPIO 20 23#define NET48XX_ERROR_LED_GPIO 20
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index c61c5ebcc08..f2e51c13439 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -28,7 +28,7 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/leds.h> 30#include <linux/leds.h>
31#include <linux/platform_data/leds-kirkwood-netxbig.h> 31#include <mach/leds-netxbig.h>
32 32
33/* 33/*
34 * GPIO extension bus. 34 * GPIO extension bus.
@@ -71,7 +71,7 @@ static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
71 spin_unlock_irqrestore(&gpio_ext_lock, flags); 71 spin_unlock_irqrestore(&gpio_ext_lock, flags);
72} 72}
73 73
74static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext) 74static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
75{ 75{
76 int err; 76 int err;
77 int i; 77 int i;
@@ -81,23 +81,35 @@ static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
81 81
82 /* Configure address GPIOs. */ 82 /* Configure address GPIOs. */
83 for (i = 0; i < gpio_ext->num_addr; i++) { 83 for (i = 0; i < gpio_ext->num_addr; i++) {
84 err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW, 84 err = gpio_request(gpio_ext->addr[i], "GPIO extension addr");
85 "GPIO extension addr");
86 if (err) 85 if (err)
87 goto err_free_addr; 86 goto err_free_addr;
87 err = gpio_direction_output(gpio_ext->addr[i], 0);
88 if (err) {
89 gpio_free(gpio_ext->addr[i]);
90 goto err_free_addr;
91 }
88 } 92 }
89 /* Configure data GPIOs. */ 93 /* Configure data GPIOs. */
90 for (i = 0; i < gpio_ext->num_data; i++) { 94 for (i = 0; i < gpio_ext->num_data; i++) {
91 err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW, 95 err = gpio_request(gpio_ext->data[i], "GPIO extension data");
92 "GPIO extension data");
93 if (err) 96 if (err)
94 goto err_free_data; 97 goto err_free_data;
98 err = gpio_direction_output(gpio_ext->data[i], 0);
99 if (err) {
100 gpio_free(gpio_ext->data[i]);
101 goto err_free_data;
102 }
95 } 103 }
96 /* Configure "enable select" GPIO. */ 104 /* Configure "enable select" GPIO. */
97 err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW, 105 err = gpio_request(gpio_ext->enable, "GPIO extension enable");
98 "GPIO extension enable");
99 if (err) 106 if (err)
100 goto err_free_data; 107 goto err_free_data;
108 err = gpio_direction_output(gpio_ext->enable, 0);
109 if (err) {
110 gpio_free(gpio_ext->enable);
111 goto err_free_data;
112 }
101 113
102 return 0; 114 return 0;
103 115
@@ -112,7 +124,7 @@ err_free_addr:
112 return err; 124 return err;
113} 125}
114 126
115static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) 127static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
116{ 128{
117 int i; 129 int i;
118 130
@@ -243,7 +255,7 @@ static ssize_t netxbig_led_sata_store(struct device *dev,
243 int mode_val; 255 int mode_val;
244 int ret; 256 int ret;
245 257
246 ret = kstrtoul(buff, 10, &enable); 258 ret = strict_strtoul(buff, 10, &enable);
247 if (ret < 0) 259 if (ret < 0)
248 return ret; 260 return ret;
249 261
@@ -294,14 +306,14 @@ static ssize_t netxbig_led_sata_show(struct device *dev,
294 306
295static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); 307static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
296 308
297static void delete_netxbig_led(struct netxbig_led_data *led_dat) 309static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat)
298{ 310{
299 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) 311 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
300 device_remove_file(led_dat->cdev.dev, &dev_attr_sata); 312 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
301 led_classdev_unregister(&led_dat->cdev); 313 led_classdev_unregister(&led_dat->cdev);
302} 314}
303 315
304static int 316static int __devinit
305create_netxbig_led(struct platform_device *pdev, 317create_netxbig_led(struct platform_device *pdev,
306 struct netxbig_led_data *led_dat, 318 struct netxbig_led_data *led_dat,
307 const struct netxbig_led *template) 319 const struct netxbig_led *template)
@@ -352,7 +364,7 @@ create_netxbig_led(struct platform_device *pdev,
352 return ret; 364 return ret;
353} 365}
354 366
355static int netxbig_led_probe(struct platform_device *pdev) 367static int __devinit netxbig_led_probe(struct platform_device *pdev)
356{ 368{
357 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; 369 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
358 struct netxbig_led_data *leds_data; 370 struct netxbig_led_data *leds_data;
@@ -362,14 +374,14 @@ static int netxbig_led_probe(struct platform_device *pdev)
362 if (!pdata) 374 if (!pdata)
363 return -EINVAL; 375 return -EINVAL;
364 376
365 leds_data = devm_kzalloc(&pdev->dev, 377 leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds,
366 sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL); 378 GFP_KERNEL);
367 if (!leds_data) 379 if (!leds_data)
368 return -ENOMEM; 380 return -ENOMEM;
369 381
370 ret = gpio_ext_init(pdata->gpio_ext); 382 ret = gpio_ext_init(pdata->gpio_ext);
371 if (ret < 0) 383 if (ret < 0)
372 return ret; 384 goto err_free_data;
373 385
374 for (i = 0; i < pdata->num_leds; i++) { 386 for (i = 0; i < pdata->num_leds; i++) {
375 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]); 387 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
@@ -386,10 +398,13 @@ err_free_leds:
386 delete_netxbig_led(&leds_data[i]); 398 delete_netxbig_led(&leds_data[i]);
387 399
388 gpio_ext_free(pdata->gpio_ext); 400 gpio_ext_free(pdata->gpio_ext);
401err_free_data:
402 kfree(leds_data);
403
389 return ret; 404 return ret;
390} 405}
391 406
392static int netxbig_led_remove(struct platform_device *pdev) 407static int __devexit netxbig_led_remove(struct platform_device *pdev)
393{ 408{
394 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; 409 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
395 struct netxbig_led_data *leds_data; 410 struct netxbig_led_data *leds_data;
@@ -401,22 +416,34 @@ static int netxbig_led_remove(struct platform_device *pdev)
401 delete_netxbig_led(&leds_data[i]); 416 delete_netxbig_led(&leds_data[i]);
402 417
403 gpio_ext_free(pdata->gpio_ext); 418 gpio_ext_free(pdata->gpio_ext);
419 kfree(leds_data);
404 420
405 return 0; 421 return 0;
406} 422}
407 423
408static struct platform_driver netxbig_led_driver = { 424static struct platform_driver netxbig_led_driver = {
409 .probe = netxbig_led_probe, 425 .probe = netxbig_led_probe,
410 .remove = netxbig_led_remove, 426 .remove = __devexit_p(netxbig_led_remove),
411 .driver = { 427 .driver = {
412 .name = "leds-netxbig", 428 .name = "leds-netxbig",
413 .owner = THIS_MODULE, 429 .owner = THIS_MODULE,
414 }, 430 },
415}; 431};
432MODULE_ALIAS("platform:leds-netxbig");
416 433
417module_platform_driver(netxbig_led_driver); 434static int __init netxbig_led_init(void)
435{
436 return platform_driver_register(&netxbig_led_driver);
437}
438
439static void __exit netxbig_led_exit(void)
440{
441 platform_driver_unregister(&netxbig_led_driver);
442}
443
444module_init(netxbig_led_init);
445module_exit(netxbig_led_exit);
418 446
419MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 447MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
420MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards"); 448MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
421MODULE_LICENSE("GPL"); 449MODULE_LICENSE("GPL");
422MODULE_ALIAS("platform:leds-netxbig");
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index d978171c25b..f77d48d0b3e 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -28,9 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/leds.h> 30#include <linux/leds.h>
31#include <linux/module.h> 31#include <mach/leds-ns2.h>
32#include <linux/platform_data/leds-kirkwood-ns2.h>
33#include <linux/of_gpio.h>
34 32
35/* 33/*
36 * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in 34 * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in
@@ -150,7 +148,7 @@ static ssize_t ns2_led_sata_store(struct device *dev,
150 unsigned long enable; 148 unsigned long enable;
151 enum ns2_led_modes mode; 149 enum ns2_led_modes mode;
152 150
153 ret = kstrtoul(buff, 10, &enable); 151 ret = strict_strtoul(buff, 10, &enable);
154 if (ret < 0) 152 if (ret < 0)
155 return ret; 153 return ret;
156 154
@@ -185,29 +183,36 @@ static ssize_t ns2_led_sata_show(struct device *dev,
185 183
186static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store); 184static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
187 185
188static int 186static int __devinit
189create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, 187create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
190 const struct ns2_led *template) 188 const struct ns2_led *template)
191{ 189{
192 int ret; 190 int ret;
193 enum ns2_led_modes mode; 191 enum ns2_led_modes mode;
194 192
195 ret = devm_gpio_request_one(&pdev->dev, template->cmd, 193 ret = gpio_request(template->cmd, template->name);
196 GPIOF_DIR_OUT | gpio_get_value(template->cmd), 194 if (ret == 0) {
197 template->name); 195 ret = gpio_direction_output(template->cmd,
196 gpio_get_value(template->cmd));
197 if (ret)
198 gpio_free(template->cmd);
199 }
198 if (ret) { 200 if (ret) {
199 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n", 201 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n",
200 template->name); 202 template->name);
201 return ret;
202 } 203 }
203 204
204 ret = devm_gpio_request_one(&pdev->dev, template->slow, 205 ret = gpio_request(template->slow, template->name);
205 GPIOF_DIR_OUT | gpio_get_value(template->slow), 206 if (ret == 0) {
206 template->name); 207 ret = gpio_direction_output(template->slow,
208 gpio_get_value(template->slow));
209 if (ret)
210 gpio_free(template->slow);
211 }
207 if (ret) { 212 if (ret) {
208 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n", 213 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n",
209 template->name); 214 template->name);
210 return ret; 215 goto err_free_cmd;
211 } 216 }
212 217
213 rwlock_init(&led_dat->rw_lock); 218 rwlock_init(&led_dat->rw_lock);
@@ -222,7 +227,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
222 227
223 ret = ns2_led_get_mode(led_dat, &mode); 228 ret = ns2_led_get_mode(led_dat, &mode);
224 if (ret < 0) 229 if (ret < 0)
225 return ret; 230 goto err_free_slow;
226 231
227 /* Set LED initial state. */ 232 /* Set LED initial state. */
228 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0; 233 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
@@ -231,7 +236,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
231 236
232 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 237 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
233 if (ret < 0) 238 if (ret < 0)
234 return ret; 239 goto err_free_slow;
235 240
236 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); 241 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
237 if (ret < 0) 242 if (ret < 0)
@@ -241,115 +246,58 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
241 246
242err_free_cdev: 247err_free_cdev:
243 led_classdev_unregister(&led_dat->cdev); 248 led_classdev_unregister(&led_dat->cdev);
249err_free_slow:
250 gpio_free(led_dat->slow);
251err_free_cmd:
252 gpio_free(led_dat->cmd);
253
244 return ret; 254 return ret;
245} 255}
246 256
247static void delete_ns2_led(struct ns2_led_data *led_dat) 257static void __devexit delete_ns2_led(struct ns2_led_data *led_dat)
248{ 258{
249 device_remove_file(led_dat->cdev.dev, &dev_attr_sata); 259 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
250 led_classdev_unregister(&led_dat->cdev); 260 led_classdev_unregister(&led_dat->cdev);
261 gpio_free(led_dat->cmd);
262 gpio_free(led_dat->slow);
251} 263}
252 264
253#ifdef CONFIG_OF_GPIO 265static int __devinit ns2_led_probe(struct platform_device *pdev)
254/*
255 * Translate OpenFirmware node properties into platform_data.
256 */
257static int
258ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
259{
260 struct device_node *np = dev->of_node;
261 struct device_node *child;
262 struct ns2_led *leds;
263 int num_leds = 0;
264 int i = 0;
265
266 num_leds = of_get_child_count(np);
267 if (!num_leds)
268 return -ENODEV;
269
270 leds = devm_kzalloc(dev, num_leds * sizeof(struct ns2_led),
271 GFP_KERNEL);
272 if (!leds)
273 return -ENOMEM;
274
275 for_each_child_of_node(np, child) {
276 const char *string;
277 int ret;
278
279 ret = of_get_named_gpio(child, "cmd-gpio", 0);
280 if (ret < 0)
281 return ret;
282 leds[i].cmd = ret;
283 ret = of_get_named_gpio(child, "slow-gpio", 0);
284 if (ret < 0)
285 return ret;
286 leds[i].slow = ret;
287 ret = of_property_read_string(child, "label", &string);
288 leds[i].name = (ret == 0) ? string : child->name;
289 ret = of_property_read_string(child, "linux,default-trigger",
290 &string);
291 if (ret == 0)
292 leds[i].default_trigger = string;
293
294 i++;
295 }
296
297 pdata->leds = leds;
298 pdata->num_leds = num_leds;
299
300 return 0;
301}
302
303static const struct of_device_id of_ns2_leds_match[] = {
304 { .compatible = "lacie,ns2-leds", },
305 {},
306};
307#endif /* CONFIG_OF_GPIO */
308
309static int ns2_led_probe(struct platform_device *pdev)
310{ 266{
311 struct ns2_led_platform_data *pdata = pdev->dev.platform_data; 267 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
312 struct ns2_led_data *leds_data; 268 struct ns2_led_data *leds_data;
313 int i; 269 int i;
314 int ret; 270 int ret;
315 271
316#ifdef CONFIG_OF_GPIO
317 if (!pdata) {
318 pdata = devm_kzalloc(&pdev->dev,
319 sizeof(struct ns2_led_platform_data),
320 GFP_KERNEL);
321 if (!pdata)
322 return -ENOMEM;
323
324 ret = ns2_leds_get_of_pdata(&pdev->dev, pdata);
325 if (ret)
326 return ret;
327 }
328#else
329 if (!pdata) 272 if (!pdata)
330 return -EINVAL; 273 return -EINVAL;
331#endif /* CONFIG_OF_GPIO */
332 274
333 leds_data = devm_kzalloc(&pdev->dev, sizeof(struct ns2_led_data) * 275 leds_data = kzalloc(sizeof(struct ns2_led_data) *
334 pdata->num_leds, GFP_KERNEL); 276 pdata->num_leds, GFP_KERNEL);
335 if (!leds_data) 277 if (!leds_data)
336 return -ENOMEM; 278 return -ENOMEM;
337 279
338 for (i = 0; i < pdata->num_leds; i++) { 280 for (i = 0; i < pdata->num_leds; i++) {
339 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]); 281 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]);
340 if (ret < 0) { 282 if (ret < 0)
341 for (i = i - 1; i >= 0; i--) 283 goto err;
342 delete_ns2_led(&leds_data[i]); 284
343 return ret;
344 }
345 } 285 }
346 286
347 platform_set_drvdata(pdev, leds_data); 287 platform_set_drvdata(pdev, leds_data);
348 288
349 return 0; 289 return 0;
290
291err:
292 for (i = i - 1; i >= 0; i--)
293 delete_ns2_led(&leds_data[i]);
294
295 kfree(leds_data);
296
297 return ret;
350} 298}
351 299
352static int ns2_led_remove(struct platform_device *pdev) 300static int __devexit ns2_led_remove(struct platform_device *pdev)
353{ 301{
354 int i; 302 int i;
355 struct ns2_led_platform_data *pdata = pdev->dev.platform_data; 303 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
@@ -360,6 +308,7 @@ static int ns2_led_remove(struct platform_device *pdev)
360 for (i = 0; i < pdata->num_leds; i++) 308 for (i = 0; i < pdata->num_leds; i++)
361 delete_ns2_led(&leds_data[i]); 309 delete_ns2_led(&leds_data[i]);
362 310
311 kfree(leds_data);
363 platform_set_drvdata(pdev, NULL); 312 platform_set_drvdata(pdev, NULL);
364 313
365 return 0; 314 return 0;
@@ -367,17 +316,27 @@ static int ns2_led_remove(struct platform_device *pdev)
367 316
368static struct platform_driver ns2_led_driver = { 317static struct platform_driver ns2_led_driver = {
369 .probe = ns2_led_probe, 318 .probe = ns2_led_probe,
370 .remove = ns2_led_remove, 319 .remove = __devexit_p(ns2_led_remove),
371 .driver = { 320 .driver = {
372 .name = "leds-ns2", 321 .name = "leds-ns2",
373 .owner = THIS_MODULE, 322 .owner = THIS_MODULE,
374 .of_match_table = of_match_ptr(of_ns2_leds_match),
375 }, 323 },
376}; 324};
325MODULE_ALIAS("platform:leds-ns2");
377 326
378module_platform_driver(ns2_led_driver); 327static int __init ns2_led_init(void)
328{
329 return platform_driver_register(&ns2_led_driver);
330}
331
332static void __exit ns2_led_exit(void)
333{
334 platform_driver_unregister(&ns2_led_driver);
335}
336
337module_init(ns2_led_init);
338module_exit(ns2_led_exit);
379 339
380MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 340MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
381MODULE_DESCRIPTION("Network Space v2 LED driver"); 341MODULE_DESCRIPTION("Network Space v2 LED driver");
382MODULE_LICENSE("GPL"); 342MODULE_LICENSE("GPL");
383MODULE_ALIAS("platform:leds-ns2");
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
deleted file mode 100644
index ee14662ed5c..00000000000
--- a/drivers/leds/leds-ot200.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * Bachmann ot200 leds driver.
3 *
4 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
5 * Christian Gmeiner <christian.gmeiner@gmail.com>
6 *
7 * License: GPL as published by the FSF.
8 */
9
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/leds.h>
15#include <linux/io.h>
16#include <linux/module.h>
17
18
19struct ot200_led {
20 struct led_classdev cdev;
21 const char *name;
22 unsigned long port;
23 u8 mask;
24};
25
26/*
27 * The device has three leds on the back panel (led_err, led_init and led_run)
28 * and can handle up to seven leds on the front panel.
29 */
30
31static struct ot200_led leds[] = {
32 {
33 .name = "led_run",
34 .port = 0x5a,
35 .mask = BIT(0),
36 },
37 {
38 .name = "led_init",
39 .port = 0x5a,
40 .mask = BIT(1),
41 },
42 {
43 .name = "led_err",
44 .port = 0x5a,
45 .mask = BIT(2),
46 },
47 {
48 .name = "led_1",
49 .port = 0x49,
50 .mask = BIT(7),
51 },
52 {
53 .name = "led_2",
54 .port = 0x49,
55 .mask = BIT(6),
56 },
57 {
58 .name = "led_3",
59 .port = 0x49,
60 .mask = BIT(5),
61 },
62 {
63 .name = "led_4",
64 .port = 0x49,
65 .mask = BIT(4),
66 },
67 {
68 .name = "led_5",
69 .port = 0x49,
70 .mask = BIT(3),
71 },
72 {
73 .name = "led_6",
74 .port = 0x49,
75 .mask = BIT(2),
76 },
77 {
78 .name = "led_7",
79 .port = 0x49,
80 .mask = BIT(1),
81 }
82};
83
84static DEFINE_SPINLOCK(value_lock);
85
86/*
87 * we need to store the current led states, as it is not
88 * possible to read the current led state via inb().
89 */
90static u8 leds_back;
91static u8 leds_front;
92
93static void ot200_led_brightness_set(struct led_classdev *led_cdev,
94 enum led_brightness value)
95{
96 struct ot200_led *led = container_of(led_cdev, struct ot200_led, cdev);
97 u8 *val;
98 unsigned long flags;
99
100 spin_lock_irqsave(&value_lock, flags);
101
102 if (led->port == 0x49)
103 val = &leds_front;
104 else if (led->port == 0x5a)
105 val = &leds_back;
106 else
107 BUG();
108
109 if (value == LED_OFF)
110 *val &= ~led->mask;
111 else
112 *val |= led->mask;
113
114 outb(*val, led->port);
115 spin_unlock_irqrestore(&value_lock, flags);
116}
117
118static int ot200_led_probe(struct platform_device *pdev)
119{
120 int i;
121 int ret;
122
123 for (i = 0; i < ARRAY_SIZE(leds); i++) {
124
125 leds[i].cdev.name = leds[i].name;
126 leds[i].cdev.brightness_set = ot200_led_brightness_set;
127
128 ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
129 if (ret < 0)
130 goto err;
131 }
132
133 leds_front = 0; /* turn off all front leds */
134 leds_back = BIT(1); /* turn on init led */
135 outb(leds_front, 0x49);
136 outb(leds_back, 0x5a);
137
138 return 0;
139
140err:
141 for (i = i - 1; i >= 0; i--)
142 led_classdev_unregister(&leds[i].cdev);
143
144 return ret;
145}
146
147static int ot200_led_remove(struct platform_device *pdev)
148{
149 int i;
150
151 for (i = 0; i < ARRAY_SIZE(leds); i++)
152 led_classdev_unregister(&leds[i].cdev);
153
154 return 0;
155}
156
157static struct platform_driver ot200_led_driver = {
158 .probe = ot200_led_probe,
159 .remove = ot200_led_remove,
160 .driver = {
161 .name = "leds-ot200",
162 .owner = THIS_MODULE,
163 },
164};
165
166module_platform_driver(ot200_led_driver);
167
168MODULE_AUTHOR("Sebastian A. Siewior <bigeasy@linutronix.de>");
169MODULE_DESCRIPTION("ot200 LED driver");
170MODULE_LICENSE("GPL");
171MODULE_ALIAS("platform:leds-ot200");
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index cee8a5b483a..a2c874623e3 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -449,6 +449,7 @@ static int pca9532_probe(struct i2c_client *client,
449{ 449{
450 struct pca9532_data *data = i2c_get_clientdata(client); 450 struct pca9532_data *data = i2c_get_clientdata(client);
451 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data; 451 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data;
452 int err;
452 453
453 if (!pca9532_pdata) 454 if (!pca9532_pdata)
454 return -EIO; 455 return -EIO;
@@ -457,7 +458,7 @@ static int pca9532_probe(struct i2c_client *client,
457 I2C_FUNC_SMBUS_BYTE_DATA)) 458 I2C_FUNC_SMBUS_BYTE_DATA))
458 return -EIO; 459 return -EIO;
459 460
460 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 461 data = kzalloc(sizeof(*data), GFP_KERNEL);
461 if (!data) 462 if (!data)
462 return -ENOMEM; 463 return -ENOMEM;
463 464
@@ -468,7 +469,11 @@ static int pca9532_probe(struct i2c_client *client,
468 data->client = client; 469 data->client = client;
469 mutex_init(&data->update_lock); 470 mutex_init(&data->update_lock);
470 471
471 return pca9532_configure(client, data, pca9532_pdata); 472 err = pca9532_configure(client, data, pca9532_pdata);
473 if (err)
474 kfree(data);
475
476 return err;
472} 477}
473 478
474static int pca9532_remove(struct i2c_client *client) 479static int pca9532_remove(struct i2c_client *client)
@@ -480,11 +485,24 @@ static int pca9532_remove(struct i2c_client *client)
480 if (err) 485 if (err)
481 return err; 486 return err;
482 487
488 kfree(data);
483 return 0; 489 return 0;
484} 490}
485 491
486module_i2c_driver(pca9532_driver); 492static int __init pca9532_init(void)
493{
494 return i2c_add_driver(&pca9532_driver);
495}
496
497static void __exit pca9532_exit(void)
498{
499 i2c_del_driver(&pca9532_driver);
500}
487 501
488MODULE_AUTHOR("Riku Voipio"); 502MODULE_AUTHOR("Riku Voipio");
489MODULE_LICENSE("GPL"); 503MODULE_LICENSE("GPL");
490MODULE_DESCRIPTION("PCA 9532 LED dimmer"); 504MODULE_DESCRIPTION("PCA 9532 LED dimmer");
505
506module_init(pca9532_init);
507module_exit(pca9532_exit);
508
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index edf485b773c..66aa3e8e786 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -101,16 +101,11 @@ static const struct i2c_device_id pca955x_id[] = {
101}; 101};
102MODULE_DEVICE_TABLE(i2c, pca955x_id); 102MODULE_DEVICE_TABLE(i2c, pca955x_id);
103 103
104struct pca955x { 104struct pca955x_led {
105 struct mutex lock;
106 struct pca955x_led *leds;
107 struct pca955x_chipdef *chipdef; 105 struct pca955x_chipdef *chipdef;
108 struct i2c_client *client; 106 struct i2c_client *client;
109};
110
111struct pca955x_led {
112 struct pca955x *pca955x;
113 struct work_struct work; 107 struct work_struct work;
108 spinlock_t lock;
114 enum led_brightness brightness; 109 enum led_brightness brightness;
115 struct led_classdev led_cdev; 110 struct led_classdev led_cdev;
116 int led_num; /* 0 .. 15 potentially */ 111 int led_num; /* 0 .. 15 potentially */
@@ -145,7 +140,7 @@ static inline u8 pca955x_ledsel(u8 oldval, int led_num, int state)
145 */ 140 */
146static void pca955x_write_psc(struct i2c_client *client, int n, u8 val) 141static void pca955x_write_psc(struct i2c_client *client, int n, u8 val)
147{ 142{
148 struct pca955x *pca955x = i2c_get_clientdata(client); 143 struct pca955x_led *pca955x = i2c_get_clientdata(client);
149 144
150 i2c_smbus_write_byte_data(client, 145 i2c_smbus_write_byte_data(client,
151 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n, 146 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n,
@@ -161,7 +156,7 @@ static void pca955x_write_psc(struct i2c_client *client, int n, u8 val)
161 */ 156 */
162static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val) 157static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val)
163{ 158{
164 struct pca955x *pca955x = i2c_get_clientdata(client); 159 struct pca955x_led *pca955x = i2c_get_clientdata(client);
165 160
166 i2c_smbus_write_byte_data(client, 161 i2c_smbus_write_byte_data(client,
167 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n, 162 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n,
@@ -174,7 +169,7 @@ static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val)
174 */ 169 */
175static void pca955x_write_ls(struct i2c_client *client, int n, u8 val) 170static void pca955x_write_ls(struct i2c_client *client, int n, u8 val)
176{ 171{
177 struct pca955x *pca955x = i2c_get_clientdata(client); 172 struct pca955x_led *pca955x = i2c_get_clientdata(client);
178 173
179 i2c_smbus_write_byte_data(client, 174 i2c_smbus_write_byte_data(client,
180 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n, 175 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n,
@@ -187,7 +182,7 @@ static void pca955x_write_ls(struct i2c_client *client, int n, u8 val)
187 */ 182 */
188static u8 pca955x_read_ls(struct i2c_client *client, int n) 183static u8 pca955x_read_ls(struct i2c_client *client, int n)
189{ 184{
190 struct pca955x *pca955x = i2c_get_clientdata(client); 185 struct pca955x_led *pca955x = i2c_get_clientdata(client);
191 186
192 return (u8) i2c_smbus_read_byte_data(client, 187 return (u8) i2c_smbus_read_byte_data(client,
193 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n); 188 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n);
@@ -195,23 +190,18 @@ static u8 pca955x_read_ls(struct i2c_client *client, int n)
195 190
196static void pca955x_led_work(struct work_struct *work) 191static void pca955x_led_work(struct work_struct *work)
197{ 192{
198 struct pca955x_led *pca955x_led; 193 struct pca955x_led *pca955x;
199 struct pca955x *pca955x;
200 u8 ls; 194 u8 ls;
201 int chip_ls; /* which LSx to use (0-3 potentially) */ 195 int chip_ls; /* which LSx to use (0-3 potentially) */
202 int ls_led; /* which set of bits within LSx to use (0-3) */ 196 int ls_led; /* which set of bits within LSx to use (0-3) */
203 197
204 pca955x_led = container_of(work, struct pca955x_led, work); 198 pca955x = container_of(work, struct pca955x_led, work);
205 pca955x = pca955x_led->pca955x; 199 chip_ls = pca955x->led_num / 4;
206 200 ls_led = pca955x->led_num % 4;
207 chip_ls = pca955x_led->led_num / 4;
208 ls_led = pca955x_led->led_num % 4;
209
210 mutex_lock(&pca955x->lock);
211 201
212 ls = pca955x_read_ls(pca955x->client, chip_ls); 202 ls = pca955x_read_ls(pca955x->client, chip_ls);
213 203
214 switch (pca955x_led->brightness) { 204 switch (pca955x->brightness) {
215 case LED_FULL: 205 case LED_FULL:
216 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON); 206 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON);
217 break; 207 break;
@@ -229,15 +219,12 @@ static void pca955x_led_work(struct work_struct *work)
229 * OFF, HALF, or FULL. But, this is probably better than 219 * OFF, HALF, or FULL. But, this is probably better than
230 * just turning off for all other values. 220 * just turning off for all other values.
231 */ 221 */
232 pca955x_write_pwm(pca955x->client, 1, 222 pca955x_write_pwm(pca955x->client, 1, 255-pca955x->brightness);
233 255 - pca955x_led->brightness);
234 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK1); 223 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK1);
235 break; 224 break;
236 } 225 }
237 226
238 pca955x_write_ls(pca955x->client, chip_ls, ls); 227 pca955x_write_ls(pca955x->client, chip_ls, ls);
239
240 mutex_unlock(&pca955x->lock);
241} 228}
242 229
243static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value) 230static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value)
@@ -246,6 +233,7 @@ static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness v
246 233
247 pca955x = container_of(led_cdev, struct pca955x_led, led_cdev); 234 pca955x = container_of(led_cdev, struct pca955x_led, led_cdev);
248 235
236 spin_lock(&pca955x->lock);
249 pca955x->brightness = value; 237 pca955x->brightness = value;
250 238
251 /* 239 /*
@@ -253,13 +241,14 @@ static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness v
253 * can sleep. 241 * can sleep.
254 */ 242 */
255 schedule_work(&pca955x->work); 243 schedule_work(&pca955x->work);
244
245 spin_unlock(&pca955x->lock);
256} 246}
257 247
258static int pca955x_probe(struct i2c_client *client, 248static int __devinit pca955x_probe(struct i2c_client *client,
259 const struct i2c_device_id *id) 249 const struct i2c_device_id *id)
260{ 250{
261 struct pca955x *pca955x; 251 struct pca955x_led *pca955x;
262 struct pca955x_led *pca955x_led;
263 struct pca955x_chipdef *chip; 252 struct pca955x_chipdef *chip;
264 struct i2c_adapter *adapter; 253 struct i2c_adapter *adapter;
265 struct led_platform_data *pdata; 254 struct led_platform_data *pdata;
@@ -277,7 +266,7 @@ static int pca955x_probe(struct i2c_client *client,
277 return -ENODEV; 266 return -ENODEV;
278 } 267 }
279 268
280 dev_info(&client->dev, "leds-pca955x: Using %s %d-bit LED driver at " 269 printk(KERN_INFO "leds-pca955x: Using %s %d-bit LED driver at "
281 "slave address 0x%02x\n", 270 "slave address 0x%02x\n",
282 id->name, chip->bits, client->addr); 271 id->name, chip->bits, client->addr);
283 272
@@ -293,47 +282,39 @@ static int pca955x_probe(struct i2c_client *client,
293 } 282 }
294 } 283 }
295 284
296 pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL); 285 pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL);
297 if (!pca955x) 286 if (!pca955x)
298 return -ENOMEM; 287 return -ENOMEM;
299 288
300 pca955x->leds = devm_kzalloc(&client->dev,
301 sizeof(*pca955x_led) * chip->bits, GFP_KERNEL);
302 if (!pca955x->leds)
303 return -ENOMEM;
304
305 i2c_set_clientdata(client, pca955x); 289 i2c_set_clientdata(client, pca955x);
306 290
307 mutex_init(&pca955x->lock);
308 pca955x->client = client;
309 pca955x->chipdef = chip;
310
311 for (i = 0; i < chip->bits; i++) { 291 for (i = 0; i < chip->bits; i++) {
312 pca955x_led = &pca955x->leds[i]; 292 pca955x[i].chipdef = chip;
313 pca955x_led->led_num = i; 293 pca955x[i].client = client;
314 pca955x_led->pca955x = pca955x; 294 pca955x[i].led_num = i;
315 295
316 /* Platform data can specify LED names and default triggers */ 296 /* Platform data can specify LED names and default triggers */
317 if (pdata) { 297 if (pdata) {
318 if (pdata->leds[i].name) 298 if (pdata->leds[i].name)
319 snprintf(pca955x_led->name, 299 snprintf(pca955x[i].name,
320 sizeof(pca955x_led->name), "pca955x:%s", 300 sizeof(pca955x[i].name), "pca955x:%s",
321 pdata->leds[i].name); 301 pdata->leds[i].name);
322 if (pdata->leds[i].default_trigger) 302 if (pdata->leds[i].default_trigger)
323 pca955x_led->led_cdev.default_trigger = 303 pca955x[i].led_cdev.default_trigger =
324 pdata->leds[i].default_trigger; 304 pdata->leds[i].default_trigger;
325 } else { 305 } else {
326 snprintf(pca955x_led->name, sizeof(pca955x_led->name), 306 snprintf(pca955x[i].name, sizeof(pca955x[i].name),
327 "pca955x:%d", i); 307 "pca955x:%d", i);
328 } 308 }
329 309
330 pca955x_led->led_cdev.name = pca955x_led->name; 310 spin_lock_init(&pca955x[i].lock);
331 pca955x_led->led_cdev.brightness_set = pca955x_led_set; 311
312 pca955x[i].led_cdev.name = pca955x[i].name;
313 pca955x[i].led_cdev.brightness_set = pca955x_led_set;
332 314
333 INIT_WORK(&pca955x_led->work, pca955x_led_work); 315 INIT_WORK(&pca955x[i].work, pca955x_led_work);
334 316
335 err = led_classdev_register(&client->dev, 317 err = led_classdev_register(&client->dev, &pca955x[i].led_cdev);
336 &pca955x_led->led_cdev);
337 if (err < 0) 318 if (err < 0)
338 goto exit; 319 goto exit;
339 } 320 }
@@ -356,23 +337,27 @@ static int pca955x_probe(struct i2c_client *client,
356 337
357exit: 338exit:
358 while (i--) { 339 while (i--) {
359 led_classdev_unregister(&pca955x->leds[i].led_cdev); 340 led_classdev_unregister(&pca955x[i].led_cdev);
360 cancel_work_sync(&pca955x->leds[i].work); 341 cancel_work_sync(&pca955x[i].work);
361 } 342 }
362 343
344 kfree(pca955x);
345
363 return err; 346 return err;
364} 347}
365 348
366static int pca955x_remove(struct i2c_client *client) 349static int __devexit pca955x_remove(struct i2c_client *client)
367{ 350{
368 struct pca955x *pca955x = i2c_get_clientdata(client); 351 struct pca955x_led *pca955x = i2c_get_clientdata(client);
369 int i; 352 int i;
370 353
371 for (i = 0; i < pca955x->chipdef->bits; i++) { 354 for (i = 0; i < pca955x->chipdef->bits; i++) {
372 led_classdev_unregister(&pca955x->leds[i].led_cdev); 355 led_classdev_unregister(&pca955x[i].led_cdev);
373 cancel_work_sync(&pca955x->leds[i].work); 356 cancel_work_sync(&pca955x[i].work);
374 } 357 }
375 358
359 kfree(pca955x);
360
376 return 0; 361 return 0;
377} 362}
378 363
@@ -382,11 +367,22 @@ static struct i2c_driver pca955x_driver = {
382 .owner = THIS_MODULE, 367 .owner = THIS_MODULE,
383 }, 368 },
384 .probe = pca955x_probe, 369 .probe = pca955x_probe,
385 .remove = pca955x_remove, 370 .remove = __devexit_p(pca955x_remove),
386 .id_table = pca955x_id, 371 .id_table = pca955x_id,
387}; 372};
388 373
389module_i2c_driver(pca955x_driver); 374static int __init pca955x_leds_init(void)
375{
376 return i2c_add_driver(&pca955x_driver);
377}
378
379static void __exit pca955x_leds_exit(void)
380{
381 i2c_del_driver(&pca955x_driver);
382}
383
384module_init(pca955x_leds_init);
385module_exit(pca955x_leds_exit);
390 386
391MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>"); 387MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>");
392MODULE_DESCRIPTION("PCA955x LED driver"); 388MODULE_DESCRIPTION("PCA955x LED driver");
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
deleted file mode 100644
index 9aae5679ffb..00000000000
--- a/drivers/leds/leds-pca9633.c
+++ /dev/null
@@ -1,194 +0,0 @@
1/*
2 * Copyright 2011 bct electronic GmbH
3 *
4 * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
5 *
6 * Based on leds-pca955x.c
7 *
8 * This file is subject to the terms and conditions of version 2 of
9 * the GNU General Public License. See the file COPYING in the main
10 * directory of this archive for more details.
11 *
12 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <linux/string.h>
19#include <linux/ctype.h>
20#include <linux/leds.h>
21#include <linux/err.h>
22#include <linux/i2c.h>
23#include <linux/workqueue.h>
24#include <linux/slab.h>
25#include <linux/platform_data/leds-pca9633.h>
26
27/* LED select registers determine the source that drives LED outputs */
28#define PCA9633_LED_OFF 0x0 /* LED driver off */
29#define PCA9633_LED_ON 0x1 /* LED driver on */
30#define PCA9633_LED_PWM 0x2 /* Controlled through PWM */
31#define PCA9633_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
32
33#define PCA9633_MODE1 0x00
34#define PCA9633_MODE2 0x01
35#define PCA9633_PWM_BASE 0x02
36#define PCA9633_LEDOUT 0x08
37
38static const struct i2c_device_id pca9633_id[] = {
39 { "pca9633", 0 },
40 { }
41};
42MODULE_DEVICE_TABLE(i2c, pca9633_id);
43
44struct pca9633_led {
45 struct i2c_client *client;
46 struct work_struct work;
47 enum led_brightness brightness;
48 struct led_classdev led_cdev;
49 int led_num; /* 0 .. 3 potentially */
50 char name[32];
51};
52
53static void pca9633_led_work(struct work_struct *work)
54{
55 struct pca9633_led *pca9633 = container_of(work,
56 struct pca9633_led, work);
57 u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
58 int shift = 2 * pca9633->led_num;
59 u8 mask = 0x3 << shift;
60
61 switch (pca9633->brightness) {
62 case LED_FULL:
63 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
64 (ledout & ~mask) | (PCA9633_LED_ON << shift));
65 break;
66 case LED_OFF:
67 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
68 ledout & ~mask);
69 break;
70 default:
71 i2c_smbus_write_byte_data(pca9633->client,
72 PCA9633_PWM_BASE + pca9633->led_num,
73 pca9633->brightness);
74 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
75 (ledout & ~mask) | (PCA9633_LED_PWM << shift));
76 break;
77 }
78}
79
80static void pca9633_led_set(struct led_classdev *led_cdev,
81 enum led_brightness value)
82{
83 struct pca9633_led *pca9633;
84
85 pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
86
87 pca9633->brightness = value;
88
89 /*
90 * Must use workqueue for the actual I/O since I2C operations
91 * can sleep.
92 */
93 schedule_work(&pca9633->work);
94}
95
96static int pca9633_probe(struct i2c_client *client,
97 const struct i2c_device_id *id)
98{
99 struct pca9633_led *pca9633;
100 struct pca9633_platform_data *pdata;
101 int i, err;
102
103 pdata = client->dev.platform_data;
104
105 if (pdata) {
106 if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
107 dev_err(&client->dev, "board info must claim at most 4 LEDs");
108 return -EINVAL;
109 }
110 }
111
112 pca9633 = devm_kzalloc(&client->dev, 4 * sizeof(*pca9633), GFP_KERNEL);
113 if (!pca9633)
114 return -ENOMEM;
115
116 i2c_set_clientdata(client, pca9633);
117
118 for (i = 0; i < 4; i++) {
119 pca9633[i].client = client;
120 pca9633[i].led_num = i;
121
122 /* Platform data can specify LED names and default triggers */
123 if (pdata && i < pdata->leds.num_leds) {
124 if (pdata->leds.leds[i].name)
125 snprintf(pca9633[i].name,
126 sizeof(pca9633[i].name), "pca9633:%s",
127 pdata->leds.leds[i].name);
128 if (pdata->leds.leds[i].default_trigger)
129 pca9633[i].led_cdev.default_trigger =
130 pdata->leds.leds[i].default_trigger;
131 } else {
132 snprintf(pca9633[i].name, sizeof(pca9633[i].name),
133 "pca9633:%d", i);
134 }
135
136 pca9633[i].led_cdev.name = pca9633[i].name;
137 pca9633[i].led_cdev.brightness_set = pca9633_led_set;
138
139 INIT_WORK(&pca9633[i].work, pca9633_led_work);
140
141 err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
142 if (err < 0)
143 goto exit;
144 }
145
146 /* Disable LED all-call address and set normal mode */
147 i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
148
149 /* Configure output: open-drain or totem pole (push-pull) */
150 if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN)
151 i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01);
152
153 /* Turn off LEDs */
154 i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
155
156 return 0;
157
158exit:
159 while (i--) {
160 led_classdev_unregister(&pca9633[i].led_cdev);
161 cancel_work_sync(&pca9633[i].work);
162 }
163
164 return err;
165}
166
167static int pca9633_remove(struct i2c_client *client)
168{
169 struct pca9633_led *pca9633 = i2c_get_clientdata(client);
170 int i;
171
172 for (i = 0; i < 4; i++) {
173 led_classdev_unregister(&pca9633[i].led_cdev);
174 cancel_work_sync(&pca9633[i].work);
175 }
176
177 return 0;
178}
179
180static struct i2c_driver pca9633_driver = {
181 .driver = {
182 .name = "leds-pca9633",
183 .owner = THIS_MODULE,
184 },
185 .probe = pca9633_probe,
186 .remove = pca9633_remove,
187 .id_table = pca9633_id,
188};
189
190module_i2c_driver(pca9633_driver);
191
192MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
193MODULE_DESCRIPTION("PCA9633 LED driver");
194MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 2157524f277..666daf77872 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -26,7 +26,7 @@
26struct led_pwm_data { 26struct led_pwm_data {
27 struct led_classdev cdev; 27 struct led_classdev cdev;
28 struct pwm_device *pwm; 28 struct pwm_device *pwm;
29 unsigned int active_low; 29 unsigned int active_low;
30 unsigned int period; 30 unsigned int period;
31}; 31};
32 32
@@ -57,8 +57,7 @@ static int led_pwm_probe(struct platform_device *pdev)
57 if (!pdata) 57 if (!pdata)
58 return -EBUSY; 58 return -EBUSY;
59 59
60 leds_data = devm_kzalloc(&pdev->dev, 60 leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
61 sizeof(struct led_pwm_data) * pdata->num_leds,
62 GFP_KERNEL); 61 GFP_KERNEL);
63 if (!leds_data) 62 if (!leds_data)
64 return -ENOMEM; 63 return -ENOMEM;
@@ -104,10 +103,12 @@ err:
104 } 103 }
105 } 104 }
106 105
106 kfree(leds_data);
107
107 return ret; 108 return ret;
108} 109}
109 110
110static int led_pwm_remove(struct platform_device *pdev) 111static int __devexit led_pwm_remove(struct platform_device *pdev)
111{ 112{
112 int i; 113 int i;
113 struct led_pwm_platform_data *pdata = pdev->dev.platform_data; 114 struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
@@ -120,19 +121,32 @@ static int led_pwm_remove(struct platform_device *pdev)
120 pwm_free(leds_data[i].pwm); 121 pwm_free(leds_data[i].pwm);
121 } 122 }
122 123
124 kfree(leds_data);
125
123 return 0; 126 return 0;
124} 127}
125 128
126static struct platform_driver led_pwm_driver = { 129static struct platform_driver led_pwm_driver = {
127 .probe = led_pwm_probe, 130 .probe = led_pwm_probe,
128 .remove = led_pwm_remove, 131 .remove = __devexit_p(led_pwm_remove),
129 .driver = { 132 .driver = {
130 .name = "leds_pwm", 133 .name = "leds_pwm",
131 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
132 }, 135 },
133}; 136};
134 137
135module_platform_driver(led_pwm_driver); 138static int __init led_pwm_init(void)
139{
140 return platform_driver_register(&led_pwm_driver);
141}
142
143static void __exit led_pwm_exit(void)
144{
145 platform_driver_unregister(&led_pwm_driver);
146}
147
148module_init(led_pwm_init);
149module_exit(led_pwm_exit);
136 150
137MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 151MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
138MODULE_DESCRIPTION("PWM LED driver for PXA"); 152MODULE_DESCRIPTION("PWM LED driver for PXA");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
index 2e746d257b0..c3525f37f73 100644
--- a/drivers/leds/leds-rb532.c
+++ b/drivers/leds/leds-rb532.c
@@ -16,7 +16,7 @@
16#include <asm/mach-rc32434/rb.h> 16#include <asm/mach-rc32434/rb.h>
17 17
18static void rb532_led_set(struct led_classdev *cdev, 18static void rb532_led_set(struct led_classdev *cdev,
19 enum led_brightness brightness) 19 enum led_brightness brightness)
20{ 20{
21 if (brightness) 21 if (brightness)
22 set_latch_u5(LO_ULED, 0); 22 set_latch_u5(LO_ULED, 0);
@@ -37,12 +37,12 @@ static struct led_classdev rb532_uled = {
37 .default_trigger = "nand-disk", 37 .default_trigger = "nand-disk",
38}; 38};
39 39
40static int rb532_led_probe(struct platform_device *pdev) 40static int __devinit rb532_led_probe(struct platform_device *pdev)
41{ 41{
42 return led_classdev_register(&pdev->dev, &rb532_uled); 42 return led_classdev_register(&pdev->dev, &rb532_uled);
43} 43}
44 44
45static int rb532_led_remove(struct platform_device *pdev) 45static int __devexit rb532_led_remove(struct platform_device *pdev)
46{ 46{
47 led_classdev_unregister(&rb532_uled); 47 led_classdev_unregister(&rb532_uled);
48 return 0; 48 return 0;
@@ -50,16 +50,28 @@ static int rb532_led_remove(struct platform_device *pdev)
50 50
51static struct platform_driver rb532_led_driver = { 51static struct platform_driver rb532_led_driver = {
52 .probe = rb532_led_probe, 52 .probe = rb532_led_probe,
53 .remove = rb532_led_remove, 53 .remove = __devexit_p(rb532_led_remove),
54 .driver = { 54 .driver = {
55 .name = "rb532-led", 55 .name = "rb532-led",
56 .owner = THIS_MODULE, 56 .owner = THIS_MODULE,
57 }, 57 },
58}; 58};
59 59
60module_platform_driver(rb532_led_driver); 60static int __init rb532_led_init(void)
61{
62 return platform_driver_register(&rb532_led_driver);
63}
64
65static void __exit rb532_led_exit(void)
66{
67 platform_driver_unregister(&rb532_led_driver);
68}
69
70module_init(rb532_led_init);
71module_exit(rb532_led_exit);
72
73MODULE_ALIAS("platform:rb532-led");
61 74
62MODULE_LICENSE("GPL"); 75MODULE_LICENSE("GPL");
63MODULE_DESCRIPTION("User LED support for Routerboard532"); 76MODULE_DESCRIPTION("User LED support for Routerboard532");
64MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>"); 77MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
65MODULE_ALIAS("platform:rb532-led");
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 4253a9b03db..8497f56f8e4 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -140,7 +140,7 @@ static void regulator_led_brightness_set(struct led_classdev *led_cdev,
140 schedule_work(&led->work); 140 schedule_work(&led->work);
141} 141}
142 142
143static int regulator_led_probe(struct platform_device *pdev) 143static int __devinit regulator_led_probe(struct platform_device *pdev)
144{ 144{
145 struct led_regulator_platform_data *pdata = pdev->dev.platform_data; 145 struct led_regulator_platform_data *pdata = pdev->dev.platform_data;
146 struct regulator_led *led; 146 struct regulator_led *led;
@@ -158,7 +158,7 @@ static int regulator_led_probe(struct platform_device *pdev)
158 return PTR_ERR(vcc); 158 return PTR_ERR(vcc);
159 } 159 }
160 160
161 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 161 led = kzalloc(sizeof(*led), GFP_KERNEL);
162 if (led == NULL) { 162 if (led == NULL) {
163 ret = -ENOMEM; 163 ret = -ENOMEM;
164 goto err_vcc; 164 goto err_vcc;
@@ -169,7 +169,7 @@ static int regulator_led_probe(struct platform_device *pdev)
169 dev_err(&pdev->dev, "Invalid default brightness %d\n", 169 dev_err(&pdev->dev, "Invalid default brightness %d\n",
170 pdata->brightness); 170 pdata->brightness);
171 ret = -EINVAL; 171 ret = -EINVAL;
172 goto err_vcc; 172 goto err_led;
173 } 173 }
174 led->value = pdata->brightness; 174 led->value = pdata->brightness;
175 175
@@ -190,7 +190,7 @@ static int regulator_led_probe(struct platform_device *pdev)
190 ret = led_classdev_register(&pdev->dev, &led->cdev); 190 ret = led_classdev_register(&pdev->dev, &led->cdev);
191 if (ret < 0) { 191 if (ret < 0) {
192 cancel_work_sync(&led->work); 192 cancel_work_sync(&led->work);
193 goto err_vcc; 193 goto err_led;
194 } 194 }
195 195
196 /* to expose the default value to userspace */ 196 /* to expose the default value to userspace */
@@ -201,12 +201,14 @@ static int regulator_led_probe(struct platform_device *pdev)
201 201
202 return 0; 202 return 0;
203 203
204err_led:
205 kfree(led);
204err_vcc: 206err_vcc:
205 regulator_put(vcc); 207 regulator_put(vcc);
206 return ret; 208 return ret;
207} 209}
208 210
209static int regulator_led_remove(struct platform_device *pdev) 211static int __devexit regulator_led_remove(struct platform_device *pdev)
210{ 212{
211 struct regulator_led *led = platform_get_drvdata(pdev); 213 struct regulator_led *led = platform_get_drvdata(pdev);
212 214
@@ -214,6 +216,7 @@ static int regulator_led_remove(struct platform_device *pdev)
214 cancel_work_sync(&led->work); 216 cancel_work_sync(&led->work);
215 regulator_led_disable(led); 217 regulator_led_disable(led);
216 regulator_put(led->vcc); 218 regulator_put(led->vcc);
219 kfree(led);
217 return 0; 220 return 0;
218} 221}
219 222
@@ -223,10 +226,20 @@ static struct platform_driver regulator_led_driver = {
223 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
224 }, 227 },
225 .probe = regulator_led_probe, 228 .probe = regulator_led_probe,
226 .remove = regulator_led_remove, 229 .remove = __devexit_p(regulator_led_remove),
227}; 230};
228 231
229module_platform_driver(regulator_led_driver); 232static int __init regulator_led_init(void)
233{
234 return platform_driver_register(&regulator_led_driver);
235}
236module_init(regulator_led_init);
237
238static void __exit regulator_led_exit(void)
239{
240 platform_driver_unregister(&regulator_led_driver);
241}
242module_exit(regulator_led_exit);
230 243
231MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 244MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
232MODULE_DESCRIPTION("Regulator driven LED driver"); 245MODULE_DESCRIPTION("Regulator driven LED driver");
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
deleted file mode 100644
index e0fff1ca592..00000000000
--- a/drivers/leds/leds-renesas-tpu.c
+++ /dev/null
@@ -1,336 +0,0 @@
1/*
2 * LED control using Renesas TPU
3 *
4 * Copyright (C) 2011 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24#include <linux/printk.h>
25#include <linux/ioport.h>
26#include <linux/io.h>
27#include <linux/clk.h>
28#include <linux/leds.h>
29#include <linux/platform_data/leds-renesas-tpu.h>
30#include <linux/gpio.h>
31#include <linux/err.h>
32#include <linux/slab.h>
33#include <linux/pm_runtime.h>
34#include <linux/workqueue.h>
35
36enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN };
37enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON };
38
39struct r_tpu_priv {
40 struct led_classdev ldev;
41 void __iomem *mapbase;
42 struct clk *clk;
43 struct platform_device *pdev;
44 enum r_tpu_pin pin_state;
45 enum r_tpu_timer timer_state;
46 unsigned long min_rate;
47 unsigned int refresh_rate;
48 struct work_struct work;
49 enum led_brightness new_brightness;
50};
51
52static DEFINE_SPINLOCK(r_tpu_lock);
53
54#define TSTR -1 /* Timer start register (shared register) */
55#define TCR 0 /* Timer control register (+0x00) */
56#define TMDR 1 /* Timer mode register (+0x04) */
57#define TIOR 2 /* Timer I/O control register (+0x08) */
58#define TIER 3 /* Timer interrupt enable register (+0x0c) */
59#define TSR 4 /* Timer status register (+0x10) */
60#define TCNT 5 /* Timer counter (+0x14) */
61#define TGRA 6 /* Timer general register A (+0x18) */
62#define TGRB 7 /* Timer general register B (+0x1c) */
63#define TGRC 8 /* Timer general register C (+0x20) */
64#define TGRD 9 /* Timer general register D (+0x24) */
65
66static inline unsigned short r_tpu_read(struct r_tpu_priv *p, int reg_nr)
67{
68 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
69 void __iomem *base = p->mapbase;
70 unsigned long offs = reg_nr << 2;
71
72 if (reg_nr == TSTR)
73 return ioread16(base - cfg->channel_offset);
74
75 return ioread16(base + offs);
76}
77
78static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr,
79 unsigned short value)
80{
81 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
82 void __iomem *base = p->mapbase;
83 unsigned long offs = reg_nr << 2;
84
85 if (reg_nr == TSTR) {
86 iowrite16(value, base - cfg->channel_offset);
87 return;
88 }
89
90 iowrite16(value, base + offs);
91}
92
93static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start)
94{
95 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
96 unsigned long flags, value;
97
98 /* start stop register shared by multiple timer channels */
99 spin_lock_irqsave(&r_tpu_lock, flags);
100 value = r_tpu_read(p, TSTR);
101
102 if (start)
103 value |= 1 << cfg->timer_bit;
104 else
105 value &= ~(1 << cfg->timer_bit);
106
107 r_tpu_write(p, TSTR, value);
108 spin_unlock_irqrestore(&r_tpu_lock, flags);
109}
110
111static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness)
112{
113 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
114 int prescaler[] = { 1, 4, 16, 64 };
115 int k, ret;
116 unsigned long rate, tmp;
117
118 if (p->timer_state == R_TPU_TIMER_ON)
119 return 0;
120
121 /* wake up device and enable clock */
122 pm_runtime_get_sync(&p->pdev->dev);
123 ret = clk_enable(p->clk);
124 if (ret) {
125 dev_err(&p->pdev->dev, "cannot enable clock\n");
126 return ret;
127 }
128
129 /* make sure channel is disabled */
130 r_tpu_start_stop_ch(p, 0);
131
132 /* get clock rate after enabling it */
133 rate = clk_get_rate(p->clk);
134
135 /* pick the lowest acceptable rate */
136 for (k = 0; k < ARRAY_SIZE(prescaler); k++)
137 if ((rate / prescaler[k]) < p->min_rate)
138 break;
139
140 if (!k) {
141 dev_err(&p->pdev->dev, "clock rate mismatch\n");
142 goto err0;
143 }
144 dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n",
145 rate, prescaler[k - 1]);
146
147 /* clear TCNT on TGRB match, count on rising edge, set prescaler */
148 r_tpu_write(p, TCR, 0x0040 | (k - 1));
149
150 /* output 0 until TGRA, output 1 until TGRB */
151 r_tpu_write(p, TIOR, 0x0002);
152
153 rate /= prescaler[k - 1] * p->refresh_rate;
154 r_tpu_write(p, TGRB, rate);
155 dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate);
156
157 tmp = (cfg->max_brightness - brightness) * rate;
158 r_tpu_write(p, TGRA, tmp / cfg->max_brightness);
159 dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness);
160
161 /* PWM mode */
162 r_tpu_write(p, TMDR, 0x0002);
163
164 /* enable channel */
165 r_tpu_start_stop_ch(p, 1);
166
167 p->timer_state = R_TPU_TIMER_ON;
168 return 0;
169 err0:
170 clk_disable(p->clk);
171 pm_runtime_put_sync(&p->pdev->dev);
172 return -ENOTSUPP;
173}
174
175static void r_tpu_disable(struct r_tpu_priv *p)
176{
177 if (p->timer_state == R_TPU_TIMER_UNUSED)
178 return;
179
180 /* disable channel */
181 r_tpu_start_stop_ch(p, 0);
182
183 /* stop clock and mark device as idle */
184 clk_disable(p->clk);
185 pm_runtime_put_sync(&p->pdev->dev);
186
187 p->timer_state = R_TPU_TIMER_UNUSED;
188}
189
190static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state,
191 enum led_brightness brightness)
192{
193 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
194
195 if (p->pin_state == new_state) {
196 if (p->pin_state == R_TPU_PIN_GPIO)
197 gpio_set_value(cfg->pin_gpio, brightness);
198 return;
199 }
200
201 if (p->pin_state == R_TPU_PIN_GPIO)
202 gpio_free(cfg->pin_gpio);
203
204 if (p->pin_state == R_TPU_PIN_GPIO_FN)
205 gpio_free(cfg->pin_gpio_fn);
206
207 if (new_state == R_TPU_PIN_GPIO)
208 gpio_request_one(cfg->pin_gpio, GPIOF_DIR_OUT | !!brightness,
209 cfg->name);
210
211 if (new_state == R_TPU_PIN_GPIO_FN)
212 gpio_request(cfg->pin_gpio_fn, cfg->name);
213
214 p->pin_state = new_state;
215}
216
217static void r_tpu_work(struct work_struct *work)
218{
219 struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work);
220 enum led_brightness brightness = p->new_brightness;
221
222 r_tpu_disable(p);
223
224 /* off and maximum are handled as GPIO pins, in between PWM */
225 if ((brightness == 0) || (brightness == p->ldev.max_brightness))
226 r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness);
227 else {
228 r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0);
229 r_tpu_enable(p, brightness);
230 }
231}
232
233static void r_tpu_set_brightness(struct led_classdev *ldev,
234 enum led_brightness brightness)
235{
236 struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev);
237 p->new_brightness = brightness;
238 schedule_work(&p->work);
239}
240
241static int r_tpu_probe(struct platform_device *pdev)
242{
243 struct led_renesas_tpu_config *cfg = pdev->dev.platform_data;
244 struct r_tpu_priv *p;
245 struct resource *res;
246 int ret;
247
248 if (!cfg) {
249 dev_err(&pdev->dev, "missing platform data\n");
250 return -ENODEV;
251 }
252
253 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
254 if (p == NULL) {
255 dev_err(&pdev->dev, "failed to allocate driver data\n");
256 return -ENOMEM;
257 }
258
259 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
260 if (!res) {
261 dev_err(&pdev->dev, "failed to get I/O memory\n");
262 return -ENXIO;
263 }
264
265 /* map memory, let mapbase point to our channel */
266 p->mapbase = devm_ioremap_nocache(&pdev->dev, res->start,
267 resource_size(res));
268 if (p->mapbase == NULL) {
269 dev_err(&pdev->dev, "failed to remap I/O memory\n");
270 return -ENXIO;
271 }
272
273 /* get hold of clock */
274 p->clk = devm_clk_get(&pdev->dev, NULL);
275 if (IS_ERR(p->clk)) {
276 dev_err(&pdev->dev, "cannot get clock\n");
277 return PTR_ERR(p->clk);
278 }
279
280 p->pdev = pdev;
281 p->pin_state = R_TPU_PIN_UNUSED;
282 p->timer_state = R_TPU_TIMER_UNUSED;
283 p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100;
284 r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF);
285 platform_set_drvdata(pdev, p);
286
287 INIT_WORK(&p->work, r_tpu_work);
288
289 p->ldev.name = cfg->name;
290 p->ldev.brightness = LED_OFF;
291 p->ldev.max_brightness = cfg->max_brightness;
292 p->ldev.brightness_set = r_tpu_set_brightness;
293 p->ldev.flags |= LED_CORE_SUSPENDRESUME;
294 ret = led_classdev_register(&pdev->dev, &p->ldev);
295 if (ret < 0)
296 goto err0;
297
298 /* max_brightness may be updated by the LED core code */
299 p->min_rate = p->ldev.max_brightness * p->refresh_rate;
300
301 pm_runtime_enable(&pdev->dev);
302 return 0;
303
304 err0:
305 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
306 return ret;
307}
308
309static int r_tpu_remove(struct platform_device *pdev)
310{
311 struct r_tpu_priv *p = platform_get_drvdata(pdev);
312
313 r_tpu_set_brightness(&p->ldev, LED_OFF);
314 led_classdev_unregister(&p->ldev);
315 cancel_work_sync(&p->work);
316 r_tpu_disable(p);
317 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
318
319 pm_runtime_disable(&pdev->dev);
320
321 return 0;
322}
323
324static struct platform_driver r_tpu_device_driver = {
325 .probe = r_tpu_probe,
326 .remove = r_tpu_remove,
327 .driver = {
328 .name = "leds-renesas-tpu",
329 }
330};
331
332module_platform_driver(r_tpu_device_driver);
333
334MODULE_AUTHOR("Magnus Damm");
335MODULE_DESCRIPTION("Renesas TPU LED Driver");
336MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index e1a0df63a37..a77771dc2e9 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -17,11 +17,10 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h>
21 20
22#include <mach/hardware.h> 21#include <mach/hardware.h>
23#include <mach/regs-gpio.h> 22#include <mach/regs-gpio.h>
24#include <linux/platform_data/leds-s3c24xx.h> 23#include <mach/leds-gpio.h>
25 24
26/* our context */ 25/* our context */
27 26
@@ -45,19 +44,17 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev,
45{ 44{
46 struct s3c24xx_gpio_led *led = to_gpio(led_cdev); 45 struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
47 struct s3c24xx_led_platdata *pd = led->pdata; 46 struct s3c24xx_led_platdata *pd = led->pdata;
48 int state = (value ? 1 : 0) ^ (pd->flags & S3C24XX_LEDF_ACTLOW);
49 47
50 /* there will be a short delay between setting the output and 48 /* there will be a short delay between setting the output and
51 * going from output to input when using tristate. */ 49 * going from output to input when using tristate. */
52 50
53 gpio_set_value(pd->gpio, state); 51 s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^
52 (pd->flags & S3C24XX_LEDF_ACTLOW));
53
54 if (pd->flags & S3C24XX_LEDF_TRISTATE)
55 s3c2410_gpio_cfgpin(pd->gpio,
56 value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);
54 57
55 if (pd->flags & S3C24XX_LEDF_TRISTATE) {
56 if (value)
57 gpio_direction_output(pd->gpio, state);
58 else
59 gpio_direction_input(pd->gpio);
60 }
61} 58}
62 59
63static int s3c24xx_led_remove(struct platform_device *dev) 60static int s3c24xx_led_remove(struct platform_device *dev)
@@ -65,6 +62,7 @@ static int s3c24xx_led_remove(struct platform_device *dev)
65 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); 62 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);
66 63
67 led_classdev_unregister(&led->cdev); 64 led_classdev_unregister(&led->cdev);
65 kfree(led);
68 66
69 return 0; 67 return 0;
70} 68}
@@ -75,8 +73,7 @@ static int s3c24xx_led_probe(struct platform_device *dev)
75 struct s3c24xx_gpio_led *led; 73 struct s3c24xx_gpio_led *led;
76 int ret; 74 int ret;
77 75
78 led = devm_kzalloc(&dev->dev, sizeof(struct s3c24xx_gpio_led), 76 led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);
79 GFP_KERNEL);
80 if (led == NULL) { 77 if (led == NULL) {
81 dev_err(&dev->dev, "No memory for device\n"); 78 dev_err(&dev->dev, "No memory for device\n");
82 return -ENOMEM; 79 return -ENOMEM;
@@ -91,27 +88,27 @@ static int s3c24xx_led_probe(struct platform_device *dev)
91 88
92 led->pdata = pdata; 89 led->pdata = pdata;
93 90
94 ret = devm_gpio_request(&dev->dev, pdata->gpio, "S3C24XX_LED");
95 if (ret < 0)
96 return ret;
97
98 /* no point in having a pull-up if we are always driving */ 91 /* no point in having a pull-up if we are always driving */
99 92
100 s3c_gpio_setpull(pdata->gpio, S3C_GPIO_PULL_NONE); 93 if (pdata->flags & S3C24XX_LEDF_TRISTATE) {
101 94 s3c2410_gpio_setpin(pdata->gpio, 0);
102 if (pdata->flags & S3C24XX_LEDF_TRISTATE) 95 s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT);
103 gpio_direction_input(pdata->gpio); 96 } else {
104 else 97 s3c2410_gpio_pullup(pdata->gpio, 0);
105 gpio_direction_output(pdata->gpio, 98 s3c2410_gpio_setpin(pdata->gpio, 0);
106 pdata->flags & S3C24XX_LEDF_ACTLOW ? 1 : 0); 99 s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT);
100 }
107 101
108 /* register our new led device */ 102 /* register our new led device */
109 103
110 ret = led_classdev_register(&dev->dev, &led->cdev); 104 ret = led_classdev_register(&dev->dev, &led->cdev);
111 if (ret < 0) 105 if (ret < 0) {
112 dev_err(&dev->dev, "led_classdev_register failed\n"); 106 dev_err(&dev->dev, "led_classdev_register failed\n");
107 kfree(led);
108 return ret;
109 }
113 110
114 return ret; 111 return 0;
115} 112}
116 113
117static struct platform_driver s3c24xx_led_driver = { 114static struct platform_driver s3c24xx_led_driver = {
@@ -123,7 +120,18 @@ static struct platform_driver s3c24xx_led_driver = {
123 }, 120 },
124}; 121};
125 122
126module_platform_driver(s3c24xx_led_driver); 123static int __init s3c24xx_led_init(void)
124{
125 return platform_driver_register(&s3c24xx_led_driver);
126}
127
128static void __exit s3c24xx_led_exit(void)
129{
130 platform_driver_unregister(&s3c24xx_led_driver);
131}
132
133module_init(s3c24xx_led_init);
134module_exit(s3c24xx_led_exit);
127 135
128MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 136MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
129MODULE_DESCRIPTION("S3C24XX LED driver"); 137MODULE_DESCRIPTION("S3C24XX LED driver");
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index ec9b287ecfb..614ebebaaa2 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -79,7 +79,7 @@ static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id)
79 return 1; 79 return 1;
80} 80}
81 81
82static bool __initdata nodetect; 82static unsigned int __initdata nodetect;
83module_param_named(nodetect, nodetect, bool, 0); 83module_param_named(nodetect, nodetect, bool, 0);
84MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); 84MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
85 85
@@ -263,7 +263,7 @@ static int nasgpio_led_set_blink(struct led_classdev *led_cdev,
263 * already taken care of this, but we will do so in a non destructive manner 263 * already taken care of this, but we will do so in a non destructive manner
264 * so that we have what we need whether the BIOS did it or not. 264 * so that we have what we need whether the BIOS did it or not.
265 */ 265 */
266static int ich7_gpio_init(struct device *dev) 266static int __devinit ich7_gpio_init(struct device *dev)
267{ 267{
268 int i; 268 int i;
269 u32 config_data = 0; 269 u32 config_data = 0;
@@ -342,7 +342,7 @@ static void ich7_lpc_cleanup(struct device *dev)
342 * so we can retrive the required operational information and prepare the GPIO. 342 * so we can retrive the required operational information and prepare the GPIO.
343 */ 343 */
344static struct pci_dev *nas_gpio_pci_dev; 344static struct pci_dev *nas_gpio_pci_dev;
345static int ich7_lpc_probe(struct pci_dev *dev, 345static int __devinit ich7_lpc_probe(struct pci_dev *dev,
346 const struct pci_device_id *id) 346 const struct pci_device_id *id)
347{ 347{
348 int status; 348 int status;
@@ -459,7 +459,7 @@ static ssize_t nas_led_blink_store(struct device *dev,
459 struct led_classdev *led = dev_get_drvdata(dev); 459 struct led_classdev *led = dev_get_drvdata(dev);
460 unsigned long blink_state; 460 unsigned long blink_state;
461 461
462 ret = kstrtoul(buf, 10, &blink_state); 462 ret = strict_strtoul(buf, 10, &blink_state);
463 if (ret) 463 if (ret)
464 return ret; 464 return ret;
465 465
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
index 07ff5a3a6ce..1757396b20b 100644
--- a/drivers/leds/leds-sunfire.c
+++ b/drivers/leds/leds-sunfire.c
@@ -123,7 +123,7 @@ struct sunfire_drvdata {
123 struct sunfire_led leds[NUM_LEDS_PER_BOARD]; 123 struct sunfire_led leds[NUM_LEDS_PER_BOARD];
124}; 124};
125 125
126static int sunfire_led_generic_probe(struct platform_device *pdev, 126static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
127 struct led_type *types) 127 struct led_type *types)
128{ 128{
129 struct sunfire_drvdata *p; 129 struct sunfire_drvdata *p;
@@ -132,13 +132,15 @@ static int sunfire_led_generic_probe(struct platform_device *pdev,
132 if (pdev->num_resources != 1) { 132 if (pdev->num_resources != 1) {
133 printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n", 133 printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n",
134 pdev->num_resources); 134 pdev->num_resources);
135 return -EINVAL; 135 err = -EINVAL;
136 goto out;
136 } 137 }
137 138
138 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 139 p = kzalloc(sizeof(*p), GFP_KERNEL);
139 if (!p) { 140 if (!p) {
140 printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n"); 141 printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n");
141 return -ENOMEM; 142 err = -ENOMEM;
143 goto out;
142 } 144 }
143 145
144 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) { 146 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) {
@@ -154,18 +156,23 @@ static int sunfire_led_generic_probe(struct platform_device *pdev,
154 if (err) { 156 if (err) {
155 printk(KERN_ERR PFX "Could not register %s LED\n", 157 printk(KERN_ERR PFX "Could not register %s LED\n",
156 lp->name); 158 lp->name);
157 for (i--; i >= 0; i--) 159 goto out_unregister_led_cdevs;
158 led_classdev_unregister(&p->leds[i].led_cdev);
159 return err;
160 } 160 }
161 } 161 }
162 162
163 dev_set_drvdata(&pdev->dev, p); 163 dev_set_drvdata(&pdev->dev, p);
164 164
165 return 0; 165 return 0;
166
167out_unregister_led_cdevs:
168 for (i--; i >= 0; i--)
169 led_classdev_unregister(&p->leds[i].led_cdev);
170 kfree(p);
171out:
172 return err;
166} 173}
167 174
168static int sunfire_led_generic_remove(struct platform_device *pdev) 175static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
169{ 176{
170 struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev); 177 struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev);
171 int i; 178 int i;
@@ -173,6 +180,8 @@ static int sunfire_led_generic_remove(struct platform_device *pdev)
173 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) 180 for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
174 led_classdev_unregister(&p->leds[i].led_cdev); 181 led_classdev_unregister(&p->leds[i].led_cdev);
175 182
183 kfree(p);
184
176 return 0; 185 return 0;
177} 186}
178 187
@@ -192,7 +201,7 @@ static struct led_type clockboard_led_types[NUM_LEDS_PER_BOARD] = {
192 }, 201 },
193}; 202};
194 203
195static int sunfire_clockboard_led_probe(struct platform_device *pdev) 204static int __devinit sunfire_clockboard_led_probe(struct platform_device *pdev)
196{ 205{
197 return sunfire_led_generic_probe(pdev, clockboard_led_types); 206 return sunfire_led_generic_probe(pdev, clockboard_led_types);
198} 207}
@@ -213,7 +222,7 @@ static struct led_type fhc_led_types[NUM_LEDS_PER_BOARD] = {
213 }, 222 },
214}; 223};
215 224
216static int sunfire_fhc_led_probe(struct platform_device *pdev) 225static int __devinit sunfire_fhc_led_probe(struct platform_device *pdev)
217{ 226{
218 return sunfire_led_generic_probe(pdev, fhc_led_types); 227 return sunfire_led_generic_probe(pdev, fhc_led_types);
219} 228}
@@ -223,7 +232,7 @@ MODULE_ALIAS("platform:sunfire-fhc-leds");
223 232
224static struct platform_driver sunfire_clockboard_led_driver = { 233static struct platform_driver sunfire_clockboard_led_driver = {
225 .probe = sunfire_clockboard_led_probe, 234 .probe = sunfire_clockboard_led_probe,
226 .remove = sunfire_led_generic_remove, 235 .remove = __devexit_p(sunfire_led_generic_remove),
227 .driver = { 236 .driver = {
228 .name = "sunfire-clockboard-leds", 237 .name = "sunfire-clockboard-leds",
229 .owner = THIS_MODULE, 238 .owner = THIS_MODULE,
@@ -232,7 +241,7 @@ static struct platform_driver sunfire_clockboard_led_driver = {
232 241
233static struct platform_driver sunfire_fhc_led_driver = { 242static struct platform_driver sunfire_fhc_led_driver = {
234 .probe = sunfire_fhc_led_probe, 243 .probe = sunfire_fhc_led_probe,
235 .remove = sunfire_led_generic_remove, 244 .remove = __devexit_p(sunfire_led_generic_remove),
236 .driver = { 245 .driver = {
237 .name = "sunfire-fhc-leds", 246 .name = "sunfire-fhc-leds",
238 .owner = THIS_MODULE, 247 .owner = THIS_MODULE,
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
deleted file mode 100644
index b26a63bae16..00000000000
--- a/drivers/leds/leds-tca6507.c
+++ /dev/null
@@ -1,763 +0,0 @@
1/*
2 * leds-tca6507
3 *
4 * The TCA6507 is a programmable LED controller that can drive 7
5 * separate lines either by holding them low, or by pulsing them
6 * with modulated width.
7 * The modulation can be varied in a simple pattern to produce a blink or
8 * double-blink.
9 *
10 * This driver can configure each line either as a 'GPIO' which is out-only
11 * (no pull-up) or as an LED with variable brightness and hardware-assisted
12 * blinking.
13 *
14 * Apart from OFF and ON there are three programmable brightness levels which
15 * can be programmed from 0 to 15 and indicate how many 500usec intervals in
16 * each 8msec that the led is 'on'. The levels are named MASTER, BANK0 and
17 * BANK1.
18 *
19 * There are two different blink rates that can be programmed, each with
20 * separate time for rise, on, fall, off and second-off. Thus if 3 or more
21 * different non-trivial rates are required, software must be used for the extra
22 * rates. The two different blink rates must align with the two levels BANK0 and
23 * BANK1.
24 * This driver does not support double-blink so 'second-off' always matches
25 * 'off'.
26 *
27 * Only 16 different times can be programmed in a roughly logarithmic scale from
28 * 64ms to 16320ms. To be precise the possible times are:
29 * 0, 64, 128, 192, 256, 384, 512, 768,
30 * 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
31 *
32 * Times that cannot be closely matched with these must be
33 * handled in software. This driver allows 12.5% error in matching.
34 *
35 * This driver does not allow rise/fall rates to be set explicitly. When trying
36 * to match a given 'on' or 'off' period, an appropriate pair of 'change' and
37 * 'hold' times are chosen to get a close match. If the target delay is even,
38 * the 'change' number will be the smaller; if odd, the 'hold' number will be
39 * the smaller.
40
41 * Choosing pairs of delays with 12.5% errors allows us to match delays in the
42 * ranges: 56-72, 112-144, 168-216, 224-27504, 28560-36720.
43 * 26% of the achievable sums can be matched by multiple pairings. For example
44 * 1536 == 1536+0, 1024+512, or 768+768. This driver will always choose the
45 * pairing with the least maximum - 768+768 in this case. Other pairings are
46 * not available.
47 *
48 * Access to the 3 levels and 2 blinks are on a first-come, first-served basis.
49 * Access can be shared by multiple leds if they have the same level and
50 * either same blink rates, or some don't blink.
51 * When a led changes, it relinquishes access and tries again, so it might
52 * lose access to hardware blink.
53 * If a blink engine cannot be allocated, software blink is used.
54 * If the desired brightness cannot be allocated, the closest available non-zero
55 * brightness is used. As 'full' is always available, the worst case would be
56 * to have two different blink rates at '1', with Max at '2', then other leds
57 * will have to choose between '2' and '16'. Hopefully this is not likely.
58 *
59 * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the brightness
60 * and LEDs using the blink. It can only be reprogrammed when the appropriate
61 * counter is zero. The MASTER level has a single usage count.
62 *
63 * Each Led has programmable 'on' and 'off' time as milliseconds. With each
64 * there is a flag saying if it was explicitly requested or defaulted.
65 * Similarly the banks know if each time was explicit or a default. Defaults
66 * are permitted to be changed freely - they are not recognised when matching.
67 *
68 *
69 * An led-tca6507 device must be provided with platform data. This data
70 * lists for each output: the name, default trigger, and whether the signal
71 * is being used as a GPiO rather than an led. 'struct led_plaform_data'
72 * is used for this. If 'name' is NULL, the output isn't used. If 'flags'
73 * is TCA6507_MAKE_CPIO, the output is a GPO.
74 * The "struct led_platform_data" can be embedded in a
75 * "struct tca6507_platform_data" which adds a 'gpio_base' for the GPiOs,
76 * and a 'setup' callback which is called once the GPiOs are available.
77 *
78 */
79
80#include <linux/module.h>
81#include <linux/slab.h>
82#include <linux/leds.h>
83#include <linux/err.h>
84#include <linux/i2c.h>
85#include <linux/gpio.h>
86#include <linux/workqueue.h>
87#include <linux/leds-tca6507.h>
88
89/* 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_OFF1 0x1 /* Output HI-Z (off) - not used */
92#define TCA6507_LS_LED_PWM0 0x2 /* Output LOW with Bank0 rate */
93#define TCA6507_LS_LED_PWM1 0x3 /* Output LOW with Bank1 rate */
94#define TCA6507_LS_LED_ON 0x4 /* Output LOW (on) */
95#define TCA6507_LS_LED_MIR 0x5 /* Output LOW with Master Intensity */
96#define TCA6507_LS_BLINK0 0x6 /* Blink at Bank0 rate */
97#define TCA6507_LS_BLINK1 0x7 /* Blink at Bank1 rate */
98
99enum {
100 BANK0,
101 BANK1,
102 MASTER,
103};
104static int bank_source[3] = {
105 TCA6507_LS_LED_PWM0,
106 TCA6507_LS_LED_PWM1,
107 TCA6507_LS_LED_MIR,
108};
109static int blink_source[2] = {
110 TCA6507_LS_BLINK0,
111 TCA6507_LS_BLINK1,
112};
113
114/* PWM registers */
115#define TCA6507_REG_CNT 11
116
117/*
118 * 0x00, 0x01, 0x02 encode the TCA6507_LS_* values, each output
119 * owns one bit in each register
120 */
121#define TCA6507_FADE_ON 0x03
122#define TCA6507_FULL_ON 0x04
123#define TCA6507_FADE_OFF 0x05
124#define TCA6507_FIRST_OFF 0x06
125#define TCA6507_SECOND_OFF 0x07
126#define TCA6507_MAX_INTENSITY 0x08
127#define TCA6507_MASTER_INTENSITY 0x09
128#define TCA6507_INITIALIZE 0x0A
129
130#define INIT_CODE 0x8
131
132#define TIMECODES 16
133static int time_codes[TIMECODES] = {
134 0, 64, 128, 192, 256, 384, 512, 768,
135 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
136};
137
138/* Convert an led.brightness level (0..255) to a TCA6507 level (0..15) */
139static inline int TO_LEVEL(int brightness)
140{
141 return brightness >> 4;
142}
143
144/* ...and convert back */
145static inline int TO_BRIGHT(int level)
146{
147 if (level)
148 return (level << 4) | 0xf;
149 return 0;
150}
151
152#define NUM_LEDS 7
153struct tca6507_chip {
154 int reg_set; /* One bit per register where
155 * a '1' means the register
156 * should be written */
157 u8 reg_file[TCA6507_REG_CNT];
158 /* Bank 2 is Master Intensity and doesn't use times */
159 struct bank {
160 int level;
161 int ontime, offtime;
162 int on_dflt, off_dflt;
163 int time_use, level_use;
164 } bank[3];
165 struct i2c_client *client;
166 struct work_struct work;
167 spinlock_t lock;
168
169 struct tca6507_led {
170 struct tca6507_chip *chip;
171 struct led_classdev led_cdev;
172 int num;
173 int ontime, offtime;
174 int on_dflt, off_dflt;
175 int bank; /* Bank used, or -1 */
176 int blink; /* Set if hardware-blinking */
177 } leds[NUM_LEDS];
178#ifdef CONFIG_GPIOLIB
179 struct gpio_chip gpio;
180 const char *gpio_name[NUM_LEDS];
181 int gpio_map[NUM_LEDS];
182#endif
183};
184
185static const struct i2c_device_id tca6507_id[] = {
186 { "tca6507" },
187 { }
188};
189MODULE_DEVICE_TABLE(i2c, tca6507_id);
190
191static int choose_times(int msec, int *c1p, int *c2p)
192{
193 /*
194 * Choose two timecodes which add to 'msec' as near as possible.
195 * The first returned is the 'on' or 'off' time. The second is to be
196 * used as a 'fade-on' or 'fade-off' time. If 'msec' is even,
197 * the first will not be smaller than the second. If 'msec' is odd,
198 * the first will not be larger than the second.
199 * If we cannot get a sum within 1/8 of 'msec' fail with -EINVAL,
200 * otherwise return the sum that was achieved, plus 1 if the first is
201 * smaller.
202 * If two possibilities are equally good (e.g. 512+0, 256+256), choose
203 * the first pair so there is more change-time visible (i.e. it is
204 * softer).
205 */
206 int c1, c2;
207 int tmax = msec * 9 / 8;
208 int tmin = msec * 7 / 8;
209 int diff = 65536;
210
211 /* We start at '1' to ensure we never even think of choosing a
212 * total time of '0'.
213 */
214 for (c1 = 1; c1 < TIMECODES; c1++) {
215 int t = time_codes[c1];
216 if (t*2 < tmin)
217 continue;
218 if (t > tmax)
219 break;
220 for (c2 = 0; c2 <= c1; c2++) {
221 int tt = t + time_codes[c2];
222 int d;
223 if (tt < tmin)
224 continue;
225 if (tt > tmax)
226 break;
227 /* This works! */
228 d = abs(msec - tt);
229 if (d >= diff)
230 continue;
231 /* Best yet */
232 *c1p = c1;
233 *c2p = c2;
234 diff = d;
235 if (d == 0)
236 return msec;
237 }
238 }
239 if (diff < 65536) {
240 int actual;
241 if (msec & 1) {
242 c1 = *c2p;
243 *c2p = *c1p;
244 *c1p = c1;
245 }
246 actual = time_codes[*c1p] + time_codes[*c2p];
247 if (*c1p < *c2p)
248 return actual + 1;
249 else
250 return actual;
251 }
252 /* No close match */
253 return -EINVAL;
254}
255
256/*
257 * Update the register file with the appropriate 3-bit state for
258 * the given led.
259 */
260static void set_select(struct tca6507_chip *tca, int led, int val)
261{
262 int mask = (1 << led);
263 int bit;
264
265 for (bit = 0; bit < 3; bit++) {
266 int n = tca->reg_file[bit] & ~mask;
267 if (val & (1 << bit))
268 n |= mask;
269 if (tca->reg_file[bit] != n) {
270 tca->reg_file[bit] = n;
271 tca->reg_set |= (1 << bit);
272 }
273 }
274}
275
276/* Update the register file with the appropriate 4-bit code for
277 * one bank or other. This can be used for timers, for levels, or
278 * for initialisation.
279 */
280static void set_code(struct tca6507_chip *tca, int reg, int bank, int new)
281{
282 int mask = 0xF;
283 int n;
284 if (bank) {
285 mask <<= 4;
286 new <<= 4;
287 }
288 n = tca->reg_file[reg] & ~mask;
289 n |= new;
290 if (tca->reg_file[reg] != n) {
291 tca->reg_file[reg] = n;
292 tca->reg_set |= 1 << reg;
293 }
294}
295
296/* Update brightness level. */
297static void set_level(struct tca6507_chip *tca, int bank, int level)
298{
299 switch (bank) {
300 case BANK0:
301 case BANK1:
302 set_code(tca, TCA6507_MAX_INTENSITY, bank, level);
303 break;
304 case MASTER:
305 set_code(tca, TCA6507_MASTER_INTENSITY, 0, level);
306 break;
307 }
308 tca->bank[bank].level = level;
309}
310
311/* Record all relevant time code for a given bank */
312static void set_times(struct tca6507_chip *tca, int bank)
313{
314 int c1, c2;
315 int result;
316
317 result = choose_times(tca->bank[bank].ontime, &c1, &c2);
318 dev_dbg(&tca->client->dev,
319 "Chose on times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
320 c2, time_codes[c2], tca->bank[bank].ontime);
321 set_code(tca, TCA6507_FADE_ON, bank, c2);
322 set_code(tca, TCA6507_FULL_ON, bank, c1);
323 tca->bank[bank].ontime = result;
324
325 result = choose_times(tca->bank[bank].offtime, &c1, &c2);
326 dev_dbg(&tca->client->dev,
327 "Chose off times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
328 c2, time_codes[c2], tca->bank[bank].offtime);
329 set_code(tca, TCA6507_FADE_OFF, bank, c2);
330 set_code(tca, TCA6507_FIRST_OFF, bank, c1);
331 set_code(tca, TCA6507_SECOND_OFF, bank, c1);
332 tca->bank[bank].offtime = result;
333
334 set_code(tca, TCA6507_INITIALIZE, bank, INIT_CODE);
335}
336
337/* Write all needed register of tca6507 */
338
339static void tca6507_work(struct work_struct *work)
340{
341 struct tca6507_chip *tca = container_of(work, struct tca6507_chip,
342 work);
343 struct i2c_client *cl = tca->client;
344 int set;
345 u8 file[TCA6507_REG_CNT];
346 int r;
347
348 spin_lock_irq(&tca->lock);
349 set = tca->reg_set;
350 memcpy(file, tca->reg_file, TCA6507_REG_CNT);
351 tca->reg_set = 0;
352 spin_unlock_irq(&tca->lock);
353
354 for (r = 0; r < TCA6507_REG_CNT; r++)
355 if (set & (1<<r))
356 i2c_smbus_write_byte_data(cl, r, file[r]);
357}
358
359static void led_release(struct tca6507_led *led)
360{
361 /* If led owns any resource, release it. */
362 struct tca6507_chip *tca = led->chip;
363 if (led->bank >= 0) {
364 struct bank *b = tca->bank + led->bank;
365 if (led->blink)
366 b->time_use--;
367 b->level_use--;
368 }
369 led->blink = 0;
370 led->bank = -1;
371}
372
373static int led_prepare(struct tca6507_led *led)
374{
375 /* Assign this led to a bank, configuring that bank if necessary. */
376 int level = TO_LEVEL(led->led_cdev.brightness);
377 struct tca6507_chip *tca = led->chip;
378 int c1, c2;
379 int i;
380 struct bank *b;
381 int need_init = 0;
382
383 led->led_cdev.brightness = TO_BRIGHT(level);
384 if (level == 0) {
385 set_select(tca, led->num, TCA6507_LS_LED_OFF);
386 return 0;
387 }
388
389 if (led->ontime == 0 || led->offtime == 0) {
390 /*
391 * Just set the brightness, choosing first usable bank.
392 * If none perfect, choose best.
393 * Count backwards so we check MASTER bank first
394 * to avoid wasting a timer.
395 */
396 int best = -1;/* full-on */
397 int diff = 15-level;
398
399 if (level == 15) {
400 set_select(tca, led->num, TCA6507_LS_LED_ON);
401 return 0;
402 }
403
404 for (i = MASTER; i >= BANK0; i--) {
405 int d;
406 if (tca->bank[i].level == level ||
407 tca->bank[i].level_use == 0) {
408 best = i;
409 break;
410 }
411 d = abs(level - tca->bank[i].level);
412 if (d < diff) {
413 diff = d;
414 best = i;
415 }
416 }
417 if (best == -1) {
418 /* Best brightness is full-on */
419 set_select(tca, led->num, TCA6507_LS_LED_ON);
420 led->led_cdev.brightness = LED_FULL;
421 return 0;
422 }
423
424 if (!tca->bank[best].level_use)
425 set_level(tca, best, level);
426
427 tca->bank[best].level_use++;
428 led->bank = best;
429 set_select(tca, led->num, bank_source[best]);
430 led->led_cdev.brightness = TO_BRIGHT(tca->bank[best].level);
431 return 0;
432 }
433
434 /*
435 * We have on/off time so we need to try to allocate a timing bank.
436 * First check if times are compatible with hardware and give up if
437 * not.
438 */
439 if (choose_times(led->ontime, &c1, &c2) < 0)
440 return -EINVAL;
441 if (choose_times(led->offtime, &c1, &c2) < 0)
442 return -EINVAL;
443
444 for (i = BANK0; i <= BANK1; i++) {
445 if (tca->bank[i].level_use == 0)
446 /* not in use - it is ours! */
447 break;
448 if (tca->bank[i].level != level)
449 /* Incompatible level - skip */
450 /* FIX: if timer matches we maybe should consider
451 * this anyway...
452 */
453 continue;
454
455 if (tca->bank[i].time_use == 0)
456 /* Timer not in use, and level matches - use it */
457 break;
458
459 if (!(tca->bank[i].on_dflt ||
460 led->on_dflt ||
461 tca->bank[i].ontime == led->ontime))
462 /* on time is incompatible */
463 continue;
464
465 if (!(tca->bank[i].off_dflt ||
466 led->off_dflt ||
467 tca->bank[i].offtime == led->offtime))
468 /* off time is incompatible */
469 continue;
470
471 /* looks like a suitable match */
472 break;
473 }
474
475 if (i > BANK1)
476 /* Nothing matches - how sad */
477 return -EINVAL;
478
479 b = &tca->bank[i];
480 if (b->level_use == 0)
481 set_level(tca, i, level);
482 b->level_use++;
483 led->bank = i;
484
485 if (b->on_dflt ||
486 !led->on_dflt ||
487 b->time_use == 0) {
488 b->ontime = led->ontime;
489 b->on_dflt = led->on_dflt;
490 need_init = 1;
491 }
492
493 if (b->off_dflt ||
494 !led->off_dflt ||
495 b->time_use == 0) {
496 b->offtime = led->offtime;
497 b->off_dflt = led->off_dflt;
498 need_init = 1;
499 }
500
501 if (need_init)
502 set_times(tca, i);
503
504 led->ontime = b->ontime;
505 led->offtime = b->offtime;
506
507 b->time_use++;
508 led->blink = 1;
509 led->led_cdev.brightness = TO_BRIGHT(b->level);
510 set_select(tca, led->num, blink_source[i]);
511 return 0;
512}
513
514static int led_assign(struct tca6507_led *led)
515{
516 struct tca6507_chip *tca = led->chip;
517 int err;
518 unsigned long flags;
519
520 spin_lock_irqsave(&tca->lock, flags);
521 led_release(led);
522 err = led_prepare(led);
523 if (err) {
524 /*
525 * Can only fail on timer setup. In that case we need to
526 * re-establish as steady level.
527 */
528 led->ontime = 0;
529 led->offtime = 0;
530 led_prepare(led);
531 }
532 spin_unlock_irqrestore(&tca->lock, flags);
533
534 if (tca->reg_set)
535 schedule_work(&tca->work);
536 return err;
537}
538
539static void tca6507_brightness_set(struct led_classdev *led_cdev,
540 enum led_brightness brightness)
541{
542 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
543 led_cdev);
544 led->led_cdev.brightness = brightness;
545 led->ontime = 0;
546 led->offtime = 0;
547 led_assign(led);
548}
549
550static int tca6507_blink_set(struct led_classdev *led_cdev,
551 unsigned long *delay_on,
552 unsigned long *delay_off)
553{
554 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
555 led_cdev);
556
557 if (*delay_on == 0)
558 led->on_dflt = 1;
559 else if (delay_on != &led_cdev->blink_delay_on)
560 led->on_dflt = 0;
561 led->ontime = *delay_on;
562
563 if (*delay_off == 0)
564 led->off_dflt = 1;
565 else if (delay_off != &led_cdev->blink_delay_off)
566 led->off_dflt = 0;
567 led->offtime = *delay_off;
568
569 if (led->ontime == 0)
570 led->ontime = 512;
571 if (led->offtime == 0)
572 led->offtime = 512;
573
574 if (led->led_cdev.brightness == LED_OFF)
575 led->led_cdev.brightness = LED_FULL;
576 if (led_assign(led) < 0) {
577 led->ontime = 0;
578 led->offtime = 0;
579 led->led_cdev.brightness = LED_OFF;
580 return -EINVAL;
581 }
582 *delay_on = led->ontime;
583 *delay_off = led->offtime;
584 return 0;
585}
586
587#ifdef CONFIG_GPIOLIB
588static void tca6507_gpio_set_value(struct gpio_chip *gc,
589 unsigned offset, int val)
590{
591 struct tca6507_chip *tca = container_of(gc, struct tca6507_chip, gpio);
592 unsigned long flags;
593
594 spin_lock_irqsave(&tca->lock, flags);
595 /*
596 * 'OFF' is floating high, and 'ON' is pulled down, so it has the
597 * inverse sense of 'val'.
598 */
599 set_select(tca, tca->gpio_map[offset],
600 val ? TCA6507_LS_LED_OFF : TCA6507_LS_LED_ON);
601 spin_unlock_irqrestore(&tca->lock, flags);
602 if (tca->reg_set)
603 schedule_work(&tca->work);
604}
605
606static int tca6507_gpio_direction_output(struct gpio_chip *gc,
607 unsigned offset, int val)
608{
609 tca6507_gpio_set_value(gc, offset, val);
610 return 0;
611}
612
613static int tca6507_probe_gpios(struct i2c_client *client,
614 struct tca6507_chip *tca,
615 struct tca6507_platform_data *pdata)
616{
617 int err;
618 int i = 0;
619 int gpios = 0;
620
621 for (i = 0; i < NUM_LEDS; i++)
622 if (pdata->leds.leds[i].name && pdata->leds.leds[i].flags) {
623 /* Configure as a gpio */
624 tca->gpio_name[gpios] = pdata->leds.leds[i].name;
625 tca->gpio_map[gpios] = i;
626 gpios++;
627 }
628
629 if (!gpios)
630 return 0;
631
632 tca->gpio.label = "gpio-tca6507";
633 tca->gpio.names = tca->gpio_name;
634 tca->gpio.ngpio = gpios;
635 tca->gpio.base = pdata->gpio_base;
636 tca->gpio.owner = THIS_MODULE;
637 tca->gpio.direction_output = tca6507_gpio_direction_output;
638 tca->gpio.set = tca6507_gpio_set_value;
639 tca->gpio.dev = &client->dev;
640 err = gpiochip_add(&tca->gpio);
641 if (err) {
642 tca->gpio.ngpio = 0;
643 return err;
644 }
645 if (pdata->setup)
646 pdata->setup(tca->gpio.base, tca->gpio.ngpio);
647 return 0;
648}
649
650static void tca6507_remove_gpio(struct tca6507_chip *tca)
651{
652 if (tca->gpio.ngpio) {
653 int err = gpiochip_remove(&tca->gpio);
654 dev_err(&tca->client->dev, "%s failed, %d\n",
655 "gpiochip_remove()", err);
656 }
657}
658#else /* CONFIG_GPIOLIB */
659static int tca6507_probe_gpios(struct i2c_client *client,
660 struct tca6507_chip *tca,
661 struct tca6507_platform_data *pdata)
662{
663 return 0;
664}
665static void tca6507_remove_gpio(struct tca6507_chip *tca)
666{
667}
668#endif /* CONFIG_GPIOLIB */
669
670static int tca6507_probe(struct i2c_client *client,
671 const struct i2c_device_id *id)
672{
673 struct tca6507_chip *tca;
674 struct i2c_adapter *adapter;
675 struct tca6507_platform_data *pdata;
676 int err;
677 int i = 0;
678
679 adapter = to_i2c_adapter(client->dev.parent);
680 pdata = client->dev.platform_data;
681
682 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
683 return -EIO;
684
685 if (!pdata || pdata->leds.num_leds != NUM_LEDS) {
686 dev_err(&client->dev, "Need %d entries in platform-data list\n",
687 NUM_LEDS);
688 return -ENODEV;
689 }
690 tca = devm_kzalloc(&client->dev, sizeof(*tca), GFP_KERNEL);
691 if (!tca)
692 return -ENOMEM;
693
694 tca->client = client;
695 INIT_WORK(&tca->work, tca6507_work);
696 spin_lock_init(&tca->lock);
697 i2c_set_clientdata(client, tca);
698
699 for (i = 0; i < NUM_LEDS; i++) {
700 struct tca6507_led *l = tca->leds + i;
701
702 l->chip = tca;
703 l->num = i;
704 if (pdata->leds.leds[i].name && !pdata->leds.leds[i].flags) {
705 l->led_cdev.name = pdata->leds.leds[i].name;
706 l->led_cdev.default_trigger
707 = pdata->leds.leds[i].default_trigger;
708 l->led_cdev.brightness_set = tca6507_brightness_set;
709 l->led_cdev.blink_set = tca6507_blink_set;
710 l->bank = -1;
711 err = led_classdev_register(&client->dev,
712 &l->led_cdev);
713 if (err < 0)
714 goto exit;
715 }
716 }
717 err = tca6507_probe_gpios(client, tca, pdata);
718 if (err)
719 goto exit;
720 /* set all registers to known state - zero */
721 tca->reg_set = 0x7f;
722 schedule_work(&tca->work);
723
724 return 0;
725exit:
726 while (i--) {
727 if (tca->leds[i].led_cdev.name)
728 led_classdev_unregister(&tca->leds[i].led_cdev);
729 }
730 return err;
731}
732
733static int tca6507_remove(struct i2c_client *client)
734{
735 int i;
736 struct tca6507_chip *tca = i2c_get_clientdata(client);
737 struct tca6507_led *tca_leds = tca->leds;
738
739 for (i = 0; i < NUM_LEDS; i++) {
740 if (tca_leds[i].led_cdev.name)
741 led_classdev_unregister(&tca_leds[i].led_cdev);
742 }
743 tca6507_remove_gpio(tca);
744 cancel_work_sync(&tca->work);
745
746 return 0;
747}
748
749static struct i2c_driver tca6507_driver = {
750 .driver = {
751 .name = "leds-tca6507",
752 .owner = THIS_MODULE,
753 },
754 .probe = tca6507_probe,
755 .remove = tca6507_remove,
756 .id_table = tca6507_id,
757};
758
759module_i2c_driver(tca6507_driver);
760
761MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
762MODULE_DESCRIPTION("TCA6507 LED/GPO driver");
763MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index 74a24cf897c..ef5c24140a4 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -18,7 +18,6 @@
18#include <linux/mfd/wm831x/core.h> 18#include <linux/mfd/wm831x/core.h>
19#include <linux/mfd/wm831x/pdata.h> 19#include <linux/mfd/wm831x/pdata.h>
20#include <linux/mfd/wm831x/status.h> 20#include <linux/mfd/wm831x/status.h>
21#include <linux/module.h>
22 21
23 22
24struct wm831x_status { 23struct wm831x_status {
@@ -237,8 +236,7 @@ static int wm831x_status_probe(struct platform_device *pdev)
237 goto err; 236 goto err;
238 } 237 }
239 238
240 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status), 239 drvdata = kzalloc(sizeof(struct wm831x_status), GFP_KERNEL);
241 GFP_KERNEL);
242 if (!drvdata) 240 if (!drvdata)
243 return -ENOMEM; 241 return -ENOMEM;
244 dev_set_drvdata(&pdev->dev, drvdata); 242 dev_set_drvdata(&pdev->dev, drvdata);
@@ -301,6 +299,7 @@ static int wm831x_status_probe(struct platform_device *pdev)
301 299
302err_led: 300err_led:
303 led_classdev_unregister(&drvdata->cdev); 301 led_classdev_unregister(&drvdata->cdev);
302 kfree(drvdata);
304err: 303err:
305 return ret; 304 return ret;
306} 305}
@@ -311,6 +310,7 @@ static int wm831x_status_remove(struct platform_device *pdev)
311 310
312 device_remove_file(drvdata->cdev.dev, &dev_attr_src); 311 device_remove_file(drvdata->cdev.dev, &dev_attr_src);
313 led_classdev_unregister(&drvdata->cdev); 312 led_classdev_unregister(&drvdata->cdev);
313 kfree(drvdata);
314 314
315 return 0; 315 return 0;
316} 316}
@@ -324,7 +324,17 @@ static struct platform_driver wm831x_status_driver = {
324 .remove = wm831x_status_remove, 324 .remove = wm831x_status_remove,
325}; 325};
326 326
327module_platform_driver(wm831x_status_driver); 327static int __devinit wm831x_status_init(void)
328{
329 return platform_driver_register(&wm831x_status_driver);
330}
331module_init(wm831x_status_init);
332
333static void wm831x_status_exit(void)
334{
335 platform_driver_unregister(&wm831x_status_driver);
336}
337module_exit(wm831x_status_exit);
328 338
329MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 339MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
330MODULE_DESCRIPTION("WM831x status LED driver"); 340MODULE_DESCRIPTION("WM831x status LED driver");
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index ed15157c8f6..f14edd82cb0 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -17,7 +17,6 @@
17#include <linux/mfd/wm8350/pmic.h> 17#include <linux/mfd/wm8350/pmic.h>
18#include <linux/regulator/consumer.h> 18#include <linux/regulator/consumer.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h>
21 20
22/* Microamps */ 21/* Microamps */
23static const int isink_cur[] = { 22static const int isink_cur[] = {
@@ -201,7 +200,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
201 struct regulator *isink, *dcdc; 200 struct regulator *isink, *dcdc;
202 struct wm8350_led *led; 201 struct wm8350_led *led;
203 struct wm8350_led_platform_data *pdata = pdev->dev.platform_data; 202 struct wm8350_led_platform_data *pdata = pdev->dev.platform_data;
204 int i; 203 int ret, i;
205 204
206 if (pdata == NULL) { 205 if (pdata == NULL) {
207 dev_err(&pdev->dev, "no platform data\n"); 206 dev_err(&pdev->dev, "no platform data\n");
@@ -214,21 +213,24 @@ static int wm8350_led_probe(struct platform_device *pdev)
214 return -EINVAL; 213 return -EINVAL;
215 } 214 }
216 215
217 isink = devm_regulator_get(&pdev->dev, "led_isink"); 216 isink = regulator_get(&pdev->dev, "led_isink");
218 if (IS_ERR(isink)) { 217 if (IS_ERR(isink)) {
219 dev_err(&pdev->dev, "%s: can't get ISINK\n", __func__); 218 printk(KERN_ERR "%s: can't get ISINK\n", __func__);
220 return PTR_ERR(isink); 219 return PTR_ERR(isink);
221 } 220 }
222 221
223 dcdc = devm_regulator_get(&pdev->dev, "led_vcc"); 222 dcdc = regulator_get(&pdev->dev, "led_vcc");
224 if (IS_ERR(dcdc)) { 223 if (IS_ERR(dcdc)) {
225 dev_err(&pdev->dev, "%s: can't get DCDC\n", __func__); 224 printk(KERN_ERR "%s: can't get DCDC\n", __func__);
226 return PTR_ERR(dcdc); 225 ret = PTR_ERR(dcdc);
226 goto err_isink;
227 } 227 }
228 228
229 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 229 led = kzalloc(sizeof(*led), GFP_KERNEL);
230 if (led == NULL) 230 if (led == NULL) {
231 return -ENOMEM; 231 ret = -ENOMEM;
232 goto err_dcdc;
233 }
232 234
233 led->cdev.brightness_set = wm8350_led_set; 235 led->cdev.brightness_set = wm8350_led_set;
234 led->cdev.default_trigger = pdata->default_trigger; 236 led->cdev.default_trigger = pdata->default_trigger;
@@ -254,7 +256,19 @@ static int wm8350_led_probe(struct platform_device *pdev)
254 led->value = LED_OFF; 256 led->value = LED_OFF;
255 platform_set_drvdata(pdev, led); 257 platform_set_drvdata(pdev, led);
256 258
257 return led_classdev_register(&pdev->dev, &led->cdev); 259 ret = led_classdev_register(&pdev->dev, &led->cdev);
260 if (ret < 0)
261 goto err_led;
262
263 return 0;
264
265 err_led:
266 kfree(led);
267 err_dcdc:
268 regulator_put(dcdc);
269 err_isink:
270 regulator_put(isink);
271 return ret;
258} 272}
259 273
260static int wm8350_led_remove(struct platform_device *pdev) 274static int wm8350_led_remove(struct platform_device *pdev)
@@ -262,8 +276,11 @@ static int wm8350_led_remove(struct platform_device *pdev)
262 struct wm8350_led *led = platform_get_drvdata(pdev); 276 struct wm8350_led *led = platform_get_drvdata(pdev);
263 277
264 led_classdev_unregister(&led->cdev); 278 led_classdev_unregister(&led->cdev);
265 flush_work(&led->work); 279 flush_work_sync(&led->work);
266 wm8350_led_disable(led); 280 wm8350_led_disable(led);
281 regulator_put(led->dcdc);
282 regulator_put(led->isink);
283 kfree(led);
267 return 0; 284 return 0;
268} 285}
269 286
@@ -277,7 +294,17 @@ static struct platform_driver wm8350_led_driver = {
277 .shutdown = wm8350_led_shutdown, 294 .shutdown = wm8350_led_shutdown,
278}; 295};
279 296
280module_platform_driver(wm8350_led_driver); 297static int __devinit wm8350_led_init(void)
298{
299 return platform_driver_register(&wm8350_led_driver);
300}
301module_init(wm8350_led_init);
302
303static void wm8350_led_exit(void)
304{
305 platform_driver_unregister(&wm8350_led_driver);
306}
307module_exit(wm8350_led_exit);
281 308
282MODULE_AUTHOR("Mark Brown"); 309MODULE_AUTHOR("Mark Brown");
283MODULE_DESCRIPTION("WM8350 LED driver"); 310MODULE_DESCRIPTION("WM8350 LED driver");
diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c
index b358cc05eff..2982c86ac4c 100644
--- a/drivers/leds/leds-wrap.c
+++ b/drivers/leds/leds-wrap.c
@@ -15,9 +15,8 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/leds.h> 16#include <linux/leds.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/io.h> 18#include <asm/io.h>
19#include <linux/scx200_gpio.h> 19#include <linux/scx200_gpio.h>
20#include <linux/module.h>
21 20
22#define DRVNAME "wrap-led" 21#define DRVNAME "wrap-led"
23#define WRAP_POWER_LED_GPIO 2 22#define WRAP_POWER_LED_GPIO 2
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 4c50365344a..e77c7f8dcdd 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -17,7 +17,7 @@
17#include <linux/rwsem.h> 17#include <linux/rwsem.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19 19
20static inline void __led_set_brightness(struct led_classdev *led_cdev, 20static inline void led_set_brightness(struct led_classdev *led_cdev,
21 enum led_brightness value) 21 enum led_brightness value)
22{ 22{
23 if (value > led_cdev->max_brightness) 23 if (value > led_cdev->max_brightness)
@@ -32,8 +32,6 @@ static inline int led_get_brightness(struct led_classdev *led_cdev)
32 return led_cdev->brightness; 32 return led_cdev->brightness;
33} 33}
34 34
35void led_stop_software_blink(struct led_classdev *led_cdev);
36
37extern struct rw_semaphore leds_list_lock; 35extern struct rw_semaphore leds_list_lock;
38extern struct list_head leds_list; 36extern struct list_head leds_list;
39 37
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c
index 027a2b15d7d..2b513a2ad7d 100644
--- a/drivers/leds/ledtrig-backlight.c
+++ b/drivers/leds/ledtrig-backlight.c
@@ -40,15 +40,15 @@ static int fb_notifier_callback(struct notifier_block *p,
40 int new_status = *blank ? BLANK : UNBLANK; 40 int new_status = *blank ? BLANK : UNBLANK;
41 41
42 switch (event) { 42 switch (event) {
43 case FB_EVENT_BLANK: 43 case FB_EVENT_BLANK :
44 if (new_status == n->old_status) 44 if (new_status == n->old_status)
45 break; 45 break;
46 46
47 if ((n->old_status == UNBLANK) ^ n->invert) { 47 if ((n->old_status == UNBLANK) ^ n->invert) {
48 n->brightness = led->brightness; 48 n->brightness = led->brightness;
49 __led_set_brightness(led, LED_OFF); 49 led_set_brightness(led, LED_OFF);
50 } else { 50 } else {
51 __led_set_brightness(led, n->brightness); 51 led_set_brightness(led, n->brightness);
52 } 52 }
53 53
54 n->old_status = new_status; 54 n->old_status = new_status;
@@ -76,7 +76,7 @@ static ssize_t bl_trig_invert_store(struct device *dev,
76 unsigned long invert; 76 unsigned long invert;
77 int ret; 77 int ret;
78 78
79 ret = kstrtoul(buf, 10, &invert); 79 ret = strict_strtoul(buf, 10, &invert);
80 if (ret < 0) 80 if (ret < 0)
81 return ret; 81 return ret;
82 82
@@ -87,9 +87,9 @@ static ssize_t bl_trig_invert_store(struct device *dev,
87 87
88 /* After inverting, we need to update the LED. */ 88 /* After inverting, we need to update the LED. */
89 if ((n->old_status == BLANK) ^ n->invert) 89 if ((n->old_status == BLANK) ^ n->invert)
90 __led_set_brightness(led, LED_OFF); 90 led_set_brightness(led, LED_OFF);
91 else 91 else
92 __led_set_brightness(led, n->brightness); 92 led_set_brightness(led, n->brightness);
93 93
94 return num; 94 return num;
95} 95}
@@ -120,7 +120,6 @@ static void bl_trig_activate(struct led_classdev *led)
120 ret = fb_register_client(&n->notifier); 120 ret = fb_register_client(&n->notifier);
121 if (ret) 121 if (ret)
122 dev_err(led->dev, "unable to register backlight trigger\n"); 122 dev_err(led->dev, "unable to register backlight trigger\n");
123 led->activated = true;
124 123
125 return; 124 return;
126 125
@@ -134,11 +133,10 @@ static void bl_trig_deactivate(struct led_classdev *led)
134 struct bl_trig_notifier *n = 133 struct bl_trig_notifier *n =
135 (struct bl_trig_notifier *) led->trigger_data; 134 (struct bl_trig_notifier *) led->trigger_data;
136 135
137 if (led->activated) { 136 if (n) {
138 device_remove_file(led->dev, &dev_attr_inverted); 137 device_remove_file(led->dev, &dev_attr_inverted);
139 fb_unregister_client(&n->notifier); 138 fb_unregister_client(&n->notifier);
140 kfree(n); 139 kfree(n);
141 led->activated = false;
142 } 140 }
143} 141}
144 142
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
deleted file mode 100644
index 4239b3955ff..00000000000
--- a/drivers/leds/ledtrig-cpu.c
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2 * ledtrig-cpu.c - LED trigger based on CPU activity
3 *
4 * This LED trigger will be registered for each possible CPU and named as
5 * cpu0, cpu1, cpu2, cpu3, etc.
6 *
7 * It can be bound to any LED just like other triggers using either a
8 * board file or via sysfs interface.
9 *
10 * An API named ledtrig_cpu is exported for any user, who want to add CPU
11 * activity indication in their code
12 *
13 * Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
14 * Copyright 2011 - 2012 Bryan Wu <bryan.wu@canonical.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/percpu.h>
27#include <linux/syscore_ops.h>
28#include <linux/rwsem.h>
29#include "leds.h"
30
31#define MAX_NAME_LEN 8
32
33struct led_trigger_cpu {
34 char name[MAX_NAME_LEN];
35 struct led_trigger *_trig;
36};
37
38static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
39
40/**
41 * ledtrig_cpu - emit a CPU event as a trigger
42 * @evt: CPU event to be emitted
43 *
44 * Emit a CPU event on a CPU core, which will trigger a
45 * binded LED to turn on or turn off.
46 */
47void ledtrig_cpu(enum cpu_led_event ledevt)
48{
49 struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
50
51 /* Locate the correct CPU LED */
52 switch (ledevt) {
53 case CPU_LED_IDLE_END:
54 case CPU_LED_START:
55 /* Will turn the LED on, max brightness */
56 led_trigger_event(trig->_trig, LED_FULL);
57 break;
58
59 case CPU_LED_IDLE_START:
60 case CPU_LED_STOP:
61 case CPU_LED_HALTED:
62 /* Will turn the LED off */
63 led_trigger_event(trig->_trig, LED_OFF);
64 break;
65
66 default:
67 /* Will leave the LED as it is */
68 break;
69 }
70}
71EXPORT_SYMBOL(ledtrig_cpu);
72
73static int ledtrig_cpu_syscore_suspend(void)
74{
75 ledtrig_cpu(CPU_LED_STOP);
76 return 0;
77}
78
79static void ledtrig_cpu_syscore_resume(void)
80{
81 ledtrig_cpu(CPU_LED_START);
82}
83
84static void ledtrig_cpu_syscore_shutdown(void)
85{
86 ledtrig_cpu(CPU_LED_HALTED);
87}
88
89static struct syscore_ops ledtrig_cpu_syscore_ops = {
90 .shutdown = ledtrig_cpu_syscore_shutdown,
91 .suspend = ledtrig_cpu_syscore_suspend,
92 .resume = ledtrig_cpu_syscore_resume,
93};
94
95static int __init ledtrig_cpu_init(void)
96{
97 int cpu;
98
99 /* Supports up to 9999 cpu cores */
100 BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);
101
102 /*
103 * Registering CPU led trigger for each CPU core here
104 * ignores CPU hotplug, but after this CPU hotplug works
105 * fine with this trigger.
106 */
107 for_each_possible_cpu(cpu) {
108 struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
109
110 snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
111
112 led_trigger_register_simple(trig->name, &trig->_trig);
113 }
114
115 register_syscore_ops(&ledtrig_cpu_syscore_ops);
116
117 pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n");
118
119 return 0;
120}
121module_init(ledtrig_cpu_init);
122
123static void __exit ledtrig_cpu_exit(void)
124{
125 int cpu;
126
127 for_each_possible_cpu(cpu) {
128 struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
129
130 led_trigger_unregister_simple(trig->_trig);
131 trig->_trig = NULL;
132 memset(trig->name, 0, MAX_NAME_LEN);
133 }
134
135 unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
136}
137module_exit(ledtrig_cpu_exit);
138
139MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
140MODULE_AUTHOR("Bryan Wu <bryan.wu@canonical.com>");
141MODULE_DESCRIPTION("CPU LED trigger");
142MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index eac1f1b1ada..a4ef54b9d50 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
19 19
20static void defon_trig_activate(struct led_classdev *led_cdev) 20static void defon_trig_activate(struct led_classdev *led_cdev)
21{ 21{
22 __led_set_brightness(led_cdev, led_cdev->max_brightness); 22 led_set_brightness(led_cdev, led_cdev->max_brightness);
23} 23}
24 24
25static struct led_trigger defon_led_trigger = { 25static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
index 72e3ebfc281..ecc4bf3f37a 100644
--- a/drivers/leds/ledtrig-gpio.c
+++ b/drivers/leds/ledtrig-gpio.c
@@ -54,12 +54,12 @@ static void gpio_trig_work(struct work_struct *work)
54 54
55 if (tmp) { 55 if (tmp) {
56 if (gpio_data->desired_brightness) 56 if (gpio_data->desired_brightness)
57 __led_set_brightness(gpio_data->led, 57 led_set_brightness(gpio_data->led,
58 gpio_data->desired_brightness); 58 gpio_data->desired_brightness);
59 else 59 else
60 __led_set_brightness(gpio_data->led, LED_FULL); 60 led_set_brightness(gpio_data->led, LED_FULL);
61 } else { 61 } else {
62 __led_set_brightness(gpio_data->led, LED_OFF); 62 led_set_brightness(gpio_data->led, LED_OFF);
63 } 63 }
64} 64}
65 65
@@ -110,7 +110,7 @@ static ssize_t gpio_trig_inverted_store(struct device *dev,
110 unsigned long inverted; 110 unsigned long inverted;
111 int ret; 111 int ret;
112 112
113 ret = kstrtoul(buf, 10, &inverted); 113 ret = strict_strtoul(buf, 10, &inverted);
114 if (ret < 0) 114 if (ret < 0)
115 return ret; 115 return ret;
116 116
@@ -200,7 +200,6 @@ static void gpio_trig_activate(struct led_classdev *led)
200 gpio_data->led = led; 200 gpio_data->led = led;
201 led->trigger_data = gpio_data; 201 led->trigger_data = gpio_data;
202 INIT_WORK(&gpio_data->work, gpio_trig_work); 202 INIT_WORK(&gpio_data->work, gpio_trig_work);
203 led->activated = true;
204 203
205 return; 204 return;
206 205
@@ -218,7 +217,7 @@ static void gpio_trig_deactivate(struct led_classdev *led)
218{ 217{
219 struct gpio_trig_data *gpio_data = led->trigger_data; 218 struct gpio_trig_data *gpio_data = led->trigger_data;
220 219
221 if (led->activated) { 220 if (gpio_data) {
222 device_remove_file(led->dev, &dev_attr_gpio); 221 device_remove_file(led->dev, &dev_attr_gpio);
223 device_remove_file(led->dev, &dev_attr_inverted); 222 device_remove_file(led->dev, &dev_attr_inverted);
224 device_remove_file(led->dev, &dev_attr_desired_brightness); 223 device_remove_file(led->dev, &dev_attr_desired_brightness);
@@ -226,7 +225,6 @@ static void gpio_trig_deactivate(struct led_classdev *led)
226 if (gpio_data->gpio != 0) 225 if (gpio_data->gpio != 0)
227 free_irq(gpio_to_irq(gpio_data->gpio), led); 226 free_irq(gpio_to_irq(gpio_data->gpio), led);
228 kfree(gpio_data); 227 kfree(gpio_data);
229 led->activated = false;
230 } 228 }
231} 229}
232 230
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index 1edc7463ce8..759c0bba4a8 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -18,11 +18,8 @@
18#include <linux/timer.h> 18#include <linux/timer.h>
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>
22#include "leds.h" 21#include "leds.h"
23 22
24static int panic_heartbeats;
25
26struct heartbeat_trig_data { 23struct heartbeat_trig_data {
27 unsigned int phase; 24 unsigned int phase;
28 unsigned int period; 25 unsigned int period;
@@ -36,11 +33,6 @@ static void led_heartbeat_function(unsigned long data)
36 unsigned long brightness = LED_OFF; 33 unsigned long brightness = LED_OFF;
37 unsigned long delay = 0; 34 unsigned long delay = 0;
38 35
39 if (unlikely(panic_heartbeats)) {
40 led_set_brightness(led_cdev, LED_OFF);
41 return;
42 }
43
44 /* acts like an actual heart beat -- ie thump-thump-pause... */ 36 /* acts like an actual heart beat -- ie thump-thump-pause... */
45 switch (heartbeat_data->phase) { 37 switch (heartbeat_data->phase) {
46 case 0: 38 case 0:
@@ -74,7 +66,7 @@ static void led_heartbeat_function(unsigned long data)
74 break; 66 break;
75 } 67 }
76 68
77 __led_set_brightness(led_cdev, brightness); 69 led_set_brightness(led_cdev, brightness);
78 mod_timer(&heartbeat_data->timer, jiffies + delay); 70 mod_timer(&heartbeat_data->timer, jiffies + delay);
79} 71}
80 72
@@ -91,17 +83,15 @@ static void heartbeat_trig_activate(struct led_classdev *led_cdev)
91 led_heartbeat_function, (unsigned long) led_cdev); 83 led_heartbeat_function, (unsigned long) led_cdev);
92 heartbeat_data->phase = 0; 84 heartbeat_data->phase = 0;
93 led_heartbeat_function(heartbeat_data->timer.data); 85 led_heartbeat_function(heartbeat_data->timer.data);
94 led_cdev->activated = true;
95} 86}
96 87
97static void heartbeat_trig_deactivate(struct led_classdev *led_cdev) 88static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
98{ 89{
99 struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; 90 struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
100 91
101 if (led_cdev->activated) { 92 if (heartbeat_data) {
102 del_timer_sync(&heartbeat_data->timer); 93 del_timer_sync(&heartbeat_data->timer);
103 kfree(heartbeat_data); 94 kfree(heartbeat_data);
104 led_cdev->activated = false;
105 } 95 }
106} 96}
107 97
@@ -111,45 +101,13 @@ static struct led_trigger heartbeat_led_trigger = {
111 .deactivate = heartbeat_trig_deactivate, 101 .deactivate = heartbeat_trig_deactivate,
112}; 102};
113 103
114static int heartbeat_reboot_notifier(struct notifier_block *nb,
115 unsigned long code, void *unused)
116{
117 led_trigger_unregister(&heartbeat_led_trigger);
118 return NOTIFY_DONE;
119}
120
121static int heartbeat_panic_notifier(struct notifier_block *nb,
122 unsigned long code, void *unused)
123{
124 panic_heartbeats = 1;
125 return NOTIFY_DONE;
126}
127
128static struct notifier_block heartbeat_reboot_nb = {
129 .notifier_call = heartbeat_reboot_notifier,
130};
131
132static struct notifier_block heartbeat_panic_nb = {
133 .notifier_call = heartbeat_panic_notifier,
134};
135
136static int __init heartbeat_trig_init(void) 104static int __init heartbeat_trig_init(void)
137{ 105{
138 int rc = led_trigger_register(&heartbeat_led_trigger); 106 return led_trigger_register(&heartbeat_led_trigger);
139
140 if (!rc) {
141 atomic_notifier_chain_register(&panic_notifier_list,
142 &heartbeat_panic_nb);
143 register_reboot_notifier(&heartbeat_reboot_nb);
144 }
145 return rc;
146} 107}
147 108
148static void __exit heartbeat_trig_exit(void) 109static void __exit heartbeat_trig_exit(void)
149{ 110{
150 unregister_reboot_notifier(&heartbeat_reboot_nb);
151 atomic_notifier_chain_unregister(&panic_notifier_list,
152 &heartbeat_panic_nb);
153 led_trigger_unregister(&heartbeat_led_trigger); 111 led_trigger_unregister(&heartbeat_led_trigger);
154} 112}
155 113
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index 2cd7c0cf592..ec099fcbcb0 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -12,22 +12,39 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/jiffies.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/timer.h>
17#include <linux/leds.h> 19#include <linux/leds.h>
18 20
19#define BLINK_DELAY 30 21static void ledtrig_ide_timerfunc(unsigned long data);
20 22
21DEFINE_LED_TRIGGER(ledtrig_ide); 23DEFINE_LED_TRIGGER(ledtrig_ide);
22static unsigned long ide_blink_delay = BLINK_DELAY; 24static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
25static int ide_activity;
26static int ide_lastactivity;
23 27
24void ledtrig_ide_activity(void) 28void ledtrig_ide_activity(void)
25{ 29{
26 led_trigger_blink_oneshot(ledtrig_ide, 30 ide_activity++;
27 &ide_blink_delay, &ide_blink_delay, 0); 31 if (!timer_pending(&ledtrig_ide_timer))
32 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
28} 33}
29EXPORT_SYMBOL(ledtrig_ide_activity); 34EXPORT_SYMBOL(ledtrig_ide_activity);
30 35
36static void ledtrig_ide_timerfunc(unsigned long data)
37{
38 if (ide_lastactivity != ide_activity) {
39 ide_lastactivity = ide_activity;
40 /* INT_MAX will set each LED to its maximum brightness */
41 led_trigger_event(ledtrig_ide, INT_MAX);
42 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
43 } else {
44 led_trigger_event(ledtrig_ide, LED_OFF);
45 }
46}
47
31static int __init ledtrig_ide_init(void) 48static int __init ledtrig_ide_init(void)
32{ 49{
33 led_trigger_register_simple("ide-disk", &ledtrig_ide); 50 led_trigger_register_simple("ide-disk", &ledtrig_ide);
diff --git a/drivers/leds/ledtrig-oneshot.c b/drivers/leds/ledtrig-oneshot.c
deleted file mode 100644
index 2c029aa5c4f..00000000000
--- a/drivers/leds/ledtrig-oneshot.c
+++ /dev/null
@@ -1,204 +0,0 @@
1/*
2 * One-shot LED Trigger
3 *
4 * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
5 *
6 * Based on ledtrig-timer.c by Richard Purdie <rpurdie@openedhand.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
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/ctype.h>
19#include <linux/slab.h>
20#include <linux/leds.h>
21#include "leds.h"
22
23#define DEFAULT_DELAY 100
24
25struct oneshot_trig_data {
26 unsigned int invert;
27};
28
29static ssize_t led_shot(struct device *dev,
30 struct device_attribute *attr, const char *buf, size_t size)
31{
32 struct led_classdev *led_cdev = dev_get_drvdata(dev);
33 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
34
35 led_blink_set_oneshot(led_cdev,
36 &led_cdev->blink_delay_on, &led_cdev->blink_delay_off,
37 oneshot_data->invert);
38
39 /* content is ignored */
40 return size;
41}
42static ssize_t led_invert_show(struct device *dev,
43 struct device_attribute *attr, char *buf)
44{
45 struct led_classdev *led_cdev = dev_get_drvdata(dev);
46 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
47
48 return sprintf(buf, "%u\n", oneshot_data->invert);
49}
50
51static ssize_t led_invert_store(struct device *dev,
52 struct device_attribute *attr, const char *buf, size_t size)
53{
54 struct led_classdev *led_cdev = dev_get_drvdata(dev);
55 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
56 unsigned long state;
57 int ret;
58
59 ret = kstrtoul(buf, 0, &state);
60 if (ret)
61 return ret;
62
63 oneshot_data->invert = !!state;
64
65 if (oneshot_data->invert)
66 __led_set_brightness(led_cdev, LED_FULL);
67 else
68 __led_set_brightness(led_cdev, LED_OFF);
69
70 return size;
71}
72
73static ssize_t led_delay_on_show(struct device *dev,
74 struct device_attribute *attr, char *buf)
75{
76 struct led_classdev *led_cdev = dev_get_drvdata(dev);
77
78 return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
79}
80
81static ssize_t led_delay_on_store(struct device *dev,
82 struct device_attribute *attr, const char *buf, size_t size)
83{
84 struct led_classdev *led_cdev = dev_get_drvdata(dev);
85 unsigned long state;
86 int ret;
87
88 ret = kstrtoul(buf, 0, &state);
89 if (ret)
90 return ret;
91
92 led_cdev->blink_delay_on = state;
93
94 return size;
95}
96static ssize_t led_delay_off_show(struct device *dev,
97 struct device_attribute *attr, char *buf)
98{
99 struct led_classdev *led_cdev = dev_get_drvdata(dev);
100
101 return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
102}
103
104static ssize_t led_delay_off_store(struct device *dev,
105 struct device_attribute *attr, const char *buf, size_t size)
106{
107 struct led_classdev *led_cdev = dev_get_drvdata(dev);
108 unsigned long state;
109 int ret;
110
111 ret = kstrtoul(buf, 0, &state);
112 if (ret)
113 return ret;
114
115 led_cdev->blink_delay_off = state;
116
117 return size;
118}
119
120static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
121static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
122static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);
123static DEVICE_ATTR(shot, 0200, NULL, led_shot);
124
125static void oneshot_trig_activate(struct led_classdev *led_cdev)
126{
127 struct oneshot_trig_data *oneshot_data;
128 int rc;
129
130 oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL);
131 if (!oneshot_data)
132 return;
133
134 led_cdev->trigger_data = oneshot_data;
135
136 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
137 if (rc)
138 goto err_out_trig_data;
139 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
140 if (rc)
141 goto err_out_delayon;
142 rc = device_create_file(led_cdev->dev, &dev_attr_invert);
143 if (rc)
144 goto err_out_delayoff;
145 rc = device_create_file(led_cdev->dev, &dev_attr_shot);
146 if (rc)
147 goto err_out_invert;
148
149 led_cdev->blink_delay_on = DEFAULT_DELAY;
150 led_cdev->blink_delay_off = DEFAULT_DELAY;
151
152 led_cdev->activated = true;
153
154 return;
155
156err_out_invert:
157 device_remove_file(led_cdev->dev, &dev_attr_invert);
158err_out_delayoff:
159 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
160err_out_delayon:
161 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
162err_out_trig_data:
163 kfree(led_cdev->trigger_data);
164}
165
166static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
167{
168 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
169
170 if (led_cdev->activated) {
171 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
172 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
173 device_remove_file(led_cdev->dev, &dev_attr_invert);
174 device_remove_file(led_cdev->dev, &dev_attr_shot);
175 kfree(oneshot_data);
176 led_cdev->activated = false;
177 }
178
179 /* Stop blinking */
180 led_set_brightness(led_cdev, LED_OFF);
181}
182
183static struct led_trigger oneshot_led_trigger = {
184 .name = "oneshot",
185 .activate = oneshot_trig_activate,
186 .deactivate = oneshot_trig_deactivate,
187};
188
189static int __init oneshot_trig_init(void)
190{
191 return led_trigger_register(&oneshot_led_trigger);
192}
193
194static void __exit oneshot_trig_exit(void)
195{
196 led_trigger_unregister(&oneshot_led_trigger);
197}
198
199module_init(oneshot_trig_init);
200module_exit(oneshot_trig_exit);
201
202MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>");
203MODULE_DESCRIPTION("One-shot LED trigger");
204MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index f774d059220..328c64c0841 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -31,17 +31,21 @@ static ssize_t led_delay_on_store(struct device *dev,
31 struct device_attribute *attr, const char *buf, size_t size) 31 struct device_attribute *attr, const char *buf, size_t size)
32{ 32{
33 struct led_classdev *led_cdev = dev_get_drvdata(dev); 33 struct led_classdev *led_cdev = dev_get_drvdata(dev);
34 unsigned long state; 34 int ret = -EINVAL;
35 ssize_t ret = -EINVAL; 35 char *after;
36 36 unsigned long state = simple_strtoul(buf, &after, 10);
37 ret = kstrtoul(buf, 10, &state); 37 size_t count = after - buf;
38 if (ret) 38
39 return ret; 39 if (isspace(*after))
40 40 count++;
41 led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); 41
42 led_cdev->blink_delay_on = state; 42 if (count == size) {
43 led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
44 led_cdev->blink_delay_on = state;
45 ret = count;
46 }
43 47
44 return size; 48 return ret;
45} 49}
46 50
47static ssize_t led_delay_off_show(struct device *dev, 51static ssize_t led_delay_off_show(struct device *dev,
@@ -56,17 +60,21 @@ static ssize_t led_delay_off_store(struct device *dev,
56 struct device_attribute *attr, const char *buf, size_t size) 60 struct device_attribute *attr, const char *buf, size_t size)
57{ 61{
58 struct led_classdev *led_cdev = dev_get_drvdata(dev); 62 struct led_classdev *led_cdev = dev_get_drvdata(dev);
59 unsigned long state; 63 int ret = -EINVAL;
60 ssize_t ret = -EINVAL; 64 char *after;
61 65 unsigned long state = simple_strtoul(buf, &after, 10);
62 ret = kstrtoul(buf, 10, &state); 66 size_t count = after - buf;
63 if (ret) 67
64 return ret; 68 if (isspace(*after))
65 69 count++;
66 led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); 70
67 led_cdev->blink_delay_off = state; 71 if (count == size) {
72 led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
73 led_cdev->blink_delay_off = state;
74 ret = count;
75 }
68 76
69 return size; 77 return ret;
70} 78}
71 79
72static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); 80static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
@@ -87,7 +95,8 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
87 95
88 led_blink_set(led_cdev, &led_cdev->blink_delay_on, 96 led_blink_set(led_cdev, &led_cdev->blink_delay_on,
89 &led_cdev->blink_delay_off); 97 &led_cdev->blink_delay_off);
90 led_cdev->activated = true; 98
99 led_cdev->trigger_data = (void *)1;
91 100
92 return; 101 return;
93 102
@@ -97,14 +106,13 @@ err_out_delayon:
97 106
98static void timer_trig_deactivate(struct led_classdev *led_cdev) 107static void timer_trig_deactivate(struct led_classdev *led_cdev)
99{ 108{
100 if (led_cdev->activated) { 109 if (led_cdev->trigger_data) {
101 device_remove_file(led_cdev->dev, &dev_attr_delay_on); 110 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
102 device_remove_file(led_cdev->dev, &dev_attr_delay_off); 111 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
103 led_cdev->activated = false;
104 } 112 }
105 113
106 /* Stop blinking */ 114 /* Stop blinking */
107 led_set_brightness(led_cdev, LED_OFF); 115 led_brightness_set(led_cdev, LED_OFF);
108} 116}
109 117
110static struct led_trigger timer_led_trigger = { 118static struct led_trigger timer_led_trigger = {
diff --git a/drivers/leds/ledtrig-transient.c b/drivers/leds/ledtrig-transient.c
deleted file mode 100644
index 398f1042c43..00000000000
--- a/drivers/leds/ledtrig-transient.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/*
2 * LED Kernel Transient Trigger
3 *
4 * Copyright (C) 2012 Shuah Khan <shuahkhan@gmail.com>
5 *
6 * Based on Richard Purdie's ledtrig-timer.c and Atsushi Nemoto's
7 * ledtrig-heartbeat.c
8 * Design and use-case input from Jonas Bonn <jonas@southpole.se> and
9 * Neil Brown <neilb@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16/*
17 * Transient trigger allows one shot timer activation. Please refer to
18 * Documentation/leds/ledtrig-transient.txt for details
19*/
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/device.h>
25#include <linux/slab.h>
26#include <linux/timer.h>
27#include <linux/leds.h>
28#include "leds.h"
29
30struct transient_trig_data {
31 int activate;
32 int state;
33 int restore_state;
34 unsigned long duration;
35 struct timer_list timer;
36};
37
38static void transient_timer_function(unsigned long data)
39{
40 struct led_classdev *led_cdev = (struct led_classdev *) data;
41 struct transient_trig_data *transient_data = led_cdev->trigger_data;
42
43 transient_data->activate = 0;
44 __led_set_brightness(led_cdev, transient_data->restore_state);
45}
46
47static ssize_t transient_activate_show(struct device *dev,
48 struct device_attribute *attr, char *buf)
49{
50 struct led_classdev *led_cdev = dev_get_drvdata(dev);
51 struct transient_trig_data *transient_data = led_cdev->trigger_data;
52
53 return sprintf(buf, "%d\n", transient_data->activate);
54}
55
56static ssize_t transient_activate_store(struct device *dev,
57 struct device_attribute *attr, const char *buf, size_t size)
58{
59 struct led_classdev *led_cdev = dev_get_drvdata(dev);
60 struct transient_trig_data *transient_data = led_cdev->trigger_data;
61 unsigned long state;
62 ssize_t ret;
63
64 ret = kstrtoul(buf, 10, &state);
65 if (ret)
66 return ret;
67
68 if (state != 1 && state != 0)
69 return -EINVAL;
70
71 /* cancel the running timer */
72 if (state == 0 && transient_data->activate == 1) {
73 del_timer(&transient_data->timer);
74 transient_data->activate = state;
75 __led_set_brightness(led_cdev, transient_data->restore_state);
76 return size;
77 }
78
79 /* start timer if there is no active timer */
80 if (state == 1 && transient_data->activate == 0 &&
81 transient_data->duration != 0) {
82 transient_data->activate = state;
83 __led_set_brightness(led_cdev, transient_data->state);
84 transient_data->restore_state =
85 (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL;
86 mod_timer(&transient_data->timer,
87 jiffies + transient_data->duration);
88 }
89
90 /* state == 0 && transient_data->activate == 0
91 timer is not active - just return */
92 /* state == 1 && transient_data->activate == 1
93 timer is already active - just return */
94
95 return size;
96}
97
98static ssize_t transient_duration_show(struct device *dev,
99 struct device_attribute *attr, char *buf)
100{
101 struct led_classdev *led_cdev = dev_get_drvdata(dev);
102 struct transient_trig_data *transient_data = led_cdev->trigger_data;
103
104 return sprintf(buf, "%lu\n", transient_data->duration);
105}
106
107static ssize_t transient_duration_store(struct device *dev,
108 struct device_attribute *attr, const char *buf, size_t size)
109{
110 struct led_classdev *led_cdev = dev_get_drvdata(dev);
111 struct transient_trig_data *transient_data = led_cdev->trigger_data;
112 unsigned long state;
113 ssize_t ret;
114
115 ret = kstrtoul(buf, 10, &state);
116 if (ret)
117 return ret;
118
119 transient_data->duration = state;
120 return size;
121}
122
123static ssize_t transient_state_show(struct device *dev,
124 struct device_attribute *attr, char *buf)
125{
126 struct led_classdev *led_cdev = dev_get_drvdata(dev);
127 struct transient_trig_data *transient_data = led_cdev->trigger_data;
128 int state;
129
130 state = (transient_data->state == LED_FULL) ? 1 : 0;
131 return sprintf(buf, "%d\n", state);
132}
133
134static ssize_t transient_state_store(struct device *dev,
135 struct device_attribute *attr, const char *buf, size_t size)
136{
137 struct led_classdev *led_cdev = dev_get_drvdata(dev);
138 struct transient_trig_data *transient_data = led_cdev->trigger_data;
139 unsigned long state;
140 ssize_t ret;
141
142 ret = kstrtoul(buf, 10, &state);
143 if (ret)
144 return ret;
145
146 if (state != 1 && state != 0)
147 return -EINVAL;
148
149 transient_data->state = (state == 1) ? LED_FULL : LED_OFF;
150 return size;
151}
152
153static DEVICE_ATTR(activate, 0644, transient_activate_show,
154 transient_activate_store);
155static DEVICE_ATTR(duration, 0644, transient_duration_show,
156 transient_duration_store);
157static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store);
158
159static void transient_trig_activate(struct led_classdev *led_cdev)
160{
161 int rc;
162 struct transient_trig_data *tdata;
163
164 tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL);
165 if (!tdata) {
166 dev_err(led_cdev->dev,
167 "unable to allocate transient trigger\n");
168 return;
169 }
170 led_cdev->trigger_data = tdata;
171
172 rc = device_create_file(led_cdev->dev, &dev_attr_activate);
173 if (rc)
174 goto err_out;
175
176 rc = device_create_file(led_cdev->dev, &dev_attr_duration);
177 if (rc)
178 goto err_out_duration;
179
180 rc = device_create_file(led_cdev->dev, &dev_attr_state);
181 if (rc)
182 goto err_out_state;
183
184 setup_timer(&tdata->timer, transient_timer_function,
185 (unsigned long) led_cdev);
186 led_cdev->activated = true;
187
188 return;
189
190err_out_state:
191 device_remove_file(led_cdev->dev, &dev_attr_duration);
192err_out_duration:
193 device_remove_file(led_cdev->dev, &dev_attr_activate);
194err_out:
195 dev_err(led_cdev->dev, "unable to register transient trigger\n");
196 led_cdev->trigger_data = NULL;
197 kfree(tdata);
198}
199
200static void transient_trig_deactivate(struct led_classdev *led_cdev)
201{
202 struct transient_trig_data *transient_data = led_cdev->trigger_data;
203
204 if (led_cdev->activated) {
205 del_timer_sync(&transient_data->timer);
206 __led_set_brightness(led_cdev, transient_data->restore_state);
207 device_remove_file(led_cdev->dev, &dev_attr_activate);
208 device_remove_file(led_cdev->dev, &dev_attr_duration);
209 device_remove_file(led_cdev->dev, &dev_attr_state);
210 led_cdev->trigger_data = NULL;
211 led_cdev->activated = false;
212 kfree(transient_data);
213 }
214}
215
216static struct led_trigger transient_trigger = {
217 .name = "transient",
218 .activate = transient_trig_activate,
219 .deactivate = transient_trig_deactivate,
220};
221
222static int __init transient_trig_init(void)
223{
224 return led_trigger_register(&transient_trigger);
225}
226
227static void __exit transient_trig_exit(void)
228{
229 led_trigger_unregister(&transient_trigger);
230}
231
232module_init(transient_trig_init);
233module_exit(transient_trig_exit);
234
235MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>");
236MODULE_DESCRIPTION("Transient LED trigger");
237MODULE_LICENSE("GPL");