aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;