1 /*
2 * Copyright 2018, 2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(spi_mcux_lpspi_common, CONFIG_SPI_LOG_LEVEL);
9
10 #include "spi_nxp_lpspi_priv.h"
11
lpspi_wait_tx_fifo_empty(const struct device * dev)12 void lpspi_wait_tx_fifo_empty(const struct device *dev)
13 {
14 LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base);
15
16 while (LPSPI_GetTxFifoCount(base) != 0) {
17 }
18 }
19
spi_mcux_release(const struct device * dev,const struct spi_config * spi_cfg)20 int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg)
21 {
22 struct spi_mcux_data *data = dev->data;
23
24 spi_context_unlock_unconditionally(&data->ctx);
25
26 return 0;
27 }
28
spi_mcux_configure(const struct device * dev,const struct spi_config * spi_cfg)29 int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg)
30 {
31 const struct spi_mcux_config *config = dev->config;
32 struct spi_mcux_data *data = dev->data;
33 struct spi_context *ctx = &data->ctx;
34 LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base);
35 uint32_t word_size = SPI_WORD_SIZE_GET(spi_cfg->operation);
36 bool configured = ctx->config != NULL;
37 lpspi_master_config_t master_config;
38 uint32_t clock_freq;
39 int ret;
40
41 /* fast path to avoid reconfigure */
42 /* TODO: S32K3 errata ERR050456 requiring module reset before every transfer,
43 * investigate alternative workaround so we don't have this latency for S32.
44 */
45 if (spi_context_configured(ctx, spi_cfg) && !IS_ENABLED(CONFIG_SOC_FAMILY_NXP_S32)) {
46 return 0;
47 }
48
49 if (spi_cfg->operation & SPI_HALF_DUPLEX) {
50 /* the IP DOES support half duplex, need to implement driver support */
51 LOG_ERR("Half-duplex not supported");
52 return -ENOTSUP;
53 }
54
55 if (word_size < 8 || (word_size % 32 == 1)) {
56 /* Zephyr word size == hardware FRAME size (not word size)
57 * Max frame size: 4096 bits
58 * (zephyr field is 6 bit wide for max 64 bit size, no need to check)
59 * Min frame size: 8 bits.
60 * Minimum hardware word size is 2. Since this driver is intended to work
61 * for 32 bit platforms, and 64 bits is max size, then only 33 and 1 are invalid.
62 */
63 LOG_ERR("Word size %d not allowed", word_size);
64 return -EINVAL;
65 }
66
67 if (spi_cfg->slave > (LPSPI_CHIP_SELECT_COUNT - 1)) {
68 LOG_ERR("Peripheral %d select exceeds max %d", spi_cfg->slave,
69 LPSPI_CHIP_SELECT_COUNT - 1);
70 return -EINVAL;
71 }
72
73 ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq);
74 if (ret) {
75 return ret;
76 }
77
78 if (configured) {
79 /* Setting the baud rate in LPSPI_MasterInit requires module to be disabled. Only
80 * disable if already configured, otherwise the clock is not enabled and the
81 * CR register cannot be written.
82 */
83 LPSPI_Enable(base, false);
84 while ((base->CR & LPSPI_CR_MEN_MASK) != 0U) {
85 /* Wait until LPSPI is disabled. Datasheet:
86 * After writing 0, MEN (Module Enable) remains set until the LPSPI has
87 * completed the current transfer and is idle.
88 */
89 }
90
91 /* this is workaround for ERR050456 */
92 base->CR |= LPSPI_CR_RST_MASK;
93 base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
94 base->CR = 0x00U;
95 }
96
97 data->ctx.config = spi_cfg;
98
99 LPSPI_MasterGetDefaultConfig(&master_config);
100
101 master_config.bitsPerFrame = word_size;
102 master_config.cpol = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL)
103 ? kLPSPI_ClockPolarityActiveLow
104 : kLPSPI_ClockPolarityActiveHigh;
105 master_config.cpha = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA)
106 ? kLPSPI_ClockPhaseSecondEdge
107 : kLPSPI_ClockPhaseFirstEdge;
108 master_config.direction =
109 (spi_cfg->operation & SPI_TRANSFER_LSB) ? kLPSPI_LsbFirst : kLPSPI_MsbFirst;
110 master_config.baudRate = spi_cfg->frequency;
111 master_config.pcsToSckDelayInNanoSec = config->pcs_sck_delay;
112 master_config.lastSckToPcsDelayInNanoSec = config->sck_pcs_delay;
113 master_config.betweenTransferDelayInNanoSec = config->transfer_delay;
114 master_config.whichPcs = spi_cfg->slave + kLPSPI_Pcs0;
115 master_config.pcsActiveHighOrLow = (spi_cfg->operation & SPI_CS_ACTIVE_HIGH)
116 ? kLPSPI_PcsActiveHigh : kLPSPI_PcsActiveLow;
117 master_config.pinCfg = config->data_pin_config;
118 master_config.dataOutConfig = config->output_config ? kLpspiDataOutTristate :
119 kLpspiDataOutRetained;
120
121 LPSPI_MasterInit(base, &master_config, clock_freq);
122 LPSPI_SetDummyData(base, 0);
123
124 if (IS_ENABLED(CONFIG_DEBUG)) {
125 base->CR |= LPSPI_CR_DBGEN_MASK;
126 }
127
128 return 0;
129 }
130
spi_nxp_init_common(const struct device * dev)131 int spi_nxp_init_common(const struct device *dev)
132 {
133 const struct spi_mcux_config *config = dev->config;
134 struct spi_mcux_data *data = dev->data;
135 int err = 0;
136
137 DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
138
139 data->dev = dev;
140
141 if (!device_is_ready(config->clock_dev)) {
142 LOG_ERR("clock control device not ready");
143 return -ENODEV;
144 }
145
146 err = spi_context_cs_configure_all(&data->ctx);
147 if (err < 0) {
148 return err;
149 }
150
151 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
152 if (err) {
153 return err;
154 }
155
156 config->irq_config_func(dev);
157
158 return err;
159 }
160