1 /*
2 * Copyright (c) 2019 Microchip Technology Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT microchip_xec_qmspi
8
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(spi_xec, CONFIG_SPI_LOG_LEVEL);
11
12 #include "spi_context.h"
13 #include <errno.h>
14 #include <zephyr/device.h>
15 #include <zephyr/drivers/spi.h>
16 #include <zephyr/drivers/spi/rtio.h>
17 #include <zephyr/drivers/pinctrl.h>
18 #include <soc.h>
19
20 /* Device constant configuration parameters */
21 struct spi_qmspi_config {
22 QMSPI_Type *regs;
23 uint32_t cs_timing;
24 uint8_t girq;
25 uint8_t girq_pos;
26 uint8_t girq_nvic_aggr;
27 uint8_t girq_nvic_direct;
28 uint8_t irq_pri;
29 uint8_t chip_sel;
30 uint8_t width; /* 1(single), 2(dual), 4(quad) */
31 uint8_t unused;
32 const struct pinctrl_dev_config *pcfg;
33 };
34
35 /* Device run time data */
36 struct spi_qmspi_data {
37 struct spi_context ctx;
38 };
39
descr_rd(QMSPI_Type * regs,uint32_t did)40 static inline uint32_t descr_rd(QMSPI_Type *regs, uint32_t did)
41 {
42 uintptr_t raddr = (uintptr_t)regs + MCHP_QMSPI_DESC0_OFS +
43 ((did & MCHP_QMSPI_C_NEXT_DESCR_MASK0) << 2);
44
45 return REG32(raddr);
46 }
47
descr_wr(QMSPI_Type * regs,uint32_t did,uint32_t val)48 static inline void descr_wr(QMSPI_Type *regs, uint32_t did, uint32_t val)
49 {
50 uintptr_t raddr = (uintptr_t)regs + MCHP_QMSPI_DESC0_OFS +
51 ((did & MCHP_QMSPI_C_NEXT_DESCR_MASK0) << 2);
52
53 REG32(raddr) = val;
54 }
55
txb_wr8(QMSPI_Type * regs,uint8_t data8)56 static inline void txb_wr8(QMSPI_Type *regs, uint8_t data8)
57 {
58 REG8(®s->TX_FIFO) = data8;
59 }
60
rxb_rd8(QMSPI_Type * regs)61 static inline uint8_t rxb_rd8(QMSPI_Type *regs)
62 {
63 return REG8(®s->RX_FIFO);
64 }
65
66 /*
67 * Program QMSPI frequency.
68 * MEC1501 base frequency is 48MHz. QMSPI frequency divider field in the
69 * mode register is defined as: 0=maximum divider of 256. Values 1 through
70 * 255 divide 48MHz by that value.
71 */
qmspi_set_frequency(QMSPI_Type * regs,uint32_t freq_hz)72 static void qmspi_set_frequency(QMSPI_Type *regs, uint32_t freq_hz)
73 {
74 uint32_t div, qmode;
75
76 if (freq_hz == 0) {
77 div = 0; /* max divider = 256 */
78 } else {
79 div = MCHP_QMSPI_INPUT_CLOCK_FREQ_HZ / freq_hz;
80 if (div == 0) {
81 div = 1; /* max freq. divider = 1 */
82 } else if (div > 0xffu) {
83 div = 0u; /* max divider = 256 */
84 }
85 }
86
87 qmode = regs->MODE & ~(MCHP_QMSPI_M_FDIV_MASK);
88 qmode |= (div << MCHP_QMSPI_M_FDIV_POS) & MCHP_QMSPI_M_FDIV_MASK;
89 regs->MODE = qmode;
90 }
91
92 /*
93 * SPI signalling mode: CPOL and CPHA
94 * CPOL = 0 is clock idles low, 1 is clock idle high
95 * CPHA = 0 Transmitter changes data on trailing of preceding clock cycle.
96 * Receiver samples data on leading edge of clock cycle.
97 * 1 Transmitter changes data on leading edge of current clock cycle.
98 * Receiver samples data on the trailing edge of clock cycle.
99 * SPI Mode nomenclature:
100 * Mode CPOL CPHA
101 * 0 0 0
102 * 1 0 1
103 * 2 1 0
104 * 3 1 1
105 * MEC1501 has three controls, CPOL, CPHA for output and CPHA for input.
106 * SPI frequency < 48MHz
107 * Mode 0: CPOL=0 CHPA=0 (CHPA_MISO=0 and CHPA_MOSI=0)
108 * Mode 3: CPOL=1 CHPA=1 (CHPA_MISO=1 and CHPA_MOSI=1)
109 * Data sheet recommends when QMSPI set at max. SPI frequency (48MHz).
110 * SPI frequency == 48MHz sample and change data on same edge.
111 * Mode 0: CPOL=0 CHPA=0 (CHPA_MISO=1 and CHPA_MOSI=0)
112 * Mode 3: CPOL=1 CHPA=1 (CHPA_MISO=0 and CHPA_MOSI=1)
113 */
114
115 const uint8_t smode_tbl[4] = {
116 0x00u, 0x06u, 0x01u, 0x07u
117 };
118
119 const uint8_t smode48_tbl[4] = {
120 0x04u, 0x02u, 0x05u, 0x03u
121 };
122
qmspi_set_signalling_mode(QMSPI_Type * regs,uint32_t smode)123 static void qmspi_set_signalling_mode(QMSPI_Type *regs, uint32_t smode)
124 {
125 const uint8_t *ptbl;
126 uint32_t m;
127
128 ptbl = smode_tbl;
129 if (((regs->MODE >> MCHP_QMSPI_M_FDIV_POS) &
130 MCHP_QMSPI_M_FDIV_MASK0) == 1) {
131 ptbl = smode48_tbl;
132 }
133
134 m = (uint32_t)ptbl[smode & 0x03];
135 regs->MODE = (regs->MODE & ~(MCHP_QMSPI_M_SIG_MASK))
136 | (m << MCHP_QMSPI_M_SIG_POS);
137 }
138
139 /*
140 * QMSPI HW support single, dual, and quad.
141 * Return QMSPI Control/Descriptor register encoded value.
142 */
qmspi_config_get_lines(const struct spi_config * config)143 static uint32_t qmspi_config_get_lines(const struct spi_config *config)
144 {
145 #ifdef CONFIG_SPI_EXTENDED_MODES
146 uint32_t qlines;
147
148 switch (config->operation & SPI_LINES_MASK) {
149 case SPI_LINES_SINGLE:
150 qlines = MCHP_QMSPI_C_IFM_1X;
151 break;
152 #if DT_INST_PROP(0, lines) > 1
153 case SPI_LINES_DUAL:
154 qlines = MCHP_QMSPI_C_IFM_2X;
155 break;
156 #endif
157 #if DT_INST_PROP(0, lines) > 2
158 case SPI_LINES_QUAD:
159 qlines = MCHP_QMSPI_C_IFM_4X;
160 break;
161 #endif
162 default:
163 qlines = 0xffu;
164 }
165
166 return qlines;
167 #else
168 return MCHP_QMSPI_C_IFM_1X;
169 #endif
170 }
171
172 /*
173 * Configure QMSPI.
174 * NOTE: QMSPI can control two chip selects. At this time we use CS0# only.
175 */
qmspi_configure(const struct device * dev,const struct spi_config * config)176 static int qmspi_configure(const struct device *dev,
177 const struct spi_config *config)
178 {
179 const struct spi_qmspi_config *cfg = dev->config;
180 struct spi_qmspi_data *data = dev->data;
181 QMSPI_Type *regs = cfg->regs;
182 uint32_t smode;
183
184 if (spi_context_configured(&data->ctx, config)) {
185 return 0;
186 }
187
188 if (config->operation & SPI_HALF_DUPLEX) {
189 return -ENOTSUP;
190 }
191
192 if (config->operation & (SPI_TRANSFER_LSB | SPI_OP_MODE_SLAVE
193 | SPI_MODE_LOOP)) {
194 return -ENOTSUP;
195 }
196
197 smode = qmspi_config_get_lines(config);
198 if (smode == 0xff) {
199 return -ENOTSUP;
200 }
201
202 regs->CTRL = smode;
203
204 /* Use the requested or next highest possible frequency */
205 qmspi_set_frequency(regs, config->frequency);
206
207 smode = 0;
208 if ((config->operation & SPI_MODE_CPHA) != 0U) {
209 smode |= (1ul << 0);
210 }
211
212 if ((config->operation & SPI_MODE_CPOL) != 0U) {
213 smode |= (1ul << 1);
214 }
215
216 qmspi_set_signalling_mode(regs, smode);
217
218 if (SPI_WORD_SIZE_GET(config->operation) != 8) {
219 return -ENOTSUP;
220 }
221
222 /* chip select */
223 smode = regs->MODE & ~(MCHP_QMSPI_M_CS_MASK);
224 #if DT_INST_PROP(0, chip_select) == 0
225 smode |= MCHP_QMSPI_M_CS0;
226 #else
227 smode |= MCHP_QMSPI_M_CS1;
228 #endif
229 regs->MODE = smode;
230
231 /* chip select timing */
232 regs->CSTM = cfg->cs_timing;
233
234 data->ctx.config = config;
235
236 regs->MODE |= MCHP_QMSPI_M_ACTIVATE;
237
238 return 0;
239 }
240
241 /*
242 * Transmit dummy clocks - QMSPI will generate requested number of
243 * SPI clocks with I/O pins tri-stated.
244 * Single mode: 1 bit per clock -> IFM field = 00b. Max 0x7fff clocks
245 * Dual mode: 2 bits per clock -> IFM field = 01b. Max 0x3fff clocks
246 * Quad mode: 4 bits per clock -> IFM field = 1xb. Max 0x1fff clocks
247 * QMSPI unit size set to bits.
248 */
qmspi_tx_dummy_clocks(QMSPI_Type * regs,uint32_t nclocks)249 static int qmspi_tx_dummy_clocks(QMSPI_Type *regs, uint32_t nclocks)
250 {
251 uint32_t descr, ifm, qstatus;
252
253 ifm = regs->CTRL & MCHP_QMSPI_C_IFM_MASK;
254 descr = ifm | MCHP_QMSPI_C_TX_DIS | MCHP_QMSPI_C_XFR_UNITS_BITS
255 | MCHP_QMSPI_C_DESCR_LAST | MCHP_QMSPI_C_DESCR0;
256
257 if (ifm & 0x01) {
258 nclocks <<= 1;
259 } else if (ifm & 0x02) {
260 nclocks <<= 2;
261 }
262 descr |= (nclocks << MCHP_QMSPI_C_XFR_NUNITS_POS);
263
264 descr_wr(regs, 0, descr);
265
266 regs->CTRL |= MCHP_QMSPI_C_DESCR_EN;
267 regs->IEN = 0;
268 regs->STS = 0xfffffffful;
269
270 regs->EXE = MCHP_QMSPI_EXE_START;
271 do {
272 qstatus = regs->STS;
273 if (qstatus & MCHP_QMSPI_STS_PROG_ERR) {
274 return -EIO;
275 }
276 } while ((qstatus & MCHP_QMSPI_STS_DONE) == 0);
277
278 return 0;
279 }
280
281 /*
282 * Return unit size power of 2 given number of bytes to transfer.
283 */
qlen_shift(uint32_t len)284 static uint32_t qlen_shift(uint32_t len)
285 {
286 uint32_t ushift;
287
288 /* is len a multiple of 4 or 16? */
289 if ((len & 0x0F) == 0) {
290 ushift = 4;
291 } else if ((len & 0x03) == 0) {
292 ushift = 2;
293 } else {
294 ushift = 0;
295 }
296
297 return ushift;
298 }
299
300 /*
301 * Return QMSPI unit size of the number of units field in QMSPI
302 * control/descriptor register.
303 * Input: power of 2 unit size 4, 2, or 0(default) corresponding
304 * to 16, 4, or 1 byte units.
305 */
get_qunits(uint32_t qshift)306 static uint32_t get_qunits(uint32_t qshift)
307 {
308 if (qshift == 4) {
309 return MCHP_QMSPI_C_XFR_UNITS_16;
310 } else if (qshift == 2) {
311 return MCHP_QMSPI_C_XFR_UNITS_4;
312 } else {
313 return MCHP_QMSPI_C_XFR_UNITS_1;
314 }
315 }
316
317 /*
318 * Allocate(build) one or more descriptors.
319 * QMSPI contains 16 32-bit descriptor registers used as a linked
320 * list of operations. Using only 32-bits there are limitations.
321 * Each descriptor is limited to 0x7FFF units where unit size can
322 * be 1, 4, or 16 bytes. A descriptor can perform transmit or receive
323 * but not both simultaneously. Order of descriptor processing is specified
324 * by the first descriptor field of the control register, the next descriptor
325 * fields in each descriptor, and the descriptors last flag.
326 */
qmspi_descr_alloc(QMSPI_Type * regs,const struct spi_buf * txb,int didx,bool is_tx)327 static int qmspi_descr_alloc(QMSPI_Type *regs, const struct spi_buf *txb,
328 int didx, bool is_tx)
329 {
330 uint32_t descr, qshift, n, nu;
331 int dn;
332
333 if (didx >= MCHP_QMSPI_MAX_DESCR) {
334 return -EAGAIN;
335 }
336
337 if (txb->len == 0) {
338 return didx; /* nothing to do */
339 }
340
341 /* b[1:0] IFM and b[3:2] transmit mode */
342 descr = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK);
343 if (is_tx) {
344 descr |= MCHP_QMSPI_C_TX_DATA;
345 } else {
346 descr |= MCHP_QMSPI_C_RX_EN;
347 }
348
349 /* b[11:10] unit size 1, 4, or 16 bytes */
350 qshift = qlen_shift(txb->len);
351 nu = txb->len >> qshift;
352 descr |= get_qunits(qshift);
353
354 do {
355 descr &= 0x0FFFul;
356
357 dn = didx + 1;
358 /* b[15:12] next descriptor pointer */
359 descr |= ((dn & MCHP_QMSPI_C_NEXT_DESCR_MASK0) <<
360 MCHP_QMSPI_C_NEXT_DESCR_POS);
361
362 n = nu;
363 if (n > MCHP_QMSPI_C_MAX_UNITS) {
364 n = MCHP_QMSPI_C_MAX_UNITS;
365 }
366
367 descr |= (n << MCHP_QMSPI_C_XFR_NUNITS_POS);
368 descr_wr(regs, didx, descr);
369
370 if (dn < MCHP_QMSPI_MAX_DESCR) {
371 didx++;
372 } else {
373 return -EAGAIN;
374 }
375
376 nu -= n;
377 } while (nu);
378
379 return dn;
380 }
381
qmspi_tx(QMSPI_Type * regs,const struct spi_buf * tx_buf,bool close)382 static int qmspi_tx(QMSPI_Type *regs, const struct spi_buf *tx_buf,
383 bool close)
384 {
385 const uint8_t *p = tx_buf->buf;
386 size_t tlen = tx_buf->len;
387 uint32_t descr;
388 int didx;
389
390 if (tlen == 0) {
391 return 0;
392 }
393
394 /* Buffer pointer is NULL and number of bytes != 0 ? */
395 if (p == NULL) {
396 return qmspi_tx_dummy_clocks(regs, tlen);
397 }
398
399 didx = qmspi_descr_alloc(regs, tx_buf, 0, true);
400 if (didx < 0) {
401 return didx;
402 }
403
404 /* didx points to last allocated descriptor + 1 */
405 __ASSERT(didx > 0, "QMSPI descriptor index=%d expected > 0\n", didx);
406 didx--;
407
408 descr = descr_rd(regs, didx) | MCHP_QMSPI_C_DESCR_LAST;
409 if (close) {
410 descr |= MCHP_QMSPI_C_CLOSE;
411 }
412 descr_wr(regs, didx, descr);
413
414 regs->CTRL = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK) |
415 MCHP_QMSPI_C_DESCR_EN | MCHP_QMSPI_C_DESCR0;
416 regs->IEN = 0;
417 regs->STS = 0xfffffffful;
418
419 /* preload TX_FIFO */
420 while (tlen) {
421 tlen--;
422 txb_wr8(regs, *p);
423 p++;
424
425 if (regs->STS & MCHP_QMSPI_STS_TXBF_RO) {
426 break;
427 }
428 }
429
430 regs->EXE = MCHP_QMSPI_EXE_START;
431
432 if (regs->STS & MCHP_QMSPI_STS_PROG_ERR) {
433 return -EIO;
434 }
435
436 while (tlen) {
437
438 while (regs->STS & MCHP_QMSPI_STS_TXBF_RO) {
439 }
440
441 txb_wr8(regs, *p);
442 p++;
443 tlen--;
444 }
445
446 /* Wait for TX FIFO to drain and last byte to be clocked out */
447 for (;;) {
448 if (regs->STS & MCHP_QMSPI_STS_DONE) {
449 break;
450 }
451 }
452
453 return 0;
454 }
455
qmspi_rx(QMSPI_Type * regs,const struct spi_buf * rx_buf,bool close)456 static int qmspi_rx(QMSPI_Type *regs, const struct spi_buf *rx_buf,
457 bool close)
458 {
459 uint8_t *p = rx_buf->buf;
460 size_t rlen = rx_buf->len;
461 uint32_t descr;
462 int didx;
463 uint8_t data_byte;
464
465 if (rlen == 0) {
466 return 0;
467 }
468
469 didx = qmspi_descr_alloc(regs, rx_buf, 0, false);
470 if (didx < 0) {
471 return didx;
472 }
473
474 /* didx points to last allocated descriptor + 1 */
475 __ASSERT_NO_MSG(didx > 0);
476 didx--;
477
478 descr = descr_rd(regs, didx) | MCHP_QMSPI_C_DESCR_LAST;
479 if (close) {
480 descr |= MCHP_QMSPI_C_CLOSE;
481 }
482 descr_wr(regs, didx, descr);
483
484 regs->CTRL = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK)
485 | MCHP_QMSPI_C_DESCR_EN | MCHP_QMSPI_C_DESCR0;
486 regs->IEN = 0;
487 regs->STS = 0xfffffffful;
488
489 /*
490 * Trigger read based on the descriptor(s) programmed above.
491 * QMSPI will generate clocks until the RX FIFO is filled.
492 * More clocks will be generated as we pull bytes from the RX FIFO.
493 * QMSPI Programming error will be triggered after start if
494 * descriptors were programmed options that cannot be enabled
495 * simultaneously.
496 */
497 regs->EXE = MCHP_QMSPI_EXE_START;
498 if (regs->STS & MCHP_QMSPI_STS_PROG_ERR) {
499 return -EIO;
500 }
501
502 while (rlen) {
503 if (!(regs->STS & MCHP_QMSPI_STS_RXBE_RO)) {
504 data_byte = rxb_rd8(regs);
505 if (p != NULL) {
506 *p++ = data_byte;
507 }
508 rlen--;
509 }
510 }
511
512 return 0;
513 }
514
qmspi_transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)515 static int qmspi_transceive(const struct device *dev,
516 const struct spi_config *config,
517 const struct spi_buf_set *tx_bufs,
518 const struct spi_buf_set *rx_bufs)
519 {
520 const struct spi_qmspi_config *cfg = dev->config;
521 struct spi_qmspi_data *data = dev->data;
522 QMSPI_Type *regs = cfg->regs;
523 const struct spi_buf *ptx;
524 const struct spi_buf *prx;
525 size_t nb;
526 uint32_t descr, last_didx;
527 int err;
528
529 spi_context_lock(&data->ctx, false, NULL, NULL, config);
530
531 err = qmspi_configure(dev, config);
532 if (err != 0) {
533 goto done;
534 }
535
536 spi_context_cs_control(&data->ctx, true);
537
538 if (tx_bufs != NULL) {
539 ptx = tx_bufs->buffers;
540 nb = tx_bufs->count;
541 while (nb--) {
542 err = qmspi_tx(regs, ptx, false);
543 if (err != 0) {
544 goto done;
545 }
546 ptx++;
547 }
548 }
549
550 if (rx_bufs != NULL) {
551 prx = rx_bufs->buffers;
552 nb = rx_bufs->count;
553 while (nb--) {
554 err = qmspi_rx(regs, prx, false);
555 if (err != 0) {
556 goto done;
557 }
558 prx++;
559 }
560 }
561
562 /*
563 * If caller doesn't need CS# held asserted then find the last
564 * descriptor, set its close flag, and set stop.
565 */
566 if (!(config->operation & SPI_HOLD_ON_CS)) {
567 /* Get last descriptor from status register */
568 last_didx = (regs->STS >> MCHP_QMSPI_C_NEXT_DESCR_POS)
569 & MCHP_QMSPI_C_NEXT_DESCR_MASK0;
570 descr = descr_rd(regs, last_didx) | MCHP_QMSPI_C_CLOSE;
571 descr_wr(regs, last_didx, descr);
572 regs->EXE = MCHP_QMSPI_EXE_STOP;
573 }
574
575 spi_context_cs_control(&data->ctx, false);
576
577 done:
578 spi_context_release(&data->ctx, err);
579 return err;
580 }
581
qmspi_transceive_sync(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)582 static int qmspi_transceive_sync(const struct device *dev,
583 const struct spi_config *config,
584 const struct spi_buf_set *tx_bufs,
585 const struct spi_buf_set *rx_bufs)
586 {
587 return qmspi_transceive(dev, config, tx_bufs, rx_bufs);
588 }
589
590 #ifdef CONFIG_SPI_ASYNC
qmspi_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,struct k_poll_signal * async)591 static int qmspi_transceive_async(const struct device *dev,
592 const struct spi_config *config,
593 const struct spi_buf_set *tx_bufs,
594 const struct spi_buf_set *rx_bufs,
595 struct k_poll_signal *async)
596 {
597 return -ENOTSUP;
598 }
599 #endif
600
qmspi_release(const struct device * dev,const struct spi_config * config)601 static int qmspi_release(const struct device *dev,
602 const struct spi_config *config)
603 {
604 struct spi_qmspi_data *data = dev->data;
605 const struct spi_qmspi_config *cfg = dev->config;
606 QMSPI_Type *regs = cfg->regs;
607
608 /* Force CS# to de-assert on next unit boundary */
609 regs->EXE = MCHP_QMSPI_EXE_STOP;
610
611 while (regs->STS & MCHP_QMSPI_STS_ACTIVE_RO) {
612 }
613
614 spi_context_unlock_unconditionally(&data->ctx);
615
616 return 0;
617 }
618
619 /*
620 * Initialize QMSPI controller.
621 * Disable sleep control.
622 * Disable and clear interrupt status.
623 * Initialize SPI context.
624 * QMSPI will be configured and enabled when the transceive API is called.
625 */
qmspi_init(const struct device * dev)626 static int qmspi_init(const struct device *dev)
627 {
628 int err;
629 const struct spi_qmspi_config *cfg = dev->config;
630 struct spi_qmspi_data *data = dev->data;
631 QMSPI_Type *regs = cfg->regs;
632 int ret;
633
634 ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
635 if (ret != 0) {
636 LOG_ERR("QSPI pinctrl setup failed (%d)", ret);
637 return ret;
638 }
639
640 mchp_pcr_periph_slp_ctrl(PCR_QMSPI, MCHP_PCR_SLEEP_DIS);
641
642 regs->MODE = MCHP_QMSPI_M_SRST;
643
644 MCHP_GIRQ_CLR_EN(cfg->girq, cfg->girq_pos);
645 MCHP_GIRQ_SRC_CLR(cfg->girq, cfg->girq_pos);
646
647 MCHP_GIRQ_BLK_CLREN(cfg->girq);
648 NVIC_ClearPendingIRQ(cfg->girq_nvic_direct);
649
650 err = spi_context_cs_configure_all(&data->ctx);
651 if (err < 0) {
652 return err;
653 }
654
655 spi_context_unlock_unconditionally(&data->ctx);
656
657 return 0;
658 }
659
660 static DEVICE_API(spi, spi_qmspi_driver_api) = {
661 .transceive = qmspi_transceive_sync,
662 #ifdef CONFIG_SPI_ASYNC
663 .transceive_async = qmspi_transceive_async,
664 #endif
665 #ifdef CONFIG_SPI_RTIO
666 .iodev_submit = spi_rtio_iodev_default_submit,
667 #endif
668 .release = qmspi_release,
669 };
670
671
672 #define XEC_QMSPI_CS_TIMING_VAL(a, b, c, d) (((a) & 0xFu) \
673 | (((b) & 0xFu) << 8) \
674 | (((c) & 0xFu) << 16) \
675 | (((d) & 0xFu) << 24))
676
677
678 #define XEC_QMSPI_0_CS_TIMING XEC_QMSPI_CS_TIMING_VAL( \
679 DT_INST_PROP(0, dcsckon), \
680 DT_INST_PROP(0, dckcsoff), \
681 DT_INST_PROP(0, dldh), \
682 DT_INST_PROP(0, dcsda))
683
684 #if DT_NODE_HAS_STATUS_OKAY(DT_INST(0, microchip_xec_qmspi))
685
686 PINCTRL_DT_INST_DEFINE(0);
687
688 static const struct spi_qmspi_config spi_qmspi_0_config = {
689 .regs = (QMSPI_Type *)DT_INST_REG_ADDR(0),
690 .cs_timing = XEC_QMSPI_0_CS_TIMING,
691 .girq = MCHP_QMSPI_GIRQ_NUM,
692 .girq_pos = MCHP_QMSPI_GIRQ_POS,
693 .girq_nvic_direct = MCHP_QMSPI_GIRQ_NVIC_DIRECT,
694 .irq_pri = DT_INST_IRQ(0, priority),
695 .chip_sel = DT_INST_PROP(0, chip_select),
696 .width = DT_INST_PROP(0, lines),
697 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
698 };
699
700 static struct spi_qmspi_data spi_qmspi_0_dev_data = {
701 SPI_CONTEXT_INIT_LOCK(spi_qmspi_0_dev_data, ctx),
702 SPI_CONTEXT_INIT_SYNC(spi_qmspi_0_dev_data, ctx),
703 SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(0), ctx)
704 };
705
706 SPI_DEVICE_DT_INST_DEFINE(0,
707 qmspi_init, NULL, &spi_qmspi_0_dev_data,
708 &spi_qmspi_0_config, POST_KERNEL,
709 CONFIG_SPI_INIT_PRIORITY, &spi_qmspi_driver_api);
710
711 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_INST(0, microchip_xec_qmspi)) */
712