From: 黄涛 Date: Wed, 13 Apr 2011 05:15:09 +0000 (+0800) Subject: rk29: backlight: use work instead of timer, better init X-Git-Tag: firefly_0821_release~10499 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6278e9b394f3e3c16c281b394748b9e671a8a26d;p=firefly-linux-kernel-4.4.55.git rk29: backlight: use work instead of timer, better init --- diff --git a/drivers/video/backlight/rk29_backlight.c b/drivers/video/backlight/rk29_backlight.c index 20cd08ed801d..edfe0160c7c0 100755 --- a/drivers/video/backlight/rk29_backlight.c +++ b/drivers/video/backlight/rk29_backlight.c @@ -1,6 +1,6 @@ /* drivers/video/backlight/rk29_backlight.c * - * Copyright (C) 2009 Rockchip Corporation. + * Copyright (C) 2009-2011 Rockchip Corporation. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -19,17 +19,12 @@ #include #include #include -#include #include #include -#include #include #include #include -//#include -#include -#include #include #include @@ -45,174 +40,136 @@ #endif -#define write_pwm_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10)) +#define write_pwm_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10)) #define read_pwm_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10)) -#define mask_pwm_reg(id, addr, msk, val) write_dma_reg(id, addr, (val)|((~(msk))&read_dma_reg(id, addr))) static struct clk *pwm_clk; -static unsigned long pwm_clk_rate; static struct backlight_device *rk29_bl; static int suspend_flag = 0; #define BACKLIGHT_SEE_MINVALUE 52 -static s32 rk29_bl_update_status(struct backlight_device *bl) +static int rk29_bl_update_status(struct backlight_device *bl) { - u32 divh,div_total; - struct rk29_bl_info *rk29_bl_info = bl->dev.parent->platform_data; - u32 id = rk29_bl_info->pwm_id; - u32 ref = rk29_bl_info->bl_ref; - - if (suspend_flag) - return 0; - - div_total = read_pwm_reg(id, PWM_REG_LRC); - if (ref) { - divh = div_total*(bl->props.brightness)/BL_STEP; - DBG(">>>%s-->%d bl->props.brightness == %d, div_total == %d , divh == %d\n",__FUNCTION__,__LINE__,bl->props.brightness, div_total, divh); - } else { - DBG(">>>%s-->%d bl->props.brightness == %d\n",__FUNCTION__,__LINE__,bl->props.brightness); - if(bl->props.brightness < BACKLIGHT_SEE_MINVALUE) /*avoid can't view screen when close backlight*/ - bl->props.brightness = BACKLIGHT_SEE_MINVALUE; - divh = div_total*(BL_STEP-bl->props.brightness)/BL_STEP; - } - write_pwm_reg(id, PWM_REG_HRC, divh); - return 0; + u32 divh,div_total; + struct rk29_bl_info *rk29_bl_info = bl_get_data(bl); + u32 id = rk29_bl_info->pwm_id; + u32 ref = rk29_bl_info->bl_ref; + + if (suspend_flag) + return 0; + + div_total = read_pwm_reg(id, PWM_REG_LRC); + if (ref) { + divh = div_total*(bl->props.brightness)/BL_STEP; + DBG(">>>%s-->%d bl->props.brightness == %d, div_total == %d , divh == %d\n",__FUNCTION__,__LINE__,bl->props.brightness, div_total, divh); + } else { + DBG(">>>%s-->%d bl->props.brightness == %d\n",__FUNCTION__,__LINE__,bl->props.brightness); + if(bl->props.brightness < BACKLIGHT_SEE_MINVALUE) /*avoid can't view screen when close backlight*/ + bl->props.brightness = BACKLIGHT_SEE_MINVALUE; + divh = div_total*(BL_STEP-bl->props.brightness)/BL_STEP; + } + write_pwm_reg(id, PWM_REG_HRC, divh); + return 0; } -static s32 rk29_bl_get_brightness(struct backlight_device *bl) +static int rk29_bl_get_brightness(struct backlight_device *bl) { - u32 divh,div_total; - struct rk29_bl_info *rk29_bl_info = bl->dev.parent->platform_data; - u32 id = rk29_bl_info->pwm_id; - u32 ref = rk29_bl_info->bl_ref; - - div_total = read_pwm_reg(id, PWM_REG_LRC); - divh = read_pwm_reg(id, PWM_REG_HRC); - - DBG("%s:: %d div_total: %d\n",__func__,__LINE__,div_total); - - if (!div_total) - return 0; - - if (ref) { - return BL_STEP*divh/div_total; - } else { - return BL_STEP-(BL_STEP*divh/div_total); - } + u32 divh,div_total; + struct rk29_bl_info *rk29_bl_info = bl_get_data(bl); + u32 id = rk29_bl_info->pwm_id; + u32 ref = rk29_bl_info->bl_ref; + + div_total = read_pwm_reg(id, PWM_REG_LRC); + divh = read_pwm_reg(id, PWM_REG_HRC); + + if (!div_total) + return 0; + + if (ref) { + return BL_STEP*divh/div_total; + } else { + return BL_STEP-(BL_STEP*divh/div_total); + } } static struct backlight_ops rk29_bl_ops = { - .update_status = rk29_bl_update_status, - .get_brightness = rk29_bl_get_brightness, + .update_status = rk29_bl_update_status, + .get_brightness = rk29_bl_get_brightness, }; -static void rk29_delaybacklight_timer(unsigned long data) +static void rk29_backlight_work_func(struct work_struct *work) { - struct rk29_bl_info *rk29_bl_info = (struct rk29_bl_info *)data; - u32 id, brightness; - u32 div_total, divh; - - if (rk29_bl_info->pwm_resume) - rk29_bl_info->pwm_resume(); - - clk_enable(pwm_clk); - id = rk29_bl_info->pwm_id; - brightness = rk29_bl->props.brightness; - div_total = read_pwm_reg(id, PWM_REG_LRC); - if (rk29_bl_info->bl_ref) { - divh = div_total*(brightness)/BL_STEP; - } else { - divh = div_total*(BL_STEP-brightness)/BL_STEP; - } - write_pwm_reg(id, PWM_REG_HRC, divh); - suspend_flag = 0; + rk29_bl_update_status(rk29_bl); } +static DECLARE_DELAYED_WORK(rk29_backlight_work, rk29_backlight_work_func); #ifdef CONFIG_HAS_EARLYSUSPEND static void rk29_bl_suspend(struct early_suspend *h) { - struct rk29_bl_info *rk29_bl_info; - u32 id; - u32 div_total, divh; - - rk29_bl_info = rk29_bl->dev.parent->platform_data; - - id = rk29_bl_info->pwm_id; - - div_total = read_pwm_reg(id, PWM_REG_LRC); - - if(rk29_bl_info->bl_ref) { - divh = 0; - } else { - divh = div_total; - } - - write_pwm_reg(id, PWM_REG_HRC, divh); + struct rk29_bl_info *rk29_bl_info = bl_get_data(rk29_bl); + int brightness = rk29_bl->props.brightness; + + if (rk29_bl->props.brightness) { + rk29_bl->props.brightness = 0; + rk29_bl_update_status(rk29_bl); + rk29_bl->props.brightness = brightness; + } + if (!suspend_flag) { clk_disable(pwm_clk); if (rk29_bl_info->pwm_suspend) rk29_bl_info->pwm_suspend(); } - - suspend_flag = 1; - del_timer_sync(&rk29_bl_info->timer); -} + suspend_flag = 1; +} static void rk29_bl_resume(struct early_suspend *h) { - struct rk29_bl_info *rk29_bl_info; - // u32 id, brightness; - //u32 div_total, divh; - DBG("%s : %s\n", __FILE__, __FUNCTION__); - rk29_bl_info = rk29_bl->dev.parent->platform_data; - - rk29_bl_info->timer.expires = jiffies + 30; - add_timer(&rk29_bl_info->timer); - #if 0 - id = rk28_bl_info->pwm_id; - brightness = rk28_bl->props.brightness; - - div_total = read_pwm_reg(id, PWM_REG_LRC); - if (rk28_bl_info->bl_ref) { - divh = div_total*(brightness)/BL_STEP; - } else { - divh = div_total*(BL_STEP-brightness)/BL_STEP; - } - //mdelay(100); - write_pwm_reg(id, PWM_REG_HRC, divh); - - suspend_flag = 0; - #endif + struct rk29_bl_info *rk29_bl_info = bl_get_data(rk29_bl); + DBG("%s : %s\n", __FILE__, __FUNCTION__); + + if (rk29_bl_info->pwm_resume) + rk29_bl_info->pwm_resume(); + + clk_enable(pwm_clk); + suspend_flag = 0; + + schedule_delayed_work(&rk29_backlight_work, msecs_to_jiffies(30)); } -static struct early_suspend bl_early_suspend; +static struct early_suspend bl_early_suspend = { + .suspend = rk29_bl_suspend, + .resume = rk29_bl_resume, + .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1, +}; #endif static int rk29_backlight_probe(struct platform_device *pdev) { - int ret = 0; - struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data; - u32 id = rk29_bl_info->pwm_id; - u32 divh, div_total; - - if (rk29_bl) { - DBG(KERN_CRIT "%s: backlight device register has existed \n", - __func__); + int ret = 0; + struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data; + u32 id = rk29_bl_info->pwm_id; + u32 divh, div_total; + unsigned long pwm_clk_rate; + + if (rk29_bl) { + DBG(KERN_CRIT "%s: backlight device register has existed \n", + __func__); return -EEXIST; - } + } - if (rk29_bl_info && rk29_bl_info->io_init) { - rk29_bl_info->io_init(); - } + if (rk29_bl_info && rk29_bl_info->io_init) { + rk29_bl_info->io_init(); + } - rk29_bl = backlight_device_register("rk28_bl", &pdev->dev, NULL, &rk29_bl_ops); + rk29_bl = backlight_device_register("rk28_bl", &pdev->dev, rk29_bl_info, &rk29_bl_ops); if (!rk29_bl) { - DBG(KERN_CRIT "%s: backlight device register error\n", - __func__); + DBG(KERN_CRIT "%s: backlight device register error\n", + __func__); return -ENODEV; } - + pwm_clk = clk_get(NULL, "pwm"); if (IS_ERR(pwm_clk)) { printk(KERN_ERR "failed to get pwm clock source\n"); @@ -221,102 +178,67 @@ static int rk29_backlight_probe(struct platform_device *pdev) pwm_clk_rate = clk_get_rate(pwm_clk); div_total = pwm_clk_rate / PWM_APB_PRE_DIV; - - - div_total >>= (1 + (PWM_DIV >> 9)); - div_total = (div_total) ? div_total : 1; - - /// if(rk29_bl_info->bl_ref) { - /// divh = 0; - /// } else { - divh = div_total / 2; - // } - - /*init timer to dispose workqueue */ - setup_timer(&rk29_bl_info->timer, rk29_delaybacklight_timer, (unsigned long)rk29_bl_info); - - clk_enable(pwm_clk); - write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_RESET); - write_pwm_reg(id, PWM_REG_LRC, div_total); - write_pwm_reg(id, PWM_REG_HRC, divh); - write_pwm_reg(id, PWM_REG_CNTR, 0x0); - write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TIME_EN); - + div_total >>= (1 + (PWM_DIV >> 9)); + div_total = (div_total) ? div_total : 1; + + if(rk29_bl_info->bl_ref) { + divh = 0; + } else { + divh = div_total; + } + + clk_enable(pwm_clk); + write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_RESET); + write_pwm_reg(id, PWM_REG_LRC, div_total); + write_pwm_reg(id, PWM_REG_HRC, divh); + write_pwm_reg(id, PWM_REG_CNTR, 0x0); + write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TIME_EN); + rk29_bl->props.power = FB_BLANK_UNBLANK; rk29_bl->props.fb_blank = FB_BLANK_UNBLANK; rk29_bl->props.max_brightness = BL_STEP; - rk29_bl->props.brightness = rk29_bl_get_brightness(rk29_bl); + rk29_bl->props.brightness = BL_STEP / 2; -#ifdef CONFIG_HAS_EARLYSUSPEND - bl_early_suspend.suspend = rk29_bl_suspend; - bl_early_suspend.resume = rk29_bl_resume; - bl_early_suspend.level = ~0x0; - register_early_suspend(&bl_early_suspend); -#endif + schedule_delayed_work(&rk29_backlight_work, msecs_to_jiffies(30)); + + register_early_suspend(&bl_early_suspend); - printk("RK29 Backlight Driver Initialized.\n"); - return ret; + printk("RK29 Backlight Driver Initialized.\n"); + return ret; } static int rk29_backlight_remove(struct platform_device *pdev) { - struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data; - + struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data; + if (rk29_bl) { backlight_device_unregister(rk29_bl); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&bl_early_suspend); -#endif + unregister_early_suspend(&bl_early_suspend); clk_disable(pwm_clk); clk_put(pwm_clk); - if (rk29_bl_info && rk29_bl_info->io_deinit) { - rk29_bl_info->io_deinit(); - } - return 0; - } else { - DBG(KERN_CRIT "%s: no backlight device has registered\n", - __func__); - return -ENODEV; - } + if (rk29_bl_info && rk29_bl_info->io_deinit) { + rk29_bl_info->io_deinit(); + } + return 0; + } else { + DBG(KERN_CRIT "%s: no backlight device has registered\n", + __func__); + return -ENODEV; + } } + static void rk29_backlight_shutdown(struct platform_device *pdev) { + rk29_bl->props.brightness >>= 1; + rk29_bl_update_status(rk29_bl); + mdelay(100); - u32 divh,div_total; - struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data; - u32 id = rk29_bl_info->pwm_id; - u32 brightness; - brightness = rk29_bl->props.brightness; - brightness/=2; - div_total = read_pwm_reg(id, PWM_REG_LRC); - - if (rk29_bl_info->bl_ref) { - divh = div_total*(brightness)/BL_STEP; - } else { - divh = div_total*(BL_STEP-brightness)/BL_STEP; - } - write_pwm_reg(id, PWM_REG_HRC, divh); - //printk("divh=%d\n",divh); - mdelay(100); - - brightness/=2; - if (rk29_bl_info->bl_ref) { - divh = div_total*(brightness)/BL_STEP; - } else { - divh = div_total*(BL_STEP-brightness)/BL_STEP; - } - - write_pwm_reg(id, PWM_REG_HRC, divh); + rk29_bl->props.brightness >>= 1; + rk29_bl_update_status(rk29_bl); mdelay(100); - /*set PF1=1 PF2=1 for close backlight*/ - - if(rk29_bl_info->bl_ref) { - divh = 0; - } else { - divh = div_total; - } - write_pwm_reg(id, PWM_REG_HRC, divh); - + + rk29_bl->props.brightness = 0; + rk29_bl_update_status(rk29_bl); } static struct platform_driver rk29_backlight_driver = { @@ -326,10 +248,9 @@ static struct platform_driver rk29_backlight_driver = { .name = "rk29_backlight", .owner = THIS_MODULE, }, - .shutdown=rk29_backlight_shutdown, + .shutdown = rk29_backlight_shutdown, }; - static int __init rk29_backlight_init(void) { platform_driver_register(&rk29_backlight_driver);