1
2
3
4
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
23static 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
30struct wilc_sdio {
31 bool irq_gpio;
32 u32 block_size;
33 int nint;
34#define MAX_NUN_INT_THRPT_ENH2 (5)
35 int has_thrpt_enh3;
36};
37
38static struct wilc_sdio g_sdio;
39static const struct wilc_hif_func wilc_hif_sdio;
40
41static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data);
42static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data);
43static int sdio_init(struct wilc *wilc, bool resume);
44
45static 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
52static 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) {
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 {
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
81static 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) {
96 ret = sdio_memcpy_toio(func, cmd->address,
97 (void *)cmd->buffer, size);
98 } else {
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
111static 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
138static void linux_sdio_remove(struct sdio_func *func)
139{
140 wilc_netdev_cleanup(sdio_get_drvdata(func));
141}
142
143static 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
162static 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
188static 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
206static const struct dev_pm_ops wilc_sdio_pm_ops = {
207 .suspend = wilc_sdio_suspend,
208 .resume = wilc_sdio_resume,
209};
210
211static 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};
220module_driver(wilc1000_sdio_driver,
221 sdio_register_driver,
222 sdio_unregister_driver);
223MODULE_LICENSE("GPL");
224
225static 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
241static 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
256
257
258
259static 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
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
300static 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
333
334
335
336static 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
368
369
370static 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
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;
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
423static 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
434
435 if (size & 0x3) {
436 size += 4;
437 size &= ~0x3;
438 }
439
440
441
442
443 cmd.function = 0;
444 cmd.address = 0x10f;
445 } else {
446
447
448
449 if (size & 0x3) {
450 size += 4;
451 size &= ~0x3;
452 }
453
454
455
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;
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
512static 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;
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
563static 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
574
575 if (size & 0x3) {
576 size += 4;
577 size &= ~0x3;
578 }
579
580
581
582
583 cmd.function = 0;
584 cmd.address = 0x10f;
585 } else {
586
587
588
589 if (size & 0x3) {
590 size += 4;
591 size &= ~0x3;
592 }
593
594
595
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 }
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;
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
655
656
657
658static int sdio_deinit(struct wilc *wilc)
659{
660 return 1;
661}
662
663static 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
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
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
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
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
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
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
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
784static int sdio_read_size(struct wilc *wilc, u32 *size)
785{
786 u32 tmp;
787 struct sdio_cmd52 cmd;
788
789
790
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
801
802
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
812static 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
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
869static 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
886 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
887 reg |= BIT(5);
888
889 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
890 reg |= BIT(6);
891
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
914
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
961 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
962 vmm_ctl |= BIT(0);
963
964 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
965 vmm_ctl |= BIT(1);
966
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
994static 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
1013
1014 if (!sdio_read_reg(wilc, WILC_MISC, ®)) {
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
1031
1032 ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, ®);
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
1048
1049 ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, ®);
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, ®);
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, ®);
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
1091
1092
1093
1094static 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
1111