fix section mismatch warnings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / leds / leds_drv.c
CommitLineData
6fa3eb70
S
1/*
2 * drivers/leds/leds-mt65xx.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive for
6 * more details.
7 *
8 * mt65xx leds driver
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/delay.h>
15#include <linux/string.h>
16#include <linux/ctype.h>
17#include <linux/leds.h>
18#include <linux/leds-mt65xx.h>
19#include <linux/workqueue.h>
20#include <linux/wakelock.h>
21#include <linux/slab.h>
22#include <linux/spinlock.h>
23/* #include <cust_leds.h> */
24/* #include <cust_leds_def.h> */
25#include <mach/mt_pwm.h>
26/* #include <mach/mt_pwm_hal.h> */
27/* #include <mach/mt_gpio.h> */
28#include <mach/upmu_common_sw.h>
29#include <mach/upmu_hw.h>
30/* #include <mach/mt_pmic_feature_api.h> */
31/* #include <mach/mt_boot.h> */
32#include <leds_hal.h>
33/* #include <linux/leds_hal.h> */
34#include "leds_drv.h"
35
36
37
38/****************************************************************************
39 * variables
40 ***************************************************************************/
41struct cust_mt65xx_led *bl_setting = NULL;
6fa3eb70 42static unsigned int bl_brightness = 102;
6fa3eb70
S
43static unsigned int bl_duty = 21;
44static unsigned int bl_div = CLK_DIV1;
45static unsigned int bl_frequency = 32000;
46static unsigned int div_array[PWM_DIV_NUM];
47struct mt65xx_led_data *g_leds_data[MT65XX_LED_TYPE_TOTAL];
48
49
50/****************************************************************************
51 * DEBUG MACROS
52 ***************************************************************************/
53static int debug_enable_led = 1;
54#define LEDS_DRV_DEBUG(format, args...) do { \
55 if (debug_enable_led) \
56 {\
57 printk(KERN_WARNING format, ##args);\
58 } \
59} while (0)
60
61/****************************************************************************
62 * function prototypes
63 ***************************************************************************/
64#ifndef CONTROL_BL_TEMPERATURE
65#define CONTROL_BL_TEMPERATURE
66#endif
67
68#define MT_LED_INTERNAL_LEVEL_BIT_CNT 10
69
70#ifdef CONTROL_BL_TEMPERATURE
71int setMaxbrightness(int max_level, int enable);
72
73#endif
74
75/******************************************************************************
76 for DISP backlight High resolution
77******************************************************************************/
78#ifdef LED_INCREASE_LED_LEVEL_MTKPATCH
79#define LED_INTERNAL_LEVEL_BIT_CNT 10
80#endif
81
82
83static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level);
84
85/****************************************************************************
86 * add API for temperature control
87 ***************************************************************************/
88
89#ifdef CONTROL_BL_TEMPERATURE
90
91/* define int limit for brightness limitation */
92static unsigned int limit = 255;
93static unsigned int limit_flag;
94static unsigned int last_level;
95static unsigned int current_level;
96static DEFINE_MUTEX(bl_level_limit_mutex);
97extern int disp_bls_set_max_backlight(unsigned int level);
98
99
100/* this API add for control the power and temperature */
101/* if enabe=1, the value of brightness will smaller than max_level, whatever lightservice transfers to driver */
102int setMaxbrightness(int max_level, int enable)
103{
104#if !defined(CONFIG_MTK_AAL_SUPPORT)
105 struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
106 mutex_lock(&bl_level_limit_mutex);
107 if (1 == enable) {
108 limit_flag = 1;
109 limit = max_level;
110 mutex_unlock(&bl_level_limit_mutex);
111 /* LEDS_DRV_DEBUG("[LED] setMaxbrightness limit happen and release lock!!\n"); */
112 /* LEDS_DRV_DEBUG("setMaxbrightness enable:last_level=%d, current_level=%d\n", last_level, current_level); */
113 /* if (limit < last_level){ */
114 if (0 != current_level) {
115 if (limit < last_level) {
116 LEDS_DRV_DEBUG
117 ("mt65xx_leds_set_cust in setMaxbrightness:value control start! limit=%d\n",
118 limit);
119 mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD], limit);
120 } else {
121 /* LEDS_DRV_DEBUG("mt65xx_leds_set_cust in setMaxbrightness:value control start! last_level=%d\n", last_level); */
122 mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD],
123 last_level);
124 }
125 }
126 } else {
127 limit_flag = 0;
128 limit = 255;
129 mutex_unlock(&bl_level_limit_mutex);
130 /* LEDS_DRV_DEBUG("[LED] setMaxbrightness limit closed and and release lock!!\n"); */
131 /* LEDS_DRV_DEBUG("setMaxbrightness disable:last_level=%d, current_level=%d\n", last_level, current_level); */
132
133 /* if (last_level != 0){ */
134 if (0 != current_level) {
135 LEDS_DRV_DEBUG("control temperature close:limit=%d\n", limit);
136 mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD], last_level);
137
138 /* printk("mt65xx_leds_set_cust in setMaxbrightness:value control close!\n"); */
139 }
140 }
141
142 /* LEDS_DRV_DEBUG("[LED] setMaxbrightness limit_flag = %d, limit=%d, current_level=%d\n",limit_flag, limit, current_level); */
143
144#else
145 LEDS_DRV_DEBUG("setMaxbrightness go through AAL\n");
146 disp_bls_set_max_backlight(max_level);
147#endif /* endif CONFIG_MTK_AAL_SUPPORT */
148 return 0;
149
150}
151#endif
152/****************************************************************************
153 * internal functions
154 ***************************************************************************/
155static void get_div_array(void)
156{
157 int i = 0;
158 unsigned int *temp = mt_get_div_array();
159 while (i < PWM_DIV_NUM) {
160 div_array[i] = *temp++;
161 LEDS_DRV_DEBUG("get_div_array: div_array=%d\n", div_array[i]);
162 i++;
163 }
164}
165
166static int led_set_pwm(int pwm_num, struct nled_setting *led)
167{
168
169 mt_led_set_pwm(pwm_num, led);
170 return 0;
171}
172
173static int brightness_set_pmic(enum mt65xx_led_pmic pmic_type, u32 level, u32 div)
174{
175 mt_brightness_set_pmic(pmic_type, level, div);
176 return -1;
177
178}
179
180static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
181{
182#ifdef CONTROL_BL_TEMPERATURE
183 mutex_lock(&bl_level_limit_mutex);
184 current_level = level;
185 /* LEDS_DRV_DEBUG("brightness_set_cust:current_level=%d\n", current_level); */
186 if (0 == limit_flag) {
187 last_level = level;
188 /* LEDS_DRV_DEBUG("brightness_set_cust:last_level=%d\n", last_level); */
189 } else {
190 if (limit < current_level) {
191 level = limit;
192 /* LEDS_DRV_DEBUG("backlight_set_cust: control level=%d\n", level); */
193 }
194 }
195 mutex_unlock(&bl_level_limit_mutex);
196#endif
197#ifdef LED_INCREASE_LED_LEVEL_MTKPATCH
198 if (MT65XX_LED_MODE_CUST_BLS_PWM == cust->mode) {
199 mt_mt65xx_led_set_cust(cust,
200 ((((1 << LED_INTERNAL_LEVEL_BIT_CNT) - 1) * level +
201 127) / 255));
202 } else {
203 mt_mt65xx_led_set_cust(cust, level);
204 }
205#else
206 mt_mt65xx_led_set_cust(cust, level);
207#endif
208 return -1;
209}
210
211
212static void mt65xx_led_set(struct led_classdev *led_cdev, enum led_brightness level)
213{
214 struct mt65xx_led_data *led_data = container_of(led_cdev, struct mt65xx_led_data, cdev);
215 if (strcmp(led_data->cust.name, "lcd-backlight") == 0) {
216#ifdef CONTROL_BL_TEMPERATURE
217 mutex_lock(&bl_level_limit_mutex);
218 current_level = level;
219 /* LEDS_DRV_DEBUG("brightness_set_cust:current_level=%d\n", current_level); */
220 if (0 == limit_flag) {
221 last_level = level;
222 /* LEDS_DRV_DEBUG("brightness_set_cust:last_level=%d\n", last_level); */
223 } else {
224 if (limit < current_level) {
225 level = limit;
226 LEDS_DRV_DEBUG("backlight_set_cust: control level=%d\n", level);
227 }
228 }
229 mutex_unlock(&bl_level_limit_mutex);
230#endif
231 }
232 mt_mt65xx_led_set(led_cdev, level);
233}
234
235static int mt65xx_blink_set(struct led_classdev *led_cdev,
236 unsigned long *delay_on, unsigned long *delay_off)
237{
238 if (mt_mt65xx_blink_set(led_cdev, delay_on, delay_off)) {
239 return -1;
240 } else {
241 return 0;
242 }
243}
244
245/****************************************************************************
246 * external functions
247 ***************************************************************************/
248int mt65xx_leds_brightness_set(enum mt65xx_led_type type, enum led_brightness level)
249{
250 struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
251
252 LEDS_DRV_DEBUG("[LED]#%d:%d\n", type, level);
253
254 if (type < 0 || type >= MT65XX_LED_TYPE_TOTAL)
255 return -1;
256
257 if (level > LED_FULL)
258 level = LED_FULL;
259 else if (level < 0)
260 level = 0;
261
262 return mt65xx_led_set_cust(&cust_led_list[type], level);
263
264}
265EXPORT_SYMBOL(mt65xx_leds_brightness_set);
266
267
268/****************************************************************************
269 * external functions
270 ***************************************************************************/
271int backlight_brightness_set(int level)
272{
273 struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
274
275 if (level > ((1 << MT_LED_INTERNAL_LEVEL_BIT_CNT) - 1) )
276 level = ((1 << MT_LED_INTERNAL_LEVEL_BIT_CNT) - 1);
277 else if (level < 0)
278 level = 0;
279
280 if(MT65XX_LED_MODE_CUST_BLS_PWM == cust_led_list[MT65XX_LED_TYPE_LCD].mode)
281 {
282 #ifdef CONTROL_BL_TEMPERATURE
283 mutex_lock(&bl_level_limit_mutex);
284 current_level = (level >> (MT_LED_INTERNAL_LEVEL_BIT_CNT - 8)); // 8 bits
285 if(0 == limit_flag){
286 last_level = current_level;
287 }else {
288 if(limit < current_level){
289 // extend 8-bit limit to 10 bits
290 level = (limit << (MT_LED_INTERNAL_LEVEL_BIT_CNT - 8)) | (limit >> (16 - MT_LED_INTERNAL_LEVEL_BIT_CNT));
291 }
292 }
293 mutex_unlock(&bl_level_limit_mutex);
294 #endif
295
296 return mt_mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD], level);
297 }
298 else
299 {
300 return mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD],( level >> (MT_LED_INTERNAL_LEVEL_BIT_CNT - 8)) );
301 }
302
303}
304
305EXPORT_SYMBOL(backlight_brightness_set);
306
307
308static ssize_t show_duty(struct device *dev, struct device_attribute *attr, char *buf)
309{
310 LEDS_DRV_DEBUG("[LED]get backlight duty value is:%d\n", bl_duty);
311 return sprintf(buf, "%u\n", bl_duty);
312}
313
314static ssize_t store_duty(struct device *dev, struct device_attribute *attr, const char *buf,
315 size_t size)
316{
317 char *pvalue = NULL;
318 unsigned int level = 0;
319 size_t count = 0;
320 bl_div = mt_get_bl_div();
321 LEDS_DRV_DEBUG("set backlight duty start\n");
322 level = simple_strtoul(buf, &pvalue, 10);
323 count = pvalue - buf;
324 if (*pvalue && isspace(*pvalue))
325 count++;
326
327 if (count == size) {
328
329 if (bl_setting->mode == MT65XX_LED_MODE_PMIC) {
330 /* duty:0-16 */
331 if ((level >= 0) && (level <= 15)) {
332 mt_brightness_set_pmic_duty_store((level * 17), bl_div);
333 } else {
334 LEDS_DRV_DEBUG
335 ("duty value is error, please select vaule from [0-15]!\n");
336 }
337
338 }
339
340 else if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
341 if (level == 0) {
342 mt_led_pwm_disable(bl_setting->data);
343 } else if (level <= 64) {
344 mt_backlight_set_pwm_duty(bl_setting->data, level, bl_div,
345 &bl_setting->config_data);
346 }
347 }
348
349 mt_set_bl_duty(level);
350
351 }
352
353 return size;
354}
355
356
357static DEVICE_ATTR(duty, 0664, show_duty, store_duty);
358
359
360static ssize_t show_div(struct device *dev, struct device_attribute *attr, char *buf)
361{
362 bl_div = mt_get_bl_div();
363 LEDS_DRV_DEBUG("get backlight div value is:%d\n", bl_div);
364 return sprintf(buf, "%u\n", bl_div);
365}
366
367static ssize_t store_div(struct device *dev, struct device_attribute *attr, const char *buf,
368 size_t size)
369{
370 char *pvalue = NULL;
371 unsigned int div = 0;
372 size_t count = 0;
373
374 bl_duty = mt_get_bl_duty();
375 LEDS_DRV_DEBUG("set backlight div start\n");
376 div = simple_strtoul(buf, &pvalue, 10);
377 count = pvalue - buf;
378
379 if (*pvalue && isspace(*pvalue))
380 count++;
381
382 if (count == size) {
383 if (div < 0 || (div > 7)) {
384 LEDS_DRV_DEBUG("set backlight div parameter error: %d[div:0~7]\n", div);
385 return 0;
386 }
387
388 if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
389 LEDS_DRV_DEBUG("set PWM backlight div OK: div=%d, duty=%d\n", div, bl_duty);
390 mt_backlight_set_pwm_div(bl_setting->data, bl_duty, div,
391 &bl_setting->config_data);
392 }
393
394 else if (bl_setting->mode == MT65XX_LED_MODE_CUST_LCM) {
395 bl_brightness = mt_get_bl_brightness();
396 LEDS_DRV_DEBUG("set cust backlight div OK: div=%d, brightness=%d\n", div,
397 bl_brightness);
398 ((cust_brightness_set) (bl_setting->data)) (bl_brightness, div);
399 }
400 mt_set_bl_div(div);
401
402 }
403
404 return size;
405}
406
407static DEVICE_ATTR(div, 0664, show_div, store_div);
408
409
410static ssize_t show_frequency(struct device *dev, struct device_attribute *attr, char *buf)
411{
412 bl_div = mt_get_bl_div();
413 bl_frequency = mt_get_bl_frequency();
414
415 if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
416 mt_set_bl_frequency(32000 / div_array[bl_div]);
417 } else if (bl_setting->mode == MT65XX_LED_MODE_CUST_LCM) {
418 /* mtkfb_get_backlight_pwm(bl_div, &bl_frequency); */
419 mt_backlight_get_pwm_fsel(bl_div, &bl_frequency);
420 }
421
422 LEDS_DRV_DEBUG("[LED]get backlight PWM frequency value is:%d\n", bl_frequency);
423
424 return sprintf(buf, "%u\n", bl_frequency);
425}
426
427static DEVICE_ATTR(frequency, 0444, show_frequency, NULL);
428
429
430
431static ssize_t store_pwm_register(struct device *dev, struct device_attribute *attr,
432 const char *buf, size_t size)
433{
434 char *pvalue = NULL;
435 unsigned int reg_value = 0;
436 unsigned int reg_address = 0;
437 if (buf != NULL && size != 0) {
438 //LEDS_DRV_DEBUG("store_pwm_register: size:%d,address:0x%s\n", size, buf);
439 reg_address = simple_strtoul(buf, &pvalue, 16);
440
441 if (*pvalue && (*pvalue == '#')) {
442 reg_value = simple_strtoul((pvalue + 1), NULL, 16);
443 LEDS_DRV_DEBUG("set pwm register:[0x%x]= 0x%x\n", reg_address, reg_value);
444 /* OUTREG32(reg_address,reg_value); */
445 mt_store_pwm_register(reg_address, reg_value);
446
447 } else if (*pvalue && (*pvalue == '@')) {
448 LEDS_DRV_DEBUG("get pwm register:[0x%x]=0x%x\n", reg_address,
449 mt_show_pwm_register(reg_address));
450 }
451 }
452
453 return size;
454}
455
456static ssize_t show_pwm_register(struct device *dev, struct device_attribute *attr, char *buf)
457{
458 return 0;
459}
460
461static DEVICE_ATTR(pwm_register, 0664, show_pwm_register, store_pwm_register);
462
463
464/****************************************************************************
465 * driver functions
466 ***************************************************************************/
467static int __init mt65xx_leds_probe(struct platform_device *pdev)
468{
469 int i;
470 int ret, rc;
471 struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
472 LEDS_DRV_DEBUG("[LED]%s\n", __func__);
473 get_div_array();
474 for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
475 if (cust_led_list[i].mode == MT65XX_LED_MODE_NONE) {
476 g_leds_data[i] = NULL;
477 continue;
478 }
479
480 g_leds_data[i] = kzalloc(sizeof(struct mt65xx_led_data), GFP_KERNEL);
481 if (!g_leds_data[i]) {
482 ret = -ENOMEM;
483 goto err;
484 }
485
486 g_leds_data[i]->cust.mode = cust_led_list[i].mode;
487 g_leds_data[i]->cust.data = cust_led_list[i].data;
488 g_leds_data[i]->cust.name = cust_led_list[i].name;
489
490 g_leds_data[i]->cdev.name = cust_led_list[i].name;
491 g_leds_data[i]->cust.config_data = cust_led_list[i].config_data; /* bei add */
492
493 g_leds_data[i]->cdev.brightness_set = mt65xx_led_set;
494 g_leds_data[i]->cdev.blink_set = mt65xx_blink_set;
495
496 INIT_WORK(&g_leds_data[i]->work, mt_mt65xx_led_work);
497
498 ret = led_classdev_register(&pdev->dev, &g_leds_data[i]->cdev);
499
500 if (strcmp(g_leds_data[i]->cdev.name, "lcd-backlight") == 0) {
501 rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_duty);
502 if (rc) {
503 LEDS_DRV_DEBUG("[LED]device_create_file duty fail!\n");
504 }
505
506 rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_div);
507 if (rc) {
508 LEDS_DRV_DEBUG("[LED]device_create_file duty fail!\n");
509 }
510
511 rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_frequency);
512 if (rc) {
513 LEDS_DRV_DEBUG("[LED]device_create_file duty fail!\n");
514 }
515
516 rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_pwm_register);
517 if (rc) {
518 LEDS_DRV_DEBUG("[LED]device_create_file duty fail!\n");
519 }
520 bl_setting = &g_leds_data[i]->cust;
521 }
522
523 if (ret)
524 goto err;
525
526 }
527#ifdef CONTROL_BL_TEMPERATURE
528
529 last_level = 0;
530 limit = 255;
531 limit_flag = 0;
532 current_level = 0;
533 LEDS_DRV_DEBUG
534 ("[LED]led probe last_level = %d, limit = %d, limit_flag = %d, current_level = %d\n",
535 last_level, limit, limit_flag, current_level);
536#endif
537
538
539 return 0;
540
541 err:
542 if (i) {
543 for (i = i - 1; i >= 0; i--) {
544 if (!g_leds_data[i])
545 continue;
546 led_classdev_unregister(&g_leds_data[i]->cdev);
547 cancel_work_sync(&g_leds_data[i]->work);
548 kfree(g_leds_data[i]);
549 g_leds_data[i] = NULL;
550 }
551 }
552
553 return ret;
554}
555
556static int mt65xx_leds_remove(struct platform_device *pdev)
557{
558 int i;
559 for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
560 if (!g_leds_data[i])
561 continue;
562 led_classdev_unregister(&g_leds_data[i]->cdev);
563 cancel_work_sync(&g_leds_data[i]->work);
564 kfree(g_leds_data[i]);
565 g_leds_data[i] = NULL;
566 }
567
568 return 0;
569}
570
571/*
572static int mt65xx_leds_suspend(struct platform_device *pdev, pm_message_t state)
573{
574 return 0;
575}
576*/
577
578static void mt65xx_leds_shutdown(struct platform_device *pdev)
579{
580 int i;
581 struct nled_setting led_tmp_setting = { NLED_OFF, 0, 0 };
582
583 LEDS_DRV_DEBUG("[LED]%s\n", __func__);
584 LEDS_DRV_DEBUG("[LED]mt65xx_leds_shutdown: turn off backlight\n");
585
586 for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
587 if (!g_leds_data[i])
588 continue;
589 switch (g_leds_data[i]->cust.mode) {
590
591 case MT65XX_LED_MODE_PWM:
592 if (strcmp(g_leds_data[i]->cust.name, "lcd-backlight") == 0) {
593 /* mt_set_pwm_disable(g_leds_data[i]->cust.data); */
594 /* mt_pwm_power_off (g_leds_data[i]->cust.data); */
595 mt_led_pwm_disable(g_leds_data[i]->cust.data);
596 } else {
597 led_set_pwm(g_leds_data[i]->cust.data, &led_tmp_setting);
598 }
599 break;
600
601 /* case MT65XX_LED_MODE_GPIO: */
602 /* brightness_set_gpio(g_leds_data[i]->cust.data, 0); */
603 /* break; */
604
605 case MT65XX_LED_MODE_PMIC:
606 brightness_set_pmic(g_leds_data[i]->cust.data, 0, 0);
607 break;
608 case MT65XX_LED_MODE_CUST_LCM:
609 LEDS_DRV_DEBUG("[LED]backlight control through LCM!!1\n");
610 ((cust_brightness_set) (g_leds_data[i]->cust.data)) (0, bl_div);
611 break;
612 case MT65XX_LED_MODE_CUST_BLS_PWM:
613 LEDS_DRV_DEBUG("[LED]backlight control through BLS!!1\n");
614 ((cust_set_brightness) (g_leds_data[i]->cust.data)) (0);
615 break;
616 case MT65XX_LED_MODE_NONE:
617 default:
618 break;
619 }
620 }
621
622}
623
8ca3027e 624static struct platform_driver __refdata mt65xx_leds_driver = {
6fa3eb70
S
625 .driver = {
626 .name = "leds-mt65xx",
627 .owner = THIS_MODULE,
628 },
629 .probe = mt65xx_leds_probe,
630 .remove = mt65xx_leds_remove,
631 /* .suspend = mt65xx_leds_suspend, */
632 .shutdown = mt65xx_leds_shutdown,
633};
634
635#ifdef CONFIG_OF
636static struct platform_device mt65xx_leds_device = {
637 .name = "leds-mt65xx",
638 .id = -1
639};
640
641#endif
642
643static int __init mt65xx_leds_init(void)
644{
645 int ret;
646
647 LEDS_DRV_DEBUG("[LED]%s\n", __func__);
648
649#ifdef CONFIG_OF
650 ret = platform_device_register(&mt65xx_leds_device);
651 if (ret)
652 printk("[LED]mt65xx_leds_init:dev:E%d\n", ret);
653#endif
654 ret = platform_driver_register(&mt65xx_leds_driver);
655
656 if (ret) {
657 LEDS_DRV_DEBUG("[LED]mt65xx_leds_init:drv:E%d\n", ret);
658/* platform_device_unregister(&mt65xx_leds_device); */
659 return ret;
660 }
661
662 mt_leds_wake_lock_init();
663
664 return ret;
665}
666
667static void __exit mt65xx_leds_exit(void)
668{
669 platform_driver_unregister(&mt65xx_leds_driver);
670/* platform_device_unregister(&mt65xx_leds_device); */
671}
672
673module_param(debug_enable_led, int, 0644);
674
675module_init(mt65xx_leds_init);
676module_exit(mt65xx_leds_exit);
677
678MODULE_AUTHOR("MediaTek Inc.");
679MODULE_DESCRIPTION("LED driver for MediaTek MT65xx chip");
680MODULE_LICENSE("GPL");
681MODULE_ALIAS("leds-mt65xx");