Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rk610-core.c
1 #include <linux/module.h>
2 #include <linux/init.h>
3 #include <linux/i2c.h>
4 #include <linux/device.h>
5 #include <linux/delay.h>
6 #include <asm/gpio.h>
7 #include <linux/mfd/rk610_core.h>
8 #include <linux/clk.h>
9 #include <mach/iomux.h>
10 #include <linux/err.h>
11 #include <linux/slab.h>
12
13 #ifdef CONFIG_ARCH_RK30
14 #define RK610_RESET_PIN   RK30_PIN0_PC6
15 #else
16 #define RK610_RESET_PIN   RK29_PIN6_PC1
17 #endif
18
19 /*
20  * Debug
21  */
22 #if 0
23 #define DBG(x...)       printk(KERN_INFO x)
24 #else
25 #define DBG(x...)
26 #endif
27
28 static struct i2c_client *rk610_control_client = NULL;
29 #ifdef CONFIG_RK610_LCD
30 extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);
31 #else
32 int rk610_lcd_init(struct rk610_core_info *rk610_core_info){}
33 #endif
34 int rk610_control_send_byte(const char reg, const char data)
35 {
36         int ret;
37
38         DBG("reg = 0x%02x, val=0x%02x\n", reg ,data);
39
40         if(rk610_control_client == NULL)
41                 return -1;
42         //i2c_master_reg8_send
43         ret = i2c_master_reg8_send(rk610_control_client, reg, &data, 1, 100*1000);
44         if (ret > 0)
45                 ret = 0;
46
47         return ret;
48 }
49
50 #ifdef CONFIG_SND_SOC_RK610
51 static unsigned int current_pll_value = 0;
52 int rk610_codec_pll_set(unsigned int rate)
53 {
54         char N, M, NO, DIV;
55         unsigned int F;
56         char data;
57
58         if(current_pll_value == rate)
59                 return 0;
60
61     // Input clock is 12MHz.
62         if(rate == 11289600) {
63                 // For 11.2896MHz, N = 2 M= 75 F = 0.264(0x43958) NO = 8
64                 N = 2;
65                 NO = 3;
66                 M = 75;
67                 F = 0x43958;
68                 DIV = 5;
69         }
70         else if(rate == 12288000) {
71                 // For 12.2888MHz, N = 2 M= 75 F = 0.92(0xEB851) NO = 8
72                 N = 2;
73                 NO = 3;
74                 M = 75;
75                 F = 0xEB851;
76                 DIV = 5;
77         }
78         else {
79                 printk(KERN_ERR "[%s] not support such frequency\n", __FUNCTION__);
80                 return -1;
81         }
82
83         //Enable codec pll fractional number and power down.
84     data = 0x00;
85     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
86         msleep(10);
87
88     data = (N << 4) | NO;
89     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON0, data);
90     // M
91     data = M;
92     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON1, data);
93     // F
94     data = F & 0xFF;
95     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON2, data);
96     data = (F >> 8) & 0xFF;
97     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON3, data);
98     data = (F >> 16) & 0xFF;
99     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON4, data);
100
101     // i2s mclk = codec_pll/5;
102     i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
103     data &= ~CLOCK_CON1_I2S_DVIDER_MASK;
104     data |= (DIV - 1);
105     rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
106
107     // Power up codec pll.
108     data |= C_PLL_POWER_ON;
109     rk610_control_send_byte(RK610_CONTROL_REG_C_PLL_CON5, data);
110
111     current_pll_value = rate;
112     DBG("[%s] rate %u\n", __FUNCTION__, rate);
113
114     return 0;
115 }
116
117 void rk610_control_init_codec(void)
118 {
119     struct i2c_client *client = rk610_control_client;
120     char data = 0;
121     int ret;
122
123     if(rk610_control_client == NULL)
124         return;
125         DBG("[%s] start\n", __FUNCTION__);
126
127     //gpio_set_value(RK610_RESET_PIN, GPIO_LOW); //reset rk601
128    // mdelay(100);
129     //gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
130     //mdelay(100);
131
132         // Set i2c glitch timeout.
133         data = 0x22;
134         ret = i2c_master_reg8_send(client, RK610_CONTROL_REG_I2C_CON, &data, 1, 20*1000);
135
136 //    rk610_codec_pll_set(11289600);
137
138     //use internal codec, enable DAC ADC LRCK output.
139 //    i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
140 //    data = CODEC_CON_BIT_DAC_LRCL_OUTPUT_DISABLE | CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
141 //      data = CODEC_CON_BIT_ADC_LRCK_OUTPUT_DISABLE;
142         data = 0;
143         rk610_control_send_byte(RK610_CONTROL_REG_CODEC_CON, data);
144
145     // Select internal i2s clock from codec_pll.
146     i2c_master_reg8_recv(rk610_control_client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
147 //    data |= CLOCK_CON1_I2S_CLK_CODEC_PLL;
148         data = 0;
149     rk610_control_send_byte(RK610_CONTROL_REG_CLOCK_CON1, data);
150
151     i2c_master_reg8_recv(client, RK610_CONTROL_REG_CODEC_CON, &data, 1, 100*1000);
152     DBG("[%s] RK610_CONTROL_REG_CODEC_CON is %x\n", __FUNCTION__, data);
153
154     i2c_master_reg8_recv(client, RK610_CONTROL_REG_CLOCK_CON1, &data, 1, 100*1000);
155     DBG("[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
156 }
157 #endif
158 #ifdef RK610_DEBUG
159 static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)
160 {
161         return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
162 }
163
164 static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)
165 {
166         return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
167 }
168 static ssize_t rk610_show_reg_attrs(struct device *dev,
169                                               struct device_attribute *attr,
170                                               char *buf)
171 {
172
173         int i,size=0;
174         char val;
175         struct i2c_client *client=rk610_control_client;
176
177         for(i=0;i<256;i++)
178         {
179                 rk610_read_p0_reg(client, i,  &val);
180                 if(i%16==0)
181                         size += sprintf(buf+size,"\n>>>rk610_ctl %x:",i);
182                 size += sprintf(buf+size," %2x",val);
183         }
184
185         return size;
186 }
187 static ssize_t rk610_store_reg_attrs(struct device *dev,
188                                                 struct device_attribute *attr,
189                                                 const char *buf, size_t size)
190 {
191         struct i2c_client *client=NULL;
192         static char val=0,reg=0;
193         client = rk610_control_client;
194         DBG("/**********rk610 reg config******/");
195
196         sscanf(buf, "%x%x", &val,&reg);
197         DBG("reg=%x val=%x\n",reg,val);
198         rk610_write_p0_reg(client, reg,  &val);
199         DBG("val=%x\n",val);
200         return size;
201 }
202
203 static struct device_attribute rk610_attrs[] = {
204         __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
205 };
206 #endif
207
208 static int rk610_control_probe(struct i2c_client *client,
209                         const struct i2c_device_id *id)
210 {
211     int ret;
212     struct clk *iis_clk;
213         struct rk610_core_info *core_info = NULL; 
214         DBG("[%s] start\n", __FUNCTION__);
215         core_info = kmalloc(sizeof(struct rk610_core_info), GFP_KERNEL);
216     if(!core_info)
217     {
218         dev_err(&client->dev, ">> rk610 core inf kmalloc fail!");
219         return -ENOMEM;
220     }
221     memset(core_info, 0, sizeof(struct rk610_core_info));
222     
223                 iis_clk = clk_get_sys("rk29_i2s.0", "i2s");
224                 if (IS_ERR(iis_clk)) {
225                         printk("failed to get i2s clk\n");
226                         ret = PTR_ERR(iis_clk);
227                 }else{
228                         DBG("got i2s clk ok!\n");
229                         clk_enable(iis_clk);
230                         clk_set_rate(iis_clk, 11289600);
231                         #ifdef CONFIG_ARCH_RK29
232                         rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK);
233                         #else
234                         rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK);
235                         #endif
236                         clk_put(iis_clk);
237                 }
238
239     rk610_control_client = client;
240     msleep(100);
241         if(RK610_RESET_PIN != INVALID_GPIO) {
242             ret = gpio_request(RK610_RESET_PIN, "rk610 reset");
243             if (ret){
244                 printk(KERN_ERR "rk610_control_probe request gpio fail\n");
245             }
246             else {
247                 DBG("rk610_control_probe request gpio ok\n");
248                 gpio_direction_output(RK610_RESET_PIN, GPIO_HIGH);
249                     gpio_direction_output(RK610_RESET_PIN, GPIO_LOW);
250                         msleep(100);
251                     gpio_set_value(RK610_RESET_PIN, GPIO_HIGH);
252                 }
253         }
254     core_info->client = client;
255         rk610_lcd_init(core_info);
256         #ifdef RK610_DEBUG
257         device_create_file(&(client->dev), &rk610_attrs[0]);
258     #endif
259     return 0;
260 }
261
262 static int rk610_control_remove(struct i2c_client *client)
263 {
264         return 0;
265 }
266
267 static const struct i2c_device_id rk610_control_id[] = {
268         { "rk610_ctl", 0 },
269         { }
270 };
271 MODULE_DEVICE_TABLE(i2c, rk610_control_id);
272
273 static struct i2c_driver rk610_control_driver = {
274         .driver = {
275                 .name = "rk610_ctl",
276         },
277         .probe = rk610_control_probe,
278         .remove = rk610_control_remove,
279         .id_table = rk610_control_id,
280 };
281
282 static int __init rk610_control_init(void)
283 {
284         DBG("[%s] start\n", __FUNCTION__);
285         return i2c_add_driver(&rk610_control_driver);
286 }
287
288 static void __exit rk610_control_exit(void)
289 {
290         i2c_del_driver(&rk610_control_driver);
291 }
292
293 subsys_initcall_sync(rk610_control_init);
294 //module_init(rk610_control_init);
295 module_exit(rk610_control_exit);
296
297
298 MODULE_DESCRIPTION("RK610 control driver");
299 MODULE_AUTHOR("Rock-chips, <www.rock-chips.com>");
300 MODULE_LICENSE("GPL");
301