ktd2801背光控制器波形不准的问题分析

来源:互联网 发布:java 获取locale 编辑:程序博客网 时间:2024/05/17 03:19

ktd2801背光控制器支持两种调光方式:

1. 可通过控制引脚输入一组脉冲信号作为控制命令,来确定一个输出强度。

2. 同时也支持在该控制引脚输入一个持续的PWM脉冲来确定一个输出强度。

后者等同于其他类型的PWM调光控制方式:背光打开时必须要有一个持续的PWM输入信号;通过调整PWM的占空比来调整背光亮度。这种方式下的持续的PWM信号据说会造成其他设备的信号干扰。而ktd2801的第一种调光方式可解决这个问题。

在第一种调光方式中,只有亮度调整时才会向控制引脚输入一组脉冲作为控制命令,当ktd2801接到这个命令后便会改变背光强度。此后该控制引脚不需要维持脉冲信号。

通常,在该方式下,AP侧会用一个gpio引脚连接到ktd2801的控制端。软件会对该gpio进行输出高、低的操作来模拟出一组脉冲信号作为控制命令。命令协议很简单,可参考ktd2801的datasheet。

工作中出现的问题是:软件对该gpio进行输出高、底的操作时会出现偶尔的脉冲宽度不一致。也就是偶尔出现脉冲宽度比我们期望的要大很多,这会导致ktd2801解析出现错误,表现为对该命令不响应。

分析:

1. 首先必须明确,用gpio模拟一个信号时,维持高低电平的时间必须忙等,也就是必须用udelay之类的函数,绝对不能用msleep。这个原因很浅显。

2. 其次每个命令周期必须用自旋锁包裹起来,不能被打断。否则就会出现延时比你期望的要长,导致命令错误。

先前的代码对2使用的是:

spin_lock(&bl_ctrl_lock);

spin_unlock(&bl_ctrl_lock);

用了这个锁后,还是出现了延时比期望的要长,可能是有中断发生导致的。

因此,换为下面的锁,该锁会屏蔽中断,问题解决!

spin_lock_irqsave(&bl_ctrl_lock, flags);
spin_unlock_irqrestore(&bl_ctrl_lock, flags);


======================附上源码:修改前================================


