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