Add LM3643 new flash driver using LED subsystem
[mlp-open-source/kernel.git] / drivers / leds / leds-lm3643.c
1 /*
2  * drivers/leds/leds-lm3643.c
3  * General device driver for TI LM3643, FLASH LED Driver
4  *
5  * Copyright (C) 2014 Texas Instruments
6  *
7  * Contact: Daniel Jeong <gshark.jeong@gmail.com>
8  *                      Ldd-Mlp <ldd-mlp@list.ti.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * version 2 as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  */
20 #include <linux/module.h>
21 #include <linux/i2c.h>
22 #include <linux/gpio.h>
23 #include <linux/leds.h>
24 #include <linux/slab.h>
25 #include <linux/platform_device.h>
26 #include <linux/fs.h>
27 #include <linux/regmap.h>
28 #include <linux/workqueue.h>
29 #include <linux/platform_data/leds-lm3643.h>
31 /* registers definitions */
32 #define REG_ENABLE              0x01
33 #define REG_FLASH_LED0_BR       0x03
34 #define REG_FLASH_LED1_BR       0x04
35 #define REG_TORCH_LED0_BR       0x05
36 #define REG_TORCH_LED1_BR       0x06
37 #define REG_FLASH_TOUT          0x08
38 #define REG_FLAG0               0x0a
39 #define REG_FLAG1               0x0b
41 enum lm3643_devid {
42         ID_FLASH0 = 0x0,
43         ID_FLASH1,
44         ID_TORCH0,
45         ID_TORCH1,
46         ID_MAX
47 };
49 enum lm3643_mode {
50         MODE_STDBY = 0x0,
51         MODE_IR,
52         MODE_TORCH,
53         MODE_FLASH,
54         MODE_MAX
55 };
57 enum lm3643_devfile {
58         DFILE_FLASH0_ENABLE = 0,
59         DFILE_FLASH0_ONOFF,
60         DFILE_FLASH0_SOURCE,
61         DFILE_FLASH0_TIMEOUT,
62         DFILE_FLASH1_ENABLE,
63         DFILE_FLASH1_ONOFF,
64         DFILE_TORCH0_ENABLE,
65         DFILE_TORCH0_ONOFF,
66         DFILE_TORCH0_SOURCE,
67         DFILE_TORCH1_ENABLE,
68         DFILE_TORCH1_ONOFF,
69         DFILE_MAX
70 };
72 #define to_lm3643(_ctrl, _no) container_of(_ctrl, struct lm3643, cdev[_no])
74 struct lm3643 {
75         struct device *dev;
77         u8 brightness[ID_MAX];
78         struct work_struct work[ID_MAX];
79         struct led_classdev cdev[ID_MAX];
81         struct lm3643_platform_data *pdata;
82         struct regmap *regmap;
83         struct mutex lock;
84 };
86 static void lm3643_read_flag(struct lm3643 *pchip){
88         int rval;
89         unsigned int flag0, flag1;
91         rval = regmap_read(pchip->regmap,REG_FLAG0, &flag0);
92         rval |= regmap_read(pchip->regmap,REG_FLAG1, &flag1);
94         if(rval < 0)
95                 dev_err(pchip->dev, "i2c access fail.\n");
97         dev_info(pchip->dev, "[flag1] 0x%x, [flag0] 0x%x\n", flag1 & 0x1f, flag0);
98 }
100 /* torch0 brightness control */
101 static void lm3643_deferred_torch0_brightness_set(struct work_struct *work)
103         struct lm3643 *pchip = container_of(work,
104                                                         struct lm3643, work[ID_TORCH0]);
106         if(regmap_update_bits(pchip->regmap, 
107                                                                 REG_TORCH_LED0_BR, 0x7f,
108                                                                 pchip->brightness[ID_TORCH0]))
109                 dev_err(pchip->dev, "i2c access fail.\n");
110         lm3643_read_flag(pchip);
113 static void lm3643_torch0_brightness_set(struct led_classdev *cdev,
114                                         enum led_brightness brightness)
116         struct lm3643 *pchip = container_of(cdev, struct lm3643, cdev[ID_TORCH0]);
118         pchip->brightness[ID_TORCH0] = brightness;
119         schedule_work(&pchip->work[ID_TORCH0]);
122 /* torch1 brightness control */
123 static void lm3643_deferred_torch1_brightness_set(struct work_struct *work)
125         struct lm3643 *pchip = container_of(work,
126                                                         struct lm3643, work[ID_TORCH1]);
128         if(regmap_update_bits(pchip->regmap, 
129                                                                 REG_TORCH_LED1_BR, 0x7f,
130                                                                 pchip->brightness[ID_TORCH1]))
131                 dev_err(pchip->dev, "i2c access fail.\n");
132         lm3643_read_flag(pchip);
135 static void lm3643_torch1_brightness_set(struct led_classdev *cdev,
136                                         enum led_brightness brightness)
138         struct lm3643 *pchip = container_of(cdev, struct lm3643, cdev[ID_TORCH1]);
140         pchip->brightness[ID_TORCH1] = brightness;
141         schedule_work(&pchip->work[ID_TORCH1]);
144 /* flash0 brightness control */
145 static void lm3643_deferred_flash0_brightness_set(struct work_struct *work)
147         struct lm3643 *pchip = container_of(work,
148                                                         struct lm3643, work[ID_FLASH0]);
150         if(regmap_update_bits(pchip->regmap, 
151                                                                 REG_FLASH_LED0_BR, 0x7f,
152                                                                 pchip->brightness[ID_FLASH0]))
153                 dev_err(pchip->dev, "i2c access fail.\n");
154         lm3643_read_flag(pchip);
157 static void lm3643_flash0_brightness_set(struct led_classdev *cdev,
158                                         enum led_brightness brightness)
160         struct lm3643 *pchip = container_of(cdev, struct lm3643, cdev[ID_FLASH0]);
162         pchip->brightness[ID_FLASH0] = brightness;
163         schedule_work(&pchip->work[ID_FLASH0]);
166 /* flash1 brightness control */
167 static void lm3643_deferred_flash1_brightness_set(struct work_struct *work)
169         struct lm3643 *pchip = container_of(work,
170                                                         struct lm3643, work[ID_FLASH1]);
172         if(regmap_update_bits(pchip->regmap, 
173                                                                 REG_FLASH_LED1_BR, 0x7f,
174                                                                 pchip->brightness[ID_FLASH1]))
175                 dev_err(pchip->dev, "i2c access fail.\n");
176         lm3643_read_flag(pchip);
179 static void lm3643_flash1_brightness_set(struct led_classdev *cdev,
180                                         enum led_brightness brightness)
182         struct lm3643 *pchip = container_of(cdev, struct lm3643, cdev[ID_FLASH1]);
184         pchip->brightness[ID_FLASH1] = brightness;
185         schedule_work(&pchip->work[ID_FLASH1]);
188 struct lm3643_devices {
189         struct led_classdev cdev;
190         work_func_t func;
191 };
193 static struct lm3643_devices lm3643_leds[ID_MAX] = {
194         [ID_FLASH0] = {
195                 .cdev.name = "flash0",
196                 .cdev.brightness = 0,
197                 .cdev.max_brightness = 0x7f,
198                 .cdev.brightness_set = lm3643_flash0_brightness_set,
199                 .cdev.default_trigger = "flash0",
200                 .func = lm3643_deferred_flash0_brightness_set
201                 },
202         [ID_FLASH1] = {
203                 .cdev.name = "flash1",
204                 .cdev.brightness = 0,
205                 .cdev.max_brightness = 0x7f,
206                 .cdev.brightness_set = lm3643_flash1_brightness_set,
207                 .cdev.default_trigger = "flash1",
208                 .func = lm3643_deferred_flash1_brightness_set
209                 },
210         [ID_TORCH0] = {
211                 .cdev.name = "torch0",
212                 .cdev.brightness = 0,
213                 .cdev.max_brightness = 0x7f,
214                 .cdev.brightness_set = lm3643_torch0_brightness_set,
215                 .cdev.default_trigger = "torch0",
216                 .func = lm3643_deferred_torch0_brightness_set
217                 },
218         [ID_TORCH1] = {
219                 .cdev.name = "torch1",
220                 .cdev.brightness = 0,
221                 .cdev.max_brightness = 0x7f,
222                 .cdev.brightness_set = lm3643_torch1_brightness_set,
223                 .cdev.default_trigger = "torch1",
224                 .func = lm3643_deferred_torch1_brightness_set
225                 },
226 };
228 static void lm3643_led_unregister(struct lm3643 *pchip, enum lm3643_devid id)
230         int icnt;
232         for(icnt = id; icnt > 0 ; icnt--)
233                 led_classdev_unregister(&pchip->cdev[icnt-1]);
236 static int lm3643_led_register(struct lm3643 *pchip)
238         int icnt, rval; 
240         for(icnt = 0 ; icnt < ID_MAX; icnt++){
241                 INIT_WORK(&pchip->work[icnt], lm3643_leds[icnt].func);
242                 pchip->cdev[icnt].name = lm3643_leds[icnt].cdev.name;
243                 pchip->cdev[icnt].max_brightness = lm3643_leds[icnt].cdev.max_brightness;
244                 pchip->cdev[icnt].brightness = lm3643_leds[icnt].cdev.brightness;
245                 pchip->cdev[icnt].brightness_set = lm3643_leds[icnt].cdev.brightness_set;
246                 pchip->cdev[icnt].default_trigger = lm3643_leds[icnt].cdev.default_trigger;
247                 rval = led_classdev_register((struct device *)
248                                     pchip->dev, &pchip->cdev[icnt]);
249                 if(rval < 0){
250                         lm3643_led_unregister(pchip, icnt);
251                         return rval;
252                 }       
253         }
254         return 0;
257 /* device files to control registers */
258 struct lm3643_commands {
259         char *str;
260         int size;
261 };
263 enum lm3643_cmd_id {
264         CMD_ENABLE = 0,
265         CMD_DISABLE,
266         CMD_ON,
267         CMD_OFF,
268         CMD_IRMODE,
269         CMD_OVERRIDE,
270         CMD_MAX
271 };
273 struct lm3643_commands cmds[CMD_MAX] = {
274         [CMD_ENABLE] = {"enable", 6},
275         [CMD_DISABLE] = {"disable", 7},
276         [CMD_ON] = {"on", 2},
277         [CMD_OFF] = {"off", 3},
278         [CMD_IRMODE] = {"irmode", 6},
279         [CMD_OVERRIDE] = {"override", 8},
280 };
282 struct lm3643_files {
283         enum lm3643_devid id;
284         struct device_attribute attr;
285 };
287 static size_t lm3643_ctrl(struct device *dev,
288                                            const char *buf, enum lm3643_devid id,
289                                            enum lm3643_devfile dfid, size_t size)
291         struct led_classdev *led_cdev = dev_get_drvdata(dev);
292         struct lm3643 *pchip = to_lm3643(led_cdev, id);
293         enum lm3643_cmd_id icnt;
294         int tout, rval;
296         mutex_lock(&pchip->lock);
297         for(icnt=0; icnt < CMD_MAX ; icnt++){
298                 if (strncmp(buf, cmds[icnt].str, cmds[icnt].size) == 0)
299                         break;
300         }
302         switch(dfid){
303         /* led 0 enable */
304         case DFILE_FLASH0_ENABLE:
305         case DFILE_TORCH0_ENABLE:
306                 if(icnt == CMD_ENABLE)
307                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1, 0x1);
308                 else if(icnt == CMD_DISABLE)
309                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1, 0x0);
310         break;
311         /* led 1 enable, flash override */
312         case DFILE_FLASH1_ENABLE:
313                 if(icnt == CMD_ENABLE){
314                         rval = regmap_update_bits(pchip->regmap, 
315                                                         REG_FLASH_LED0_BR, 0x80, 0x0);
316                         rval |= regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x2);
317                 }else if(icnt == CMD_DISABLE){
318                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x0);
319                 }else if(icnt == CMD_OVERRIDE){
320                         rval = regmap_update_bits(pchip->regmap, 
321                                                         REG_FLASH_LED0_BR, 0x80, 0x80);
322                         rval |= regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x2);
323                 }
324         break;
325         /* led 1 enable, torch override */
326         case DFILE_TORCH1_ENABLE:
327                 if(icnt == CMD_ENABLE){
328                         rval = regmap_update_bits(pchip->regmap, 
329                                                         REG_TORCH_LED0_BR, 0x80, 0x0);
330                         rval |= regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x2);
331                 }else if(icnt == CMD_DISABLE){
332                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x0);
333                 }else if(icnt == CMD_OVERRIDE){
334                         rval = regmap_update_bits(pchip->regmap, 
335                                                         REG_TORCH_LED0_BR, 0x80, 0x80);
336                         rval |= regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, 0x2);
337                 }
338         break;
339         /* mode control flash/ir */
340         case DFILE_FLASH0_ONOFF:
341         case DFILE_FLASH1_ONOFF:
342                 if(icnt == CMD_ON)
343                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, 0xc);
344                 else if(icnt == CMD_OFF)
345                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, 0x0);
346                 else if(icnt == CMD_IRMODE)
347                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, 0x4);
348         break;
349         /* mode control torch */        
350         case DFILE_TORCH0_ONOFF:
351         case DFILE_TORCH1_ONOFF:
352                 if(icnt == CMD_ON)
353                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, 0x8);
354                 else if(icnt == CMD_OFF)
355                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, 0x0);
356         break;
357         /* strobe pin control */
358         case DFILE_FLASH0_SOURCE:
359                 if(icnt == CMD_ON)
360                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20, 0x20);
361                 else if(icnt == CMD_OFF)
362                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20, 0x0);
363         break;
364         case DFILE_TORCH0_SOURCE:
365                 if(icnt == CMD_ON)
366                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10, 0x10);
367                 else if(icnt == CMD_OFF)
368                         rval = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10, 0x0);
369         break;
370         /* flash time out */
371         case DFILE_FLASH0_TIMEOUT:
372                 rval = kstrtouint((const char *)buf, 10, &tout);
373                 if(rval < 0)
374                         break;
375                 rval = regmap_update_bits(pchip->regmap,
376                                                                         REG_FLASH_TOUT, 0x0f, tout);
377         break;
378         default:
379                 dev_err(pchip->dev, "error : undefined dev file\n");
380         break;
381         }
382         lm3643_read_flag(pchip);
383         mutex_unlock(&pchip->lock);
384         return size;
387 /* flash enable control */
388 static ssize_t lm3643_flash0_enable_store(struct device *dev,
389                                            struct device_attribute *devAttr,
390                                            const char *buf, size_t size)
392         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ENABLE, size);
395 static ssize_t lm3643_flash1_enable_store(struct device *dev,
396                                            struct device_attribute *devAttr,
397                                            const char *buf, size_t size)
399         return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ENABLE, size);
402 /* flash onoff control */
403 static ssize_t lm3643_flash0_onoff_store(struct device *dev,
404                                            struct device_attribute *devAttr,
405                                            const char *buf, size_t size)
407         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ONOFF, size);
410 static ssize_t lm3643_flash1_onoff_store(struct device *dev,
411                                            struct device_attribute *devAttr,
412                                            const char *buf, size_t size)
414         return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ONOFF, size);
417 /* flash timeout control */
418 static ssize_t lm3643_flash0_timeout_store(struct device *dev,
419                                            struct device_attribute *devAttr,
420                                            const char *buf, size_t size)
422         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_TIMEOUT, size);
425 /* flash source control */
426 static ssize_t lm3643_flash0_source_store(struct device *dev,
427                                            struct device_attribute *devAttr,
428                                            const char *buf, size_t size)
430         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_SOURCE, size);
433 /* torch enable control */
434 static ssize_t lm3643_torch0_enable_store(struct device *dev,
435                                            struct device_attribute *devAttr,
436                                            const char *buf, size_t size)
438         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_TORCH0_ENABLE, size);
441 static ssize_t lm3643_torch1_enable_store(struct device *dev,
442                                            struct device_attribute *devAttr,
443                                            const char *buf, size_t size)
445         return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ENABLE, size);
448 /* torch onoff control */
449 static ssize_t lm3643_torch0_onoff_store(struct device *dev,
450                                            struct device_attribute *devAttr,
451                                            const char *buf, size_t size)
453         return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_ONOFF, size);
456 static ssize_t lm3643_torch1_onoff_store(struct device *dev,
457                                            struct device_attribute *devAttr,
458                                            const char *buf, size_t size)
460         return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ONOFF, size);
463 /* torch source control */
464 static ssize_t lm3643_torch0_source_store(struct device *dev,
465                                            struct device_attribute *devAttr,
466                                            const char *buf, size_t size)
468         return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_SOURCE, size);
471 #define lm3643_attr(_name, _show, _store)\
472 {\
473         .attr = {\
474                 .name = _name,\
475                 .mode = 0644,\
476         },\
477         .show = _show,\
478         .store = _store,\
481 static struct lm3643_files lm3643_devfiles[DFILE_MAX] = {
482         [DFILE_FLASH0_ENABLE] = {
483                 .id = ID_FLASH0,
484                 .attr = lm3643_attr("enable", NULL, lm3643_flash0_enable_store),
485         },
486         [DFILE_FLASH0_ONOFF] = {
487                 .id = ID_FLASH0,
488                 .attr = lm3643_attr("onoff", NULL, lm3643_flash0_onoff_store),
489         },
490         [DFILE_FLASH0_SOURCE] = {
491                 .id = ID_FLASH0,
492                 .attr = lm3643_attr("source", NULL, lm3643_flash0_source_store),
493         },
494         [DFILE_FLASH0_TIMEOUT] = {
495                 .id = ID_FLASH0,
496                 .attr = lm3643_attr("timeout", NULL, lm3643_flash0_timeout_store),
497         },
498         [DFILE_FLASH1_ENABLE] = {
499                 .id = ID_FLASH1,
500                 .attr = lm3643_attr("enable", NULL, lm3643_flash1_enable_store),
501         },
502         [DFILE_FLASH1_ONOFF] = {
503                 .id = ID_FLASH1,
504                 .attr = lm3643_attr("onoff", NULL, lm3643_flash1_onoff_store),
505         },
506         [DFILE_TORCH0_ENABLE] = {
507                 .id = ID_TORCH0,
508                 .attr = lm3643_attr("enable", NULL, lm3643_torch0_enable_store),
509         },
510         [DFILE_TORCH0_ONOFF] = {
511                 .id = ID_TORCH0,
512                 .attr = lm3643_attr("onoff", NULL, lm3643_torch0_onoff_store),
513         },
514         [DFILE_TORCH0_SOURCE] = {
515                 .id = ID_TORCH0,
516                 .attr = lm3643_attr("source", NULL, lm3643_torch0_source_store),
517         },
518         [DFILE_TORCH1_ENABLE] = {
519                 .id = ID_TORCH1,
520                 .attr = lm3643_attr("enable", NULL, lm3643_torch1_enable_store),
521         },
522         [DFILE_TORCH1_ONOFF] = {
523                 .id = ID_TORCH1,
524                 .attr = lm3643_attr("onoff", NULL, lm3643_torch1_onoff_store),
525         }
526 };
528 static void lm3643_df_remove(struct lm3643 *pchip, enum lm3643_devfile dfid)
530         enum lm3643_devfile icnt;
531         
532         for( icnt = dfid; icnt > 0; icnt--)
533                 device_remove_file(pchip->cdev[lm3643_devfiles[icnt-1].id].dev,
534                                                                         &lm3643_devfiles[icnt-1].attr);
537 static int lm3643_df_create(struct lm3643 *pchip)
538 {       
539         enum lm3643_devfile icnt;
540         int rval; 
542         for(icnt = 0; icnt < DFILE_MAX; icnt++){
543                 rval = device_create_file(pchip->cdev[lm3643_devfiles[icnt].id].dev,
544                                                                         &lm3643_devfiles[icnt].attr);
545                 if (rval < 0){
546                         lm3643_df_remove(pchip, icnt);
547                         return rval;
548                 }
549         }
550         return 0;
553 static const struct regmap_config lm3643_regmap = {
554         .reg_bits = 8,
555         .val_bits = 8,
556         .max_register = 0xff,
557 };
559 static int lm3643_probe(struct i2c_client *client,
560                         const struct i2c_device_id *id)
562         struct lm3643 *pchip;
563         int rval;
565         /* i2c check */
566         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
567                 dev_err(&client->dev, "i2c functionality check fail.\n");
568                 return -EOPNOTSUPP;
569         }
571         pchip = devm_kzalloc(&client->dev, sizeof(struct lm3643), GFP_KERNEL);
572         if (!pchip)
573                 return -ENOMEM;
575         pchip->dev = &client->dev;
576         pchip->regmap = devm_regmap_init_i2c(client, &lm3643_regmap);
577         if (IS_ERR(pchip->regmap)) {
578                 rval = PTR_ERR(pchip->regmap);
579                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
580                         rval);
581                 return rval;
582         }
583         mutex_init(&pchip->lock);
584         i2c_set_clientdata(client, pchip);
586         /* led class register */
587         rval = lm3643_led_register(pchip);
588         if (rval < 0)
589                 return rval;
591         /* create dev files*/
592         rval =  lm3643_df_create(pchip);
593         if (rval < 0){
594                 lm3643_led_unregister(pchip, ID_MAX);
595                 return rval;
596         }
598         dev_info(pchip->dev, "lm3643 leds initialized\n");
599         return 0;
602 static int lm3643_remove(struct i2c_client *client)
604         struct lm3643 *pchip = i2c_get_clientdata(client);
606         lm3643_df_remove(pchip, DFILE_MAX);
607         lm3643_led_unregister(pchip, ID_MAX);
609         return 0;
612 static const struct i2c_device_id lm3643_id[] = {
613         {LM3643_NAME, 0},
614         {}
615 };
617 MODULE_DEVICE_TABLE(i2c, lm3643_id);
619 static struct i2c_driver lm3643_i2c_driver = {
620         .driver = {
621                    .name = LM3643_NAME,
622                    .owner = THIS_MODULE,
623                    .pm = NULL,
624                    },
625         .probe = lm3643_probe,
626         .remove = lm3643_remove,
627         .id_table = lm3643_id,
628 };
630 module_i2c_driver(lm3643_i2c_driver);
632 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3643");
633 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
634 MODULE_LICENSE("GPL v2");