mfd:rk616:vif:support dual display and scaler
[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 #ifndef MHZ
19 #define MHZ (1000*1000)
20 #endif
21
22 static struct mfd_cell rk616_devs[] = {
23         {
24                 .name = "rk616-vif",
25                 .id = 0,
26         },
27         {
28                 .name = "rk616-codec",
29                 .id = 1,
30         },
31         {
32                 .name = "rk616-hdmi",
33                 .id = 2,
34         },
35         {
36                 .name = "rk616-mipi",
37                 .id = 3,
38         },
39 };
40
41 static int rk616_i2c_read_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
42 {
43         struct i2c_client * client = rk616->client;
44         struct i2c_adapter *adap = client->adapter;
45         struct i2c_msg msgs[2];
46         int ret;
47         char reg_buf[2];
48         
49         memcpy(reg_buf, &reg, 2);
50
51         msgs[0].addr = client->addr;
52         msgs[0].flags = client->flags;
53         msgs[0].len = 2;
54         msgs[0].buf = reg_buf;
55         msgs[0].scl_rate = rk616->pdata->scl_rate;
56         msgs[0].udelay = client->udelay;
57
58         msgs[1].addr = client->addr;
59         msgs[1].flags = client->flags | I2C_M_RD;
60         msgs[1].len = 4;
61         msgs[1].buf = (char *)pval;
62         msgs[1].scl_rate = rk616->pdata->scl_rate;
63         msgs[1].udelay = client->udelay;
64
65         ret = i2c_transfer(adap, msgs, 2);
66
67         
68         return (ret == 2)? 4 : ret;
69
70 }
71
72 static int rk616_i2c_write_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
73 {
74         struct i2c_client *client = rk616->client;
75         struct i2c_adapter *adap = client->adapter;
76         struct i2c_msg msg;
77         int ret;
78         char *tx_buf = (char *)kmalloc(6, GFP_KERNEL);
79         if(!tx_buf)
80                 return -ENOMEM;
81         
82         memcpy(tx_buf, &reg, 2); 
83         memcpy(tx_buf+2, (char *)pval, 4); 
84
85         msg.addr = client->addr;
86         msg.flags = client->flags;
87         msg.len = 6;
88         msg.buf = (char *)tx_buf;
89         msg.scl_rate = rk616->pdata->scl_rate;
90         msg.udelay = client->udelay;
91
92         ret = i2c_transfer(adap, &msg, 1);
93         kfree(tx_buf);
94         
95         
96         return (ret == 1) ? 4 : ret;
97 }
98
99
100 #if defined(CONFIG_DEBUG_FS)
101 static int rk616_reg_show(struct seq_file *s, void *v)
102 {
103         int i = 0;
104         u32 val = 0;
105         struct mfd_rk616 *rk616 = s->private;
106         if(!rk616)
107         {
108                 dev_err(rk616->dev,"no mfd rk616!\n");
109                 return 0;
110         }
111
112         for(i=0;i<= CRU_CFGMISC_CON;i+=4)
113         {
114                 rk616->read_dev(rk616,i,&val);
115                 if(i%16==0)
116                         seq_printf(s,"\n0x%04x:",i);
117                 seq_printf(s," %08x",val);
118         }
119         seq_printf(s,"\n");
120
121         return 0;
122 }
123
124 static ssize_t rk616_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
125
126         struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
127         u32 reg;
128         u32 val;
129         
130         char kbuf[25];
131         if (copy_from_user(kbuf, buf, count))
132                 return -EFAULT;
133         sscanf(kbuf, "%x%x", &reg,&val);
134         dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg,val);
135         rk616->write_dev(rk616,reg,&val);
136         return count;
137 }
138
139 static int rk616_reg_open(struct inode *inode, struct file *file)
140 {
141         struct mfd_rk616 *rk616 = inode->i_private;
142         return single_open(file,rk616_reg_show,rk616);
143 }
144
145 static const struct file_operations rk616_reg_fops = {
146         .owner          = THIS_MODULE,
147         .open           = rk616_reg_open,
148         .read           = seq_read,
149         .write          = rk616_reg_write,
150         .llseek         = seq_lseek,
151         .release        = single_release,
152 };
153 #endif
154
155
156 static u32 rk616_clk_gcd(u32 numerator, u32 denominator)
157 {
158         u32 a, b;
159
160         if (!numerator || !denominator)
161                 return 0;
162
163         if (numerator > denominator) {
164                 a = numerator;
165                 b = denominator;
166         } else {
167                 a = denominator;
168                 b = numerator;
169         }
170
171         while (b != 0) {
172                 int r = b;
173                 b = a % b;
174                 a = r;
175         }
176
177         return a;
178 }
179
180
181 static int rk616_pll_par_calc(u32 fin_hz,u32 fout_hz,u32 *refdiv, u32 *fbdiv,
182                                         u32 *postdiv1, u32 *postdiv2, u32 *frac)
183 {
184         // FIXME set postdiv1/2 always 1        
185         u32 gcd;
186         u64 fin_64, frac_64;
187         u32 f_frac;
188         if(!fin_hz || !fout_hz)
189                 return -EINVAL;
190
191         if(fin_hz / MHZ * MHZ == fin_hz && fout_hz /MHZ * MHZ == fout_hz)
192         {
193                 fin_hz /= MHZ;
194                 fout_hz /= MHZ;
195                 gcd = rk616_clk_gcd(fin_hz, fout_hz);
196                 *refdiv = fin_hz / gcd;
197                 *fbdiv = fout_hz / gcd;
198                 *postdiv1 = 1;
199                 *postdiv2 = 1;
200
201                 *frac = 0;
202                 
203         } 
204         else 
205         {
206                 
207                 gcd = rk616_clk_gcd(fin_hz / MHZ, fout_hz / MHZ);
208                 *refdiv = fin_hz / MHZ / gcd;
209                 *fbdiv = fout_hz / MHZ / gcd;
210                 *postdiv1 = 1;
211                 *postdiv2 = 1;
212
213                 *frac = 0;
214
215                 f_frac = (fout_hz % MHZ);
216                 fin_64 = fin_hz;
217                 do_div(fin_64, (u64)*refdiv);
218                 frac_64 = (u64)f_frac << 24;
219                 do_div(frac_64, fin_64);
220                 *frac = (u32) frac_64;
221                 printk(KERN_INFO "frac_64=%llx, frac=%u\n", frac_64, *frac);
222         }
223         printk(KERN_INFO "fin=%u,fout=%u,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
224                                 fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
225         return 0;
226 }
227
228
229 static  int  rk616_pll_wait_lock(struct mfd_rk616 *rk616,int id)
230 {
231         u32 delay = 10;
232         u32 val = 0;
233         int ret;
234         int offset;
235
236         if(id == 0)  //PLL0
237         {
238                 offset = 0;
239         }
240         else // PLL1
241         {
242                 offset = 0x0c;
243         }
244         while (delay >= 1) 
245         {
246                 ret = rk616->read_dev(rk616,CRU_PLL0_CON1 + offset,&val);
247                 if (val&PLL0_LOCK)
248                 {
249                         dev_info(rk616->dev,"PLL%d locked\n",id);
250                         break;
251                 }
252                 msleep(1);
253                 delay--;
254         }
255         if (delay == 0)
256         {
257                 printk(KERN_ALERT "rk616 wait pll bit time out!\n");
258         }
259
260         return 0;
261 }
262
263
264 int rk616_pll_set_rate(struct mfd_rk616 *rk616,int id,u32 cfg_val,u32 frac)
265 {
266         u32 val = 0;
267         int ret;
268         int offset;
269         u16 con0 = cfg_val & 0xffff;
270         u16 con1 = (cfg_val >> 16)&0xffff;
271         u32 fbdiv = con0 & 0xfff;
272         u32 postdiv1 = (con0 >> 12)&0x7;
273         u32 refdiv = con1 & 0x3f;
274         u32 postdiv2 = (con1 >> 6) & 0x7;
275         u8 mode = !frac;
276         
277         
278         if(id == 0)  //PLL0
279         {
280                 offset = 0;
281         }
282         else // PLL1
283         {
284                 offset = 0x0c;
285         }
286
287
288         val = PLL0_PWR_DN | (PLL0_PWR_DN << 16);
289         ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val);
290
291         val = PLL0_POSTDIV1(postdiv1) | PLL0_FBDIV(fbdiv) | PLL0_POSTDIV1_MASK | 
292                 PLL0_FBDIV_MASK | (PLL0_BYPASS << 16);
293         ret = rk616->write_dev(rk616,CRU_PLL0_CON0 + offset,&val);
294
295         val = PLL0_DIV_MODE(mode) | PLL0_POSTDIV2(postdiv2) | PLL0_REFDIV(refdiv) |
296                 (PLL0_DIV_MODE_MASK) | PLL0_POSTDIV2_MASK | PLL0_REFDIV_MASK;
297         ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val);
298
299         val = PLL0_FRAC(frac);
300         ret = rk616->write_dev(rk616,CRU_PLL0_CON2 + offset,&val);
301         
302         val = (PLL0_PWR_DN << 16);
303         ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val);
304         rk616_pll_wait_lock(rk616,id);
305
306         return 0;       
307         
308 }
309 /***********************************
310 default clk patch settiing:
311 CLKIN-------->CODEC
312 LCD_DCLK0--->PLL0--->Dither--->LVDS/MIPI
313 LCD_DCLK1--->PLL1--->HDMI
314 ************************************/
315
316 static int rk616_clk_common_init(struct mfd_rk616 *rk616)
317 {
318         u32 val = 0;
319         int ret;
320
321         val = PLL1_CLK_SEL(LCD1_DCLK) | PLL0_CLK_SEL(LCD0_DCLK) | LCD1_CLK_DIV(0) | 
322                 LCD0_CLK_DIV(0) | PLL1_CLK_SEL_MASK | PLL0_CLK_SEL_MASK | 
323                 LCD1_CLK_DIV_MASK | LCD0_CLK_DIV_MASK; //pll1 clk from lcdc1_dclk,pll0 clk from lcdc0_dclk,mux_lcdx = lcdx_clk
324         ret = rk616->write_dev(rk616,CRU_CLKSEL0_CON,&val);
325
326         val = SCLK_SEL(SCLK_SEL_PLL1) | CODEC_MCLK_SEL(CODEC_MCLK_SEL_12M) |
327                 CODEC_MCLK_SEL_MASK | SCLK_SEL_MASK; //codec mclk from clkin
328         ret = rk616->write_dev(rk616,CRU_CLKSEL1_CON,&val);
329         
330         val = 0; //codec mck = clkin
331         ret = rk616->write_dev(rk616,CRU_CODEC_DIV,&val);
332
333         val = (PLL0_BYPASS) | (PLL0_BYPASS << 16);  //bypass pll0 
334         ret = rk616->write_dev(rk616,CRU_PLL0_CON0,&val);
335
336         val = (PLL1_BYPASS) | (PLL1_BYPASS << 16);
337         ret = rk616->write_dev(rk616,CRU_PLL1_CON0,&val);
338
339         return 0;
340 }
341
342
343 static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
344 {
345         int ret;
346         struct mfd_rk616 *rk616 = NULL;
347         struct clk *iis_clk;
348
349         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
350         {
351                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
352                 ret = -ENODEV;
353         }
354         rk616 = kzalloc(sizeof(struct mfd_rk616), GFP_KERNEL);
355         if (rk616 == NULL)
356         {
357                 printk(KERN_ALERT "alloc for struct rk616 fail\n");
358                 ret = -ENOMEM;
359         }
360         
361         rk616->dev = &client->dev;
362         rk616->pdata = client->dev.platform_data;
363         rk616->client = client;
364         i2c_set_clientdata(client, rk616);
365         dev_set_drvdata(rk616->dev,rk616);
366         
367         if(rk616->pdata->power_init)
368                 rk616->pdata->power_init();
369
370 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)        
371         iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
372 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
373         iis_clk = clk_get_sys("rk29_i2s.1", "i2s");
374 #else
375         iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
376 #endif
377         if (IS_ERR(iis_clk)) 
378         {
379                 dev_err(&client->dev,"failed to get i2s clk\n");
380                 ret = PTR_ERR(iis_clk);
381         }
382         else
383         {
384                 #if defined(CONFIG_ARCH_RK29)
385                 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
386                 #else
387                 iomux_set(I2S0_CLK);
388                 #endif
389                 clk_enable(iis_clk);
390                 clk_set_rate(iis_clk, 11289600);
391                 clk_put(iis_clk);
392         }
393         rk616->read_dev = rk616_i2c_read_reg;
394         rk616->write_dev = rk616_i2c_write_reg;
395         
396 #if defined(CONFIG_DEBUG_FS)
397         rk616->debugfs_dir = debugfs_create_dir("rk616", NULL);
398         if (IS_ERR(rk616->debugfs_dir))
399         {
400                 dev_err(rk616->dev,"failed to create debugfs dir for rk616!\n");
401         }
402         else
403                 debugfs_create_file("core", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_reg_fops);
404 #endif
405         rk616_clk_common_init(rk616);
406         ret = mfd_add_devices(rk616->dev, -1,
407                                       rk616_devs, ARRAY_SIZE(rk616_devs),
408                                       NULL, rk616->irq_base);
409         
410         dev_info(&client->dev,"rk616 core probe success!\n");
411         return 0;
412 }
413
414 static int __devexit rk616_i2c_remove(struct i2c_client *client)
415 {
416         return 0;
417 }
418
419 static const struct i2c_device_id id_table[] = {
420         {"rk616", 0 },
421         { }
422 };
423
424 static struct i2c_driver rk616_i2c_driver  = {
425         .driver = {
426                 .name  = "rk616",
427                 .owner = THIS_MODULE,
428         },
429         .probe          = &rk616_i2c_probe,
430         .remove         = &rk616_i2c_remove,
431         .id_table       = id_table,
432 };
433
434
435 static int __init rk616_module_init(void)
436 {
437         return i2c_add_driver(&rk616_i2c_driver);
438 }
439
440 static void __exit rk616_module_exit(void)
441 {
442         i2c_del_driver(&rk616_i2c_driver);
443 }
444
445 subsys_initcall_sync(rk616_module_init);
446 module_exit(rk616_module_exit);
447
448