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)
87 {
89         int rval;
90         unsigned int flag0, flag1;
92         rval = regmap_read(pchip->regmap, REG_FLAG0, &flag0);
93         rval |= regmap_read(pchip->regmap, REG_FLAG1, &flag1);
95         if (rval < 0)
96                 dev_err(pchip->dev, "i2c access fail.\n");
98         dev_info(pchip->dev, "[flag1] 0x%x, [flag0] 0x%x\n",
99                  flag1 & 0x1f, flag0);
102 /* torch0 brightness control */
103 static void lm3643_deferred_torch0_brightness_set(struct work_struct *work)
105         struct lm3643 *pchip = container_of(work,
106                                             struct lm3643, work[ID_TORCH0]);
108         if (regmap_update_bits(pchip->regmap,
109                                REG_TORCH_LED0_BR, 0x7f,
110                                pchip->brightness[ID_TORCH0]))
111                 dev_err(pchip->dev, "i2c access fail.\n");
112         lm3643_read_flag(pchip);
115 static void lm3643_torch0_brightness_set(struct led_classdev *cdev,
116                                          enum led_brightness brightness)
118         struct lm3643 *pchip =
119             container_of(cdev, struct lm3643, cdev[ID_TORCH0]);
121         pchip->brightness[ID_TORCH0] = brightness;
122         schedule_work(&pchip->work[ID_TORCH0]);
125 /* torch1 brightness control */
126 static void lm3643_deferred_torch1_brightness_set(struct work_struct *work)
128         struct lm3643 *pchip = container_of(work,
129                                             struct lm3643, work[ID_TORCH1]);
131         if (regmap_update_bits(pchip->regmap,
132                                REG_TORCH_LED1_BR, 0x7f,
133                                pchip->brightness[ID_TORCH1]))
134                 dev_err(pchip->dev, "i2c access fail.\n");
135         lm3643_read_flag(pchip);
138 static void lm3643_torch1_brightness_set(struct led_classdev *cdev,
139                                          enum led_brightness brightness)
141         struct lm3643 *pchip =
142             container_of(cdev, struct lm3643, cdev[ID_TORCH1]);
144         pchip->brightness[ID_TORCH1] = brightness;
145         schedule_work(&pchip->work[ID_TORCH1]);
148 /* flash0 brightness control */
149 static void lm3643_deferred_flash0_brightness_set(struct work_struct *work)
151         struct lm3643 *pchip = container_of(work,
152                                             struct lm3643, work[ID_FLASH0]);
154         if (regmap_update_bits(pchip->regmap,
155                                REG_FLASH_LED0_BR, 0x7f,
156                                pchip->brightness[ID_FLASH0]))
157                 dev_err(pchip->dev, "i2c access fail.\n");
158         lm3643_read_flag(pchip);
161 static void lm3643_flash0_brightness_set(struct led_classdev *cdev,
162                                          enum led_brightness brightness)
164         struct lm3643 *pchip =
165             container_of(cdev, struct lm3643, cdev[ID_FLASH0]);
167         pchip->brightness[ID_FLASH0] = brightness;
168         schedule_work(&pchip->work[ID_FLASH0]);
171 /* flash1 brightness control */
172 static void lm3643_deferred_flash1_brightness_set(struct work_struct *work)
174         struct lm3643 *pchip = container_of(work,
175                                             struct lm3643, work[ID_FLASH1]);
177         if (regmap_update_bits(pchip->regmap,
178                                REG_FLASH_LED1_BR, 0x7f,
179                                pchip->brightness[ID_FLASH1]))
180                 dev_err(pchip->dev, "i2c access fail.\n");
181         lm3643_read_flag(pchip);
184 static void lm3643_flash1_brightness_set(struct led_classdev *cdev,
185                                          enum led_brightness brightness)
187         struct lm3643 *pchip =
188             container_of(cdev, struct lm3643, cdev[ID_FLASH1]);
190         pchip->brightness[ID_FLASH1] = brightness;
191         schedule_work(&pchip->work[ID_FLASH1]);
194 struct lm3643_devices {
195         struct led_classdev cdev;
196         work_func_t func;
197 };
199 static struct lm3643_devices lm3643_leds[ID_MAX] = {
200         [ID_FLASH0] = {
201                        .cdev.name = "flash0",
202                        .cdev.brightness = 0,
203                        .cdev.max_brightness = 0x7f,
204                        .cdev.brightness_set = lm3643_flash0_brightness_set,
205                        .cdev.default_trigger = "flash0",
206                        .func = lm3643_deferred_flash0_brightness_set},
207         [ID_FLASH1] = {
208                        .cdev.name = "flash1",
209                        .cdev.brightness = 0,
210                        .cdev.max_brightness = 0x7f,
211                        .cdev.brightness_set = lm3643_flash1_brightness_set,
212                        .cdev.default_trigger = "flash1",
213                        .func = lm3643_deferred_flash1_brightness_set},
214         [ID_TORCH0] = {
215                        .cdev.name = "torch0",
216                        .cdev.brightness = 0,
217                        .cdev.max_brightness = 0x7f,
218                        .cdev.brightness_set = lm3643_torch0_brightness_set,
219                        .cdev.default_trigger = "torch0",
220                        .func = lm3643_deferred_torch0_brightness_set},
221         [ID_TORCH1] = {
222                        .cdev.name = "torch1",
223                        .cdev.brightness = 0,
224                        .cdev.max_brightness = 0x7f,
225                        .cdev.brightness_set = lm3643_torch1_brightness_set,
226                        .cdev.default_trigger = "torch1",
227                        .func = lm3643_deferred_torch1_brightness_set},
228 };
230 static void lm3643_led_unregister(struct lm3643 *pchip, enum lm3643_devid id)
232         int icnt;
234         for (icnt = id; icnt > 0; icnt--)
235                 led_classdev_unregister(&pchip->cdev[icnt - 1]);
238 static int lm3643_led_register(struct lm3643 *pchip)
240         int icnt, rval;
242         for (icnt = 0; icnt < ID_MAX; icnt++) {
243                 INIT_WORK(&pchip->work[icnt], lm3643_leds[icnt].func);
244                 pchip->cdev[icnt].name = lm3643_leds[icnt].cdev.name;
245                 pchip->cdev[icnt].max_brightness =
246                     lm3643_leds[icnt].cdev.max_brightness;
247                 pchip->cdev[icnt].brightness =
248                     lm3643_leds[icnt].cdev.brightness;
249                 pchip->cdev[icnt].brightness_set =
250                     lm3643_leds[icnt].cdev.brightness_set;
251                 pchip->cdev[icnt].default_trigger =
252                     lm3643_leds[icnt].cdev.default_trigger;
253                 rval = led_classdev_register((struct device *)
254                                              pchip->dev, &pchip->cdev[icnt]);
255                 if (rval < 0) {
256                         lm3643_led_unregister(pchip, icnt);
257                         return rval;
258                 }
259         }
260         return 0;
263 /* device files to control registers */
264 struct lm3643_commands {
265         char *str;
266         int size;
267 };
269 enum lm3643_cmd_id {
270         CMD_ENABLE = 0,
271         CMD_DISABLE,
272         CMD_ON,
273         CMD_OFF,
274         CMD_IRMODE,
275         CMD_OVERRIDE,
276         CMD_MAX
277 };
279 struct lm3643_commands cmds[CMD_MAX] = {
280         [CMD_ENABLE] = {"enable", 6},
281         [CMD_DISABLE] = {"disable", 7},
282         [CMD_ON] = {"on", 2},
283         [CMD_OFF] = {"off", 3},
284         [CMD_IRMODE] = {"irmode", 6},
285         [CMD_OVERRIDE] = {"override", 8},
286 };
288 struct lm3643_files {
289         enum lm3643_devid id;
290         struct device_attribute attr;
291 };
293 static size_t lm3643_ctrl(struct device *dev,
294                           const char *buf, enum lm3643_devid id,
295                           enum lm3643_devfile dfid, size_t size)
297         struct led_classdev *led_cdev = dev_get_drvdata(dev);
298         struct lm3643 *pchip = to_lm3643(led_cdev, id);
299         enum lm3643_cmd_id icnt;
300         int tout, rval;
302         mutex_lock(&pchip->lock);
303         for (icnt = 0; icnt < CMD_MAX; icnt++) {
304                 if (strncmp(buf, cmds[icnt].str, cmds[icnt].size) == 0)
305                         break;
306         }
308         switch (dfid) {
309                 /* led 0 enable */
310         case DFILE_FLASH0_ENABLE:
311         case DFILE_TORCH0_ENABLE:
312                 if (icnt == CMD_ENABLE)
313                         rval =
314                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1,
315                                                0x1);
316                 else if (icnt == CMD_DISABLE)
317                         rval =
318                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1,
319                                                0x0);
320                 break;
321                 /* led 1 enable, flash override */
322         case DFILE_FLASH1_ENABLE:
323                 if (icnt == CMD_ENABLE) {
324                         rval = regmap_update_bits(pchip->regmap,
325                                                   REG_FLASH_LED0_BR, 0x80, 0x0);
326                         rval |=
327                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
328                                                0x2);
329                 } else if (icnt == CMD_DISABLE) {
330                         rval =
331                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
332                                                0x0);
333                 } else if (icnt == CMD_OVERRIDE) {
334                         rval = regmap_update_bits(pchip->regmap,
335                                                   REG_FLASH_LED0_BR, 0x80,
336                                                   0x80);
337                         rval |=
338                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
339                                                0x2);
340                 }
341                 break;
342                 /* led 1 enable, torch override */
343         case DFILE_TORCH1_ENABLE:
344                 if (icnt == CMD_ENABLE) {
345                         rval = regmap_update_bits(pchip->regmap,
346                                                   REG_TORCH_LED0_BR, 0x80, 0x0);
347                         rval |=
348                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
349                                                0x2);
350                 } else if (icnt == CMD_DISABLE) {
351                         rval =
352                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
353                                                0x0);
354                 } else if (icnt == CMD_OVERRIDE) {
355                         rval = regmap_update_bits(pchip->regmap,
356                                                   REG_TORCH_LED0_BR, 0x80,
357                                                   0x80);
358                         rval |=
359                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2,
360                                                0x2);
361                 }
362                 break;
363                 /* mode control flash/ir */
364         case DFILE_FLASH0_ONOFF:
365         case DFILE_FLASH1_ONOFF:
366                 if (icnt == CMD_ON)
367                         rval =
368                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc,
369                                                0xc);
370                 else if (icnt == CMD_OFF)
371                         rval =
372                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc,
373                                                0x0);
374                 else if (icnt == CMD_IRMODE)
375                         rval =
376                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc,
377                                                0x4);
378                 break;
379                 /* mode control torch */
380         case DFILE_TORCH0_ONOFF:
381         case DFILE_TORCH1_ONOFF:
382                 if (icnt == CMD_ON)
383                         rval =
384                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc,
385                                                0x8);
386                 else if (icnt == CMD_OFF)
387                         rval =
388                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc,
389                                                0x0);
390                 break;
391                 /* strobe pin control */
392         case DFILE_FLASH0_SOURCE:
393                 if (icnt == CMD_ON)
394                         rval =
395                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20,
396                                                0x20);
397                 else if (icnt == CMD_OFF)
398                         rval =
399                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20,
400                                                0x0);
401                 break;
402         case DFILE_TORCH0_SOURCE:
403                 if (icnt == CMD_ON)
404                         rval =
405                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10,
406                                                0x10);
407                 else if (icnt == CMD_OFF)
408                         rval =
409                             regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10,
410                                                0x0);
411                 break;
412                 /* flash time out */
413         case DFILE_FLASH0_TIMEOUT:
414                 rval = kstrtouint((const char *)buf, 10, &tout);
415                 if (rval < 0)
416                         break;
417                 rval = regmap_update_bits(pchip->regmap,
418                                           REG_FLASH_TOUT, 0x0f, tout);
419                 break;
420         default:
421                 dev_err(pchip->dev, "error : undefined dev file\n");
422                 break;
423         }
424         lm3643_read_flag(pchip);
425         mutex_unlock(&pchip->lock);
426         return size;
429 /* flash enable control */
430 static ssize_t lm3643_flash0_enable_store(struct device *dev,
431                                           struct device_attribute *devAttr,
432                                           const char *buf, size_t size)
434         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ENABLE, size);
437 static ssize_t lm3643_flash1_enable_store(struct device *dev,
438                                           struct device_attribute *devAttr,
439                                           const char *buf, size_t size)
441         return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ENABLE, size);
444 /* flash onoff control */
445 static ssize_t lm3643_flash0_onoff_store(struct device *dev,
446                                          struct device_attribute *devAttr,
447                                          const char *buf, size_t size)
449         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ONOFF, size);
452 static ssize_t lm3643_flash1_onoff_store(struct device *dev,
453                                          struct device_attribute *devAttr,
454                                          const char *buf, size_t size)
456         return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ONOFF, size);
459 /* flash timeout control */
460 static ssize_t lm3643_flash0_timeout_store(struct device *dev,
461                                            struct device_attribute *devAttr,
462                                            const char *buf, size_t size)
464         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_TIMEOUT, size);
467 /* flash source control */
468 static ssize_t lm3643_flash0_source_store(struct device *dev,
469                                           struct device_attribute *devAttr,
470                                           const char *buf, size_t size)
472         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_SOURCE, size);
475 /* torch enable control */
476 static ssize_t lm3643_torch0_enable_store(struct device *dev,
477                                           struct device_attribute *devAttr,
478                                           const char *buf, size_t size)
480         return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_TORCH0_ENABLE, size);
483 static ssize_t lm3643_torch1_enable_store(struct device *dev,
484                                           struct device_attribute *devAttr,
485                                           const char *buf, size_t size)
487         return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ENABLE, size);
490 /* torch onoff control */
491 static ssize_t lm3643_torch0_onoff_store(struct device *dev,
492                                          struct device_attribute *devAttr,
493                                          const char *buf, size_t size)
495         return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_ONOFF, size);
498 static ssize_t lm3643_torch1_onoff_store(struct device *dev,
499                                          struct device_attribute *devAttr,
500                                          const char *buf, size_t size)
502         return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ONOFF, size);
505 /* torch source control */
506 static ssize_t lm3643_torch0_source_store(struct device *dev,
507                                           struct device_attribute *devAttr,
508                                           const char *buf, size_t size)
510         return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_SOURCE, size);
513 #define lm3643_attr(_name, _show, _store)\
514 {\
515         .attr = {\
516                 .name = _name,\
517                 .mode = 0644,\
518         },\
519         .show = _show,\
520         .store = _store,\
523 static struct lm3643_files lm3643_devfiles[DFILE_MAX] = {
524         [DFILE_FLASH0_ENABLE] = {
525                                  .id = ID_FLASH0,
526                                  .attr =
527                                  lm3643_attr("enable", NULL,
528                                              lm3643_flash0_enable_store),
529                                  },
530         [DFILE_FLASH0_ONOFF] = {
531                                 .id = ID_FLASH0,
532                                 .attr =
533                                 lm3643_attr("onoff", NULL,
534                                             lm3643_flash0_onoff_store),
535                                 },
536         [DFILE_FLASH0_SOURCE] = {
537                                  .id = ID_FLASH0,
538                                  .attr =
539                                  lm3643_attr("source", NULL,
540                                              lm3643_flash0_source_store),
541                                  },
542         [DFILE_FLASH0_TIMEOUT] = {
543                                   .id = ID_FLASH0,
544                                   .attr =
545                                   lm3643_attr("timeout", NULL,
546                                               lm3643_flash0_timeout_store),
547                                   },
548         [DFILE_FLASH1_ENABLE] = {
549                                  .id = ID_FLASH1,
550                                  .attr =
551                                  lm3643_attr("enable", NULL,
552                                              lm3643_flash1_enable_store),
553                                  },
554         [DFILE_FLASH1_ONOFF] = {
555                                 .id = ID_FLASH1,
556                                 .attr =
557                                 lm3643_attr("onoff", NULL,
558                                             lm3643_flash1_onoff_store),
559                                 },
560         [DFILE_TORCH0_ENABLE] = {
561                                  .id = ID_TORCH0,
562                                  .attr =
563                                  lm3643_attr("enable", NULL,
564                                              lm3643_torch0_enable_store),
565                                  },
566         [DFILE_TORCH0_ONOFF] = {
567                                 .id = ID_TORCH0,
568                                 .attr =
569                                 lm3643_attr("onoff", NULL,
570                                             lm3643_torch0_onoff_store),
571                                 },
572         [DFILE_TORCH0_SOURCE] = {
573                                  .id = ID_TORCH0,
574                                  .attr =
575                                  lm3643_attr("source", NULL,
576                                              lm3643_torch0_source_store),
577                                  },
578         [DFILE_TORCH1_ENABLE] = {
579                                  .id = ID_TORCH1,
580                                  .attr =
581                                  lm3643_attr("enable", NULL,
582                                              lm3643_torch1_enable_store),
583                                  },
584         [DFILE_TORCH1_ONOFF] = {
585                                 .id = ID_TORCH1,
586                                 .attr =
587                                 lm3643_attr("onoff", NULL,
588                                             lm3643_torch1_onoff_store),
589                                 }
590 };
592 static void lm3643_df_remove(struct lm3643 *pchip, enum lm3643_devfile dfid)
594         enum lm3643_devfile icnt;
596         for (icnt = dfid; icnt > 0; icnt--)
597                 device_remove_file(pchip->cdev[lm3643_devfiles[icnt - 1].id].
598                                    dev, &lm3643_devfiles[icnt - 1].attr);
601 static int lm3643_df_create(struct lm3643 *pchip)
603         enum lm3643_devfile icnt;
604         int rval;
606         for (icnt = 0; icnt < DFILE_MAX; icnt++) {
607                 rval =
608                     device_create_file(pchip->cdev[lm3643_devfiles[icnt].id].
609                                        dev, &lm3643_devfiles[icnt].attr);
610                 if (rval < 0) {
611                         lm3643_df_remove(pchip, icnt);
612                         return rval;
613                 }
614         }
615         return 0;
618 static const struct regmap_config lm3643_regmap = {
619         .reg_bits = 8,
620         .val_bits = 8,
621         .max_register = 0xff,
622 };
624 static int lm3643_probe(struct i2c_client *client,
625                         const struct i2c_device_id *id)
627         struct lm3643 *pchip;
628         int rval;
630         /* i2c check */
631         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
632                 dev_err(&client->dev, "i2c functionality check fail.\n");
633                 return -EOPNOTSUPP;
634         }
636         pchip = devm_kzalloc(&client->dev, sizeof(struct lm3643), GFP_KERNEL);
637         if (!pchip)
638                 return -ENOMEM;
640         pchip->dev = &client->dev;
641         pchip->regmap = devm_regmap_init_i2c(client, &lm3643_regmap);
642         if (IS_ERR(pchip->regmap)) {
643                 rval = PTR_ERR(pchip->regmap);
644                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
645                         rval);
646                 return rval;
647         }
648         mutex_init(&pchip->lock);
649         i2c_set_clientdata(client, pchip);
651         /* led class register */
652         rval = lm3643_led_register(pchip);
653         if (rval < 0)
654                 return rval;
656         /* create dev files */
657         rval = lm3643_df_create(pchip);
658         if (rval < 0) {
659                 lm3643_led_unregister(pchip, ID_MAX);
660                 return rval;
661         }
663         dev_info(pchip->dev, "lm3643 leds initialized\n");
664         return 0;
667 static int lm3643_remove(struct i2c_client *client)
669         struct lm3643 *pchip = i2c_get_clientdata(client);
671         lm3643_df_remove(pchip, DFILE_MAX);
672         lm3643_led_unregister(pchip, ID_MAX);
674         return 0;
677 static const struct i2c_device_id lm3643_id[] = {
678         {LM3643_NAME, 0},
679         {}
680 };
682 MODULE_DEVICE_TABLE(i2c, lm3643_id);
684 static struct i2c_driver lm3643_i2c_driver = {
685         .driver = {
686                    .name = LM3643_NAME,
687                    .owner = THIS_MODULE,
688                    .pm = NULL,
689                    },
690         .probe = lm3643_probe,
691         .remove = lm3643_remove,
692         .id_table = lm3643_id,
693 };
695 module_i2c_driver(lm3643_i2c_driver);
697 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3643");
698 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
699 MODULE_LICENSE("GPL v2");