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