1 /** @file mlan_sdio.c
2 *
3 * @brief This file provides mlan driver for SDIO
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10 #include <wmerrno.h>
11 #include <board.h>
12 #include <wifi_bt_config.h>
13
14 #include <mlan_sdio_api.h>
15 #include <osa.h>
16 #include <zephyr/sd/sdio.h>
17
18 #define SDIO_CMD_TIMEOUT 2000
19
20 const struct device *sdhc_dev = DEVICE_DT_GET(DT_BUS(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_wifi)));
21
22 static struct sd_card wm_g_sd;
23 static struct sdio_func g_sdio_funcs[8];
24
sdio_drv_creg_read(int addr,int fn,uint32_t * resp)25 int sdio_drv_creg_read(int addr, int fn, uint32_t *resp)
26 {
27 struct sdio_func *func = &g_sdio_funcs[fn];
28
29 if (sdio_read_byte(func, addr, (uint8_t *)resp) != 0)
30 {
31 return 0;
32 }
33
34 return 1;
35 }
36
sdio_drv_creg_write(int addr,int fn,uint8_t data,uint32_t * resp)37 int sdio_drv_creg_write(int addr, int fn, uint8_t data, uint32_t *resp)
38 {
39 struct sdio_func *func = &g_sdio_funcs[fn];
40
41 if (sdio_rw_byte(func, addr, data, (uint8_t *)resp) != 0)
42 {
43 return 0;
44 }
45
46 return 1;
47 }
48
sdio_drv_read(uint32_t addr,uint32_t fn,uint32_t bcnt,uint32_t bsize,uint8_t * buf,uint32_t * resp)49 int sdio_drv_read(uint32_t addr, uint32_t fn, uint32_t bcnt, uint32_t bsize, uint8_t *buf, uint32_t *resp)
50 {
51 struct sdio_func *func = &g_sdio_funcs[fn];
52
53 if (sdio_read_addr(func, addr, buf, bcnt * bsize) != 0)
54 {
55 return 0;
56 }
57
58 return 1;
59 }
60
sdio_drv_write(uint32_t addr,uint32_t fn,uint32_t bcnt,uint32_t bsize,uint8_t * buf,uint32_t * resp)61 int sdio_drv_write(uint32_t addr, uint32_t fn, uint32_t bcnt, uint32_t bsize, uint8_t *buf, uint32_t *resp)
62 {
63 struct sdio_func *func = &g_sdio_funcs[fn];
64
65 if (sdio_write_addr(func, addr, buf, bcnt * bsize) != 0)
66 {
67 return 0;
68 }
69
70 return 1;
71 }
72
73 extern void handle_cdint(int error);
74
sdio_irq_handler(const struct device * dev,int reason,const void * user_data)75 void sdio_irq_handler(const struct device *dev, int reason, const void *user_data)
76 {
77 if (reason == SDHC_INT_SDIO)
78 {
79 sdhc_disable_interrupt(sdhc_dev, SDHC_INT_SDIO);
80 handle_cdint(0);
81 }
82 }
83
sdio_enable_interrupt(void)84 void sdio_enable_interrupt(void)
85 {
86 sdhc_enable_interrupt(sdhc_dev, (sdhc_interrupt_cb_t)sdio_irq_handler, SDHC_INT_SDIO, NULL);
87 return;
88 }
89
sdio_controller_init(void)90 static void sdio_controller_init(void)
91 {
92 (void)memset(&wm_g_sd, 0, sizeof(struct sd_card));
93 }
94
sdio_card_init(void)95 static int sdio_card_init(void)
96 {
97 int ret = WM_SUCCESS;
98 uint32_t resp;
99
100 if (!device_is_ready(sdhc_dev))
101 {
102 sdio_e("SD controller not ready");
103 return -EIO;
104 }
105
106 if (!sdhc_card_present(sdhc_dev))
107 {
108 sdio_e("SDIO card not present");
109 return -EIO;
110 }
111
112 ret = sd_init(sdhc_dev, &wm_g_sd);
113 if (ret)
114 {
115 return ret;
116 }
117
118 memcpy(&g_sdio_funcs[0], &wm_g_sd.func0, sizeof(struct sdio_func));
119 (void)sdio_drv_creg_read(0x0, 0, &resp);
120
121 sdio_d("Card Version - (0x%x)", resp & 0xff);
122 /* Init SDIO functions */
123 sdio_init_func(&wm_g_sd, &g_sdio_funcs[1], SDIO_FUNC_NUM_1);
124 sdio_init_func(&wm_g_sd, &g_sdio_funcs[2], SDIO_FUNC_NUM_2);
125
126 /* Mask interrupts in card */
127 (void)sdio_drv_creg_write(0x4, 0, 0x3, &resp);
128 /* Enable IO in card */
129 (void)sdio_drv_creg_write(0x2, 0, 0x2, &resp);
130
131 (void)sdio_set_block_size(&g_sdio_funcs[0], 256);
132 (void)sdio_set_block_size(&g_sdio_funcs[1], 256);
133 (void)sdio_set_block_size(&g_sdio_funcs[2], 256);
134
135 return ret;
136 }
137
sdio_drv_init(void (* cd_int)(int))138 int sdio_drv_init(void (*cd_int)(int))
139 {
140 sdio_controller_init();
141
142 if (sdio_card_init() != WM_SUCCESS)
143 {
144 sdio_e("Card initialization failed");
145 return -WM_FAIL;
146 }
147 else
148 {
149 sdio_d("Card initialization successful");
150 }
151
152 return WM_SUCCESS;
153 }
154
sdio_drv_deinit(void)155 void sdio_drv_deinit(void)
156 {
157 // SDIO_Deinit(&wm_g_sd);
158 }
159