/*************** maintained by customer ***************************************/#define CONFIG_BACKLIGHT_AMAZING 1/* * linux/drivers/video/backlight/s2c_bl.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. *//******************************************************************************** Copyright 2010 Broadcom Corporation.  All rights reserved.** @filedrivers/video/backlight/s2c_bl.c** Unless you and Broadcom execute a separate written software license agreement* governing use of this software, this software is licensed to you under the* terms of the GNU General Public License version 2, available at* http://www.gnu.org/copyleft/gpl.html (the "GPL").** Notwithstanding the above, under no circumstances may you combine this* software in any way with any other Broadcom software provided under a license* other than the GPL, without Broadcom's express prior written consent.*******************************************************************************/#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/fb.h>#include <linux/backlight.h>#include <linux/err.h>#include <linux/ktd2801_bl.h>#include <mach/gpio.h>#include <linux/delay.h>#include <linux/spinlock.h>#ifdef CONFIG_EARLYSUSPEND#include <linux/earlysuspend.h>#endifstatic DEFINE_SPINLOCK(bl_ctrl_lock);#define BACKLIGHT_DEBUG 1#if BACKLIGHT_DEBUG#define BLDBG(fmt, args...) printk(fmt, ## args)#else#define BLDBG(fmt, args...)#endif#define EXPRESSWIRE_DIMMING#ifdef EXPRESSWIRE_DIMMING#define EW_DELAY 200#define EW_DETECT 300#define EW_WINDOW 900#define DATA_START 40#define LOW_BIT_L 40#define LOW_BIT_H 10#define HIGH_BIT_L 10#define HIGH_BIT_H 40#define END_DATA_L 10#define END_DATA_H 400#endif#define BACKLIGHT_DEV_NAME"sprd_backlight"int BL_brightness;int is_poweron = 1;int current_brightness;int wakeup_brightness;#ifdef CONFIG_MACH_NEVISTD#define GPIO_BL_CTRL138#else#define GPIO_BL_CTRL190#endif#ifdef CONFIG_MACH_NEVISTD#define MAX_BRIGHTNESS255#define MIN_BRIGHTNESS20#define DEFAULT_BRIGHTNESS 130#define DEFAULT_PULSE 20#define DIMMING_VALUE31#define MAX_BRIGHTNESS_IN_BLU32 // backlight-IC MAX VALUE#else#define MAX_BRIGHTNESS255#define MIN_BRIGHTNESS20#define DEFAULT_BRIGHTNESS 122#define DEFAULT_PULSE 20#define DIMMING_VALUE31#define MAX_BRIGHTNESS_IN_BLU32 // backlight-IC MAX VALUE#endifstatic int lcd_brightness = DEFAULT_PULSE;struct brt_value{int level;// Platform setting valuesint tune_level;// Chip Setting values};#ifdef CONFIG_HAS_EARLYSUSPENDstruct early_suspendearly_suspend_BL;#endifstruct brt_value brt_table_ktd[] = {{ 255,0 }, /* Max */{ 250,2 },{ 245,3 },{ 240,4 },{ 235,5 },{ 230,6 },{ 220,7 },{ 210,8 },{ 200,9 },{ 190,10 },{ 180,11 },{ 170,12 },{ 160,13 },{ 150,14 },{ 140,15 },{ 130,16 },{ 120,17 }, /* default */{ 115,18 },{ 110,19 },{ 105,20 },{ 100,21 },{ 95,22 },{ 90,23 },{ 85,24 },{ 80,25 },{ 70,26 }, /* Dimming */{ 60,27 },{ 50,28 },{ 40,29 },{ 30,30 },{ 20,31 },{ 0,31 }, /* Off */};#define NB_BRT_LEVEL (int)(sizeof(brt_table_ktd)/sizeof(struct brt_value))#if defined(CONFIG_FB_SC8825) && defined(CONFIG_FB_LCD_NT35510_MIPI)extern bool is_first_frame_done;#endif#ifdef CONFIG_MACH_NEVISTDextern int spa_lpm_charging_mode_get(void);#endif#ifdef CONFIG_EARLYSUSPENDstatic void ktd253_backlight_early_suspend(struct early_suspend *h){is_poweron = 0;ktd_backlight_set_brightness(0);#ifdef EXPRESSWIRE_DIMMINGgpio_set_value(GPIO_BL_CTRL, 0);#endifreturn;}static void ktd253_backlight_late_resume(struct early_suspend *h){int i = 0;#if defined(CONFIG_FB_SC8825) && defined(CONFIG_FB_LCD_NT35510_MIPI)while (i++ < 10 && !is_first_frame_done) {printk(KERN_INFO "[Backlight] wait first vsync_done, sleep 200msec\n", __func__);msleep(200);}#endif#ifdef EXPRESSWIRE_DIMMINGspin_lock(&bl_ctrl_lock);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);spin_unlock(&bl_ctrl_lock);#endifktd_backlight_set_brightness(wakeup_brightness);is_poweron = 1;}#endif#ifdef EXPRESSWIRE_DIMMINGvoid ktd_backlight_set_brightness(int level){int i = 0;unsigned char brightness;int bit_map[8];brightness = level;printk("set_brightness : level(%d)\n", brightness);for(i = 0; i < 8; i++){bit_map[i] = brightness & 0x01;brightness >>= 1;}spin_lock(&bl_ctrl_lock);#if 0gpio_set_value(GPIO_BL_CTRL, 0);msleep(10);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);#endifgpio_set_value(GPIO_BL_CTRL, 1);udelay(DATA_START);for(i = 7; i >= 0; i--){if(bit_map[i]){gpio_set_value(GPIO_BL_CTRL, 0);udelay(HIGH_BIT_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(HIGH_BIT_H);}else{gpio_set_value(GPIO_BL_CTRL, 0);udelay(LOW_BIT_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(LOW_BIT_H);}}gpio_set_value(GPIO_BL_CTRL, 0);udelay(END_DATA_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(END_DATA_H);spin_unlock(&bl_ctrl_lock);return;}#elsevoid ktd_backlight_set_brightness(int level){int tune_level = 0;spin_lock(&bl_ctrl_lock);if (level > 0) {if (level < MIN_BRIGHTNESS) {tune_level = DIMMING_VALUE; /* DIMMING */} else {int i;for (i = 0; i < NB_BRT_LEVEL; i++) {if (level <= brt_table_ktd[i].level&& level > brt_table_ktd[i+1].level) {tune_level = brt_table_ktd[i].tune_level;break;}}}} /*  BACKLIGHT is KTD model */printk("set_brightness : level(%d) tune (%d)\n",level, tune_level);current_brightness = level;if (!level) {gpio_set_value(GPIO_BL_CTRL, 0);mdelay(3);lcd_brightness = tune_level;} else {int pulse;if (unlikely(lcd_brightness < 0)) {int val = gpio_get_value(GPIO_BL_CTRL);if (val) {lcd_brightness = 0;gpio_set_value(GPIO_BL_CTRL, 0);mdelay(3);printk(KERN_INFO "LCD Baklight init in boot time on kernel\n");}}#ifdef CONFIG_MACH_NEVISTDif(spa_lpm_charging_mode_get())msleep(500);#endifif (!lcd_brightness) {gpio_set_value(GPIO_BL_CTRL, 1);udelay(3);lcd_brightness = MAX_BRIGHTNESS_IN_BLU;}pulse = (tune_level - lcd_brightness + MAX_BRIGHTNESS_IN_BLU)% MAX_BRIGHTNESS_IN_BLU;for (; pulse > 0; pulse--) {gpio_set_value(GPIO_BL_CTRL, 0);udelay(3);gpio_set_value(GPIO_BL_CTRL, 1);udelay(3);}lcd_brightness = tune_level;}mdelay(1);spin_unlock(&bl_ctrl_lock);return;}#endifstatic int ktd_backlight_update_status(struct backlight_device *bl){int brightness = bl->props.brightness;if (bl->props.power != FB_BLANK_UNBLANK)brightness = 0;if (bl->props.fb_blank != FB_BLANK_UNBLANK)brightness = 0;wakeup_brightness = brightness;if (is_poweron == 1)ktd_backlight_set_brightness(brightness);elseBLDBG("[BACKLIGHT] warning : ignore set brightness\n");return 0;}static int ktd_backlight_get_brightness(struct backlight_device *bl){BLDBG("[BACKLIGHT] ktd_backlight_get_brightness\n");BL_brightness = bl->props.brightness;return BL_brightness;}static const struct backlight_ops ktd_backlight_ops = {.update_status= ktd_backlight_update_status,.get_brightness= ktd_backlight_get_brightness,};static int ktd_backlight_probe(struct platform_device *pdev){//struct platform_ktd253b_backlight_data *data = pdev->dev.platform_data;struct backlight_device *bl;struct backlight_properties props;printk("[BACKLIGHT] ktd253b_backlight_probe\n");memset(&props, 0, sizeof(struct backlight_properties));props.max_brightness = MAX_BRIGHTNESS;props.type = BACKLIGHT_RAW;bl = backlight_device_register(BACKLIGHT_DEV_NAME, &pdev->dev, NULL,&ktd_backlight_ops, &props);if (IS_ERR(bl)){dev_err(&pdev->dev, "failed to register backlight\n");return PTR_ERR(bl);}bl->props.max_brightness = MAX_BRIGHTNESS;bl->props.brightness = DEFAULT_BRIGHTNESS;platform_set_drvdata(pdev, bl);if(gpio_request(GPIO_BL_CTRL,"BL_CTRL"))printk(KERN_ERR "Request GPIO failed,""gpio: %d \n", GPIO_BL_CTRL);#ifdef EXPRESSWIRE_DIMMINGspin_lock(&bl_ctrl_lock);gpio_set_value(GPIO_BL_CTRL, 0);udelay(1500);udelay(1500);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);spin_unlock(&bl_ctrl_lock);#endif#ifdef CONFIG_HAS_EARLYSUSPENDearly_suspend_BL.suspend = ktd253_backlight_early_suspend;early_suspend_BL.resume  = ktd253_backlight_late_resume;early_suspend_BL.level   = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;register_early_suspend(&early_suspend_BL);#endifktd_backlight_update_status(bl);return 0;out:return 1;}static int ktd_backlight_remove(struct platform_device *pdev){struct backlight_device *bl = platform_get_drvdata(pdev);backlight_device_unregister(bl);gpio_direction_output(GPIO_BL_CTRL, 0);mdelay(3);return 0;}void ktd_backlight_shutdown(struct platform_device *pdev){printk("[coko] %s\n",__FUNCTION__);gpio_direction_output(GPIO_BL_CTRL, 0);mdelay(5);}static struct platform_driver ktd_backlight_driver = {.driver= {.name= BACKLIGHT_DEV_NAME,.owner= THIS_MODULE,},.probe= ktd_backlight_probe,.remove= ktd_backlight_remove,.shutdown       = ktd_backlight_shutdown,};static int __init ktd_backlight_init(void){return platform_driver_register(&ktd_backlight_driver);}module_init(ktd_backlight_init);static void __exit ktd_backlight_exit(void){platform_driver_unregister(&ktd_backlight_driver);}module_exit(ktd_backlight_exit);MODULE_DESCRIPTION("KTD based Backlight Driver");MODULE_LICENSE("GPL");MODULE_ALIAS("platform:ktd-backlight");


