Add LM3646 driver using LED subsystem structure - V0
[mlp-open-source/kernel.git] / drivers / leds / leds-lm3646.c
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;
133 static void lm3646_mode_ctrl(struct lm3646 *pchip,
134                              const char *buf, enum lm3646_mode mode)
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");
148 static void lm3646_input_control(struct lm3646 *pchip,
149                                  const char *buf, u8 reg, u8 mask)
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");
165 /* torch brightness(max current) control */
166 static void lm3646_deferred_torch_brightness_set(struct work_struct *work)
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");
177 static void lm3646_torch_brightness_set(struct led_classdev *cdev,
178                                         enum led_brightness brightness)
180         struct lm3646 *pchip = container_of(cdev, struct lm3646, cdev_torch);
182         pchip->br_torch = brightness;
183         schedule_work(&pchip->work_torch);
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)
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;
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)
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;
212 /* flash brightness(max current) control */
213 static void lm3646_deferred_flash_brightness_set(struct work_struct *work)
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");
223 static void lm3646_flash_brightness_set(struct led_classdev *cdev,
224                                         enum led_brightness brightness)
226         struct lm3646 *pchip = container_of(cdev, struct lm3646, cdev_flash);
228         pchip->br_flash = brightness;
229         schedule_work(&pchip->work_flash);
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)
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;
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)
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;
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)
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;
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)
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;
328 #define lm3646_attr(_name, _show, _store)\
329 {\
330         .attr = {\
331                 .name = _name,\
332                 .mode = 0644,\
333         },\
334         .show = _show,\
335         .store = _store,\
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)
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;
469 static int lm3646_remove(struct i2c_client *client)
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;
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");