wifi->esp8089:
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_driver / esp_ext.c
1 /*
2  * Copyright (c) 2010 -2013 Espressif System.
3  *
4  *   extended gpio
5  *    - interface for other driver or kernel
6  *    - gpio control
7  *
8  */
9
10 #ifdef USE_EXT_GPIO
11
12 #include <net/cfg80211.h>
13 #include <linux/skbuff.h>
14 #include <linux/bitops.h>
15 #include <linux/version.h>
16 #include <linux/mmc/card.h>
17 #include <linux/mmc/mmc.h>
18 #include <linux/mmc/host.h>
19 #include <linux/mmc/sdio_func.h>
20 #include <linux/mmc/sdio_ids.h>
21 #include <linux/mmc/sdio.h>
22 #include <linux/mmc/sd.h>
23 #include <linux/completion.h>
24
25 #include "esp_ext.h"
26 #include "esp_debug.h"
27 #include "esp_sip.h"
28 #include "esp_sif.h"
29
30 #ifdef EXT_GPIO_OPS
31 extern void register_ext_gpio_ops(struct esp_ext_gpio_ops *ops);
32 extern void unregister_ext_gpio_ops(void);
33
34 static struct esp_ext_gpio_ops ext_gpio_ops = {
35         .gpio_request    = ext_gpio_request,                             /* gpio_request gpio_no from 0x0 to 0xf*/
36         .gpio_release    = ext_gpio_release,                             /* gpio_release */
37         .gpio_set_mode   = ext_gpio_set_mode,                            /* gpio_set_mode, data is irq_func of irq_mode , default level of output_mode */
38         .gpio_get_mode   = ext_gpio_get_mode,                            /* gpio_get_mode, current mode */
39         .gpio_set_state  = ext_gpio_set_output_state,                    /* only output state, high level or low level */
40         .gpio_get_state  = ext_gpio_get_state,                           /* current state */
41         .irq_ack         = ext_irq_ack,                                  /* ack interrupt */
42 };
43
44
45 #endif
46
47 static struct esp_pub *ext_epub = NULL;
48
49 static u16 intr_mask_reg = 0x0000;
50 struct workqueue_struct *ext_irq_wkq = NULL;
51 struct work_struct ext_irq_work;
52 static struct mutex ext_mutex_lock;
53
54 static struct ext_gpio_info gpio_list[EXT_GPIO_MAX_NUM] = {
55         { 0, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
56         { 1, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
57         { 2, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
58         { 3, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
59         { 4, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
60         { 5, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
61         { 6, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
62         { 7, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
63         { 8, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
64         { 9, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
65         {10, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
66         {11, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
67         {12, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
68         {13, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
69         {14, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
70         {15, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL},
71 };
72
73 static struct pending_intr_list_info esp_pending_intr_list = {
74         .start_pos = 0,
75         .end_pos = 0,
76         .curr_num = 0,
77 };
78
79 u16 ext_gpio_get_int_mask_reg(void)
80 {
81         return intr_mask_reg;
82 }
83
84 int ext_gpio_request(int gpio_no)
85 {
86         if (ext_epub == NULL || ext_epub->sip == NULL ||
87                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
88                 esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", __func__);
89                 return -ENOTRECOVERABLE;
90         }
91
92         mutex_lock(&ext_mutex_lock);
93
94         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
95                 mutex_unlock(&ext_mutex_lock);
96                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
97                 return -ERANGE;
98         }
99
100         if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_DISABLE) {
101                 mutex_unlock(&ext_mutex_lock);
102                 esp_dbg(ESP_DBG_ERROR, "%s gpio is already in used by other\n", __func__);
103                 return -EPERM;
104         } else {
105                 gpio_list[gpio_no].gpio_mode = EXT_GPIO_MODE_MAX;
106                 mutex_unlock(&ext_mutex_lock);
107                 return 0;
108         }
109 }
110 EXPORT_SYMBOL(ext_gpio_request);
111         
112 int ext_gpio_release(int gpio_no)
113 {
114         int ret;
115
116         if (ext_epub == NULL || ext_epub->sip == NULL ||
117                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
118                 esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", __func__);
119                 return -ENOTRECOVERABLE;
120         }
121
122         mutex_lock(&ext_mutex_lock);
123
124         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
125                 mutex_unlock(&ext_mutex_lock);
126                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
127                 return -ERANGE;
128         }
129         sif_lock_bus(ext_epub);
130         ret = sif_config_gpio_mode(ext_epub, (u8)gpio_no, EXT_GPIO_MODE_DISABLE);
131         sif_unlock_bus(ext_epub);       
132         if (ret) {
133                 esp_dbg(ESP_DBG_ERROR, "%s gpio release error\n", __func__);
134                 mutex_unlock(&ext_mutex_lock);
135                 return ret;
136         }
137
138         gpio_list[gpio_no].gpio_mode  = EXT_GPIO_MODE_DISABLE;
139         gpio_list[gpio_no].gpio_state  = EXT_GPIO_STATE_IDLE;
140         gpio_list[gpio_no].irq_handler = NULL;
141         intr_mask_reg &= ~(1<<gpio_no);
142         
143         mutex_unlock(&ext_mutex_lock);
144
145         return 0;
146 }
147 EXPORT_SYMBOL(ext_gpio_release);
148
149 int ext_gpio_set_mode(int gpio_no, int mode, void *data)
150 {
151         u8 gpio_mode;
152         int ret;
153         struct ext_gpio_info backup_info;
154
155         if (ext_epub == NULL || ext_epub->sip == NULL ||
156                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
157                 esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__);
158                 return -ENOTRECOVERABLE;
159         }
160
161         mutex_lock(&ext_mutex_lock);
162
163         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
164                 mutex_unlock(&ext_mutex_lock);
165                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
166                 return -ERANGE;
167         }
168
169         if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_DISABLE) {
170                 mutex_unlock(&ext_mutex_lock);
171                 esp_dbg(ESP_DBG_ERROR, "%s gpio is not in occupy, please request gpio\n", __func__);
172                 return -ENOTRECOVERABLE;
173         }
174
175         if (mode <= EXT_GPIO_MODE_OOB || mode >= EXT_GPIO_MODE_MAX) {
176                 mutex_unlock(&ext_mutex_lock);
177                 esp_dbg(ESP_DBG_ERROR, "%s gpio mode unknown\n", __func__);
178                 return -EOPNOTSUPP;
179         }
180
181         memcpy(&backup_info, &gpio_list[gpio_no], sizeof(struct ext_gpio_info));
182
183         gpio_list[gpio_no].gpio_mode = mode;
184         gpio_mode = (u8)mode;
185
186         switch (mode) {
187                 case EXT_GPIO_MODE_INTR_POSEDGE:
188                 case EXT_GPIO_MODE_INTR_NEGEDGE:
189                 case EXT_GPIO_MODE_INTR_LOLEVEL:
190                 case EXT_GPIO_MODE_INTR_HILEVEL:
191                         if (!data) {
192                                 memcpy(&gpio_list[gpio_no], &backup_info, sizeof(struct ext_gpio_info));
193                                 esp_dbg(ESP_DBG_ERROR, "%s irq_handler is NULL\n", __func__);
194                                 mutex_unlock(&ext_mutex_lock);
195                                 return -EINVAL;
196                         }
197                         gpio_list[gpio_no].irq_handler = (ext_irq_handler_t)data;
198                         intr_mask_reg |= (1<<gpio_no);
199                         break;
200                 case EXT_GPIO_MODE_OUTPUT:
201                         if (!data) {
202                                 memcpy(&gpio_list[gpio_no], &backup_info, sizeof(struct ext_gpio_info));
203                                 esp_dbg(ESP_DBG_ERROR, "%s output default value is NULL\n", __func__);
204                                 mutex_unlock(&ext_mutex_lock);
205                                 return -EINVAL;
206                         }
207                         *(int *)data = (*(int *)data == 0 ? 0 : 1);
208                         gpio_mode = (u8)(((*(int *)data)<<4) | gpio_mode);
209                 default:
210                         gpio_list[gpio_no].irq_handler = NULL;
211                         intr_mask_reg &= ~(1<<gpio_no);
212                         break;
213         }
214
215         sif_lock_bus(ext_epub);
216         ret = sif_config_gpio_mode(ext_epub, (u8)gpio_no, gpio_mode);
217         sif_unlock_bus(ext_epub);
218         if (ret) {
219                 memcpy(&gpio_list[gpio_no], &backup_info, sizeof(struct ext_gpio_info));
220                 esp_dbg(ESP_DBG_ERROR, "%s gpio set error\n", __func__);
221                 mutex_unlock(&ext_mutex_lock);
222                 return ret;
223         }
224
225         mutex_unlock(&ext_mutex_lock);
226         return 0;
227 }
228 EXPORT_SYMBOL(ext_gpio_set_mode);
229
230 int ext_gpio_get_mode(int gpio_no)
231 {
232         int gpio_mode;
233
234         if (ext_epub == NULL || ext_epub->sip == NULL ||
235                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
236                 esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__);
237                 return -ENOTRECOVERABLE;
238         }
239
240         mutex_lock(&ext_mutex_lock);
241
242         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
243                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
244                 mutex_unlock(&ext_mutex_lock);
245                 return -ERANGE;
246         }
247
248         gpio_mode = gpio_list[gpio_no].gpio_mode;
249
250         mutex_unlock(&ext_mutex_lock);
251
252         return gpio_mode;
253 }
254 EXPORT_SYMBOL(ext_gpio_get_mode);
255
256
257 int ext_gpio_set_output_state(int gpio_no, int state)
258 {
259         int ret;
260
261         if (ext_epub == NULL || ext_epub->sip == NULL ||
262                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
263                 esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__);
264                 return -ENOTRECOVERABLE;
265         }
266
267         mutex_lock(&ext_mutex_lock);
268
269         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
270                 mutex_unlock(&ext_mutex_lock);
271                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
272                 return -ERANGE;
273         }
274
275         if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_OUTPUT) {
276                 mutex_unlock(&ext_mutex_lock);
277                 esp_dbg(ESP_DBG_ERROR, "%s gpio is not in output state, please request gpio or set output state\n", __func__);
278                 return -EOPNOTSUPP;
279         }
280
281         if (state != EXT_GPIO_STATE_LOW && state != EXT_GPIO_STATE_HIGH) {
282                 mutex_unlock(&ext_mutex_lock);
283                 esp_dbg(ESP_DBG_ERROR, "%s gpio state unknown\n", __func__);
284                 return -ENOTRECOVERABLE;
285         }
286
287         sif_lock_bus(ext_epub);
288         ret = sif_set_gpio_output(ext_epub, 1<<gpio_no, state<<gpio_no);
289         sif_unlock_bus(ext_epub);       
290         if (ret) {
291                 esp_dbg(ESP_DBG_ERROR, "%s gpio state set error\n", __func__);
292                 mutex_unlock(&ext_mutex_lock);
293                 return ret;
294         }
295         gpio_list[gpio_no].gpio_state = state;
296         
297         mutex_unlock(&ext_mutex_lock);
298
299         return 0;
300 }
301 EXPORT_SYMBOL(ext_gpio_set_output_state);
302
303 int ext_gpio_get_state(int gpio_no)
304 {
305         int ret;
306         u16 state;
307         u16 mask;
308
309         if (ext_epub == NULL || ext_epub->sip == NULL ||
310                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
311                 esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__);
312                 return -ENOTRECOVERABLE;
313         }
314
315         mutex_lock(&ext_mutex_lock);
316
317         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
318                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
319                 mutex_unlock(&ext_mutex_lock);
320                 return -ERANGE;
321         }
322
323         if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_OUTPUT) {
324                 state = gpio_list[gpio_no].gpio_state;
325          } else if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_INPUT) {
326                 sif_lock_bus(ext_epub);
327                 ret = sif_get_gpio_input(ext_epub, &mask, &state);
328                 sif_unlock_bus(ext_epub);
329                 if (ret) {
330                         esp_dbg(ESP_DBG_ERROR, "%s get gpio_input state error\n", __func__);
331                         mutex_unlock(&ext_mutex_lock);
332                         return ret;
333                 }       
334          } else {
335                 esp_dbg(ESP_DBG_ERROR, "%s gpio_state is not input or output\n", __func__);
336                 mutex_unlock(&ext_mutex_lock);
337                 return -EOPNOTSUPP;
338         }
339         mutex_unlock(&ext_mutex_lock);
340
341         return (state & (1<<gpio_no)) ? 1 : 0;
342 }
343 EXPORT_SYMBOL(ext_gpio_get_state);
344
345 int ext_irq_ack(int gpio_no)
346 {
347         int ret;
348
349         if (ext_epub == NULL || ext_epub->sip == NULL ||
350                         atomic_read(&ext_epub->sip->state) != SIP_RUN) {
351                 esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__);
352                 return -ENOTRECOVERABLE;
353         }
354
355         mutex_lock(&ext_mutex_lock);
356         if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) {
357                 esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__);
358                 mutex_unlock(&ext_mutex_lock);
359                 return -ERANGE;
360         }
361
362         if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_POSEDGE 
363                         && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_NEGEDGE
364                         && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_LOLEVEL
365                         && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_HILEVEL) {
366                 esp_dbg(ESP_DBG_ERROR, "%s gpio mode is not intr mode\n", __func__);
367                 mutex_unlock(&ext_mutex_lock);
368                 return -ENOTRECOVERABLE;
369         }
370
371         sif_lock_bus(ext_epub);
372         ret = sif_set_gpio_output(ext_epub, 0x00, 1<<gpio_no);
373         sif_unlock_bus(ext_epub);
374         if (ret) {
375                 esp_dbg(ESP_DBG_ERROR, "%s gpio intr ack error\n", __func__);
376                 mutex_unlock(&ext_mutex_lock);
377                 return ret;
378         }
379
380         mutex_unlock(&ext_mutex_lock);
381         return 0;
382 }
383 EXPORT_SYMBOL(ext_irq_ack);
384
385 void show_status(void)
386 {
387         int i=0;
388         for (i = 0; i < MAX_PENDING_INTR_LIST;i++)
389                 esp_dbg(ESP_DBG_ERROR, "status[%d] = [0x%04x]\n", i, esp_pending_intr_list.pending_intr_list[i]);
390
391         esp_dbg(ESP_DBG_ERROR, "start_pos[%d]\n",esp_pending_intr_list.start_pos);
392         esp_dbg(ESP_DBG_ERROR, "end_pos[%d]\n",esp_pending_intr_list.end_pos);
393         esp_dbg(ESP_DBG_ERROR, "curr_num[%d]\n",esp_pending_intr_list.curr_num);
394         
395 }
396 void esp_tx_work(struct work_struct *work)
397 {
398         int i;
399         u16 tmp_intr_status_reg;
400
401         esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__);
402
403         spin_lock(&esp_pending_intr_list.spin_lock);
404
405         tmp_intr_status_reg = esp_pending_intr_list.pending_intr_list[esp_pending_intr_list.start_pos];
406         
407         esp_pending_intr_list.pending_intr_list[esp_pending_intr_list.start_pos] = 0x0000;
408         esp_pending_intr_list.start_pos = (esp_pending_intr_list.start_pos + 1) % MAX_PENDING_INTR_LIST;
409         esp_pending_intr_list.curr_num--;
410         
411         spin_unlock(&esp_pending_intr_list.spin_lock);
412         
413         for (i = 0; i < EXT_GPIO_MAX_NUM; i++) {
414                 if (tmp_intr_status_reg & (1<<i) && (gpio_list[i].irq_handler))
415                         gpio_list[i].irq_handler();
416         }
417
418         spin_lock(&esp_pending_intr_list.spin_lock);
419         if (esp_pending_intr_list.curr_num > 0)
420                 queue_work(ext_irq_wkq, &ext_irq_work);
421         spin_unlock(&esp_pending_intr_list.spin_lock);
422 }
423
424 void ext_gpio_int_process(u16 value) {
425         if (value == 0x00)
426                 return;
427
428         esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__);
429
430         /* intr cycle queue is full, wait */
431         while (esp_pending_intr_list.curr_num >= MAX_PENDING_INTR_LIST)
432         {
433                 udelay(1);
434         }
435
436         spin_lock(&esp_pending_intr_list.spin_lock);
437         
438         esp_pending_intr_list.pending_intr_list[esp_pending_intr_list.end_pos] = value;
439         esp_pending_intr_list.end_pos = (esp_pending_intr_list.end_pos + 1) % MAX_PENDING_INTR_LIST;
440         esp_pending_intr_list.curr_num++;
441
442         queue_work(ext_irq_wkq, &ext_irq_work);
443         
444         spin_unlock(&esp_pending_intr_list.spin_lock);
445 }
446
447 int ext_gpio_init(struct esp_pub *epub)
448 {
449         esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__);
450
451         ext_irq_wkq = create_singlethread_workqueue("esp_ext_irq_wkq");
452         if (ext_irq_wkq == NULL) {
453                 esp_dbg(ESP_DBG_ERROR, "%s create workqueue error\n", __func__);
454                 return -EACCES;
455         }
456
457         INIT_WORK(&ext_irq_work, esp_tx_work);
458         mutex_init(&ext_mutex_lock);
459
460         ext_epub = epub;
461
462         if (ext_epub == NULL)
463                 return -EINVAL;
464
465 #ifdef EXT_GPIO_OPS
466         register_ext_gpio_ops(&ext_gpio_ops);
467 #endif
468         
469         return 0;
470 }
471
472 void ext_gpio_deinit(void)
473 {
474         esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__);
475
476 #ifdef EXT_GPIO_OPS
477         unregister_ext_gpio_ops();
478 #endif
479         ext_epub = NULL;
480         cancel_work_sync(&ext_irq_work);
481
482         if (ext_irq_wkq)
483                 destroy_workqueue(ext_irq_wkq);
484
485 }
486
487 #endif /* USE_EXT_GPIO */