1 /* drivers/leds/rtfled.c
2 * Richtek Flash LED Universal Architecture
4 * Copyright (C) 2013 Richtek Technology Corp.
5 * Author: Patrick Chang <patrick_chang@richtek.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
17 #include <linux/init.h>
18 #include <linux/version.h>
20 #define RTFLED_INFO(format, args...) \
21 pr_info("%s:%s() line-%d: " format, \
22 ALIAS_NAME, __func__, __LINE__, ## args)
23 #define RTFLED_WARN(format, args...) \
24 pr_warn("%s:%s() line-%d: " format, \
25 ALIAS_NAME, __func__, __LINE__, ## args)
26 #define RTFLED_ERR(format, args...) \
27 pr_err("%s:%s() line-%d: " format, \
28 ALIAS_NAME, __func__, __LINE__, ## args)
30 #define RT_FLED_DEVICE "rt-flash-led"
31 #define ALIAS_NAME RT_FLED_DEVICE
33 rt_fled_info_t *rt_fled_get_info_by_name(char *name)
35 struct flashlight_device *flashlight_dev;
37 flashlight_dev = find_flashlight_by_name(name ? name : RT_FLED_DEVICE);
38 if (flashlight_dev == NULL)
39 return (rt_fled_info_t *) NULL;
40 return flashlight_get_data(flashlight_dev);
42 EXPORT_SYMBOL(rt_fled_get_info_by_name);
44 static int rtfled_set_torch_brightness(struct flashlight_device *flashlight_dev,
47 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
49 return info->hal->fled_set_torch_current_sel(info, brightness_sel);
52 static int rtfled_set_strobe_brightness(struct flashlight_device
53 *flashlight_dev, int brightness_sel)
55 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
57 return info->hal->fled_set_strobe_current_sel(info, brightness_sel);
60 static int rtfled_set_strobe_timeout(struct flashlight_device *flashlight_dev,
63 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
67 return info->hal->fled_set_strobe_timeout(info, timeout, timeout, &sel);
70 static int rtfled_list_strobe_timeout(struct flashlight_device *flashlight_dev,
73 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
75 return info->hal->fled_strobe_timeout_list(info, selector);
78 static int rtfled_set_mode(struct flashlight_device *flashlight_dev, int mode)
80 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
82 return info->hal->fled_set_mode(info, mode);
85 static int rtfled_strobe(struct flashlight_device *flashlight_dev)
87 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
89 return info->hal->fled_strobe(info);
92 static int rtfled_set_color_temperature(struct flashlight_device
93 *flashlight_dev, int color_temp)
95 /* Doesn't support color temperature */
99 static int rtfled_list_color_temperature(struct flashlight_device
100 *flashlight_dev, int selector)
102 /* Doesn't support color temperature */
106 static int rtfled_suspend(struct flashlight_device *flashlight_dev,
109 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
111 if (info->hal->fled_suspend)
112 return info->hal->fled_suspend(info, state);
116 static int rtfled_resume(struct flashlight_device *flashlight_dev)
118 rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
120 if (info->hal->fled_resume)
121 return info->hal->fled_resume(info);
125 static struct flashlight_ops rtfled_impl_ops = {
126 .set_torch_brightness = rtfled_set_torch_brightness,
127 .set_strobe_brightness = rtfled_set_strobe_brightness,
128 .set_strobe_timeout = rtfled_set_strobe_timeout,
129 .list_strobe_timeout = rtfled_list_strobe_timeout,
130 .set_mode = rtfled_set_mode,
131 .strobe = rtfled_strobe,
132 .set_color_temperature = rtfled_set_color_temperature,
133 .list_color_temperature = rtfled_list_color_temperature,
134 .suspend = rtfled_suspend,
135 .resume = rtfled_resume,
138 static void rfled_shutdown(struct platform_device *pdev)
140 struct rt_fled_info *info = platform_get_drvdata(pdev);
142 if (info->hal->fled_shutdown)
143 info->hal->fled_shutdown(info);
146 static int rtled_impl_set_torch_current(struct rt_fled_info *info,
147 int min_uA, int max_uA, int *selector)
152 for (sel = 0;; sel++) {
153 rc = info->hal->fled_torch_current_list(info, sel);
156 if (rc >= min_uA && rc <= max_uA) {
158 return info->hal->fled_set_torch_current_sel(info, sel);
164 static int rtled_impl_set_strobe_current(struct rt_fled_info *info,
165 int min_uA, int max_uA, int *selector)
170 for (sel = 0;; sel++) {
171 rc = info->hal->fled_strobe_current_list(info, sel);
174 if (rc >= min_uA && rc <= max_uA) {
176 return info->hal->fled_set_strobe_current_sel(info,
183 static int rtled_impl_set_timeout_level(struct rt_fled_info *info,
184 int min_uA, int max_uA, int *selector)
189 for (sel = 0;; sel++) {
190 rc = info->hal->fled_timeout_level_list(info, sel);
193 if (rc >= min_uA && rc <= max_uA) {
195 return info->hal->fled_set_timeout_level_sel(info, sel);
201 static int rtled_impl_set_lv_protection(struct rt_fled_info *info,
202 int min_mV, int max_mV, int *selector)
207 for (sel = 0;; sel++) {
208 rc = info->hal->fled_lv_protection_list(info, sel);
211 if (rc >= min_mV && rc <= max_mV) {
213 return info->hal->fled_set_lv_protection_sel(info, sel);
219 static int rtled_impl_set_strobe_timeout(struct rt_fled_info *info,
220 int min_ms, int max_ms, int *selector)
225 for (sel = 0;; sel++) {
226 rc = info->hal->fled_strobe_timeout_list(info, sel);
229 if (rc >= min_ms && rc <= max_ms) {
231 return info->hal->fled_set_strobe_timeout_sel(info,
238 static int rtled_impl_get_torch_current(struct rt_fled_info *info)
240 int sel = info->hal->fled_get_torch_current_sel(info);
244 return info->hal->fled_torch_current_list(info, sel);
247 static int rtled_impl_get_strobe_current(struct rt_fled_info *info)
249 int sel = info->hal->fled_get_strobe_current_sel(info);
253 return info->hal->fled_strobe_current_list(info, sel);
256 static int rtled_impl_get_timeout_level(struct rt_fled_info *info)
258 int sel = info->hal->fled_get_timeout_level_sel(info);
262 return info->hal->fled_timeout_level_list(info, sel);
265 static int rtled_impl_get_lv_protection(struct rt_fled_info *info)
267 int sel = info->hal->fled_get_lv_protection_sel(info);
271 return info->hal->fled_lv_protection_list(info, sel);
274 static int rtled_impl_get_strobe_timeout(struct rt_fled_info *info)
276 int sel = info->hal->fled_get_strobe_timeout_sel(info);
280 return info->hal->fled_strobe_timeout_list(info, sel);
283 #define HAL_NOT_IMPLEMENTED(x) (hal->x == NULL)
284 #define CHECK_HAL_IMPLEMENTED(x) \
286 if (hal->x == NULL) \
290 static int rtfled_check_hal_implement(struct rt_fled_hal *hal)
292 if (HAL_NOT_IMPLEMENTED(fled_set_torch_current))
293 hal->fled_set_torch_current = rtled_impl_set_torch_current;
294 if (HAL_NOT_IMPLEMENTED(fled_set_strobe_current))
295 hal->fled_set_strobe_current = rtled_impl_set_strobe_current;
296 if (HAL_NOT_IMPLEMENTED(fled_set_timeout_level))
297 hal->fled_set_timeout_level = rtled_impl_set_timeout_level;
298 if (HAL_NOT_IMPLEMENTED(fled_set_lv_protection))
299 hal->fled_set_lv_protection = rtled_impl_set_lv_protection;
300 if (HAL_NOT_IMPLEMENTED(fled_set_strobe_timeout))
301 hal->fled_set_strobe_timeout = rtled_impl_set_strobe_timeout;
302 if (HAL_NOT_IMPLEMENTED(fled_get_torch_current))
303 hal->fled_get_torch_current = rtled_impl_get_torch_current;
304 if (HAL_NOT_IMPLEMENTED(fled_get_strobe_current))
305 hal->fled_get_strobe_current = rtled_impl_get_strobe_current;
306 if (HAL_NOT_IMPLEMENTED(fled_get_timeout_level))
307 hal->fled_get_timeout_level = rtled_impl_get_timeout_level;
308 if (HAL_NOT_IMPLEMENTED(fled_get_lv_protection))
309 hal->fled_get_lv_protection = rtled_impl_get_lv_protection;
310 if (HAL_NOT_IMPLEMENTED(fled_get_strobe_timeout))
311 hal->fled_get_strobe_timeout = rtled_impl_get_strobe_timeout;
312 CHECK_HAL_IMPLEMENTED(fled_set_mode);
313 CHECK_HAL_IMPLEMENTED(fled_get_mode);
314 CHECK_HAL_IMPLEMENTED(fled_strobe);
315 CHECK_HAL_IMPLEMENTED(fled_torch_current_list);
316 CHECK_HAL_IMPLEMENTED(fled_strobe_current_list);
317 CHECK_HAL_IMPLEMENTED(fled_timeout_level_list);
318 CHECK_HAL_IMPLEMENTED(fled_lv_protection_list);
319 CHECK_HAL_IMPLEMENTED(fled_strobe_timeout_list);
320 CHECK_HAL_IMPLEMENTED(fled_set_torch_current_sel);
321 CHECK_HAL_IMPLEMENTED(fled_set_strobe_current_sel);
322 CHECK_HAL_IMPLEMENTED(fled_set_timeout_level_sel);
323 CHECK_HAL_IMPLEMENTED(fled_set_lv_protection_sel);
324 CHECK_HAL_IMPLEMENTED(fled_set_strobe_timeout_sel);
325 CHECK_HAL_IMPLEMENTED(fled_get_torch_current_sel);
326 CHECK_HAL_IMPLEMENTED(fled_get_strobe_current_sel);
327 CHECK_HAL_IMPLEMENTED(fled_get_timeout_level_sel);
328 CHECK_HAL_IMPLEMENTED(fled_get_lv_protection_sel);
329 CHECK_HAL_IMPLEMENTED(fled_get_strobe_timeout_sel);
333 static int rtfled_probe(struct platform_device *pdev)
335 rt_fled_info_t *info = dev_get_drvdata(pdev->dev.parent);
338 BUG_ON(info == NULL);
339 BUG_ON(info->hal == NULL);
341 RTFLED_INFO("Richtek FlashLED Driver is probing\n");
342 rc = rtfled_check_hal_implement(info->hal);
344 RTFLED_ERR("HAL implemented uncompletedly\n");
347 platform_set_drvdata(pdev, info);
348 info->flashlight_dev =
349 flashlight_device_register(info->name ? info->name : RT_FLED_DEVICE,
350 &pdev->dev, info, &rtfled_impl_ops,
352 if (info->hal->fled_init) {
353 rc = info->hal->fled_init(info);
355 RTFLED_ERR("Initialization failed\n");
359 RTFLED_INFO("Richtek FlashLED Driver initialized successfully\n");
362 flashlight_device_unregister(info->flashlight_dev);
367 static int rtfled_remove(struct platform_device *pdev)
369 rt_fled_info_t *info = platform_get_drvdata(pdev);
371 platform_set_drvdata(pdev, NULL);
372 flashlight_device_unregister(info->flashlight_dev);
376 static struct platform_driver rt_flash_led_driver = {
378 .name = RT_FLED_DEVICE,
379 .owner = THIS_MODULE,
381 .shutdown = rfled_shutdown,
382 .probe = rtfled_probe,
383 .remove = rtfled_remove,
386 static int rtfled_init(void)
388 return platform_driver_register(&rt_flash_led_driver);
390 subsys_initcall(rtfled_init);
392 static void rtfled_exit(void)
394 platform_driver_unregister(&rt_flash_led_driver);
396 module_exit(rtfled_exit);
398 MODULE_LICENSE("GPL");
399 MODULE_AUTHOR("Patrick Chang <patrick_chang@richtek.com");
400 MODULE_VERSION("1.0.0_G");
401 MODULE_DESCRIPTION("Richtek Flash LED Driver");