mfd rk616 hdmi:fix register config bug
[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-lvds",
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                 seq_printf(s,"0x%04x>>0x%08x\n",i,val);
116         }
117
118         return 0;
119 }
120
121 static ssize_t rk616_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
122
123         struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
124         u32 reg;
125         u32 val;
126         char kbuf[25];
127         if (copy_from_user(kbuf, buf, count))
128                 return -EFAULT;
129         sscanf(kbuf, "%x%x", &reg,&val);
130         dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg,val);
131         rk616->write_dev(rk616,reg,&val);
132         return count;
133 }
134
135 static int rk616_reg_open(struct inode *inode, struct file *file)
136 {
137         struct mfd_rk616 *rk616 = inode->i_private;
138         return single_open(file,rk616_reg_show,rk616);
139 }
140
141 static const struct file_operations rk616_reg_fops = {
142         .owner          = THIS_MODULE,
143         .open           = rk616_reg_open,
144         .read           = seq_read,
145         .write          = rk616_reg_write,
146         .llseek         = seq_lseek,
147         .release        = single_release,
148 };
149 #endif
150
151
152 static u32 rk616_clk_gcd(u32 numerator, u32 denominator)
153 {
154         u32 a, b;
155
156         if (!numerator || !denominator)
157                 return 0;
158
159         if (numerator > denominator) {
160                 a = numerator;
161                 b = denominator;
162         } else {
163                 a = denominator;
164                 b = numerator;
165         }
166
167         while (b != 0) {
168                 int r = b;
169                 b = a % b;
170                 a = r;
171         }
172
173         return a;
174 }
175
176
177 static int rk616_pll_clk_get_set(struct mfd_rk616 *rk616,unsigned long fin_hz,unsigned long fout_hz,
178                                         u32 *refdiv, u32 *fbdiv, u32 *postdiv1, u32 *postdiv2, u32 *frac)
179 {
180         // FIXME set postdiv1/2 always 1        
181         u32 gcd;
182         u64 fin_64, frac_64;
183         u32 f_frac;
184         if(!fin_hz || !fout_hz || fout_hz == fin_hz)
185                 return -1;
186
187         if(fin_hz / MHZ * MHZ == fin_hz && fout_hz /MHZ * MHZ == fout_hz)
188         {
189                 fin_hz /= MHZ;
190                 fout_hz /= MHZ;
191                 gcd = rk616_clk_gcd(fin_hz, fout_hz);
192                 *refdiv = fin_hz / gcd;
193                 *fbdiv = fout_hz / gcd;
194                 *postdiv1 = 1;
195                 *postdiv2 = 1;
196
197                 *frac = 0;
198
199                 dev_info(rk616->dev,"fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
200                                 fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
201         } 
202         else 
203         {
204                 dev_info(rk616->dev,"******frac div running, fin_hz=%lu, fout_hz=%lu, fin_mhz=%lu, fout_mhz=%lu\n",
205                                 fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
206                 gcd = rk616_clk_gcd(fin_hz / MHZ, fout_hz / MHZ);
207                 *refdiv = fin_hz / MHZ / gcd;
208                 *fbdiv = fout_hz / MHZ / gcd;
209                 *postdiv1 = 1;
210                 *postdiv2 = 1;
211
212                 *frac = 0;
213
214                 f_frac = (fout_hz % MHZ);
215                 fin_64 = fin_hz;
216                 do_div(fin_64, (u64)*refdiv);
217                 frac_64 = (u64)f_frac << 24;
218                 do_div(frac_64, fin_64);
219                 *frac = (u32) frac_64;
220                 dev_dbg(rk616->dev,"frac_64=%llx, frac=%u\n", frac_64, *frac);
221         }
222         return 0;
223 }
224
225 /***********************************
226 default clk patch settiing:
227 CLKIN-------->CODEC
228 LCD_DCLK0--->PLL0--->Dither--->LVDS/MIPI
229 LCD_DCLK1--->PLL1--->HDMI
230 ************************************/
231
232 static int rk616_clk_common_init(struct mfd_rk616 *rk616)
233 {
234         u32 val = 0;
235         int ret;
236
237         val = PLL1_CLK_SEL(1) | PLL0_CLK_SEL(0) | LCD1_CLK_DIV(0) | LCD0_CLK_DIV(0) |
238                 PLL1_CLK_SEL_MASK | PLL0_CLK_SEL_MASK | LCD1_CLK_DIV_MASK | 
239                 LCD0_CLK_DIV_MASK; //pll1 clk from lcdc1_dclk,pll0 clk from lcdc0_dclk,mux_lcdx = lcdx_clk
240         ret = rk616->write_dev(rk616,CRU_CLKSEL0_CON,&val);
241
242         val = CODEC_MCLK_SEL(2) | CODEC_MCLK_SEL_MASK; //codec mclk from clkin
243         ret = rk616->write_dev(rk616,CRU_CLKSEL1_CON,&val);
244         
245         val = 0; //codec mck = clkin
246         ret = rk616->write_dev(rk616,CRU_CODEC_DIV,&val);
247
248         val = (PLL0_BYPASS) | (PLL0_BYPASS << 16);  //bypass pll0 
249         ret = rk616->write_dev(rk616,CRU_PLL0_CON0,&val);
250
251         val = (PLL1_BYPASS) | (PLL1_BYPASS << 16);
252         ret = rk616->write_dev(rk616,CRU_PLL1_CON0,&val);
253
254         return 0;
255 }
256 static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
257 {
258         int ret;
259         struct mfd_rk616 *rk616 = NULL;
260         struct clk *iis_clk;
261
262         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
263         {
264                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
265                 ret = -ENODEV;
266         }
267         rk616 = kzalloc(sizeof(struct mfd_rk616), GFP_KERNEL);
268         if (rk616 == NULL)
269         {
270                 printk(KERN_ALERT "alloc for struct rk616 fail\n");
271                 ret = -ENOMEM;
272         }
273         
274         rk616->dev = &client->dev;
275         rk616->pdata = client->dev.platform_data;
276         rk616->client = client;
277         i2c_set_clientdata(client, rk616);
278         dev_set_drvdata(rk616->dev,rk616);
279         
280         if(rk616->pdata->power_init)
281                 rk616->pdata->power_init();
282
283 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)        
284         iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
285 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
286         iis_clk = clk_get_sys("rk29_i2s.1", "i2s");
287 #else
288         iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
289 #endif
290         if (IS_ERR(iis_clk)) 
291         {
292                 dev_err(&client->dev,"failed to get i2s clk\n");
293                 ret = PTR_ERR(iis_clk);
294         }
295         else
296         {
297                 #if defined(CONFIG_ARCH_RK29)
298                 rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
299                 #else
300                 iomux_set(I2S0_CLK);
301                 #endif
302                 clk_enable(iis_clk);
303                 clk_set_rate(iis_clk, 11289600);
304                 clk_put(iis_clk);
305         }
306         rk616->read_dev = rk616_i2c_read_reg;
307         rk616->write_dev = rk616_i2c_write_reg;
308 #if defined(CONFIG_DEBUG_FS)
309         rk616->debugfs_dir = debugfs_create_dir("rk616", NULL);
310         if (IS_ERR(rk616->debugfs_dir))
311         {
312                 dev_err(rk616->dev,"failed to create debugfs dir for rk616!\n");
313         }
314         else
315                 debugfs_create_file("rk616-core", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_reg_fops);
316 #endif
317         rk616_clk_common_init(rk616);
318         ret = mfd_add_devices(rk616->dev, -1,
319                                       rk616_devs, ARRAY_SIZE(rk616_devs),
320                                       NULL, rk616->irq_base);
321         
322         dev_info(&client->dev,"rk616 core probe success!\n");
323         return 0;
324 }
325
326 static int __devexit rk616_i2c_remove(struct i2c_client *client)
327 {
328         return 0;
329 }
330
331 static const struct i2c_device_id id_table[] = {
332         {"rk616", 0 },
333         { }
334 };
335
336 static struct i2c_driver rk616_i2c_driver  = {
337         .driver = {
338                 .name  = "rk616",
339                 .owner = THIS_MODULE,
340         },
341         .probe          = &rk616_i2c_probe,
342         .remove         = &rk616_i2c_remove,
343         .id_table       = id_table,
344 };
345
346
347 static int __init rk616_module_init(void)
348 {
349         return i2c_add_driver(&rk616_i2c_driver);
350 }
351
352 static void __exit rk616_module_exit(void)
353 {
354         i2c_del_driver(&rk616_i2c_driver);
355 }
356
357 subsys_initcall_sync(rk616_module_init);
358 module_exit(rk616_module_exit);
359
360