Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk2928 / board-rk2928-phonepad-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(RK2928_PIN1_PC0,GPIO_HIGH);//set mmc0-clk to high
29                 gpio_direction_output(RK2928_PIN1_PB7,GPIO_HIGH);// set mmc0-cmd to high.
30                 gpio_direction_output(RK2928_PIN1_PC2,GPIO_HIGH);//set mmc0-data0 to high.
31                 gpio_direction_output(RK2928_PIN1_PC3,GPIO_HIGH);//set mmc0-data1 to high.
32                 gpio_direction_output(RK2928_PIN1_PC4,GPIO_HIGH);//set mmc0-data2 to high.
33                 gpio_direction_output(RK2928_PIN1_PC5,GPIO_HIGH);//set mmc0-data3 to high.
34
35                 mdelay(30);
36             }
37             else
38             {
39                 rk30_mux_api_set(GPIO1C0_MMC0_CLKOUT_NAME, GPIO1C_GPIO1C0);
40                 gpio_request(RK2928_PIN1_PC0, "mmc0-clk");
41                 gpio_direction_output(RK2928_PIN1_PC0,GPIO_LOW);//set mmc0-clk to low.
42
43                 rk30_mux_api_set(GPIO1B7_MMC0_CMD_NAME, GPIO1B_GPIO1B7);
44                 gpio_request(RK2928_PIN1_PB7, "mmc0-cmd");
45                 gpio_direction_output(RK2928_PIN1_PB7,GPIO_LOW);//set mmc0-cmd to low.
46
47                 rk30_mux_api_set(GPIO1C2_MMC0_D0_NAME, GPIO1C_GPIO1C2);
48                 gpio_request(RK2928_PIN1_PC2, "mmc0-data0");
49                 gpio_direction_output(RK2928_PIN1_PC2,GPIO_LOW);//set mmc0-data0 to low.
50
51                 rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_GPIO1C3);
52                 gpio_request(RK2928_PIN1_PC3, "mmc0-data1");
53                 gpio_direction_output(RK2928_PIN1_PC3,GPIO_LOW);//set mmc0-data1 to low.
54
55                 rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_GPIO1C4);
56                 gpio_request(RK2928_PIN1_PC4, "mmc0-data2");
57                 gpio_direction_output(RK2928_PIN1_PC4,GPIO_LOW);//set mmc0-data2 to low.
58
59                 rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_GPIO1C5);
60                 gpio_request(RK2928_PIN1_PC5, "mmc0-data3");
61                 gpio_direction_output(RK2928_PIN1_PC5,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_request(RK2928_PIN0_PB1, "mmc1-clk");
75                 gpio_direction_output(RK2928_PIN0_PB1,GPIO_HIGH);//set mmc1-clk to high
76
77                 gpio_request(RK2928_PIN0_PB0, "mmc1-cmd");
78                 gpio_direction_output(RK2928_PIN0_PB0,GPIO_HIGH);//set mmc1-cmd to high.
79
80                 gpio_request(RK2928_PIN0_PB3, "mmc1-data0");
81                 gpio_direction_output(RK2928_PIN0_PB3,GPIO_HIGH);//set mmc1-data0 to high.
82
83                                 gpio_request(RK2928_PIN0_PB4, "mmc1-data1");
84                 gpio_direction_output(RK2928_PIN0_PB4,GPIO_HIGH);//set mmc1-data1 to high.
85
86                                 gpio_request(RK2928_PIN0_PB5, "mmc1-data2");
87                 gpio_direction_output(RK2928_PIN0_PB5,GPIO_HIGH);//set mmc1-data2 to high.
88
89                                 gpio_request(RK2928_PIN0_PB6, "mmc1-data3");
90                 gpio_direction_output(RK2928_PIN0_PB6,GPIO_HIGH);//set mmc1-data3 to high.
91                 mdelay(100);
92             }
93             else
94             {
95                 rk30_mux_api_set(GPIO0B1_MMC1_CLKOUT_NAME, GPIO0B_GPIO0B1);
96                 gpio_request(RK2928_PIN0_PB1, "mmc1-clk");
97                 gpio_direction_output(RK2928_PIN0_PB1,GPIO_LOW);//set mmc1-clk to low.
98
99                 rk30_mux_api_set(GPIO0B0_MMC1_CMD_NAME, GPIO0B_GPIO0B0);
100                 gpio_request(RK2928_PIN0_PB0, "mmc1-cmd");
101                 gpio_direction_output(RK2928_PIN0_PB0,GPIO_LOW);//set mmc1-cmd to low.
102
103                 rk30_mux_api_set(GPIO0B3_MMC1_D0_NAME, GPIO0B_GPIO0B3);
104                 gpio_request(RK2928_PIN0_PB3, "mmc1-data0");
105                 gpio_direction_output(RK2928_PIN0_PB3,GPIO_LOW);//set mmc1-data0 to low.
106
107                                 #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
108                                 rk29_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_GPIO0B4);
109                                 gpio_request(RK2928_PIN0_PB4, "mmc1-data1");
110                                 gpio_direction_output(RK2928_PIN0_PB4,GPIO_LOW);//set mmc1-data1 to low.
111
112                                 rk29_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_GPIO0B5);
113                                 gpio_request(RK2928_PIN0_PB5, "mmc1-data2");
114                                 gpio_direction_output(RK2928_PIN0_PB5,GPIO_LOW);//set mmc1-data2 to low.
115
116                                 rk29_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_GPIO0B6);
117                                 gpio_request(RK2928_PIN0_PB6, "mmc1-data3");
118                                 gpio_direction_output(RK2928_PIN0_PB6,GPIO_LOW);//set mmc1-data3 to low.
119
120                                 //rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
121                                 #endif
122
123                 mdelay(100);
124             }
125             #endif
126         }
127         break; 
128         
129         case 2: //mmc2
130         break;
131         
132         default:
133         break;
134     }
135 }
136
137 static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width)
138 {
139     switch (bus_width)
140     {
141         
142         case 1://SDMMC_CTYPE_4BIT:
143         {
144                 rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_MMC0_D1);
145                 rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_MMC0_D2);
146                 rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_MMC0_D3);
147         }
148         break;
149
150         case 0x10000://SDMMC_CTYPE_8BIT:
151             break;
152         case 0xFFFF: //gpio_reset
153         {
154             rk30_mux_api_set(GPIO1B6_MMC0_PWREN_NAME, GPIO1B_GPIO1B6);
155             gpio_request(RK2928_PIN1_PB6,"sdmmc-power");
156             gpio_direction_output(RK2928_PIN1_PB6,GPIO_HIGH); //power-off
157
158             rk29_sdmmc_gpio_open(0, 0);
159
160             gpio_direction_output(RK2928_PIN1_PB6,GPIO_LOW); //power-on
161
162             rk29_sdmmc_gpio_open(0, 1);
163         }
164         break;
165
166         default: //case 0://SDMMC_CTYPE_1BIT:
167         {
168                 rk30_mux_api_set(GPIO1B7_MMC0_CMD_NAME, GPIO1B_MMC0_CMD);
169                 rk30_mux_api_set(GPIO1C0_MMC0_CLKOUT_NAME, GPIO1C_MMC0_CLKOUT);
170                 rk30_mux_api_set(GPIO1C2_MMC0_D0_NAME, GPIO1C_MMC0_D0);
171
172             rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_GPIO1C3);
173             gpio_request(RK2928_PIN1_PC3, "mmc0-data1");
174             gpio_direction_output(RK2928_PIN1_PC3,GPIO_HIGH);//set mmc0-data1 to high.
175
176             rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_GPIO1C4);
177             gpio_request(RK2928_PIN1_PC4, "mmc0-data2");
178             gpio_direction_output(RK2928_PIN1_PC4,GPIO_HIGH);//set mmc0-data2 to high.
179
180             rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_GPIO1C5);
181             gpio_request(RK2928_PIN1_PC5, "mmc0-data3");
182             gpio_direction_output(RK2928_PIN1_PC5,GPIO_HIGH);//set mmc0-data3 to high.
183         }
184         break;
185         }
186 }
187
188 static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width)
189 {
190     rk30_mux_api_set(GPIO0B0_MMC1_CMD_NAME, GPIO0B_MMC1_CMD);
191     rk30_mux_api_set(GPIO0B1_MMC1_CLKOUT_NAME, GPIO0B_MMC1_CLKOUT);
192     rk30_mux_api_set(GPIO0B3_MMC1_D0_NAME, GPIO0B_MMC1_D0);
193     rk30_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_MMC1_D1);
194     rk30_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_MMC1_D2);
195     rk30_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_MMC1_D3);
196 }
197
198 static void rk29_sdmmc_set_iomux_mmc2(unsigned int bus_width)
199 {
200     ;//
201 }
202
203 static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
204 {
205     switch(device_id)
206     {
207         case 0:
208             #ifdef CONFIG_SDMMC0_RK29
209             rk29_sdmmc_set_iomux_mmc0(bus_width);
210             #endif
211             break;
212         case 1:
213             #ifdef CONFIG_SDMMC1_RK29
214             rk29_sdmmc_set_iomux_mmc1(bus_width);
215             #endif
216             break;
217         case 2:
218             rk29_sdmmc_set_iomux_mmc2(bus_width);
219             break;
220         default:
221             break;
222     }    
223 }
224
225 #endif
226
227
228
229 #ifdef CONFIG_WIFI_CONTROL_FUNC
230
231 //
232 // Define wifi module's power and reset gpio, and gpio sensitive level 
233 //
234
235 #if defined(CONFIG_RK903) || defined(CONFIG_RK901)
236 #define RK30SDK_WIFI_GPIO_POWER_N       RK2928_PIN0_PD6
237 #define RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE GPIO_HIGH 
238 #define RK30SDK_WIFI_GPIO_RESET_N       RK2928_PIN3_PC2
239 #define RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE GPIO_HIGH 
240 #endif
241
242 #if defined(CONFIG_RTL8192CU) || defined(CONFIG_RTL8188EU) 
243 #define RK30SDK_WIFI_GPIO_POWER_N       RK2928_PIN0_PD6
244 #define RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE GPIO_LOW 
245 #endif
246
247 #if defined(CONFIG_BCM4329) || defined(CONFIG_BCM4319) 
248 #define RK30SDK_WIFI_GPIO_POWER_N       RK2928_PIN0_PD6
249 #define RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE GPIO_HIGH 
250 #define RK30SDK_WIFI_GPIO_RESET_N       RK2928_PIN3_PC2
251 #define RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE GPIO_HIGH 
252 #endif
253 #if defined(CONFIG_RDA5990)
254 #define RK30SDK_WIFI_GPIO_POWER_N       RK2928_PIN0_PD6
255 #define RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE GPIO_HIGH 
256 #define RK30SDK_WIFI_GPIO_RESET_N       RK2928_PIN3_PC2
257 #define RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE GPIO_HIGH 
258 #endif
259
260 #define PREALLOC_WLAN_SEC_NUM           4
261 #define PREALLOC_WLAN_BUF_NUM           160
262 #define PREALLOC_WLAN_SECTION_HEADER    24
263
264 #define WLAN_SECTION_SIZE_0     (PREALLOC_WLAN_BUF_NUM * 128)
265 #define WLAN_SECTION_SIZE_1     (PREALLOC_WLAN_BUF_NUM * 128)
266 #define WLAN_SECTION_SIZE_2     (PREALLOC_WLAN_BUF_NUM * 512)
267 #define WLAN_SECTION_SIZE_3     (PREALLOC_WLAN_BUF_NUM * 1024)
268
269 #define WLAN_SKB_BUF_NUM        16
270
271 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
272
273 struct wifi_mem_prealloc {
274         void *mem_ptr;
275         unsigned long size;
276 };
277
278 static struct wifi_mem_prealloc wifi_mem_array[PREALLOC_WLAN_SEC_NUM] = {
279         {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
280         {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
281         {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
282         {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
283 };
284
285 static void *rk29sdk_mem_prealloc(int section, unsigned long size)
286 {
287         if (section == PREALLOC_WLAN_SEC_NUM)
288                 return wlan_static_skb;
289
290         if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
291                 return NULL;
292
293         if (wifi_mem_array[section].size < size)
294                 return NULL;
295
296         return wifi_mem_array[section].mem_ptr;
297 }
298
299 static int __init rk29sdk_init_wifi_mem(void)
300 {
301         int i;
302         int j;
303
304         for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) {
305                 wlan_static_skb[i] = dev_alloc_skb(
306                                 ((i < (WLAN_SKB_BUF_NUM / 2)) ? 4096 : 8192));
307
308                 if (!wlan_static_skb[i])
309                         goto err_skb_alloc;
310         }
311
312         for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
313                 wifi_mem_array[i].mem_ptr =
314                                 kmalloc(wifi_mem_array[i].size, GFP_KERNEL);
315
316                 if (!wifi_mem_array[i].mem_ptr)
317                         goto err_mem_alloc;
318         }
319         return 0;
320
321 err_mem_alloc:
322         pr_err("Failed to mem_alloc for WLAN\n");
323         for (j = 0 ; j < i ; j++)
324                kfree(wifi_mem_array[j].mem_ptr);
325
326         i = WLAN_SKB_BUF_NUM;
327
328 err_skb_alloc:
329         pr_err("Failed to skb_alloc for WLAN\n");
330         for (j = 0 ; j < i ; j++)
331                 dev_kfree_skb(wlan_static_skb[j]);
332
333         return -ENOMEM;
334 }
335
336 static int rk29sdk_wifi_cd = 0;   /* wifi virtual 'card detect' status */
337 static void (*wifi_status_cb)(int card_present, void *dev_id);
338 static void *wifi_status_cb_devid;
339
340 static int rk29sdk_wifi_status(struct device *dev)
341 {
342         return rk29sdk_wifi_cd;
343 }
344
345 static int rk29sdk_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id)
346 {
347         if(wifi_status_cb)
348                 return -EAGAIN;
349         wifi_status_cb = callback;
350         wifi_status_cb_devid = dev_id;
351         return 0;
352 }
353
354 static int __init rk29sdk_wifi_bt_gpio_control_init(void)
355 {
356     rk29sdk_init_wifi_mem();
357     
358     rk29_mux_api_set(GPIO0D6_MMC1_PWREN_NAME, GPIO0D_GPIO0D6);
359     
360     if (gpio_request(RK30SDK_WIFI_GPIO_POWER_N, "wifi_power")) {
361            pr_info("%s: request wifi power gpio failed\n", __func__);
362            return -1;
363     }
364
365 #ifdef RK30SDK_WIFI_GPIO_RESET_N
366     if (gpio_request(RK30SDK_WIFI_GPIO_RESET_N, "wifi reset")) {
367            pr_info("%s: request wifi reset gpio failed\n", __func__);
368            gpio_free(RK30SDK_WIFI_GPIO_POWER_N);
369            return -1;
370     }
371 #endif    
372
373     gpio_direction_output(RK30SDK_WIFI_GPIO_POWER_N, !RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE);
374 #ifdef RK30SDK_WIFI_GPIO_RESET_N    
375     gpio_direction_output(RK30SDK_WIFI_GPIO_RESET_N, !RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE);
376 #endif    
377
378     #if 0//defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
379     
380     rk29_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_GPIO0B4);
381     gpio_request(RK2928_PIN0_PB4, "mmc1-data1");
382     gpio_direction_output(RK2928_PIN0_PB4,GPIO_LOW);//set mmc1-data1 to low.
383
384     rk29_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_GPIO0B5);
385     gpio_request(RK2928_PIN0_PB5, "mmc1-data2");
386     gpio_direction_output(RK2928_PIN0_PB5,GPIO_LOW);//set mmc1-data2 to low.
387
388     rk29_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_GPIO0B6);
389     gpio_request(RK2928_PIN0_PB6, "mmc1-data3");
390     gpio_direction_output(RK2928_PIN0_PB6,GPIO_LOW);//set mmc1-data3 to low.
391     
392     rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
393     #endif    
394     pr_info("%s: init finished\n",__func__);
395
396     return 0;
397 }
398
399 #if defined(CONFIG_RTL8192CU) || defined(CONFIG_RTL8188EU) 
400 static int usbwifi_power_status = 1;
401 int rk29sdk_wifi_power(int on)
402 {
403         pr_info("%s: %d\n", __func__, on);
404          if (on){
405                 /*if(usbwifi_power_status == 1) {
406                     rkusb_wifi_power(0);
407                     mdelay(50);
408                 }*/
409                 rkusb_wifi_power(1);
410                 usbwifi_power_status = 1;
411                  pr_info("wifi turn on power\n");       
412         }else{
413                 rkusb_wifi_power(0);
414                 usbwifi_power_status = 0;       
415                  pr_info("wifi shut off power\n");
416         }
417         return 0;
418 }
419 #else
420 int rk29sdk_wifi_power(int on)
421 {
422         pr_info("%s: %d\n", __func__, on);
423         if (on){
424                 //gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE);
425                 mdelay(50);
426
427                 #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
428                 rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13
429                 #endif
430
431 #ifdef RK30SDK_WIFI_GPIO_RESET_N
432                 //gpio_set_value(RK30SDK_WIFI_GPIO_RESET_N, RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE);
433 #endif                
434                 mdelay(100);
435                 pr_info("wifi turn on power\n");
436         }else{
437 //                if (!rk29sdk_bt_power_state){
438                        // gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, !RK30SDK_WIFI_GPIO_POWER_ENABLE_VALUE);
439
440                         #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
441                         rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
442                         #endif
443                         
444                         mdelay(100);
445                         pr_info("wifi shut off power\n");
446 //                }else
447 //                {
448 //                        pr_info("wifi shouldn't shut off power, bt is using it!\n");
449 //                }
450 #ifdef RK30SDK_WIFI_GPIO_RESET_N
451                 //gpio_set_value(RK30SDK_WIFI_GPIO_RESET_N, !RK30SDK_WIFI_GPIO_RESET_ENABLE_VALUE);
452 #endif 
453
454         }
455
456         //rk29sdk_wifi_power_state = on;
457         return 0;
458 }
459 #endif
460 EXPORT_SYMBOL(rk29sdk_wifi_power);
461
462 static int rk29sdk_wifi_reset_state;
463 static int rk29sdk_wifi_reset(int on)
464 {
465         pr_info("%s: %d\n", __func__, on);
466         //mdelay(100);
467         rk29sdk_wifi_reset_state = on;
468         return 0;
469 }
470
471 int rk29sdk_wifi_set_carddetect(int val)
472 {
473         pr_info("%s:%d\n", __func__, val);
474         rk29sdk_wifi_cd = val;
475         if (wifi_status_cb){
476                 wifi_status_cb(val, wifi_status_cb_devid);
477         }else {
478                 pr_warning("%s, nobody to notify\n", __func__);
479         }
480         return 0;
481 }
482 EXPORT_SYMBOL(rk29sdk_wifi_set_carddetect);
483
484 #define WIFI_HOST_WAKE RK2928_PIN3_PC0
485
486 static struct resource resources[] = {
487         {
488                 .start = WIFI_HOST_WAKE,
489                 .flags = IORESOURCE_IRQ,
490                 .name = "bcmdhd_wlan_irq",
491         },
492 };
493
494 static struct wifi_platform_data rk29sdk_wifi_control = {
495         .set_power = rk29sdk_wifi_power,
496         .set_reset = rk29sdk_wifi_reset,
497         .set_carddetect = rk29sdk_wifi_set_carddetect,
498         .mem_prealloc   = rk29sdk_mem_prealloc,
499 };
500
501 static struct platform_device rk29sdk_wifi_device = {
502         .name = "bcmdhd_wlan",
503         .id = 1,
504         .num_resources = ARRAY_SIZE(resources),
505         .resource = resources,
506         .dev = {
507                 .platform_data = &rk29sdk_wifi_control,
508          },
509 };
510 #endif
511
512
513 #endif // endif --#ifdef CONFIG_SDMMC_RK29
514