Merge tag 'defconfig-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / leds / flash / leds-rt8515.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * LED driver for Richtek RT8515 flash/torch white LEDs
4  * found on some Samsung mobile phones.
5  *
6  * This is a 1.5A Boost dual channel driver produced around 2011.
7  *
8  * The component lacks a datasheet, but in the schematic picture
9  * from the LG P970 service manual you can see the connections
10  * from the RT8515 to the LED, with two resistors connected
11  * from the pins "RFS" and "RTS" to ground.
12  *
13  * On the LG P970:
14  * RFS (resistance flash setting?) is 20 kOhm
15  * RTS (resistance torch setting?) is 39 kOhm
16  *
17  * Some sleuthing finds us the RT9387A which we have a datasheet for:
18  * https://static5.arrow.com/pdfs/2014/7/27/8/21/12/794/rtt_/manual/94download_ds.jspprt9387a.jspprt9387a.pdf
19  * This apparently works the same way so in theory this driver
20  * should cover RT9387A as well. This has not been tested, please
21  * update the compatibles if you add RT9387A support.
22  *
23  * Linus Walleij <linus.walleij@linaro.org>
24  */
25 #include <linux/delay.h>
26 #include <linux/err.h>
27 #include <linux/gpio/consumer.h>
28 #include <linux/led-class-flash.h>
29 #include <linux/mod_devicetable.h>
30 #include <linux/module.h>
31 #include <linux/platform_device.h>
32 #include <linux/property.h>
33 #include <linux/regulator/consumer.h>
34
35 #include <media/v4l2-flash-led-class.h>
36
37 /* We can provide 15-700 mA out to the LED */
38 #define RT8515_MIN_IOUT_MA      15
39 #define RT8515_MAX_IOUT_MA      700
40 /* The maximum intensity is 1-16 for flash and 1-100 for torch */
41 #define RT8515_FLASH_MAX        16
42 #define RT8515_TORCH_MAX        100
43
44 #define RT8515_TIMEOUT_US       250000U
45 #define RT8515_MAX_TIMEOUT_US   300000U
46
47 struct rt8515 {
48         struct led_classdev_flash fled;
49         struct device *dev;
50         struct v4l2_flash *v4l2_flash;
51         struct mutex lock;
52         struct regulator *reg;
53         struct gpio_desc *enable_torch;
54         struct gpio_desc *enable_flash;
55         struct timer_list powerdown_timer;
56         u32 max_timeout; /* Flash max timeout */
57         int flash_max_intensity;
58         int torch_max_intensity;
59 };
60
61 static struct rt8515 *to_rt8515(struct led_classdev_flash *fled)
62 {
63         return container_of(fled, struct rt8515, fled);
64 }
65
66 static void rt8515_gpio_led_off(struct rt8515 *rt)
67 {
68         gpiod_set_value(rt->enable_flash, 0);
69         gpiod_set_value(rt->enable_torch, 0);
70 }
71
72 static void rt8515_gpio_brightness_commit(struct gpio_desc *gpiod,
73                                           int brightness)
74 {
75         int i;
76
77         /*
78          * Toggling a GPIO line with a small delay increases the
79          * brightness one step at a time.
80          */
81         for (i = 0; i < brightness; i++) {
82                 gpiod_set_value(gpiod, 0);
83                 udelay(1);
84                 gpiod_set_value(gpiod, 1);
85                 udelay(1);
86         }
87 }
88
89 /* This is setting the torch light level */
90 static int rt8515_led_brightness_set(struct led_classdev *led,
91                                      enum led_brightness brightness)
92 {
93         struct led_classdev_flash *fled = lcdev_to_flcdev(led);
94         struct rt8515 *rt = to_rt8515(fled);
95
96         mutex_lock(&rt->lock);
97
98         if (brightness == LED_OFF) {
99                 /* Off */
100                 rt8515_gpio_led_off(rt);
101         } else if (brightness < RT8515_TORCH_MAX) {
102                 /* Step it up to movie mode brightness using the flash pin */
103                 rt8515_gpio_brightness_commit(rt->enable_torch, brightness);
104         } else {
105                 /* Max torch brightness requested */
106                 gpiod_set_value(rt->enable_torch, 1);
107         }
108
109         mutex_unlock(&rt->lock);
110
111         return 0;
112 }
113
114 static int rt8515_led_flash_strobe_set(struct led_classdev_flash *fled,
115                                        bool state)
116 {
117         struct rt8515 *rt = to_rt8515(fled);
118         struct led_flash_setting *timeout = &fled->timeout;
119         int brightness = rt->flash_max_intensity;
120
121         mutex_lock(&rt->lock);
122
123         if (state) {
124                 /* Enable LED flash mode and set brightness */
125                 rt8515_gpio_brightness_commit(rt->enable_flash, brightness);
126                 /* Set timeout */
127                 mod_timer(&rt->powerdown_timer,
128                           jiffies + usecs_to_jiffies(timeout->val));
129         } else {
130                 del_timer_sync(&rt->powerdown_timer);
131                 /* Turn the LED off */
132                 rt8515_gpio_led_off(rt);
133         }
134
135         fled->led_cdev.brightness = LED_OFF;
136         /* After this the torch LED will be disabled */
137
138         mutex_unlock(&rt->lock);
139
140         return 0;
141 }
142
143 static int rt8515_led_flash_strobe_get(struct led_classdev_flash *fled,
144                                        bool *state)
145 {
146         struct rt8515 *rt = to_rt8515(fled);
147
148         *state = timer_pending(&rt->powerdown_timer);
149
150         return 0;
151 }
152
153 static int rt8515_led_flash_timeout_set(struct led_classdev_flash *fled,
154                                         u32 timeout)
155 {
156         /* The timeout is stored in the led-class-flash core */
157         return 0;
158 }
159
160 static const struct led_flash_ops rt8515_flash_ops = {
161         .strobe_set = rt8515_led_flash_strobe_set,
162         .strobe_get = rt8515_led_flash_strobe_get,
163         .timeout_set = rt8515_led_flash_timeout_set,
164 };
165
166 static void rt8515_powerdown_timer(struct timer_list *t)
167 {
168         struct rt8515 *rt = from_timer(rt, t, powerdown_timer);
169
170         /* Turn the LED off */
171         rt8515_gpio_led_off(rt);
172 }
173
174 static void rt8515_init_flash_timeout(struct rt8515 *rt)
175 {
176         struct led_classdev_flash *fled = &rt->fled;
177         struct led_flash_setting *s;
178
179         /* Init flash timeout setting */
180         s = &fled->timeout;
181         s->min = 1;
182         s->max = rt->max_timeout;
183         s->step = 1;
184         /*
185          * Set default timeout to RT8515_TIMEOUT_US except if
186          * max_timeout from DT is lower.
187          */
188         s->val = min(rt->max_timeout, RT8515_TIMEOUT_US);
189 }
190
191 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
192 /* Configure the V2L2 flash subdevice */
193 static void rt8515_init_v4l2_flash_config(struct rt8515 *rt,
194                                           struct v4l2_flash_config *v4l2_sd_cfg)
195 {
196         struct led_classdev *led = &rt->fled.led_cdev;
197         struct led_flash_setting *s;
198
199         strscpy(v4l2_sd_cfg->dev_name, led->dev->kobj.name,
200                 sizeof(v4l2_sd_cfg->dev_name));
201
202         /*
203          * Init flash intensity setting: this is a linear scale
204          * capped from the device tree max intensity setting
205          * 1..flash_max_intensity
206          */
207         s = &v4l2_sd_cfg->intensity;
208         s->min = 1;
209         s->max = rt->flash_max_intensity;
210         s->step = 1;
211         s->val = s->max;
212 }
213
214 static void rt8515_v4l2_flash_release(struct rt8515 *rt)
215 {
216         v4l2_flash_release(rt->v4l2_flash);
217 }
218
219 #else
220 static void rt8515_init_v4l2_flash_config(struct rt8515 *rt,
221                                           struct v4l2_flash_config *v4l2_sd_cfg)
222 {
223 }
224
225 static void rt8515_v4l2_flash_release(struct rt8515 *rt)
226 {
227 }
228 #endif
229
230 static void rt8515_determine_max_intensity(struct rt8515 *rt,
231                                            struct fwnode_handle *led,
232                                            const char *resistance,
233                                            const char *max_ua_prop, int hw_max,
234                                            int *max_intensity_setting)
235 {
236         u32 res = 0; /* Can't be 0 so 0 is undefined */
237         u32 ua;
238         u32 max_ma;
239         int max_intensity;
240         int ret;
241
242         fwnode_property_read_u32(rt->dev->fwnode, resistance, &res);
243         ret = fwnode_property_read_u32(led, max_ua_prop, &ua);
244
245         /* Missing info in DT, OK go with hardware maxima */
246         if (ret || res == 0) {
247                 dev_err(rt->dev,
248                         "either %s or %s missing from DT, using HW max\n",
249                         resistance, max_ua_prop);
250                 max_ma = RT8515_MAX_IOUT_MA;
251                 max_intensity = hw_max;
252                 goto out_assign_max;
253         }
254
255         /*
256          * Formula from the datasheet, this is the maximum current
257          * defined by the hardware.
258          */
259         max_ma = (5500 * 1000) / res;
260         /*
261          * Calculate max intensity (linear scaling)
262          * Formula is ((ua / 1000) / max_ma) * 100, then simplified
263          */
264         max_intensity = (ua / 10) / max_ma;
265
266         dev_info(rt->dev,
267                  "current restricted from %u to %u mA, max intensity %d/100\n",
268                  max_ma, (ua / 1000), max_intensity);
269
270 out_assign_max:
271         dev_info(rt->dev, "max intensity %d/%d = %d mA\n",
272                  max_intensity, hw_max, max_ma);
273         *max_intensity_setting = max_intensity;
274 }
275
276 static int rt8515_probe(struct platform_device *pdev)
277 {
278         struct device *dev = &pdev->dev;
279         struct fwnode_handle *child;
280         struct rt8515 *rt;
281         struct led_classdev *led;
282         struct led_classdev_flash *fled;
283         struct led_init_data init_data = {};
284         struct v4l2_flash_config v4l2_sd_cfg = {};
285         int ret;
286
287         rt = devm_kzalloc(dev, sizeof(*rt), GFP_KERNEL);
288         if (!rt)
289                 return -ENOMEM;
290
291         rt->dev = dev;
292         fled = &rt->fled;
293         led = &fled->led_cdev;
294
295         /* ENF - Enable Flash line */
296         rt->enable_flash = devm_gpiod_get(dev, "enf", GPIOD_OUT_LOW);
297         if (IS_ERR(rt->enable_flash))
298                 return dev_err_probe(dev, PTR_ERR(rt->enable_flash),
299                                      "cannot get ENF (enable flash) GPIO\n");
300
301         /* ENT - Enable Torch line */
302         rt->enable_torch = devm_gpiod_get(dev, "ent", GPIOD_OUT_LOW);
303         if (IS_ERR(rt->enable_torch))
304                 return dev_err_probe(dev, PTR_ERR(rt->enable_torch),
305                                      "cannot get ENT (enable torch) GPIO\n");
306
307         child = fwnode_get_next_available_child_node(dev->fwnode, NULL);
308         if (!child) {
309                 dev_err(dev,
310                         "No fwnode child node found for connected LED.\n");
311                 return -EINVAL;
312         }
313         init_data.fwnode = child;
314
315         rt8515_determine_max_intensity(rt, child, "richtek,rfs-ohms",
316                                        "flash-max-microamp",
317                                        RT8515_FLASH_MAX,
318                                        &rt->flash_max_intensity);
319         rt8515_determine_max_intensity(rt, child, "richtek,rts-ohms",
320                                        "led-max-microamp",
321                                        RT8515_TORCH_MAX,
322                                        &rt->torch_max_intensity);
323
324         ret = fwnode_property_read_u32(child, "flash-max-timeout-us",
325                                        &rt->max_timeout);
326         if (ret) {
327                 rt->max_timeout = RT8515_MAX_TIMEOUT_US;
328                 dev_warn(dev,
329                          "flash-max-timeout-us property missing\n");
330         }
331         timer_setup(&rt->powerdown_timer, rt8515_powerdown_timer, 0);
332         rt8515_init_flash_timeout(rt);
333
334         fled->ops = &rt8515_flash_ops;
335
336         led->max_brightness = rt->torch_max_intensity;
337         led->brightness_set_blocking = rt8515_led_brightness_set;
338         led->flags |= LED_CORE_SUSPENDRESUME | LED_DEV_CAP_FLASH;
339
340         mutex_init(&rt->lock);
341
342         platform_set_drvdata(pdev, rt);
343
344         ret = devm_led_classdev_flash_register_ext(dev, fled, &init_data);
345         if (ret) {
346                 fwnode_handle_put(child);
347                 mutex_destroy(&rt->lock);
348                 dev_err(dev, "can't register LED %s\n", led->name);
349                 return ret;
350         }
351
352         rt8515_init_v4l2_flash_config(rt, &v4l2_sd_cfg);
353
354         /* Create a V4L2 Flash device if V4L2 flash is enabled */
355         rt->v4l2_flash = v4l2_flash_init(dev, child, fled, NULL, &v4l2_sd_cfg);
356         if (IS_ERR(rt->v4l2_flash)) {
357                 ret = PTR_ERR(rt->v4l2_flash);
358                 dev_err(dev, "failed to register V4L2 flash device (%d)\n",
359                         ret);
360                 /*
361                  * Continue without the V4L2 flash
362                  * (we still have the classdev)
363                  */
364         }
365
366         fwnode_handle_put(child);
367         return 0;
368 }
369
370 static int rt8515_remove(struct platform_device *pdev)
371 {
372         struct rt8515 *rt = platform_get_drvdata(pdev);
373
374         rt8515_v4l2_flash_release(rt);
375         del_timer_sync(&rt->powerdown_timer);
376         mutex_destroy(&rt->lock);
377
378         return 0;
379 }
380
381 static const struct of_device_id rt8515_match[] = {
382         { .compatible = "richtek,rt8515", },
383         { /* sentinel */ }
384 };
385 MODULE_DEVICE_TABLE(of, rt8515_match);
386
387 static struct platform_driver rt8515_driver = {
388         .driver = {
389                 .name  = "rt8515",
390                 .of_match_table = rt8515_match,
391         },
392         .probe  = rt8515_probe,
393         .remove = rt8515_remove,
394 };
395 module_platform_driver(rt8515_driver);
396
397 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
398 MODULE_DESCRIPTION("Richtek RT8515 LED driver");
399 MODULE_LICENSE("GPL");