mfd:rk616: vif:add sync mode

core:add write_dev_bits interface
This commit is contained in:
yxj
2013-06-28 12:10:48 +08:00
parent fa87607483
commit 304e07b32c
3 changed files with 73 additions and 11 deletions

View File

@@ -94,6 +94,40 @@ static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
}
static int rk616_i2c_write_bits(struct mfd_rk616 *rk616, u16 reg,u32 mask,u32 *pval)
{
struct i2c_client *client = rk616->client;
struct i2c_adapter *adap = client->adapter;
struct i2c_msg msg;
int ret;
u32 reg_val;
char *tx_buf = NULL;
mutex_lock(&rk616->reg_lock);
tx_buf = (char *)kmalloc(6, GFP_KERNEL);
if(!tx_buf)
return -ENOMEM;
rk616->read_dev(rk616,reg,&reg_val);
reg_val &= ~mask;
reg_val |= *pval;
*pval = reg_val;
memcpy(tx_buf, &reg, 2);
memcpy(tx_buf+2, (char *)pval, 4);
msg.addr = client->addr;
msg.flags = client->flags;
msg.len = 6;
msg.buf = (char *)tx_buf;
msg.scl_rate = rk616->pdata->scl_rate;
msg.udelay = client->udelay;
ret = i2c_transfer(adap, &msg, 1);
kfree(tx_buf);
mutex_unlock(&rk616->reg_lock);
return (ret == 1) ? 4 : ret;
}
#if defined(CONFIG_DEBUG_FS)
static int rk616_reg_show(struct seq_file *s, void *v)
{
@@ -444,12 +478,14 @@ static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id
//clk_put(iis_clk);
}
mutex_init(&rk616->reg_lock);
if(rk616->pdata->power_init)
rk616->pdata->power_init();
rk616->read_dev = rk616_i2c_read_reg;
rk616->write_dev = rk616_i2c_write_reg;
rk616->write_dev_bits = rk616_i2c_write_bits;
#if defined(CONFIG_DEBUG_FS)
rk616->debugfs_dir = debugfs_create_dir("rk616", NULL);

View File

