diff options
author | yxj <yxj@rock-chips.com> | 2013-04-10 12:22:54 +0800 |
---|---|---|
committer | yxj <yxj@rock-chips.com> | 2013-04-10 12:23:19 +0800 |
commit | 2657d433ee87d7a954da266ed79661e05d58354b (patch) | |
tree | 4457dd0835e5f66f3f9b211548f676832e86f99b /drivers/mfd/rk616-core.c | |
parent | 16c8142b0b60f7f5191ac01e779e8ac19e45b49e (diff) |
mfd:rk616:add clk common init,add debug interface
Diffstat (limited to 'drivers/mfd/rk616-core.c')
-rw-r--r-- | drivers/mfd/rk616-core.c | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/drivers/mfd/rk616-core.c b/drivers/mfd/rk616-core.c index 395383c9c7ec..81a0c7fde72c 100644 --- a/drivers/mfd/rk616-core.c +++ b/drivers/mfd/rk616-core.c @@ -4,11 +4,16 @@ #include <linux/delay.h> #include <linux/mfd/core.h> #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> +#include <linux/uaccess.h> +#if defined(CONFIG_DEBUG_FS) +#include <linux/fs.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#endif static struct mfd_cell rk616_devs[] = { @@ -89,8 +94,85 @@ static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval) } -static int rk616_clk_route_init(struct mfd_rk616 *rk616) +#if defined(CONFIG_DEBUG_FS) +static int rk616_reg_show(struct seq_file *s, void *v) { + int i = 0; + u32 val = 0; + struct mfd_rk616 *rk616 = s->private; + if(!rk616) + { + dev_err(rk616->dev,"no mfd rk616!\n"); + return 0; + } + + for(i=0;i<= CRU_CFGMISC_CON;i+=4) + { + rk616->read_dev(rk616,i,&val); + seq_printf(s,"0x%04x>>0x%08x\n",i,val); + } + + return 0; +} + +static ssize_t rk616_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private; + u32 reg; + u32 val; + char kbuf[25]; + if (copy_from_user(kbuf, buf, count)) + return -EFAULT; + sscanf(kbuf, "%x%x", ®,&val); + dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg,val); + rk616->write_dev(rk616,reg,&val); + return count; +} + +static int rk616_reg_open(struct inode *inode, struct file *file) +{ + struct mfd_rk616 *rk616 = inode->i_private; + return single_open(file,rk616_reg_show,rk616); +} + +static const struct file_operations rk616_reg_fops = { + .owner = THIS_MODULE, + .open = rk616_reg_open, + .read = seq_read, + .write = rk616_reg_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +/*********************************** +default clk patch settiing: +CLKIN-------->CODEC +LCD_DCLK0--->PLL0--->Dither--->LVDS/MIPI +LCD_DCLK1--->PLL1--->HDMI +************************************/ + +static int rk616_clk_common_init(struct mfd_rk616 *rk616) +{ + u32 val = 0; + int ret; + + val = PLL1_CLK_SEL(1) | PLL0_CLK_SEL(0) | LCD1_CLK_DIV(0) | LCD0_CLK_DIV(0) | + PLL1_CLK_SEL_MASK | PLL0_CLK_SEL_MASK | LCD1_CLK_DIV_MASK | + LCD0_CLK_DIV_MASK; //pll1 clk from lcdc1_dclk,pll0 clk from lcdc0_dclk,mux_lcdx = lcdx_clk + ret = rk616->write_dev(rk616,CRU_CLKSEL0_CON,&val); + + val = CODEC_MCLK_SEL(2) | CODEC_MCLK_SEL_MASK; //codec mclk from clkin + ret = rk616->write_dev(rk616,CRU_CLKSEL1_CON,&val); + + val = 0; //codec mck = clkin + ret = rk616->write_dev(rk616,CRU_CODEC_DIV,&val); + + val = (PLL0_BYPASS) | (PLL0_BYPASS << 16); //bypass pll0 + ret = rk616->write_dev(rk616,CRU_PLL0_CON0,&val); + + val = (PLL1_BYPASS) | (PLL1_BYPASS << 16); + ret = rk616->write_dev(rk616,CRU_PLL1_CON0,&val); return 0; } @@ -146,6 +228,10 @@ static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id } rk616->read_dev = rk616_i2c_read_reg; rk616->write_dev = rk616_i2c_write_reg; +#if defined(CONFIG_DEBUG_FS) + debugfs_create_file("rk616-reg", S_IRUSR,NULL,rk616,&rk616_reg_fops); +#endif + rk616_clk_common_init(rk616); ret = mfd_add_devices(rk616->dev, -1, rk616_devs, ARRAY_SIZE(rk616_devs), NULL, rk616->irq_base); |