Skip to content

Commit

Permalink
drivers/leds/leds-lm3530.c: add regulator
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Shreshtha Kumar Sahu authored and torvalds committed May 25, 2011
1 parent 402f758 commit 9b2da53
Showing 1 changed file with 65 additions and 8 deletions.
73 changes: 65 additions & 8 deletions drivers/leds/leds-lm3530.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/input.h>
#include <linux/led-lm3530.h>
#include <linux/types.h>
#include <linux/regulator/consumer.h>

#define LM3530_LED_DEV "lcd-backlight"
#define LM3530_NAME "lm3530-led"
Expand Down Expand Up @@ -96,12 +97,18 @@ static struct lm3530_mode_map mode_map[] = {
* @client: i2c client
* @pdata: LM3530 platform data
* @mode: mode of operation - manual, ALS, PWM
* @regulator: regulator
* @brighness: previous brightness value
* @enable: regulator is enabled
*/
struct lm3530_data {
struct led_classdev led_dev;
struct i2c_client *client;
struct lm3530_platform_data *pdata;
enum lm3530_mode mode;
struct regulator *regulator;
enum led_brightness brightness;
bool enable;
};

static const u8 lm3530_reg[LM3530_REG_MAX] = {
Expand Down Expand Up @@ -172,7 +179,10 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
(pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);

brightness = pltfm->brt_val;
if (drvdata->brightness)
brightness = drvdata->brightness;
else
brightness = drvdata->brightness = pltfm->brt_val;

reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */
reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
Expand All @@ -190,6 +200,16 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */
reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */

if (!drvdata->enable) {
ret = regulator_enable(drvdata->regulator);
if (ret) {
dev_err(&drvdata->client->dev,
"Enable regulator failed\n");
return ret;
}
drvdata->enable = true;
}

for (i = 0; i < LM3530_REG_MAX; i++) {
ret = i2c_smbus_write_byte_data(client,
lm3530_reg[i], reg_val[i]);
Expand All @@ -210,12 +230,31 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
switch (drvdata->mode) {
case LM3530_BL_MODE_MANUAL:

if (!drvdata->enable) {
err = lm3530_init_registers(drvdata);
if (err) {
dev_err(&drvdata->client->dev,
"Register Init failed: %d\n", err);
break;
}
}

/* set the brightness in brightness control register*/
err = i2c_smbus_write_byte_data(drvdata->client,
LM3530_BRT_CTRL_REG, brt_val / 2);
if (err)
dev_err(&drvdata->client->dev,
"Unable to set brightness: %d\n", err);
else
drvdata->brightness = brt_val / 2;

if (brt_val == 0) {
err = regulator_disable(drvdata->regulator);
if (err)
dev_err(&drvdata->client->dev,
"Disable regulator failed\n");
drvdata->enable = false;
}
break;
case LM3530_BL_MODE_ALS:
break;
Expand Down Expand Up @@ -297,20 +336,31 @@ static int __devinit lm3530_probe(struct i2c_client *client,
drvdata->mode = pdata->mode;
drvdata->client = client;
drvdata->pdata = pdata;
drvdata->brightness = LED_OFF;
drvdata->enable = false;
drvdata->led_dev.name = LM3530_LED_DEV;
drvdata->led_dev.brightness_set = lm3530_brightness_set;

i2c_set_clientdata(client, drvdata);

err = lm3530_init_registers(drvdata);
if (err < 0) {
dev_err(&client->dev, "Register Init failed: %d\n", err);
err = -ENODEV;
goto err_reg_init;
drvdata->regulator = regulator_get(&client->dev, "vin");
if (IS_ERR(drvdata->regulator)) {
dev_err(&client->dev, "regulator get failed\n");
err = PTR_ERR(drvdata->regulator);
drvdata->regulator = NULL;
goto err_regulator_get;
}

err = led_classdev_register((struct device *)
&client->dev, &drvdata->led_dev);
if (drvdata->pdata->brt_val) {
err = lm3530_init_registers(drvdata);
if (err < 0) {
dev_err(&client->dev,
"Register Init failed: %d\n", err);
err = -ENODEV;
goto err_reg_init;
}
}
err = led_classdev_register(&client->dev, &drvdata->led_dev);
if (err < 0) {
dev_err(&client->dev, "Register led class failed: %d\n", err);
err = -ENODEV;
Expand All @@ -330,6 +380,9 @@ static int __devinit lm3530_probe(struct i2c_client *client,
led_classdev_unregister(&drvdata->led_dev);
err_class_register:
err_reg_init:
regulator_put(drvdata->regulator);
err_regulator_get:
i2c_set_clientdata(client, NULL);
kfree(drvdata);
err_out:
return err;
Expand All @@ -340,6 +393,10 @@ static int __devexit lm3530_remove(struct i2c_client *client)
struct lm3530_data *drvdata = i2c_get_clientdata(client);

device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);

if (drvdata->enable)
regulator_disable(drvdata->regulator);
regulator_put(drvdata->regulator);
led_classdev_unregister(&drvdata->led_dev);
kfree(drvdata);
return 0;
Expand Down

0 comments on commit 9b2da53

Please sign in to comment.