======================附上源码:修改后================================


/*************** maintained by customer ***************************************/#define CONFIG_BACKLIGHT_AMAZING 1/* * linux/drivers/video/backlight/s2c_bl.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. *//******************************************************************************** Copyright 2010 Broadcom Corporation.  All rights reserved.** @filedrivers/video/backlight/s2c_bl.c** Unless you and Broadcom execute a separate written software license agreement* governing use of this software, this software is licensed to you under the* terms of the GNU General Public License version 2, available at* http://www.gnu.org/copyleft/gpl.html (the "GPL").** Notwithstanding the above, under no circumstances may you combine this* software in any way with any other Broadcom software provided under a license* other than the GPL, without Broadcom's express prior written consent.*******************************************************************************/#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/fb.h>#include <linux/backlight.h>#include <linux/err.h>#include <linux/ktd2801_bl.h>#include <mach/gpio.h>#include <linux/delay.h>#include <linux/spinlock.h>#ifdef CONFIG_EARLYSUSPEND#include <linux/earlysuspend.h>#endifstatic DEFINE_SPINLOCK(bl_ctrl_lock);#define BACKLIGHT_DEBUG 1#if BACKLIGHT_DEBUG#define BLDBG(fmt, args...) printk(fmt, ## args)#else#define BLDBG(fmt, args...)#endif#define EXPRESSWIRE_DIMMING#ifdef EXPRESSWIRE_DIMMING#define EW_DELAY 200#define EW_DETECT 300#define EW_WINDOW 900#define DATA_START 10#define LOW_BIT_L 15#define LOW_BIT_H 5#define HIGH_BIT_L 5#define HIGH_BIT_H 15#define END_DATA_L 10#define END_DATA_H 400#endif#define BACKLIGHT_DEV_NAME"sprd_backlight"int BL_brightness;int is_poweron = 1;int current_brightness;int wakeup_brightness;#ifdef CONFIG_MACH_NEVISTD#define GPIO_BL_CTRL138#else#define GPIO_BL_CTRL190#endif#ifdef CONFIG_MACH_NEVISTD#define MAX_BRIGHTNESS255#define MIN_BRIGHTNESS20#define DEFAULT_BRIGHTNESS 130#define DEFAULT_PULSE 20#define DIMMING_VALUE31#define MAX_BRIGHTNESS_IN_BLU32 // backlight-IC MAX VALUE#else#define MAX_BRIGHTNESS255#define MIN_BRIGHTNESS20#define DEFAULT_BRIGHTNESS 122#define DEFAULT_PULSE 20#define DIMMING_VALUE31#define MAX_BRIGHTNESS_IN_BLU32 // backlight-IC MAX VALUE#endifstatic int lcd_brightness = DEFAULT_PULSE;struct brt_value{int level;// Platform setting valuesint tune_level;// Chip Setting values};#ifdef CONFIG_HAS_EARLYSUSPENDstruct early_suspendearly_suspend_BL;#endifstruct brt_value brt_table_ktd[] = {{ 255,0 }, /* Max */{ 250,2 },{ 245,3 },{ 240,4 },{ 235,5 },{ 230,6 },{ 220,7 },{ 210,8 },{ 200,9 },{ 190,10 },{ 180,11 },{ 170,12 },{ 160,13 },{ 150,14 },{ 140,15 },{ 130,16 },{ 120,17 }, /* default */{ 115,18 },{ 110,19 },{ 105,20 },{ 100,21 },{ 95,22 },{ 90,23 },{ 85,24 },{ 80,25 },{ 70,26 }, /* Dimming */{ 60,27 },{ 50,28 },{ 40,29 },{ 30,30 },{ 20,31 },{ 0,31 }, /* Off */};#define NB_BRT_LEVEL (int)(sizeof(brt_table_ktd)/sizeof(struct brt_value))#if defined(CONFIG_FB_SC8825) && defined(CONFIG_FB_LCD_NT35510_MIPI)extern bool is_first_frame_done;#endif#ifdef CONFIG_MACH_NEVISTDextern int spa_lpm_charging_mode_get(void);#endif#ifdef CONFIG_EARLYSUSPENDstatic void ktd253_backlight_early_suspend(struct early_suspend *h){is_poweron = 0;ktd_backlight_set_brightness(0);#ifdef EXPRESSWIRE_DIMMINGgpio_set_value(GPIO_BL_CTRL, 0);#endifreturn;}static void ktd253_backlight_late_resume(struct early_suspend *h){int i = 0;unsigned long flags;#if defined(CONFIG_FB_SC8825) && defined(CONFIG_FB_LCD_NT35510_MIPI)while (i++ < 10 && !is_first_frame_done) {printk(KERN_INFO "[Backlight] wait first vsync_done, sleep 200msec\n", __func__);msleep(200);}#endif#ifdef EXPRESSWIRE_DIMMING//spin_lock(&bl_ctrl_lock);spin_lock_irqsave(&bl_ctrl_lock, flags);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);//spin_unlock(&bl_ctrl_lock);spin_unlock_irqrestore(&bl_ctrl_lock, flags);#endifktd_backlight_set_brightness(wakeup_brightness);is_poweron = 1;}#endif#ifdef EXPRESSWIRE_DIMMINGvoid ktd_backlight_set_brightness(int level){int i = 0;unsigned char brightness;int bit_map[8];brightness = level;unsigned long flags;printk("set_brightness : level(%d)\n", brightness);for(i = 0; i < 8; i++){bit_map[i] = brightness & 0x01;brightness >>= 1;}//spin_lock(&bl_ctrl_lock);spin_lock_irqsave(&bl_ctrl_lock, flags);#if 0gpio_set_value(GPIO_BL_CTRL, 0);msleep(10);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);#endifgpio_set_value(GPIO_BL_CTRL, 1);udelay(DATA_START);for(i = 7; i >= 0; i--){if(bit_map[i]){gpio_set_value(GPIO_BL_CTRL, 0);udelay(HIGH_BIT_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(HIGH_BIT_H);}else{gpio_set_value(GPIO_BL_CTRL, 0);udelay(LOW_BIT_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(LOW_BIT_H);}}gpio_set_value(GPIO_BL_CTRL, 0);udelay(END_DATA_L);gpio_set_value(GPIO_BL_CTRL, 1);udelay(END_DATA_H);//spin_unlock(&bl_ctrl_lock);spin_unlock_irqrestore(&bl_ctrl_lock, flags);return;}#elsevoid ktd_backlight_set_brightness(int level){int tune_level = 0;spin_lock(&bl_ctrl_lock);if (level > 0) {if (level < MIN_BRIGHTNESS) {tune_level = DIMMING_VALUE; /* DIMMING */} else {int i;for (i = 0; i < NB_BRT_LEVEL; i++) {if (level <= brt_table_ktd[i].level&& level > brt_table_ktd[i+1].level) {tune_level = brt_table_ktd[i].tune_level;break;}}}} /*  BACKLIGHT is KTD model */printk("set_brightness : level(%d) tune (%d)\n",level, tune_level);current_brightness = level;if (!level) {gpio_set_value(GPIO_BL_CTRL, 0);mdelay(3);lcd_brightness = tune_level;} else {int pulse;if (unlikely(lcd_brightness < 0)) {int val = gpio_get_value(GPIO_BL_CTRL);if (val) {lcd_brightness = 0;gpio_set_value(GPIO_BL_CTRL, 0);mdelay(3);printk(KERN_INFO "LCD Baklight init in boot time on kernel\n");}}#ifdef CONFIG_MACH_NEVISTDif(spa_lpm_charging_mode_get())msleep(500);#endifif (!lcd_brightness) {gpio_set_value(GPIO_BL_CTRL, 1);udelay(3);lcd_brightness = MAX_BRIGHTNESS_IN_BLU;}pulse = (tune_level - lcd_brightness + MAX_BRIGHTNESS_IN_BLU)% MAX_BRIGHTNESS_IN_BLU;for (; pulse > 0; pulse--) {gpio_set_value(GPIO_BL_CTRL, 0);udelay(3);gpio_set_value(GPIO_BL_CTRL, 1);udelay(3);}lcd_brightness = tune_level;}mdelay(1);spin_unlock(&bl_ctrl_lock);return;}#endifstatic int ktd_backlight_update_status(struct backlight_device *bl){int brightness = bl->props.brightness;if (bl->props.power != FB_BLANK_UNBLANK)brightness = 0;if (bl->props.fb_blank != FB_BLANK_UNBLANK)brightness = 0;wakeup_brightness = brightness;if (is_poweron == 1)ktd_backlight_set_brightness(brightness);elseBLDBG("[BACKLIGHT] warning : ignore set brightness\n");return 0;}static int ktd_backlight_get_brightness(struct backlight_device *bl){BLDBG("[BACKLIGHT] ktd_backlight_get_brightness\n");BL_brightness = bl->props.brightness;return BL_brightness;}static const struct backlight_ops ktd_backlight_ops = {.update_status= ktd_backlight_update_status,.get_brightness= ktd_backlight_get_brightness,};static int ktd_backlight_probe(struct platform_device *pdev){//struct platform_ktd253b_backlight_data *data = pdev->dev.platform_data;struct backlight_device *bl;struct backlight_properties props;unsigned long flags;printk("[BACKLIGHT] ktd253b_backlight_probe\n");memset(&props, 0, sizeof(struct backlight_properties));props.max_brightness = MAX_BRIGHTNESS;props.type = BACKLIGHT_RAW;bl = backlight_device_register(BACKLIGHT_DEV_NAME, &pdev->dev, NULL,&ktd_backlight_ops, &props);if (IS_ERR(bl)){dev_err(&pdev->dev, "failed to register backlight\n");return PTR_ERR(bl);}bl->props.max_brightness = MAX_BRIGHTNESS;bl->props.brightness = DEFAULT_BRIGHTNESS;platform_set_drvdata(pdev, bl);if(gpio_request(GPIO_BL_CTRL,"BL_CTRL"))printk(KERN_ERR "Request GPIO failed,""gpio: %d \n", GPIO_BL_CTRL);#ifdef EXPRESSWIRE_DIMMING//spin_lock(&bl_ctrl_lock);spin_lock_irqsave(&bl_ctrl_lock, flags);gpio_set_value(GPIO_BL_CTRL, 0);udelay(1500);udelay(1500);gpio_set_value(GPIO_BL_CTRL, 1);udelay(200);gpio_set_value(GPIO_BL_CTRL, 0);udelay(300);gpio_set_value(GPIO_BL_CTRL, 1);udelay(400);//spin_unlock(&bl_ctrl_lock);spin_unlock_irqrestore(&bl_ctrl_lock, flags);#endif#ifdef CONFIG_HAS_EARLYSUSPENDearly_suspend_BL.suspend = ktd253_backlight_early_suspend;early_suspend_BL.resume  = ktd253_backlight_late_resume;early_suspend_BL.level   = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;register_early_suspend(&early_suspend_BL);#endifktd_backlight_update_status(bl);return 0;out:return 1;}static int ktd_backlight_remove(struct platform_device *pdev){struct backlight_device *bl = platform_get_drvdata(pdev);backlight_device_unregister(bl);gpio_direction_output(GPIO_BL_CTRL, 0);mdelay(3);return 0;}void ktd_backlight_shutdown(struct platform_device *pdev){printk("[coko] %s\n",__FUNCTION__);gpio_direction_output(GPIO_BL_CTRL, 0);mdelay(5);}static struct platform_driver ktd_backlight_driver = {.driver= {.name= BACKLIGHT_DEV_NAME,.owner= THIS_MODULE,},.probe= ktd_backlight_probe,.remove= ktd_backlight_remove,.shutdown       = ktd_backlight_shutdown,};static int __init ktd_backlight_init(void){return platform_driver_register(&ktd_backlight_driver);}module_init(ktd_backlight_init);static void __exit ktd_backlight_exit(void){platform_driver_unregister(&ktd_backlight_driver);}module_exit(ktd_backlight_exit);MODULE_DESCRIPTION("KTD based Backlight Driver");MODULE_LICENSE("GPL");MODULE_ALIAS("platform:ktd-backlight");




0 0