| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862 |
- /*
- * drivers/leds/leds-mt65xx.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- * mt65xx leds driver
- *
- */
- #include <linux/i2c.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/delay.h>
- #include <linux/string.h>
- #include <linux/ctype.h>
- #include <linux/leds.h>
- /* #include <linux/leds-mt65xx.h> */
- #include <linux/workqueue.h>
- #include <linux/wakelock.h>
- #include <linux/slab.h>
- #include <linux/spinlock.h>
- /* #include <mach/mt_pwm.h> */
- /* #include <mach/mt_pwm_hal.h> */
- /* #include <mach/mt_gpio.h> */
- /*
- #include <mach/upmu_common_sw.h>
- #include <mach/upmu_hw.h> */
- /* #include <mach/mt_pmic_feature_api.h> */
- /* #include <mach/mt_boot.h> */
- #include <leds_hal.h>
- #include "leds_drv.h"
- #include <mt-plat/mt_pwm.h>
- #include <mt-plat/upmu_common.h>
- #ifdef BACKLIGHT_SUPPORT_LP8557
- #include <linux/of_gpio.h>
- #include <linux/gpio.h>
- #include <asm-generic/gpio.h>
- #endif
- /****************************************************************************
- * variables
- ***************************************************************************/
- struct cust_mt65xx_led *bl_setting = NULL;
- /* static unsigned int bl_brightness = 102;
- static unsigned int bl_duty = 21;
- static unsigned int bl_div = CLK_DIV1;
- static unsigned int bl_frequency = 32000; */
- static unsigned int bl_div = CLK_DIV1;
- #define PWM_DIV_NUM 8
- static unsigned int div_array[PWM_DIV_NUM];
- struct mt65xx_led_data *g_leds_data[MT65XX_LED_TYPE_TOTAL];
- #ifdef BACKLIGHT_SUPPORT_LP8557
- static unsigned int last_level1 = 102;
- static struct i2c_client *g_client;
- static int I2C_SET_FOR_BACKLIGHT = 350;
- #endif
- /****************************************************************************
- * DEBUG MACROS
- ***************************************************************************/
- static int debug_enable_led = 1;
- /* #define pr_fmt(fmt) "[LED_DRV]"fmt */
- #define LEDS_DRV_DEBUG(format, args...) do { \
- if (debug_enable_led) { \
- pr_debug(format, ##args);\
- } \
- } while (0)
- /****************************************************************************
- * function prototypes
- ***************************************************************************/
- #ifndef CONTROL_BL_TEMPERATURE
- #define CONTROL_BL_TEMPERATURE
- #endif
- #define MT_LED_INTERNAL_LEVEL_BIT_CNT 10
- /******************************************************************************
- for DISP backlight High resolution
- ******************************************************************************/
- #ifdef LED_INCREASE_LED_LEVEL_MTKPATCH
- #define LED_INTERNAL_LEVEL_BIT_CNT 10
- #endif
- static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level);
- /****************************************************************************
- * add API for temperature control
- ***************************************************************************/
- #ifdef CONTROL_BL_TEMPERATURE
- /* define int limit for brightness limitation */
- static unsigned int limit = 255;
- static unsigned int limit_flag;
- static unsigned int last_level;
- static unsigned int current_level;
- static DEFINE_MUTEX(bl_level_limit_mutex);
- /****************************************************************************
- * external functions for display
- * this API add for control the power and temperature,
- * if enabe=1, the value of brightness will smaller than max_level,
- * whatever lightservice transfers to driver.
- ***************************************************************************/
- int setMaxbrightness(int max_level, int enable)
- {
- #if !defined(CONFIG_MTK_AAL_SUPPORT)
- struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
- mutex_lock(&bl_level_limit_mutex);
- if (1 == enable) {
- limit_flag = 1;
- limit = max_level;
- mutex_unlock(&bl_level_limit_mutex);
- /* if (limit < last_level){ */
- if (0 != current_level) {
- if (limit < last_level) {
- LEDS_DRV_DEBUG
- ("mt65xx_leds_set_cust in setMaxbrightness:value control start! limit=%d\n",
- limit);
- mt65xx_led_set_cust(&cust_led_list
- [MT65XX_LED_TYPE_LCD],
- limit);
- } else {
- mt65xx_led_set_cust(&cust_led_list
- [MT65XX_LED_TYPE_LCD],
- last_level);
- }
- }
- } else {
- limit_flag = 0;
- limit = 255;
- mutex_unlock(&bl_level_limit_mutex);
- if (0 != current_level) {
- LEDS_DRV_DEBUG("control temperature close:limit=%d\n",
- limit);
- mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD],
- last_level);
- }
- }
- #else
- LEDS_DRV_DEBUG("setMaxbrightness go through AAL\n");
- disp_bls_set_max_backlight(((((1 << LED_INTERNAL_LEVEL_BIT_CNT) -
- 1) * max_level + 127) / 255));
- #endif /* endif CONFIG_MTK_AAL_SUPPORT */
- return 0;
- }
- EXPORT_SYMBOL(setMaxbrightness);
- #endif
- /****************************************************************************
- * internal functions
- ***************************************************************************/
- static void get_div_array(void)
- {
- int i = 0;
- unsigned int *temp = mt_get_div_array();
- while (i < PWM_DIV_NUM) {
- div_array[i] = *temp++;
- LEDS_DRV_DEBUG("get_div_array: div_array=%d\n", div_array[i]);
- i++;
- }
- }
- static int led_set_pwm(int pwm_num, struct nled_setting *led)
- {
- mt_led_set_pwm(pwm_num, led);
- return 0;
- }
- static int brightness_set_pmic(enum mt65xx_led_pmic pmic_type, u32 level,
- u32 div)
- {
- mt_brightness_set_pmic(pmic_type, level, div);
- return -1;
- }
- static int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level)
- {
- #ifdef CONTROL_BL_TEMPERATURE
- mutex_lock(&bl_level_limit_mutex);
- current_level = level;
- /* LEDS_DRV_DEBUG("brightness_set_cust:current_level=%d\n", current_level); */
- if (0 == limit_flag) {
- last_level = level;
- /* LEDS_DRV_DEBUG("brightness_set_cust:last_level=%d\n", last_level); */
- } else {
- if (limit < current_level) {
- level = limit;
- /* LEDS_DRV_DEBUG("backlight_set_cust: control level=%d\n", level); */
- }
- }
- mutex_unlock(&bl_level_limit_mutex);
- #endif
- #ifdef LED_INCREASE_LED_LEVEL_MTKPATCH
- if (MT65XX_LED_MODE_CUST_BLS_PWM == cust->mode) {
- mt_mt65xx_led_set_cust(cust,
- ((((1 << LED_INTERNAL_LEVEL_BIT_CNT) -
- 1) * level + 127) / 255));
- } else {
- mt_mt65xx_led_set_cust(cust, level);
- }
- #else
- mt_mt65xx_led_set_cust(cust, level);
- #endif
- return -1;
- }
- static void mt65xx_led_set(struct led_classdev *led_cdev,
- enum led_brightness level)
- {
- struct mt65xx_led_data *led_data =
- container_of(led_cdev, struct mt65xx_led_data, cdev);
- #ifdef BACKLIGHT_SUPPORT_LP8557
- bool flag = FALSE;
- int value = 0;
- int retval;
- struct device_node *node = NULL;
- struct i2c_client *client = g_client;
- value = i2c_smbus_read_byte_data(g_client, 0x10);
- LEDS_DRV_DEBUG("LEDS:mt65xx_led_set:0x10 = %d\n", value);
- node = of_find_compatible_node(NULL, NULL,
- "mediatek,lcd-backlight");
- if (node) {
- I2C_SET_FOR_BACKLIGHT = of_get_named_gpio(node, "gpios", 0);
- LEDS_DRV_DEBUG("Led_i2c gpio num for power:%d\n", I2C_SET_FOR_BACKLIGHT);
- }
- #endif
- if (strcmp(led_data->cust.name, "lcd-backlight") == 0) {
- #ifdef CONTROL_BL_TEMPERATURE
- mutex_lock(&bl_level_limit_mutex);
- current_level = level;
- /* LEDS_DRV_DEBUG("brightness_set_cust:current_level=%d\n", current_level); */
- if (0 == limit_flag) {
- last_level = level;
- /* LEDS_DRV_DEBUG("brightness_set_cust:last_level=%d\n", last_level); */
- } else {
- if (limit < current_level) {
- level = limit;
- LEDS_DRV_DEBUG
- ("backlight_set_cust: control level=%d\n",
- level);
- }
- }
- mutex_unlock(&bl_level_limit_mutex);
- #endif
- }
- #ifdef BACKLIGHT_SUPPORT_LP8557
- retval = gpio_request(I2C_SET_FOR_BACKLIGHT, "i2c_set_for_backlight");
- if (retval)
- LEDS_DRV_DEBUG("LEDS: request I2C gpio149 failed\n");
- if (strcmp(led_data->cust.name, "lcd-backlight") == 0) {
- if (level == 0) {
- LEDS_DRV_DEBUG("LEDS:mt65xx_led_set:close the power\n");
- i2c_smbus_write_byte_data(client, 0x00, 0);
- gpio_direction_output(I2C_SET_FOR_BACKLIGHT, 0);
- }
- if (!last_level1 && level) {
- LEDS_DRV_DEBUG("LEDS:mt65xx_led_set:open the power\n");
- gpio_direction_output(I2C_SET_FOR_BACKLIGHT, 1);
- mdelay(100);
- i2c_smbus_write_byte_data(client, 0x10, 4);
- flag = TRUE;
- }
- last_level1 = level;
- }
- gpio_free(I2C_SET_FOR_BACKLIGHT);
- #endif
- mt_mt65xx_led_set(led_cdev, level);
- #ifdef BACKLIGHT_SUPPORT_LP8557
- if (strcmp(led_data->cust.name, "lcd-backlight") == 0) {
- if (flag) {
- i2c_smbus_write_byte_data(client, 0x14, 0xdf);
- i2c_smbus_write_byte_data(client, 0x04, 0xff);
- i2c_smbus_write_byte_data(client, 0x00, 1);
- }
- }
- #endif
- }
- static int mt65xx_blink_set(struct led_classdev *led_cdev,
- unsigned long *delay_on, unsigned long *delay_off)
- {
- if (mt_mt65xx_blink_set(led_cdev, delay_on, delay_off))
- return -1;
- else
- return 0;
- }
- /****************************************************************************
- * external functions for display
- ***************************************************************************/
- int mt65xx_leds_brightness_set(enum mt65xx_led_type type,
- enum led_brightness level)
- {
- int val;
- struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
- #ifdef BACKLIGHT_SUPPORT_LP8557
- bool flag = FALSE;
- int value = 0;
- int retval;
- struct device_node *node = NULL;
- struct i2c_client *client = g_client;
- value = i2c_smbus_read_byte_data(g_client, 0x10);
- LEDS_DRV_DEBUG("LEDS:mt65xx_led_set:0x10 = %d\n", value);
- node = of_find_compatible_node(NULL, NULL,
- "mediatek,lcd-backlight");
- if (node) {
- I2C_SET_FOR_BACKLIGHT = of_get_named_gpio(node, "gpios", 0);
- LEDS_DRV_DEBUG("Led_i2c gpio num for power:%d\n", I2C_SET_FOR_BACKLIGHT);
- }
- #endif
- LEDS_DRV_DEBUG("#%d:%d\n", type, level);
- if (type < 0 || type >= MT65XX_LED_TYPE_TOTAL)
- return -1;
- if (level > LED_FULL)
- level = LED_FULL;
- else if (level < 0)
- level = 0;
- #ifdef BACKLIGHT_SUPPORT_LP8557
- retval = gpio_request(I2C_SET_FOR_BACKLIGHT, "i2c_set_for_backlight");
- if (retval)
- LEDS_DRV_DEBUG("LEDS: request I2C gpio149 failed\n");
- if (strcmp(cust_led_list[type].name, "lcd-backlight") == 0) {
- if (level == 0) {
- i2c_smbus_write_byte_data(client, 0x00, 0);
- gpio_direction_output(I2C_SET_FOR_BACKLIGHT, 0);
- }
- if (!last_level1 && level) {
- gpio_direction_output(I2C_SET_FOR_BACKLIGHT, 1);
- mdelay(100);
- i2c_smbus_write_byte_data(client, 0x10, 4);
- flag = TRUE;
- }
- last_level1 = level;
- }
- gpio_free(I2C_SET_FOR_BACKLIGHT);
- #endif
- val = mt65xx_led_set_cust(&cust_led_list[type], level);
- #ifdef BACKLIGHT_SUPPORT_LP8557
- if (strcmp(cust_led_list[type].name, "lcd-backlight") == 0) {
- if (flag) {
- i2c_smbus_write_byte_data(client, 0x14, 0xdf);
- i2c_smbus_write_byte_data(client, 0x04, 0xff);
- i2c_smbus_write_byte_data(client, 0x00, 1);
- }
- }
- #endif
- return val;
- }
- EXPORT_SYMBOL(mt65xx_leds_brightness_set);
- /****************************************************************************
- * external functions for AAL
- ***************************************************************************/
- int backlight_brightness_set(int level)
- {
- struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
- if (level > ((1 << MT_LED_INTERNAL_LEVEL_BIT_CNT) - 1))
- level = ((1 << MT_LED_INTERNAL_LEVEL_BIT_CNT) - 1);
- else if (level < 0)
- level = 0;
- if (MT65XX_LED_MODE_CUST_BLS_PWM ==
- cust_led_list[MT65XX_LED_TYPE_LCD].mode) {
- #ifdef CONTROL_BL_TEMPERATURE
- mutex_lock(&bl_level_limit_mutex);
- current_level = (level >> (MT_LED_INTERNAL_LEVEL_BIT_CNT - 8)); /* 8 bits */
- if (0 == limit_flag) {
- last_level = current_level;
- } else {
- if (limit < current_level) {
- /* extend 8-bit limit to 10 bits */
- level =
- (limit <<
- (MT_LED_INTERNAL_LEVEL_BIT_CNT -
- 8)) | (limit >> (16 -
- MT_LED_INTERNAL_LEVEL_BIT_CNT));
- }
- }
- mutex_unlock(&bl_level_limit_mutex);
- #endif
- return
- mt_mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD],
- level);
- } else {
- return mt65xx_led_set_cust(&cust_led_list[MT65XX_LED_TYPE_LCD],
- (level >>
- (MT_LED_INTERNAL_LEVEL_BIT_CNT -
- 8)));
- }
- }
- EXPORT_SYMBOL(backlight_brightness_set);
- #if 0
- static ssize_t show_duty(struct device *dev, struct device_attribute *attr,
- char *buf)
- {
- LEDS_DRV_DEBUG("get backlight duty value is:%d\n", bl_duty);
- return sprintf(buf, "%u\n", bl_duty);
- }
- static ssize_t store_duty(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size)
- {
- char *pvalue = NULL;
- unsigned int level = 0;
- size_t count = 0;
- bl_div = mt_get_bl_div();
- LEDS_DRV_DEBUG("set backlight duty start\n");
- level = (unsigned int) kstrtoul(buf, &pvalue, 10);
- count = pvalue - buf;
- if (*pvalue && isspace(*pvalue))
- count++;
- if (count == size) {
- if (bl_setting->mode == MT65XX_LED_MODE_PMIC) {
- /* duty:0-16 */
- if ((level >= 0) && (level <= 15)) {
- mt_brightness_set_pmic_duty_store((level * 17),
- bl_div);
- } else {
- LEDS_DRV_DEBUG
- ("duty value is error, please select value from [0-15]!\n");
- }
- }
- else if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
- if (level == 0) {
- mt_led_pwm_disable(bl_setting->data);
- } else if (level <= 64) {
- mt_backlight_set_pwm_duty(bl_setting->data,
- level, bl_div,
- &bl_setting->
- config_data);
- }
- }
- mt_set_bl_duty(level);
- }
- return size;
- }
- static DEVICE_ATTR(duty, 0664, show_duty, store_duty);
- static ssize_t show_div(struct device *dev, struct device_attribute *attr,
- char *buf)
- {
- bl_div = mt_get_bl_div();
- LEDS_DRV_DEBUG("get backlight div value is:%d\n", bl_div);
- return sprintf(buf, "%u\n", bl_div);
- }
- static ssize_t store_div(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size)
- {
- char *pvalue = NULL;
- unsigned int div = 0;
- size_t count = 0;
- bl_duty = mt_get_bl_duty();
- LEDS_DRV_DEBUG("set backlight div start\n");
- div = kstrtoul(buf, &pvalue, 10);
- count = pvalue - buf;
- if (*pvalue && isspace(*pvalue))
- count++;
- if (count == size) {
- if (div < 0 || (div > 7)) {
- LEDS_DRV_DEBUG
- ("set backlight div parameter error: %d[div:0~7]\n",
- div);
- return 0;
- }
- if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
- LEDS_DRV_DEBUG
- ("set PWM backlight div OK: div=%d, duty=%d\n", div,
- bl_duty);
- mt_backlight_set_pwm_div(bl_setting->data, bl_duty, div,
- &bl_setting->config_data);
- }
- else if (bl_setting->mode == MT65XX_LED_MODE_CUST_LCM) {
- bl_brightness = mt_get_bl_brightness();
- LEDS_DRV_DEBUG
- ("set cust backlight div OK: div=%d, brightness=%d\n",
- div, bl_brightness);
- ((cust_brightness_set) (bl_setting->data))
- (bl_brightness, div);
- }
- mt_set_bl_div(div);
- }
- return size;
- }
- static DEVICE_ATTR(div, 0664, show_div, store_div);
- static ssize_t show_frequency(struct device *dev, struct device_attribute *attr,
- char *buf)
- {
- bl_div = mt_get_bl_div();
- bl_frequency = mt_get_bl_frequency();
- if (bl_setting->mode == MT65XX_LED_MODE_PWM) {
- mt_set_bl_frequency(32000 / div_array[bl_div]);
- } else if (bl_setting->mode == MT65XX_LED_MODE_CUST_LCM) {
- /* mtkfb_get_backlight_pwm(bl_div, &bl_frequency); */
- mt_backlight_get_pwm_fsel(bl_div, &bl_frequency);
- }
- LEDS_DRV_DEBUG("get backlight PWM frequency value is:%d\n",
- bl_frequency);
- return sprintf(buf, "%u\n", bl_frequency);
- }
- static DEVICE_ATTR(frequency, 0444, show_frequency, NULL);
- static ssize_t store_pwm_register(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
- {
- char *pvalue = NULL;
- unsigned int reg_value = 0;
- unsigned int reg_address = 0;
- if (buf != NULL && size != 0) {
- /* LEDS_DRV_DEBUG("store_pwm_register: size:%d,address:0x%s\n", size, buf); */
- reg_address = kstrtoul(buf, &pvalue, 16);
- if (*pvalue && (*pvalue == '#')) {
- reg_value = kstrtoul((pvalue + 1), NULL, 16);
- LEDS_DRV_DEBUG("set pwm register:[0x%x]= 0x%x\n",
- reg_address, reg_value);
- /* OUTREG32(reg_address,reg_value); */
- mt_store_pwm_register(reg_address, reg_value);
- } else if (*pvalue && (*pvalue == '@')) {
- LEDS_DRV_DEBUG("get pwm register:[0x%x]=0x%x\n",
- reg_address,
- mt_show_pwm_register(reg_address));
- }
- }
- return size;
- }
- static ssize_t show_pwm_register(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- return 0;
- }
- static DEVICE_ATTR(pwm_register, 0664, show_pwm_register, store_pwm_register);
- #endif
- #ifdef BACKLIGHT_SUPPORT_LP8557
- static int led_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
- static int led_i2c_remove(struct i2c_client *client);
- /*
- static struct i2c_board_info leds_board_info __initdata = {
- I2C_BOARD_INFO("lp8557_led", 0x2c),
- };*/
- static const struct of_device_id lp855x_id[] = {
- {.compatible = "mediatek,8173led_i2c"},
- {},
- };
- MODULE_DEVICE_TABLE(OF, lp855x_id);
- static const struct i2c_device_id lp855x_i2c_id[] = {{"lp8557_led", 0}, {} };
- struct i2c_driver led_i2c_driver = {
- .probe = led_i2c_probe,
- .remove = led_i2c_remove,
- .driver = {
- .name = "lp8557_led",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(lp855x_id),
- },
- .id_table = lp855x_i2c_id,
- };
- static int led_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
- {
- g_client = client;
- return 0;
- }
- static int led_i2c_remove(struct i2c_client *client)
- {
- return 0;
- }
- #endif
- /****************************************************************************
- * driver functions
- ***************************************************************************/
- static int mt65xx_leds_probe(struct platform_device *pdev)
- {
- int i;
- int ret;/* rc; */
- struct cust_mt65xx_led *cust_led_list = mt_get_cust_led_list();
- #ifdef BACKLIGHT_SUPPORT_LP8557
- /*i2c_register_board_info(4, &leds_board_info, 1);*/
- if (i2c_add_driver(&led_i2c_driver)) {
- LEDS_DRV_DEBUG("unable to add led-i2c driver.\n");
- return -1;
- }
- #endif
- LEDS_DRV_DEBUG("%s\n", __func__);
- get_div_array();
- for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
- if (cust_led_list[i].mode == MT65XX_LED_MODE_NONE) {
- g_leds_data[i] = NULL;
- continue;
- }
- g_leds_data[i] =
- kzalloc(sizeof(struct mt65xx_led_data), GFP_KERNEL);
- if (!g_leds_data[i]) {
- ret = -ENOMEM;
- goto err;
- }
- g_leds_data[i]->cust.mode = cust_led_list[i].mode;
- g_leds_data[i]->cust.data = cust_led_list[i].data;
- g_leds_data[i]->cust.name = cust_led_list[i].name;
- g_leds_data[i]->cdev.name = cust_led_list[i].name;
- g_leds_data[i]->cust.config_data = cust_led_list[i].config_data; /* bei add */
- g_leds_data[i]->cdev.brightness_set = mt65xx_led_set;
- g_leds_data[i]->cdev.blink_set = mt65xx_blink_set;
- INIT_WORK(&g_leds_data[i]->work, mt_mt65xx_led_work);
- ret = led_classdev_register(&pdev->dev, &g_leds_data[i]->cdev);
- #if 0
- if (strcmp(g_leds_data[i]->cdev.name, "lcd-backlight") == 0) {
- rc = device_create_file(g_leds_data[i]->cdev.dev,
- &dev_attr_duty);
- if (rc) {
- LEDS_DRV_DEBUG
- ("device_create_file duty fail!\n");
- }
- rc = device_create_file(g_leds_data[i]->cdev.dev,
- &dev_attr_div);
- if (rc) {
- LEDS_DRV_DEBUG
- ("device_create_file duty fail!\n");
- }
- rc = device_create_file(g_leds_data[i]->cdev.dev,
- &dev_attr_frequency);
- if (rc) {
- LEDS_DRV_DEBUG
- ("device_create_file duty fail!\n");
- }
- rc = device_create_file(g_leds_data[i]->cdev.dev,
- &dev_attr_pwm_register);
- if (rc) {
- LEDS_DRV_DEBUG
- ("device_create_file duty fail!\n");
- }
- bl_setting = &g_leds_data[i]->cust;
- }
- #endif
- if (ret)
- goto err;
- }
- #ifdef CONTROL_BL_TEMPERATURE
- last_level = 0;
- limit = 255;
- limit_flag = 0;
- current_level = 0;
- LEDS_DRV_DEBUG
- ("led probe last_level = %d, limit = %d, limit_flag = %d, current_level = %d\n",
- last_level, limit, limit_flag, current_level);
- #endif
- return 0;
- err:
- if (i) {
- for (i = i - 1; i >= 0; i--) {
- if (!g_leds_data[i])
- continue;
- led_classdev_unregister(&g_leds_data[i]->cdev);
- cancel_work_sync(&g_leds_data[i]->work);
- kfree(g_leds_data[i]);
- g_leds_data[i] = NULL;
- }
- }
- return ret;
- }
- static int mt65xx_leds_remove(struct platform_device *pdev)
- {
- int i;
- for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
- if (!g_leds_data[i])
- continue;
- led_classdev_unregister(&g_leds_data[i]->cdev);
- cancel_work_sync(&g_leds_data[i]->work);
- kfree(g_leds_data[i]);
- g_leds_data[i] = NULL;
- }
- return 0;
- }
- /*
- static int mt65xx_leds_suspend(struct platform_device *pdev, pm_message_t state)
- {
- return 0;
- }
- */
- static void mt65xx_leds_shutdown(struct platform_device *pdev)
- {
- int i;
- struct nled_setting led_tmp_setting = { NLED_OFF, 0, 0 };
- LEDS_DRV_DEBUG("%s\n", __func__);
- LEDS_DRV_DEBUG("mt65xx_leds_shutdown: turn off backlight\n");
- for (i = 0; i < MT65XX_LED_TYPE_TOTAL; i++) {
- if (!g_leds_data[i])
- continue;
- switch (g_leds_data[i]->cust.mode) {
- case MT65XX_LED_MODE_PWM:
- if (strcmp(g_leds_data[i]->cust.name, "lcd-backlight")
- == 0) {
- /* mt_set_pwm_disable(g_leds_data[i]->cust.data); */
- /* mt_pwm_power_off (g_leds_data[i]->cust.data); */
- mt_led_pwm_disable(g_leds_data[i]->cust.data);
- } else {
- led_set_pwm(g_leds_data[i]->cust.data,
- &led_tmp_setting);
- }
- break;
- /* case MT65XX_LED_MODE_GPIO: */
- /* brightness_set_gpio(g_leds_data[i]->cust.data, 0); */
- /* break; */
- case MT65XX_LED_MODE_PMIC:
- brightness_set_pmic(g_leds_data[i]->cust.data, 0, 0);
- break;
- case MT65XX_LED_MODE_CUST_LCM:
- LEDS_DRV_DEBUG("backlight control through LCM!!1\n");
- ((cust_brightness_set) (g_leds_data[i]->cust.data)) (0,
- bl_div);
- break;
- case MT65XX_LED_MODE_CUST_BLS_PWM:
- LEDS_DRV_DEBUG("backlight control through BLS!!1\n");
- ((cust_set_brightness) (g_leds_data[i]->cust.data)) (0);
- break;
- case MT65XX_LED_MODE_NONE:
- default:
- break;
- }
- }
- }
- static struct platform_driver mt65xx_leds_driver = {
- .driver = {
- .name = "leds-mt65xx",
- .owner = THIS_MODULE,
- },
- .probe = mt65xx_leds_probe,
- .remove = mt65xx_leds_remove,
- /* .suspend = mt65xx_leds_suspend, */
- .shutdown = mt65xx_leds_shutdown,
- };
- #ifdef CONFIG_OF
- static struct platform_device mt65xx_leds_device = {
- .name = "leds-mt65xx",
- .id = -1
- };
- #endif
- static int __init mt65xx_leds_init(void)
- {
- int ret;
- LEDS_DRV_DEBUG("%s\n", __func__);
- #ifdef CONFIG_OF
- ret = platform_device_register(&mt65xx_leds_device);
- if (ret)
- LEDS_DRV_DEBUG("mt65xx_leds_init:dev:E%d\n", ret);
- #endif
- ret = platform_driver_register(&mt65xx_leds_driver);
- if (ret) {
- LEDS_DRV_DEBUG("mt65xx_leds_init:drv:E%d\n", ret);
- /* platform_device_unregister(&mt65xx_leds_device); */
- return ret;
- }
- mt_leds_wake_lock_init();
- return ret;
- }
- static void __exit mt65xx_leds_exit(void)
- {
- platform_driver_unregister(&mt65xx_leds_driver);
- /* platform_device_unregister(&mt65xx_leds_device); */
- }
- module_param(debug_enable_led, int, 0644);
- module_init(mt65xx_leds_init);
- module_exit(mt65xx_leds_exit);
- MODULE_AUTHOR("MediaTek Inc.");
- MODULE_DESCRIPTION("LED driver for MediaTek MT65xx chip");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("leds-mt65xx");
|