aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:15 -0400
committerJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:59 -0400
commit07f9479a40cc778bc1462ada11f95b01360ae4ff (patch)
tree0676cf38df3844004bb3ebfd99dfa67a4a8998f5 /drivers/leds
parent9d5e6bdb3013acfb311ab407eeca0b6a6a3dedbf (diff)
parentcd2e49e90f1cae7726c9a2c54488d881d7f1cd1c (diff)
Merge branch 'master' into for-next
Fast-forwarded to current state of Linus' tree as there are patches to be applied for files that didn't exist on the old branch.
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig10
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/led-triggers.c20
-rw-r--r--drivers/leds/leds-88pm860x.c60
-rw-r--r--drivers/leds/leds-bd2802.c47
-rw-r--r--drivers/leds/leds-lm3530.c378
-rw-r--r--drivers/leds/leds-lp5521.c14
-rw-r--r--drivers/leds/leds-lp5523.c20
-rw-r--r--drivers/leds/leds-mc13783.c7
-rw-r--r--drivers/leds/leds-net5501.c2
-rw-r--r--drivers/leds/leds-pca9532.c2
-rw-r--r--drivers/leds/leds-regulator.c4
-rw-r--r--drivers/leds/leds-wm8350.c4
13 files changed, 494 insertions, 75 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 6f190f4cdbc0..9bec8699b8a3 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -34,6 +34,16 @@ config LEDS_ATMEL_PWM
34 This option enables support for LEDs driven using outputs 34 This option enables support for LEDs driven using outputs
35 of the dedicated PWM controller found on newer Atmel SOCs. 35 of the dedicated PWM controller found on newer Atmel SOCs.
36 36
37config LEDS_LM3530
38 tristate "LCD Backlight driver for LM3530"
39 depends on LEDS_CLASS
40 depends on I2C
41 help
42 This option enables support for the LCD backlight using
43 LM3530 ambient light sensor chip. This ALS chip can be
44 controlled manually or using PWM input or using ambient
45 light automatically.
46
37config LEDS_LOCOMO 47config LEDS_LOCOMO
38 tristate "LED Support for Locomo device" 48 tristate "LED Support for Locomo device"
39 depends on LEDS_CLASS 49 depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index aae6989ff6b6..39c80fca84d2 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
9obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o 9obj-$(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_MIKROTIK_RB532) += leds-rb532.o 13obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
13obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o 14obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
14obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o 15obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index c41eb6180c9c..4bebae733349 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -231,6 +231,26 @@ void led_trigger_event(struct led_trigger *trigger,
231} 231}
232EXPORT_SYMBOL_GPL(led_trigger_event); 232EXPORT_SYMBOL_GPL(led_trigger_event);
233 233
234void led_trigger_blink(struct led_trigger *trigger,
235 unsigned long *delay_on,
236 unsigned long *delay_off)
237{
238 struct list_head *entry;
239
240 if (!trigger)
241 return;
242
243 read_lock(&trigger->leddev_list_lock);
244 list_for_each(entry, &trigger->led_cdevs) {
245 struct led_classdev *led_cdev;
246
247 led_cdev = list_entry(entry, struct led_classdev, trig_list);
248 led_blink_set(led_cdev, delay_on, delay_off);
249 }
250 read_unlock(&trigger->leddev_list_lock);
251}
252EXPORT_SYMBOL_GPL(led_trigger_blink);
253
234void led_trigger_register_simple(const char *name, struct led_trigger **tp) 254void led_trigger_register_simple(const char *name, struct led_trigger **tp)
235{ 255{
236 struct led_trigger *trigger; 256 struct led_trigger *trigger;
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index e672b44ee172..416def84d045 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -17,6 +17,7 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/mfd/core.h>
20#include <linux/mfd/88pm860x.h> 21#include <linux/mfd/88pm860x.h>
21 22
22#define LED_PWM_SHIFT (3) 23#define LED_PWM_SHIFT (3)
@@ -118,7 +119,8 @@ static void pm860x_led_work(struct work_struct *work)
118 119
119 struct pm860x_led *led; 120 struct pm860x_led *led;
120 struct pm860x_chip *chip; 121 struct pm860x_chip *chip;
121 int mask; 122 unsigned char buf[3];
123 int mask, ret;
122 124
123 led = container_of(work, struct pm860x_led, work); 125 led = container_of(work, struct pm860x_led, work);
124 chip = led->chip; 126 chip = led->chip;
@@ -128,16 +130,27 @@ static void pm860x_led_work(struct work_struct *work)
128 pm860x_set_bits(led->i2c, __led_off(led->port), 130 pm860x_set_bits(led->i2c, __led_off(led->port),
129 LED_CURRENT_MASK, led->iset); 131 LED_CURRENT_MASK, led->iset);
130 } 132 }
133 pm860x_set_bits(led->i2c, __blink_off(led->port),
134 LED_BLINK_MASK, LED_ON_CONTINUOUS);
131 mask = __blink_ctl_mask(led->port); 135 mask = __blink_ctl_mask(led->port);
132 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); 136 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
133 } else if (led->brightness == 0) {
134 pm860x_set_bits(led->i2c, __led_off(led->port),
135 LED_CURRENT_MASK, 0);
136 mask = __blink_ctl_mask(led->port);
137 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
138 } 137 }
139 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK, 138 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
140 led->brightness); 139 led->brightness);
140
141 if (led->brightness == 0) {
142 pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
143 ret = buf[0] & LED_PWM_MASK;
144 ret |= buf[1] & LED_PWM_MASK;
145 ret |= buf[2] & LED_PWM_MASK;
146 if (ret == 0) {
147 /* unset current since no led is lighting */
148 pm860x_set_bits(led->i2c, __led_off(led->port),
149 LED_CURRENT_MASK, 0);
150 mask = __blink_ctl_mask(led->port);
151 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
152 }
153 }
141 led->current_brightness = led->brightness; 154 led->current_brightness = led->brightness;
142 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 155 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
143 __led_off(led->port), led->brightness); 156 __led_off(led->port), led->brightness);
@@ -153,31 +166,12 @@ static void pm860x_led_set(struct led_classdev *cdev,
153 schedule_work(&data->work); 166 schedule_work(&data->work);
154} 167}
155 168
156static int __check_device(struct pm860x_led_pdata *pdata, char *name)
157{
158 struct pm860x_led_pdata *p = pdata;
159 int ret = -EINVAL;
160
161 while (p && p->id) {
162 if ((p->id != PM8606_ID_LED) || (p->flags < 0))
163 break;
164
165 if (!strncmp(name, pm860x_led_name[p->flags],
166 MFD_NAME_SIZE)) {
167 ret = (int)p->flags;
168 break;
169 }
170 p++;
171 }
172 return ret;
173}
174
175static int pm860x_led_probe(struct platform_device *pdev) 169static int pm860x_led_probe(struct platform_device *pdev)
176{ 170{
177 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 171 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
178 struct pm860x_platform_data *pm860x_pdata;
179 struct pm860x_led_pdata *pdata; 172 struct pm860x_led_pdata *pdata;
180 struct pm860x_led *data; 173 struct pm860x_led *data;
174 struct mfd_cell *cell;
181 struct resource *res; 175 struct resource *res;
182 int ret; 176 int ret;
183 177
@@ -187,10 +181,11 @@ static int pm860x_led_probe(struct platform_device *pdev)
187 return -EINVAL; 181 return -EINVAL;
188 } 182 }
189 183
190 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
191 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
192 pdata = pm860x_pdata->led; 186 return -ENODEV;
193 } else { 187 pdata = cell->mfd_data;
188 if (pdata == NULL) {
194 dev_err(&pdev->dev, "No platform data!\n"); 189 dev_err(&pdev->dev, "No platform data!\n");
195 return -EINVAL; 190 return -EINVAL;
196 } 191 }
@@ -198,12 +193,12 @@ static int pm860x_led_probe(struct platform_device *pdev)
198 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 193 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
199 if (data == NULL) 194 if (data == NULL)
200 return -ENOMEM; 195 return -ENOMEM;
201 strncpy(data->name, res->name, MFD_NAME_SIZE); 196 strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
202 dev_set_drvdata(&pdev->dev, data); 197 dev_set_drvdata(&pdev->dev, data);
203 data->chip = chip; 198 data->chip = chip;
204 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 199 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
205 data->iset = pdata->iset; 200 data->iset = pdata->iset;
206 data->port = __check_device(pdata, data->name); 201 data->port = pdata->flags;
207 if (data->port < 0) { 202 if (data->port < 0) {
208 dev_err(&pdev->dev, "check device failed\n"); 203 dev_err(&pdev->dev, "check device failed\n");
209 kfree(data); 204 kfree(data);
@@ -221,6 +216,7 @@ static int pm860x_led_probe(struct platform_device *pdev)
221 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 216 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
222 goto out; 217 goto out;
223 } 218 }
219 pm860x_led_set(&data->cdev, 0);
224 return 0; 220 return 0;
225out: 221out:
226 kfree(data); 222 kfree(data);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 19dc4b61a105..3ebe3824662d 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -19,7 +19,7 @@
19#include <linux/leds.h> 19#include <linux/leds.h>
20#include <linux/leds-bd2802.h> 20#include <linux/leds-bd2802.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22#include <linux/pm.h>
23 23
24#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0)) 24#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
25 25
@@ -319,20 +319,6 @@ static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
319 bd2802_update_state(led, id, color, BD2802_OFF); 319 bd2802_update_state(led, id, color, BD2802_OFF);
320} 320}
321 321
322static void bd2802_restore_state(struct bd2802_led *led)
323{
324 int i;
325
326 for (i = 0; i < LED_NUM; i++) {
327 if (led->led[i].r)
328 bd2802_turn_on(led, i, RED, led->led[i].r);
329 if (led->led[i].g)
330 bd2802_turn_on(led, i, GREEN, led->led[i].g);
331 if (led->led[i].b)
332 bd2802_turn_on(led, i, BLUE, led->led[i].b);
333 }
334}
335
336#define BD2802_SET_REGISTER(reg_addr, reg_name) \ 322#define BD2802_SET_REGISTER(reg_addr, reg_name) \
337static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \ 323static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
338 struct device_attribute *attr, const char *buf, size_t count) \ 324 struct device_attribute *attr, const char *buf, size_t count) \
@@ -761,8 +747,25 @@ static int __exit bd2802_remove(struct i2c_client *client)
761 return 0; 747 return 0;
762} 748}
763 749
764static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg) 750#ifdef CONFIG_PM
751
752static void bd2802_restore_state(struct bd2802_led *led)
765{ 753{
754 int i;
755
756 for (i = 0; i < LED_NUM; i++) {
757 if (led->led[i].r)
758 bd2802_turn_on(led, i, RED, led->led[i].r);
759 if (led->led[i].g)
760 bd2802_turn_on(led, i, GREEN, led->led[i].g);
761 if (led->led[i].b)
762 bd2802_turn_on(led, i, BLUE, led->led[i].b);
763 }
764}
765
766static int bd2802_suspend(struct device *dev)
767{
768 struct i2c_client *client = to_i2c_client(dev);
766 struct bd2802_led *led = i2c_get_clientdata(client); 769 struct bd2802_led *led = i2c_get_clientdata(client);
767 770
768 gpio_set_value(led->pdata->reset_gpio, 0); 771 gpio_set_value(led->pdata->reset_gpio, 0);
@@ -770,8 +773,9 @@ static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
770 return 0; 773 return 0;
771} 774}
772 775
773static int bd2802_resume(struct i2c_client *client) 776static int bd2802_resume(struct device *dev)
774{ 777{
778 struct i2c_client *client = to_i2c_client(dev);
775 struct bd2802_led *led = i2c_get_clientdata(client); 779 struct bd2802_led *led = i2c_get_clientdata(client);
776 780
777 if (!bd2802_is_all_off(led) || led->adf_on) { 781 if (!bd2802_is_all_off(led) || led->adf_on) {
@@ -782,6 +786,12 @@ static int bd2802_resume(struct i2c_client *client)
782 return 0; 786 return 0;
783} 787}
784 788
789static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume);
790#define BD2802_PM (&bd2802_pm)
791#else /* CONFIG_PM */
792#define BD2802_PM NULL
793#endif
794
785static const struct i2c_device_id bd2802_id[] = { 795static const struct i2c_device_id bd2802_id[] = {
786 { "BD2802", 0 }, 796 { "BD2802", 0 },
787 { } 797 { }
@@ -791,11 +801,10 @@ MODULE_DEVICE_TABLE(i2c, bd2802_id);
791static struct i2c_driver bd2802_i2c_driver = { 801static struct i2c_driver bd2802_i2c_driver = {
792 .driver = { 802 .driver = {
793 .name = "BD2802", 803 .name = "BD2802",
804 .pm = BD2802_PM,
794 }, 805 },
795 .probe = bd2802_probe, 806 .probe = bd2802_probe,
796 .remove = __exit_p(bd2802_remove), 807 .remove = __exit_p(bd2802_remove),
797 .suspend = bd2802_suspend,
798 .resume = bd2802_resume,
799 .id_table = bd2802_id, 808 .id_table = bd2802_id,
800}; 809};
801 810
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
new file mode 100644
index 000000000000..e7089a1f6cb6
--- /dev/null
+++ b/drivers/leds/leds-lm3530.c
@@ -0,0 +1,378 @@
1/*
2 * Copyright (C) 2011 ST-Ericsson SA.
3 * Copyright (C) 2009 Motorola, Inc.
4 *
5 * License Terms: GNU General Public License v2
6 *
7 * Simple driver for National Semiconductor LM3530 Backlight driver chip
8 *
9 * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
10 * based on leds-lm3530.c by Dan Murphy <D.Murphy@motorola.com>
11 */
12
13#include <linux/i2c.h>
14#include <linux/leds.h>
15#include <linux/slab.h>
16#include <linux/platform_device.h>
17#include <linux/input.h>
18#include <linux/led-lm3530.h>
19#include <linux/types.h>
20
21#define LM3530_LED_DEV "lcd-backlight"
22#define LM3530_NAME "lm3530-led"
23
24#define LM3530_GEN_CONFIG 0x10
25#define LM3530_ALS_CONFIG 0x20
26#define LM3530_BRT_RAMP_RATE 0x30
27#define LM3530_ALS_ZONE_REG 0x40
28#define LM3530_ALS_IMP_SELECT 0x41
29#define LM3530_BRT_CTRL_REG 0xA0
30#define LM3530_ALS_ZB0_REG 0x60
31#define LM3530_ALS_ZB1_REG 0x61
32#define LM3530_ALS_ZB2_REG 0x62
33#define LM3530_ALS_ZB3_REG 0x63
34#define LM3530_ALS_Z0T_REG 0x70
35#define LM3530_ALS_Z1T_REG 0x71
36#define LM3530_ALS_Z2T_REG 0x72
37#define LM3530_ALS_Z3T_REG 0x73
38#define LM3530_ALS_Z4T_REG 0x74
39#define LM3530_REG_MAX 15
40
41/* General Control Register */
42#define LM3530_EN_I2C_SHIFT (0)
43#define LM3530_RAMP_LAW_SHIFT (1)
44#define LM3530_MAX_CURR_SHIFT (2)
45#define LM3530_EN_PWM_SHIFT (5)
46#define LM3530_PWM_POL_SHIFT (6)
47#define LM3530_EN_PWM_SIMPLE_SHIFT (7)
48
49#define LM3530_ENABLE_I2C (1 << LM3530_EN_I2C_SHIFT)
50#define LM3530_ENABLE_PWM (1 << LM3530_EN_PWM_SHIFT)
51#define LM3530_POL_LOW (1 << LM3530_PWM_POL_SHIFT)
52#define LM3530_ENABLE_PWM_SIMPLE (1 << LM3530_EN_PWM_SIMPLE_SHIFT)
53
54/* ALS Config Register Options */
55#define LM3530_ALS_AVG_TIME_SHIFT (0)
56#define LM3530_EN_ALS_SHIFT (3)
57#define LM3530_ALS_SEL_SHIFT (5)
58
59#define LM3530_ENABLE_ALS (3 << LM3530_EN_ALS_SHIFT)
60
61/* Brightness Ramp Rate Register */
62#define LM3530_BRT_RAMP_FALL_SHIFT (0)
63#define LM3530_BRT_RAMP_RISE_SHIFT (3)
64
65/* ALS Resistor Select */
66#define LM3530_ALS1_IMP_SHIFT (0)
67#define LM3530_ALS2_IMP_SHIFT (4)
68
69/* Zone Boundary Register defaults */
70#define LM3530_DEF_ZB_0 (0x33)
71#define LM3530_DEF_ZB_1 (0x66)
72#define LM3530_DEF_ZB_2 (0x99)
73#define LM3530_DEF_ZB_3 (0xCC)
74
75/* Zone Target Register defaults */
76#define LM3530_DEF_ZT_0 (0x19)
77#define LM3530_DEF_ZT_1 (0x33)
78#define LM3530_DEF_ZT_2 (0x4C)
79#define LM3530_DEF_ZT_3 (0x66)
80#define LM3530_DEF_ZT_4 (0x7F)
81
82struct lm3530_mode_map {
83 const char *mode;
84 enum lm3530_mode mode_val;
85};
86
87static struct lm3530_mode_map mode_map[] = {
88 { "man", LM3530_BL_MODE_MANUAL },
89 { "als", LM3530_BL_MODE_ALS },
90 { "pwm", LM3530_BL_MODE_PWM },
91};
92
93/**
94 * struct lm3530_data
95 * @led_dev: led class device
96 * @client: i2c client
97 * @pdata: LM3530 platform data
98 * @mode: mode of operation - manual, ALS, PWM
99 */
100struct lm3530_data {
101 struct led_classdev led_dev;
102 struct i2c_client *client;
103 struct lm3530_platform_data *pdata;
104 enum lm3530_mode mode;
105};
106
107static const u8 lm3530_reg[LM3530_REG_MAX] = {
108 LM3530_GEN_CONFIG,
109 LM3530_ALS_CONFIG,
110 LM3530_BRT_RAMP_RATE,
111 LM3530_ALS_ZONE_REG,
112 LM3530_ALS_IMP_SELECT,
113 LM3530_BRT_CTRL_REG,
114 LM3530_ALS_ZB0_REG,
115 LM3530_ALS_ZB1_REG,
116 LM3530_ALS_ZB2_REG,
117 LM3530_ALS_ZB3_REG,
118 LM3530_ALS_Z0T_REG,
119 LM3530_ALS_Z1T_REG,
120 LM3530_ALS_Z2T_REG,
121 LM3530_ALS_Z3T_REG,
122 LM3530_ALS_Z4T_REG,
123};
124
125static int lm3530_get_mode_from_str(const char *str)
126{
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(mode_map); i++)
130 if (sysfs_streq(str, mode_map[i].mode))
131 return mode_map[i].mode_val;
132
133 return -1;
134}
135
136static int lm3530_init_registers(struct lm3530_data *drvdata)
137{
138 int ret = 0;
139 int i;
140 u8 gen_config;
141 u8 als_config = 0;
142 u8 brt_ramp;
143 u8 als_imp_sel = 0;
144 u8 brightness;
145 u8 reg_val[LM3530_REG_MAX];
146 struct lm3530_platform_data *pltfm = drvdata->pdata;
147 struct i2c_client *client = drvdata->client;
148
149 gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
150 ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
151
152 if (drvdata->mode == LM3530_BL_MODE_MANUAL ||
153 drvdata->mode == LM3530_BL_MODE_ALS)
154 gen_config |= (LM3530_ENABLE_I2C);
155
156 if (drvdata->mode == LM3530_BL_MODE_ALS) {
157 als_config =
158 (pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
159 (LM3530_ENABLE_ALS) |
160 (pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT);
161
162 als_imp_sel =
163 (pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
164 (pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
165 }
166
167 if (drvdata->mode == LM3530_BL_MODE_PWM)
168 gen_config |= (LM3530_ENABLE_PWM) |
169 (pltfm->pwm_pol_hi << LM3530_PWM_POL_SHIFT) |
170 (LM3530_ENABLE_PWM_SIMPLE);
171
172 brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
173 (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
174
175 brightness = pltfm->brt_val;
176
177 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */
178 reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
179 reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */
180 reg_val[3] = 0x00; /* LM3530_ALS_ZONE_REG */
181 reg_val[4] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */
182 reg_val[5] = brightness; /* LM3530_BRT_CTRL_REG */
183 reg_val[6] = LM3530_DEF_ZB_0; /* LM3530_ALS_ZB0_REG */
184 reg_val[7] = LM3530_DEF_ZB_1; /* LM3530_ALS_ZB1_REG */
185 reg_val[8] = LM3530_DEF_ZB_2; /* LM3530_ALS_ZB2_REG */
186 reg_val[9] = LM3530_DEF_ZB_3; /* LM3530_ALS_ZB3_REG */
187 reg_val[10] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */
188 reg_val[11] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */
189 reg_val[12] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */
190 reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */
191 reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
192
193 for (i = 0; i < LM3530_REG_MAX; i++) {
194 ret = i2c_smbus_write_byte_data(client,
195 lm3530_reg[i], reg_val[i]);
196 if (ret)
197 break;
198 }
199
200 return ret;
201}
202
203static void lm3530_brightness_set(struct led_classdev *led_cdev,
204 enum led_brightness brt_val)
205{
206 int err;
207 struct lm3530_data *drvdata =
208 container_of(led_cdev, struct lm3530_data, led_dev);
209
210 switch (drvdata->mode) {
211 case LM3530_BL_MODE_MANUAL:
212
213 /* set the brightness in brightness control register*/
214 err = i2c_smbus_write_byte_data(drvdata->client,
215 LM3530_BRT_CTRL_REG, brt_val / 2);
216 if (err)
217 dev_err(&drvdata->client->dev,
218 "Unable to set brightness: %d\n", err);
219 break;
220 case LM3530_BL_MODE_ALS:
221 break;
222 case LM3530_BL_MODE_PWM:
223 break;
224 default:
225 break;
226 }
227}
228
229
230static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
231 *attr, const char *buf, size_t size)
232{
233 int err;
234 struct i2c_client *client = container_of(
235 dev->parent, struct i2c_client, dev);
236 struct lm3530_data *drvdata = i2c_get_clientdata(client);
237 int mode;
238
239 mode = lm3530_get_mode_from_str(buf);
240 if (mode < 0) {
241 dev_err(dev, "Invalid mode\n");
242 return -EINVAL;
243 }
244
245 if (mode == LM3530_BL_MODE_MANUAL)
246 drvdata->mode = LM3530_BL_MODE_MANUAL;
247 else if (mode == LM3530_BL_MODE_ALS)
248 drvdata->mode = LM3530_BL_MODE_ALS;
249 else if (mode == LM3530_BL_MODE_PWM) {
250 dev_err(dev, "PWM mode not supported\n");
251 return -EINVAL;
252 }
253
254 err = lm3530_init_registers(drvdata);
255 if (err) {
256 dev_err(dev, "Setting %s Mode failed :%d\n", buf, err);
257 return err;
258 }
259
260 return sizeof(drvdata->mode);
261}
262
263static DEVICE_ATTR(mode, 0644, NULL, lm3530_mode_set);
264
265static int __devinit lm3530_probe(struct i2c_client *client,
266 const struct i2c_device_id *id)
267{
268 struct lm3530_platform_data *pdata = client->dev.platform_data;
269 struct lm3530_data *drvdata;
270 int err = 0;
271
272 if (pdata == NULL) {
273 dev_err(&client->dev, "platform data required\n");
274 err = -ENODEV;
275 goto err_out;
276 }
277
278 /* BL mode */
279 if (pdata->mode > LM3530_BL_MODE_PWM) {
280 dev_err(&client->dev, "Illegal Mode request\n");
281 err = -EINVAL;
282 goto err_out;
283 }
284
285 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
286 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n");
287 err = -EIO;
288 goto err_out;
289 }
290
291 drvdata = kzalloc(sizeof(struct lm3530_data), GFP_KERNEL);
292 if (drvdata == NULL) {
293 err = -ENOMEM;
294 goto err_out;
295 }
296
297 drvdata->mode = pdata->mode;
298 drvdata->client = client;
299 drvdata->pdata = pdata;
300 drvdata->led_dev.name = LM3530_LED_DEV;
301 drvdata->led_dev.brightness_set = lm3530_brightness_set;
302
303 i2c_set_clientdata(client, drvdata);
304
305 err = lm3530_init_registers(drvdata);
306 if (err < 0) {
307 dev_err(&client->dev, "Register Init failed: %d\n", err);
308 err = -ENODEV;
309 goto err_reg_init;
310 }
311
312 err = led_classdev_register((struct device *)
313 &client->dev, &drvdata->led_dev);
314 if (err < 0) {
315 dev_err(&client->dev, "Register led class failed: %d\n", err);
316 err = -ENODEV;
317 goto err_class_register;
318 }
319
320 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
321 if (err < 0) {
322 dev_err(&client->dev, "File device creation failed: %d\n", err);
323 err = -ENODEV;
324 goto err_create_file;
325 }
326
327 return 0;
328
329err_create_file:
330 led_classdev_unregister(&drvdata->led_dev);
331err_class_register:
332err_reg_init:
333 kfree(drvdata);
334err_out:
335 return err;
336}
337
338static int __devexit lm3530_remove(struct i2c_client *client)
339{
340 struct lm3530_data *drvdata = i2c_get_clientdata(client);
341
342 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
343 led_classdev_unregister(&drvdata->led_dev);
344 kfree(drvdata);
345 return 0;
346}
347
348static const struct i2c_device_id lm3530_id[] = {
349 {LM3530_NAME, 0},
350 {}
351};
352
353static struct i2c_driver lm3530_i2c_driver = {
354 .probe = lm3530_probe,
355 .remove = lm3530_remove,
356 .id_table = lm3530_id,
357 .driver = {
358 .name = LM3530_NAME,
359 .owner = THIS_MODULE,
360 },
361};
362
363static int __init lm3530_init(void)
364{
365 return i2c_add_driver(&lm3530_i2c_driver);
366}
367
368static void __exit lm3530_exit(void)
369{
370 i2c_del_driver(&lm3530_i2c_driver);
371}
372
373module_init(lm3530_init);
374module_exit(lm3530_exit);
375
376MODULE_DESCRIPTION("Back Light driver for LM3530");
377MODULE_LICENSE("GPL v2");
378MODULE_AUTHOR("Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>");
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 80a3ae3c00b9..c0cff64a1ae6 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -534,7 +534,7 @@ static ssize_t lp5521_selftest(struct device *dev,
534} 534}
535 535
536/* led class device attributes */ 536/* led class device attributes */
537static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); 537static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
538static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); 538static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
539 539
540static struct attribute *lp5521_led_attributes[] = { 540static struct attribute *lp5521_led_attributes[] = {
@@ -548,15 +548,15 @@ static struct attribute_group lp5521_led_attribute_group = {
548}; 548};
549 549
550/* device attributes */ 550/* device attributes */
551static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, 551static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
552 show_engine1_mode, store_engine1_mode); 552 show_engine1_mode, store_engine1_mode);
553static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, 553static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
554 show_engine2_mode, store_engine2_mode); 554 show_engine2_mode, store_engine2_mode);
555static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, 555static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
556 show_engine3_mode, store_engine3_mode); 556 show_engine3_mode, store_engine3_mode);
557static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); 557static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
558static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); 558static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
559static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); 559static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
560static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); 560static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
561 561
562static struct attribute *lp5521_attributes[] = { 562static struct attribute *lp5521_attributes[] = {
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index d0c4068ecddd..e19fed25f137 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -713,7 +713,7 @@ static ssize_t store_current(struct device *dev,
713} 713}
714 714
715/* led class device attributes */ 715/* led class device attributes */
716static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); 716static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
717static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); 717static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
718 718
719static struct attribute *lp5523_led_attributes[] = { 719static struct attribute *lp5523_led_attributes[] = {
@@ -727,21 +727,21 @@ static struct attribute_group lp5523_led_attribute_group = {
727}; 727};
728 728
729/* device attributes */ 729/* device attributes */
730static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, 730static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
731 show_engine1_mode, store_engine1_mode); 731 show_engine1_mode, store_engine1_mode);
732static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, 732static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
733 show_engine2_mode, store_engine2_mode); 733 show_engine2_mode, store_engine2_mode);
734static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, 734static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
735 show_engine3_mode, store_engine3_mode); 735 show_engine3_mode, store_engine3_mode);
736static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO, 736static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUSR,
737 show_engine1_leds, store_engine1_leds); 737 show_engine1_leds, store_engine1_leds);
738static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO, 738static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUSR,
739 show_engine2_leds, store_engine2_leds); 739 show_engine2_leds, store_engine2_leds);
740static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO, 740static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUSR,
741 show_engine3_leds, store_engine3_leds); 741 show_engine3_leds, store_engine3_leds);
742static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); 742static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
743static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); 743static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
744static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); 744static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
745static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); 745static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL);
746 746
747static struct attribute *lp5523_attributes[] = { 747static struct attribute *lp5523_attributes[] = {
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index f369e56d6547..126ca7955f6e 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -22,6 +22,7 @@
22#include <linux/leds.h> 22#include <linux/leds.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/mfd/mc13783.h> 24#include <linux/mfd/mc13783.h>
25#include <linux/mfd/core.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26 27
27struct mc13783_led { 28struct mc13783_led {
@@ -183,7 +184,7 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
183 184
184static int __devinit mc13783_leds_prepare(struct platform_device *pdev) 185static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
185{ 186{
186 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 187 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 188 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
188 int ret = 0; 189 int ret = 0;
189 int reg = 0; 190 int reg = 0;
@@ -264,7 +265,7 @@ out:
264 265
265static int __devinit mc13783_led_probe(struct platform_device *pdev) 266static int __devinit mc13783_led_probe(struct platform_device *pdev)
266{ 267{
267 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 268 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
268 struct mc13783_led_platform_data *led_cur; 269 struct mc13783_led_platform_data *led_cur;
269 struct mc13783_led *led, *led_dat; 270 struct mc13783_led *led, *led_dat;
270 int ret, i; 271 int ret, i;
@@ -351,7 +352,7 @@ err_free:
351 352
352static int __devexit mc13783_led_remove(struct platform_device *pdev) 353static int __devexit mc13783_led_remove(struct platform_device *pdev)
353{ 354{
354 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 355 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
355 struct mc13783_led *led = platform_get_drvdata(pdev); 356 struct mc13783_led *led = platform_get_drvdata(pdev);
356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 357 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
357 int i; 358 int i;
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c
index 1739557a9038..7e764b8365e6 100644
--- a/drivers/leds/leds-net5501.c
+++ b/drivers/leds/leds-net5501.c
@@ -19,7 +19,7 @@
19 19
20#include <asm/geode.h> 20#include <asm/geode.h>
21 21
22static struct gpio_led net5501_leds[] = { 22static const struct gpio_led net5501_leds[] = {
23 { 23 {
24 .name = "error", 24 .name = "error",
25 .gpio = 6, 25 .gpio = 6,
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index afac338d5025..5bf63af09ddf 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -58,7 +58,7 @@ static struct i2c_driver pca9532_driver = {
58 .id_table = pca9532_id, 58 .id_table = pca9532_id,
59}; 59};
60 60
61/* We have two pwm/blinkers, but 16 possible leds to drive. Additionaly, 61/* We have two pwm/blinkers, but 16 possible leds to drive. Additionally,
62 * the clever Thecus people are using one pwm to drive the beeper. So, 62 * the clever Thecus people are using one pwm to drive the beeper. So,
63 * as a compromise we average one pwm to the values requested by all 63 * as a compromise we average one pwm to the values requested by all
64 * leds that are not ON/OFF. 64 * leds that are not ON/OFF.
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 3790816643be..8497f56f8e46 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -178,6 +178,10 @@ static int __devinit regulator_led_probe(struct platform_device *pdev)
178 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 178 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
179 led->vcc = vcc; 179 led->vcc = vcc;
180 180
181 /* to handle correctly an already enabled regulator */
182 if (regulator_is_enabled(led->vcc))
183 led->enabled = 1;
184
181 mutex_init(&led->mutex); 185 mutex_init(&led->mutex);
182 INIT_WORK(&led->work, led_work); 186 INIT_WORK(&led->work, led_work);
183 187
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index a04523273282..f14edd82cb00 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -215,13 +215,13 @@ static int wm8350_led_probe(struct platform_device *pdev)
215 215
216 isink = regulator_get(&pdev->dev, "led_isink"); 216 isink = regulator_get(&pdev->dev, "led_isink");
217 if (IS_ERR(isink)) { 217 if (IS_ERR(isink)) {
218 printk(KERN_ERR "%s: cant get ISINK\n", __func__); 218 printk(KERN_ERR "%s: can't get ISINK\n", __func__);
219 return PTR_ERR(isink); 219 return PTR_ERR(isink);
220 } 220 }
221 221
222 dcdc = regulator_get(&pdev->dev, "led_vcc"); 222 dcdc = regulator_get(&pdev->dev, "led_vcc");
223 if (IS_ERR(dcdc)) { 223 if (IS_ERR(dcdc)) {
224 printk(KERN_ERR "%s: cant get DCDC\n", __func__); 224 printk(KERN_ERR "%s: can't get DCDC\n", __func__);
225 ret = PTR_ERR(dcdc); 225 ret = PTR_ERR(dcdc);
226 goto err_isink; 226 goto err_isink;
227 } 227 }