aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2011-05-24 20:13:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 11:39:51 -0400
commit9b2da53f7627304cd4030cb4883908bfb1bce998 (patch)
treea76de46f2dd953d3d354a71c6dbf868fc58f3c7e /drivers/leds
parent402f758813f5b3c21de36e9f720aacc8972ca94e (diff)
drivers/leds/leds-lm3530.c: add regulator
Add add regulator support to lm3530 driver. The lm3530 driver needs to get proper regulator during device probe and enable it before accessing the device. Also it disables the regulator in case of brightness == LED_OFF, and puts it back during driver removal. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Cc: Lee Jones <lee.jones@linaro.org> Cc: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Cc: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lm3530.c73
1 files changed, 65 insertions, 8 deletions
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index b37e6186d0fa..4d7ce7631acf 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -17,6 +17,7 @@
17#include <linux/input.h> 17#include <linux/input.h>
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 21
21#define LM3530_LED_DEV "lcd-backlight" 22#define LM3530_LED_DEV "lcd-backlight"
22#define LM3530_NAME "lm3530-led" 23#define LM3530_NAME "lm3530-led"
@@ -96,12 +97,18 @@ static struct lm3530_mode_map mode_map[] = {
96 * @client: i2c client 97 * @client: i2c client
97 * @pdata: LM3530 platform data 98 * @pdata: LM3530 platform data
98 * @mode: mode of operation - manual, ALS, PWM 99 * @mode: mode of operation - manual, ALS, PWM
100 * @regulator: regulator
101 * @brighness: previous brightness value
102 * @enable: regulator is enabled
99 */ 103 */
100struct lm3530_data { 104struct lm3530_data {
101 struct led_classdev led_dev; 105 struct led_classdev led_dev;
102 struct i2c_client *client; 106 struct i2c_client *client;
103 struct lm3530_platform_data *pdata; 107 struct lm3530_platform_data *pdata;
104 enum lm3530_mode mode; 108 enum lm3530_mode mode;
109 struct regulator *regulator;
110 enum led_brightness brightness;
111 bool enable;
105}; 112};
106 113
107static const u8 lm3530_reg[LM3530_REG_MAX] = { 114static const u8 lm3530_reg[LM3530_REG_MAX] = {
@@ -172,7 +179,10 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
172 brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | 179 brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
173 (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); 180 (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
174 181
175 brightness = pltfm->brt_val; 182 if (drvdata->brightness)
183 brightness = drvdata->brightness;
184 else
185 brightness = drvdata->brightness = pltfm->brt_val;
176 186
177 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */ 187 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */
178 reg_val[1] = als_config; /* LM3530_ALS_CONFIG */ 188 reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
@@ -190,6 +200,16 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
190 reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ 200 reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */
191 reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ 201 reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
192 202
203 if (!drvdata->enable) {
204 ret = regulator_enable(drvdata->regulator);
205 if (ret) {
206 dev_err(&drvdata->client->dev,
207 "Enable regulator failed\n");
208 return ret;
209 }
210 drvdata->enable = true;
211 }
212
193 for (i = 0; i < LM3530_REG_MAX; i++) { 213 for (i = 0; i < LM3530_REG_MAX; i++) {
194 ret = i2c_smbus_write_byte_data(client, 214 ret = i2c_smbus_write_byte_data(client,
195 lm3530_reg[i], reg_val[i]); 215 lm3530_reg[i], reg_val[i]);
@@ -210,12 +230,31 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
210 switch (drvdata->mode) { 230 switch (drvdata->mode) {
211 case LM3530_BL_MODE_MANUAL: 231 case LM3530_BL_MODE_MANUAL:
212 232
233 if (!drvdata->enable) {
234 err = lm3530_init_registers(drvdata);
235 if (err) {
236 dev_err(&drvdata->client->dev,
237 "Register Init failed: %d\n", err);
238 break;
239 }
240 }
241
213 /* set the brightness in brightness control register*/ 242 /* set the brightness in brightness control register*/
214 err = i2c_smbus_write_byte_data(drvdata->client, 243 err = i2c_smbus_write_byte_data(drvdata->client,
215 LM3530_BRT_CTRL_REG, brt_val / 2); 244 LM3530_BRT_CTRL_REG, brt_val / 2);
216 if (err) 245 if (err)
217 dev_err(&drvdata->client->dev, 246 dev_err(&drvdata->client->dev,
218 "Unable to set brightness: %d\n", err); 247 "Unable to set brightness: %d\n", err);
248 else
249 drvdata->brightness = brt_val / 2;
250
251 if (brt_val == 0) {
252 err = regulator_disable(drvdata->regulator);
253 if (err)
254 dev_err(&drvdata->client->dev,
255 "Disable regulator failed\n");
256 drvdata->enable = false;
257 }
219 break; 258 break;
220 case LM3530_BL_MODE_ALS: 259 case LM3530_BL_MODE_ALS:
221 break; 260 break;
@@ -297,20 +336,31 @@ static int __devinit lm3530_probe(struct i2c_client *client,
297 drvdata->mode = pdata->mode; 336 drvdata->mode = pdata->mode;
298 drvdata->client = client; 337 drvdata->client = client;
299 drvdata->pdata = pdata; 338 drvdata->pdata = pdata;
339 drvdata->brightness = LED_OFF;
340 drvdata->enable = false;
300 drvdata->led_dev.name = LM3530_LED_DEV; 341 drvdata->led_dev.name = LM3530_LED_DEV;
301 drvdata->led_dev.brightness_set = lm3530_brightness_set; 342 drvdata->led_dev.brightness_set = lm3530_brightness_set;
302 343
303 i2c_set_clientdata(client, drvdata); 344 i2c_set_clientdata(client, drvdata);
304 345
305 err = lm3530_init_registers(drvdata); 346 drvdata->regulator = regulator_get(&client->dev, "vin");
306 if (err < 0) { 347 if (IS_ERR(drvdata->regulator)) {
307 dev_err(&client->dev, "Register Init failed: %d\n", err); 348 dev_err(&client->dev, "regulator get failed\n");
308 err = -ENODEV; 349 err = PTR_ERR(drvdata->regulator);
309 goto err_reg_init; 350 drvdata->regulator = NULL;
351 goto err_regulator_get;
310 } 352 }
311 353
312 err = led_classdev_register((struct device *) 354 if (drvdata->pdata->brt_val) {
313 &client->dev, &drvdata->led_dev); 355 err = lm3530_init_registers(drvdata);
356 if (err < 0) {
357 dev_err(&client->dev,
358 "Register Init failed: %d\n", err);
359 err = -ENODEV;
360 goto err_reg_init;
361 }
362 }
363 err = led_classdev_register(&client->dev, &drvdata->led_dev);
314 if (err < 0) { 364 if (err < 0) {
315 dev_err(&client->dev, "Register led class failed: %d\n", err); 365 dev_err(&client->dev, "Register led class failed: %d\n", err);
316 err = -ENODEV; 366 err = -ENODEV;
@@ -330,6 +380,9 @@ err_create_file:
330 led_classdev_unregister(&drvdata->led_dev); 380 led_classdev_unregister(&drvdata->led_dev);
331err_class_register: 381err_class_register:
332err_reg_init: 382err_reg_init:
383 regulator_put(drvdata->regulator);
384err_regulator_get:
385 i2c_set_clientdata(client, NULL);
333 kfree(drvdata); 386 kfree(drvdata);
334err_out: 387err_out:
335 return err; 388 return err;
@@ -340,6 +393,10 @@ static int __devexit lm3530_remove(struct i2c_client *client)
340 struct lm3530_data *drvdata = i2c_get_clientdata(client); 393 struct lm3530_data *drvdata = i2c_get_clientdata(client);
341 394
342 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode); 395 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
396
397 if (drvdata->enable)
398 regulator_disable(drvdata->regulator);
399 regulator_put(drvdata->regulator);
343 led_classdev_unregister(&drvdata->led_dev); 400 led_classdev_unregister(&drvdata->led_dev);
344 kfree(drvdata); 401 kfree(drvdata);
345 return 0; 402 return 0;