Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Shreshtha Kumar Sahu and committed by
Linus Torvalds
9b2da53f 402f7588

+65 -8
+65 -8
drivers/leds/leds-lm3530.c
··· 17 17 #include <linux/input.h> 18 18 #include <linux/led-lm3530.h> 19 19 #include <linux/types.h> 20 + #include <linux/regulator/consumer.h> 20 21 21 22 #define LM3530_LED_DEV "lcd-backlight" 22 23 #define LM3530_NAME "lm3530-led" ··· 97 96 * @client: i2c client 98 97 * @pdata: LM3530 platform data 99 98 * @mode: mode of operation - manual, ALS, PWM 99 + * @regulator: regulator 100 + * @brighness: previous brightness value 101 + * @enable: regulator is enabled 100 102 */ 101 103 struct lm3530_data { 102 104 struct led_classdev led_dev; 103 105 struct i2c_client *client; 104 106 struct lm3530_platform_data *pdata; 105 107 enum lm3530_mode mode; 108 + struct regulator *regulator; 109 + enum led_brightness brightness; 110 + bool enable; 106 111 }; 107 112 108 113 static const u8 lm3530_reg[LM3530_REG_MAX] = { ··· 179 172 brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | 180 173 (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); 181 174 182 - brightness = pltfm->brt_val; 175 + if (drvdata->brightness) 176 + brightness = drvdata->brightness; 177 + else 178 + brightness = drvdata->brightness = pltfm->brt_val; 183 179 184 180 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */ 185 181 reg_val[1] = als_config; /* LM3530_ALS_CONFIG */ ··· 199 189 reg_val[12] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */ 200 190 reg_val[13] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ 201 191 reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ 192 + 193 + if (!drvdata->enable) { 194 + ret = regulator_enable(drvdata->regulator); 195 + if (ret) { 196 + dev_err(&drvdata->client->dev, 197 + "Enable regulator failed\n"); 198 + return ret; 199 + } 200 + drvdata->enable = true; 201 + } 202 202 203 203 for (i = 0; i < LM3530_REG_MAX; i++) { 204 204 ret = i2c_smbus_write_byte_data(client, ··· 230 210 switch (drvdata->mode) { 231 211 case LM3530_BL_MODE_MANUAL: 232 212 213 + if (!drvdata->enable) { 214 + err = lm3530_init_registers(drvdata); 215 + if (err) { 216 + dev_err(&drvdata->client->dev, 217 + "Register Init failed: %d\n", err); 218 + break; 219 + } 220 + } 221 + 233 222 /* set the brightness in brightness control register*/ 234 223 err = i2c_smbus_write_byte_data(drvdata->client, 235 224 LM3530_BRT_CTRL_REG, brt_val / 2); 236 225 if (err) 237 226 dev_err(&drvdata->client->dev, 238 227 "Unable to set brightness: %d\n", err); 228 + else 229 + drvdata->brightness = brt_val / 2; 230 + 231 + if (brt_val == 0) { 232 + err = regulator_disable(drvdata->regulator); 233 + if (err) 234 + dev_err(&drvdata->client->dev, 235 + "Disable regulator failed\n"); 236 + drvdata->enable = false; 237 + } 239 238 break; 240 239 case LM3530_BL_MODE_ALS: 241 240 break; ··· 336 297 drvdata->mode = pdata->mode; 337 298 drvdata->client = client; 338 299 drvdata->pdata = pdata; 300 + drvdata->brightness = LED_OFF; 301 + drvdata->enable = false; 339 302 drvdata->led_dev.name = LM3530_LED_DEV; 340 303 drvdata->led_dev.brightness_set = lm3530_brightness_set; 341 304 342 305 i2c_set_clientdata(client, drvdata); 343 306 344 - err = lm3530_init_registers(drvdata); 345 - if (err < 0) { 346 - dev_err(&client->dev, "Register Init failed: %d\n", err); 347 - err = -ENODEV; 348 - goto err_reg_init; 307 + drvdata->regulator = regulator_get(&client->dev, "vin"); 308 + if (IS_ERR(drvdata->regulator)) { 309 + dev_err(&client->dev, "regulator get failed\n"); 310 + err = PTR_ERR(drvdata->regulator); 311 + drvdata->regulator = NULL; 312 + goto err_regulator_get; 349 313 } 350 314 351 - err = led_classdev_register((struct device *) 352 - &client->dev, &drvdata->led_dev); 315 + if (drvdata->pdata->brt_val) { 316 + err = lm3530_init_registers(drvdata); 317 + if (err < 0) { 318 + dev_err(&client->dev, 319 + "Register Init failed: %d\n", err); 320 + err = -ENODEV; 321 + goto err_reg_init; 322 + } 323 + } 324 + err = led_classdev_register(&client->dev, &drvdata->led_dev); 353 325 if (err < 0) { 354 326 dev_err(&client->dev, "Register led class failed: %d\n", err); 355 327 err = -ENODEV; ··· 380 330 led_classdev_unregister(&drvdata->led_dev); 381 331 err_class_register: 382 332 err_reg_init: 333 + regulator_put(drvdata->regulator); 334 + err_regulator_get: 335 + i2c_set_clientdata(client, NULL); 383 336 kfree(drvdata); 384 337 err_out: 385 338 return err; ··· 393 340 struct lm3530_data *drvdata = i2c_get_clientdata(client); 394 341 395 342 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode); 343 + 344 + if (drvdata->enable) 345 + regulator_disable(drvdata->regulator); 346 + regulator_put(drvdata->regulator); 396 347 led_classdev_unregister(&drvdata->led_dev); 397 348 kfree(drvdata); 398 349 return 0;