}
+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,®_val);
+ reg_val &= ~mask;
+ reg_val |= *pval;
+ *pval = reg_val;
+ memcpy(tx_buf, ®, 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)
{
//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);
}
+
ret = rk616->write_dev(rk616,VIF0_REG1 + offset,&val);
val = (screen->hsync_len << 16) | (screen->hsync_len + screen->left_margin +
(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;
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;
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
{
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);
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
{
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);
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)
{
(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;
}
#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)
#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)
#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
u8 scl_bypass;
u16 dither_sel;
u16 hdmi_sel;
+ u16 hdmi_clk_sel;
u16 pll0_clk_sel;
u16 pll1_clk_sel;
u16 sclk_sel;
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);