blob: 6a5332ee1f6172cc0c11a61c590a11fa91c7f950 [file] [log] [blame]
Shilpa Suresh68c62ad2020-03-20 17:39:55 +05301/* Copyright (c) 2013-2014, 2017, 2020, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/leds.h>
19#include <linux/platform_device.h>
20#include <linux/of_gpio.h>
21#include <linux/gpio.h>
22#include <linux/of.h>
23#include <linux/printk.h>
24#include <linux/list.h>
25#include <linux/clk/msm-clk.h>
26#include <linux/clk/msm-clk-provider.h>
27#include <linux/pinctrl/consumer.h>
28
29/* #define CONFIG_GPIO_FLASH_DEBUG */
30#undef CDBG
31#ifdef CONFIG_GPIO_FLASH_DEBUG
32#define CDBG(fmt, args...) pr_err(fmt, ##args)
33#else
34#define CDBG(fmt, args...) do { } while (0)
35#endif
36
37#define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
38#define LED_TRIGGER_DEFAULT "none"
39
40#define GPIO_OUT_LOW (0 << 1)
41#define GPIO_OUT_HIGH (1 << 1)
42
43#define DUTY_CYCLE_BASE 100
44
45enum msm_flash_seq_type_t {
46 FLASH_EN,
47 FLASH_NOW,
48};
49
50enum msm_flash_gpio_type_t {
51 NORMAL_GPIO,
52 CLK_GPIO,
53};
54
55struct msm_flash_ctrl_seq {
56 enum msm_flash_seq_type_t seq_type;
57 uint8_t flash_on_val;
58 uint8_t torch_on_val;
59};
60
61struct led_gpio_flash_data {
62 int flash_en;
63 int flash_now;
64 struct clk *flash_en_clk;
65 struct clk *flash_now_clk;
66 int brightness;
67 atomic_t clk_enabled[2];
68 uint32_t clk_freq[2];
69 uint32_t duty_cycle[2];
70 enum msm_flash_gpio_type_t gpio_type[2];
71 struct led_classdev cdev;
72 struct pinctrl *pinctrl;
73 struct pinctrl_state *gpio_state_default;
74 struct msm_flash_ctrl_seq ctrl_seq[2];
75};
76
77static const struct of_device_id led_gpio_flash_of_match[] = {
78 {.compatible = LED_GPIO_FLASH_DRIVER_NAME,},
79 {},
80};
81
82static void led_gpio_brightness_set(struct led_classdev *led_cdev,
83 enum led_brightness value)
84{
85 int rc = 0;
86 int brightness = value;
87 int flash_en = 0;
88 int flash_now = 0;
89 struct led_gpio_flash_data *flash_led =
90 container_of(led_cdev, struct led_gpio_flash_data, cdev);
91
92 if (brightness > LED_HALF) {
93 flash_en =
94 flash_led->ctrl_seq[FLASH_EN].flash_on_val;
95 flash_now =
96 flash_led->ctrl_seq[FLASH_NOW].flash_on_val;
97 } else if (brightness > LED_OFF) {
98 flash_en =
99 flash_led->ctrl_seq[FLASH_EN].torch_on_val;
100 flash_now =
101 flash_led->ctrl_seq[FLASH_NOW].torch_on_val;
102 } else {
103 flash_en = 0;
104 flash_now = 0;
105 }
106
107 CDBG("%s:flash_en=%d, flash_now=%d\n", __func__, flash_en, flash_now);
108
109 if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
110 rc = gpio_direction_output(flash_led->flash_en, flash_en);
111 } else {
112 if (flash_en == GPIO_OUT_HIGH &&
113 !atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
114 rc = clk_prepare_enable(flash_led->flash_en_clk);
115 atomic_set(&flash_led->clk_enabled[FLASH_EN], 1);
116 } else if (flash_en == GPIO_OUT_LOW &&
117 atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
118 clk_disable_unprepare(flash_led->flash_en_clk);
119 atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
120 }
121 }
122
123 if (rc) {
124 pr_err("%s: Failed to set flash en.\n", __func__);
125 return;
126 }
127
128 if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
129 rc = gpio_direction_output(flash_led->flash_now, flash_now);
130 } else {
131 if (flash_now == GPIO_OUT_HIGH &&
132 !atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
133 rc = clk_prepare_enable(flash_led->flash_now_clk);
134 atomic_set(&flash_led->clk_enabled[FLASH_NOW], 1);
135 } else if (flash_now == GPIO_OUT_LOW &&
136 atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
137 clk_disable_unprepare(flash_led->flash_now_clk);
138 atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
139 }
140 }
141
142 if (rc) {
143 pr_err("%s: Failed to set flash now.\n", __func__);
144 return;
145 }
146
147 flash_led->brightness = brightness;
148}
149
150static enum led_brightness led_gpio_brightness_get(struct led_classdev
151 *led_cdev)
152{
153 struct led_gpio_flash_data *flash_led =
154 container_of(led_cdev, struct led_gpio_flash_data, cdev);
155 return flash_led->brightness;
156}
157
158static int led_gpio_get_dt_data(struct device *dev,
159 struct led_gpio_flash_data *flash_led)
160{
161 int rc = 0;
162 int i = 0;
163 const char *temp_str = NULL;
164 const char *seq_name = NULL;
165 uint32_t array_flash_seq[2];
166 uint32_t array_torch_seq[2];
167 struct device_node *node = dev->of_node;
168
169 flash_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
170 rc = of_property_read_string(node, "linux,default-trigger",
171 &temp_str);
172 if (!rc)
173 flash_led->cdev.default_trigger = temp_str;
174
175 rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
176 if (rc) {
177 pr_err("Failed to read linux name. rc = %d\n", rc);
178 return rc;
179 }
180
181 /* Configure the gpio type as NORMAL_GPIO by default,
182 * the gpio type should be CLK_GPIO if the frequency
183 * is not 0.
184 */
185 flash_led->gpio_type[FLASH_EN] = NORMAL_GPIO;
186 flash_led->gpio_type[FLASH_NOW] = NORMAL_GPIO;
187 rc = of_property_read_u32_array(node, "qcom,clk-freq",
188 flash_led->clk_freq, 2);
189 if (!rc) {
190 if (flash_led->clk_freq[FLASH_EN])
191 flash_led->gpio_type[FLASH_EN] = CLK_GPIO;
192
193 if (flash_led->clk_freq[FLASH_NOW])
194 flash_led->gpio_type[FLASH_NOW] = CLK_GPIO;
195 }
196
197 if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
198 flash_led->flash_en =
199 of_get_named_gpio(node, "qcom,flash-en", 0);
200 if (flash_led->flash_en < 0) {
201 pr_err("Read flash-en property failed. rc = %d\n",
202 flash_led->flash_en);
203 return -EINVAL;
204 }
205 rc = gpio_request(flash_led->flash_en, "FLASH_EN");
206 if (rc) {
207 pr_err("%s: Failed to request gpio %d,rc = %d\n",
208 __func__, flash_led->flash_en, rc);
209 return rc;
210 }
211 } else {
212 flash_led->flash_en_clk =
213 devm_clk_get(dev, "flash_en_clk");
214 if (IS_ERR(flash_led->flash_en_clk)) {
215 pr_err("Failed to get flash-en clk.\n");
216 return -EINVAL;
217 }
218
219 flash_led->clk_freq[FLASH_EN] =
220 clk_round_rate(flash_led->flash_en_clk,
221 flash_led->clk_freq[FLASH_EN]);
222 rc = clk_set_rate(flash_led->flash_en_clk,
223 flash_led->clk_freq[FLASH_EN]);
224 if (rc) {
225 pr_err("%s: Failed to set rate for flash en.\n",
226 __func__);
227 return rc;
228 }
229 }
230
231 if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
232 flash_led->flash_now =
233 of_get_named_gpio(node, "qcom,flash-now", 0);
234 if (flash_led->flash_now < 0) {
235 pr_err("Read flash-now property failed. rc = %d\n",
236 flash_led->flash_now);
237 return -EINVAL;
238 }
239 rc = gpio_request(flash_led->flash_now, "FLASH_NOW");
240 if (rc) {
241 pr_err("%s: Failed to request gpio %d,rc = %d\n",
242 __func__, flash_led->flash_now, rc);
243 return rc;
244 }
245 } else {
246 flash_led->flash_now_clk =
247 devm_clk_get(dev, "flash_now_clk");
248 if (IS_ERR(flash_led->flash_now_clk)) {
249 pr_err("Failed to get flash-now clk.\n");
250 return -EINVAL;
251 }
252
253 flash_led->clk_freq[FLASH_NOW] =
254 clk_round_rate(flash_led->flash_now_clk,
255 flash_led->clk_freq[FLASH_NOW]);
256 rc = clk_set_rate(flash_led->flash_now_clk,
257 flash_led->clk_freq[FLASH_NOW]);
258 if (rc) {
259 pr_err("%s: Failed to set rate for flash now.\n",
260 __func__);
261 return rc;
262 }
263 }
264
265 /* Configure the duty cycle if need. */
266 if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO ||
267 flash_led->gpio_type[FLASH_NOW] == CLK_GPIO) {
268 rc = of_property_read_u32_array(node, "qcom,duty-cycle",
269 flash_led->duty_cycle, 2);
270 if (!rc &&
271 flash_led->duty_cycle[FLASH_EN] >= DUTY_CYCLE_BASE &&
272 flash_led->duty_cycle[FLASH_NOW] >= DUTY_CYCLE_BASE) {
273 pr_err("%s: the duty cycle value is invalid.\n",
274 __func__);
275 return -EINVAL;
276 }
277 }
278
279 /* Based on clk protocol, only RCG clks support duty cycle
280 * configuration, so if the used clk doesn't support set duty
281 * cycle, we use the clk's parent rcg clk to configure the
282 * duty cycle.
283 */
284 if (flash_led->duty_cycle[FLASH_EN]) {
285 struct clk *flash_en_duty_cycle_clk = NULL;
286
287 flash_en_duty_cycle_clk = devm_clk_get(dev,
288 "flash_en_duty_cycle_clk");
289 if (!IS_ERR(flash_en_duty_cycle_clk)) {
290 rc = clk_set_duty_cycle(flash_en_duty_cycle_clk,
291 flash_led->duty_cycle[FLASH_EN],
292 DUTY_CYCLE_BASE);
293 clk_put(flash_en_duty_cycle_clk);
294 } else {
295 rc = clk_set_duty_cycle(flash_led->flash_en_clk,
296 flash_led->duty_cycle[FLASH_EN],
297 DUTY_CYCLE_BASE);
298 }
299
300 if (rc) {
301 pr_err("Failed to set duty cycle for flash en.\n");
302 return rc;
303 }
304 }
305
306 if (flash_led->duty_cycle[FLASH_NOW]) {
307 struct clk *flash_now_duty_cycle_clk = NULL;
308
309 flash_now_duty_cycle_clk = devm_clk_get(dev,
310 "flash_now_duty_cycle_clk");
311 if (!IS_ERR(flash_now_duty_cycle_clk)) {
312 rc = clk_set_duty_cycle(flash_now_duty_cycle_clk,
313 flash_led->duty_cycle[FLASH_NOW],
314 DUTY_CYCLE_BASE);
315 clk_put(flash_now_duty_cycle_clk);
316 } else {
317 rc = clk_set_duty_cycle(flash_led->flash_now_clk,
318 flash_led->duty_cycle[FLASH_NOW],
319 DUTY_CYCLE_BASE);
320 }
321
322 if (rc) {
323 pr_err("Failed to set duty cycle for flash now.\n");
324 return rc;
325 }
326 }
327
328 rc = of_property_read_u32_array(node, "qcom,flash-seq-val",
329 array_flash_seq, 2);
330 if (rc < 0) {
331 pr_err("Failed to get flash op seq, rc = %d\n", rc);
332 return rc;
333 }
334
335 rc = of_property_read_u32_array(node, "qcom,torch-seq-val",
336 array_torch_seq, 2);
337 if (rc < 0) {
338 pr_err("Failed to get torch op seq, rc = %d\n", rc);
339 return rc;
340 }
341
342 pr_debug("%s: seq: flash: %d, %d torch:%d, %d\n", __func__,
343 array_flash_seq[0], array_flash_seq[1],
344 array_torch_seq[0], array_torch_seq[1]);
345
346 for (i = 0; i < 2; i++) {
347 rc = of_property_read_string_index(node,
348 "qcom,op-seq", i,
349 &seq_name);
350 CDBG("%s seq_name[%d] = %s\n", __func__, i,
351 seq_name);
352 if (rc < 0) {
353 pr_err("%s failed %d\n", __func__, __LINE__);
354 return rc;
355 }
356
357 if (!strcmp(seq_name, "flash_en")) {
358 flash_led->ctrl_seq[FLASH_EN].seq_type =
359 FLASH_EN;
360 CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
361 i, flash_led->ctrl_seq[FLASH_EN].seq_type);
362 if (array_flash_seq[i] == 0)
363 flash_led->ctrl_seq[FLASH_EN].flash_on_val =
364 GPIO_OUT_LOW;
365 else
366 flash_led->ctrl_seq[FLASH_EN].flash_on_val =
367 GPIO_OUT_HIGH;
368
369 if (array_torch_seq[i] == 0)
370 flash_led->ctrl_seq[FLASH_EN].torch_on_val =
371 GPIO_OUT_LOW;
372 else
373 flash_led->ctrl_seq[FLASH_EN].torch_on_val =
374 GPIO_OUT_HIGH;
375 } else if (!strcmp(seq_name, "flash_now")) {
376 flash_led->ctrl_seq[FLASH_NOW].seq_type =
377 FLASH_NOW;
378 CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
379 i, flash_led->ctrl_seq[FLASH_NOW].seq_type);
380 if (array_flash_seq[i] == 0)
381 flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
382 GPIO_OUT_LOW;
383 else
384 flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
385 GPIO_OUT_HIGH;
386
387 if (array_torch_seq[i] == 0)
388 flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
389 GPIO_OUT_LOW;
390 else
391 flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
392 GPIO_OUT_HIGH;
393 }
394 }
395
396 return rc;
397}
398
399static int led_gpio_flash_probe(struct platform_device *pdev)
400{
401 int rc = 0;
402 struct led_gpio_flash_data *flash_led = NULL;
403
404 flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
405 GFP_KERNEL);
406 if (flash_led == NULL)
407 return -ENOMEM;
408
409 flash_led->pinctrl = devm_pinctrl_get(&pdev->dev);
410 if (IS_ERR(flash_led->pinctrl)) {
411 pr_err("%s:failed to get pinctrl\n", __func__);
412 rc = PTR_ERR(flash_led->pinctrl);
413 goto error;
414 }
415
416 flash_led->gpio_state_default = pinctrl_lookup_state(flash_led->pinctrl,
417 "flash_default");
418 if (IS_ERR(flash_led->gpio_state_default)) {
419 pr_err("%s:can not get active pinstate\n", __func__);
420 rc = -EINVAL;
421 goto error;
422 }
423
424 rc = pinctrl_select_state(flash_led->pinctrl,
425 flash_led->gpio_state_default);
426 if (rc) {
427 pr_err("%s:set state failed!\n", __func__);
428 goto error;
429 }
430
431 rc = led_gpio_get_dt_data(&pdev->dev, flash_led);
432 if (rc) {
433 pr_err("%s: get device tree data failed.\n",
434 __func__);
435 goto error;
436 }
437
438 /* Add these atomic variables to make sure clk is disabled
439 * just after the clk has been enabled.
440 */
441 atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
442 atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
443
444 platform_set_drvdata(pdev, flash_led);
445 flash_led->cdev.max_brightness = LED_FULL;
446 flash_led->cdev.brightness_set = led_gpio_brightness_set;
447 flash_led->cdev.brightness_get = led_gpio_brightness_get;
448
449 rc = led_classdev_register(&pdev->dev, &flash_led->cdev);
450 if (rc) {
451 pr_err("%s: Failed to register led dev. rc = %d\n",
452 __func__, rc);
453 goto error;
454 }
455 pr_err("%s:probe successfully!\n", __func__);
456 return 0;
457
458error:
459 if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO &&
460 IS_ERR(flash_led->flash_en_clk))
461 devm_clk_put(&pdev->dev, flash_led->flash_en_clk);
462 else if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO &&
463 flash_led->flash_en)
464 gpio_free(flash_led->flash_en);
465
466 if (flash_led->gpio_type[FLASH_NOW] == CLK_GPIO &&
467 IS_ERR(flash_led->flash_now_clk))
468 devm_clk_put(&pdev->dev, flash_led->flash_now_clk);
469 else if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO &&
470 flash_led->flash_now)
471 gpio_free(flash_led->flash_now);
472
473 if (IS_ERR(flash_led->pinctrl))
474 devm_pinctrl_put(flash_led->pinctrl);
475
476 devm_kfree(&pdev->dev, flash_led);
477 return rc;
478}
479
480static int led_gpio_flash_remove(struct platform_device *pdev)
481{
482 struct led_gpio_flash_data *flash_led =
483 (struct led_gpio_flash_data *)platform_get_drvdata(pdev);
484 if (IS_ERR(flash_led->pinctrl))
485 devm_pinctrl_put(flash_led->pinctrl);
486 led_classdev_unregister(&flash_led->cdev);
487 devm_kfree(&pdev->dev, flash_led);
488 return 0;
489}
490
491static struct platform_driver led_gpio_flash_driver = {
492 .probe = led_gpio_flash_probe,
493 .remove = led_gpio_flash_remove,
494 .driver = {
495 .name = LED_GPIO_FLASH_DRIVER_NAME,
496 .owner = THIS_MODULE,
497 .of_match_table = led_gpio_flash_of_match,
498 }
499};
500
501static int __init led_gpio_flash_init(void)
502{
503 return platform_driver_register(&led_gpio_flash_driver);
504}
505
506static void __exit led_gpio_flash_exit(void)
507{
508 return platform_driver_unregister(&led_gpio_flash_driver);
509}
510
511late_initcall(led_gpio_flash_init);
512module_exit(led_gpio_flash_exit);
513
514MODULE_DESCRIPTION("QTI GPIO LEDs driver");
515MODULE_LICENSE("GPL v2");
516MODULE_ALIAS("leds:leds-msm-gpio-flash");