@@ -203,6 +203,7 @@ int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id)
}
ret = rk616->write_dev(rk616,VIF0_REG1 + offset,&val);
val = (screen->hsync_len << 16) | (screen->hsync_len + screen->left_margin +
@@ -223,6 +224,16 @@ int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id)
(screen->vsync_len + screen->upper_margin);
ret = rk616->write_dev(rk616,VIF0_REG5 + offset,&val);
if(id == 0)
{
val = VIF0_SYNC_EN | (VIF0_SYNC_EN << 16);
rk616->write_dev(rk616,CRU_IO_CON0,&val);
}
else
{
val = VIF1_SYNC_EN | (VIF1_SYNC_EN << 16);
rk616->write_dev(rk616,CRU_IO_CON0,&val);
}
rk616_vif_enable(rk616,id);
return ret;
@@ -436,7 +447,8 @@ static int rk616_dual_input_cfg(struct mfd_rk616 *rk616,rk_screen *screen,
route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
route->pll1_clk_sel = PLL1_CLK_SEL(LCD1_DCLK);
route->vif1_clk_sel = VIF1_CLKIN_SEL(VIF_CLKIN_SEL_PLL1);
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF1);
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF1);
route->hdmi_clk_sel = HDMI_CLK_SEL(HDMI_CLK_SEL_VIF1);
if(enable) //hdmi plug in
{
route->vif1_bypass = 0;
@@ -491,8 +503,8 @@ static int rk616_lcd0_input_lcd1_unused_cfg(struct mfd_rk616 *rk616,rk_screen *s
route->scl_en = 1;
route->sclk_sel = SCLK_SEL(SCLK_SEL_PLL1);
route->dither_sel = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF0);//from vif0
route->hdmi_clk_sel = HDMI_CLK_SEL(HDMI_CLK_SEL_VIF0);
}
else
{
@@ -501,7 +513,7 @@ static int rk616_lcd0_input_lcd1_unused_cfg(struct mfd_rk616 *rk616,rk_screen *s
route->sclin_sel = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
route->scl_en = 0;
route->dither_sel = DITHER_IN_SEL(DITHER_SEL_VIF0); //dither from sclaer
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF0);//from vif0
}
route->pll1_clk_sel = PLL1_CLK_SEL(LCD0_DCLK);
route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
@@ -544,7 +556,8 @@ static int rk616_lcd0_input_lcd1_output_cfg(struct mfd_rk616 *rk616,rk_screen *s
route->scl_en = 1;
route->sclk_sel = SCLK_SEL(SCLK_SEL_PLL1);
route->dither_sel = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF0);//from vif0
route->hdmi_clk_sel = HDMI_CLK_SEL(HDMI_CLK_SEL_VIF0);
}
else
{
@@ -553,7 +566,8 @@ static int rk616_lcd0_input_lcd1_output_cfg(struct mfd_rk616 *rk616,rk_screen *s
route->sclin_sel = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
route->scl_en = 0;
route->dither_sel = DITHER_IN_SEL(DITHER_SEL_VIF0); //dither from sclaer
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF0);//from vif0
route->hdmi_clk_sel = HDMI_CLK_SEL(HDMI_CLK_SEL_VIF1);
}
route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
route->pll1_clk_sel = PLL1_CLK_SEL(LCD0_DCLK);
@@ -598,7 +612,8 @@ static int rk616_lcd0_unused_lcd1_input_cfg(struct mfd_rk616 *rk616,rk_screen *s
route->sclk_sel = SCLK_SEL(SCLK_SEL_PLL0);
route->dither_sel = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
route->hdmi_sel = HDMI_IN_SEL(HDMI_CLK_SEL_VIF1); //from vif1
route->hdmi_sel = HDMI_IN_SEL(HDMI_IN_SEL_VIF1); //from vif1
route->hdmi_clk_sel = HDMI_CLK_SEL(HDMI_CLK_SEL_VIF1);
route->lcd1_input = 1;
if(screen->type == SCREEN_RGB)
{
@@ -687,6 +702,8 @@ static int rk616_router_cfg(struct mfd_rk616 *rk616)
(route->hdmi_sel) | (route->vif1_bypass) | (route->vif0_bypass) |
(route->vif1_clk_sel)| (route->vif0_clk_sel);
ret = rk616->write_dev(rk616,CRU_CLKSEL2_CON,&val);
val = route->hdmi_clk_sel;
ret = rk616->write_dev_bits(rk616,CRU_CFGMISC_CON,HDMI_CLK_SEL_MASK,&val);
return ret;
}

View File

@@ -100,10 +100,10 @@
#define DITHER_SEL_VIF0 0
#define DITHER_SEL_SCL 1
#define HDMI_IN_SEL(x) (((x)&3)<<12)
#define HDMI_CLK_SEL_VIF1 0
#define HDMI_CLK_SEL_SCL 1
#define HDMI_CLK_SEL_VIF0 2
#define HDMI_IN_SEL(x) (((x)&3)<<12) //hdmi data in select
#define HDMI_IN_SEL_VIF1 0
#define HDMI_IN_SEL_SCL 1
#define HDMI_IN_SEL_VIF0 2
#define VIF1_CLK_DIV(x) (((x)&7)<<9)
#define VIF1_CLK_GATE (1<<8)
#define VIF1_CLK_BYPASS (1<<7)
@@ -185,6 +185,8 @@
#define CRU_IO_CON0 0x0088
#define VIF1_SYNC_EN (1<<15)
#define VIF0_SYNC_EN (1<<14)
#define I2S1_OUT_DISABLE (1<<13)
#define I2S0_OUT_DISABLE (1<<12)
#define LVDS_OUT_EN (1<<11)
@@ -216,6 +218,11 @@
#define CRU_PCM2IS2_CON1 0x0094
#define CRU_PCM2IS2_CON2 0x0098
#define CRU_CFGMISC_CON 0x009C
#define HDMI_CLK_SEL_MASK (3<<12)
#define HDMI_CLK_SEL(x) (((x)&3)<<12) //hdmi data in select
#define HDMI_CLK_SEL_VIF1 0
#define HDMI_CLK_SEL_SCL 1
#define HDMI_CLK_SEL_VIF0 2
enum lcd_port_func{ // the function of lcd ports(lcd0,lcd1),the lcd0 only can be used as input or unused
@@ -252,6 +259,7 @@ struct rk616_route {
u8 scl_bypass;
u16 dither_sel;
u16 hdmi_sel;
u16 hdmi_clk_sel;
u16 pll0_clk_sel;
u16 pll1_clk_sel;
u16 sclk_sel;
@@ -275,6 +283,7 @@ struct mfd_rk616 {
struct dentry *debugfs_dir;
int (*read_dev)(struct mfd_rk616 *rk616,u16 reg,u32 *pval);
int (*write_dev)(struct mfd_rk616 *rk616,u16 reg,u32 *pval);
int (*write_dev_bits)(struct mfd_rk616 *rk616,u16 reg,u32 mask,u32 *pval);
};
extern int rk616_set_vif(struct mfd_rk616 * rk616,rk_screen * screen,bool connect);