mfd:rk616:add clk common init,add debug interface
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rk616-core.c
1
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/delay.h>
5 #include <linux/mfd/core.h>
6 #include <linux/slab.h>
7 #include <linux/mfd/rk616.h>
8 #include <linux/clk.h>
9 #include <mach/iomux.h>
10 #include <linux/err.h>
11 #include <linux/uaccess.h>
12 #if defined(CONFIG_DEBUG_FS)
13 #include <linux/fs.h>
14 #include <linux/debugfs.h>
15 #include <linux/seq_file.h>
16 #endif
17
18
19 static struct mfd_cell rk616_devs[] = {
20         {
21                 .name = "rk616-lvds",
22                 .id = 0,
23         },
24         {
25                 .name = "rk616-codec",
26                 .id = 1,
27         },
28         {
29                 .name = "rk616-hdmi",
30                 .id = 2,
31         },
32         {
33                 .name = "rk616-mipi",
34                 .id = 3,
35         },
36 };
37
38 static int rk616_i2c_read_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
39 {
40         struct i2c_client * client = rk616->client;
41         struct i2c_adapter *adap = client->adapter;
42         struct i2c_msg msgs[2];
43         int ret;
44         char reg_buf[2];
45         
46         memcpy(reg_buf, &reg, 2);
47
48         msgs[0].addr = client->addr;
49         msgs[0].flags = client->flags;
50         msgs[0].len = 2;
51         msgs[0].buf = reg_buf;
52         msgs[0].scl_rate = rk616->pdata->scl_rate;
53         msgs[0].udelay = client->udelay;
54
55         msgs[1].addr = client->addr;
56         msgs[1].flags = client->flags | I2C_M_RD;
57         msgs[1].len = 4;
58         msgs[1].buf = (char *)pval;
59         msgs[1].scl_rate = rk616->pdata->scl_rate;
60         msgs[1].udelay = client->udelay;
61
62         ret = i2c_transfer(adap, msgs, 2);
63
64         
65         return (ret == 2)? 4 : ret;
66
67 }
68
69 static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
70 {
71         struct i2c_client *client = rk616->client;
72         struct i2c_adapter *adap = client->adapter;
73         struct i2c_msg msg;
74         int ret;
75         char *tx_buf = (char *)kmalloc(6, GFP_KERNEL);
76         if(!tx_buf)
77                 return -ENOMEM;
78         
79         memcpy(tx_buf, &reg, 2); 
80         memcpy(tx_buf+2, (char *)pval, 4); 
81
82         msg.addr = client->addr;
83         msg.flags = client->flags;
84         msg.len = 6;
85         msg.buf = (char *)tx_buf;
86         msg.scl_rate = rk616->pdata->scl_rate;
87         msg.udelay = client->udelay;
88
89         ret = i2c_transfer(adap, &msg, 1);
90         kfree(tx_buf);
91         
92         
93         return (ret == 1) ? 4 : ret;
94 }
95
96
97 #if defined(CONFIG_DEBUG_FS)
98 static int rk616_reg_show(struct seq_file *s, void *v)
99 {
100         int i = 0;
101         u32 val = 0;
102         struct mfd_rk616 *rk616 = s->private;
103         if(!rk616)
104         {
105                 dev_err(rk616->dev,"no mfd rk616!\n");
106                 return 0;
107         }
108
109         for(i=0;i<= CRU_CFGMISC_CON;i+=4)
110         {
111                 rk616->read_dev(rk616,i,&val);
112                 seq_printf(s,"0x%04x>>0x%08x\n",i,val);
113         }
114
115         return 0;
116 }
117
118 static ssize_t rk616_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
119
120         struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
121         u32 reg;
122         u32 val;
123         char kbuf[25];
124         if (copy_from_user(kbuf, buf, count))
125                 return -EFAULT;
126         sscanf(kbuf, "%x%x", &reg,&val);
127         dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg,val);
128         rk616->write_dev(rk616,reg,&val);
129         return count;
130 }
131
132 static int rk616_reg_open(struct inode *inode, struct file *file)
133 {
134         struct mfd_rk616 *rk616 = inode->i_private;
135         return single_open(file,rk616_reg_show,rk616);
136 }
137
138 static const struct file_operations rk616_reg_fops = {
139         .owner          = THIS_MODULE,
140         .open           = rk616_reg_open,
141         .read           = seq_read,
142         .write          = rk616_reg_write,
143         .llseek         = seq_lseek,
144         .release        = single_release,
145 };
146 #endif
147
148 /***********************************
149 default clk patch settiing:
150 CLKIN-------->CODEC
151 LCD_DCLK0--->PLL0--->Dither--->LVDS/MIPI
152 LCD_DCLK1--->PLL1--->HDMI
153 ************************************/
154
155 static int rk616_clk_common_init(struct mfd_rk616 *rk616)
156 {
157         u32 val = 0;
158         int ret;
159
160         val = PLL1_CLK_SEL(1) | PLL0_CLK_SEL(0) | LCD1_CLK_DIV(0) | LCD0_CLK_DIV(0) |
161                 PLL1_CLK_SEL_MASK | PLL0_CLK_SEL_MASK | LCD1_CLK_DIV_MASK | 
162                 LCD0_CLK_DIV_MASK; //pll1 clk from lcdc1_dclk,pll0 clk from lcdc0_dclk,mux_lcdx = lcdx_clk
163         ret = rk616->write_dev(rk616,CRU_CLKSEL0_CON,&val);
164
165         val = CODEC_MCLK_SEL(2) | CODEC_MCLK_SEL_MASK; //codec mclk from clkin
166         ret = rk616->write_dev(rk616,CRU_CLKSEL1_CON,&val);
167         
168         val = 0; //codec mck = clkin
169         ret = rk616->write_dev(rk616,CRU_CODEC_DIV,&val);
170
171         val = (PLL0_BYPASS) | (PLL0_BYPASS << 16);  //bypass pll0 
172         ret = rk616->write_dev(rk616,CRU_PLL0_CON0,&val);
173
174         val = (PLL1_BYPASS) | (PLL1_BYPASS << 16);
175         ret = rk616->write_dev(rk616,CRU_PLL1_CON0,&val);
176
177         return 0;
178 }
179 static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
180 {
181         int ret;
182         struct mfd_rk616 *rk616 = NULL;
183         struct clk *iis_clk;
184
185         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
186         {
187                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
188                 ret = -ENODEV;
189         }
190         rk616 = kzalloc(sizeof(struct mfd_rk616), GFP_KERNEL);
191         if (rk616 == NULL)
192         {
193                 printk(KERN_ALERT "alloc for struct rk616 fail\n");
194                 ret = -ENOMEM;
195         }
196         
197         rk616->dev = &client->dev;
198         rk616->pdata = client->dev.platform_data;
199         rk616->client = client;
200         i2c_set_clientdata(client, rk616);
201         dev_set_drvdata(rk616->dev,rk616);
202         
203         if(rk616->pdata->power_init)
204                 rk616->pdata->power_init();
205
206 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)        
207         iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
208 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
209         iis_clk = clk_get_sys("rk29_i2s.1", "i2s");
210 #else
211         iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
212 #endif
213         if (IS_ERR(iis_clk)) 
214         {
215                 dev_err(&client->dev,"failed to get i2s clk\n");
216                 ret = PTR_ERR(iis_clk);
217         }
218         else
219         {
220                 #if defined(CONFIG_ARCH_RK29)
221                 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
222                 #else
223                 iomux_set(I2S0_CLK);
224                 #endif
225                 clk_enable(iis_clk);
226                 clk_set_rate(iis_clk, 11289600);
227                 clk_put(iis_clk);
228         }
229         rk616->read_dev = rk616_i2c_read_reg;
230         rk616->write_dev = rk616_i2c_write_reg;
231 #if defined(CONFIG_DEBUG_FS)
232         debugfs_create_file("rk616-reg", S_IRUSR,NULL,rk616,&rk616_reg_fops);
233 #endif
234         rk616_clk_common_init(rk616);
235         ret = mfd_add_devices(rk616->dev, -1,
236                                       rk616_devs, ARRAY_SIZE(rk616_devs),
237                                       NULL, rk616->irq_base);
238         
239         dev_info(&client->dev,"rk616 core probe success!\n");
240         return 0;
241 }
242
243 static int __devexit rk616_i2c_remove(struct i2c_client *client)
244 {
245         return 0;
246 }
247
248 static const struct i2c_device_id id_table[] = {
249         {"rk616", 0 },
250         { }
251 };
252
253 static struct i2c_driver rk616_i2c_driver  = {
254         .driver = {
255                 .name  = "rk616",
256                 .owner = THIS_MODULE,
257         },
258         .probe          = &rk616_i2c_probe,
259         .remove         = &rk616_i2c_remove,
260         .id_table       = id_table,
261 };
262
263
264 static int __init rk616_module_init(void)
265 {
266         return i2c_add_driver(&rk616_i2c_driver);
267 }
268
269 static void __exit rk616_module_exit(void)
270 {
271         i2c_del_driver(&rk616_i2c_driver);
272 }
273
274 subsys_initcall_sync(rk616_module_init);
275 module_exit(rk616_module_exit);
276
277