xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/platforms/rk3126-generic-wlan.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2015 South Silicon Valley Microelectronics Inc.
3  * Copyright (c) 2015 iComm Corporation
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <linux/irq.h>
18 #include <linux/version.h>
19 #include <linux/module.h>
20 #include <linux/vmalloc.h>
21 #include <linux/gpio.h>
22 #include <linux/mmc/host.h>
23 #include <linux/delay.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/semaphore.h>
26 #include <linux/platform_device.h>
27 #ifdef CONFIG_HAS_WAKELOCK
28 #include <linux/wakelock.h>
29 #endif
30 #include <asm/io.h>
31 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
32 #include <linux/printk.h>
33 #include <linux/err.h>
34 #else
35 #include <config/printk.h>
36 #endif
37 #if LINUX_VERSION_CODE > KERNEL_VERSION(3,2,0)
38 #include <linux/wlan_plat.h>
39 #else
40 struct wifi_platform_data {
41     int (*set_power)(int val);
42     int (*set_reset)(int val);
43     int (*set_carddetect)(int val);
44     void *(*mem_prealloc)(int section, unsigned long size);
45     int (*get_mac_addr)(unsigned char *buf);
46     void *(*get_country_code)(char *ccode);
47 };
48 #endif
49 extern int rockchip_wifi_power(int on);
50 extern int rockchip_wifi_set_carddetect(int val);
51 extern int ssv6xxx_get_dev_status(void);
52 static struct wifi_platform_data *wifi_control_data = NULL;
53 #define GPIO_REG_WRITEL(val,reg) do{__raw_writel(val, CTL_PIN_BASE + (reg));}while(0)
54 unsigned int oob_irq = 0;
55 static int g_wifidev_registered = 0;
56 static struct semaphore wifi_control_sem;
57 extern int rockchip_wifi_get_oob_irq(void);
58 extern int ssvdevice_init(void);
59 extern void ssvdevice_exit(void);
60 #ifdef CONFIG_SSV_SUPPORT_AES_ASM
61 extern int aes_init(void);
62 extern void aes_fini(void);
63 extern int sha1_mod_init(void);
64 extern void sha1_mod_fini(void);
65 #endif
66 #ifdef CONFIG_HAS_WAKELOCK
67 struct wake_lock icomm_wake_lock;
68 #endif
icomm_wifi_power(int on)69 static int icomm_wifi_power(int on)
70 {
71     printk("%s: %d\n", __func__, on);
72     rockchip_wifi_power(on);
73     return 0;
74 }
icomm_wifi_set_carddetect(int val)75 int icomm_wifi_set_carddetect(int val)
76 {
77     rockchip_wifi_set_carddetect(val);
78     return 0;
79 }
80 static struct wifi_platform_data icomm_wifi_control = {
81     .set_power = icomm_wifi_power,
82     .set_carddetect = icomm_wifi_set_carddetect,
83 };
icomm_wifi_device_release(struct device * dev)84 void icomm_wifi_device_release(struct device *dev)
85 {
86     printk("%s\n", __func__);
87 }
88 static struct platform_device icomm_wifi_device = {
89     .name = "icomm_wlan",
90     .id = 1,
91     .dev = {
92             .platform_data = &icomm_wifi_control,
93             .release = icomm_wifi_device_release,
94      },
95 };
wifi_set_power(int on,unsigned long msec)96 int wifi_set_power(int on, unsigned long msec)
97 {
98     if (wifi_control_data && wifi_control_data->set_power) {
99         wifi_control_data->set_power(on);
100     }
101     if (msec)
102         msleep(msec);
103     return 0;
104 }
wifi_set_carddetect(int on)105 static int wifi_set_carddetect(int on)
106 {
107     if (wifi_control_data && wifi_control_data->set_carddetect) {
108         wifi_control_data->set_carddetect(on);
109     }
110     return 0;
111 }
wifi_wakeup_irq_handler(int irq,void * dev)112 static irqreturn_t wifi_wakeup_irq_handler(int irq, void *dev)
113 {
114     printk("%s\n", __func__);
115     wake_lock_timeout(&icomm_wake_lock, HZ);
116     return IRQ_HANDLED;
117 }
setup_wifi_wakeup_BB(void)118 void setup_wifi_wakeup_BB(void)
119 {
120     int err;
121     oob_irq = rockchip_wifi_get_oob_irq();
122     if (oob_irq <= 0) {
123         printk("%s: oob_irq NULL\n", __func__);
124         return;
125     }
126     err = request_threaded_irq(oob_irq,
127                                wifi_wakeup_irq_handler,
128                                NULL,
129                                IRQF_TRIGGER_FALLING,
130                                "wlan_wakeup_irq",
131                                NULL);
132     printk("%s: set oob_irq:%d %s\n", __func__, oob_irq, (err < 0) ? "NG": "OK");
133 }
free_wifi_wakeup_BB(void)134 void free_wifi_wakeup_BB(void)
135 {
136     if (oob_irq > 0) {
137         free_irq(oob_irq, NULL);
138         oob_irq = 0;
139     }
140 }
wifi_probe(struct platform_device * pdev)141 static int wifi_probe(struct platform_device *pdev)
142 {
143     struct wifi_platform_data *wifi_ctrl =
144         (struct wifi_platform_data *)(pdev->dev.platform_data);
145     printk("%s\n", __func__);
146     wifi_control_data = wifi_ctrl;
147     wifi_set_power(0, 50);
148     wifi_set_power(1, 50);
149     wifi_set_carddetect(1);
150     msleep(120);
151     up(&wifi_control_sem);
152     return 0;
153 }
wifi_remove(struct platform_device * pdev)154 static int wifi_remove(struct platform_device *pdev)
155 {
156     struct wifi_platform_data *wifi_ctrl =
157         (struct wifi_platform_data *)(pdev->dev.platform_data);
158     printk("%s\n", __func__);
159     wifi_control_data = wifi_ctrl;
160     wifi_set_carddetect(0);
161     msleep(120);
162     wifi_set_power(0, 50);
163 #ifdef CONFIG_HAS_WAKELOCK
164     wake_lock_destroy(&icomm_wake_lock);
165 #endif
166     return 0;
167 }
168 #ifdef CONFIG_PM
wifi_suspend(struct platform_device * pdev,pm_message_t state)169 static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
170 {
171     printk("%s\n", __func__);
172     return 0;
173 }
wifi_resume(struct platform_device * pdev)174 static int wifi_resume(struct platform_device *pdev)
175 {
176     printk("%s\n", __func__);
177 #if 0
178     if (wifi_control_data && wifi_control_data->set_carddetect) {
179         wifi_control_data->set_carddetect(0);
180     }
181     msleep(50);
182     if (wifi_control_data && wifi_control_data->set_carddetect) {
183         wifi_control_data->set_carddetect(1);
184     }
185 #endif
186     return 0;
187 }
188 #endif
189 static struct platform_driver wifi_driver = {
190     .probe = wifi_probe,
191     .remove = wifi_remove,
192 #ifdef CONFIG_PM
193     .suspend = wifi_suspend,
194     .resume = wifi_resume,
195 #endif
196     .driver = {
197     .name = "icomm_wlan",
198     }
199 };
initWlan(void)200 int initWlan(void)
201 {
202     int ret=0;
203 #ifdef CONFIG_HAS_WAKELOCK
204     wake_lock_init(&icomm_wake_lock, WAKE_LOCK_SUSPEND, "ssv6051");
205     wake_lock(&icomm_wake_lock);
206 #endif
207     sema_init(&wifi_control_sem, 0);
208     platform_device_register(&icomm_wifi_device);
209     platform_driver_register(&wifi_driver);
210     g_wifidev_registered = 1;
211     if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
212         ret = -EINVAL;
213         printk(KERN_ALERT "%s: platform_driver_register timeout\n", __FUNCTION__);
214     }
215     ret = ssvdevice_init();
216 #ifdef CONFIG_HAS_WAKELOCK
217     wake_unlock(&icomm_wake_lock);
218 #endif
219     return ret;
220 }
exitWlan(void)221 void exitWlan(void)
222 {
223     if (g_wifidev_registered)
224     {
225         ssvdevice_exit();
226         platform_driver_unregister(&wifi_driver);
227         platform_device_unregister(&icomm_wifi_device);
228         g_wifidev_registered = 0;
229     }
230     return;
231 }
generic_wifi_init_module(void)232 static __init int generic_wifi_init_module(void)
233 {
234     int ret;
235     int time = 5;
236     printk("%s\n", __func__);
237 #ifdef CONFIG_SSV_SUPPORT_AES_ASM
238     sha1_mod_init();
239     aes_init();
240 #endif
241     ret = initWlan();
242  while(time-- > 0)
243  {
244  msleep(500);
245  if(ssv6xxx_get_dev_status() == 1)
246   break;
247  printk("%s : Retry to carddetect\n",__func__);
248  wifi_set_carddetect(0);
249     wifi_set_power(0, 50);
250  msleep(150);
251  wifi_set_power(1, 50);
252  wifi_set_carddetect(1);
253  }
254  return ret;
255 }
generic_wifi_exit_module(void)256 static __exit void generic_wifi_exit_module(void)
257 {
258     printk("%s\n", __func__);
259 #ifdef CONFIG_SSV_SUPPORT_AES_ASM
260     aes_fini();
261     sha1_mod_fini();
262 #endif
263     exitWlan();
264 }
265 EXPORT_SYMBOL(generic_wifi_init_module);
266 EXPORT_SYMBOL(generic_wifi_exit_module);
267 module_init(generic_wifi_init_module);
268 module_exit(generic_wifi_exit_module);
269 MODULE_LICENSE("Dual BSD/GPL");
270