]> Git Repo - J-linux.git/blob - drivers/leds/flash/leds-mt6370-flash.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / leds / flash / leds-mt6370-flash.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 Richtek Technology Corp.
4  *
5  * Authors:
6  *   Alice Chen <[email protected]>
7  *   ChiYuan Huang <[email protected]>
8  */
9
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/led-class-flash.h>
16 #include <linux/module.h>
17 #include <linux/mutex.h>
18 #include <linux/platform_device.h>
19 #include <linux/property.h>
20 #include <linux/regmap.h>
21
22 #include <media/v4l2-flash-led-class.h>
23
24 enum {
25         MT6370_LED_FLASH1 = 0,
26         MT6370_LED_FLASH2,
27         MT6370_MAX_LEDS
28 };
29
30 /* Virtual definition for multicolor */
31
32 #define MT6370_REG_FLEDEN               0x17E
33 #define MT6370_REG_STRBTO               0x173
34 #define MT6370_REG_CHGSTAT2             0x1D1
35 #define MT6370_REG_FLEDSTAT1            0x1D9
36 #define MT6370_REG_FLEDISTRB(_id)       (0x174 + 4 * (_id))
37 #define MT6370_REG_FLEDITOR(_id)        (0x175 + 4 * (_id))
38 #define MT6370_ITORCH_MASK              GENMASK(4, 0)
39 #define MT6370_ISTROBE_MASK             GENMASK(6, 0)
40 #define MT6370_STRBTO_MASK              GENMASK(6, 0)
41 #define MT6370_TORCHEN_MASK             BIT(3)
42 #define MT6370_STROBEN_MASK             BIT(2)
43 #define MT6370_FLCSEN_MASK(_id)         BIT(MT6370_LED_FLASH2 - (_id))
44 #define MT6370_FLCSEN_MASK_ALL          GENMASK(1, 0)
45 #define MT6370_FLEDCHGVINOVP_MASK       BIT(3)
46 #define MT6370_FLED1STRBTO_MASK         BIT(11)
47 #define MT6370_FLED2STRBTO_MASK         BIT(10)
48 #define MT6370_FLED1STRB_MASK           BIT(9)
49 #define MT6370_FLED2STRB_MASK           BIT(8)
50 #define MT6370_FLED1SHORT_MASK          BIT(7)
51 #define MT6370_FLED2SHORT_MASK          BIT(6)
52 #define MT6370_FLEDLVF_MASK             BIT(3)
53
54 #define MT6370_LED_JOINT                2
55 #define MT6370_RANGE_FLED_REG           4
56 #define MT6370_ITORCH_MIN_uA            25000
57 #define MT6370_ITORCH_STEP_uA           12500
58 #define MT6370_ITORCH_MAX_uA            400000
59 #define MT6370_ITORCH_DOUBLE_MAX_uA     800000
60 #define MT6370_ISTRB_MIN_uA             50000
61 #define MT6370_ISTRB_STEP_uA            12500
62 #define MT6370_ISTRB_MAX_uA             1500000
63 #define MT6370_ISTRB_DOUBLE_MAX_uA      3000000
64 #define MT6370_STRBTO_MIN_US            64000
65 #define MT6370_STRBTO_STEP_US           32000
66 #define MT6370_STRBTO_MAX_US            2432000
67
68 #define to_mt6370_led(ptr, member) container_of(ptr, struct mt6370_led, member)
69
70 struct mt6370_led {
71         struct led_classdev_flash flash;
72         struct v4l2_flash *v4l2_flash;
73         struct mt6370_priv *priv;
74         u8 led_no;
75 };
76
77 struct mt6370_priv {
78         struct regmap *regmap;
79         struct mutex lock;
80         unsigned int fled_strobe_used;
81         unsigned int fled_torch_used;
82         unsigned int leds_active;
83         unsigned int leds_count;
84         struct mt6370_led leds[] __counted_by(leds_count);
85 };
86
87 static int mt6370_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness level)
88 {
89         struct mt6370_led *led = to_mt6370_led(lcdev, flash.led_cdev);
90         struct mt6370_priv *priv = led->priv;
91         u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
92                               MT6370_FLCSEN_MASK(led->led_no);
93         u32 enable_mask = MT6370_TORCHEN_MASK | led_enable_mask;
94         u32 val = level ? led_enable_mask : 0;
95         u32 curr;
96         int ret, i;
97
98         mutex_lock(&priv->lock);
99
100         /*
101          * There is only one set of flash control logic, and this flag is used to check if 'strobe'
102          * is currently being used.
103          */
104         if (priv->fled_strobe_used) {
105                 dev_warn(lcdev->dev, "Please disable strobe first [%d]\n", priv->fled_strobe_used);
106                 ret = -EBUSY;
107                 goto unlock;
108         }
109
110         if (level)
111                 curr = priv->fled_torch_used | BIT(led->led_no);
112         else
113                 curr = priv->fled_torch_used & ~BIT(led->led_no);
114
115         if (curr)
116                 val |= MT6370_TORCHEN_MASK;
117
118         if (level) {
119                 level -= 1;
120                 if (led->led_no == MT6370_LED_JOINT) {
121                         u32 flevel[MT6370_MAX_LEDS];
122
123                         /*
124                          * There're two flash channels in MT6370. If joint flash output is used,
125                          * torch current will be averaged output from both channels.
126                          */
127                         flevel[0] = level / 2;
128                         flevel[1] = level - flevel[0];
129                         for (i = 0; i < MT6370_MAX_LEDS; i++) {
130                                 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(i),
131                                                          MT6370_ITORCH_MASK, flevel[i]);
132                                 if (ret)
133                                         goto unlock;
134                         }
135                 } else {
136                         ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDITOR(led->led_no),
137                                                  MT6370_ITORCH_MASK, level);
138                         if (ret)
139                                 goto unlock;
140                 }
141         }
142
143         ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val);
144         if (ret)
145                 goto unlock;
146
147         priv->fled_torch_used = curr;
148
149 unlock:
150         mutex_unlock(&priv->lock);
151         return ret;
152 }
153
154 static int mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
155 {
156         /*
157          * Because of the current spikes when turning on the flash, the brightness should be kept
158          * by the LED framework. This empty function is used to prevent checking failure when
159          * led_classdev_flash registers ops.
160          */
161         return 0;
162 }
163
164 static int _mt6370_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
165 {
166         struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
167         struct mt6370_priv *priv = led->priv;
168         struct led_flash_setting *setting = &fl_cdev->brightness;
169         u32 val = (brightness - setting->min) / setting->step;
170         int ret, i;
171
172         if (led->led_no == MT6370_LED_JOINT) {
173                 u32 flevel[MT6370_MAX_LEDS];
174
175                 /*
176                  * There're two flash channels in MT6370. If joint flash output is used, storbe
177                  * current will be averaged output from both channels.
178                  */
179                 flevel[0] = val / 2;
180                 flevel[1] = val - flevel[0];
181                 for (i = 0; i < MT6370_MAX_LEDS; i++) {
182                         ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(i),
183                                                  MT6370_ISTROBE_MASK, flevel[i]);
184                         if (ret)
185                                 break;
186                 }
187         } else {
188                 ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDISTRB(led->led_no),
189                                          MT6370_ISTROBE_MASK, val);
190         }
191
192         return ret;
193 }
194
195 static int mt6370_strobe_set(struct led_classdev_flash *fl_cdev, bool state)
196 {
197         struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
198         struct mt6370_priv *priv = led->priv;
199         struct led_classdev *lcdev = &fl_cdev->led_cdev;
200         struct led_flash_setting *s = &fl_cdev->brightness;
201         u32 led_enable_mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
202                               MT6370_FLCSEN_MASK(led->led_no);
203         u32 enable_mask = MT6370_STROBEN_MASK | led_enable_mask;
204         u32 val = state ? led_enable_mask : 0;
205         u32 curr;
206         int ret;
207
208         mutex_lock(&priv->lock);
209
210         /*
211          * There is only one set of flash control logic, and this flag is used to check if 'torch'
212          * is currently being used.
213          */
214         if (priv->fled_torch_used) {
215                 dev_warn(lcdev->dev, "Please disable torch first [0x%x]\n", priv->fled_torch_used);
216                 ret = -EBUSY;
217                 goto unlock;
218         }
219
220         if (state)
221                 curr = priv->fled_strobe_used | BIT(led->led_no);
222         else
223                 curr = priv->fled_strobe_used & ~BIT(led->led_no);
224
225         if (curr)
226                 val |= MT6370_STROBEN_MASK;
227
228         ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, enable_mask, val);
229         if (ret) {
230                 dev_err(lcdev->dev, "[%d] control current source %d fail\n", led->led_no, state);
231                 goto unlock;
232         }
233
234         /*
235          * If the flash needs to turn on, configure the flash current to ramp up to the setting
236          * value. Otherwise, always revert to the minimum one.
237          */
238         ret = _mt6370_flash_brightness_set(fl_cdev, state ? s->val : s->min);
239         if (ret) {
240                 dev_err(lcdev->dev, "[%d] Failed to set brightness\n", led->led_no);
241                 goto unlock;
242         }
243
244         /*
245          * For the flash to turn on/off, we must wait for HW ramping up/down time 5ms/500us to
246          * prevent the unexpected problem.
247          */
248         if (!priv->fled_strobe_used && curr)
249                 usleep_range(5000, 6000);
250         else if (priv->fled_strobe_used && !curr)
251                 usleep_range(500, 600);
252
253         priv->fled_strobe_used = curr;
254
255 unlock:
256         mutex_unlock(&priv->lock);
257         return ret;
258 }
259
260 static int mt6370_strobe_get(struct led_classdev_flash *fl_cdev, bool *state)
261 {
262         struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
263         struct mt6370_priv *priv = led->priv;
264
265         mutex_lock(&priv->lock);
266         *state = !!(priv->fled_strobe_used & BIT(led->led_no));
267         mutex_unlock(&priv->lock);
268
269         return 0;
270 }
271
272 static int mt6370_timeout_set(struct led_classdev_flash *fl_cdev, u32 timeout)
273 {
274         struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
275         struct mt6370_priv *priv = led->priv;
276         struct led_flash_setting *s = &fl_cdev->timeout;
277         u32 val = (timeout - s->min) / s->step;
278
279         return regmap_update_bits(priv->regmap, MT6370_REG_STRBTO, MT6370_STRBTO_MASK, val);
280 }
281
282 static int mt6370_fault_get(struct led_classdev_flash *fl_cdev, u32 *fault)
283 {
284         struct mt6370_led *led = to_mt6370_led(fl_cdev, flash);
285         struct mt6370_priv *priv = led->priv;
286         u16 fled_stat;
287         unsigned int chg_stat, strobe_timeout_mask, fled_short_mask;
288         u32 rfault = 0;
289         int ret;
290
291         ret = regmap_read(priv->regmap, MT6370_REG_CHGSTAT2, &chg_stat);
292         if (ret)
293                 return ret;
294
295         ret = regmap_raw_read(priv->regmap, MT6370_REG_FLEDSTAT1, &fled_stat, sizeof(fled_stat));
296         if (ret)
297                 return ret;
298
299         switch (led->led_no) {
300         case MT6370_LED_FLASH1:
301                 strobe_timeout_mask = MT6370_FLED1STRBTO_MASK;
302                 fled_short_mask = MT6370_FLED1SHORT_MASK;
303                 break;
304
305         case MT6370_LED_FLASH2:
306                 strobe_timeout_mask = MT6370_FLED2STRBTO_MASK;
307                 fled_short_mask = MT6370_FLED2SHORT_MASK;
308                 break;
309
310         case MT6370_LED_JOINT:
311                 strobe_timeout_mask = MT6370_FLED1STRBTO_MASK | MT6370_FLED2STRBTO_MASK;
312                 fled_short_mask = MT6370_FLED1SHORT_MASK | MT6370_FLED2SHORT_MASK;
313                 break;
314         default:
315                 return -EINVAL;
316         }
317
318         if (chg_stat & MT6370_FLEDCHGVINOVP_MASK)
319                 rfault |= LED_FAULT_INPUT_VOLTAGE;
320
321         if (fled_stat & strobe_timeout_mask)
322                 rfault |= LED_FAULT_TIMEOUT;
323
324         if (fled_stat & fled_short_mask)
325                 rfault |= LED_FAULT_SHORT_CIRCUIT;
326
327         if (fled_stat & MT6370_FLEDLVF_MASK)
328                 rfault |= LED_FAULT_UNDER_VOLTAGE;
329
330         *fault = rfault;
331         return ret;
332 }
333
334 static const struct led_flash_ops mt6370_flash_ops = {
335         .flash_brightness_set = mt6370_flash_brightness_set,
336         .strobe_set = mt6370_strobe_set,
337         .strobe_get = mt6370_strobe_get,
338         .timeout_set = mt6370_timeout_set,
339         .fault_get = mt6370_fault_get,
340 };
341
342 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
343 static int mt6370_flash_external_strobe_set(struct v4l2_flash *v4l2_flash,
344                                             bool enable)
345 {
346         struct led_classdev_flash *flash = v4l2_flash->fled_cdev;
347         struct mt6370_led *led = to_mt6370_led(flash, flash);
348         struct mt6370_priv *priv = led->priv;
349         u32 mask = led->led_no == MT6370_LED_JOINT ? MT6370_FLCSEN_MASK_ALL :
350                    MT6370_FLCSEN_MASK(led->led_no);
351         u32 val = enable ? mask : 0;
352         int ret;
353
354         mutex_lock(&priv->lock);
355
356         ret = regmap_update_bits(priv->regmap, MT6370_REG_FLEDEN, mask, val);
357         if (ret)
358                 goto unlock;
359
360         if (enable)
361                 priv->fled_strobe_used |= BIT(led->led_no);
362         else
363                 priv->fled_strobe_used &= ~BIT(led->led_no);
364
365 unlock:
366         mutex_unlock(&priv->lock);
367         return ret;
368 }
369
370 static const struct v4l2_flash_ops v4l2_flash_ops = {
371         .external_strobe_set = mt6370_flash_external_strobe_set,
372 };
373
374 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg)
375 {
376         struct led_classdev *lcdev;
377         struct led_flash_setting *s = &cfg->intensity;
378
379         lcdev = &led->flash.led_cdev;
380
381         s->min = MT6370_ITORCH_MIN_uA;
382         s->step = MT6370_ITORCH_STEP_uA;
383         s->val = s->max = s->min + (lcdev->max_brightness - 1) * s->step;
384
385         cfg->has_external_strobe = 1;
386         strscpy(cfg->dev_name, dev_name(lcdev->dev), sizeof(cfg->dev_name));
387
388         cfg->flash_faults = LED_FAULT_SHORT_CIRCUIT | LED_FAULT_TIMEOUT |
389                             LED_FAULT_INPUT_VOLTAGE | LED_FAULT_UNDER_VOLTAGE;
390 }
391 #else
392 static const struct v4l2_flash_ops v4l2_flash_ops;
393 static void mt6370_init_v4l2_flash_config(struct mt6370_led *led, struct v4l2_flash_config *cfg)
394 {
395 }
396 #endif
397
398 static void mt6370_v4l2_flash_release(void *v4l2_flash)
399 {
400         v4l2_flash_release(v4l2_flash);
401 }
402
403 static int mt6370_led_register(struct device *parent, struct mt6370_led *led,
404                                struct fwnode_handle *fwnode)
405 {
406         struct led_init_data init_data = { .fwnode = fwnode };
407         struct v4l2_flash_config v4l2_config = {};
408         int ret;
409
410         ret = devm_led_classdev_flash_register_ext(parent, &led->flash, &init_data);
411         if (ret)
412                 return dev_err_probe(parent, ret, "Couldn't register flash %d\n", led->led_no);
413
414         mt6370_init_v4l2_flash_config(led, &v4l2_config);
415         led->v4l2_flash = v4l2_flash_init(parent, fwnode, &led->flash, &v4l2_flash_ops,
416                                           &v4l2_config);
417         if (IS_ERR(led->v4l2_flash))
418                 return dev_err_probe(parent, PTR_ERR(led->v4l2_flash),
419                                      "Failed to register %d v4l2 sd\n", led->led_no);
420
421         return devm_add_action_or_reset(parent, mt6370_v4l2_flash_release, led->v4l2_flash);
422 }
423
424 static u32 mt6370_clamp(u32 val, u32 min, u32 max, u32 step)
425 {
426         u32 retval;
427
428         retval = clamp_val(val, min, max);
429         if (step > 1)
430                 retval = rounddown(retval - min, step) + min;
431
432         return retval;
433 }
434
435 static int mt6370_init_flash_properties(struct device *dev, struct mt6370_led *led,
436                                         struct fwnode_handle *fwnode)
437 {
438         struct led_classdev_flash *flash = &led->flash;
439         struct led_classdev *lcdev = &flash->led_cdev;
440         struct mt6370_priv *priv = led->priv;
441         struct led_flash_setting *s;
442         u32 sources[MT6370_MAX_LEDS];
443         u32 max_ua, val;
444         int i, ret, num;
445
446         num = fwnode_property_count_u32(fwnode, "led-sources");
447         if (num < 1)
448                 return dev_err_probe(dev, -EINVAL,
449                                      "Not specified or wrong number of led-sources\n");
450
451         ret = fwnode_property_read_u32_array(fwnode, "led-sources", sources, num);
452         if (ret)
453                 return ret;
454
455         for (i = 0; i < num; i++) {
456                 if (sources[i] >= MT6370_MAX_LEDS)
457                         return -EINVAL;
458                 if (priv->leds_active & BIT(sources[i]))
459                         return -EINVAL;
460                 priv->leds_active |= BIT(sources[i]);
461         }
462
463         /* If both channels are specified in 'led-sources', joint flash output mode is used */
464         led->led_no = num == 2 ? MT6370_LED_JOINT : sources[0];
465
466         max_ua = num == 2 ? MT6370_ITORCH_DOUBLE_MAX_uA : MT6370_ITORCH_MAX_uA;
467         val = MT6370_ITORCH_MIN_uA;
468         ret = fwnode_property_read_u32(fwnode, "led-max-microamp", &val);
469         if (!ret)
470                 val = mt6370_clamp(val, MT6370_ITORCH_MIN_uA, max_ua, MT6370_ITORCH_STEP_uA);
471
472         lcdev->max_brightness = (val - MT6370_ITORCH_MIN_uA) / MT6370_ITORCH_STEP_uA + 1;
473         lcdev->brightness_set_blocking = mt6370_torch_brightness_set;
474         lcdev->flags |= LED_DEV_CAP_FLASH;
475
476         max_ua = num == 2 ? MT6370_ISTRB_DOUBLE_MAX_uA : MT6370_ISTRB_MAX_uA;
477         val = MT6370_ISTRB_MIN_uA;
478         ret = fwnode_property_read_u32(fwnode, "flash-max-microamp", &val);
479         if (!ret)
480                 val = mt6370_clamp(val, MT6370_ISTRB_MIN_uA, max_ua, MT6370_ISTRB_STEP_uA);
481
482         s = &flash->brightness;
483         s->min = MT6370_ISTRB_MIN_uA;
484         s->step = MT6370_ISTRB_STEP_uA;
485         s->val = s->max = val;
486
487         /* Always configure to the minimum level when off to prevent flash current spikes. */
488         ret = _mt6370_flash_brightness_set(flash, s->min);
489         if (ret)
490                 return ret;
491
492         val = MT6370_STRBTO_MIN_US;
493         ret = fwnode_property_read_u32(fwnode, "flash-max-timeout-us", &val);
494         if (!ret)
495                 val = mt6370_clamp(val, MT6370_STRBTO_MIN_US, MT6370_STRBTO_MAX_US,
496                                    MT6370_STRBTO_STEP_US);
497
498         s = &flash->timeout;
499         s->min = MT6370_STRBTO_MIN_US;
500         s->step = MT6370_STRBTO_STEP_US;
501         s->val = s->max = val;
502
503         flash->ops = &mt6370_flash_ops;
504
505         return 0;
506 }
507
508 static int mt6370_led_probe(struct platform_device *pdev)
509 {
510         struct device *dev = &pdev->dev;
511         struct mt6370_priv *priv;
512         size_t count;
513         int i = 0, ret;
514
515         count = device_get_child_node_count(dev);
516         if (!count || count > MT6370_MAX_LEDS)
517                 return dev_err_probe(dev, -EINVAL,
518                        "No child node or node count over max led number %zu\n", count);
519
520         priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL);
521         if (!priv)
522                 return -ENOMEM;
523
524         priv->leds_count = count;
525         mutex_init(&priv->lock);
526
527         priv->regmap = dev_get_regmap(dev->parent, NULL);
528         if (!priv->regmap)
529                 return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n");
530
531         device_for_each_child_node_scoped(dev, child) {
532                 struct mt6370_led *led = priv->leds + i;
533
534                 led->priv = priv;
535
536                 ret = mt6370_init_flash_properties(dev, led, child);
537                 if (ret)
538                         return ret;
539
540                 ret = mt6370_led_register(dev, led, child);
541                 if (ret)
542                         return ret;
543
544                 i++;
545         }
546
547         return 0;
548 }
549
550 static const struct of_device_id mt6370_led_of_id[] = {
551         { .compatible = "mediatek,mt6370-flashlight" },
552         {}
553 };
554 MODULE_DEVICE_TABLE(of, mt6370_led_of_id);
555
556 static struct platform_driver mt6370_led_driver = {
557         .driver = {
558                 .name = "mt6370-flashlight",
559                 .of_match_table = mt6370_led_of_id,
560         },
561         .probe = mt6370_led_probe,
562 };
563 module_platform_driver(mt6370_led_driver);
564
565 MODULE_AUTHOR("Alice Chen <[email protected]>");
566 MODULE_AUTHOR("ChiYuan Huang <[email protected]>");
567 MODULE_DESCRIPTION("MT6370 FLASH LED Driver");
568 MODULE_LICENSE("GPL");
This page took 0.05948 seconds and 4 git commands to generate.