1 /* ////////////////////////////////////////////////////////////////////////// */
3 /* Copyright (c) Atmel Corporation. All rights reserved. */
5 /* Module Name: wilc_sdio.c */
8 /* //////////////////////////////////////////////////////////////////////////// */
10 #include "wilc_wlan_if.h"
11 #include "wilc_wlan.h"
13 #define WILC_SDIO_BLOCK_SIZE 512
17 wilc_wlan_os_func_t os_func;
19 int (*sdio_cmd52)(sdio_cmd52_t *);
20 int (*sdio_cmd53)(sdio_cmd53_t *);
21 int (*sdio_set_max_speed)(void);
22 int (*sdio_set_default_speed)(void);
23 wilc_debug_func dPrint;
25 #define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
29 static wilc_sdio_t g_sdio;
31 #ifdef WILC_SDIO_IRQ_GPIO
32 static int sdio_write_reg(uint32_t addr, uint32_t data);
33 static int sdio_read_reg(uint32_t addr, uint32_t *data);
35 extern unsigned int int_clrd;
37 /********************************************
41 ********************************************/
43 static int sdio_set_func0_csa_address(uint32_t adr)
54 cmd.data = (uint8_t)adr;
55 if (!g_sdio.sdio_cmd52(&cmd)) {
56 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n");
61 cmd.data = (uint8_t)(adr >> 8);
62 if (!g_sdio.sdio_cmd52(&cmd)) {
63 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10d data...\n");
68 cmd.data = (uint8_t)(adr >> 16);
69 if (!g_sdio.sdio_cmd52(&cmd)) {
70 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10e data...\n");
79 static int sdio_set_func0_csa_address_byte0(uint32_t adr)
90 cmd.data = (uint8_t)adr;
91 if (!g_sdio.sdio_cmd52(&cmd)) {
92 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10c data...\n");
101 static int sdio_set_func0_block_size(uint32_t block_size)
109 cmd.data = (uint8_t)block_size;
110 if (!g_sdio.sdio_cmd52(&cmd)) {
111 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x10 data...\n");
116 cmd.data = (uint8_t)(block_size >> 8);
117 if (!g_sdio.sdio_cmd52(&cmd)) {
118 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x11 data...\n");
127 /********************************************
131 ********************************************/
133 static int sdio_set_func1_block_size(uint32_t block_size)
141 cmd.data = (uint8_t)block_size;
142 if (!g_sdio.sdio_cmd52(&cmd)) {
143 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x110 data...\n");
147 cmd.data = (uint8_t)(block_size >> 8);
148 if (!g_sdio.sdio_cmd52(&cmd)) {
149 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0x111 data...\n");
158 static int sdio_clear_int(void)
160 #ifndef WILC_SDIO_IRQ_GPIO
169 g_sdio.sdio_cmd52(&cmd);
176 if (!sdio_read_reg(WILC_HOST_RX_CTRL_0, ®)) {
177 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
181 sdio_write_reg(WILC_HOST_RX_CTRL_0, reg);
188 uint32_t sdio_xfer_cnt(void)
198 g_sdio.sdio_cmd52(&cmd);
206 g_sdio.sdio_cmd52(&cmd);
207 cnt |= (cmd.data << 8);
214 g_sdio.sdio_cmd52(&cmd);
215 cnt |= (cmd.data << 16);
220 /********************************************
224 ********************************************/
225 int sdio_check_bs(void)
237 if (!g_sdio.sdio_cmd52(&cmd)) {
238 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get BS register...\n");
249 static int sdio_write_reg(uint32_t addr, uint32_t data)
252 data = BYTE_SWAP(data);
255 if ((addr >= 0xf0) && (addr <= 0xff)) {
263 if (!g_sdio.sdio_cmd52(&cmd)) {
264 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
271 * set the AHB address
273 if (!sdio_set_func0_csa_address(addr))
282 cmd.buffer = (uint8_t *)&data;
283 cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
285 if (!g_sdio.sdio_cmd53(&cmd)) {
286 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, write reg (%08x)...\n", addr);
298 static int sdio_write(uint32_t addr, uint8_t *buf, uint32_t size)
300 uint32_t block_size = g_sdio.block_size;
307 * has to be word aligned...
321 * has to be word aligned...
335 nblk = size / block_size;
336 nleft = size % block_size;
343 cmd.block_size = block_size;
345 if (!sdio_set_func0_csa_address(addr))
348 if (!g_sdio.sdio_cmd53(&cmd)) {
349 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block send...\n", addr);
353 addr += nblk * block_size;
354 buf += nblk * block_size;
363 cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
366 if (!sdio_set_func0_csa_address(addr))
369 if (!g_sdio.sdio_cmd53(&cmd)) {
370 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes send...\n", addr);
382 static int sdio_read_reg(uint32_t addr, uint32_t *data)
384 if ((addr >= 0xf0) && (addr <= 0xff)) {
391 if (!g_sdio.sdio_cmd52(&cmd)) {
392 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
399 if (!sdio_set_func0_csa_address(addr))
408 cmd.buffer = (uint8_t *)data;
410 cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
412 if (!g_sdio.sdio_cmd53(&cmd)) {
413 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53, read reg (%08x)...\n", addr);
419 *data = BYTE_SWAP(*data);
429 static int sdio_read(uint32_t addr, uint8_t *buf, uint32_t size)
431 uint32_t block_size = g_sdio.block_size;
438 * has to be word aligned...
452 * has to be word aligned...
466 nblk = size / block_size;
467 nleft = size % block_size;
474 cmd.block_size = block_size;
476 if (!sdio_set_func0_csa_address(addr))
479 if (!g_sdio.sdio_cmd53(&cmd)) {
480 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], block read...\n", addr);
484 addr += nblk * block_size;
485 buf += nblk * block_size;
486 } /* if (nblk > 0) */
494 cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
497 if (!sdio_set_func0_csa_address(addr))
500 if (!g_sdio.sdio_cmd53(&cmd)) {
501 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd53 [%x], bytes read...\n", addr);
513 /********************************************
517 ********************************************/
519 static int sdio_deinit(void *pv)
524 static int sdio_sync(void)
529 * Disable power sequencer
531 if (!sdio_read_reg(WILC_MISC, ®)) {
532 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
537 if (!sdio_write_reg(WILC_MISC, reg)) {
538 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
542 #ifdef WILC_SDIO_IRQ_GPIO
548 * interrupt pin mux select
550 ret = sdio_read_reg(WILC_PIN_MUX_0, ®);
552 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
556 ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
558 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
565 ret = sdio_read_reg(WILC_INTR_ENABLE, ®);
567 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
571 ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
573 g_sdio.dPrint(N_ERR, "[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
582 static int sdio_init(wilc_wlan_inp_t *inp, wilc_debug_func func)
588 memset(&g_sdio, 0, sizeof(wilc_sdio_t));
590 g_sdio.dPrint = func;
591 g_sdio.os_context = inp->os_context.os_private;
592 memcpy((void *)&g_sdio.os_func, (void *)&inp->os_func, sizeof(wilc_wlan_os_func_t));
594 if (inp->io_func.io_init) {
595 if (!inp->io_func.io_init(g_sdio.os_context)) {
596 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed io init bus...\n");
603 g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52;
604 g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53;
605 g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed;
606 g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed;
609 * function 0 csa enable
616 if (!g_sdio.sdio_cmd52(&cmd)) {
617 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, enable csa...\n");
622 * function 0 block size
624 if (!sdio_set_func0_block_size(WILC_SDIO_BLOCK_SIZE)) {
625 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set func 0 block size...\n");
628 g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
638 if (!g_sdio.sdio_cmd52(&cmd)) {
639 g_sdio.dPrint(N_ERR, "[wilc sdio] Fail cmd 52, set IOE register...\n");
644 * make sure func 1 is up
653 if (!g_sdio.sdio_cmd52(&cmd)) {
654 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, get IOR register...\n");
662 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail func 1 is not ready...\n");
667 * func 1 is ready, set func 1 block size
669 if (!sdio_set_func1_block_size(WILC_SDIO_BLOCK_SIZE)) {
670 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail set func 1 block size...\n");
675 * func 1 interrupt enable
682 if (!g_sdio.sdio_cmd52(&cmd)) {
683 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd 52, set IEN register...\n");
688 * make sure can read back chip id correctly
690 if (!sdio_read_reg(0x1000, &chipid)) {
691 g_sdio.dPrint(N_ERR, "[wilc sdio]: Fail cmd read chip id...\n");
694 g_sdio.dPrint(N_ERR, "[wilc sdio]: chipid (%08x)\n", chipid);
695 if ((chipid & 0xfff) > 0x2a0)
696 g_sdio.has_thrpt_enh3 = 1;
698 g_sdio.has_thrpt_enh3 = 0;
699 g_sdio.dPrint(N_ERR, "[wilc sdio]: has_thrpt_enh3 = %d...\n", g_sdio.has_thrpt_enh3);
708 static void sdio_set_max_speed(void)
710 g_sdio.sdio_set_max_speed();
713 static void sdio_set_default_speed(void)
715 g_sdio.sdio_set_default_speed();
718 static int sdio_read_size(uint32_t *size)
725 * Read DMA count in words
732 g_sdio.sdio_cmd52(&cmd);
735 /* cmd.read_write = 0; */
736 /* cmd.function = 0; */
740 g_sdio.sdio_cmd52(&cmd);
741 tmp |= (cmd.data << 8);
747 static int sdio_read_int(uint32_t *int_status)
753 sdio_read_size(&tmp);
758 #ifndef WILC_SDIO_IRQ_GPIO
759 /* cmd.read_write = 0; */
764 g_sdio.sdio_cmd52(&cmd);
766 if (cmd.data & (1 << 0))
768 if (cmd.data & (1 << 2))
770 if (cmd.data & (1 << 3))
772 if (cmd.data & (1 << 4))
774 if (cmd.data & (1 << 5))
776 if (cmd.data & (1 << 6))
781 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
782 if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
783 g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data);
797 g_sdio.sdio_cmd52(&cmd);
798 irq_flags = cmd.data & 0x1f;
799 tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
809 static int sdio_clear_int_ext(uint32_t val)
813 if (g_sdio.has_thrpt_enh3) {
816 #ifdef WILC_SDIO_IRQ_GPIO
820 flags = val & ((1 << MAX_NUN_INT_THRPT_ENH2) - 1);
826 /* select VMM table 0 */
827 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
829 /* select VMM table 1 */
830 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
833 if ((val & EN_VMM) == EN_VMM)
844 ret = g_sdio.sdio_cmd52(&cmd);
846 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
852 #ifdef WILC_SDIO_IRQ_GPIO
854 /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
855 /* Cannot clear multiple interrupts. Must clear each interrupt individually */
858 flags = val & ((1 << MAX_NUM_INT) - 1);
863 for (i = 0; i < g_sdio.nint; i++) {
873 ret = g_sdio.sdio_cmd52(&cmd);
875 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
886 for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
888 g_sdio.dPrint(N_ERR, "[wilc sdio]: Unexpected interrupt cleared %d...\n", i);
893 #endif /* WILC_SDIO_IRQ_GPIO */
899 /* select VMM table 0 */
900 if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
902 /* select VMM table 1 */
903 if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
906 if ((val & EN_VMM) == EN_VMM)
917 ret = g_sdio.sdio_cmd52(&cmd);
919 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__);
931 static int sdio_sync_ext(int nint /* how mant interrupts to enable. */)
935 if (nint > MAX_NUM_INT) {
936 g_sdio.dPrint(N_ERR, "[wilc sdio]: Too many interupts (%d)...\n", nint);
939 if (nint > MAX_NUN_INT_THRPT_ENH2) {
940 g_sdio.dPrint(N_ERR, "[wilc sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
947 * Disable power sequencer
949 if (!sdio_read_reg(WILC_MISC, ®)) {
950 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read misc reg...\n");
955 if (!sdio_write_reg(WILC_MISC, reg)) {
956 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write misc reg...\n");
960 #ifdef WILC_SDIO_IRQ_GPIO
966 * interrupt pin mux select
968 ret = sdio_read_reg(WILC_PIN_MUX_0, ®);
970 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
974 ret = sdio_write_reg(WILC_PIN_MUX_0, reg);
976 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
983 ret = sdio_read_reg(WILC_INTR_ENABLE, ®);
985 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
989 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
990 reg |= (1 << (27 + i));
991 ret = sdio_write_reg(WILC_INTR_ENABLE, reg);
993 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
997 ret = sdio_read_reg(WILC_INTR2_ENABLE, ®);
999 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
1003 for (i = 0; (i < 3) && (nint > 0); i++, nint--)
1006 ret = sdio_read_reg(WILC_INTR2_ENABLE, ®);
1008 g_sdio.dPrint(N_ERR, "[wilc sdio]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
1013 #endif /* WILC_SDIO_IRQ_GPIO */
1017 /********************************************
1019 * Global sdio HIF function table
1021 ********************************************/
1023 wilc_hif_func_t hif_sdio = {
1040 sdio_set_default_speed,