aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim, Milo <Milo.Kim@ti.com>2012-03-23 18:02:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 19:58:35 -0400
commitbb982009d3850759d3f4a4c853f9c456c48b6c2d (patch)
tree9bd6ed1979f86e5531f83240720cf0119b33a4e0
parente13d97865942e9dcf4fdd39d9fb9c5ae31e7c3d1 (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>
-rw-r--r--drivers/leds/leds-lm3530.c32
-rw-r--r--include/linux/led-lm3530.h9
2 files changed, 33 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) {
diff --git a/include/linux/led-lm3530.h b/include/linux/led-lm3530.h
index 8eb12357a110..eeae6e742471 100644
--- a/include/linux/led-lm3530.h
+++ b/include/linux/led-lm3530.h
@@ -72,6 +72,12 @@ enum lm3530_als_mode {
72 LM3530_INPUT_CEIL, /* Max of ALS1 and ALS2 */ 72 LM3530_INPUT_CEIL, /* Max of ALS1 and ALS2 */
73}; 73};
74 74
75/* PWM Platform Specific Data */
76struct lm3530_pwm_data {
77 void (*pwm_set_intensity) (int brightness, int max_brightness);
78 int (*pwm_get_intensity) (int max_brightness);
79};
80
75/** 81/**
76 * struct lm3530_platform_data 82 * struct lm3530_platform_data
77 * @mode: mode of operation i.e. Manual, ALS or PWM 83 * @mode: mode of operation i.e. Manual, ALS or PWM
@@ -87,6 +93,7 @@ enum lm3530_als_mode {
87 * @als_vmin: als input voltage calibrated for max brightness in mV 93 * @als_vmin: als input voltage calibrated for max brightness in mV
88 * @als_vmax: als input voltage calibrated for min brightness in mV 94 * @als_vmax: als input voltage calibrated for min brightness in mV
89 * @brt_val: brightness value (0-255) 95 * @brt_val: brightness value (0-255)
96 * @pwm_data: PWM control functions (only valid when the mode is PWM)
90 */ 97 */
91struct lm3530_platform_data { 98struct lm3530_platform_data {
92 enum lm3530_mode mode; 99 enum lm3530_mode mode;
@@ -107,6 +114,8 @@ struct lm3530_platform_data {
107 u32 als_vmax; 114 u32 als_vmax;
108 115
109 u8 brt_val; 116 u8 brt_val;
117
118 struct lm3530_pwm_data pwm_data;
110}; 119};
111 120
112#endif /* _LINUX_LED_LM3530_H__ */ 121#endif /* _LINUX_LED_LM3530_H__ */