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