rk30:add rk30 backlight support

This commit is contained in:
lw 2012-02-20 15:02:52 +08:00
commit b972d84721
4 changed files with 128 additions and 9 deletions

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -25,7 +25,6 @@
#include <linux/earlysuspend.h>
#include <asm/io.h>
#include <mach/rk29_iomap.h>
#include <mach/board.h>
#include "rk2818_backlight.h"
@ -39,9 +38,15 @@
#define DBG(x...)
#endif
#if defined(CONFIG_ARCH_RK30)
#include <mach/io.h>
#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 <mach/rk29_iomap.h>
#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;