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
7 #include <linux/module.h>
\r
8 #include <linux/init.h>
\r
9 #include <linux/slab.h>
\r
11 #include "hw_test.h"
\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
20 static const struct sdio_device_id hw_sdio_id_tbl[] = {
\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
29 MODULE_LICENSE("GPL");
\r
30 MODULE_DEVICE_TABLE(sdio, hw_sdio_id_tbl);
\r
32 static int hw_sdio_probe (
\r
33 struct sdio_func *func,
\r
34 const struct sdio_device_id *id
\r
37 static void hw_sdio_remove (
\r
38 struct sdio_func *func
\r
40 INT32 read_card_info(struct sdio_func * func,UINT32 offset,PUINT32 pbuf,UINT32 len);
\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
49 UINT8 read_sdio_card_register_by_cmd52(struct sdio_func * func)
\r
54 sdio_claim_host(func);
\r
55 val = sdio_f0_readb(func,0x03,&ret);
\r
56 sdio_release_host(func);
\r
58 HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52 fail!\n");
\r
61 HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52:0x%08x\n",val);
\r
66 UINT32 read_sdio_card_register_by_cmd53(struct sdio_func * func)
\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
77 HWTEST_INFO_FUNC("read sdio register by cmd53:0x%08x\n",val);
\r
82 UINT16 read_sdio_card_cccr_register(struct sdio_func * func)
\r
88 sdio_claim_host(func);
\r
89 val1 = sdio_f0_readb(func,0x110,&ret);
\r
90 sdio_release_host(func);
\r
92 HWTEST_INFO_FUNC("read sdio cccr register fail!\n");
\r
95 HWTEST_INFO_FUNC("read current function blksize_first byte:0x%08x\n",val1);
\r
98 sdio_claim_host(func);
\r
99 val2 = sdio_f0_readb(func,0x111,&ret);
\r
100 sdio_release_host(func);
\r
102 HWTEST_INFO_FUNC("read sdio cccr register fail!\n");
\r
105 HWTEST_INFO_FUNC("read current function blksize_second byte:0x%08x\n",val2);
\r
107 result = val2 << 8;
\r
112 static int hw_sdio_probe (struct sdio_func *func,const struct sdio_device_id *id)
\r
117 HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);
\r
119 HWTEST_INFO_FUNC("func pointer is null!\n");
\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
128 g_read_card_info_bysdio = (char **)kmalloc((func->card->num_info) * sizeof(char*),GFP_KERNEL);
\r
132 for(i = 0; i < func->card->num_info;i++){
\r
134 HWTEST_INFO_FUNC("card info str(%d) strlen = %d\n",i,strlen(func->card->info[i]));
\r
136 if(!g_read_card_info_bysdio[i]){
\r
137 HWTEST_INFO_FUNC("kmalloc buffer fail!\n");
\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
146 g_read_card_info_bysdio[i] = kmalloc(128,GFP_KERNEL);
\r
147 memset(g_read_card_info_bysdio[i],0,128);
\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
162 sdio_claim_host(func);
\r
163 sdio_enable_func(func);
\r
164 sdio_release_host(func);
\r
166 sdio_claim_host(func);
\r
167 sdio_set_block_size(func, 512);
\r
168 sdio_release_host(func);
\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
174 HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);
\r
178 static void hw_sdio_remove (struct sdio_func *func)
\r
181 HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);
\r
184 HWTEST_INFO_FUNC("func pointer is null!\n");
\r
188 for(i = 0; i < func->card->num_info;i++){
\r
190 if(g_read_card_info_bysdio[i]){
\r
191 kfree(g_read_card_info_bysdio[i]);
\r
195 kfree(g_read_card_info_bysdio);
\r
197 HWTEST_INFO_FUNC("%s:sdio func(0x%p) is removed successfully!\n", __FUNCTION__, func);
\r
199 HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);
\r
203 static int __init hw_sdio_init(void)
\r
207 HWTEST_INFO_FUNC("%s start \n",__FUNCTION__);
\r
209 //register to mmc driver
\r
210 ret = sdio_register_driver(&hw_sdio_client_drv);
\r
212 HWTEST_INFO_FUNC("sdio_register_driver() ret=%d\n", ret);
\r
213 HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);
\r
218 static void __exit hw_sdio_exit(void)
\r
222 HWTEST_INFO_FUNC("%s start \n", __FUNCTION__);
\r
224 sdio_unregister_driver(&hw_sdio_client_drv);
\r
227 HWTEST_INFO_FUNC("%s end\n", __FUNCTION__);
\r
231 module_init(hw_sdio_init);
\r
232 module_exit(hw_sdio_exit);
\r