f4cdc7e87023c973e6c005d8ba0fd44c4b89c7da
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / ext_flashled_drv / leds-rt8547.c
1 /*
2  *  drivers/leds/leds-rt8547.c
3  *  Driver for Richtek RT8547 LED Flash IC
4  *
5  *  Copyright (C) 2014 Richtek Technology Corp.
6  *  cy_huang <cy_huang@richtek.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  */
13
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/spinlock.h>
18 #include <linux/platform_device.h>
19 #include <linux/delay.h>
20 #include <linux/of_gpio.h>
21 #ifdef CONFIG_OF
22 #include <linux/of.h>
23 #endif /* #ifdef CONFIG_OF */
24 #ifdef CONFIG_DEBUG_FS
25 #include <linux/debugfs.h>
26 #include <linux/uaccess.h>
27 #endif /* #ifdef CONFIG_DEBUG_FS */
28
29 #include "rtfled.h"
30 #include "leds-rt8547.h"
31
32 struct rt8547_chip {
33         rt_fled_info_t base;
34         struct device *dev;
35         struct rt8547_platform_data *pdata;
36         spinlock_t io_lock;
37         unsigned char suspend:1;
38         int in_use_mode;
39 #ifdef CONFIG_DEBUG_FS
40         struct flashlight_device *fled_dev;
41         unsigned char reg_addr;
42         unsigned char reg_data;
43 #endif                          /* #ifdef CONFIG_DEBUG_FS */
44 };
45
46 #ifdef CONFIG_DEBUG_FS
47 struct rt_debug_st {
48         void *info;
49         int id;
50 };
51
52 enum {
53         RT8547_DBG_REG,
54         RT8547_DBG_DATA,
55         RT8547_DBG_REGS,
56         RT8547_DBG_FLED,
57         RT8547_DBG_MAX
58 };
59
60 static struct dentry *debugfs_rt_dent;
61 static struct dentry *debugfs_file[RT8547_DBG_MAX];
62 static struct rt_debug_st rtdbg_data[RT8547_DBG_MAX];
63 #endif /* #ifdef CONFIG_DEBUG_FS */
64
65 static unsigned char rt8547_reg_initval[] = {
66         0x06,                   /* REG 0x01 */
67         0x12,                   /* REG 0x02 */
68         0x02,                   /* REG 0x03 */
69         0x0F,                   /* REG 0x04 */
70 };
71
72 static inline int rt8547_send_bit(struct rt8547_platform_data *pdata,
73                                   unsigned char bit)
74 {
75         if (bit) {
76                 gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
77                 udelay(RT8547_SHORT_DELAY);
78                 gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
79                 udelay(RT8547_LONG_DELAY);
80         } else {
81                 gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
82                 udelay(RT8547_LONG_DELAY);
83                 gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
84                 udelay(RT8547_SHORT_DELAY);
85         }
86         return 0;
87 }
88
89 static inline int rt8547_send_byte(struct rt8547_platform_data *pdata,
90                                    unsigned char byte)
91 {
92         int i;
93
94         /*Send order is high bit to low bit */
95         for (i = 7; i >= 0; i--)
96                 rt8547_send_bit(pdata, byte & (0x1 << i));
97         return 0;
98 }
99
100 static inline int rt8547_send_special_byte(struct rt8547_platform_data *pdata,
101                                            unsigned char byte)
102 {
103         int i;
104
105         /*Only send three bit for register address */
106         for (i = 2; i >= 0; i--)
107                 rt8547_send_bit(pdata, byte & (0x1 << i));
108         return 0;
109 }
110
111 static inline int rt8547_start_xfer(struct rt8547_platform_data *pdata)
112 {
113         gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
114         udelay(RT8547_START_DELAY);
115         return 0;
116 }
117
118 static inline int rt8547_stop_xfer(struct rt8547_platform_data *pdata)
119 {
120         /*Redundant one bit as the stop condition */
121         rt8547_send_bit(pdata, 1);
122         return 0;
123 }
124
125 static int rt8547_send_data(struct rt8547_chip *chip, unsigned char reg,
126                             unsigned char data)
127 {
128         struct rt8547_platform_data *pdata = chip->pdata;
129         unsigned long flags;
130         unsigned char xfer_data[3];     /*0: adddr, 1: reg, 2: reg data*/
131
132         xfer_data[0] = RT8547_ONEWIRE_ADDR;
133         xfer_data[1] = reg;
134         xfer_data[2] = data;
135         RT_DBG("rt8547-> 0: 0x%02x, 1: 0x%02x, 2: 0x%02x\n", xfer_data[0],
136                xfer_data[1], xfer_data[2]);
137         spin_lock_irqsave(&chip->io_lock, flags);
138         rt8547_start_xfer(pdata);
139         rt8547_send_byte(pdata, xfer_data[0]);
140         rt8547_send_special_byte(pdata, xfer_data[1]);
141         rt8547_send_byte(pdata, xfer_data[2]);
142         rt8547_stop_xfer(pdata);
143         spin_unlock_irqrestore(&chip->io_lock, flags);
144         /*write back to reg array*/
145         rt8547_reg_initval[reg - 1] = data;
146         return 0;
147 }
148
149 #ifdef CONFIG_DEBUG_FS
150 static int reg_debug_open(struct inode *inode, struct file *file)
151 {
152         file->private_data = inode->i_private;
153         return 0;
154 }
155
156 static int get_parameters(char *buf, long int *param1, int num_of_par)
157 {
158         char *token;
159         int base, cnt;
160
161         token = strsep(&buf, " ");
162
163         for (cnt = 0; cnt < num_of_par; cnt++) {
164                 if (token != NULL) {
165                         if ((token[1] == 'x') || (token[1] == 'X'))
166                                 base = 16;
167                         else
168                                 base = 10;
169
170                         if (kstrtoul(token, base, &param1[cnt]) != 0)
171                                 return -EINVAL;
172
173                         token = strsep(&buf, " ");
174                 } else
175                         return -EINVAL;
176         }
177         return 0;
178 }
179
180 static ssize_t reg_debug_read(struct file *filp, char __user *ubuf,
181                               size_t count, loff_t *ppos)
182 {
183         struct rt_debug_st *st = filp->private_data;
184         struct rt8547_chip *di = st->info;
185         char lbuf[1000];
186         int i = 0, j = 0;
187
188         lbuf[0] = '\0';
189         switch (st->id) {
190         case RT8547_DBG_REG:
191                 snprintf(lbuf, sizeof(lbuf), "0x%x\n", di->reg_addr);
192                 break;
193         case RT8547_DBG_DATA:
194                 di->reg_data = rt8547_reg_initval[di->reg_addr - 1];
195                 snprintf(lbuf, sizeof(lbuf), "0x%x\n", di->reg_data);
196                 break;
197         case RT8547_DBG_REGS:
198                 for (i = RT8547_FLED_REG0; i < RT8547_FLED_REGMAX; i++)
199                         j += snprintf(lbuf + j, 20, "0x%02x:%02x\n", i,
200                                       rt8547_reg_initval[i - 1]);
201                 break;
202         case RT8547_DBG_FLED:
203                 snprintf(lbuf, sizeof(lbuf), "%d\n", di->in_use_mode);
204                 break;
205         default:
206                 return -EINVAL;
207
208         }
209         return simple_read_from_buffer(ubuf, count, ppos, lbuf, strlen(lbuf));
210 }
211
212 static ssize_t reg_debug_write(struct file *filp,
213                                const char __user *ubuf, size_t cnt,
214                                loff_t *ppos)
215 {
216         struct rt_debug_st *st = filp->private_data;
217         struct rt8547_chip *di = st->info;
218         char lbuf[32];
219         int rc;
220         long int param[5];
221
222         if (cnt > sizeof(lbuf) - 1)
223                 return -EINVAL;
224
225         rc = copy_from_user(lbuf, ubuf, cnt);
226         if (rc)
227                 return -EFAULT;
228
229         lbuf[cnt] = '\0';
230
231         switch (st->id) {
232         case RT8547_DBG_REG:
233                 rc = get_parameters(lbuf, param, 1);
234                 if ((param[0] < RT8547_FLED_REGMAX) && (rc == 0)) {
235                         if ((param[0] >= RT8547_FLED_REG0
236                              && param[0] <= RT8547_FLED_REG3))
237                                 di->reg_addr = (unsigned char)param[0];
238                         else
239                                 rc = -EINVAL;
240                 } else
241                         rc = -EINVAL;
242                 break;
243         case RT8547_DBG_DATA:
244                 rc = get_parameters(lbuf, param, 1);
245                 if ((param[0] <= 0xff) && (rc == 0)) {
246                         rt8547_send_data(di, di->reg_addr,
247                                          (unsigned char)param[0]);
248                 } else
249                         rc = -EINVAL;
250                 break;
251         case RT8547_DBG_FLED:
252                 if (!di->fled_dev)
253                         di->fled_dev = find_flashlight_by_name("rt-flash-led");
254                 rc = get_parameters(lbuf, param, 1);
255                 if ((param[0] <= FLASHLIGHT_MODE_FLASH) && (rc == 0)
256                     && di->fled_dev) {
257                         switch (param[0]) {
258                         case FLASHLIGHT_MODE_TORCH:
259                                 flashlight_set_torch_brightness(di->fled_dev,
260                                                                 2);
261                                 flashlight_set_mode(di->fled_dev,
262                                                     FLASHLIGHT_MODE_TORCH);
263                                 break;
264                         case FLASHLIGHT_MODE_FLASH:
265                                 flashlight_set_strobe_timeout(di->fled_dev,
266                                                               256, 256);
267                                 flashlight_set_strobe_brightness(di->fled_dev,
268                                                                  18);
269                                 flashlight_set_mode(di->fled_dev,
270                                                     FLASHLIGHT_MODE_FLASH);
271                                 flashlight_strobe(di->fled_dev);
272                                 break;
273                         case FLASHLIGHT_MODE_OFF:
274                                 flashlight_set_mode(di->fled_dev,
275                                                     FLASHLIGHT_MODE_OFF);
276                                 break;
277                         }
278                 } else
279                         rc = -EINVAL;
280                 break;
281         default:
282                 return -EINVAL;
283         }
284         if (rc == 0)
285                 rc = cnt;
286         return rc;
287 }
288
289 static const struct file_operations reg_debug_ops = {
290         .open = reg_debug_open,
291         .write = reg_debug_write,
292         .read = reg_debug_read
293 };
294
295 static void rt8547_create_debugfs(struct rt8547_chip *chip)
296 {
297         RT_DBG("add debugfs for RT8547\n");
298         debugfs_rt_dent = debugfs_create_dir("rt8547_dbg", 0);
299         if (!IS_ERR(debugfs_rt_dent)) {
300                 rtdbg_data[0].info = chip;
301                 rtdbg_data[0].id = RT8547_DBG_REG;
302                 debugfs_file[0] = debugfs_create_file("reg",
303                                                       S_IFREG | S_IRUGO,
304                                                       debugfs_rt_dent,
305                                                       (void *)&rtdbg_data[0],
306                                                       &reg_debug_ops);
307
308                 rtdbg_data[1].info = chip;
309                 rtdbg_data[1].id = RT8547_DBG_DATA;
310                 debugfs_file[1] = debugfs_create_file("data",
311                                                       S_IFREG | S_IRUGO,
312                                                       debugfs_rt_dent,
313                                                       (void *)&rtdbg_data[1],
314                                                       &reg_debug_ops);
315
316                 rtdbg_data[2].info = chip;
317                 rtdbg_data[2].id = RT8547_DBG_REGS;
318                 debugfs_file[2] = debugfs_create_file("regs",
319                                                       S_IFREG | S_IRUGO,
320                                                       debugfs_rt_dent,
321                                                       (void *)&rtdbg_data[2],
322                                                       &reg_debug_ops);
323
324                 rtdbg_data[3].info = chip;
325                 rtdbg_data[3].id = RT8547_DBG_FLED;
326                 debugfs_file[3] = debugfs_create_file("fled",
327                                                       S_IFREG | S_IRUGO,
328                                                       debugfs_rt_dent,
329                                                       (void *)&rtdbg_data[3],
330                                                       &reg_debug_ops);
331         } else {
332                 dev_err(chip->dev, "create debugfs failed\n");
333         }
334 }
335
336 static void rt8547_remove_debugfs(void)
337 {
338         if (!IS_ERR(debugfs_rt_dent))
339                 debugfs_remove_recursive(debugfs_rt_dent);
340 }
341 #endif /* #ifdef CONFIG_DEBUG_FS */
342
343 static inline void rt8547_fled_power_on(struct rt8547_platform_data *pdata)
344 {
345     if (gpio_is_valid(pdata->flset_gpio))
346         gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
347 }
348
349 static inline void rt8547_fled_power_off(struct rt8547_platform_data *pdata)
350 {
351     if (gpio_is_valid(pdata->flset_gpio))
352         gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
353         udelay(RT8547_STOP_DELAY);
354 }
355
356 static inline void rt8547_fled_ctrl_en(struct rt8547_platform_data *pdata,
357                                        int en)
358 {
359     if (gpio_is_valid(pdata->ctl_gpio)){
360         if (en)
361                 gpio_set_value(pdata->ctl_gpio, ((pdata->ctl_active) & 0x1));
362         else
363                 gpio_set_value(pdata->ctl_gpio, (~(pdata->ctl_active) & 0x1));
364         }
365         RT_DBG("en %d\n", en);
366 }
367
368 static inline void rt8547_fled_flash_en(struct rt8547_platform_data *pdata,
369                                         int en)
370 {
371     if (gpio_is_valid(pdata->flen_gpio)){
372         if (en)
373                 gpio_set_value(pdata->flen_gpio, ((pdata->flen_active) & 0x1));
374         else
375                 gpio_set_value(pdata->flen_gpio, (~(pdata->flen_active) & 0x1));
376         }
377         RT_DBG("en %d\n", en);
378 }
379
380 static int rt8547_fled_init(struct rt_fled_info *info)
381 {
382         RT_DBG("\n");
383         return 0;
384 }
385
386 static int rt8547_fled_resume(struct rt_fled_info *info)
387 {
388         struct rt8547_chip *fi = (struct rt8547_chip *)info;
389
390         RT_DBG("\n");
391         fi->suspend = 0;
392         return 0;
393 }
394
395 static int rt8547_fled_suspend(struct rt_fled_info *info, pm_message_t state)
396 {
397         struct rt8547_chip *fi = (struct rt8547_chip *)info;
398
399         RT_DBG("\n");
400         fi->suspend = 1;
401         return 0;
402 }
403
404 static int rt8547_fled_set_mode(struct rt_fled_info *info,
405                                 flashlight_mode_t mode)
406 {
407         struct rt8547_chip *fi = (struct rt8547_chip *)info;
408         unsigned char tmp = 0;
409         int ret = 0;
410
411         RT_DBG("mode=%d\n", mode);
412         switch (mode) {
413         case FLASHLIGHT_MODE_TORCH:
414                 if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
415                         rt8547_fled_power_on(fi->pdata);
416                 tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
417                 tmp |= RT8547_MODESEL_MASK;
418                 rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
419                 rt8547_fled_ctrl_en(fi->pdata, 1);
420                 rt8547_fled_flash_en(fi->pdata, 1);
421                 fi->in_use_mode = mode;
422                 break;
423         case FLASHLIGHT_MODE_FLASH:
424                 if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
425                         rt8547_fled_power_on(fi->pdata);
426                 tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
427                 tmp &= ~RT8547_MODESEL_MASK;
428                 rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
429                 fi->in_use_mode = mode;
430                 break;
431         case FLASHLIGHT_MODE_OFF:
432                 rt8547_fled_flash_en(fi->pdata, 0);
433                 rt8547_fled_ctrl_en(fi->pdata, 0);
434                 if (fi->in_use_mode != FLASHLIGHT_MODE_OFF)
435                         rt8547_fled_power_off(fi->pdata);
436                 fi->in_use_mode = mode;
437                 break;
438         case FLASHLIGHT_MODE_MIXED:
439         default:
440                 ret = -EINVAL;
441         }
442         return 0;
443 }
444
445 static int rt8547_fled_get_mode(struct rt_fled_info *info)
446 {
447         struct rt8547_chip *fi = (struct rt8547_chip *)info;
448
449         RT_DBG("\n");
450         return fi->in_use_mode;
451 }
452
453 static int rt8547_fled_strobe(struct rt_fled_info *info)
454 {
455         struct rt8547_chip *fi = (struct rt8547_chip *)info;
456
457         RT_DBG("\n");
458         rt8547_fled_flash_en(fi->pdata, 0);
459         rt8547_fled_ctrl_en(fi->pdata, 0);
460         rt8547_fled_ctrl_en(fi->pdata, 1);
461         rt8547_fled_flash_en(fi->pdata, 1);
462         return 0;
463 }
464
465 static int rt8547_fled_torch_current_list(struct rt_fled_info *info,
466                                           int selector)
467 {
468         RT_DBG("selector=%d\n", selector);
469         return 25000 + selector * 25000;        /* unit: uA */
470 }
471
472 static int rt8547_fled_strobe_current_list(struct rt_fled_info *info,
473                                            int selector)
474 {
475         RT_DBG("selector=%d\n", selector);
476         return 100000 + selector * 50000;       /* unit: uA */
477 }
478
479 static int rt8547_fled_timeout_level_list(struct rt_fled_info *info,
480                                           int selector)
481 {
482         RT_DBG("selector=%d\n", selector);
483         return 100000 + selector * 50000;       /* unit: uA */
484 }
485
486 static int rt8547_fled_lv_protection_list(struct rt_fled_info *info,
487                                           int selector)
488 {
489         RT_DBG("selector=%d\n", selector);
490         return 3000 + selector * 100;   /* unit: mV */
491 }
492
493 static int rt8547_fled_strobe_timeout_list(struct rt_fled_info *info,
494                                            int selector)
495 {
496         RT_DBG("selector=%d\n", selector);
497         return 64 + selector * 32;      /* unit: mS */
498 }
499
500 static int rt8547_fled_set_torch_current_sel(struct rt_fled_info *info,
501                                              int selector)
502 {
503
504         struct rt8547_chip *fi = (struct rt8547_chip *)info;
505         unsigned char tmp = 0;
506
507         RT_DBG("selector=%d\n", selector);
508         tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
509         tmp &= ~RT8547_TCLEVEL_MASK;
510         tmp |= selector;
511         rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
512         return 0;
513 }
514
515 static int rt8547_fled_set_strobe_current_sel(struct rt_fled_info *info,
516                                               int selector)
517 {
518         struct rt8547_chip *fi = (struct rt8547_chip *)info;
519         unsigned char tmp = 0;
520
521         RT_DBG("selector=%d\n", selector);
522         tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
523         tmp &= ~RT8547_SCLEVEL_MASK;
524         tmp |= selector;
525         rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
526         return 0;
527 }
528
529 static int rt8547_fled_set_timeout_level_sel(struct rt_fled_info *info,
530                                              int selector)
531 {
532         struct rt8547_chip *fi = (struct rt8547_chip *)info;
533         unsigned char tmp = 0;
534
535         RT_DBG("selector=%d\n", selector);
536         if (selector > RT8547_TOL_MAX)
537                 return -EINVAL;
538         tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
539         tmp &= ~RT8547_TOCLEVEL_MASK;
540         tmp |= (selector << RT8547_TOCLEVEL_SHFT);
541         rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
542         return 0;
543 }
544
545 static int rt8547_fled_set_lv_protection_sel(struct rt_fled_info *info,
546                                              int selector)
547 {
548         struct rt8547_chip *fi = (struct rt8547_chip *)info;
549         unsigned char tmp = 0;
550
551         RT_DBG("selector=%d\n", selector);
552         if (selector > RT8547_LVP_MAX)
553                 return -EINVAL;
554         tmp = rt8547_reg_initval[RT8547_FLED_REG0 - 1];
555         tmp &= ~RT8547_LVP_MASK;
556         tmp |= selector;
557         rt8547_send_data(fi, RT8547_FLED_REG0, tmp);
558         return 0;
559 }
560
561 static int rt8547_fled_set_strobe_timeout_sel(struct rt_fled_info *info,
562                                               int selector)
563 {
564         struct rt8547_chip *fi = (struct rt8547_chip *)info;
565         unsigned char tmp = 0;
566
567         RT_DBG("selector=%d\n", selector);
568         if (selector > RT8547_STO_MAX)
569                 return -EINVAL;
570         tmp = rt8547_reg_initval[RT8547_FLED_REG3 - 1];
571         tmp &= ~RT8547_STO_MASK;
572         tmp |= selector;
573         rt8547_send_data(fi, RT8547_FLED_REG3, tmp);
574         return 0;
575 }
576
577 static int rt8547_fled_get_torch_current_sel(struct rt_fled_info *info)
578 {
579         int selector =
580             rt8547_reg_initval[RT8547_FLED_REG2 - 1] & RT8547_TCLEVEL_MASK;
581
582         return selector;
583 }
584
585 static int rt8547_fled_get_strobe_current_sel(struct rt_fled_info *info)
586 {
587         int selector =
588             rt8547_reg_initval[RT8547_FLED_REG1 - 1] & RT8547_SCLEVEL_MASK;
589
590         return selector;
591 }
592
593 static int rt8547_fled_get_timeout_level_sel(struct rt_fled_info *info)
594 {
595         int selector =
596             rt8547_reg_initval[RT8547_FLED_REG1 - 1] & RT8547_TOCLEVEL_MASK;
597
598         selector >>= RT8547_TOCLEVEL_SHFT;
599         return selector;
600 }
601
602 static int rt8547_fled_get_lv_protection_sel(struct rt_fled_info *info)
603 {
604         int selector =
605             rt8547_reg_initval[RT8547_FLED_REG0 - 1] & RT8547_LVP_MASK;
606
607         return selector;
608 }
609
610 static int rt8547_fled_get_strobe_timeout_sel(struct rt_fled_info *info)
611 {
612         int selector =
613             rt8547_reg_initval[RT8547_FLED_REG3 - 1] & RT8547_STO_MASK;
614
615         return selector;
616 }
617
618 static struct rt_fled_hal rt8547_fled_hal = {
619         .fled_init = rt8547_fled_init,
620         .fled_suspend = rt8547_fled_suspend,
621         .fled_resume = rt8547_fled_resume,
622         .fled_set_mode = rt8547_fled_set_mode,
623         .fled_get_mode = rt8547_fled_get_mode,
624         .fled_strobe = rt8547_fled_strobe,
625         .fled_torch_current_list = rt8547_fled_torch_current_list,
626         .fled_strobe_current_list = rt8547_fled_strobe_current_list,
627         .fled_timeout_level_list = rt8547_fled_timeout_level_list,
628         .fled_lv_protection_list = rt8547_fled_lv_protection_list,
629         .fled_strobe_timeout_list = rt8547_fled_strobe_timeout_list,
630         /* method to set */
631         .fled_set_torch_current_sel = rt8547_fled_set_torch_current_sel,
632         .fled_set_strobe_current_sel = rt8547_fled_set_strobe_current_sel,
633         .fled_set_timeout_level_sel = rt8547_fled_set_timeout_level_sel,
634         .fled_set_lv_protection_sel = rt8547_fled_set_lv_protection_sel,
635         .fled_set_strobe_timeout_sel = rt8547_fled_set_strobe_timeout_sel,
636         /* method to get */
637         .fled_get_torch_current_sel = rt8547_fled_get_torch_current_sel,
638         .fled_get_strobe_current_sel = rt8547_fled_get_strobe_current_sel,
639         .fled_get_timeout_level_sel = rt8547_fled_get_timeout_level_sel,
640         .fled_get_lv_protection_sel = rt8547_fled_get_lv_protection_sel,
641         .fled_get_strobe_timeout_sel = rt8547_fled_get_strobe_timeout_sel,
642 };
643
644 static struct flashlight_properties rt8547_fled_props = {
645         .type = FLASHLIGHT_TYPE_LED,
646         .torch_brightness = 2,
647         .torch_max_brightness = 15,
648         .strobe_brightness = 18,
649         .strobe_max_brightness = 30,
650         .strobe_delay = 2,
651         .strobe_timeout = 544,
652         .alias_name = "rt8547-fled",
653 };
654
655 static void rt8547_parse_dt(struct rt8547_platform_data *pdata,
656                             struct device *dev)
657 {
658 #ifdef CONFIG_OF
659         struct device_node *np = dev->of_node;
660         u32 tmp;
661
662         if (of_property_read_u32(np, "rt,def_lvp", &tmp) < 0) {
663                 dev_warn(dev, "use 3V as the default lvp\n");
664         } else {
665                 if (tmp > RT8547_LVP_MAX)
666                         tmp = RT8547_LVP_MAX;
667                 rt8547_reg_initval[RT8547_FLED_REG0 - 1] &= ~RT8547_LVP_MASK;
668                 rt8547_reg_initval[RT8547_FLED_REG0 - 1] |= tmp;
669         }
670
671         if (of_property_read_u32(np, "rt,def_tol", &tmp) < 0) {
672                 dev_warn(dev, "use 100mA as the default timeout level\n");
673         } else {
674                 if (tmp > RT8547_TOL_MAX)
675                         tmp = RT8547_TOL_MAX;
676                 tmp <<= RT8547_TOCLEVEL_SHFT;
677                 rt8547_reg_initval[RT8547_FLED_REG1 - 1] &=
678                     ~RT8547_TOCLEVEL_MASK;
679                 rt8547_reg_initval[RT8547_FLED_REG1 - 1] |= tmp;
680         }
681         pdata->flen_gpio = of_get_named_gpio(np, "rt,flen_gpio", 0);
682         pdata->ctl_gpio = of_get_named_gpio(np, "rt,ctl_gpio", 0);
683         pdata->flset_gpio = of_get_named_gpio(np, "rt,flset_gpio", 0);
684 #endif /* #ifdef CONFIG_OF */
685 }
686
687 static void rt8547_parse_pdata(struct rt8547_platform_data *pdata,
688                                struct device *dev)
689 {
690         u32 tmp;
691
692         tmp = pdata->def_lvp;
693         rt8547_reg_initval[RT8547_FLED_REG0 - 1] &= ~RT8547_LVP_MASK;
694         rt8547_reg_initval[RT8547_FLED_REG0 - 1] |= tmp;
695
696         tmp = pdata->def_tol;
697         tmp <<= RT8547_TOCLEVEL_SHFT;
698         rt8547_reg_initval[RT8547_FLED_REG1 - 1] &= ~RT8547_TOCLEVEL_MASK;
699         rt8547_reg_initval[RT8547_FLED_REG1 - 1] |= tmp;
700 }
701
702 static int rt8547_io_init(struct rt8547_platform_data *pdata,
703                           struct device *dev)
704 {
705         int rc = 0;
706
707         if (gpio_is_valid(pdata->flen_gpio)) {
708                 rc = gpio_request_one(pdata->flen_gpio, ((~(pdata->flen_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
709                                       "rt8547_flen");
710                 if (rc < 0) {
711                         dev_err(dev, "request rt8547 flash en pin fail\n");
712                         goto gpio_request1;
713                 }
714
715         }
716
717         if(gpio_is_valid(pdata->ctl_gpio)){
718                 rc = gpio_request_one(pdata->ctl_gpio, ((~(pdata->ctl_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
719                                       "rt8547_ctl");
720                 if (rc < 0) {
721                         dev_err(dev, "request rt8547 ctl pin fail\n");
722                         goto gpio_request2;
723                 }
724         }
725
726         if(gpio_is_valid(pdata->flset_gpio)){
727                 rc = gpio_request_one(pdata->flset_gpio, ((~(pdata->flset_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
728                                       "rt8547_flset");
729                 if (rc < 0) {
730                         dev_err(dev, "request rt8547 flash set pin fail\n");
731                         goto gpio_request3;
732                 }
733         }
734         return 0;
735 gpio_request3:
736     if(gpio_is_valid(pdata->ctl_gpio))
737         gpio_free(pdata->ctl_gpio);
738 gpio_request2:
739     if (gpio_is_valid(pdata->flen_gpio))
740         gpio_free(pdata->flen_gpio);
741 gpio_request1:
742         return rc;
743
744 }
745
746 static int rt8547_io_deinit(struct rt8547_platform_data *pdata)
747 {
748     if (gpio_is_valid(pdata->flen_gpio)){
749         gpio_direction_input(pdata->flen_gpio);
750         gpio_free(pdata->flen_gpio);
751         }
752     if(gpio_is_valid(pdata->ctl_gpio)){
753         gpio_direction_input(pdata->ctl_gpio);
754         gpio_free(pdata->ctl_gpio);
755         }
756         if(gpio_is_valid(pdata->flset_gpio)){
757         gpio_direction_input(pdata->flset_gpio);
758         gpio_free(pdata->flset_gpio);
759         }
760         return 0;
761 }
762
763 static void rt8547_reg_init(struct rt8547_chip *chip)
764 {
765         RT_DBG("\n");
766         rt8547_send_data(chip, RT8547_FLED_REG0,
767                          rt8547_reg_initval[RT8547_FLED_REG0 - 1]);
768         rt8547_send_data(chip, RT8547_FLED_REG1,
769                          rt8547_reg_initval[RT8547_FLED_REG1 - 1]);
770         rt8547_send_data(chip, RT8547_FLED_REG2,
771                          rt8547_reg_initval[RT8547_FLED_REG2 - 1]);
772         rt8547_send_data(chip, RT8547_FLED_REG3,
773                          rt8547_reg_initval[RT8547_FLED_REG3 - 1]);
774 }
775
776 static struct platform_device rt_fled_pdev = {
777         .name = "rt-flash-led",
778         .id = -1,
779 };
780
781 static int rt8547_led_probe(struct platform_device *pdev)
782 {
783         struct rt8547_platform_data *pdata = pdev->dev.platform_data;
784         struct rt8547_chip *chip;
785         bool use_dt = pdev->dev.of_node;
786         int ret = 0;
787
788         chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
789         if (!chip)
790                 return -ENOMEM;
791         if (use_dt) {
792                 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
793                 if (!pdata)
794                         goto err_probe;
795                 rt8547_parse_dt(pdata, &pdev->dev);
796         } else {
797                 if (!pdata)
798                         goto err_probe;
799                 rt8547_parse_pdata(pdata, &pdev->dev);
800         }
801
802         ret = rt8547_io_init(pdata, &pdev->dev);
803         if (ret < 0)
804                 goto err_io;
805
806         chip->dev = &pdev->dev;
807         chip->pdata = pdata;
808         spin_lock_init(&chip->io_lock);
809         chip->in_use_mode = FLASHLIGHT_MODE_OFF;
810         platform_set_drvdata(pdev, chip);
811
812         rt8547_fled_power_on(pdata);
813         rt8547_reg_init(chip);
814         rt8547_fled_power_off(pdata);
815
816         chip->base.hal = &rt8547_fled_hal;
817         chip->base.init_props = &rt8547_fled_props;
818         rt_fled_pdev.dev.parent = &pdev->dev;
819         ret = platform_device_register(&rt_fled_pdev);
820         if (ret < 0) {
821                 dev_err(&pdev->dev, "register rtfled fail\n");
822                 goto err_io;
823         }
824 #ifdef CONFIG_DEBUG_FS
825         rt8547_create_debugfs(chip);
826 #endif /* #ifdef CONFIG_DEBUG_FS */
827         dev_info(&pdev->dev, "driver successfully registered\n");
828         return 0;
829 err_io:
830         if (use_dt)
831                 devm_kfree(&pdev->dev, pdata);
832 err_probe:
833         devm_kfree(&pdev->dev, chip);
834         return ret;
835 }
836
837 static int rt8547_led_remove(struct platform_device *pdev)
838 {
839         struct rt8547_chip *chip = platform_get_drvdata(pdev);
840
841 #ifdef CONFIG_DEBUG_FS
842         rt8547_remove_debugfs();
843 #endif /* #ifdef CONFIG_DEBUG_FS */
844         platform_device_unregister(&rt_fled_pdev);
845         rt8547_io_deinit(chip->pdata);
846         return 0;
847 }
848
849 static const struct of_device_id rt_match_table[] = {
850         {.compatible = "rt,rt8547",},
851         {},
852 };
853
854 static struct platform_driver rt8547_led_driver = {
855         .driver = {
856                    .name = "rt8547",
857                    .owner = THIS_MODULE,
858                    .of_match_table = rt_match_table,
859                    },
860         .probe = rt8547_led_probe,
861         .remove = rt8547_led_remove,
862 };
863
864 static int rt8547_led_init(void)
865 {
866         return platform_driver_register(&rt8547_led_driver);
867 }
868
869 module_init(rt8547_led_init);
870
871 static void rt8547_led_exit(void)
872 {
873         platform_driver_unregister(&rt8547_led_driver);
874 }
875
876 module_exit(rt8547_led_exit);
877
878 MODULE_LICENSE("GPL");
879 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
880 MODULE_DESCRIPTION("LED Flash Driver for RT8547");
881 MODULE_VERSION(RT8547_DRV_VER);