1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing QSPI Bus Layer specific function definitions of the
9 * Wi-Fi driver.
10 */
11
12 #include "bal_structs.h"
13 #include "spi.h"
14 #include "pal.h"
15
16
nrf_wifi_bus_spi_irq_handler(void * data)17 static int nrf_wifi_bus_spi_irq_handler(void *data)
18 {
19 struct nrf_wifi_bus_spi_dev_ctx *dev_ctx = NULL;
20 struct nrf_wifi_bus_spi_priv *spi_priv = NULL;
21 int ret = 0;
22
23 dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)data;
24 spi_priv = dev_ctx->spi_priv;
25
26 ret = spi_priv->intr_callbk_fn(dev_ctx->bal_dev_ctx);
27
28 return ret;
29 }
30
31
nrf_wifi_bus_spi_dev_add(void * bus_priv,void * bal_dev_ctx)32 static void *nrf_wifi_bus_spi_dev_add(void *bus_priv,
33 void *bal_dev_ctx)
34 {
35 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
36 struct nrf_wifi_bus_spi_priv *spi_priv = NULL;
37 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
38 struct nrf_wifi_osal_host_map host_map;
39
40 spi_priv = bus_priv;
41
42 spi_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*spi_dev_ctx));
43
44 if (!spi_dev_ctx) {
45 nrf_wifi_osal_log_err("%s: Unable to allocate spi_dev_ctx", __func__);
46 goto out;
47 }
48
49 spi_dev_ctx->spi_priv = spi_priv;
50 spi_dev_ctx->bal_dev_ctx = bal_dev_ctx;
51
52 spi_dev_ctx->os_spi_dev_ctx = nrf_wifi_osal_bus_spi_dev_add(spi_priv->os_spi_priv,
53 spi_dev_ctx);
54
55 if (!spi_dev_ctx->os_spi_dev_ctx) {
56 nrf_wifi_osal_log_err("%s: nrf_wifi_osal_bus_spi_dev_add failed", __func__);
57
58 nrf_wifi_osal_mem_free(spi_dev_ctx);
59
60 spi_dev_ctx = NULL;
61
62 goto out;
63 }
64
65 nrf_wifi_osal_bus_spi_dev_host_map_get(spi_dev_ctx->os_spi_dev_ctx,
66 &host_map);
67
68 spi_dev_ctx->host_addr_base = host_map.addr;
69
70 spi_dev_ctx->addr_pktram_base = spi_dev_ctx->host_addr_base +
71 spi_priv->cfg_params.addr_pktram_base;
72
73 out:
74 return spi_dev_ctx;
75 }
76
77
nrf_wifi_bus_spi_dev_rem(void * bus_dev_ctx)78 static void nrf_wifi_bus_spi_dev_rem(void *bus_dev_ctx)
79 {
80 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
81
82 spi_dev_ctx = bus_dev_ctx;
83
84 nrf_wifi_osal_mem_free(spi_dev_ctx);
85 }
86
87
nrf_wifi_bus_spi_dev_init(void * bus_dev_ctx)88 static enum nrf_wifi_status nrf_wifi_bus_spi_dev_init(void *bus_dev_ctx)
89 {
90 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
91 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
92
93 spi_dev_ctx = bus_dev_ctx;
94
95
96 status = nrf_wifi_osal_bus_spi_dev_intr_reg(spi_dev_ctx->os_spi_dev_ctx, spi_dev_ctx,
97 &nrf_wifi_bus_spi_irq_handler);
98
99 if (status != NRF_WIFI_STATUS_SUCCESS) {
100 nrf_wifi_osal_log_err(
101 "%s: Unable to register interrupt to the OS",
102 __func__);
103 goto out;
104 }
105
106 status = nrf_wifi_osal_bus_spi_dev_init(spi_dev_ctx->os_spi_dev_ctx);
107
108 if (status != NRF_WIFI_STATUS_SUCCESS) {
109 nrf_wifi_osal_log_err("%s: nrf_wifi_osal_spi_dev_init failed", __func__);
110
111 nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->os_spi_dev_ctx);
112 goto out;
113 }
114 out:
115 return status;
116 }
117
118
nrf_wifi_bus_spi_dev_deinit(void * bus_dev_ctx)119 static void nrf_wifi_bus_spi_dev_deinit(void *bus_dev_ctx)
120 {
121 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
122
123 spi_dev_ctx = bus_dev_ctx;
124
125 nrf_wifi_osal_bus_spi_dev_intr_unreg(
126 spi_dev_ctx->os_spi_dev_ctx);
127
128 nrf_wifi_osal_bus_spi_dev_deinit(
129 spi_dev_ctx->os_spi_dev_ctx);
130 }
131
132
nrf_wifi_bus_spi_init(void * params,enum nrf_wifi_status (* intr_callbk_fn)(void * bal_dev_ctx))133 static void *nrf_wifi_bus_spi_init(void *params,
134 enum nrf_wifi_status (*intr_callbk_fn)(void *bal_dev_ctx))
135 {
136 struct nrf_wifi_bus_spi_priv *spi_priv = NULL;
137
138 spi_priv = nrf_wifi_osal_mem_zalloc(sizeof(*spi_priv));
139
140 if (!spi_priv) {
141 nrf_wifi_osal_log_err("%s: Unable to allocate memory for spi_priv",
142 __func__);
143 goto out;
144 }
145
146 nrf_wifi_osal_mem_cpy(&spi_priv->cfg_params,
147 params,
148 sizeof(spi_priv->cfg_params));
149
150 spi_priv->intr_callbk_fn = intr_callbk_fn;
151
152 spi_priv->os_spi_priv = nrf_wifi_osal_bus_spi_init();
153 if (!spi_priv->os_spi_priv) {
154 nrf_wifi_osal_log_err("%s: Unable to register QSPI driver",
155 __func__);
156
157 nrf_wifi_osal_mem_free(spi_priv);
158
159 spi_priv = NULL;
160
161 goto out;
162 }
163 out:
164 return spi_priv;
165 }
166
167
nrf_wifi_bus_spi_deinit(void * bus_priv)168 static void nrf_wifi_bus_spi_deinit(void *bus_priv)
169 {
170 struct nrf_wifi_bus_spi_priv *spi_priv = NULL;
171
172 spi_priv = bus_priv;
173
174 nrf_wifi_osal_bus_spi_deinit(spi_priv->os_spi_priv);
175
176 nrf_wifi_osal_mem_free(spi_priv);
177 }
178
179
nrf_wifi_bus_spi_read_word(void * dev_ctx,unsigned long addr_offset)180 static unsigned int nrf_wifi_bus_spi_read_word(void *dev_ctx,
181 unsigned long addr_offset)
182 {
183 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
184 unsigned int val = 0;
185
186 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
187
188 val = nrf_wifi_osal_spi_read_reg32(spi_dev_ctx->os_spi_dev_ctx,
189 spi_dev_ctx->host_addr_base + addr_offset);
190 return val;
191 }
192
193
nrf_wifi_bus_spi_write_word(void * dev_ctx,unsigned long addr_offset,unsigned int val)194 static void nrf_wifi_bus_spi_write_word(void *dev_ctx,
195 unsigned long addr_offset,
196 unsigned int val)
197 {
198 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
199
200 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
201
202 nrf_wifi_osal_spi_write_reg32(spi_dev_ctx->os_spi_dev_ctx,
203 spi_dev_ctx->host_addr_base + addr_offset,
204 val);
205 }
206
207
nrf_wifi_bus_spi_read_block(void * dev_ctx,void * dest_addr,unsigned long src_addr_offset,size_t len)208 static void nrf_wifi_bus_spi_read_block(void *dev_ctx,
209 void *dest_addr,
210 unsigned long src_addr_offset,
211 size_t len)
212 {
213 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
214
215 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
216
217 nrf_wifi_osal_spi_cpy_from(spi_dev_ctx->os_spi_dev_ctx,
218 dest_addr,
219 spi_dev_ctx->host_addr_base + src_addr_offset,
220 len);
221 }
222
223
nrf_wifi_bus_spi_write_block(void * dev_ctx,unsigned long dest_addr_offset,const void * src_addr,size_t len)224 static void nrf_wifi_bus_spi_write_block(void *dev_ctx,
225 unsigned long dest_addr_offset,
226 const void *src_addr,
227 size_t len)
228 {
229 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
230
231 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
232
233 nrf_wifi_osal_spi_cpy_to(spi_dev_ctx->os_spi_dev_ctx,
234 spi_dev_ctx->host_addr_base + dest_addr_offset,
235 src_addr,
236 len);
237 }
238
239
nrf_wifi_bus_spi_dma_map(void * dev_ctx,unsigned long virt_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)240 static unsigned long nrf_wifi_bus_spi_dma_map(void *dev_ctx,
241 unsigned long virt_addr,
242 size_t len,
243 enum nrf_wifi_osal_dma_dir dma_dir)
244 {
245 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
246 unsigned long phy_addr = 0;
247
248 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
249
250 phy_addr = spi_dev_ctx->host_addr_base + (virt_addr - spi_dev_ctx->addr_pktram_base);
251
252
253 return phy_addr;
254 }
255
256
nrf_wifi_bus_spi_dma_unmap(void * dev_ctx,unsigned long phy_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)257 static unsigned long nrf_wifi_bus_spi_dma_unmap(void *dev_ctx,
258 unsigned long phy_addr,
259 size_t len,
260 enum nrf_wifi_osal_dma_dir dma_dir)
261 {
262 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
263 unsigned long virt_addr = 0;
264
265 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
266
267 virt_addr = spi_dev_ctx->addr_pktram_base + (phy_addr - spi_dev_ctx->host_addr_base);
268
269 return virt_addr;
270 }
271
272
273 #ifdef NRF_WIFI_LOW_POWER
nrf_wifi_bus_spi_ps_sleep(void * dev_ctx)274 static void nrf_wifi_bus_spi_ps_sleep(void *dev_ctx)
275 {
276 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
277
278 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
279
280 nrf_wifi_osal_bus_qspi_ps_sleep(spi_dev_ctx->os_spi_dev_ctx);
281 }
282
283
nrf_wifi_bus_spi_ps_wake(void * dev_ctx)284 static void nrf_wifi_bus_spi_ps_wake(void *dev_ctx)
285 {
286 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
287
288 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
289
290 nrf_wifi_osal_bus_qspi_ps_wake(spi_dev_ctx->os_spi_dev_ctx);
291 }
292
293
nrf_wifi_bus_spi_ps_status(void * dev_ctx)294 static int nrf_wifi_bus_spi_ps_status(void *dev_ctx)
295 {
296 struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL;
297
298 spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx;
299
300 return nrf_wifi_osal_bus_qspi_ps_status(spi_dev_ctx->os_spi_dev_ctx);
301 }
302 #endif /* NRF_WIFI_LOW_POWER */
303
304
305 static struct nrf_wifi_bal_ops nrf_wifi_bus_spi_ops = {
306 .init = &nrf_wifi_bus_spi_init,
307 .deinit = &nrf_wifi_bus_spi_deinit,
308 .dev_add = &nrf_wifi_bus_spi_dev_add,
309 .dev_rem = &nrf_wifi_bus_spi_dev_rem,
310 .dev_init = &nrf_wifi_bus_spi_dev_init,
311 .dev_deinit = &nrf_wifi_bus_spi_dev_deinit,
312 .read_word = &nrf_wifi_bus_spi_read_word,
313 .write_word = &nrf_wifi_bus_spi_write_word,
314 .read_block = &nrf_wifi_bus_spi_read_block,
315 .write_block = &nrf_wifi_bus_spi_write_block,
316 .dma_map = &nrf_wifi_bus_spi_dma_map,
317 .dma_unmap = &nrf_wifi_bus_spi_dma_unmap,
318 #ifdef NRF_WIFI_LOW_POWER
319 .rpu_ps_sleep = &nrf_wifi_bus_spi_ps_sleep,
320 .rpu_ps_wake = &nrf_wifi_bus_spi_ps_wake,
321 .rpu_ps_status = &nrf_wifi_bus_spi_ps_status,
322 #endif /* NRF_WIFI_LOW_POWER */
323 };
324
325
get_bus_ops(void)326 struct nrf_wifi_bal_ops *get_bus_ops(void)
327 {
328 return &nrf_wifi_bus_spi_ops;
329 }
330