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