From c2020ab7d69a7398afa4652271e88523afc78416 Mon Sep 17 00:00:00 2001 From: yxj Date: Mon, 8 Apr 2013 14:30:48 +0800 Subject: [PATCH] rk616:add more control register defination --- drivers/mfd/rk616-core.c | 38 +++++- .../video/display/transmitter/rk616_lvds.c | 56 +++++++- include/linux/mfd/rk616.h | 120 +++++++++++++++++- 3 files changed, 204 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/rk616-core.c b/drivers/mfd/rk616-core.c index 5848bee62ce6..395383c9c7ec 100644 --- a/drivers/mfd/rk616-core.c +++ b/drivers/mfd/rk616-core.c @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include static struct mfd_cell rk616_devs[] = { @@ -85,11 +88,17 @@ static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval) return (ret == 1) ? 4 : ret; } + +static int rk616_clk_route_init(struct mfd_rk616 *rk616) +{ + + return 0; +} static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) { int ret; struct mfd_rk616 *rk616 = NULL; - + struct clk *iis_clk; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { @@ -111,14 +120,37 @@ static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id if(rk616->pdata->power_init) rk616->pdata->power_init(); - + +#if defined(CONFIG_SND_RK29_SOC_I2S_8CH) + iis_clk = clk_get_sys("rk29_i2s.0", "i2s"); +#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH) + iis_clk = clk_get_sys("rk29_i2s.1", "i2s"); +#else + iis_clk = clk_get_sys("rk29_i2s.2", "i2s"); +#endif + if (IS_ERR(iis_clk)) + { + dev_err(&client->dev,"failed to get i2s clk\n"); + ret = PTR_ERR(iis_clk); + } + else + { + #if defined(CONFIG_ARCH_RK29) + rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK); + #else + iomux_set(I2S0_CLK); + #endif + clk_enable(iis_clk); + clk_set_rate(iis_clk, 11289600); + clk_put(iis_clk); + } rk616->read_dev = rk616_i2c_read_reg; rk616->write_dev = rk616_i2c_write_reg; ret = mfd_add_devices(rk616->dev, -1, rk616_devs, ARRAY_SIZE(rk616_devs), NULL, rk616->irq_base); - printk("%s.........\n",__func__); + dev_info(&client->dev,"rk616 core probe success!\n"); return 0; } diff --git a/drivers/video/display/transmitter/rk616_lvds.c b/drivers/video/display/transmitter/rk616_lvds.c index d7e2fb53581b..5de44dd9dbb3 100644 --- a/drivers/video/display/transmitter/rk616_lvds.c +++ b/drivers/video/display/transmitter/rk616_lvds.c @@ -8,6 +8,23 @@ struct mfd_rk616 *g_rk616; +/******************************************** +LCDC1------>HDMI +LCDC0------>Dither------->LVDS/MIPI +*********************************************/ +static struct rk616_route rk616_route = { + .vif0_bypass = 1, + .vif0_en = 0, + .vif1_bypass = 1, + .vif1_en = 0, + .sclin_sel = 0, + .scl_en = 0, + .dither_sel = 0, + .hdmi_sel = 0, + .lcd1_input = 1, + .lvds_mode = 1, //lvds out put +}; + /*rk616 video interface config*/ static int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id) { @@ -55,7 +72,7 @@ static int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id) } -static int rk616_vif_bypass(struct mfd_rk616 *rk616,int id) +static int rk616_vif_disable(struct mfd_rk616 *rk616,int id) { int ret; u32 val = 0; @@ -74,7 +91,7 @@ static int rk616_vif_bypass(struct mfd_rk616 *rk616,int id) return ret; } -static int rk616_scaler_bypass(struct mfd_rk616 *rk616) +static int rk616_scaler_disable(struct mfd_rk616 *rk616) { u32 val = 0; int ret; @@ -87,6 +104,34 @@ static int rk616_scaler_bypass(struct mfd_rk616 *rk616) } + +static int rk616_display_router_cfg(struct mfd_rk616 *rk616) +{ + u32 val = 0; + int ret; + struct rk616_route *route = rk616->route; + + val = (0xffff<<16) | (route->sclin_sel<<15) | (route->dither_sel<<14) | + (route->hdmi_sel<<12) | (route->vif1_bypass<<7) | + (route->vif0_bypass<<1) ; + ret = rk616->write_dev(rk616,CRU_CLKSE2_CON,&val); + + val = 0; + val = (LVDS_CH0TTL_DISABLE) | (LVDS_CH1TTL_DISABLE) | (LVDS_CH0_PWR_EN) | + (LVDS_CBG_PWR_EN) | (LVDS_CH0TTL_DISABLE << 16) | (LVDS_CH1TTL_DISABLE << 16) | + (LVDS_CH0_PWR_EN << 16) | (LVDS_CBG_PWR_EN << 16); + ret = rk616->write_dev(rk616,CRU_LVDS_CON0,&val); + + if(!route->vif0_en) + rk616_vif_disable(rk616,0); //disable vif0 + if(!route->vif1_en) + rk616_vif_disable(rk616,1); //disable vif1 + if(!route->scl_en) + rk616_scaler_disable(rk616); + + return 0; + +} int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale { int ret; @@ -96,10 +141,7 @@ int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass printk(KERN_ERR "%s:mfd rk616 is null!\n",__func__); return -1; } - rk616_vif_bypass(rk616,0); - rk616_vif_bypass(rk616,1); - rk616_scaler_bypass(rk616); - + rk616_display_router_cfg(rk616); return ret; } @@ -114,6 +156,8 @@ static int rk616_lvds_probe(struct platform_device *pdev) } else g_rk616 = rk616; + + rk616->route = &rk616_route; dev_info(&pdev->dev,"rk616 lvds probe success!\n"); diff --git a/include/linux/mfd/rk616.h b/include/linux/mfd/rk616.h index 2f160784d087..fad5fd2000af 100644 --- a/include/linux/mfd/rk616.h +++ b/include/linux/mfd/rk616.h @@ -34,20 +34,122 @@ #define SCL_REG7 0x004C #define SCL_REG8 0x0050 #define FRC_REG 0x0054 + #define CRU_CLKSEL0_CON 0x0058 +#define PLL1_IN_SEL(x) (((x)&3)<<8) +#define PLL0_IN_SEL(x) (((x)&3)<<6) +#define LCD1_CLK_DIV(x) (((x)&7)<<3) +#define LCD0_CLK_DIV(x) (((x)&7)<<0) + #define CRU_CLKSEL1_CON 0x005C +#define LCDC_CLK_GATE (1<<12) +#define LCDC1_CLK_GATE (1<<11) +#define MIPI_CLK_GATE (1<<10) +#define LVDS_CLK_GATE (1<<9) +#define HDMI_CLK_GATE (1<<8) +#define SCL_CLK_DIV (((x)&7)<<5) +#define SCL_CLK_GATE (1<<4) +#define SCL_CLK_IN_SEL (1<<3) +#define CODEC_CLK_GATE (1<<2) +#define CODEC_CLK_IN_SEL(x) (((x)&3)<<0) #define CRU_CODEC_DIV 0x0060 + #define CRU_CLKSE2_CON 0x0064 +#define SCLIN_CLK_SEL (1<<15) +#define DITHER_CLK_SEL (1<<14) +#define HDMI_CLK_SEL(x) (((x)&3)<<12) +#define VIF1_CLK_DIV(x) (((x)&7)<<9) +#define VIF1_CLK_GATE (1<<8) +#define VIF1_CLK_BYPASS (1<<7) +#define VIF1_CLK_SEL (1<<6) +#define VIF0_CLK_DIV(x) (((x)&7)<<3) +#define VIF0_CLK_GATE (1<<2) +#define VIF0_CLK_BYPASS (1<<1) +#define VIF0_CLK_SEL (1<<0) + #define CRU_PLL0_CON0 0x0068 +#define PLL0_BYPASS (1<<15) +#define PLL0_POSTDIV1(x) (((x)&7)<<12) +#define PLL0_FBDIV(x) (((x)&0xfff)<<0) + #define CRU_PLL0_CON1 0x006C +#define PLL0_PWR_DN (1<<10) +#define PLL0_DIV_MODE (1<<9) +#define PLL0_POSTDIV2(x)(((x)&7)<<6) +#define PLL0_REFDIV(x) (((x)&0x3f)<<0) + #define CRU_PLL0_CON2 0x0070 +#define PLL0_FOUT4_PWR_DN (1<<27) +#define PLL0_FOUTVCO_PWR_DN (1<<26) +#define PLL0_POSTDIV_PWR_DN (1<<25) +#define PLL0_DAC_PWR_DN (1<<24) +#define PLL0_FRAC(x) (((x)&0xffffff)<0) + #define CRU_PLL1_CON0 0x0074 +#define PLL1_BYPASS (1<<15) +#define PLL1_POSTDIV1(x) (((x)&7)<<12) +#define PLL1_FBDIV(x) (((x)&0xfff)<<0) + #define CRU_PLL1_CON1 0x0078 +#define PLL1_PWR_DN (1<<10) +#define PLL1_DIV_MODE (1<<9) +#define PLL1_POSTDIV2(x)(((x)&7)<<6) +#define PLL1_REFDIV(x) (((x)&0x3f)<<0) + #define CRU_PLL1_CON2 0x007C +#define PLL1_FOUT4_PWR_DN (1<<27) +#define PLL1_FOUTVCO_PWR_DN (1<<26) +#define PLL1_POSTDIV_PWR_DN (1<<25) +#define PLL1_DAC_PWR_DN (1<<24) +#define PLL1_FRAC(x) (((x)&0xffffff)<0) + #define CRU_I2C_CON0 0x0080 + #define CRU_LVDS_CON0 0x0084 +#define LVDS_CON_ST_PHASE (1<<14) +#define LVDS_DCLK_INV (1<<13) +#define LVDS_CH1_LOAD (1<<12) +#define LVDS_CH0_LOAD (1<<11) +#define LVDS_CH1TTL_DISABLE (1<<10) +#define LVDS_CH0TTL_DISABLE (1<<9) +#define LVDS_CH1_PWR_EN (1<<8) +#define LVDS_CH0_PWR_EN (1<<7) +#define LVDS_CBG_PWR_EN (1<<6) +#define LVDS_PLL_PWR_DN (1<<5) +#define LVDS_START_CH_SEL (1<<4) +#define LVDS_CH_SEL (1<<3) +#define LVDS_MSB_SEL (1<<2) +#define LVDS_OUT_FORMAT (1<<0) + + #define CRU_IO_CON0 0x0088 -#define CRU_IO_CON1 0x008C +#define I2S1_OUT_EN (1<<13) +#define I2S0_OUT_EN (1<<12) +#define LVDS_OUT_EN (1<<11) +#define LCD1_INPUT_EN (1<<10) +#define LVDS_RGBIO_PD_DISABLE (1<<9) +#define LCD1_IO_PD_DISABLE (1<<8) +#define LCD0_IO_PD_DISABLE (1<<7) +#define HDMI_IO_PU_DISABLE (1<<6) +#define SPDIF_IO_PD_DISABLE (1<<5) +#define I2S1_PD_DISABLE (1<<4) +#define I2S0_PD_DISABLE (1<<3) +#define I2C_PU_DISABLE (1<<2) +#define INT_IO_PU (1<<1) +#define CLKIN_PU (1<<0) + + +#define CRU_IO_CON1 0x008C +#define LVDS_RGBIO_SI_EN (1<<9) //shmitt input enable +#define LCD1_SI_EN (1<<8) +#define LCD0_SI_EN (1<<7) +#define HDMI_SI_EN (1<<6) +#define SPDIF_SI_EN (1<<5) +#define I2S1_SI_EN (1<<4) +#define I2S0_SI_EN (1<<3) +#define I2C_SI_EN (1<<2) +#define INT_SI_EN (1<<1) +#define CLKIN_SI_EN (1<<0) #define CRU_PCM2IS2_CON0 0x0090 #define CRU_PCM2IS2_CON1 0x0094 #define CRU_PCM2IS2_CON2 0x0098 @@ -71,15 +173,31 @@ struct rk616_platform_data { int (*power_init)(void); int scl_rate; }; + +struct rk616_route { + u8 vif0_bypass; + u8 vif0_en; + u8 vif1_bypass; + u8 vif1_en; + u8 sclin_sel; + u8 scl_en; + u8 dither_sel; + u8 hdmi_sel; + u8 lcd1_input; + u8 lvds_mode; //RGB or LVDS +}; + struct mfd_rk616 { struct mutex reg_lock; struct device *dev; unsigned int irq_base; struct rk616_platform_data *pdata; + struct rk616_route *route; //display path router struct i2c_client *client; int (*read_dev)(struct mfd_rk616 *rk616, u16 reg,u32 *pval); int (*write_dev)(struct mfd_rk616 *rk616,u16 reg,u32 *pval); }; + #endif -- 2.34.1