#define read_pwm_reg(id, addr) __raw_readl(addr+(RK2818_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 backlight_device *rk2818_bl = NULL;
+static struct clk *pwm_clk;
+static unsigned long pwm_clk_rate;
+static struct backlight_device *rk2818_bl;
static int suspend_flag = 0;
#define BACKLIGHT_SEE_MINVALUE 52
.get_brightness = rk2818_bl_get_brightness,
};
-
+#ifdef CONFIG_CPU_FREQ
static int rk2818_bl_change_clk(struct notifier_block *nb, unsigned long val, void *data)
{
struct rk2818_bl_info *rk2818_bl_info;
u32 id;
u32 divl, divh, tmp;
u32 div_total;
- struct clk* pclk;
+ int is_suspended = suspend_flag;
- if (!rk2818_bl)
- {
- DBG(KERN_CRIT "%s: backlight device does not exist \n",
- __func__);
+ if (!rk2818_bl) {
+ DBG(KERN_CRIT "%s: backlight device does not exist\n", __func__);
return -ENODEV;
}
- switch (val)
- {
+ switch (val) {
case CPUFREQ_PRECHANGE:
break;
case CPUFREQ_POSTCHANGE:
+ if (clk_get_rate(pwm_clk) == pwm_clk_rate)
+ break;
+ pwm_clk_rate = clk_get_rate(pwm_clk);
rk2818_bl_info = rk2818_bl->dev.parent->platform_data;
id = rk2818_bl_info->pwm_id;
- pclk = clk_get(NULL, "arm_pclk");
- if (!pclk || IS_ERR(pclk))
- {
- printk(KERN_ERR "%s, %s, failed to get lcd clock source\n",__FILE__, __FUNCTION__);
- return -ENODEV;
- }
+
divl = read_pwm_reg(id, PWM_REG_LRC);
divh = read_pwm_reg(id, PWM_REG_HRC);
- tmp = clk_get_rate(pclk)/PWM_APB_PRE_DIV;
+ tmp = pwm_clk_rate / PWM_APB_PRE_DIV;
tmp >>= (1 + (PWM_DIV >> 9));
- clk_put(pclk);
div_total = (tmp) ? tmp : 1;
tmp = div_total*divh/divl;
+ if (!is_suspended)
+ clk_disable(pwm_clk);
write_pwm_reg(id, PWM_REG_LRC, div_total);
write_pwm_reg(id, PWM_REG_HRC, tmp);
write_pwm_reg(id, PWM_REG_CNTR, 0);
+ if (!is_suspended)
+ clk_enable(pwm_clk);
break;
}
return 0;
}
+#endif
static void rk2818_delaybacklight_timer(unsigned long data)
{
struct rk2818_bl_info *rk2818_bl_info = (struct rk2818_bl_info *)data;
u32 id, brightness;
u32 div_total, divh;
+ clk_enable(pwm_clk);
id = rk2818_bl_info->pwm_id;
brightness = rk2818_bl->props.brightness;
div_total = read_pwm_reg(id, PWM_REG_LRC);
DBG("%s: ========== suspend =============== \n",__func__);
write_pwm_reg(id, PWM_REG_HRC, divh);
+ clk_disable(pwm_clk);
suspend_flag = 1;
struct rk2818_bl_info *rk2818_bl_info = pdev->dev.platform_data;
u32 id = rk2818_bl_info->pwm_id;
u32 divh, div_total;
- struct clk* arm_pclk;
DBG("%s::=======================================\n",__func__);
return -ENODEV;
}
- arm_pclk = clk_get(NULL, "arm_pclk");
- if (!arm_pclk || IS_ERR(arm_pclk))
- {
- printk(KERN_ERR "failed to get lcd clock source\n");
+ if (!pwm_clk)
+ pwm_clk = clk_get(NULL, "pwm");
+ if (!pwm_clk || IS_ERR(pwm_clk)) {
+ printk(KERN_ERR "failed to get pwm clock source\n");
return -ENODEV;
}
- div_total = clk_get_rate(arm_pclk)/PWM_APB_PRE_DIV;
+ pwm_clk_rate = clk_get_rate(pwm_clk);
+ div_total = pwm_clk_rate / PWM_APB_PRE_DIV;
- clk_put(arm_pclk);
div_total >>= (1 + (PWM_DIV >> 9));
div_total = (div_total) ? div_total : 1;
/*init timer to dispose workqueue */
setup_timer(&rk2818_bl_info->timer, rk2818_delaybacklight_timer, (unsigned long)rk2818_bl_info);
+#ifdef CONFIG_CPU_FREQ
rk2818_bl_info->freq_transition.notifier_call = rk2818_bl_change_clk;
cpufreq_register_notifier(&rk2818_bl_info->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+// clk_disable(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);
+ clk_enable(pwm_clk);
rk2818_bl->props.power = FB_BLANK_UNBLANK;
rk2818_bl->props.fb_blank = FB_BLANK_UNBLANK;
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&bl_early_suspend);
#endif
+#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier(&rk2818_bl_info->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+ clk_disable(pwm_clk);
+ clk_put(pwm_clk);
if (rk2818_bl_info && rk2818_bl_info->io_deinit) {
rk2818_bl_info->io_deinit();
}