1 /*
2 * Copyright (c) 2015 Intel Corporation.
3 * Copyright (c) 2023 Synopsys, Inc. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT snps_designware_spi
9
10 /* spi_dw.c - Designware SPI driver implementation */
11
12 #define LOG_LEVEL CONFIG_SPI_LOG_LEVEL
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(spi_dw);
15
16 #if (CONFIG_SPI_LOG_LEVEL == 4)
17 #define DBG_COUNTER_INIT() \
18 uint32_t __cnt = 0
19 #define DBG_COUNTER_INC() \
20 (__cnt++)
21 #define DBG_COUNTER_RESULT() \
22 (__cnt)
23 #else
24 #define DBG_COUNTER_INIT() {; }
25 #define DBG_COUNTER_INC() {; }
26 #define DBG_COUNTER_RESULT() 0
27 #endif
28
29 #include <errno.h>
30
31 #include <zephyr/kernel.h>
32 #include <zephyr/arch/cpu.h>
33
34 #include <zephyr/device.h>
35 #include <zephyr/init.h>
36 #include <zephyr/pm/device.h>
37
38 #include <zephyr/sys/sys_io.h>
39 #include <zephyr/sys/util.h>
40
41 #ifdef CONFIG_IOAPIC
42 #include <zephyr/drivers/interrupt_controller/ioapic.h>
43 #endif
44
45 #include <zephyr/drivers/spi.h>
46 #include <zephyr/irq.h>
47
48 #include "spi_dw.h"
49 #include "spi_context.h"
50
51 #ifdef CONFIG_PINCTRL
52 #include <zephyr/drivers/pinctrl.h>
53 #endif
54
spi_dw_is_slave(struct spi_dw_data * spi)55 static inline bool spi_dw_is_slave(struct spi_dw_data *spi)
56 {
57 return (IS_ENABLED(CONFIG_SPI_SLAVE) &&
58 spi_context_is_slave(&spi->ctx));
59 }
60
completed(const struct device * dev,int error)61 static void completed(const struct device *dev, int error)
62 {
63 const struct spi_dw_config *info = dev->config;
64 struct spi_dw_data *spi = dev->data;
65
66 if (error) {
67 goto out;
68 }
69
70 if (spi_context_tx_on(&spi->ctx) ||
71 spi_context_rx_on(&spi->ctx)) {
72 return;
73 }
74
75 out:
76 /* need to give time for FIFOs to drain before issuing more commands */
77 while (test_bit_sr_busy(info)) {
78 }
79
80 /* Disabling interrupts */
81 write_imr(info, DW_SPI_IMR_MASK);
82 /* Disabling the controller */
83 clear_bit_ssienr(info);
84
85 spi_context_cs_control(&spi->ctx, false);
86
87 LOG_DBG("SPI transaction completed %s error",
88 error ? "with" : "without");
89
90 spi_context_complete(&spi->ctx, dev, error);
91 }
92
push_data(const struct device * dev)93 static void push_data(const struct device *dev)
94 {
95 const struct spi_dw_config *info = dev->config;
96 struct spi_dw_data *spi = dev->data;
97 uint32_t data = 0U;
98 uint32_t f_tx;
99
100 DBG_COUNTER_INIT();
101
102 if (spi_context_rx_on(&spi->ctx)) {
103 f_tx = info->fifo_depth - read_txflr(info) -
104 read_rxflr(info);
105 if ((int)f_tx < 0) {
106 f_tx = 0U; /* if rx-fifo is full, hold off tx */
107 }
108 } else {
109 f_tx = info->fifo_depth - read_txflr(info);
110 }
111
112 while (f_tx) {
113 if (spi_context_tx_buf_on(&spi->ctx)) {
114 switch (spi->dfs) {
115 case 1:
116 data = UNALIGNED_GET((uint8_t *)
117 (spi->ctx.tx_buf));
118 break;
119 case 2:
120 data = UNALIGNED_GET((uint16_t *)
121 (spi->ctx.tx_buf));
122 break;
123 #ifndef CONFIG_ARC
124 case 4:
125 data = UNALIGNED_GET((uint32_t *)
126 (spi->ctx.tx_buf));
127 break;
128 #endif
129 }
130 } else if (spi_context_rx_on(&spi->ctx)) {
131 /* No need to push more than necessary */
132 if ((int)(spi->ctx.rx_len - spi->fifo_diff) <= 0) {
133 break;
134 }
135
136 data = 0U;
137 } else if (spi_context_tx_on(&spi->ctx)) {
138 data = 0U;
139 } else {
140 /* Nothing to push anymore */
141 break;
142 }
143
144 write_dr(info, data);
145
146 spi_context_update_tx(&spi->ctx, spi->dfs, 1);
147 spi->fifo_diff++;
148
149 f_tx--;
150
151 DBG_COUNTER_INC();
152 }
153
154 if (!spi_context_tx_on(&spi->ctx)) {
155 /* prevents any further interrupts demanding TX fifo fill */
156 write_txftlr(info, 0);
157 }
158
159 LOG_DBG("Pushed: %d", DBG_COUNTER_RESULT());
160 }
161
pull_data(const struct device * dev)162 static void pull_data(const struct device *dev)
163 {
164 const struct spi_dw_config *info = dev->config;
165 struct spi_dw_data *spi = dev->data;
166
167 DBG_COUNTER_INIT();
168
169 while (read_rxflr(info)) {
170 uint32_t data = read_dr(info);
171
172 DBG_COUNTER_INC();
173
174 if (spi_context_rx_buf_on(&spi->ctx)) {
175 switch (spi->dfs) {
176 case 1:
177 UNALIGNED_PUT(data, (uint8_t *)spi->ctx.rx_buf);
178 break;
179 case 2:
180 UNALIGNED_PUT(data, (uint16_t *)spi->ctx.rx_buf);
181 break;
182 #ifndef CONFIG_ARC
183 case 4:
184 UNALIGNED_PUT(data, (uint32_t *)spi->ctx.rx_buf);
185 break;
186 #endif
187 }
188 }
189
190 spi_context_update_rx(&spi->ctx, spi->dfs, 1);
191 spi->fifo_diff--;
192 }
193
194 if (!spi->ctx.rx_len && spi->ctx.tx_len < info->fifo_depth) {
195 write_rxftlr(info, spi->ctx.tx_len - 1);
196 } else if (read_rxftlr(info) >= spi->ctx.rx_len) {
197 write_rxftlr(info, spi->ctx.rx_len - 1);
198 }
199
200 LOG_DBG("Pulled: %d", DBG_COUNTER_RESULT());
201 }
202
spi_dw_configure(const struct spi_dw_config * info,struct spi_dw_data * spi,const struct spi_config * config)203 static int spi_dw_configure(const struct spi_dw_config *info,
204 struct spi_dw_data *spi,
205 const struct spi_config *config)
206 {
207 uint32_t ctrlr0 = 0U;
208
209 LOG_DBG("%p (prev %p)", config, spi->ctx.config);
210
211 if (spi_context_configured(&spi->ctx, config)) {
212 /* Nothing to do */
213 return 0;
214 }
215
216 if (config->operation & SPI_HALF_DUPLEX) {
217 LOG_ERR("Half-duplex not supported");
218 return -ENOTSUP;
219 }
220
221 /* Verify if requested op mode is relevant to this controller */
222 if (config->operation & SPI_OP_MODE_SLAVE) {
223 if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_SLAVE)) {
224 LOG_ERR("Slave mode not supported");
225 return -ENOTSUP;
226 }
227 } else {
228 if (!(info->op_modes & SPI_CTX_RUNTIME_OP_MODE_MASTER)) {
229 LOG_ERR("Master mode not supported");
230 return -ENOTSUP;
231 }
232 }
233
234 if ((config->operation & SPI_TRANSFER_LSB) ||
235 (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) &&
236 (config->operation & (SPI_LINES_DUAL |
237 SPI_LINES_QUAD | SPI_LINES_OCTAL)))) {
238 LOG_ERR("Unsupported configuration");
239 return -EINVAL;
240 }
241
242 /* Word size */
243 ctrlr0 |= DW_SPI_CTRLR0_DFS(SPI_WORD_SIZE_GET(config->operation));
244
245 /* Determine how many bytes are required per-frame */
246 spi->dfs = SPI_WS_TO_DFS(SPI_WORD_SIZE_GET(config->operation));
247
248 /* SPI mode */
249 if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) {
250 ctrlr0 |= DW_SPI_CTRLR0_SCPOL;
251 }
252
253 if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) {
254 ctrlr0 |= DW_SPI_CTRLR0_SCPH;
255 }
256
257 if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) {
258 ctrlr0 |= DW_SPI_CTRLR0_SRL;
259 }
260
261 /* Installing the configuration */
262 write_ctrlr0(info, ctrlr0);
263
264 /* At this point, it's mandatory to set this on the context! */
265 spi->ctx.config = config;
266
267 if (!spi_dw_is_slave(spi)) {
268 /* Baud rate and Slave select, for master only */
269 write_baudr(info, SPI_DW_CLK_DIVIDER(info->clock_frequency,
270 config->frequency));
271 write_ser(info, 1 << config->slave);
272 }
273
274 if (spi_dw_is_slave(spi)) {
275 LOG_DBG("Installed slave config %p:"
276 " ws/dfs %u/%u, mode %u/%u/%u",
277 config,
278 SPI_WORD_SIZE_GET(config->operation), spi->dfs,
279 (SPI_MODE_GET(config->operation) &
280 SPI_MODE_CPOL) ? 1 : 0,
281 (SPI_MODE_GET(config->operation) &
282 SPI_MODE_CPHA) ? 1 : 0,
283 (SPI_MODE_GET(config->operation) &
284 SPI_MODE_LOOP) ? 1 : 0);
285 } else {
286 LOG_DBG("Installed master config %p: freq %uHz (div = %u),"
287 " ws/dfs %u/%u, mode %u/%u/%u, slave %u",
288 config, config->frequency,
289 SPI_DW_CLK_DIVIDER(info->clock_frequency,
290 config->frequency),
291 SPI_WORD_SIZE_GET(config->operation), spi->dfs,
292 (SPI_MODE_GET(config->operation) &
293 SPI_MODE_CPOL) ? 1 : 0,
294 (SPI_MODE_GET(config->operation) &
295 SPI_MODE_CPHA) ? 1 : 0,
296 (SPI_MODE_GET(config->operation) &
297 SPI_MODE_LOOP) ? 1 : 0,
298 config->slave);
299 }
300
301 return 0;
302 }
303
spi_dw_compute_ndf(const struct spi_buf * rx_bufs,size_t rx_count,uint8_t dfs)304 static uint32_t spi_dw_compute_ndf(const struct spi_buf *rx_bufs,
305 size_t rx_count, uint8_t dfs)
306 {
307 uint32_t len = 0U;
308
309 for (; rx_count; rx_bufs++, rx_count--) {
310 if (len > (UINT16_MAX - rx_bufs->len)) {
311 goto error;
312 }
313
314 len += rx_bufs->len;
315 }
316
317 if (len) {
318 return (len / dfs) - 1;
319 }
320 error:
321 return UINT32_MAX;
322 }
323
spi_dw_update_txftlr(const struct spi_dw_config * info,struct spi_dw_data * spi)324 static void spi_dw_update_txftlr(const struct spi_dw_config *info,
325 struct spi_dw_data *spi)
326 {
327 uint32_t dw_spi_txftlr_dflt = (info->fifo_depth * 1) / 2;
328 uint32_t reg_data = dw_spi_txftlr_dflt;
329
330 if (spi_dw_is_slave(spi)) {
331 if (!spi->ctx.tx_len) {
332 reg_data = 0U;
333 } else if (spi->ctx.tx_len < dw_spi_txftlr_dflt) {
334 reg_data = spi->ctx.tx_len - 1;
335 }
336 }
337
338 LOG_DBG("TxFTLR: %u", reg_data);
339
340 write_txftlr(info, reg_data);
341 }
342
transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,bool asynchronous,spi_callback_t cb,void * userdata)343 static int transceive(const struct device *dev,
344 const struct spi_config *config,
345 const struct spi_buf_set *tx_bufs,
346 const struct spi_buf_set *rx_bufs,
347 bool asynchronous,
348 spi_callback_t cb,
349 void *userdata)
350 {
351 const struct spi_dw_config *info = dev->config;
352 struct spi_dw_data *spi = dev->data;
353 uint32_t tmod = DW_SPI_CTRLR0_TMOD_TX_RX;
354 uint32_t dw_spi_rxftlr_dflt = (info->fifo_depth * 5) / 8;
355 uint32_t reg_data;
356 int ret;
357
358 spi_context_lock(&spi->ctx, asynchronous, cb, userdata, config);
359
360 #ifdef CONFIG_PM_DEVICE
361 if (!pm_device_is_busy(dev)) {
362 pm_device_busy_set(dev);
363 }
364 #endif /* CONFIG_PM_DEVICE */
365
366 /* Configure */
367 ret = spi_dw_configure(info, spi, config);
368 if (ret) {
369 goto out;
370 }
371
372 if (!rx_bufs || !rx_bufs->buffers) {
373 tmod = DW_SPI_CTRLR0_TMOD_TX;
374 } else if (!tx_bufs || !tx_bufs->buffers) {
375 tmod = DW_SPI_CTRLR0_TMOD_RX;
376 }
377
378 /* ToDo: add a way to determine EEPROM mode */
379
380 if (tmod >= DW_SPI_CTRLR0_TMOD_RX &&
381 !spi_dw_is_slave(spi)) {
382 reg_data = spi_dw_compute_ndf(rx_bufs->buffers,
383 rx_bufs->count,
384 spi->dfs);
385 if (reg_data == UINT32_MAX) {
386 ret = -EINVAL;
387 goto out;
388 }
389
390 write_ctrlr1(info, reg_data);
391 } else {
392 write_ctrlr1(info, 0);
393 }
394
395 if (spi_dw_is_slave(spi)) {
396 /* Enabling MISO line relevantly */
397 if (tmod == DW_SPI_CTRLR0_TMOD_RX) {
398 tmod |= DW_SPI_CTRLR0_SLV_OE;
399 } else {
400 tmod &= ~DW_SPI_CTRLR0_SLV_OE;
401 }
402 }
403
404 /* Updating TMOD in CTRLR0 register */
405 reg_data = read_ctrlr0(info);
406 reg_data &= ~DW_SPI_CTRLR0_TMOD_RESET;
407 reg_data |= tmod;
408
409 write_ctrlr0(info, reg_data);
410
411 /* Set buffers info */
412 spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, spi->dfs);
413
414 spi->fifo_diff = 0U;
415
416 /* Tx Threshold */
417 spi_dw_update_txftlr(info, spi);
418
419 /* Does Rx thresholds needs to be lower? */
420 reg_data = dw_spi_rxftlr_dflt;
421
422 if (spi_dw_is_slave(spi)) {
423 if (spi->ctx.rx_len &&
424 spi->ctx.rx_len < dw_spi_rxftlr_dflt) {
425 reg_data = spi->ctx.rx_len - 1;
426 }
427 } else {
428 if (spi->ctx.rx_len && spi->ctx.rx_len < info->fifo_depth) {
429 reg_data = spi->ctx.rx_len - 1;
430 }
431 }
432
433 /* Rx Threshold */
434 write_rxftlr(info, reg_data);
435
436 /* Enable interrupts */
437 reg_data = !rx_bufs ?
438 DW_SPI_IMR_UNMASK & DW_SPI_IMR_MASK_RX :
439 DW_SPI_IMR_UNMASK;
440 write_imr(info, reg_data);
441
442 spi_context_cs_control(&spi->ctx, true);
443
444 LOG_DBG("Enabling controller");
445 set_bit_ssienr(info);
446
447 ret = spi_context_wait_for_completion(&spi->ctx);
448 out:
449 spi_context_release(&spi->ctx, ret);
450
451 pm_device_busy_clear(dev);
452
453 return ret;
454 }
455
spi_dw_transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)456 static int spi_dw_transceive(const struct device *dev,
457 const struct spi_config *config,
458 const struct spi_buf_set *tx_bufs,
459 const struct spi_buf_set *rx_bufs)
460 {
461 LOG_DBG("%p, %p, %p", dev, tx_bufs, rx_bufs);
462
463 return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL);
464 }
465
466 #ifdef CONFIG_SPI_ASYNC
spi_dw_transceive_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,spi_callback_t cb,void * userdata)467 static int spi_dw_transceive_async(const struct device *dev,
468 const struct spi_config *config,
469 const struct spi_buf_set *tx_bufs,
470 const struct spi_buf_set *rx_bufs,
471 spi_callback_t cb,
472 void *userdata)
473 {
474 LOG_DBG("%p, %p, %p, %p, %p", dev, tx_bufs, rx_bufs, cb, userdata);
475
476 return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata);
477 }
478 #endif /* CONFIG_SPI_ASYNC */
479
spi_dw_release(const struct device * dev,const struct spi_config * config)480 static int spi_dw_release(const struct device *dev,
481 const struct spi_config *config)
482 {
483 struct spi_dw_data *spi = dev->data;
484
485 if (!spi_context_configured(&spi->ctx, config)) {
486 return -EINVAL;
487 }
488
489 spi_context_unlock_unconditionally(&spi->ctx);
490
491 return 0;
492 }
493
spi_dw_isr(const struct device * dev)494 void spi_dw_isr(const struct device *dev)
495 {
496 const struct spi_dw_config *info = dev->config;
497 uint32_t int_status;
498 int error;
499
500 int_status = read_isr(info);
501
502 LOG_DBG("SPI %p int_status 0x%x - (tx: %d, rx: %d)", dev, int_status,
503 read_txflr(info), read_rxflr(info));
504
505 if (int_status & DW_SPI_ISR_ERRORS_MASK) {
506 error = -EIO;
507 goto out;
508 }
509
510 error = 0;
511
512 if (int_status & DW_SPI_ISR_RXFIS) {
513 pull_data(dev);
514 }
515
516 if (int_status & DW_SPI_ISR_TXEIS) {
517 push_data(dev);
518 }
519
520 out:
521 clear_interrupts(info);
522 completed(dev, error);
523 }
524
525 static const struct spi_driver_api dw_spi_api = {
526 .transceive = spi_dw_transceive,
527 #ifdef CONFIG_SPI_ASYNC
528 .transceive_async = spi_dw_transceive_async,
529 #endif /* CONFIG_SPI_ASYNC */
530 .release = spi_dw_release,
531 };
532
spi_dw_init(const struct device * dev)533 int spi_dw_init(const struct device *dev)
534 {
535 int err;
536 const struct spi_dw_config *info = dev->config;
537 struct spi_dw_data *spi = dev->data;
538
539 #ifdef CONFIG_PINCTRL
540 pinctrl_apply_state(info->pcfg, PINCTRL_STATE_DEFAULT);
541 #endif
542
543 info->config_func();
544
545 /* Masking interrupt and making sure controller is disabled */
546 write_imr(info, DW_SPI_IMR_MASK);
547 clear_bit_ssienr(info);
548
549 LOG_DBG("Designware SPI driver initialized on device: %p", dev);
550
551 err = spi_context_cs_configure_all(&spi->ctx);
552 if (err < 0) {
553 return err;
554 }
555
556 spi_context_unlock_unconditionally(&spi->ctx);
557
558 return 0;
559 }
560
561
562 #if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay)
563 void spi_config_0_irq(void);
564
565 struct spi_dw_data spi_dw_data_port_0 = {
566 SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_0, ctx),
567 SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_0, ctx),
568 SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(0), ctx)
569 };
570
571 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency)
572 #define INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
573 DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency)
574 #else
575 #define INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
576 DT_INST_PROP(0, clock_frequency)
577 #endif
578
579 #ifdef CONFIG_PINCTRL
580 PINCTRL_DT_INST_DEFINE(0);
581 #endif
582 const struct spi_dw_config spi_dw_config_0 = {
583 .regs = DT_INST_REG_ADDR(0),
584 .clock_frequency = INST_0_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
585 .config_func = spi_config_0_irq,
586 .op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
587 .fifo_depth = DT_INST_PROP(0, fifo_depth),
588 #ifdef CONFIG_PINCTRL
589 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
590 #endif
591 #if DT_INST_PROP(0, aux_reg)
592 .read_func = aux_reg_read,
593 .write_func = aux_reg_write,
594 .set_bit_func = aux_reg_set_bit,
595 .clear_bit_func = aux_reg_clear_bit,
596 .test_bit_func = aux_reg_test_bit
597 #else
598 .read_func = reg_read,
599 .write_func = reg_write,
600 .set_bit_func = reg_set_bit,
601 .clear_bit_func = reg_clear_bit,
602 .test_bit_func = reg_test_bit
603 #endif
604 };
605
606 DEVICE_DT_INST_DEFINE(0, spi_dw_init, NULL,
607 &spi_dw_data_port_0, &spi_dw_config_0,
608 POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
609 &dw_spi_api);
610
spi_config_0_irq(void)611 void spi_config_0_irq(void)
612 {
613 #if DT_NUM_IRQS(DT_DRV_INST(0)) == 1
614 #if DT_INST_IRQ_HAS_NAME(0, flags)
615 #define INST_0_IRQ_FLAGS DT_INST_IRQ_BY_NAME(0, flags, irq)
616 #else
617 #define INST_0_IRQ_FLAGS 0
618 #endif
619 IRQ_CONNECT(DT_INST_IRQN(0),
620 DT_INST_IRQ(0, priority),
621 spi_dw_isr, DEVICE_DT_INST_GET(0),
622 INST_0_IRQ_FLAGS);
623 irq_enable(DT_INST_IRQN(0));
624 #else
625 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, rx_avail, irq),
626 DT_INST_IRQ_BY_NAME(0, rx_avail, priority),
627 spi_dw_isr, DEVICE_DT_INST_GET(0),
628 0);
629 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, tx_req, irq),
630 DT_INST_IRQ_BY_NAME(0, tx_req, priority),
631 spi_dw_isr, DEVICE_DT_INST_GET(0),
632 0);
633 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, err_int, irq),
634 DT_INST_IRQ_BY_NAME(0, err_int, priority),
635 spi_dw_isr, DEVICE_DT_INST_GET(0),
636 0);
637
638 irq_enable(DT_INST_IRQ_BY_NAME(0, rx_avail, irq));
639 irq_enable(DT_INST_IRQ_BY_NAME(0, tx_req, irq));
640 irq_enable(DT_INST_IRQ_BY_NAME(0, err_int, irq));
641
642 #endif
643 }
644 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) */
645
646 #if DT_NODE_HAS_STATUS(DT_DRV_INST(1), okay)
647 void spi_config_1_irq(void);
648
649 struct spi_dw_data spi_dw_data_port_1 = {
650 SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_1, ctx),
651 SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_1, ctx),
652 SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(1), ctx)
653 };
654
655 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(1, clocks), clock_frequency)
656 #define INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
657 DT_INST_PROP_BY_PHANDLE(1, clocks, clock_frequency)
658 #else
659 #define INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
660 DT_INST_PROP(1, clock_frequency)
661 #endif
662
663 #ifdef CONFIG_PINCTRL
664 PINCTRL_DT_INST_DEFINE(1);
665 #endif
666 static const struct spi_dw_config spi_dw_config_1 = {
667 .regs = DT_INST_REG_ADDR(1),
668 .clock_frequency = INST_1_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
669 .config_func = spi_config_1_irq,
670 .op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
671 .fifo_depth = DT_INST_PROP(1, fifo_depth),
672 #ifdef CONFIG_PINCTRL
673 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(1),
674 #endif
675 #if DT_INST_PROP(1, aux_reg)
676 .read_func = aux_reg_read,
677 .write_func = aux_reg_write,
678 .set_bit_func = aux_reg_set_bit,
679 .clear_bit_func = aux_reg_clear_bit,
680 .test_bit_func = aux_reg_test_bit
681 #else
682 .read_func = reg_read,
683 .write_func = reg_write,
684 .set_bit_func = reg_set_bit,
685 .clear_bit_func = reg_clear_bit,
686 .test_bit_func = reg_test_bit
687 #endif
688 };
689
690 DEVICE_DT_INST_DEFINE(1, spi_dw_init, NULL,
691 &spi_dw_data_port_1, &spi_dw_config_1,
692 POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
693 &dw_spi_api);
694
spi_config_1_irq(void)695 void spi_config_1_irq(void)
696 {
697 #if DT_NUM_IRQS(DT_DRV_INST(1)) == 1
698 #if DT_INST_IRQ_HAS_NAME(1, flags)
699 #define INST_1_IRQ_FLAGS DT_INST_IRQ_BY_NAME(1, flags, irq)
700 #else
701 #define INST_1_IRQ_FLAGS 0
702 #endif
703 IRQ_CONNECT(DT_INST_IRQN(1),
704 DT_INST_IRQ(1, priority),
705 spi_dw_isr, DEVICE_DT_INST_GET(1),
706 INST_1_IRQ_FLAGS);
707 irq_enable(DT_INST_IRQN(1));
708 #else
709 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, rx_avail, irq),
710 DT_INST_IRQ_BY_NAME(1, rx_avail, priority),
711 spi_dw_isr, DEVICE_DT_INST_GET(1),
712 0);
713 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, tx_req, irq),
714 DT_INST_IRQ_BY_NAME(1, tx_req, priority),
715 spi_dw_isr, DEVICE_DT_INST_GET(1),
716 0);
717 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, err_int, irq),
718 DT_INST_IRQ_BY_NAME(1, err_int, priority),
719 spi_dw_isr, DEVICE_DT_INST_GET(1),
720 0);
721
722 irq_enable(DT_INST_IRQ_BY_NAME(1, rx_avail, irq));
723 irq_enable(DT_INST_IRQ_BY_NAME(1, tx_req, irq));
724 irq_enable(DT_INST_IRQ_BY_NAME(1, err_int, irq));
725
726 #endif
727 }
728 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(1), okay) */
729
730 #if DT_NODE_HAS_STATUS(DT_DRV_INST(2), okay)
731 void spi_config_2_irq(void);
732
733 struct spi_dw_data spi_dw_data_port_2 = {
734 SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_2, ctx),
735 SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_2, ctx),
736 SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(2), ctx)
737 };
738
739 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(2, clocks), clock_frequency)
740 #define INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
741 DT_INST_PROP_BY_PHANDLE(2, clocks, clock_frequency)
742 #else
743 #define INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
744 DT_INST_PROP(2, clock_frequency)
745 #endif
746
747 #ifdef CONFIG_PINCTRL
748 PINCTRL_DT_INST_DEFINE(2);
749 #endif
750 static const struct spi_dw_config spi_dw_config_2 = {
751 .regs = DT_INST_REG_ADDR(2),
752 .clock_frequency = INST_2_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
753 .config_func = spi_config_2_irq,
754 .op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
755 .fifo_depth = DT_INST_PROP(2, fifo_depth),
756 #ifdef CONFIG_PINCTRL
757 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(2),
758 #endif
759 #if DT_INST_PROP(2, aux_reg)
760 .read_func = aux_reg_read,
761 .write_func = aux_reg_write,
762 .set_bit_func = aux_reg_set_bit,
763 .clear_bit_func = aux_reg_clear_bit,
764 .test_bit_func = aux_reg_test_bit
765 #else
766 .read_func = reg_read,
767 .write_func = reg_write,
768 .set_bit_func = reg_set_bit,
769 .clear_bit_func = reg_clear_bit,
770 .test_bit_func = reg_test_bit
771 #endif
772 };
773
774 DEVICE_DT_INST_DEFINE(2, spi_dw_init, NULL,
775 &spi_dw_data_port_2, &spi_dw_config_2,
776 POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
777 &dw_spi_api);
778
spi_config_2_irq(void)779 void spi_config_2_irq(void)
780 {
781 #if DT_NUM_IRQS(DT_DRV_INST(2)) == 1
782 #if DT_INST_IRQ_HAS_NAME(2, flags)
783 #define INST_2_IRQ_FLAGS DT_INST_IRQ_BY_NAME(2, flags, irq)
784 #else
785 #define INST_2_IRQ_FLAGS 0
786 #endif
787 IRQ_CONNECT(DT_INST_IRQN(2),
788 DT_INST_IRQ(2, priority),
789 spi_dw_isr, DEVICE_DT_INST_GET(2),
790 INST_2_IRQ_FLAGS);
791 irq_enable(DT_INST_IRQN(2));
792 #else
793 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, rx_avail, irq),
794 DT_INST_IRQ_BY_NAME(2, rx_avail, priority),
795 spi_dw_isr, DEVICE_DT_INST_GET(2),
796 0);
797 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, tx_req, irq),
798 DT_INST_IRQ_BY_NAME(2, tx_req, priority),
799 spi_dw_isr, DEVICE_DT_INST_GET(2),
800 0);
801 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, err_int, irq),
802 DT_INST_IRQ_BY_NAME(2, err_int, priority),
803 spi_dw_isr, DEVICE_DT_INST_GET(2),
804 0);
805
806 irq_enable(DT_INST_IRQ_BY_NAME(2, rx_avail, irq));
807 irq_enable(DT_INST_IRQ_BY_NAME(2, tx_req, irq));
808 irq_enable(DT_INST_IRQ_BY_NAME(2, err_int, irq));
809
810 #endif
811 }
812 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(2), okay) */
813
814 #if DT_NODE_HAS_STATUS(DT_DRV_INST(3), okay)
815 void spi_config_3_irq(void);
816
817 struct spi_dw_data spi_dw_data_port_3 = {
818 SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_3, ctx),
819 SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_3, ctx),
820 SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(3), ctx)
821 };
822
823 #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(3, clocks), clock_frequency)
824 #define INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
825 DT_INST_PROP_BY_PHANDLE(3, clocks, clock_frequency)
826 #else
827 #define INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ \
828 DT_INST_PROP(3, clock_frequency)
829 #endif
830
831 #ifdef CONFIG_PINCTRL
832 PINCTRL_DT_INST_DEFINE(3);
833 #endif
834 static const struct spi_dw_config spi_dw_config_3 = {
835 .regs = DT_INST_REG_ADDR(3),
836 .clock_frequency = INST_3_SNPS_DESIGNWARE_SPI_CLOCK_FREQ,
837 .config_func = spi_config_3_irq,
838 .op_modes = SPI_CTX_RUNTIME_OP_MODE_MASTER,
839 .fifo_depth = DT_INST_PROP(3, fifo_depth),
840 #ifdef CONFIG_PINCTRL
841 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(3),
842 #endif
843 #if DT_INST_PROP(3, aux_reg)
844 .read_func = aux_reg_read,
845 .write_func = aux_reg_write,
846 .set_bit_func = aux_reg_set_bit,
847 .clear_bit_func = aux_reg_clear_bit,
848 .test_bit_func = aux_reg_test_bit
849 #else
850 .read_func = reg_read,
851 .write_func = reg_write,
852 .set_bit_func = reg_set_bit,
853 .clear_bit_func = reg_clear_bit,
854 .test_bit_func = reg_test_bit
855 #endif
856 };
857
858 DEVICE_DT_INST_DEFINE(3, spi_dw_init, NULL,
859 &spi_dw_data_port_3, &spi_dw_config_3,
860 POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
861 &dw_spi_api);
862
spi_config_3_irq(void)863 void spi_config_3_irq(void)
864 {
865 #if DT_NUM_IRQS(DT_DRV_INST(3)) == 1
866 #if DT_INST_IRQ_HAS_NAME(3, flags)
867 #define INST_3_IRQ_FLAGS DT_INST_IRQ_BY_NAME(3, flags, irq)
868 #else
869 #define INST_3_IRQ_FLAGS 0
870 #endif
871 IRQ_CONNECT(DT_INST_IRQN(3),
872 DT_INST_IRQ(3, priority),
873 spi_dw_isr, DEVICE_DT_INST_GET(3),
874 INST_3_IRQ_FLAGS);
875 irq_enable(DT_INST_IRQN(3));
876 #else
877 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, rx_avail, irq),
878 DT_INST_IRQ_BY_NAME(3, rx_avail, priority),
879 spi_dw_isr, DEVICE_DT_INST_GET(3),
880 0);
881 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, tx_req, irq),
882 DT_INST_IRQ_BY_NAME(3, tx_req, priority),
883 spi_dw_isr, DEVICE_DT_INST_GET(3),
884 0);
885 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, err_int, irq),
886 DT_INST_IRQ_BY_NAME(3, err_int, priority),
887 spi_dw_isr, DEVICE_DT_INST_GET(3),
888 0);
889
890 irq_enable(DT_INST_IRQ_BY_NAME(3, rx_avail, irq));
891 irq_enable(DT_INST_IRQ_BY_NAME(3, tx_req, irq));
892 irq_enable(DT_INST_IRQ_BY_NAME(3, err_int, irq));
893
894 #endif
895 }
896 #endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(3), okay) */
897