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