From b972d847215973e95b2c32558da3fb1aa315c5ce Mon Sep 17 00:00:00 2001 From: lw Date: Mon, 20 Feb 2012 15:02:52 +0800 Subject: [PATCH] rk30:add rk30 backlight support --- arch/arm/mach-rk30/devices.c | 101 +++++++++++++++++++++++ arch/arm/mach-rk30/include/mach/board.h | 12 +++ drivers/video/backlight/Kconfig | 4 +- drivers/video/backlight/rk29_backlight.c | 20 +++-- 4 files changed, 128 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index ac3be39e6c32..9730873aecaa 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -670,6 +670,103 @@ static void __init rk30_init_spim(void) } +/*********************************************************** +* rk30 backlight +************************************************************/ +#ifdef CONFIG_BACKLIGHT_RK29_BL +#define PWM_ID 0 +#define PWM_MUX_NAME GPIO0A3_PWM0_NAME +#define PWM_MUX_MODE GPIO0A_PWM0 +#define PWM_MUX_MODE_GPIO GPIO0A_GPIO0A3 +#define PWM_GPIO RK30_PIN0_PA3 +#define PWM_EFFECT_VALUE 1 + +#define LCD_DISP_ON_PIN + +#ifdef LCD_DISP_ON_PIN +//#define BL_EN_MUX_NAME GPIOF34_UART3_SEL_NAME +//#define BL_EN_MUX_MODE IOMUXB_GPIO1_B34 + +#define BL_EN_PIN INVALID_GPIO //? +#define BL_EN_VALUE GPIO_HIGH +#endif +static int rk29_backlight_io_init(void) +{ + int ret = 0; + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); +#ifdef LCD_DISP_ON_PIN + // rk30_mux_api_set(BL_EN_MUX_NAME, BL_EN_MUX_MODE); + + ret = gpio_request(BL_EN_PIN, NULL); + if(ret != 0) + { + gpio_free(BL_EN_PIN); + } + + gpio_direction_output(BL_EN_PIN, 0); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); +#endif + return ret; +} + +static int rk29_backlight_io_deinit(void) +{ + int ret = 0; +#ifdef LCD_DISP_ON_PIN + gpio_free(BL_EN_PIN); +#endif + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + return ret; +} + +static int rk29_backlight_pwm_suspend(void) +{ + int ret = 0; + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE_GPIO); + if (gpio_request(PWM_GPIO, NULL)) { + printk("func %s, line %d: request gpio fail\n", __FUNCTION__, __LINE__); + return -1; + } + gpio_direction_output(PWM_GPIO, GPIO_LOW); +#ifdef LCD_DISP_ON_PIN + gpio_direction_output(BL_EN_PIN, 0); + gpio_set_value(BL_EN_PIN, !BL_EN_VALUE); +#endif + return ret; +} + +static int rk29_backlight_pwm_resume(void) +{ + gpio_free(PWM_GPIO); + rk30_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE); +#ifdef LCD_DISP_ON_PIN + msleep(30); + gpio_direction_output(BL_EN_PIN, 1); + gpio_set_value(BL_EN_PIN, BL_EN_VALUE); +#endif + return 0; +} + +struct rk29_bl_info rk29_bl_info = { + .pwm_id = PWM_ID, + .bl_ref = PWM_EFFECT_VALUE, + .io_init = rk29_backlight_io_init, + .io_deinit = rk29_backlight_io_deinit, + .pwm_suspend = rk29_backlight_pwm_suspend, + .pwm_resume = rk29_backlight_pwm_resume, +}; + + +struct platform_device rk29_device_backlight = { + .name = "rk29_backlight", + .id = -1, + .dev = { + .platform_data = &rk29_bl_info, + } +}; + +#endif + #ifdef CONFIG_MTD_NAND_RK29XX static struct resource resources_nand[] = { { @@ -704,6 +801,10 @@ static int __init rk30_init_devices(void) rk30_init_uart(); rk30_init_i2c(); rk30_init_spim(); + +#ifdef CONFIG_BACKLIGHT_RK29_BL + platform_device_register(&rk29_device_backlight); +#endif #ifdef CONFIG_MTD_NAND_RK29XX platform_device_register(&device_nand); #endif diff --git a/arch/arm/mach-rk30/include/mach/board.h b/arch/arm/mach-rk30/include/mach/board.h index 58fc85d14599..b670605e9085 100644 --- a/arch/arm/mach-rk30/include/mach/board.h +++ b/arch/arm/mach-rk30/include/mach/board.h @@ -36,5 +36,17 @@ struct rk29xx_spi_platform_data { u16 num_chipselect; }; +struct rk29_bl_info{ + u32 pwm_id; + u32 bl_ref; + int (*io_init)(void); + int (*io_deinit)(void); + int (*pwm_suspend)(void); + int (*pwm_resume)(void); + int min_brightness; /* 0 ~ 255 */ + unsigned int delay_ms; /* in milliseconds */ +}; + + #endif diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 985d680e5bfc..235dbfd62eb4 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -298,8 +298,8 @@ config BACKLIGHT_RK2818_BL rk2818 backlight support. config BACKLIGHT_RK29_BL - bool "rk29 backlight driver" - depends on BACKLIGHT_CLASS_DEVICE && ARCH_RK29 + bool "rk backlight driver" + depends on BACKLIGHT_CLASS_DEVICE && (ARCH_RK29 || ARCH_RK30) default y help rk29 backlight support. diff --git a/drivers/video/backlight/rk29_backlight.c b/drivers/video/backlight/rk29_backlight.c index f9a3eec2d558..6cd9df330b05 100755 --- a/drivers/video/backlight/rk29_backlight.c +++ b/drivers/video/backlight/rk29_backlight.c @@ -25,7 +25,6 @@ #include #include -#include #include #include "rk2818_backlight.h" @@ -39,9 +38,15 @@ #define DBG(x...) #endif - +#if defined(CONFIG_ARCH_RK30) +#include +#define write_pwm_reg(id, addr, val) __raw_writel(val, addr+(RK30_PWM01_BASE+(id>>1)*0x20000)+id*10) +#define read_pwm_reg(id, addr) __raw_readl(addr+(RK30_PWM01_BASE+(id>>1)*0x20000+id*0x10)) +#else defined(CONFIG_ARCH_RK29) +#include #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)) +#endif static struct clk *pwm_clk; static struct backlight_device *rk29_bl; @@ -145,7 +150,7 @@ static struct early_suspend bl_early_suspend = { .resume = rk29_bl_resume, .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1, }; -#endif + void rk29_backlight_set(bool on) { printk("%s: set %d\n", __func__, on); @@ -156,6 +161,7 @@ void rk29_backlight_set(bool on) return; } EXPORT_SYMBOL(rk29_backlight_set); +#endif static int rk29_backlight_probe(struct platform_device *pdev) { @@ -167,7 +173,7 @@ static int rk29_backlight_probe(struct platform_device *pdev) struct backlight_properties props; if (rk29_bl) { - DBG(KERN_CRIT "%s: backlight device register has existed \n", + printk(KERN_CRIT "%s: backlight device register has existed \n", __func__); return -EEXIST; } @@ -187,7 +193,7 @@ static int rk29_backlight_probe(struct platform_device *pdev) props.max_brightness = BL_STEP; rk29_bl = backlight_device_register("rk28_bl", &pdev->dev, rk29_bl_info, &rk29_bl_ops, &props); if (!rk29_bl) { - DBG(KERN_CRIT "%s: backlight device register error\n", + printk(KERN_CRIT "%s: backlight device register error\n", __func__); return -ENODEV; } @@ -195,7 +201,7 @@ static int rk29_backlight_probe(struct platform_device *pdev) pwm_clk = clk_get(NULL, "pwm"); if (IS_ERR(pwm_clk)) { printk(KERN_ERR "failed to get pwm clock source\n"); - return -ENODEV; + //return -ENODEV; } pwm_clk_rate = clk_get_rate(pwm_clk); div_total = pwm_clk_rate / PWM_APB_PRE_DIV; @@ -215,7 +221,7 @@ static int rk29_backlight_probe(struct platform_device *pdev) 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.brightness = BL_STEP / 2; -- 2.34.1