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
wilc_sdio_interrupt(struct sdio_func * func)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
wilc_sdio_cmd52(struct wilc * wilc,struct sdio_cmd52 * cmd)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
wilc_sdio_cmd53(struct wilc * wilc,struct sdio_cmd53 * cmd)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
linux_sdio_probe(struct sdio_func * func,const struct sdio_device_id * id)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
linux_sdio_remove(struct sdio_func * func)138 static void linux_sdio_remove(struct sdio_func *func)
139 {
140 wilc_netdev_cleanup(sdio_get_drvdata(func));
141 }
142
sdio_reset(struct wilc * wilc)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
wilc_sdio_suspend(struct device * dev)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
wilc_sdio_resume(struct device * dev)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
wilc_sdio_enable_interrupt(struct wilc * dev)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
wilc_sdio_disable_interrupt(struct wilc * dev)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
sdio_set_func0_csa_address(struct wilc * wilc,u32 adr)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
sdio_set_func0_block_size(struct wilc * wilc,u32 block_size)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
sdio_set_func1_block_size(struct wilc * wilc,u32 block_size)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 ********************************************/
sdio_write_reg(struct wilc * wilc,u32 addr,u32 data)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
sdio_write(struct wilc * wilc,u32 addr,u8 * buf,u32 size)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
sdio_read_reg(struct wilc * wilc,u32 addr,u32 * data)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
sdio_read(struct wilc * wilc,u32 addr,u8 * buf,u32 size)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
sdio_deinit(struct wilc * wilc)658 static int sdio_deinit(struct wilc *wilc)
659 {
660 return 1;
661 }
662
sdio_init(struct wilc * wilc,bool resume)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
sdio_read_size(struct wilc * wilc,u32 * size)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
sdio_read_int(struct wilc * wilc,u32 * int_status)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
sdio_clear_int_ext(struct wilc * wilc,u32 val)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
sdio_sync_ext(struct wilc * wilc,int nint)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, ®)) {
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, ®);
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, ®);
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, ®);
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, ®);
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
1112