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