diff options
author | Kim, Milo <Milo.Kim@ti.com> | 2012-03-23 18:02:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:35 -0400 |
commit | bb982009d3850759d3f4a4c853f9c456c48b6c2d (patch) | |
tree | 9bd6ed1979f86e5531f83240720cf0119b33a4e0 /drivers/leds/leds-lm3530.c | |
parent | e13d97865942e9dcf4fdd39d9fb9c5ae31e7c3d1 (diff) |
leds-lm3530: support pwm input mode
* add 'struct lm3530_pwm_data' in the platform data
The pwm data is the platform specific functions which generate the pwm.
The pwm data is only valid when brightness is pwm input mode.
Functions should be implemented by the pwm driver.
pwm_set_intensity() : set duty of pwm.
pwm_get_intensity() : get current the brightness.
* brightness control by pwm
If the control mode is pwm, then brightness is changed by the duty of
pwm=. So pwm platform function should be called in lm3530_brightness_set().
* do not update brightness register when pwm input mode
In pwm input mode, brightness register is not used.
If any value is updated in this register, then the led will be off.
* when input mode is changed, set duty of pwm to 0 if unnecessary.
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
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/leds-lm3530.c')
-rw-r--r-- | drivers/leds/leds-lm3530.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index ce79523a4d10..a889311eead1 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c | |||
@@ -157,6 +157,7 @@ static int lm3530_init_registers(struct lm3530_data *drvdata) | |||
157 | u32 als_vmin, als_vmax, als_vstep; | 157 | u32 als_vmin, als_vmax, als_vstep; |
158 | struct lm3530_platform_data *pltfm = drvdata->pdata; | 158 | struct lm3530_platform_data *pltfm = drvdata->pdata; |
159 | struct i2c_client *client = drvdata->client; | 159 | struct i2c_client *client = drvdata->client; |
160 | struct lm3530_pwm_data *pwm = &pltfm->pwm_data; | ||
160 | 161 | ||
161 | gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | | 162 | gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | |
162 | ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT); | 163 | ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT); |
@@ -240,6 +241,15 @@ static int lm3530_init_registers(struct lm3530_data *drvdata) | |||
240 | } | 241 | } |
241 | 242 | ||
242 | for (i = 0; i < LM3530_REG_MAX; i++) { | 243 | for (i = 0; i < LM3530_REG_MAX; i++) { |
244 | /* do not update brightness register when pwm mode */ | ||
245 | if (lm3530_reg[i] == LM3530_BRT_CTRL_REG && | ||
246 | drvdata->mode == LM3530_BL_MODE_PWM) { | ||
247 | if (pwm->pwm_set_intensity) | ||
248 | pwm->pwm_set_intensity(reg_val[i], | ||
249 | drvdata->led_dev.max_brightness); | ||
250 | continue; | ||
251 | } | ||
252 | |||
243 | ret = i2c_smbus_write_byte_data(client, | 253 | ret = i2c_smbus_write_byte_data(client, |
244 | lm3530_reg[i], reg_val[i]); | 254 | lm3530_reg[i], reg_val[i]); |
245 | if (ret) | 255 | if (ret) |
@@ -255,6 +265,9 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, | |||
255 | int err; | 265 | int err; |
256 | struct lm3530_data *drvdata = | 266 | struct lm3530_data *drvdata = |
257 | container_of(led_cdev, struct lm3530_data, led_dev); | 267 | container_of(led_cdev, struct lm3530_data, led_dev); |
268 | struct lm3530_platform_data *pdata = drvdata->pdata; | ||
269 | struct lm3530_pwm_data *pwm = &pdata->pwm_data; | ||
270 | u8 max_brightness = led_cdev->max_brightness; | ||
258 | 271 | ||
259 | switch (drvdata->mode) { | 272 | switch (drvdata->mode) { |
260 | case LM3530_BL_MODE_MANUAL: | 273 | case LM3530_BL_MODE_MANUAL: |
@@ -288,6 +301,8 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev, | |||
288 | case LM3530_BL_MODE_ALS: | 301 | case LM3530_BL_MODE_ALS: |
289 | break; | 302 | break; |
290 | case LM3530_BL_MODE_PWM: | 303 | case LM3530_BL_MODE_PWM: |
304 | if (pwm->pwm_set_intensity) | ||
305 | pwm->pwm_set_intensity(brt_val, max_brightness); | ||
291 | break; | 306 | break; |
292 | default: | 307 | default: |
293 | break; | 308 | break; |
@@ -318,23 +333,24 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute | |||
318 | { | 333 | { |
319 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 334 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
320 | struct lm3530_data *drvdata; | 335 | struct lm3530_data *drvdata; |
336 | struct lm3530_pwm_data *pwm; | ||
337 | u8 max_brightness; | ||
321 | int mode, err; | 338 | int mode, err; |
322 | 339 | ||
323 | drvdata = container_of(led_cdev, struct lm3530_data, led_dev); | 340 | drvdata = container_of(led_cdev, struct lm3530_data, led_dev); |
341 | pwm = &drvdata->pdata->pwm_data; | ||
342 | max_brightness = led_cdev->max_brightness; | ||
324 | mode = lm3530_get_mode_from_str(buf); | 343 | mode = lm3530_get_mode_from_str(buf); |
325 | if (mode < 0) { | 344 | if (mode < 0) { |
326 | dev_err(dev, "Invalid mode\n"); | 345 | dev_err(dev, "Invalid mode\n"); |
327 | return -EINVAL; | 346 | return -EINVAL; |
328 | } | 347 | } |
329 | 348 | ||
330 | if (mode == LM3530_BL_MODE_MANUAL) | 349 | drvdata->mode = mode; |
331 | drvdata->mode = LM3530_BL_MODE_MANUAL; | 350 | |
332 | else if (mode == LM3530_BL_MODE_ALS) | 351 | /* set pwm to low if unnecessary */ |
333 | drvdata->mode = LM3530_BL_MODE_ALS; | 352 | if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity) |
334 | else if (mode == LM3530_BL_MODE_PWM) { | 353 | pwm->pwm_set_intensity(0, max_brightness); |
335 | dev_err(dev, "PWM mode not supported\n"); | ||
336 | return -EINVAL; | ||
337 | } | ||
338 | 354 | ||
339 | err = lm3530_init_registers(drvdata); | 355 | err = lm3530_init_registers(drvdata); |
340 | if (err) { | 356 | if (err) { |