#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/mfd/rk616.h>
+#include <linux/clk.h>
+#include <mach/iomux.h>
+#include <linux/err.h>
static struct mfd_cell rk616_devs[] = {
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))
{
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;
}
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)
{
}
-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;
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;
}
+
+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;
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;
}
}
else
g_rk616 = rk616;
+
+ rk616->route = &rk616_route;
dev_info(&pdev->dev,"rk616 lvds probe success!\n");
#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
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