add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / common / linux / hw_sdio_client.c
1 \r
2 #include <linux/mmc/card.h>\r
3 #include <linux/mmc/host.h>\r
4 #include <linux/mmc/sdio_func.h>\r
5 #include <linux/mmc/sdio_ids.h>\r
6 \r
7 #include <linux/module.h>\r
8 #include <linux/init.h>\r
9 #include <linux/slab.h>\r
10 \r
11 #include "hw_test.h"\r
12 \r
13 \r
14 \r
15 extern unsigned char** g_read_card_info_bysdio;\r
16 extern UINT8 g_read_current_io_isready_from_sdio_card;\r
17 extern UINT16 g_read_function_blksize_from_sdio_card;\r
18 extern UINT32 g_read_int_from_sdio_card;\r
19 \r
20 static const struct sdio_device_id hw_sdio_id_tbl[] = {\r
21 \r
22     /* MT6620 */ /* Not an SDIO standard class device */\r
23     { SDIO_DEVICE(0x037A, 0x020A) }, /* SDIO1:FUNC1:WIFI */\r
24     { SDIO_DEVICE(0x037A, 0x020B) }, /* SDIO2:FUNC1:BT+FM+GPS */\r
25     { SDIO_DEVICE(0x037A, 0x020C) }, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */\r
26         {},\r
27 };\r
28 \r
29 MODULE_LICENSE("GPL");\r
30 MODULE_DEVICE_TABLE(sdio, hw_sdio_id_tbl);\r
31 \r
32 static int hw_sdio_probe (\r
33     struct sdio_func *func,\r
34     const struct sdio_device_id *id\r
35     );\r
36 \r
37 static void hw_sdio_remove (\r
38     struct sdio_func *func\r
39     );\r
40 INT32 read_card_info(struct sdio_func * func,UINT32 offset,PUINT32 pbuf,UINT32 len);\r
41 \r
42 static struct sdio_driver hw_sdio_client_drv = {\r
43     .name = "hw_sdio_client", /* MTK SDIO Client Driver */\r
44     .id_table = hw_sdio_id_tbl, /* all supported struct sdio_device_id table */\r
45     .probe = hw_sdio_probe,\r
46     .remove = hw_sdio_remove,\r
47 };\r
48 \r
49 UINT8 read_sdio_card_register_by_cmd52(struct sdio_func * func)\r
50 {\r
51         UINT8  val;\r
52         INT32 ret = -1;\r
53         \r
54         sdio_claim_host(func);\r
55         val = sdio_f0_readb(func,0x03,&ret);\r
56         sdio_release_host(func);\r
57         if(val == 0xff){\r
58                 HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52 fail!\n");\r
59                 return -1;\r
60         }else{\r
61                 HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52:0x%08x\n",val);\r
62                 return val;\r
63         }\r
64 }\r
65 \r
66 UINT32 read_sdio_card_register_by_cmd53(struct sdio_func * func)\r
67 {\r
68         UINT32 val;\r
69         INT32 ret = -1;\r
70         sdio_claim_host(func);\r
71         val = sdio_readl(func,0x0000,&ret);\r
72         sdio_release_host(func);\r
73         if(val == 0xffffffff){\r
74                 HWTEST_INFO_FUNC("read sdio register by cmd53 fail!\n");\r
75                 return -1;\r
76         }else{\r
77                 HWTEST_INFO_FUNC("read sdio register by cmd53:0x%08x\n",val);\r
78                 return val;\r
79         }\r
80 }\r
81 \r
82 UINT16 read_sdio_card_cccr_register(struct sdio_func * func)\r
83 {\r
84         UINT8 val1, val2;\r
85         INT32 ret = -1;\r
86         UINT16 result = 0;\r
87         \r
88         sdio_claim_host(func);\r
89         val1 = sdio_f0_readb(func,0x110,&ret);\r
90         sdio_release_host(func);\r
91         if(val1 == 0xff){\r
92                 HWTEST_INFO_FUNC("read sdio cccr register fail!\n");\r
93                 return -1;\r
94         }else{\r
95                 HWTEST_INFO_FUNC("read current function blksize_first byte:0x%08x\n",val1);\r
96         }\r
97         \r
98         sdio_claim_host(func);\r
99         val2 = sdio_f0_readb(func,0x111,&ret);\r
100         sdio_release_host(func);\r
101         if(val2 == 0xff){\r
102                 HWTEST_INFO_FUNC("read sdio cccr register fail!\n");\r
103                 return -1;\r
104         }else{\r
105                 HWTEST_INFO_FUNC("read current function blksize_second byte:0x%08x\n",val2);\r
106         }\r
107         result = val2 << 8;\r
108         result |= val1;\r
109         return result;\r
110 }\r
111 \r
112 static int hw_sdio_probe (struct sdio_func *func,const struct sdio_device_id *id)\r
113 {\r
114         int i = 0;\r
115         char buf[128];\r
116         \r
117         HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);\r
118     if(!func){\r
119                 HWTEST_INFO_FUNC("func pointer is null!\n");\r
120                 return -1;\r
121         }\r
122 \r
123     //4 <0> display debug information\r
124     HWTEST_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num);\r
125     for (i = 0;i < func->card->num_info;i++) {\r
126         HWTEST_INFO_FUNC("card->info[%d]: %s\n", i, func->card->info[i]);\r
127     }\r
128         g_read_card_info_bysdio = (char **)kmalloc((func->card->num_info) * sizeof(char*),GFP_KERNEL);\r
129 \r
130 \r
131         \r
132         for(i = 0; i < func->card->num_info;i++){\r
133 \r
134                 HWTEST_INFO_FUNC("card info str(%d) strlen = %d\n",i,strlen(func->card->info[i]));\r
135                 \r
136                 if(!g_read_card_info_bysdio[i]){\r
137                         HWTEST_INFO_FUNC("kmalloc buffer fail!\n");\r
138                         return -2;\r
139                 }\r
140                 if(0 != strlen(func->card->info[i])){\r
141                         g_read_card_info_bysdio[i] = kmalloc(strlen(func->card->info[i]) * sizeof(char),GFP_KERNEL);\r
142                         strcpy(g_read_card_info_bysdio[i],func->card->info[i]);\r
143                         HWTEST_INFO_FUNC("g_read_card_info_bysdio[%d] = %s\n",i,g_read_card_info_bysdio[i]);\r
144                 }\r
145                 else{\r
146                         g_read_card_info_bysdio[i] = kmalloc(128,GFP_KERNEL);\r
147                         memset(g_read_card_info_bysdio[i],0,128);\r
148                 }\r
149         }\r
150         \r
151 \r
152         sprintf(buf,"verdor is 0x%x,device is 0x%x,func number is 0x%x",func->vendor,func->device,func->num);\r
153         HWTEST_INFO_FUNC("buf = %s\n",buf);\r
154         for(i = 0; i < func->card->num_info;i++){\r
155                 if(!g_read_card_info_bysdio[i][0]){\r
156                         strcpy(g_read_card_info_bysdio[i],buf);\r
157                         break;\r
158                 }\r
159         }\r
160         \r
161 \r
162         sdio_claim_host(func);\r
163     sdio_enable_func(func);\r
164     sdio_release_host(func);\r
165 \r
166         sdio_claim_host(func);\r
167         sdio_set_block_size(func, 512);\r
168         sdio_release_host(func);\r
169                 \r
170         g_read_current_io_isready_from_sdio_card = read_sdio_card_register_by_cmd52(func);\r
171         g_read_function_blksize_from_sdio_card = read_sdio_card_cccr_register(func);\r
172         g_read_int_from_sdio_card = read_sdio_card_register_by_cmd53(func);\r
173         \r
174         HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);\r
175         return 0;\r
176 }\r
177 \r
178 static void hw_sdio_remove (struct sdio_func *func)\r
179 {\r
180         int i = 0;\r
181         HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);\r
182 \r
183         if(!func){\r
184                 HWTEST_INFO_FUNC("func pointer is null!\n");\r
185                 return;\r
186         }\r
187 \r
188         for(i = 0; i < func->card->num_info;i++){\r
189 \r
190                 if(g_read_card_info_bysdio[i]){\r
191                         kfree(g_read_card_info_bysdio[i]);\r
192                 }\r
193         }\r
194 \r
195         kfree(g_read_card_info_bysdio);\r
196         \r
197         HWTEST_INFO_FUNC("%s:sdio func(0x%p) is removed successfully!\n", __FUNCTION__, func);\r
198         \r
199         HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);\r
200 }\r
201 \r
202 \r
203 static int __init hw_sdio_init(void)\r
204 {\r
205     int   ret = 0;\r
206         \r
207         HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);\r
208 \r
209     //register to mmc driver\r
210     ret = sdio_register_driver(&hw_sdio_client_drv);\r
211         \r
212         HWTEST_INFO_FUNC("sdio_register_driver() ret=%d\n", ret);\r
213         HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);\r
214 \r
215     return ret;\r
216 }\r
217 \r
218 static void __exit hw_sdio_exit(void)\r
219 {\r
220         int   ret = 0;\r
221 \r
222     HWTEST_INFO_FUNC("%s start \n", __FUNCTION__);\r
223 \r
224     sdio_unregister_driver(&hw_sdio_client_drv);\r
225 \r
226 \r
227     HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);\r
228     return;\r
229\r
230 \r
231 module_init(hw_sdio_init);\r
232 module_exit(hw_sdio_exit);\r
233 \r