diff options
-rw-r--r-- | drivers/video/backlight/Kconfig | 6 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/backlight/lm3630_bl.c | 475 | ||||
-rw-r--r-- | drivers/video/backlight/lm3630a_bl.c | 483 | ||||
-rw-r--r-- | include/linux/platform_data/lm3630_bl.h | 57 | ||||
-rw-r--r-- | include/linux/platform_data/lm3630a_bl.h | 65 |
6 files changed, 552 insertions, 536 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a65dd063ecad..5a3eb2ecb525 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -368,12 +368,12 @@ config BACKLIGHT_AAT2870 | |||
368 | If you have a AnalogicTech AAT2870 say Y to enable the | 368 | If you have a AnalogicTech AAT2870 say Y to enable the |
369 | backlight driver. | 369 | backlight driver. |
370 | 370 | ||
371 | config BACKLIGHT_LM3630 | 371 | config BACKLIGHT_LM3630A |
372 | tristate "Backlight Driver for LM3630" | 372 | tristate "Backlight Driver for LM3630A" |
373 | depends on BACKLIGHT_CLASS_DEVICE && I2C | 373 | depends on BACKLIGHT_CLASS_DEVICE && I2C |
374 | select REGMAP_I2C | 374 | select REGMAP_I2C |
375 | help | 375 | help |
376 | This supports TI LM3630 Backlight Driver | 376 | This supports TI LM3630A Backlight Driver |
377 | 377 | ||
378 | config BACKLIGHT_LM3639 | 378 | config BACKLIGHT_LM3639 |
379 | tristate "Backlight Driver for LM3639" | 379 | tristate "Backlight Driver for LM3639" |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 38e1babb1946..bb820024f346 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -37,7 +37,7 @@ obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o | |||
37 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 37 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
38 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o | 38 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o |
39 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o | 39 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o |
40 | obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o | 40 | obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o |
41 | obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o | 41 | obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o |
42 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o | 42 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o |
43 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o | 43 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o |
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c deleted file mode 100644 index 76a62e978fc3..000000000000 --- a/drivers/video/backlight/lm3630_bl.c +++ /dev/null | |||
@@ -1,475 +0,0 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630 Backlight driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/platform_data/lm3630_bl.h> | ||
20 | |||
21 | #define REG_CTRL 0x00 | ||
22 | #define REG_CONFIG 0x01 | ||
23 | #define REG_BRT_A 0x03 | ||
24 | #define REG_BRT_B 0x04 | ||
25 | #define REG_INT_STATUS 0x09 | ||
26 | #define REG_INT_EN 0x0A | ||
27 | #define REG_FAULT 0x0B | ||
28 | #define REG_PWM_OUTLOW 0x12 | ||
29 | #define REG_PWM_OUTHIGH 0x13 | ||
30 | #define REG_MAX 0x1F | ||
31 | |||
32 | #define INT_DEBOUNCE_MSEC 10 | ||
33 | |||
34 | enum lm3630_leds { | ||
35 | BLED_ALL = 0, | ||
36 | BLED_1, | ||
37 | BLED_2 | ||
38 | }; | ||
39 | |||
40 | static const char * const bled_name[] = { | ||
41 | [BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */ | ||
42 | [BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */ | ||
43 | [BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */ | ||
44 | }; | ||
45 | |||
46 | struct lm3630_chip_data { | ||
47 | struct device *dev; | ||
48 | struct delayed_work work; | ||
49 | int irq; | ||
50 | struct workqueue_struct *irqthread; | ||
51 | struct lm3630_platform_data *pdata; | ||
52 | struct backlight_device *bled1; | ||
53 | struct backlight_device *bled2; | ||
54 | struct regmap *regmap; | ||
55 | }; | ||
56 | |||
57 | /* initialize chip */ | ||
58 | static int lm3630_chip_init(struct lm3630_chip_data *pchip) | ||
59 | { | ||
60 | int ret; | ||
61 | unsigned int reg_val; | ||
62 | struct lm3630_platform_data *pdata = pchip->pdata; | ||
63 | |||
64 | /*pwm control */ | ||
65 | reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03); | ||
66 | ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val); | ||
67 | if (ret < 0) | ||
68 | goto out; | ||
69 | |||
70 | /* bank control */ | ||
71 | reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) | | ||
72 | (pdata->bank_a_ctrl & 0x07); | ||
73 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val); | ||
74 | if (ret < 0) | ||
75 | goto out; | ||
76 | |||
77 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
78 | if (ret < 0) | ||
79 | goto out; | ||
80 | |||
81 | /* set initial brightness */ | ||
82 | if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) { | ||
83 | ret = regmap_write(pchip->regmap, | ||
84 | REG_BRT_A, pdata->init_brt_led1); | ||
85 | if (ret < 0) | ||
86 | goto out; | ||
87 | } | ||
88 | |||
89 | if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) { | ||
90 | ret = regmap_write(pchip->regmap, | ||
91 | REG_BRT_B, pdata->init_brt_led2); | ||
92 | if (ret < 0) | ||
93 | goto out; | ||
94 | } | ||
95 | return ret; | ||
96 | |||
97 | out: | ||
98 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* interrupt handling */ | ||
103 | static void lm3630_delayed_func(struct work_struct *work) | ||
104 | { | ||
105 | int ret; | ||
106 | unsigned int reg_val; | ||
107 | struct lm3630_chip_data *pchip; | ||
108 | |||
109 | pchip = container_of(work, struct lm3630_chip_data, work.work); | ||
110 | |||
111 | ret = regmap_read(pchip->regmap, REG_INT_STATUS, ®_val); | ||
112 | if (ret < 0) { | ||
113 | dev_err(pchip->dev, | ||
114 | "i2c failed to access REG_INT_STATUS Register\n"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val); | ||
119 | } | ||
120 | |||
121 | static irqreturn_t lm3630_isr_func(int irq, void *chip) | ||
122 | { | ||
123 | int ret; | ||
124 | struct lm3630_chip_data *pchip = chip; | ||
125 | unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); | ||
126 | |||
127 | queue_delayed_work(pchip->irqthread, &pchip->work, delay); | ||
128 | |||
129 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
130 | if (ret < 0) | ||
131 | goto out; | ||
132 | |||
133 | return IRQ_HANDLED; | ||
134 | out: | ||
135 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
136 | return IRQ_HANDLED; | ||
137 | } | ||
138 | |||
139 | static int lm3630_intr_config(struct lm3630_chip_data *pchip) | ||
140 | { | ||
141 | INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func); | ||
142 | pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd"); | ||
143 | if (!pchip->irqthread) { | ||
144 | dev_err(pchip->dev, "create irq thread fail...\n"); | ||
145 | return -1; | ||
146 | } | ||
147 | if (request_threaded_irq | ||
148 | (pchip->irq, NULL, lm3630_isr_func, | ||
149 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) { | ||
150 | dev_err(pchip->dev, "request threaded irq fail..\n"); | ||
151 | return -1; | ||
152 | } | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static bool | ||
157 | set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip) | ||
158 | { | ||
159 | if (!pchip->pdata->pwm_set_intensity) | ||
160 | return false; | ||
161 | pchip->pdata->pwm_set_intensity(bl->props.brightness - 1, | ||
162 | pchip->pdata->pwm_period); | ||
163 | return true; | ||
164 | } | ||
165 | |||
166 | /* update and get brightness */ | ||
167 | static int lm3630_bank_a_update_status(struct backlight_device *bl) | ||
168 | { | ||
169 | int ret; | ||
170 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
171 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
172 | |||
173 | /* brightness 0 means disable */ | ||
174 | if (!bl->props.brightness) { | ||
175 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00); | ||
176 | if (ret < 0) | ||
177 | goto out; | ||
178 | return bl->props.brightness; | ||
179 | } | ||
180 | |||
181 | /* pwm control */ | ||
182 | if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
183 | if (!set_intensity(bl, pchip)) | ||
184 | dev_err(pchip->dev, "No pwm control func. in plat-data\n"); | ||
185 | } else { | ||
186 | |||
187 | /* i2c control */ | ||
188 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
189 | if (ret < 0) | ||
190 | goto out; | ||
191 | mdelay(1); | ||
192 | ret = regmap_write(pchip->regmap, | ||
193 | REG_BRT_A, bl->props.brightness - 1); | ||
194 | if (ret < 0) | ||
195 | goto out; | ||
196 | } | ||
197 | return bl->props.brightness; | ||
198 | out: | ||
199 | dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); | ||
200 | return bl->props.brightness; | ||
201 | } | ||
202 | |||
203 | static int lm3630_bank_a_get_brightness(struct backlight_device *bl) | ||
204 | { | ||
205 | unsigned int reg_val; | ||
206 | int brightness, ret; | ||
207 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
208 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
209 | |||
210 | if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
211 | ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); | ||
212 | if (ret < 0) | ||
213 | goto out; | ||
214 | brightness = reg_val & 0x01; | ||
215 | ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); | ||
216 | if (ret < 0) | ||
217 | goto out; | ||
218 | brightness = ((brightness << 8) | reg_val) + 1; | ||
219 | } else { | ||
220 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
221 | if (ret < 0) | ||
222 | goto out; | ||
223 | mdelay(1); | ||
224 | ret = regmap_read(pchip->regmap, REG_BRT_A, ®_val); | ||
225 | if (ret < 0) | ||
226 | goto out; | ||
227 | brightness = reg_val + 1; | ||
228 | } | ||
229 | bl->props.brightness = brightness; | ||
230 | return bl->props.brightness; | ||
231 | out: | ||
232 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static const struct backlight_ops lm3630_bank_a_ops = { | ||
237 | .options = BL_CORE_SUSPENDRESUME, | ||
238 | .update_status = lm3630_bank_a_update_status, | ||
239 | .get_brightness = lm3630_bank_a_get_brightness, | ||
240 | }; | ||
241 | |||
242 | static int lm3630_bank_b_update_status(struct backlight_device *bl) | ||
243 | { | ||
244 | int ret; | ||
245 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
246 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
247 | |||
248 | if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
249 | if (!set_intensity(bl, pchip)) | ||
250 | dev_err(pchip->dev, | ||
251 | "no pwm control func. in plat-data\n"); | ||
252 | } else { | ||
253 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
254 | if (ret < 0) | ||
255 | goto out; | ||
256 | mdelay(1); | ||
257 | ret = regmap_write(pchip->regmap, | ||
258 | REG_BRT_B, bl->props.brightness - 1); | ||
259 | } | ||
260 | return bl->props.brightness; | ||
261 | out: | ||
262 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
263 | return bl->props.brightness; | ||
264 | } | ||
265 | |||
266 | static int lm3630_bank_b_get_brightness(struct backlight_device *bl) | ||
267 | { | ||
268 | unsigned int reg_val; | ||
269 | int brightness, ret; | ||
270 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
271 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
272 | |||
273 | if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
274 | ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); | ||
275 | if (ret < 0) | ||
276 | goto out; | ||
277 | brightness = reg_val & 0x01; | ||
278 | ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); | ||
279 | if (ret < 0) | ||
280 | goto out; | ||
281 | brightness = ((brightness << 8) | reg_val) + 1; | ||
282 | } else { | ||
283 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
284 | if (ret < 0) | ||
285 | goto out; | ||
286 | mdelay(1); | ||
287 | ret = regmap_read(pchip->regmap, REG_BRT_B, ®_val); | ||
288 | if (ret < 0) | ||
289 | goto out; | ||
290 | brightness = reg_val + 1; | ||
291 | } | ||
292 | bl->props.brightness = brightness; | ||
293 | |||
294 | return bl->props.brightness; | ||
295 | out: | ||
296 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
297 | return bl->props.brightness; | ||
298 | } | ||
299 | |||
300 | static const struct backlight_ops lm3630_bank_b_ops = { | ||
301 | .options = BL_CORE_SUSPENDRESUME, | ||
302 | .update_status = lm3630_bank_b_update_status, | ||
303 | .get_brightness = lm3630_bank_b_get_brightness, | ||
304 | }; | ||
305 | |||
306 | static int lm3630_backlight_register(struct lm3630_chip_data *pchip, | ||
307 | enum lm3630_leds ledno) | ||
308 | { | ||
309 | const char *name = bled_name[ledno]; | ||
310 | struct backlight_properties props; | ||
311 | struct lm3630_platform_data *pdata = pchip->pdata; | ||
312 | |||
313 | props.type = BACKLIGHT_RAW; | ||
314 | switch (ledno) { | ||
315 | case BLED_1: | ||
316 | case BLED_ALL: | ||
317 | props.brightness = pdata->init_brt_led1; | ||
318 | props.max_brightness = pdata->max_brt_led1; | ||
319 | pchip->bled1 = | ||
320 | backlight_device_register(name, pchip->dev, pchip, | ||
321 | &lm3630_bank_a_ops, &props); | ||
322 | if (IS_ERR(pchip->bled1)) | ||
323 | return PTR_ERR(pchip->bled1); | ||
324 | break; | ||
325 | case BLED_2: | ||
326 | props.brightness = pdata->init_brt_led2; | ||
327 | props.max_brightness = pdata->max_brt_led2; | ||
328 | pchip->bled2 = | ||
329 | backlight_device_register(name, pchip->dev, pchip, | ||
330 | &lm3630_bank_b_ops, &props); | ||
331 | if (IS_ERR(pchip->bled2)) | ||
332 | return PTR_ERR(pchip->bled2); | ||
333 | break; | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip) | ||
339 | { | ||
340 | if (pchip->bled1) | ||
341 | backlight_device_unregister(pchip->bled1); | ||
342 | if (pchip->bled2) | ||
343 | backlight_device_unregister(pchip->bled2); | ||
344 | } | ||
345 | |||
346 | static const struct regmap_config lm3630_regmap = { | ||
347 | .reg_bits = 8, | ||
348 | .val_bits = 8, | ||
349 | .max_register = REG_MAX, | ||
350 | }; | ||
351 | |||
352 | static int lm3630_probe(struct i2c_client *client, | ||
353 | const struct i2c_device_id *id) | ||
354 | { | ||
355 | struct lm3630_platform_data *pdata = client->dev.platform_data; | ||
356 | struct lm3630_chip_data *pchip; | ||
357 | int ret; | ||
358 | |||
359 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
360 | dev_err(&client->dev, "fail : i2c functionality check...\n"); | ||
361 | return -EOPNOTSUPP; | ||
362 | } | ||
363 | |||
364 | if (pdata == NULL) { | ||
365 | dev_err(&client->dev, "fail : no platform data.\n"); | ||
366 | return -ENODATA; | ||
367 | } | ||
368 | |||
369 | pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data), | ||
370 | GFP_KERNEL); | ||
371 | if (!pchip) | ||
372 | return -ENOMEM; | ||
373 | pchip->pdata = pdata; | ||
374 | pchip->dev = &client->dev; | ||
375 | |||
376 | pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap); | ||
377 | if (IS_ERR(pchip->regmap)) { | ||
378 | ret = PTR_ERR(pchip->regmap); | ||
379 | dev_err(&client->dev, "fail : allocate register map: %d\n", | ||
380 | ret); | ||
381 | return ret; | ||
382 | } | ||
383 | i2c_set_clientdata(client, pchip); | ||
384 | |||
385 | /* chip initialize */ | ||
386 | ret = lm3630_chip_init(pchip); | ||
387 | if (ret < 0) { | ||
388 | dev_err(&client->dev, "fail : init chip\n"); | ||
389 | goto err_chip_init; | ||
390 | } | ||
391 | |||
392 | switch (pdata->bank_a_ctrl) { | ||
393 | case BANK_A_CTRL_ALL: | ||
394 | ret = lm3630_backlight_register(pchip, BLED_ALL); | ||
395 | pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; | ||
396 | break; | ||
397 | case BANK_A_CTRL_LED1: | ||
398 | ret = lm3630_backlight_register(pchip, BLED_1); | ||
399 | break; | ||
400 | case BANK_A_CTRL_LED2: | ||
401 | ret = lm3630_backlight_register(pchip, BLED_2); | ||
402 | pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; | ||
403 | break; | ||
404 | default: | ||
405 | break; | ||
406 | } | ||
407 | |||
408 | if (ret < 0) | ||
409 | goto err_bl_reg; | ||
410 | |||
411 | if (pdata->bank_b_ctrl && pchip->bled2 == NULL) { | ||
412 | ret = lm3630_backlight_register(pchip, BLED_2); | ||
413 | if (ret < 0) | ||
414 | goto err_bl_reg; | ||
415 | } | ||
416 | |||
417 | /* interrupt enable : irq 0 is not allowed for lm3630 */ | ||
418 | pchip->irq = client->irq; | ||
419 | if (pchip->irq) | ||
420 | lm3630_intr_config(pchip); | ||
421 | |||
422 | dev_info(&client->dev, "LM3630 backlight register OK.\n"); | ||
423 | return 0; | ||
424 | |||
425 | err_bl_reg: | ||
426 | dev_err(&client->dev, "fail : backlight register.\n"); | ||
427 | lm3630_backlight_unregister(pchip); | ||
428 | err_chip_init: | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static int lm3630_remove(struct i2c_client *client) | ||
433 | { | ||
434 | int ret; | ||
435 | struct lm3630_chip_data *pchip = i2c_get_clientdata(client); | ||
436 | |||
437 | ret = regmap_write(pchip->regmap, REG_BRT_A, 0); | ||
438 | if (ret < 0) | ||
439 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
440 | |||
441 | ret = regmap_write(pchip->regmap, REG_BRT_B, 0); | ||
442 | if (ret < 0) | ||
443 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
444 | |||
445 | lm3630_backlight_unregister(pchip); | ||
446 | if (pchip->irq) { | ||
447 | free_irq(pchip->irq, pchip); | ||
448 | flush_workqueue(pchip->irqthread); | ||
449 | destroy_workqueue(pchip->irqthread); | ||
450 | } | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static const struct i2c_device_id lm3630_id[] = { | ||
455 | {LM3630_NAME, 0}, | ||
456 | {} | ||
457 | }; | ||
458 | |||
459 | MODULE_DEVICE_TABLE(i2c, lm3630_id); | ||
460 | |||
461 | static struct i2c_driver lm3630_i2c_driver = { | ||
462 | .driver = { | ||
463 | .name = LM3630_NAME, | ||
464 | }, | ||
465 | .probe = lm3630_probe, | ||
466 | .remove = lm3630_remove, | ||
467 | .id_table = lm3630_id, | ||
468 | }; | ||
469 | |||
470 | module_i2c_driver(lm3630_i2c_driver); | ||
471 | |||
472 | MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630"); | ||
473 | MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); | ||
474 | MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); | ||
475 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c new file mode 100644 index 000000000000..cf40cc8e662b --- /dev/null +++ b/drivers/video/backlight/lm3630a_bl.c | |||
@@ -0,0 +1,483 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630A Backlight driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/pwm.h> | ||
20 | #include <linux/platform_data/lm3630a_bl.h> | ||
21 | |||
22 | #define REG_CTRL 0x00 | ||
23 | #define REG_BOOST 0x02 | ||
24 | #define REG_CONFIG 0x01 | ||
25 | #define REG_BRT_A 0x03 | ||
26 | #define REG_BRT_B 0x04 | ||
27 | #define REG_I_A 0x05 | ||
28 | #define REG_I_B 0x06 | ||
29 | #define REG_INT_STATUS 0x09 | ||
30 | #define REG_INT_EN 0x0A | ||
31 | #define REG_FAULT 0x0B | ||
32 | #define REG_PWM_OUTLOW 0x12 | ||
33 | #define REG_PWM_OUTHIGH 0x13 | ||
34 | #define REG_MAX 0x1F | ||
35 | |||
36 | #define INT_DEBOUNCE_MSEC 10 | ||
37 | struct lm3630a_chip { | ||
38 | struct device *dev; | ||
39 | struct delayed_work work; | ||
40 | |||
41 | int irq; | ||
42 | struct workqueue_struct *irqthread; | ||
43 | struct lm3630a_platform_data *pdata; | ||
44 | struct backlight_device *bleda; | ||
45 | struct backlight_device *bledb; | ||
46 | struct regmap *regmap; | ||
47 | struct pwm_device *pwmd; | ||
48 | }; | ||
49 | |||
50 | /* i2c access */ | ||
51 | static int lm3630a_read(struct lm3630a_chip *pchip, unsigned int reg) | ||
52 | { | ||
53 | int rval; | ||
54 | unsigned int reg_val; | ||
55 | |||
56 | rval = regmap_read(pchip->regmap, reg, ®_val); | ||
57 | if (rval < 0) | ||
58 | return rval; | ||
59 | return reg_val & 0xFF; | ||
60 | } | ||
61 | |||
62 | static int lm3630a_write(struct lm3630a_chip *pchip, | ||
63 | unsigned int reg, unsigned int data) | ||
64 | { | ||
65 | return regmap_write(pchip->regmap, reg, data); | ||
66 | } | ||
67 | |||
68 | static int lm3630a_update(struct lm3630a_chip *pchip, | ||
69 | unsigned int reg, unsigned int mask, | ||
70 | unsigned int data) | ||
71 | { | ||
72 | return regmap_update_bits(pchip->regmap, reg, mask, data); | ||
73 | } | ||
74 | |||
75 | /* initialize chip */ | ||
76 | static int lm3630a_chip_init(struct lm3630a_chip *pchip) | ||
77 | { | ||
78 | int rval; | ||
79 | struct lm3630a_platform_data *pdata = pchip->pdata; | ||
80 | |||
81 | usleep_range(1000, 2000); | ||
82 | /* set Filter Strength Register */ | ||
83 | rval = lm3630a_write(pchip, 0x50, 0x03); | ||
84 | /* set Cofig. register */ | ||
85 | rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); | ||
86 | /* set boost control */ | ||
87 | rval |= lm3630a_write(pchip, REG_BOOST, 0x38); | ||
88 | /* set current A */ | ||
89 | rval |= lm3630a_update(pchip, REG_I_A, 0x1F, 0x1F); | ||
90 | /* set current B */ | ||
91 | rval |= lm3630a_write(pchip, REG_I_B, 0x1F); | ||
92 | /* set control */ | ||
93 | rval |= | ||
94 | lm3630a_write(pchip, REG_CTRL, pdata->leda_ctrl | pdata->ledb_ctrl); | ||
95 | usleep_range(1000, 2000); | ||
96 | /* set brightness A and B */ | ||
97 | rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt); | ||
98 | rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt); | ||
99 | |||
100 | if (rval < 0) | ||
101 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
102 | return rval; | ||
103 | } | ||
104 | |||
105 | /* interrupt handling */ | ||
106 | static void lm3630a_delayed_func(struct work_struct *work) | ||
107 | { | ||
108 | unsigned int rval; | ||
109 | struct lm3630a_chip *pchip; | ||
110 | |||
111 | pchip = container_of(work, struct lm3630a_chip, work.work); | ||
112 | |||
113 | rval = lm3630a_read(pchip, REG_INT_STATUS); | ||
114 | if (rval < 0) { | ||
115 | dev_err(pchip->dev, | ||
116 | "i2c failed to access REG_INT_STATUS Register\n"); | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", rval); | ||
121 | } | ||
122 | |||
123 | static irqreturn_t lm3630a_isr_func(int irq, void *chip) | ||
124 | { | ||
125 | int rval; | ||
126 | struct lm3630a_chip *pchip = chip; | ||
127 | unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); | ||
128 | |||
129 | queue_delayed_work(pchip->irqthread, &pchip->work, delay); | ||
130 | |||
131 | rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); | ||
132 | if (rval < 0) { | ||
133 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
134 | return IRQ_NONE; | ||
135 | } | ||
136 | return IRQ_HANDLED; | ||
137 | } | ||
138 | |||
139 | static int lm3630a_intr_config(struct lm3630a_chip *pchip) | ||
140 | { | ||
141 | int rval; | ||
142 | |||
143 | rval = lm3630a_write(pchip, REG_INT_EN, 0x87); | ||
144 | if (rval < 0) | ||
145 | return rval; | ||
146 | |||
147 | INIT_DELAYED_WORK(&pchip->work, lm3630a_delayed_func); | ||
148 | pchip->irqthread = create_singlethread_workqueue("lm3630a-irqthd"); | ||
149 | if (!pchip->irqthread) { | ||
150 | dev_err(pchip->dev, "create irq thread fail\n"); | ||
151 | return -ENOMEM; | ||
152 | } | ||
153 | if (request_threaded_irq | ||
154 | (pchip->irq, NULL, lm3630a_isr_func, | ||
155 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630a_irq", pchip)) { | ||
156 | dev_err(pchip->dev, "request threaded irq fail\n"); | ||
157 | return -ENOMEM; | ||
158 | } | ||
159 | return rval; | ||
160 | } | ||
161 | |||
162 | static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) | ||
163 | { | ||
164 | unsigned int period = pwm_get_period(pchip->pwmd); | ||
165 | unsigned int duty = br * period / br_max; | ||
166 | |||
167 | pwm_config(pchip->pwmd, duty, period); | ||
168 | if (duty) | ||
169 | pwm_enable(pchip->pwmd); | ||
170 | else | ||
171 | pwm_disable(pchip->pwmd); | ||
172 | } | ||
173 | |||
174 | /* update and get brightness */ | ||
175 | static int lm3630a_bank_a_update_status(struct backlight_device *bl) | ||
176 | { | ||
177 | int ret; | ||
178 | struct lm3630a_chip *pchip = bl_get_data(bl); | ||
179 | enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
180 | |||
181 | /* pwm control */ | ||
182 | if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { | ||
183 | lm3630a_pwm_ctrl(pchip, bl->props.brightness, | ||
184 | bl->props.max_brightness); | ||
185 | return bl->props.brightness; | ||
186 | } | ||
187 | |||
188 | /* disable sleep */ | ||
189 | ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); | ||
190 | if (ret < 0) | ||
191 | goto out_i2c_err; | ||
192 | usleep_range(1000, 2000); | ||
193 | /* minimum brightness is 0x04 */ | ||
194 | ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); | ||
195 | if (bl->props.brightness < 0x4) | ||
196 | ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); | ||
197 | else | ||
198 | ret |= lm3630a_update(pchip, REG_CTRL, | ||
199 | LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE); | ||
200 | if (ret < 0) | ||
201 | goto out_i2c_err; | ||
202 | return bl->props.brightness; | ||
203 | |||
204 | out_i2c_err: | ||
205 | dev_err(pchip->dev, "i2c failed to access\n"); | ||
206 | return bl->props.brightness; | ||
207 | } | ||
208 | |||
209 | static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) | ||
210 | { | ||
211 | int brightness, rval; | ||
212 | struct lm3630a_chip *pchip = bl_get_data(bl); | ||
213 | enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
214 | |||
215 | if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { | ||
216 | rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); | ||
217 | if (rval < 0) | ||
218 | goto out_i2c_err; | ||
219 | brightness = (rval & 0x01) << 8; | ||
220 | rval = lm3630a_read(pchip, REG_PWM_OUTLOW); | ||
221 | if (rval < 0) | ||
222 | goto out_i2c_err; | ||
223 | brightness |= rval; | ||
224 | goto out; | ||
225 | } | ||
226 | |||
227 | /* disable sleep */ | ||
228 | rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); | ||
229 | if (rval < 0) | ||
230 | goto out_i2c_err; | ||
231 | usleep_range(1000, 2000); | ||
232 | rval = lm3630a_read(pchip, REG_BRT_A); | ||
233 | if (rval < 0) | ||
234 | goto out_i2c_err; | ||
235 | brightness = rval; | ||
236 | |||
237 | out: | ||
238 | bl->props.brightness = brightness; | ||
239 | return bl->props.brightness; | ||
240 | out_i2c_err: | ||
241 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static const struct backlight_ops lm3630a_bank_a_ops = { | ||
246 | .options = BL_CORE_SUSPENDRESUME, | ||
247 | .update_status = lm3630a_bank_a_update_status, | ||
248 | .get_brightness = lm3630a_bank_a_get_brightness, | ||
249 | }; | ||
250 | |||
251 | /* update and get brightness */ | ||
252 | static int lm3630a_bank_b_update_status(struct backlight_device *bl) | ||
253 | { | ||
254 | int ret; | ||
255 | struct lm3630a_chip *pchip = bl_get_data(bl); | ||
256 | enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
257 | |||
258 | /* pwm control */ | ||
259 | if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { | ||
260 | lm3630a_pwm_ctrl(pchip, bl->props.brightness, | ||
261 | bl->props.max_brightness); | ||
262 | return bl->props.brightness; | ||
263 | } | ||
264 | |||
265 | /* disable sleep */ | ||
266 | ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); | ||
267 | if (ret < 0) | ||
268 | goto out_i2c_err; | ||
269 | usleep_range(1000, 2000); | ||
270 | /* minimum brightness is 0x04 */ | ||
271 | ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); | ||
272 | if (bl->props.brightness < 0x4) | ||
273 | ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); | ||
274 | else | ||
275 | ret |= lm3630a_update(pchip, REG_CTRL, | ||
276 | LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE); | ||
277 | if (ret < 0) | ||
278 | goto out_i2c_err; | ||
279 | return bl->props.brightness; | ||
280 | |||
281 | out_i2c_err: | ||
282 | dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); | ||
283 | return bl->props.brightness; | ||
284 | } | ||
285 | |||
286 | static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) | ||
287 | { | ||
288 | int brightness, rval; | ||
289 | struct lm3630a_chip *pchip = bl_get_data(bl); | ||
290 | enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
291 | |||
292 | if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { | ||
293 | rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); | ||
294 | if (rval < 0) | ||
295 | goto out_i2c_err; | ||
296 | brightness = (rval & 0x01) << 8; | ||
297 | rval = lm3630a_read(pchip, REG_PWM_OUTLOW); | ||
298 | if (rval < 0) | ||
299 | goto out_i2c_err; | ||
300 | brightness |= rval; | ||
301 | goto out; | ||
302 | } | ||
303 | |||
304 | /* disable sleep */ | ||
305 | rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); | ||
306 | if (rval < 0) | ||
307 | goto out_i2c_err; | ||
308 | usleep_range(1000, 2000); | ||
309 | rval = lm3630a_read(pchip, REG_BRT_B); | ||
310 | if (rval < 0) | ||
311 | goto out_i2c_err; | ||
312 | brightness = rval; | ||
313 | |||
314 | out: | ||
315 | bl->props.brightness = brightness; | ||
316 | return bl->props.brightness; | ||
317 | out_i2c_err: | ||
318 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static const struct backlight_ops lm3630a_bank_b_ops = { | ||
323 | .options = BL_CORE_SUSPENDRESUME, | ||
324 | .update_status = lm3630a_bank_b_update_status, | ||
325 | .get_brightness = lm3630a_bank_b_get_brightness, | ||
326 | }; | ||
327 | |||
328 | static int lm3630a_backlight_register(struct lm3630a_chip *pchip) | ||
329 | { | ||
330 | struct backlight_properties props; | ||
331 | struct lm3630a_platform_data *pdata = pchip->pdata; | ||
332 | |||
333 | props.type = BACKLIGHT_RAW; | ||
334 | if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { | ||
335 | props.brightness = pdata->leda_init_brt; | ||
336 | props.max_brightness = pdata->leda_max_brt; | ||
337 | pchip->bleda = | ||
338 | devm_backlight_device_register(pchip->dev, "lm3630a_leda", | ||
339 | pchip->dev, pchip, | ||
340 | &lm3630a_bank_a_ops, &props); | ||
341 | if (IS_ERR(pchip->bleda)) | ||
342 | return PTR_ERR(pchip->bleda); | ||
343 | } | ||
344 | |||
345 | if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) && | ||
346 | (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { | ||
347 | props.brightness = pdata->ledb_init_brt; | ||
348 | props.max_brightness = pdata->ledb_max_brt; | ||
349 | pchip->bledb = | ||
350 | devm_backlight_device_register(pchip->dev, "lm3630a_ledb", | ||
351 | pchip->dev, pchip, | ||
352 | &lm3630a_bank_b_ops, &props); | ||
353 | if (IS_ERR(pchip->bledb)) | ||
354 | return PTR_ERR(pchip->bledb); | ||
355 | } | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static const struct regmap_config lm3630a_regmap = { | ||
360 | .reg_bits = 8, | ||
361 | .val_bits = 8, | ||
362 | .max_register = REG_MAX, | ||
363 | }; | ||
364 | |||
365 | static int lm3630a_probe(struct i2c_client *client, | ||
366 | const struct i2c_device_id *id) | ||
367 | { | ||
368 | struct lm3630a_platform_data *pdata = client->dev.platform_data; | ||
369 | struct lm3630a_chip *pchip; | ||
370 | int rval; | ||
371 | |||
372 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
373 | dev_err(&client->dev, "fail : i2c functionality check\n"); | ||
374 | return -EOPNOTSUPP; | ||
375 | } | ||
376 | |||
377 | pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip), | ||
378 | GFP_KERNEL); | ||
379 | if (!pchip) | ||
380 | return -ENOMEM; | ||
381 | pchip->dev = &client->dev; | ||
382 | |||
383 | pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap); | ||
384 | if (IS_ERR(pchip->regmap)) { | ||
385 | rval = PTR_ERR(pchip->regmap); | ||
386 | dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval); | ||
387 | return rval; | ||
388 | } | ||
389 | |||
390 | i2c_set_clientdata(client, pchip); | ||
391 | if (pdata == NULL) { | ||
392 | pchip->pdata = devm_kzalloc(pchip->dev, | ||
393 | sizeof(struct | ||
394 | lm3630a_platform_data), | ||
395 | GFP_KERNEL); | ||
396 | if (pchip->pdata == NULL) | ||
397 | return -ENOMEM; | ||
398 | /* default values */ | ||
399 | pchip->pdata->leda_ctrl = LM3630A_LEDA_ENABLE; | ||
400 | pchip->pdata->ledb_ctrl = LM3630A_LEDB_ENABLE; | ||
401 | pchip->pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; | ||
402 | pchip->pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; | ||
403 | pchip->pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; | ||
404 | pchip->pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; | ||
405 | } else { | ||
406 | pchip->pdata = pdata; | ||
407 | } | ||
408 | /* chip initialize */ | ||
409 | rval = lm3630a_chip_init(pchip); | ||
410 | if (rval < 0) { | ||
411 | dev_err(&client->dev, "fail : init chip\n"); | ||
412 | return rval; | ||
413 | } | ||
414 | /* backlight register */ | ||
415 | rval = lm3630a_backlight_register(pchip); | ||
416 | if (rval < 0) { | ||
417 | dev_err(&client->dev, "fail : backlight register.\n"); | ||
418 | return rval; | ||
419 | } | ||
420 | /* pwm */ | ||
421 | if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) { | ||
422 | pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm"); | ||
423 | if (IS_ERR(pchip->pwmd)) { | ||
424 | dev_err(&client->dev, "fail : get pwm device\n"); | ||
425 | return PTR_ERR(pchip->pwmd); | ||
426 | } | ||
427 | } | ||
428 | pchip->pwmd->period = pdata->pwm_period; | ||
429 | |||
430 | /* interrupt enable : irq 0 is not allowed */ | ||
431 | pchip->irq = client->irq; | ||
432 | if (pchip->irq) { | ||
433 | rval = lm3630a_intr_config(pchip); | ||
434 | if (rval < 0) | ||
435 | return rval; | ||
436 | } | ||
437 | dev_info(&client->dev, "LM3630A backlight register OK.\n"); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int lm3630a_remove(struct i2c_client *client) | ||
442 | { | ||
443 | int rval; | ||
444 | struct lm3630a_chip *pchip = i2c_get_clientdata(client); | ||
445 | |||
446 | rval = lm3630a_write(pchip, REG_BRT_A, 0); | ||
447 | if (rval < 0) | ||
448 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
449 | |||
450 | rval = lm3630a_write(pchip, REG_BRT_B, 0); | ||
451 | if (rval < 0) | ||
452 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
453 | |||
454 | if (pchip->irq) { | ||
455 | free_irq(pchip->irq, pchip); | ||
456 | flush_workqueue(pchip->irqthread); | ||
457 | destroy_workqueue(pchip->irqthread); | ||
458 | } | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | static const struct i2c_device_id lm3630a_id[] = { | ||
463 | {LM3630A_NAME, 0}, | ||
464 | {} | ||
465 | }; | ||
466 | |||
467 | MODULE_DEVICE_TABLE(i2c, lm3630a_id); | ||
468 | |||
469 | static struct i2c_driver lm3630a_i2c_driver = { | ||
470 | .driver = { | ||
471 | .name = LM3630A_NAME, | ||
472 | }, | ||
473 | .probe = lm3630a_probe, | ||
474 | .remove = lm3630a_remove, | ||
475 | .id_table = lm3630a_id, | ||
476 | }; | ||
477 | |||
478 | module_i2c_driver(lm3630a_i2c_driver); | ||
479 | |||
480 | MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630A"); | ||
481 | MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); | ||
482 | MODULE_AUTHOR("LDD MLP <ldd-mlp@list.ti.com>"); | ||
483 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/platform_data/lm3630_bl.h b/include/linux/platform_data/lm3630_bl.h deleted file mode 100644 index 9176dd3f2d63..000000000000 --- a/include/linux/platform_data/lm3630_bl.h +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630 LED Flash driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_LM3630_H | ||
12 | #define __LINUX_LM3630_H | ||
13 | |||
14 | #define LM3630_NAME "lm3630_bl" | ||
15 | |||
16 | enum lm3630_pwm_ctrl { | ||
17 | PWM_CTRL_DISABLE = 0, | ||
18 | PWM_CTRL_BANK_A, | ||
19 | PWM_CTRL_BANK_B, | ||
20 | PWM_CTRL_BANK_ALL, | ||
21 | }; | ||
22 | |||
23 | enum lm3630_pwm_active { | ||
24 | PWM_ACTIVE_HIGH = 0, | ||
25 | PWM_ACTIVE_LOW, | ||
26 | }; | ||
27 | |||
28 | enum lm3630_bank_a_ctrl { | ||
29 | BANK_A_CTRL_DISABLE = 0x0, | ||
30 | BANK_A_CTRL_LED1 = 0x4, | ||
31 | BANK_A_CTRL_LED2 = 0x1, | ||
32 | BANK_A_CTRL_ALL = 0x5, | ||
33 | }; | ||
34 | |||
35 | enum lm3630_bank_b_ctrl { | ||
36 | BANK_B_CTRL_DISABLE = 0, | ||
37 | BANK_B_CTRL_LED2, | ||
38 | }; | ||
39 | |||
40 | struct lm3630_platform_data { | ||
41 | |||
42 | /* maximum brightness */ | ||
43 | int max_brt_led1; | ||
44 | int max_brt_led2; | ||
45 | |||
46 | /* initial on brightness */ | ||
47 | int init_brt_led1; | ||
48 | int init_brt_led2; | ||
49 | enum lm3630_pwm_ctrl pwm_ctrl; | ||
50 | enum lm3630_pwm_active pwm_active; | ||
51 | enum lm3630_bank_a_ctrl bank_a_ctrl; | ||
52 | enum lm3630_bank_b_ctrl bank_b_ctrl; | ||
53 | unsigned int pwm_period; | ||
54 | void (*pwm_set_intensity) (int brightness, int max_brightness); | ||
55 | }; | ||
56 | |||
57 | #endif /* __LINUX_LM3630_H */ | ||
diff --git a/include/linux/platform_data/lm3630a_bl.h b/include/linux/platform_data/lm3630a_bl.h new file mode 100644 index 000000000000..7538e38e270b --- /dev/null +++ b/include/linux/platform_data/lm3630a_bl.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630A LED Flash driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_LM3630A_H | ||
12 | #define __LINUX_LM3630A_H | ||
13 | |||
14 | #define LM3630A_NAME "lm3630a_bl" | ||
15 | |||
16 | enum lm3630a_pwm_ctrl { | ||
17 | LM3630A_PWM_DISABLE = 0x00, | ||
18 | LM3630A_PWM_BANK_A, | ||
19 | LM3630A_PWM_BANK_B, | ||
20 | LM3630A_PWM_BANK_ALL, | ||
21 | LM3630A_PWM_BANK_A_ACT_LOW = 0x05, | ||
22 | LM3630A_PWM_BANK_B_ACT_LOW, | ||
23 | LM3630A_PWM_BANK_ALL_ACT_LOW, | ||
24 | }; | ||
25 | |||
26 | enum lm3630a_leda_ctrl { | ||
27 | LM3630A_LEDA_DISABLE = 0x00, | ||
28 | LM3630A_LEDA_ENABLE = 0x04, | ||
29 | LM3630A_LEDA_ENABLE_LINEAR = 0x14, | ||
30 | }; | ||
31 | |||
32 | enum lm3630a_ledb_ctrl { | ||
33 | LM3630A_LEDB_DISABLE = 0x00, | ||
34 | LM3630A_LEDB_ON_A = 0x01, | ||
35 | LM3630A_LEDB_ENABLE = 0x02, | ||
36 | LM3630A_LEDB_ENABLE_LINEAR = 0x0A, | ||
37 | }; | ||
38 | |||
39 | #define LM3630A_MAX_BRIGHTNESS 255 | ||
40 | /* | ||
41 | *@leda_init_brt : led a init brightness. 4~255 | ||
42 | *@leda_max_brt : led a max brightness. 4~255 | ||
43 | *@leda_ctrl : led a disable, enable linear, enable exponential | ||
44 | *@ledb_init_brt : led b init brightness. 4~255 | ||
45 | *@ledb_max_brt : led b max brightness. 4~255 | ||
46 | *@ledb_ctrl : led b disable, enable linear, enable exponential | ||
47 | *@pwm_period : pwm period | ||
48 | *@pwm_ctrl : pwm disable, bank a or b, active high or low | ||
49 | */ | ||
50 | struct lm3630a_platform_data { | ||
51 | |||
52 | /* led a config. */ | ||
53 | int leda_init_brt; | ||
54 | int leda_max_brt; | ||
55 | enum lm3630a_leda_ctrl leda_ctrl; | ||
56 | /* led b config. */ | ||
57 | int ledb_init_brt; | ||
58 | int ledb_max_brt; | ||
59 | enum lm3630a_ledb_ctrl ledb_ctrl; | ||
60 | /* pwm config. */ | ||
61 | unsigned int pwm_period; | ||
62 | enum lm3630a_pwm_ctrl pwm_ctrl; | ||
63 | }; | ||
64 | |||
65 | #endif /* __LINUX_LM3630A_H */ | ||