Lines Matching +full:spi +full:- +full:clock +full:- +full:mode +full:- +full:cpha
4 * SPDX-License-Identifier: Apache-2.0
9 #include <zephyr/drivers/spi.h>
10 #include <zephyr/drivers/spi/rtio.h>
46 const struct spi_npcx_spip_cfg *const config = dev->config; in spi_npcx_spip_configure()
47 struct spi_npcx_spip_data *const data = dev->data; in spi_npcx_spip_configure()
48 struct spip_reg *const reg_base = config->reg_base; in spi_npcx_spip_configure()
49 spi_operation_t operation = spi_cfg->operation; in spi_npcx_spip_configure()
52 if (spi_context_configured(&data->ctx, spi_cfg)) { in spi_npcx_spip_configure()
58 LOG_ERR("Half duplex mode is not supported"); in spi_npcx_spip_configure()
59 return -ENOTSUP; in spi_npcx_spip_configure()
63 LOG_ERR("Only SPI controller mode is supported"); in spi_npcx_spip_configure()
64 return -ENOTSUP; in spi_npcx_spip_configure()
68 LOG_ERR("Loopback mode is not supported"); in spi_npcx_spip_configure()
69 return -ENOTSUP; in spi_npcx_spip_configure()
78 return -ENOTSUP; in spi_npcx_spip_configure()
84 data->bytes_per_frame = 1; in spi_npcx_spip_configure()
85 reg_base->SPIP_CTL1 &= ~BIT(NPCX_SPIP_CTL1_MOD); in spi_npcx_spip_configure()
87 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_MOD); in spi_npcx_spip_configure()
88 data->bytes_per_frame = 2; in spi_npcx_spip_configure()
91 return -ENOTSUP; in spi_npcx_spip_configure()
96 LOG_ERR("Only single line mode is supported"); in spi_npcx_spip_configure()
97 return -ENOTSUP; in spi_npcx_spip_configure()
103 return -ENOTSUP; in spi_npcx_spip_configure()
107 * Set CPOL and CPHA. in spi_npcx_spip_configure()
108 * The following is how to map npcx spip control register to CPOL and CPHA in spi_npcx_spip_configure()
109 * CPOL CPHA | SCIDL SCM in spi_npcx_spip_configure()
110 * ----------------------------- in spi_npcx_spip_configure()
117 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_SCIDL); in spi_npcx_spip_configure()
119 reg_base->SPIP_CTL1 &= ~BIT(NPCX_SPIP_CTL1_SCIDL); in spi_npcx_spip_configure()
123 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_SCM); in spi_npcx_spip_configure()
125 reg_base->SPIP_CTL1 &= ~BIT(NPCX_SPIP_CTL1_SCM); in spi_npcx_spip_configure()
128 /* Set the SPI frequency */ in spi_npcx_spip_configure()
129 prescaler_divider = data->src_clock_freq / 2 / spi_cfg->frequency; in spi_npcx_spip_configure()
131 prescaler_divider -= 1; in spi_npcx_spip_configure()
134 LOG_ERR("SPI divider %d exceeds the max allowed value %d.", prescaler_divider, in spi_npcx_spip_configure()
136 return -ENOTSUP; in spi_npcx_spip_configure()
138 SET_FIELD(reg_base->SPIP_CTL1, NPCX_SPIP_CTL1_SCDV, prescaler_divider); in spi_npcx_spip_configure()
140 data->ctx.config = spi_cfg; in spi_npcx_spip_configure()
148 if (spi_context_tx_buf_on(&data->ctx)) { in spi_npcx_spip_process_tx_buf()
149 if (data->bytes_per_frame == 1) { in spi_npcx_spip_process_tx_buf()
150 *tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); in spi_npcx_spip_process_tx_buf()
152 *tx_frame = UNALIGNED_GET((uint16_t *)(data->ctx.tx_buf)); in spi_npcx_spip_process_tx_buf()
159 spi_context_update_tx(&data->ctx, data->bytes_per_frame, 1); in spi_npcx_spip_process_tx_buf()
164 if (spi_context_rx_buf_on(&data->ctx)) { in spi_npcx_spip_process_rx_buf()
165 if (data->bytes_per_frame == 1) { in spi_npcx_spip_process_rx_buf()
166 UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); in spi_npcx_spip_process_rx_buf()
168 UNALIGNED_PUT(rx_frame, (uint16_t *)data->ctx.rx_buf); in spi_npcx_spip_process_rx_buf()
171 spi_context_update_rx(&data->ctx, data->bytes_per_frame, 1); in spi_npcx_spip_process_rx_buf()
177 const struct spi_npcx_spip_cfg *const config = dev->config; in spi_npcx_spip_xfer_frame()
178 struct spip_reg *const reg_base = config->reg_base; in spi_npcx_spip_xfer_frame()
179 struct spi_npcx_spip_data *const data = dev->data; in spi_npcx_spip_xfer_frame()
185 if (WAIT_FOR(!IS_BIT_SET(reg_base->SPIP_STAT, NPCX_SPIP_STAT_BSY), in spi_npcx_spip_xfer_frame()
188 return -ETIMEDOUT; in spi_npcx_spip_xfer_frame()
191 reg_base->SPIP_DATA = tx_frame; in spi_npcx_spip_xfer_frame()
193 if (WAIT_FOR(IS_BIT_SET(reg_base->SPIP_STAT, NPCX_SPIP_STAT_RBF), in spi_npcx_spip_xfer_frame()
196 return -ETIMEDOUT; in spi_npcx_spip_xfer_frame()
199 rx_frame = reg_base->SPIP_DATA; in spi_npcx_spip_xfer_frame()
208 return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); in spi_npcx_spip_transfer_ongoing()
214 const struct spi_npcx_spip_cfg *const config = dev->config; in spi_npcx_spip_isr()
215 struct spip_reg *const reg_base = config->reg_base; in spi_npcx_spip_isr()
216 struct spi_npcx_spip_data *const data = dev->data; in spi_npcx_spip_isr()
217 struct spi_context *ctx = &data->ctx; in spi_npcx_spip_isr()
222 status = reg_base->SPIP_STAT; in spi_npcx_spip_isr()
225 reg_base->SPIP_CTL1 &= ~BIT(NPCX_SPIP_CTL1_EIW); in spi_npcx_spip_isr()
228 reg_base->SPIP_DATA = tx_frame; in spi_npcx_spip_isr()
230 rx_frame = reg_base->SPIP_DATA; in spi_npcx_spip_isr()
235 reg_base->SPIP_CTL1 &= ~BIT(NPCX_SPIP_CTL1_EIR); in spi_npcx_spip_isr()
237 * The CS might not de-assert if SPI_HOLD_ON_CS is configured. in spi_npcx_spip_isr()
238 * In this case, CS de-assertion reles on the caller to explicitly call in spi_npcx_spip_isr()
247 reg_base->SPIP_DATA = tx_frame; in spi_npcx_spip_isr()
257 const struct spi_npcx_spip_cfg *const config = dev->config; in transceive()
258 struct spip_reg *const reg_base = config->reg_base; in transceive()
259 struct spi_npcx_spip_data *const data = dev->data; in transceive()
260 struct spi_context *ctx = &data->ctx; in transceive()
269 return -ENOTSUP; in transceive()
273 /* Lock the SPI Context */ in transceive()
282 spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, data->bytes_per_frame); in transceive()
289 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_SPIEN); in transceive()
292 while (IS_BIT_SET(reg_base->SPIP_STAT, NPCX_SPIP_STAT_RBF)) { in transceive()
295 unused = reg_base->SPIP_DATA; in transceive()
302 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_EIR) | BIT(NPCX_SPIP_CTL1_EIW); in transceive()
303 rc = spi_context_wait_for_completion(&data->ctx); in transceive()
313 * The CS might not de-assert if SPI_HOLD_ON_CS is configured. in transceive()
314 * In this case, CS de-assertion reles on the caller to explicitly call spi_release() API. in transceive()
344 struct spi_npcx_spip_data *const data = dev->data; in spi_npcx_spip_release()
345 struct spi_context *ctx = &data->ctx; in spi_npcx_spip_release()
348 return -EINVAL; in spi_npcx_spip_release()
359 struct spi_npcx_spip_data *const data = dev->data; in spi_npcx_spip_init()
360 const struct spi_npcx_spip_cfg *const config = dev->config; in spi_npcx_spip_init()
361 struct spip_reg *const reg_base = config->reg_base; in spi_npcx_spip_init()
365 LOG_ERR("clock control device not ready"); in spi_npcx_spip_init()
366 return -ENODEV; in spi_npcx_spip_init()
369 ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->clk_cfg); in spi_npcx_spip_init()
371 LOG_ERR("Turn on SPIP clock fail %d", ret); in spi_npcx_spip_init()
375 ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)&config->clk_cfg, in spi_npcx_spip_init()
376 &data->src_clock_freq); in spi_npcx_spip_init()
378 LOG_ERR("Get SPIP clock source rate error %d", ret); in spi_npcx_spip_init()
382 ret = spi_context_cs_configure_all(&data->ctx); in spi_npcx_spip_init()
387 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in spi_npcx_spip_init()
393 spi_context_unlock_unconditionally(&data->ctx); in spi_npcx_spip_init()
396 config->irq_cfg_func(dev); in spi_npcx_spip_init()
400 reg_base->SPIP_CTL1 |= BIT(NPCX_SPIP_CTL1_SPIEN); in spi_npcx_spip_init()
405 static DEVICE_API(spi, spi_npcx_spip_api) = {