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