]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/wilc_sdio.c
Merge tag 'libnvdimm-for-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdim...
[karo-tx-linux.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.function = 1;
827                 cmd.address = 0x04;
828                 cmd.data = 0;
829                 wilc_sdio_cmd52(wilc, &cmd);
830
831                 if (cmd.data & BIT(0))
832                         tmp |= INT_0;
833                 if (cmd.data & BIT(2))
834                         tmp |= INT_1;
835                 if (cmd.data & BIT(3))
836                         tmp |= INT_2;
837                 if (cmd.data & BIT(4))
838                         tmp |= INT_3;
839                 if (cmd.data & BIT(5))
840                         tmp |= INT_4;
841                 if (cmd.data & BIT(6))
842                         tmp |= INT_5;
843                 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
844                         if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
845                                 dev_err(&func->dev,
846                                         "Unexpected interrupt (1) : tmp=%x, data=%x\n",
847                                         tmp, cmd.data);
848                                 break;
849                         }
850                 }
851         } else {
852                 u32 irq_flags;
853
854                 cmd.read_write = 0;
855                 cmd.function = 0;
856                 cmd.raw = 0;
857                 cmd.address = 0xf7;
858                 cmd.data = 0;
859                 wilc_sdio_cmd52(wilc, &cmd);
860                 irq_flags = cmd.data & 0x1f;
861                 tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
862         }
863
864         *int_status = tmp;
865
866         return 1;
867 }
868
869 static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
870 {
871         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
872         int ret;
873
874         if (g_sdio.has_thrpt_enh3) {
875                 u32 reg;
876
877                 if (g_sdio.irq_gpio) {
878                         u32 flags;
879
880                         flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
881                         reg = flags;
882                 } else {
883                         reg = 0;
884                 }
885                 /* select VMM table 0 */
886                 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
887                         reg |= BIT(5);
888                 /* select VMM table 1 */
889                 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
890                         reg |= BIT(6);
891                 /* enable VMM */
892                 if ((val & EN_VMM) == EN_VMM)
893                         reg |= BIT(7);
894                 if (reg) {
895                         struct sdio_cmd52 cmd;
896
897                         cmd.read_write = 1;
898                         cmd.function = 0;
899                         cmd.raw = 0;
900                         cmd.address = 0xf8;
901                         cmd.data = reg;
902
903                         ret = wilc_sdio_cmd52(wilc, &cmd);
904                         if (ret) {
905                                 dev_err(&func->dev,
906                                         "Failed cmd52, set 0xf8 data (%d) ...\n",
907                                         __LINE__);
908                                 goto _fail_;
909                         }
910                 }
911         } else {
912                 if (g_sdio.irq_gpio) {
913                         /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
914                         /* Cannot clear multiple interrupts. Must clear each interrupt individually */
915                         u32 flags;
916
917                         flags = val & (BIT(MAX_NUM_INT) - 1);
918                         if (flags) {
919                                 int i;
920
921                                 ret = 1;
922                                 for (i = 0; i < g_sdio.nint; i++) {
923                                         if (flags & 1) {
924                                                 struct sdio_cmd52 cmd;
925
926                                                 cmd.read_write = 1;
927                                                 cmd.function = 0;
928                                                 cmd.raw = 0;
929                                                 cmd.address = 0xf8;
930                                                 cmd.data = BIT(i);
931
932                                                 ret = wilc_sdio_cmd52(wilc, &cmd);
933                                                 if (ret) {
934                                                         dev_err(&func->dev,
935                                                                 "Failed cmd52, set 0xf8 data (%d) ...\n",
936                                                                 __LINE__);
937                                                         goto _fail_;
938                                                 }
939                                         }
940                                         if (!ret)
941                                                 break;
942                                         flags >>= 1;
943                                 }
944                                 if (!ret)
945                                         goto _fail_;
946                                 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
947                                         if (flags & 1)
948                                                 dev_err(&func->dev,
949                                                         "Unexpected interrupt cleared %d...\n",
950                                                         i);
951                                         flags >>= 1;
952                                 }
953                         }
954                 }
955
956                 {
957                         u32 vmm_ctl;
958
959                         vmm_ctl = 0;
960                         /* select VMM table 0 */
961                         if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
962                                 vmm_ctl |= BIT(0);
963                         /* select VMM table 1 */
964                         if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
965                                 vmm_ctl |= BIT(1);
966                         /* enable VMM */
967                         if ((val & EN_VMM) == EN_VMM)
968                                 vmm_ctl |= BIT(2);
969
970                         if (vmm_ctl) {
971                                 struct sdio_cmd52 cmd;
972
973                                 cmd.read_write = 1;
974                                 cmd.function = 0;
975                                 cmd.raw = 0;
976                                 cmd.address = 0xf6;
977                                 cmd.data = vmm_ctl;
978                                 ret = wilc_sdio_cmd52(wilc, &cmd);
979                                 if (ret) {
980                                         dev_err(&func->dev,
981                                                 "Failed cmd52, set 0xf6 data (%d) ...\n",
982                                                 __LINE__);
983                                         goto _fail_;
984                                 }
985                         }
986                 }
987         }
988
989         return 1;
990 _fail_:
991         return 0;
992 }
993
994 static int sdio_sync_ext(struct wilc *wilc, int nint)
995 {
996         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
997         u32 reg;
998
999         if (nint > MAX_NUM_INT) {
1000                 dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
1001                 return 0;
1002         }
1003         if (nint > MAX_NUN_INT_THRPT_ENH2) {
1004                 dev_err(&func->dev,
1005                         "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
1006                 return 0;
1007         }
1008
1009         g_sdio.nint = nint;
1010
1011         /**
1012          *      Disable power sequencer
1013          **/
1014         if (!sdio_read_reg(wilc, WILC_MISC, &reg)) {
1015                 dev_err(&func->dev, "Failed read misc reg...\n");
1016                 return 0;
1017         }
1018
1019         reg &= ~BIT(8);
1020         if (!sdio_write_reg(wilc, WILC_MISC, reg)) {
1021                 dev_err(&func->dev, "Failed write misc reg...\n");
1022                 return 0;
1023         }
1024
1025         if (g_sdio.irq_gpio) {
1026                 u32 reg;
1027                 int ret, i;
1028
1029                 /**
1030                  *      interrupt pin mux select
1031                  **/
1032                 ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
1033                 if (!ret) {
1034                         dev_err(&func->dev, "Failed read reg (%08x)...\n",
1035                                 WILC_PIN_MUX_0);
1036                         return 0;
1037                 }
1038                 reg |= BIT(8);
1039                 ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
1040                 if (!ret) {
1041                         dev_err(&func->dev, "Failed write reg (%08x)...\n",
1042                                 WILC_PIN_MUX_0);
1043                         return 0;
1044                 }
1045
1046                 /**
1047                  *      interrupt enable
1048                  **/
1049                 ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
1050                 if (!ret) {
1051                         dev_err(&func->dev, "Failed read reg (%08x)...\n",
1052                                 WILC_INTR_ENABLE);
1053                         return 0;
1054                 }
1055
1056                 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
1057                         reg |= BIT((27 + i));
1058                 ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
1059                 if (!ret) {
1060                         dev_err(&func->dev, "Failed write reg (%08x)...\n",
1061                                 WILC_INTR_ENABLE);
1062                         return 0;
1063                 }
1064                 if (nint) {
1065                         ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1066                         if (!ret) {
1067                                 dev_err(&func->dev,
1068                                         "Failed read reg (%08x)...\n",
1069                                         WILC_INTR2_ENABLE);
1070                                 return 0;
1071                         }
1072
1073                         for (i = 0; (i < 3) && (nint > 0); i++, nint--)
1074                                 reg |= BIT(i);
1075
1076                         ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1077                         if (!ret) {
1078                                 dev_err(&func->dev,
1079                                         "Failed write reg (%08x)...\n",
1080                                         WILC_INTR2_ENABLE);
1081                                 return 0;
1082                         }
1083                 }
1084         }
1085         return 1;
1086 }
1087
1088 /********************************************
1089  *
1090  *      Global sdio HIF function table
1091  *
1092  ********************************************/
1093
1094 static const struct wilc_hif_func wilc_hif_sdio = {
1095         .hif_init = sdio_init,
1096         .hif_deinit = sdio_deinit,
1097         .hif_read_reg = sdio_read_reg,
1098         .hif_write_reg = sdio_write_reg,
1099         .hif_block_rx = sdio_read,
1100         .hif_block_tx = sdio_write,
1101         .hif_read_int = sdio_read_int,
1102         .hif_clear_int_ext = sdio_clear_int_ext,
1103         .hif_read_size = sdio_read_size,
1104         .hif_block_tx_ext = sdio_write,
1105         .hif_block_rx_ext = sdio_read,
1106         .hif_sync_ext = sdio_sync_ext,
1107         .enable_interrupt = wilc_sdio_enable_interrupt,
1108         .disable_interrupt = wilc_sdio_disable_interrupt,
1109 };
1110