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