These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / wilc1000 / wilc_sdio.c
1 /* ////////////////////////////////////////////////////////////////////////// */
2 /*  */
3 /* Copyright (c) Atmel Corporation.  All rights reserved. */
4 /*  */
5 /* Module Name:  wilc_sdio.c */
6 /*  */
7 /*  */
8 /* //////////////////////////////////////////////////////////////////////////// */
9
10 #include <linux/string.h>
11 #include "wilc_wlan_if.h"
12 #include "wilc_wlan.h"
13
14 #define WILC_SDIO_BLOCK_SIZE 512
15
16 typedef struct {
17         void *os_context;
18         u32 block_size;
19         int (*sdio_cmd52)(sdio_cmd52_t *);
20         int (*sdio_cmd53)(sdio_cmd53_t *);
21         int (*sdio_set_max_speed)(void);
22         int (*sdio_set_default_speed)(void);
23         wilc_debug_func dPrint;
24         int nint;
25 #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
26         int has_thrpt_enh3;
27 } wilc_sdio_t;
28
29 static wilc_sdio_t g_sdio;
30
31 #ifdef WILC_SDIO_IRQ_GPIO
32 static int sdio_write_reg(u32 addr, u32 data);
33 static int sdio_read_reg(u32 addr, u32 *data);
34 #endif
35
36 /********************************************
37  *
38  *      Function 0
39  *
40  ********************************************/
41
42 static int sdio_set_func0_csa_address(u32 adr)
43 {
44         sdio_cmd52_t cmd;
45
46         /**
47          *      Review: BIG ENDIAN
48          **/
49         cmd.read_write = 1;
50         cmd.function = 0;
51         cmd.raw = 0;
52         cmd.address = 0x10c;
53         cmd.data = (u8)adr;
54         if (!g_sdio.sdio_cmd52(&cmd)) {
55                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n");
56                 goto _fail_;
57         }
58
59         cmd.address = 0x10d;
60         cmd.data = (u8)(adr >> 8);
61         if (!g_sdio.sdio_cmd52(&cmd)) {
62                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n");
63                 goto _fail_;
64         }
65
66         cmd.address = 0x10e;
67         cmd.data = (u8)(adr >> 16);
68         if (!g_sdio.sdio_cmd52(&cmd)) {
69                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n");
70                 goto _fail_;
71         }
72
73         return 1;
74 _fail_:
75         return 0;
76 }
77
78 static int sdio_set_func0_block_size(u32 block_size)
79 {
80         sdio_cmd52_t cmd;
81
82         cmd.read_write = 1;
83         cmd.function = 0;
84         cmd.raw = 0;
85         cmd.address = 0x10;
86         cmd.data = (u8)block_size;
87         if (!g_sdio.sdio_cmd52(&cmd)) {
88                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n");
89                 goto _fail_;
90         }
91
92         cmd.address = 0x11;
93         cmd.data = (u8)(block_size >> 8);
94         if (!g_sdio.sdio_cmd52(&cmd)) {
95                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n");
96                 goto _fail_;
97         }
98
99         return 1;
100 _fail_:
101         return 0;
102 }
103
104 /********************************************
105  *
106  *      Function 1
107  *
108  ********************************************/
109
110 static int sdio_set_func1_block_size(u32 block_size)
111 {
112         sdio_cmd52_t cmd;
113
114         cmd.read_write = 1;
115         cmd.function = 0;
116         cmd.raw = 0;
117         cmd.address = 0x110;
118         cmd.data = (u8)block_size;
119         if (!g_sdio.sdio_cmd52(&cmd)) {
120                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n");
121                 goto _fail_;
122         }
123         cmd.address = 0x111;
124         cmd.data = (u8)(block_size >> 8);
125         if (!g_sdio.sdio_cmd52(&cmd)) {
126                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n");
127                 goto _fail_;
128         }
129
130         return 1;
131 _fail_:
132         return 0;
133 }
134
135 static int sdio_clear_int(void)
136 {
137 #ifndef WILC_SDIO_IRQ_GPIO
138         /* u32 sts; */
139         sdio_cmd52_t cmd;
140
141         cmd.read_write = 0;
142         cmd.function = 1;
143         cmd.raw = 0;
144         cmd.address = 0x4;
145         cmd.data = 0;
146         g_sdio.sdio_cmd52(&cmd);
147
148         return cmd.data;
149 #else
150         u32 reg;
151
152         if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, &reg)) {
153                 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
154                 return 0;
155         }
156         reg &= ~0x1;
157         sdio_write_reg(WILC_HOST_RX_CTRL_0, reg);
158         return 1;
159 #endif
160
161 }
162
163 u32 sdio_xfer_cnt(void)
164 {
165         u32 cnt = 0;
166         sdio_cmd52_t cmd;
167
168         cmd.read_write = 0;
169         cmd.function = 1;
170         cmd.raw = 0;
171         cmd.address = 0x1C;
172         cmd.data = 0;
173         g_sdio.sdio_cmd52(&cmd);
174         cnt = cmd.data;
175
176         cmd.read_write = 0;
177         cmd.function = 1;
178         cmd.raw = 0;
179         cmd.address = 0x1D;
180         cmd.data = 0;
181         g_sdio.sdio_cmd52(&cmd);
182         cnt |= (cmd.data << 8);
183
184         cmd.read_write = 0;
185         cmd.function = 1;
186         cmd.raw = 0;
187         cmd.address = 0x1E;
188         cmd.data = 0;
189         g_sdio.sdio_cmd52(&cmd);
190         cnt |= (cmd.data << 16);
191
192         return cnt;
193 }
194
195 /********************************************
196  *
197  *      Sdio interfaces
198  *
199  ********************************************/
200 int sdio_check_bs(void)
201 {
202         sdio_cmd52_t cmd;
203
204         /**
205          *      poll until BS is 0
206          **/
207         cmd.read_write = 0;
208         cmd.function = 0;
209         cmd.raw = 0;
210         cmd.address = 0xc;
211         cmd.data = 0;
212         if (!g_sdio.sdio_cmd52(&cmd)) {
213                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n");
214                 goto _fail_;
215         }
216
217         return 1;
218
219 _fail_:
220
221         return 0;
222 }
223
224 static int sdio_write_reg(u32 addr, u32 data)
225 {
226 #ifdef BIG_ENDIAN
227         data = BYTE_SWAP(data);
228 #endif
229
230         if ((addr >= 0xf0) && (addr <= 0xff)) {
231                 sdio_cmd52_t cmd;
232
233                 cmd.read_write = 1;
234                 cmd.function = 0;
235                 cmd.raw = 0;
236                 cmd.address = addr;
237                 cmd.data = data;
238                 if (!g_sdio.sdio_cmd52(&cmd)) {
239                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
240                         goto _fail_;
241                 }
242         } else {
243                 sdio_cmd53_t cmd;
244
245                 /**
246                  *      set the AHB address
247                  **/
248                 if (!sdio_set_func0_csa_address(addr))
249                         goto _fail_;
250
251                 cmd.read_write = 1;
252                 cmd.function = 0;
253                 cmd.address = 0x10f;
254                 cmd.block_mode = 0;
255                 cmd.increment = 1;
256                 cmd.count = 4;
257                 cmd.buffer = (u8 *)&data;
258                 cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
259
260                 if (!g_sdio.sdio_cmd53(&cmd)) {
261                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr);
262                         goto _fail_;
263                 }
264         }
265
266         return 1;
267
268 _fail_:
269
270         return 0;
271 }
272
273 static int sdio_write(u32 addr, u8 *buf, u32 size)
274 {
275         u32 block_size = g_sdio.block_size;
276         sdio_cmd53_t cmd;
277         int nblk, nleft;
278
279         cmd.read_write = 1;
280         if (addr > 0) {
281                 /**
282                  *      has to be word aligned...
283                  **/
284                 if (size & 0x3) {
285                         size += 4;
286                         size &= ~0x3;
287                 }
288
289                 /**
290                  *      func 0 access
291                  **/
292                 cmd.function = 0;
293                 cmd.address = 0x10f;
294         } else {
295                 /**
296                  *      has to be word aligned...
297                  **/
298                 if (size & 0x3) {
299                         size += 4;
300                         size &= ~0x3;
301                 }
302
303                 /**
304                  *      func 1 access
305                  **/
306                 cmd.function = 1;
307                 cmd.address = 0;
308         }
309
310         nblk = size / block_size;
311         nleft = size % block_size;
312
313         if (nblk > 0) {
314                 cmd.block_mode = 1;
315                 cmd.increment = 1;
316                 cmd.count = nblk;
317                 cmd.buffer = buf;
318                 cmd.block_size = block_size;
319                 if (addr > 0) {
320                         if (!sdio_set_func0_csa_address(addr))
321                                 goto _fail_;
322                 }
323                 if (!g_sdio.sdio_cmd53(&cmd)) {
324                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr);
325                         goto _fail_;
326                 }
327                 if (addr > 0)
328                         addr += nblk * block_size;
329                 buf += nblk * block_size;
330         }
331
332         if (nleft > 0) {
333                 cmd.block_mode = 0;
334                 cmd.increment = 1;
335                 cmd.count = nleft;
336                 cmd.buffer = buf;
337
338                 cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
339
340                 if (addr > 0) {
341                         if (!sdio_set_func0_csa_address(addr))
342                                 goto _fail_;
343                 }
344                 if (!g_sdio.sdio_cmd53(&cmd)) {
345                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr);
346                         goto _fail_;
347                 }
348         }
349
350         return 1;
351
352 _fail_:
353
354         return 0;
355 }
356
357 static int sdio_read_reg(u32 addr, u32 *data)
358 {
359         if ((addr >= 0xf0) && (addr <= 0xff)) {
360                 sdio_cmd52_t cmd;
361
362                 cmd.read_write = 0;
363                 cmd.function = 0;
364                 cmd.raw = 0;
365                 cmd.address = addr;
366                 if (!g_sdio.sdio_cmd52(&cmd)) {
367                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
368                         goto _fail_;
369                 }
370                 *data = cmd.data;
371         } else {
372                 sdio_cmd53_t cmd;
373
374                 if (!sdio_set_func0_csa_address(addr))
375                         goto _fail_;
376
377                 cmd.read_write = 0;
378                 cmd.function = 0;
379                 cmd.address = 0x10f;
380                 cmd.block_mode = 0;
381                 cmd.increment = 1;
382                 cmd.count = 4;
383                 cmd.buffer = (u8 *)data;
384
385                 cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
386
387                 if (!g_sdio.sdio_cmd53(&cmd)) {
388                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr);
389                         goto _fail_;
390                 }
391         }
392
393 #ifdef BIG_ENDIAN
394         *data = BYTE_SWAP(*data);
395 #endif
396
397         return 1;
398
399 _fail_:
400
401         return 0;
402 }
403
404 static int sdio_read(u32 addr, u8 *buf, u32 size)
405 {
406         u32 block_size = g_sdio.block_size;
407         sdio_cmd53_t cmd;
408         int nblk, nleft;
409
410         cmd.read_write = 0;
411         if (addr > 0) {
412                 /**
413                  *      has to be word aligned...
414                  **/
415                 if (size & 0x3) {
416                         size += 4;
417                         size &= ~0x3;
418                 }
419
420                 /**
421                  *      func 0 access
422                  **/
423                 cmd.function = 0;
424                 cmd.address = 0x10f;
425         } else {
426                 /**
427                  *      has to be word aligned...
428                  **/
429                 if (size & 0x3) {
430                         size += 4;
431                         size &= ~0x3;
432                 }
433
434                 /**
435                  *      func 1 access
436                  **/
437                 cmd.function = 1;
438                 cmd.address = 0;
439         }
440
441         nblk = size / block_size;
442         nleft = size % block_size;
443
444         if (nblk > 0) {
445                 cmd.block_mode = 1;
446                 cmd.increment = 1;
447                 cmd.count = nblk;
448                 cmd.buffer = buf;
449                 cmd.block_size = block_size;
450                 if (addr > 0) {
451                         if (!sdio_set_func0_csa_address(addr))
452                                 goto _fail_;
453                 }
454                 if (!g_sdio.sdio_cmd53(&cmd)) {
455                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr);
456                         goto _fail_;
457                 }
458                 if (addr > 0)
459                         addr += nblk * block_size;
460                 buf += nblk * block_size;
461         }       /* if (nblk > 0) */
462
463         if (nleft > 0) {
464                 cmd.block_mode = 0;
465                 cmd.increment = 1;
466                 cmd.count = nleft;
467                 cmd.buffer = buf;
468
469                 cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
470
471                 if (addr > 0) {
472                         if (!sdio_set_func0_csa_address(addr))
473                                 goto _fail_;
474                 }
475                 if (!g_sdio.sdio_cmd53(&cmd)) {
476                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr);
477                         goto _fail_;
478                 }
479         }
480
481         return 1;
482
483 _fail_:
484
485         return 0;
486 }
487
488 /********************************************
489  *
490  *      Bus interfaces
491  *
492  ********************************************/
493
494 static int sdio_deinit(void *pv)
495 {
496         return 1;
497 }
498
499 static int sdio_sync(void)
500 {
501         u32 reg;
502
503         /**
504          *      Disable power sequencer
505          **/
506         if (!sdio_read_reg(WILC_MISC, &reg)) {
507                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
508                 return 0;
509         }
510
511         reg &= ~BIT(8);
512         if (!sdio_write_reg(WILC_MISC, reg)) {
513                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
514                 return 0;
515         }
516
517 #ifdef WILC_SDIO_IRQ_GPIO
518         {
519                 u32 reg;
520                 int ret;
521
522                 /**
523                  *      interrupt pin mux select
524                  **/
525                 ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
526                 if (!ret) {
527                         g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
528                         return 0;
529                 }
530                 reg |= BIT(8);
531                 ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
532                 if (!ret) {
533                         g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
534                         return 0;
535                 }
536
537                 /**
538                  *      interrupt enable
539                  **/
540                 ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
541                 if (!ret) {
542                         g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
543                         return 0;
544                 }
545                 reg |= BIT(16);
546                 ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
547                 if (!ret) {
548                         g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
549                         return 0;
550                 }
551         }
552 #endif
553
554         return 1;
555 }
556
557 static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func)
558 {
559         sdio_cmd52_t cmd;
560         int loop;
561         u32 chipid;
562
563         memset(&g_sdio, 0, sizeof(wilc_sdio_t));
564
565         g_sdio.dPrint = func;
566         g_sdio.os_context = inp->os_context.os_private;
567
568         if (inp->io_func.io_init) {
569                 if (!inp->io_func.io_init(g_sdio.os_context)) {
570                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n");
571                         return 0;
572                 }
573         } else {
574                 return 0;
575         }
576
577         g_sdio.sdio_cmd52       = inp->io_func.u.sdio.sdio_cmd52;
578         g_sdio.sdio_cmd53       = inp->io_func.u.sdio.sdio_cmd53;
579         g_sdio.sdio_set_max_speed       = inp->io_func.u.sdio.sdio_set_max_speed;
580         g_sdio.sdio_set_default_speed   = inp->io_func.u.sdio.sdio_set_default_speed;
581
582         /**
583          *      function 0 csa enable
584          **/
585         cmd.read_write = 1;
586         cmd.function = 0;
587         cmd.raw = 1;
588         cmd.address = 0x100;
589         cmd.data = 0x80;
590         if (!g_sdio.sdio_cmd52(&cmd)) {
591                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n");
592                 goto _fail_;
593         }
594
595         /**
596          *      function 0 block size
597          **/
598         if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) {
599                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n");
600                 goto _fail_;
601         }
602         g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
603
604         /**
605          *      enable func1 IO
606          **/
607         cmd.read_write = 1;
608         cmd.function = 0;
609         cmd.raw = 1;
610         cmd.address = 0x2;
611         cmd.data = 0x2;
612         if (!g_sdio.sdio_cmd52(&cmd)) {
613                 g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n");
614                 goto _fail_;
615         }
616
617         /**
618          *      make sure func 1 is up
619          **/
620         cmd.read_write = 0;
621         cmd.function = 0;
622         cmd.raw = 0;
623         cmd.address = 0x3;
624         loop = 3;
625         do {
626                 cmd.data = 0;
627                 if (!g_sdio.sdio_cmd52(&cmd)) {
628                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n");
629                         goto _fail_;
630                 }
631                 if (cmd.data == 0x2)
632                         break;
633         } while (loop--);
634
635         if (loop <= 0) {
636                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n");
637                 goto _fail_;
638         }
639
640         /**
641          *      func 1 is ready, set func 1 block size
642          **/
643         if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) {
644                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n");
645                 goto _fail_;
646         }
647
648         /**
649          *      func 1 interrupt enable
650          **/
651         cmd.read_write = 1;
652         cmd.function = 0;
653         cmd.raw = 1;
654         cmd.address = 0x4;
655         cmd.data = 0x3;
656         if (!g_sdio.sdio_cmd52(&cmd)) {
657                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n");
658                 goto _fail_;
659         }
660
661         /**
662          *      make sure can read back chip id correctly
663          **/
664         if (!sdio_read_reg(0x1000, &chipid)) {
665                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n");
666                 goto _fail_;
667         }
668         g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid);
669         if ((chipid & 0xfff) > 0x2a0)
670                 g_sdio.has_thrpt_enh3 = 1;
671         else
672                 g_sdio.has_thrpt_enh3 = 0;
673         g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
674
675         return 1;
676
677 _fail_:
678
679         return 0;
680 }
681
682 static void sdio_set_max_speed(void)
683 {
684         g_sdio.sdio_set_max_speed();
685 }
686
687 static void sdio_set_default_speed(void)
688 {
689         g_sdio.sdio_set_default_speed();
690 }
691
692 static int sdio_read_size(u32 *size)
693 {
694
695         u32 tmp;
696         sdio_cmd52_t cmd;
697
698         /**
699          *      Read DMA count in words
700          **/
701         cmd.read_write = 0;
702         cmd.function = 0;
703         cmd.raw = 0;
704         cmd.address = 0xf2;
705         cmd.data = 0;
706         g_sdio.sdio_cmd52(&cmd);
707         tmp = cmd.data;
708
709         /* cmd.read_write = 0; */
710         /* cmd.function = 0; */
711         /* cmd.raw = 0; */
712         cmd.address = 0xf3;
713         cmd.data = 0;
714         g_sdio.sdio_cmd52(&cmd);
715         tmp |= (cmd.data << 8);
716
717         *size = tmp;
718         return 1;
719 }
720
721 static int sdio_read_int(u32 *int_status)
722 {
723
724         u32 tmp;
725         sdio_cmd52_t cmd;
726
727         sdio_read_size(&tmp);
728
729         /**
730          *      Read IRQ flags
731          **/
732 #ifndef WILC_SDIO_IRQ_GPIO
733         cmd.function = 1;
734         cmd.address = 0x04;
735         cmd.data = 0;
736         g_sdio.sdio_cmd52(&cmd);
737
738         if (cmd.data & BIT(0))
739                 tmp |= INT_0;
740         if (cmd.data & BIT(2))
741                 tmp |= INT_1;
742         if (cmd.data & BIT(3))
743                 tmp |= INT_2;
744         if (cmd.data & BIT(4))
745                 tmp |= INT_3;
746         if (cmd.data & BIT(5))
747                 tmp |= INT_4;
748         if (cmd.data & BIT(6))
749                 tmp |= INT_5;
750         {
751                 int i;
752
753                 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
754                         if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
755                                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data);
756                                 break;
757                         }
758                 }
759         }
760 #else
761         {
762                 u32 irq_flags;
763
764                 cmd.read_write = 0;
765                 cmd.function = 0;
766                 cmd.raw = 0;
767                 cmd.address = 0xf7;
768                 cmd.data = 0;
769                 g_sdio.sdio_cmd52(&cmd);
770                 irq_flags = cmd.data & 0x1f;
771                 tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
772         }
773
774 #endif
775
776         *int_status = tmp;
777
778         return 1;
779 }
780
781 static int sdio_clear_int_ext(u32 val)
782 {
783         int ret;
784
785         if (g_sdio.has_thrpt_enh3) {
786                 u32 reg;
787
788 #ifdef WILC_SDIO_IRQ_GPIO
789                 {
790                         u32 flags;
791
792                         flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
793                         reg = flags;
794                 }
795 #else
796                 reg = 0;
797 #endif
798                 /* select VMM table 0 */
799                 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
800                         reg |= BIT(5);
801                 /* select VMM table 1 */
802                 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
803                         reg |= BIT(6);
804                 /* enable VMM */
805                 if ((val & EN_VMM) == EN_VMM)
806                         reg |= BIT(7);
807                 if (reg) {
808                         sdio_cmd52_t cmd;
809
810                         cmd.read_write = 1;
811                         cmd.function = 0;
812                         cmd.raw = 0;
813                         cmd.address = 0xf8;
814                         cmd.data = reg;
815
816                         ret = g_sdio.sdio_cmd52(&cmd);
817                         if (!ret) {
818                                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
819                                 goto _fail_;
820                         }
821
822                 }
823         } else {
824 #ifdef WILC_SDIO_IRQ_GPIO
825                 {
826                         /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
827                         /* Cannot clear multiple interrupts. Must clear each interrupt individually */
828                         u32 flags;
829
830                         flags = val & (BIT(MAX_NUM_INT) - 1);
831                         if (flags) {
832                                 int i;
833
834                                 ret = 1;
835                                 for (i = 0; i < g_sdio.nint; i++) {
836                                         if (flags & 1) {
837                                                 sdio_cmd52_t cmd;
838
839                                                 cmd.read_write = 1;
840                                                 cmd.function = 0;
841                                                 cmd.raw = 0;
842                                                 cmd.address = 0xf8;
843                                                 cmd.data = BIT(i);
844
845                                                 ret = g_sdio.sdio_cmd52(&cmd);
846                                                 if (!ret) {
847                                                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
848                                                         goto _fail_;
849                                                 }
850
851                                         }
852                                         if (!ret)
853                                                 break;
854                                         flags >>= 1;
855                                 }
856                                 if (!ret)
857                                         goto _fail_;
858                                 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
859                                         if (flags & 1)
860                                                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i);
861                                         flags >>= 1;
862                                 }
863                         }
864                 }
865 #endif /* WILC_SDIO_IRQ_GPIO */
866
867                 {
868                         u32 vmm_ctl;
869
870                         vmm_ctl = 0;
871                         /* select VMM table 0 */
872                         if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
873                                 vmm_ctl |= BIT(0);
874                         /* select VMM table 1 */
875                         if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
876                                 vmm_ctl |= BIT(1);
877                         /* enable VMM */
878                         if ((val & EN_VMM) == EN_VMM)
879                                 vmm_ctl |= BIT(2);
880
881                         if (vmm_ctl) {
882                                 sdio_cmd52_t cmd;
883
884                                 cmd.read_write = 1;
885                                 cmd.function = 0;
886                                 cmd.raw = 0;
887                                 cmd.address = 0xf6;
888                                 cmd.data = vmm_ctl;
889                                 ret = g_sdio.sdio_cmd52(&cmd);
890                                 if (!ret) {
891                                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__);
892                                         goto _fail_;
893                                 }
894                         }
895                 }
896         }
897
898         return 1;
899 _fail_:
900         return 0;
901 }
902
903 static int sdio_sync_ext(int nint /*  how mant interrupts to enable. */)
904 {
905         u32 reg;
906
907         if (nint > MAX_NUM_INT) {
908                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint);
909                 return 0;
910         }
911         if (nint > MAX_NUN_INT_THRPT_ENH2) {
912                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
913                 return 0;
914         }
915
916         g_sdio.nint = nint;
917
918         /**
919          *      Disable power sequencer
920          **/
921         if (!sdio_read_reg(WILC_MISC, &reg)) {
922                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
923                 return 0;
924         }
925
926         reg &= ~BIT(8);
927         if (!sdio_write_reg(WILC_MISC, reg)) {
928                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
929                 return 0;
930         }
931
932 #ifdef WILC_SDIO_IRQ_GPIO
933         {
934                 u32 reg;
935                 int ret, i;
936
937                 /**
938                  *      interrupt pin mux select
939                  **/
940                 ret = sdio_read_reg(WILC_PIN_MUX_0, &reg);
941                 if (!ret) {
942                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
943                         return 0;
944                 }
945                 reg |= BIT(8);
946                 ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
947                 if (!ret) {
948                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
949                         return 0;
950                 }
951
952                 /**
953                  *      interrupt enable
954                  **/
955                 ret = sdio_read_reg(WILC_INTR_ENABLE, &reg);
956                 if (!ret) {
957                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
958                         return 0;
959                 }
960
961                 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
962                         reg |= BIT((27 + i));
963                 ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
964                 if (!ret) {
965                         g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
966                         return 0;
967                 }
968                 if (nint) {
969                         ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
970                         if (!ret) {
971                                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
972                                 return 0;
973                         }
974
975                         for (i = 0; (i < 3) && (nint > 0); i++, nint--)
976                                 reg |= BIT(i);
977
978                         ret = sdio_read_reg(WILC_INTR2_ENABLE, &reg);
979                         if (!ret) {
980                                 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
981                                 return 0;
982                         }
983                 }
984         }
985 #endif /* WILC_SDIO_IRQ_GPIO */
986         return 1;
987 }
988
989 /********************************************
990  *
991  *      Global sdio HIF function table
992  *
993  ********************************************/
994
995 wilc_hif_func_t hif_sdio = {
996         sdio_init,
997         sdio_deinit,
998         sdio_read_reg,
999         sdio_write_reg,
1000         sdio_read,
1001         sdio_write,
1002         sdio_sync,
1003         sdio_clear_int,
1004         sdio_read_int,
1005         sdio_clear_int_ext,
1006         sdio_read_size,
1007         sdio_write,
1008         sdio_read,
1009         sdio_sync_ext,
1010
1011         sdio_set_max_speed,
1012         sdio_set_default_speed,
1013 };
1014