2 /*
3 * Simple driver for Texas Instruments LM3646 LED Flash driver chip
4 * Copyright (C) 2013 Texas Instruments
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/gpio.h>
14 #include <linux/leds.h>
15 #include <linux/slab.h>
16 #include <linux/platform_device.h>
17 #include <linux/fs.h>
18 #include <linux/regmap.h>
19 #include <linux/workqueue.h>
20 #include <linux/platform_data/leds-lm3646.h>
22 #define REG_REV 0x00
23 #define REG_MODE 0x01
24 #define REG_STR_CTRL 0x04
25 #define REG_MAX_BR 0x05
26 #define REG_FLASH_BR 0x06
27 #define REG_TORCH_BR 0x07
29 #define STR_OFF "off"
30 #define NUM_OFF "0"
32 #define WARM_FLASH_CTRL_SIZE 8
34 struct warm_flash {
35 u8 max_current;
36 u8 led1_current;
37 };
39 enum lm3646_mode {
40 MODE_STDBY = 0x0,
41 MODE_TORCH = 0x2,
42 MODE_FLASH = 0x3,
43 MODE_MAX
44 };
46 enum lm3646_devfile {
47 DFILE_FLASH_CTRL = 0,
48 DFILE_FLASH_LED1,
49 DFILE_FLASH_DUR,
50 DFILE_TORCH_CTRL,
51 DFILE_TORCH_LED1,
52 DFILE_WARM_FLASH,
53 DFILE_MAX
54 };
56 struct lm3646 {
57 struct device *dev;
59 struct led_classdev cdev_flash;
60 struct led_classdev cdev_torch;
62 struct work_struct work_flash;
63 struct work_struct work_torch;
65 u8 br_flash;
66 u8 br_torch;
68 struct lm3646_platform_data *pdata;
69 struct regmap *regmap;
70 struct mutex lock;
71 };
73 static int lm3646_read_byte(struct lm3646 *pchip, u8 addr)
74 {
75 int rval, ret;
76 ret = regmap_read(pchip->regmap, addr, &rval);
77 if (ret < 0)
78 return ret;
79 return rval;
80 }
82 static int lm3646_update_byte(struct lm3646 *pchip, u8 addr, u8 mask, u8 data)
83 {
84 return regmap_update_bits(pchip->regmap, addr, mask, data);
85 }
87 static int lm3646_chip_init(struct lm3646 *pchip,
88 struct lm3646_platform_data *pdata)
89 {
90 int rval;
92 rval = lm3646_read_byte(pchip, REG_REV);
93 if (rval < 0)
94 goto out;
95 dev_info(pchip->dev, "LM3646 CHIP_ID/REV[0x%x]\n", rval);
97 if (pdata == NULL) {
98 pdata =
99 kzalloc(sizeof(struct lm3646_platform_data), GFP_KERNEL);
100 if (pdata == NULL)
101 return -ENODEV;
102 pdata->flash_imax = 0x0F;
103 pdata->torch_imax = 0x07;
104 pdata->led1_flash_imax = 0x7F;
105 pdata->led1_torch_imax = 0x7F;
106 }
107 pchip->pdata = pdata;
109 rval = lm3646_update_byte(pchip, REG_MODE, 0x08, pdata->tx_pin);
110 if (rval < 0)
111 goto out;
112 rval = lm3646_update_byte(pchip, REG_TORCH_BR, 0xFF,
113 pdata->torch_pin | pdata->led1_torch_imax);
114 if (rval < 0)
115 goto out;
116 rval = lm3646_update_byte(pchip, REG_FLASH_BR, 0xFF,
117 pdata->strobe_pin | pdata->led1_flash_imax);
118 if (rval < 0)
119 goto out;
120 rval = lm3646_update_byte(pchip, REG_MAX_BR, 0x7F,
121 (pdata->torch_imax << 4) | pdata->flash_imax);
122 if (rval < 0)
123 goto out;
124 pchip->br_flash = pdata->flash_imax;
125 pchip->br_torch = pdata->torch_imax;
127 return rval;
128 out:
129 dev_err(pchip->dev, "i2c acces fail.\n");
130 return rval;
131 }
133 static void lm3646_mode_ctrl(struct lm3646 *pchip,
134 const char *buf, enum lm3646_mode mode)
135 {
136 int rval;
138 if (strncmp(buf, STR_OFF, 3) == 0 || strncmp(buf, NUM_OFF, 1) == 0)
139 mode = MODE_STDBY;
141 mutex_lock(&pchip->lock);
142 rval = lm3646_update_byte(pchip, REG_MODE, 0x03, mode);
143 mutex_unlock(&pchip->lock);
144 if (rval < 0)
145 dev_err(pchip->dev, "i2c access fail.\n");
146 }
148 static void lm3646_input_control(struct lm3646 *pchip,
149 const char *buf, u8 reg, u8 mask)
150 {
151 int rval, ival;
153 rval = kstrtouint(buf, 10, &ival);
154 if (rval) {
155 dev_err(pchip->dev, "str to int fail.\n");
156 return;
157 }
158 mutex_lock(&pchip->lock);
159 rval = lm3646_update_byte(pchip, reg, mask, ival);
160 mutex_unlock(&pchip->lock);
161 if (rval < 0)
162 dev_err(pchip->dev, "i2c access fail.\n");
163 }
165 /* torch brightness(max current) control */
166 static void lm3646_deferred_torch_brightness_set(struct work_struct *work)
167 {
168 int rval;
169 struct lm3646 *pchip = container_of(work, struct lm3646, work_torch);
171 rval =
172 lm3646_update_byte(pchip, REG_MAX_BR, 0x70, (pchip->br_torch) << 4);
173 if (rval < 0)
174 dev_err(pchip->dev, "i2c access fail.\n");
175 }
177 static void lm3646_torch_brightness_set(struct led_classdev *cdev,
178 enum led_brightness brightness)
179 {
180 struct lm3646 *pchip = container_of(cdev, struct lm3646, cdev_torch);
182 pchip->br_torch = brightness;
183 schedule_work(&pchip->work_torch);
184 }
186 /* torch on/off(mode) control */
187 static ssize_t lm3646_torch_ctrl_store(struct device *dev,
188 struct device_attribute *devAttr,
189 const char *buf, size_t size)
190 {
191 struct led_classdev *led_cdev = dev_get_drvdata(dev);
192 struct lm3646 *pchip =
193 container_of(led_cdev, struct lm3646, cdev_torch);
195 lm3646_mode_ctrl(pchip, buf, MODE_TORCH);
196 return size;
197 }
199 /* torch dual led control */
200 static ssize_t lm3646_torch_iled1_ctrl_store(struct device *dev,
201 struct device_attribute *devAttr,
202 const char *buf, size_t size)
203 {
204 struct led_classdev *led_cdev = dev_get_drvdata(dev);
205 struct lm3646 *pchip =
206 container_of(led_cdev, struct lm3646, cdev_torch);
208 lm3646_input_control(pchip, buf, REG_TORCH_BR, 0x7F);
209 return size;
210 }
212 /* flash brightness(max current) control */
213 static void lm3646_deferred_flash_brightness_set(struct work_struct *work)
214 {
215 int rval;
216 struct lm3646 *pchip = container_of(work, struct lm3646, work_flash);
218 rval = lm3646_update_byte(pchip, REG_MAX_BR, 0x0F, pchip->br_flash);
219 if (rval < 0)
220 dev_err(pchip->dev, "i2c access fail.\n");
221 }
223 static void lm3646_flash_brightness_set(struct led_classdev *cdev,
224 enum led_brightness brightness)
225 {
226 struct lm3646 *pchip = container_of(cdev, struct lm3646, cdev_flash);
228 pchip->br_flash = brightness;
229 schedule_work(&pchip->work_flash);
230 }
232 /* flash on(mode) control */
233 static ssize_t lm3646_flash_ctrl_store(struct device *dev,
234 struct device_attribute *devAttr,
235 const char *buf, size_t size)
236 {
237 struct led_classdev *led_cdev = dev_get_drvdata(dev);
238 struct lm3646 *pchip =
239 container_of(led_cdev, struct lm3646, cdev_flash);
241 lm3646_mode_ctrl(pchip, buf, MODE_FLASH);
242 return size;
243 }
245 /* flash dual led control */
246 static ssize_t lm3646_flash_iled1_ctrl_store(struct device *dev,
247 struct device_attribute *devAttr,
248 const char *buf, size_t size)
249 {
250 struct led_classdev *led_cdev = dev_get_drvdata(dev);
251 struct lm3646 *pchip =
252 container_of(led_cdev, struct lm3646, cdev_flash);
254 lm3646_input_control(pchip, buf, REG_FLASH_BR, 0x7F);
255 return size;
256 }
258 /* flash duration(timeout) control */
259 static ssize_t lm3646_flash_duration_store(struct device *dev,
260 struct device_attribute *devAttr,
261 const char *buf, size_t size)
262 {
263 struct led_classdev *led_cdev = dev_get_drvdata(dev);
264 struct lm3646 *pchip =
265 container_of(led_cdev, struct lm3646, cdev_flash);
267 lm3646_input_control(pchip, buf, REG_STR_CTRL, 0x07);
268 return size;
269 }
271 /* warm-flash setting data */
272 static struct warm_flash warm_flash_set[WARM_FLASH_CTRL_SIZE] = {
273 /* LED1 = MAX, LED2 = Diabled */
274 [0] = {0x0F, 0x7F},
275 [1] = {0x0F, 0x3F},
276 [2] = {0x0F, 0x1F},
277 [3] = {0x0F, 0x0F},
278 [4] = {0x0F, 0x07},
279 [5] = {0x0F, 0x03},
280 [6] = {0x0F, 0x01},
281 /* LED1 = Diabled, LED2 = MAX */
282 [7] = {0x0F, 0x00},
283 };
285 /* flash duration(timeout) control */
286 static ssize_t lm3646_warm_flash_store(struct device *dev,
287 struct device_attribute *devAttr,
288 const char *buf, size_t size)
289 {
290 struct led_classdev *led_cdev = dev_get_drvdata(dev);
291 struct lm3646 *pchip =
292 container_of(led_cdev, struct lm3646, cdev_flash);
294 int rval, ival;
296 rval = kstrtouint(buf, 10, &ival);
297 if (rval) {
298 dev_err(pchip->dev, "str to int fail.\n");
299 goto out_err;
300 }
302 if (ival > WARM_FLASH_CTRL_SIZE - 1) {
303 dev_err(pchip->dev, "input error.\n");
304 goto out_err;
305 }
307 mutex_lock(&pchip->lock);
308 rval =
309 lm3646_update_byte(pchip, REG_MAX_BR, 0x0F,
310 warm_flash_set[ival].max_current);
311 if (rval < 0)
312 goto out;
313 rval =
314 lm3646_update_byte(pchip, REG_FLASH_BR, 0x7F,
315 warm_flash_set[ival].led1_current);
316 if (rval < 0)
317 goto out;
318 if (pchip->pdata->strobe_pin == LM3646_STROBE_PIN_DISABLED)
319 lm3646_update_byte(pchip, REG_MODE, 0x03, MODE_FLASH);
320 out:
321 mutex_unlock(&pchip->lock);
322 if (rval < 0)
323 dev_err(pchip->dev, "i2c access fail.\n");
324 out_err:
325 return size;
326 }
328 #define lm3646_attr(_name, _show, _store)\
329 {\
330 .attr = {\
331 .name = _name,\
332 .mode = 0644,\
333 },\
334 .show = _show,\
335 .store = _store,\
336 }
338 static struct device_attribute dev_attr_ctrl[DFILE_MAX] = {
339 [DFILE_FLASH_CTRL] = lm3646_attr("ctrl", NULL, lm3646_flash_ctrl_store),
340 [DFILE_FLASH_LED1] =
341 lm3646_attr("iled1", NULL, lm3646_flash_iled1_ctrl_store),
342 [DFILE_FLASH_DUR] = lm3646_attr("duration",
343 NULL, lm3646_flash_duration_store),
344 [DFILE_TORCH_CTRL] = lm3646_attr("ctrl", NULL, lm3646_torch_ctrl_store),
345 [DFILE_TORCH_LED1] =
346 lm3646_attr("iled1", NULL, lm3646_torch_iled1_ctrl_store),
347 [DFILE_WARM_FLASH] =
348 lm3646_attr("warmness", NULL, lm3646_warm_flash_store),
349 };
351 static const struct regmap_config lm3646_regmap = {
352 .reg_bits = 8,
353 .val_bits = 8,
354 .max_register = 0xFF,
355 };
357 /* module initialize */
358 static int lm3646_probe(struct i2c_client *client,
359 const struct i2c_device_id *id)
360 {
361 struct lm3646_platform_data *pdata = client->dev.platform_data;
362 struct lm3646 *pchip;
364 int err;
365 /* i2c check */
366 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
367 dev_err(&client->dev, "i2c functionality check fail.\n");
368 return -EOPNOTSUPP;
369 }
371 pchip = devm_kzalloc(&client->dev, sizeof(struct lm3646), GFP_KERNEL);
372 if (!pchip)
373 return -ENOMEM;
375 pchip->dev = &client->dev;
376 pchip->regmap = devm_regmap_init_i2c(client, &lm3646_regmap);
377 if (IS_ERR(pchip->regmap)) {
378 err = PTR_ERR(pchip->regmap);
379 dev_err(&client->dev, "Failed to allocate register map: %d\n",
380 err);
381 return err;
382 }
383 mutex_init(&pchip->lock);
384 i2c_set_clientdata(client, pchip);
386 /* platform data check */
387 err = lm3646_chip_init(pchip, pdata);
388 if (err < 0)
389 goto err_out;
390 /* flash brightness control */
391 INIT_WORK(&pchip->work_flash, lm3646_deferred_flash_brightness_set);
392 pchip->cdev_flash.name = "flash";
393 pchip->cdev_flash.max_brightness = 16;
394 pchip->cdev_flash.brightness = pchip->br_flash;
395 pchip->cdev_flash.brightness_set = lm3646_flash_brightness_set;
396 pchip->cdev_flash.default_trigger = "flash";
397 err = led_classdev_register((struct device *)
398 &client->dev, &pchip->cdev_flash);
399 if (err < 0)
400 goto err_out;
401 /* flash on control */
402 err = device_create_file(pchip->cdev_flash.dev,
403 &dev_attr_ctrl[DFILE_FLASH_CTRL]);
404 if (err < 0)
405 goto err_create_flash_ctrl_file;
406 /* flash duration control */
407 err = device_create_file(pchip->cdev_flash.dev,
408 &dev_attr_ctrl[DFILE_FLASH_DUR]);
409 if (err < 0)
410 goto err_create_flash_duration_file;
411 /* flash - dual led control */
412 err = device_create_file(pchip->cdev_flash.dev,
413 &dev_attr_ctrl[DFILE_FLASH_LED1]);
414 if (err < 0)
415 goto err_create_flash_iled1_file;
417 /* flash - warmness input */
418 err = device_create_file(pchip->cdev_flash.dev,
419 &dev_attr_ctrl[DFILE_WARM_FLASH]);
420 if (err < 0)
421 goto err_create_flash_warmness_file;
423 /* torch brightness control */
424 INIT_WORK(&pchip->work_torch, lm3646_deferred_torch_brightness_set);
425 pchip->cdev_torch.name = "torch";
426 pchip->cdev_torch.max_brightness = 8;
427 pchip->cdev_torch.brightness = pchip->br_torch;
428 pchip->cdev_torch.brightness_set = lm3646_torch_brightness_set;
429 pchip->cdev_torch.default_trigger = "torch";
430 err = led_classdev_register((struct device *)
431 &client->dev, &pchip->cdev_torch);
432 if (err < 0)
433 goto err_create_torch_file;
434 /* torch on/off control */
435 err = device_create_file(pchip->cdev_torch.dev,
436 &dev_attr_ctrl[DFILE_TORCH_CTRL]);
437 if (err < 0)
438 goto err_create_torch_ctrl_file;
439 /* torch - dual led control */
440 err = device_create_file(pchip->cdev_torch.dev,
441 &dev_attr_ctrl[DFILE_TORCH_LED1]);
442 if (err < 0)
443 goto err_create_torch_iled1_file;
444 return 0;
446 err_create_torch_iled1_file:
447 device_remove_file(pchip->cdev_flash.dev,
448 &dev_attr_ctrl[DFILE_TORCH_CTRL]);
449 err_create_torch_ctrl_file:
450 led_classdev_unregister(&pchip->cdev_torch);
451 err_create_torch_file:
452 device_remove_file(pchip->cdev_flash.dev,
453 &dev_attr_ctrl[DFILE_WARM_FLASH]);
454 err_create_flash_warmness_file:
455 device_remove_file(pchip->cdev_flash.dev,
456 &dev_attr_ctrl[DFILE_FLASH_LED1]);
457 err_create_flash_iled1_file:
458 device_remove_file(pchip->cdev_flash.dev,
459 &dev_attr_ctrl[DFILE_FLASH_DUR]);
460 err_create_flash_duration_file:
461 device_remove_file(pchip->cdev_flash.dev,
462 &dev_attr_ctrl[DFILE_FLASH_CTRL]);
463 err_create_flash_ctrl_file:
464 led_classdev_unregister(&pchip->cdev_flash);
465 err_out:
466 return err;
467 }
469 static int lm3646_remove(struct i2c_client *client)
470 {
471 struct lm3646 *pchip = i2c_get_clientdata(client);
472 /* set standby mode */
473 lm3646_update_byte(pchip, REG_MODE, 0x03, MODE_STDBY);
474 /* flash */
475 device_remove_file(pchip->cdev_flash.dev,
476 &dev_attr_ctrl[DFILE_FLASH_LED1]);
477 device_remove_file(pchip->cdev_flash.dev,
478 &dev_attr_ctrl[DFILE_FLASH_DUR]);
479 device_remove_file(pchip->cdev_flash.dev,
480 &dev_attr_ctrl[DFILE_TORCH_CTRL]);
481 device_remove_file(pchip->cdev_flash.dev,
482 &dev_attr_ctrl[DFILE_WARM_FLASH]);
483 led_classdev_unregister(&pchip->cdev_flash);
484 /* torch */
485 device_remove_file(pchip->cdev_torch.dev,
486 &dev_attr_ctrl[DFILE_TORCH_LED1]);
487 device_remove_file(pchip->cdev_torch.dev,
488 &dev_attr_ctrl[DFILE_TORCH_CTRL]);
489 led_classdev_unregister(&pchip->cdev_torch);
491 return 0;
492 }
494 static const struct i2c_device_id lm3646_id[] = {
495 {LM3646_NAME, 0},
496 {}
497 };
499 MODULE_DEVICE_TABLE(i2c, lm3646_id);
501 static struct i2c_driver lm3646_i2c_driver = {
502 .driver = {
503 .name = LM3646_NAME,
504 .owner = THIS_MODULE,
505 .pm = NULL,
506 },
507 .probe = lm3646_probe,
508 .remove = lm3646_remove,
509 .id_table = lm3646_id,
510 };
512 module_i2c_driver(lm3646_i2c_driver);
514 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3646");
515 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
516 MODULE_LICENSE("GPL v2");