BT: remove bt reset gpio at board-rk30-phone-sdmmc.c
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk30 / board-rk30-phone-sdmmc.c
1 /* arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c
2  *
3  * Copyright (C) 2012 ROCKCHIP, Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #ifdef CONFIG_SDMMC_RK29
17
18 #if !defined(CONFIG_SDMMC_RK29_OLD)     
19 static void rk29_sdmmc_gpio_open(int device_id, int on)
20 {
21     switch(device_id)
22     {
23         case 0://mmc0
24         {
25             #ifdef CONFIG_SDMMC0_RK29
26             if(on)
27             {
28                 gpio_direction_output(GPIO3B_GPIO3B0,GPIO_HIGH);//set mmc0-clk to high
29                 gpio_direction_output(GPIO3B_GPIO3B1,GPIO_HIGH);// set mmc0-cmd to high.
30                 gpio_direction_output(GPIO3B_GPIO3B2,GPIO_HIGH);//set mmc0-data0 to high.
31                 gpio_direction_output(GPIO3B_GPIO3B3,GPIO_HIGH);//set mmc0-data1 to high.
32                 gpio_direction_output(GPIO3B_GPIO3B4,GPIO_HIGH);//set mmc0-data2 to high.
33                 gpio_direction_output(GPIO3B_GPIO3B5,GPIO_HIGH);//set mmc0-data3 to high.
34
35                 mdelay(30);
36             }
37             else
38             {
39                 rk30_mux_api_set(GPIO3B0_SDMMC0CLKOUT_NAME, GPIO3B_GPIO3B0);
40                 gpio_request(RK30_PIN3_PB0, "mmc0-clk");
41                 gpio_direction_output(RK30_PIN3_PB0,GPIO_LOW);//set mmc0-clk to low.
42
43                 rk30_mux_api_set(GPIO3B1_SDMMC0CMD_NAME, GPIO3B_GPIO3B1);
44                 gpio_request(RK30_PIN3_PB1, "mmc0-cmd");
45                 gpio_direction_output(RK30_PIN3_PB1,GPIO_LOW);//set mmc0-cmd to low.
46
47                 rk30_mux_api_set(GPIO3B2_SDMMC0DATA0_NAME, GPIO3B_GPIO3B2);
48                 gpio_request(RK30_PIN3_PB2, "mmc0-data0");
49                 gpio_direction_output(RK30_PIN3_PB2,GPIO_LOW);//set mmc0-data0 to low.
50
51                 rk30_mux_api_set(GPIO3B3_SDMMC0DATA1_NAME, GPIO3B_GPIO3B3);
52                 gpio_request(RK30_PIN3_PB3, "mmc0-data1");
53                 gpio_direction_output(RK30_PIN3_PB3,GPIO_LOW);//set mmc0-data1 to low.
54
55                 rk30_mux_api_set(GPIO3B4_SDMMC0DATA2_NAME, GPIO3B_GPIO3B4);
56                 gpio_request(RK30_PIN3_PB4, "mmc0-data2");
57                 gpio_direction_output(RK30_PIN3_PB4,GPIO_LOW);//set mmc0-data2 to low.
58
59                 rk30_mux_api_set(GPIO3B5_SDMMC0DATA3_NAME, GPIO3B_GPIO3B5);
60                 gpio_request(RK30_PIN3_PB5, "mmc0-data3");
61                 gpio_direction_output(RK30_PIN3_PB5,GPIO_LOW);//set mmc0-data3 to low.
62
63                 mdelay(30);
64             }
65             #endif
66         }
67         break;
68         
69         case 1://mmc1
70         {
71             #ifdef CONFIG_SDMMC1_RK29
72             if(on)
73             {
74                 gpio_direction_output(RK30_PIN3_PC5,GPIO_HIGH);//set mmc1-clk to high
75                 gpio_direction_output(RK30_PIN3_PC0,GPIO_HIGH);//set mmc1-cmd to high.
76                 gpio_direction_output(RK30_PIN3_PC1,GPIO_HIGH);//set mmc1-data0 to high.
77                 gpio_direction_output(RK30_PIN3_PC2,GPIO_HIGH);//set mmc1-data1 to high.
78                 gpio_direction_output(RK30_PIN3_PC3,GPIO_HIGH);//set mmc1-data2 to high.
79                 gpio_direction_output(RK30_PIN3_PC5,GPIO_HIGH);//set mmc1-data3 to high.
80                 mdelay(100);
81             }
82             else
83             {
84                 rk30_mux_api_set(GPIO3C5_SDMMC1CLKOUT_NAME, GPIO3C_GPIO3C5);
85                 gpio_request(RK30_PIN3_PC5, "mmc1-clk");
86                 gpio_direction_output(RK30_PIN3_PC5,GPIO_LOW);//set mmc1-clk to low.
87
88                 rk30_mux_api_set(GPIO3C0_SMMC1CMD_NAME, GPIO3C_GPIO3C0);
89                 gpio_request(RK30_PIN3_PC0, "mmc1-cmd");
90                 gpio_direction_output(RK30_PIN3_PC0,GPIO_LOW);//set mmc1-cmd to low.
91
92                 rk30_mux_api_set(GPIO3C1_SDMMC1DATA0_NAME, GPIO3C_GPIO3C1);
93                 gpio_request(RK30_PIN3_PC1, "mmc1-data0");
94                 gpio_direction_output(RK30_PIN3_PC1,GPIO_LOW);//set mmc1-data0 to low.
95
96                 mdelay(100);
97             }
98             #endif
99         }
100         break; 
101         
102         case 2: //mmc2
103         break;
104         
105         default:
106         break;
107     }
108 }
109
110 static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width)
111 {
112     switch (bus_width)
113     {
114         
115         case 1://SDMMC_CTYPE_4BIT:
116         {
117                 rk30_mux_api_set(GPIO3B3_SDMMC0DATA1_NAME, GPIO3B_SDMMC0_DATA1);
118                 rk30_mux_api_set(GPIO3B4_SDMMC0DATA2_NAME, GPIO3B_SDMMC0_DATA2);
119                 rk30_mux_api_set(GPIO3B5_SDMMC0DATA3_NAME, GPIO3B_SDMMC0_DATA3);
120         }
121         break;
122
123         case 0x10000://SDMMC_CTYPE_8BIT:
124             break;
125         case 0xFFFF: //gpio_reset
126         {
127             rk30_mux_api_set(GPIO3A7_SDMMC0PWREN_NAME, GPIO3A_GPIO3A7);
128             gpio_request(RK30_PIN3_PA7,"sdmmc-power");
129             gpio_direction_output(RK30_PIN3_PA7,GPIO_HIGH); //power-off
130
131             rk29_sdmmc_gpio_open(0, 0);
132
133             gpio_direction_output(RK30_PIN3_PA7,GPIO_LOW); //power-on
134
135             rk29_sdmmc_gpio_open(0, 1);
136         }
137         break;
138
139         default: //case 0://SDMMC_CTYPE_1BIT:
140         {
141                 rk30_mux_api_set(GPIO3B1_SDMMC0CMD_NAME, GPIO3B_SDMMC0_CMD);
142                 rk30_mux_api_set(GPIO3B0_SDMMC0CLKOUT_NAME, GPIO3B_SDMMC0_CLKOUT);
143                 rk30_mux_api_set(GPIO3B2_SDMMC0DATA0_NAME, GPIO3B_SDMMC0_DATA0);
144
145             rk30_mux_api_set(GPIO3B3_SDMMC0DATA1_NAME, GPIO3B_GPIO3B3);
146             gpio_request(RK30_PIN3_PB3, "mmc0-data1");
147             gpio_direction_output(RK30_PIN3_PB3,GPIO_HIGH);//set mmc0-data1 to high.
148
149             rk30_mux_api_set(GPIO3B4_SDMMC0DATA2_NAME, GPIO3B_GPIO3B4);
150             gpio_request(RK30_PIN3_PB4, "mmc0-data2");
151             gpio_direction_output(RK30_PIN3_PB4,GPIO_HIGH);//set mmc0-data2 to high.
152
153             rk30_mux_api_set(GPIO3B5_SDMMC0DATA3_NAME, GPIO3B_GPIO3B5);
154             gpio_request(RK30_PIN3_PB5, "mmc0-data3");
155             gpio_direction_output(RK30_PIN3_PB5,GPIO_HIGH);//set mmc0-data3 to high.
156         }
157         break;
158         }
159 }
160
161 static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width)
162 {
163     rk30_mux_api_set(GPIO3C0_SMMC1CMD_NAME, GPIO3C_SMMC1_CMD);
164     rk30_mux_api_set(GPIO3C5_SDMMC1CLKOUT_NAME, GPIO3C_SDMMC1_CLKOUT);
165     rk30_mux_api_set(GPIO3C1_SDMMC1DATA0_NAME, GPIO3C_SDMMC1_DATA0);
166     rk30_mux_api_set(GPIO3C2_SDMMC1DATA1_NAME, GPIO3C_SDMMC1_DATA1);
167     rk30_mux_api_set(GPIO3C3_SDMMC1DATA2_NAME, GPIO3C_SDMMC1_DATA2);
168     rk30_mux_api_set(GPIO3C4_SDMMC1DATA3_NAME, GPIO3C_SDMMC1_DATA3);
169 }
170
171 static void rk29_sdmmc_set_iomux_mmc2(unsigned int bus_width)
172 {
173     ;//
174 }
175
176 static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
177 {
178     switch(device_id)
179     {
180         case 0:
181             #ifdef CONFIG_SDMMC0_RK29
182             rk29_sdmmc_set_iomux_mmc0(bus_width);
183             #endif
184             break;
185         case 1:
186             #ifdef CONFIG_SDMMC1_RK29
187             rk29_sdmmc_set_iomux_mmc1(bus_width);
188             #endif
189             break;
190         case 2:
191             rk29_sdmmc_set_iomux_mmc2(bus_width);
192             break;
193         default:
194             break;
195     }    
196 }
197
198 #endif
199
200
201 int rk29sdk_wifi_power_state = 0;
202 int rk29sdk_bt_power_state = 0;
203
204 #ifdef CONFIG_WIFI_CONTROL_FUNC
205 #define RK30SDK_WIFI_BT_GPIO_POWER_N       RK30_PIN4_PD5
206 #define RK30SDK_WIFI_GPIO_RESET_N       RK30_PIN3_PD0
207
208
209 #define PREALLOC_WLAN_SEC_NUM           4
210 #define PREALLOC_WLAN_BUF_NUM           160
211 #define PREALLOC_WLAN_SECTION_HEADER    24
212
213 #define WLAN_SECTION_SIZE_0     (PREALLOC_WLAN_BUF_NUM * 128)
214 #define WLAN_SECTION_SIZE_1     (PREALLOC_WLAN_BUF_NUM * 128)
215 #define WLAN_SECTION_SIZE_2     (PREALLOC_WLAN_BUF_NUM * 512)
216 #define WLAN_SECTION_SIZE_3     (PREALLOC_WLAN_BUF_NUM * 1024)
217
218 #define WLAN_SKB_BUF_NUM        16
219
220 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
221
222 struct wifi_mem_prealloc {
223         void *mem_ptr;
224         unsigned long size;
225 };
226
227 static struct wifi_mem_prealloc wifi_mem_array[PREALLOC_WLAN_SEC_NUM] = {
228         {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
229         {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
230         {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
231         {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
232 };
233
234 static void *rk29sdk_mem_prealloc(int section, unsigned long size)
235 {
236         if (section == PREALLOC_WLAN_SEC_NUM)
237                 return wlan_static_skb;
238
239         if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
240                 return NULL;
241
242         if (wifi_mem_array[section].size < size)
243                 return NULL;
244
245         return wifi_mem_array[section].mem_ptr;
246 }
247
248 static int __init rk29sdk_init_wifi_mem(void)
249 {
250         int i;
251         int j;
252
253         for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) {
254                 wlan_static_skb[i] = dev_alloc_skb(
255                                 ((i < (WLAN_SKB_BUF_NUM / 2)) ? 4096 : 8192));
256
257                 if (!wlan_static_skb[i])
258                         goto err_skb_alloc;
259         }
260
261         for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
262                 wifi_mem_array[i].mem_ptr =
263                                 kmalloc(wifi_mem_array[i].size, GFP_KERNEL);
264
265                 if (!wifi_mem_array[i].mem_ptr)
266                         goto err_mem_alloc;
267         }
268         return 0;
269
270 err_mem_alloc:
271         pr_err("Failed to mem_alloc for WLAN\n");
272         for (j = 0 ; j < i ; j++)
273                kfree(wifi_mem_array[j].mem_ptr);
274
275         i = WLAN_SKB_BUF_NUM;
276
277 err_skb_alloc:
278         pr_err("Failed to skb_alloc for WLAN\n");
279         for (j = 0 ; j < i ; j++)
280                 dev_kfree_skb(wlan_static_skb[j]);
281
282         return -ENOMEM;
283 }
284
285 static int rk29sdk_wifi_cd = 0;   /* wifi virtual 'card detect' status */
286 static void (*wifi_status_cb)(int card_present, void *dev_id);
287 static void *wifi_status_cb_devid;
288
289 static int rk29sdk_wifi_status(struct device *dev)
290 {
291         return rk29sdk_wifi_cd;
292 }
293
294 static int rk29sdk_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id)
295 {
296         if(wifi_status_cb)
297                 return -EAGAIN;
298         wifi_status_cb = callback;
299         wifi_status_cb_devid = dev_id;
300         return 0;
301 }
302
303 static int __init rk29sdk_wifi_bt_gpio_control_init(void)
304 {
305     rk29sdk_init_wifi_mem();
306  
307    rk29_mux_api_set(GPIO4D5_SMCDATA13_TRACEDATA13_NAME, GPIO4D_GPIO4D5);
308    
309     rk29_mux_api_set(GPIO3D0_SDMMC1PWREN_NAME, GPIO3D_GPIO3D0);
310     
311     if (gpio_request(RK30SDK_WIFI_BT_GPIO_POWER_N, "wifi_power")) {
312            pr_info("%s: request wifi power gpio failed\n", __func__);
313            return -1;
314     }
315
316     if (gpio_request(RK30SDK_WIFI_GPIO_RESET_N, "wifi reset")) {
317            pr_info("%s: request wifi reset gpio failed\n", __func__);
318            gpio_free(RK30SDK_WIFI_GPIO_RESET_N);
319            return -1;
320     }
321
322
323     gpio_direction_output(RK30SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
324     gpio_direction_output(RK30SDK_WIFI_GPIO_RESET_N,    GPIO_LOW);
325
326     #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
327     
328     rk29_mux_api_set(GPIO3C2_SDMMC1DATA1_NAME, GPIO3C_GPIO3C2);
329     gpio_request(RK30_PIN3_PC2, "mmc1-data1");
330     gpio_direction_output(RK30_PIN3_PC2,GPIO_LOW);//set mmc1-data1 to low.
331
332     rk29_mux_api_set(GPIO3C3_SDMMC1DATA2_NAME, GPIO3C_GPIO3C3);
333     gpio_request(RK30_PIN3_PC3, "mmc1-data2");
334     gpio_direction_output(RK30_PIN3_PC3,GPIO_LOW);//set mmc1-data2 to low.
335
336     rk29_mux_api_set(GPIO3C4_SDMMC1DATA3_NAME, GPIO3C_GPIO3C4);
337     gpio_request(RK30_PIN3_PC4, "mmc1-data3");
338     gpio_direction_output(RK30_PIN3_PC4,GPIO_LOW);//set mmc1-data3 to low.
339     
340     rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
341     #endif    
342     pr_info("%s: init finished\n",__func__);
343
344     return 0;
345 }
346
347 static int rk29sdk_wifi_power(int on)
348 {
349         pr_info("%s: %d\n", __func__, on);
350         if (on){
351                 gpio_set_value(RK30SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH);
352
353                 #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
354                 rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13
355                 #endif
356
357                 gpio_set_value(RK30SDK_WIFI_GPIO_RESET_N, GPIO_HIGH);
358                 mdelay(100);
359                 pr_info("wifi turn on power\n");
360         }else{
361                 if (!rk29sdk_bt_power_state){
362                         gpio_set_value(RK30SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
363
364                         #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
365                         rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
366                         #endif
367                         
368                         mdelay(100);
369                         pr_info("wifi shut off power\n");
370                 }else
371                 {
372                         pr_info("wifi shouldn't shut off power, bt is using it!\n");
373                 }
374                  gpio_set_value(RK30SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
375
376         }
377
378         rk29sdk_wifi_power_state = on;
379         return 0;
380 }
381
382 static int rk29sdk_wifi_reset_state;
383 static int rk29sdk_wifi_reset(int on)
384 {
385         pr_info("%s: %d\n", __func__, on);
386         gpio_set_value(RK30SDK_WIFI_GPIO_RESET_N, on);
387         mdelay(100);
388         rk29sdk_wifi_reset_state = on;
389         return 0;
390 }
391
392 int rk29sdk_wifi_set_carddetect(int val)
393 {
394         pr_info("%s:%d\n", __func__, val);
395         rk29sdk_wifi_cd = val;
396         if (wifi_status_cb){
397                 wifi_status_cb(val, wifi_status_cb_devid);
398         }else {
399                 pr_warning("%s, nobody to notify\n", __func__);
400         }
401         return 0;
402 }
403 EXPORT_SYMBOL(rk29sdk_wifi_set_carddetect);
404
405 static struct wifi_platform_data rk29sdk_wifi_control = {
406         .set_power = rk29sdk_wifi_power,
407         .set_reset = rk29sdk_wifi_reset,
408         .set_carddetect = rk29sdk_wifi_set_carddetect,
409         .mem_prealloc   = rk29sdk_mem_prealloc,
410 };
411
412 static struct platform_device rk29sdk_wifi_device = {
413         .name = "bcm4329_wlan",
414         .id = 1,
415         .dev = {
416                 .platform_data = &rk29sdk_wifi_control,
417          },
418 };
419 #endif
420
421
422 #endif // endif --#ifdef CONFIG_SDMMC_RK29
423