2 #include "hif_sdio_chrdev.h"
6 static int hif_sdio_proc(void * pvData);
7 static int hif_sdio_open(struct inode *inode, struct file *file);
8 static int hif_sdio_release(struct inode *inode, struct file *file);
9 static long hif_sdio_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
10 static ssize_t hif_sdio_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
14 unsigned int hifSdioMajor = 0;
16 #define COMBO_IOC_MAGIC 'h'
17 #define COMBO_IOCTL_GET_CHIP_ID _IOR(COMBO_IOC_MAGIC, 0, int)
18 #define COMBO_IOCTL_SET_CHIP_ID _IOW(COMBO_IOC_MAGIC, 1, int)
20 MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = {
21 /* MT6620 */ /* Not an SDIO standard class device */
22 { {SDIO_DEVICE(0x037A, 0x020A)}, 0x6620 }, /* SDIO1:FUNC1:WIFI */
23 { {SDIO_DEVICE(0x037A, 0x020B)}, 0x6620 }, /* SDIO2:FUNC1:BT+FM+GPS */
24 { {SDIO_DEVICE(0x037A, 0x020C)}, 0x6620 }, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */
26 /* MT6628 */ /* SDIO1: Wi-Fi, SDIO2: BGF */
27 { {SDIO_DEVICE(0x037A, 0x6628)}, 0x6628},
33 struct file_operations hifDevOps =
36 .open = hif_sdio_open,
37 .release = hif_sdio_release,
38 .unlocked_ioctl = hif_sdio_unlocked_ioctl,
39 .read = hif_sdio_read,
42 struct class *pHifClass = NULL;
43 struct device *pHifDev = NULL;
44 UCHAR *HifClassName = "hifsdiod";
45 UCHAR *kObjName = "hifsdiod";
48 struct task_struct *gConIdQueryThread;
49 wait_queue_head_t gHifsdiodEvent;
51 //OSAL_THREAD gConIdQueryThread;
52 //OSAL_EVENT gHifsdiodEvent;
53 UCHAR *gConIdQueryName = "consys-id-query";
54 INT32 gComboChipId = -1;
58 INT32 hifsdiod_start(void)
61 init_waitqueue_head(&gHifsdiodEvent);
63 osal_event_init(&gHifsdiodEvent);
64 gConIdQueryThread.pThreadData = (VOID *)NULL;
65 gConIdQueryThread.pThreadFunc = (VOID *)hif_sdio_proc;
66 osal_memcpy(gConIdQueryThread.threadName, gConIdQueryName , osal_strlen(gConIdQueryName));
69 iRet = osal_thread_create(&gConIdQueryThread);
72 HIF_SDIO_ERR_FUNC("osal_thread_create fail...\n");
76 gConIdQueryThread = kthread_create(hif_sdio_proc, NULL, gConIdQueryName);
77 if (NULL == gConIdQueryThread)
79 HIF_SDIO_ERR_FUNC("osal_thread_create fail...\n");
86 /* Start STPd thread*/
87 iRet = osal_thread_run(&gConIdQueryThread);
90 HIF_SDIO_ERR_FUNC("osal_thread_run FAILS\n");
94 if (gConIdQueryThread) {
95 wake_up_process(gConIdQueryThread);
103 HIF_SDIO_INFO_FUNC("succeed\n");
108 HIF_SDIO_ERR_FUNC("failed\n");
113 INT32 hifsdiod_stop(void)
115 if (gConIdQueryThread) {
116 HIF_SDIO_INFO_FUNC("inform hifsdiod exit..\n");
117 kthread_stop(gConIdQueryThread);
118 gConIdQueryThread = NULL;
124 static int hif_sdio_proc(void * pvData)
126 while (!kthread_should_stop())
128 //HIF_SDIO_INFO_FUNC("enter sleep.\n");
130 //HIF_SDIO_INFO_FUNC("wakeup\n");
132 HIF_SDIO_INFO_FUNC("hifsdiod exit.\n");
137 static int hif_sdio_open(struct inode *inode, struct file *file)
139 HIF_SDIO_INFO_FUNC(" ++\n");
140 HIF_SDIO_INFO_FUNC(" --\n");
144 static int hif_sdio_release(struct inode *inode, struct file *file)
146 HIF_SDIO_INFO_FUNC(" ++\n");
147 HIF_SDIO_INFO_FUNC(" --\n");
153 static ssize_t hif_sdio_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
156 HIF_SDIO_INFO_FUNC(" ++\n");
157 HIF_SDIO_INFO_FUNC(" --\n");
162 static long hif_sdio_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
166 HIF_SDIO_DBG_FUNC("cmd (%d)\n", cmd);
170 case COMBO_IOCTL_GET_CHIP_ID:
171 gComboChipId = 0x6628;
172 retval = gComboChipId;
173 HIF_SDIO_INFO_FUNC("get combo chip id: 0x%x\n", gComboChipId);
175 case COMBO_IOCTL_SET_CHIP_ID:
177 HIF_SDIO_INFO_FUNC("set combo chip id to 0x%x\n", gComboChipId);
180 HIF_SDIO_WARN_FUNC("unknown cmd (%d)\n", cmd);
188 INT32 hif_sdio_is_chipid_valid (INT32 chipId)
194 INT32 right = sizeof (gChipInfoArray) / sizeof (gChipInfoArray[0]) - 1;
195 if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId))
198 middle = (left + right) / 2;
200 while (left <= right)
202 if (chipId > gChipInfoArray[middle].chipId)
206 else if (chipId < gChipInfoArray[middle].chipId)
215 middle = (left + right) / 2;
220 HIF_SDIO_ERR_FUNC("no supported chipid found\n");
224 HIF_SDIO_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId);
230 INT32 hif_sdio_match_chipid_by_dev_id (const struct sdio_device_id *id)
232 INT32 maxIndex = sizeof (gChipInfoArray) / sizeof (gChipInfoArray[0]);
234 struct sdio_device_id *localId = NULL;
236 for (index = 0; index < maxIndex; index++)
238 localId = &(gChipInfoArray[index].deviceId);
239 if ((localId->vendor == id->vendor) && (localId->device == id->device))
241 chipId = gChipInfoArray[index].chipId;
242 HIF_SDIO_INFO_FUNC("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, localId->vendor, localId->device, chipId);
243 gComboChipId = chipId;
249 HIF_SDIO_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, id->device);
256 INT32 mtk_wcn_hif_sdio_query_chipid(INT32 waitFlag)
258 UINT32 timeSlotMs = 200;
259 UINT32 maxTimeSlot = 15;
261 //gComboChipId = 0x6628;
264 if (0 <= hif_sdio_is_chipid_valid(gComboChipId))
266 wmt_plat_pwr_ctrl(FUNC_ON);
267 wmt_plat_sdio_ctrl(WMT_SDIO_SLOT_SDIO1, FUNC_ON);
268 while (counter < maxTimeSlot)
270 if (0 <= hif_sdio_is_chipid_valid(gComboChipId))
272 osal_msleep(timeSlotMs);
276 wmt_plat_sdio_ctrl(WMT_SDIO_SLOT_SDIO1, FUNC_OFF);
277 wmt_plat_pwr_ctrl(FUNC_OFF);
280 EXPORT_SYMBOL(mtk_wcn_hif_sdio_query_chipid);
282 INT32 mtk_wcn_hif_sdio_tell_chipid(INT32 chipId)
285 gComboChipId = chipId;
286 HIF_SDIO_INFO_FUNC("set combo chip id to 0x%x\n", gComboChipId);
290 EXPORT_SYMBOL(mtk_wcn_hif_sdio_tell_chipid);
292 INT32 hif_sdio_create_dev_node(void)
297 HIF_SDIO_DBG_FUNC( "++");
298 iResult = register_chrdev(hifSdioMajor, kObjName, &hifDevOps);
301 HIF_SDIO_ERR_FUNC("register_chrdev failed.\n");
306 hifSdioMajor = hifSdioMajor == 0 ? iResult : hifSdioMajor;
307 HIF_SDIO_INFO_FUNC("register_chrdev succeed, mtk_jajor = %d\n", hifSdioMajor);
308 pHifClass = class_create(THIS_MODULE, HifClassName);
309 if(IS_ERR(pHifClass))
311 HIF_SDIO_ERR_FUNC("class_create error\n");
316 pHifDev = device_create(pHifClass, NULL, MKDEV(hifSdioMajor, 0), NULL, HifClassName, "%d", 0);
319 HIF_SDIO_ERR_FUNC("device_create error:%ld\n", PTR_ERR(pHifDev));
324 HIF_SDIO_INFO_FUNC("device_create succeed\n");
333 INT32 hif_sdio_remove_dev_node(void)
337 device_destroy(pHifClass, MKDEV(hifSdioMajor, 0));
340 if(pHifClass != NULL)
342 class_destroy(pHifClass);
346 if(hifSdioMajor != 0)
348 unregister_chrdev(hifSdioMajor, kObjName);