Lines Matching +full:max +full:- +full:xfer +full:- +full:size

6  * SPDX-License-Identifier: Apache-2.0
11 /* spi_dw.c - Designware SPI driver implementation */
47 spi_context_is_slave(&spi->ctx)); in spi_dw_is_slave()
52 struct spi_dw_data *spi = dev->data; in completed()
53 struct spi_context *ctx = &spi->ctx; in completed()
59 if (spi_context_tx_on(&spi->ctx) || in completed()
60 spi_context_rx_on(&spi->ctx)) { in completed()
75 if (spi_cs_is_gpio(ctx->config)) { in completed()
85 spi_context_complete(&spi->ctx, dev, error); in completed()
90 const struct spi_dw_config *info = dev->config; in push_data()
91 struct spi_dw_data *spi = dev->data; in push_data()
95 if (spi_context_rx_on(&spi->ctx)) { in push_data()
96 f_tx = info->fifo_depth - read_txflr(dev) - in push_data()
99 f_tx = 0U; /* if rx-fifo is full, hold off tx */ in push_data()
102 f_tx = info->fifo_depth - read_txflr(dev); in push_data()
106 if (spi_context_tx_buf_on(&spi->ctx)) { in push_data()
107 switch (spi->dfs) { in push_data()
110 (spi->ctx.tx_buf)); in push_data()
114 (spi->ctx.tx_buf)); in push_data()
118 (spi->ctx.tx_buf)); in push_data()
121 } else if (spi_context_rx_on(&spi->ctx)) { in push_data()
123 if ((int)(spi->ctx.rx_len - spi->fifo_diff) <= 0) { in push_data()
128 } else if (spi_context_tx_on(&spi->ctx)) { in push_data()
137 spi_context_update_tx(&spi->ctx, spi->dfs, 1); in push_data()
138 spi->fifo_diff++; in push_data()
140 f_tx--; in push_data()
143 if (!spi_context_tx_on(&spi->ctx)) { in push_data()
151 const struct spi_dw_config *info = dev->config; in pull_data()
152 struct spi_dw_data *spi = dev->data; in pull_data()
157 if (spi_context_rx_buf_on(&spi->ctx)) { in pull_data()
158 switch (spi->dfs) { in pull_data()
160 UNALIGNED_PUT(data, (uint8_t *)spi->ctx.rx_buf); in pull_data()
163 UNALIGNED_PUT(data, (uint16_t *)spi->ctx.rx_buf); in pull_data()
166 UNALIGNED_PUT(data, (uint32_t *)spi->ctx.rx_buf); in pull_data()
171 spi_context_update_rx(&spi->ctx, spi->dfs, 1); in pull_data()
172 spi->fifo_diff--; in pull_data()
175 if (!spi->ctx.rx_len && spi->ctx.tx_len < info->fifo_depth) { in pull_data()
176 write_rxftlr(dev, spi->ctx.tx_len - 1); in pull_data()
177 } else if (read_rxftlr(dev) >= spi->ctx.rx_len) { in pull_data()
178 write_rxftlr(dev, spi->ctx.rx_len - 1); in pull_data()
186 const struct spi_dw_config *info = dev->config; in spi_dw_configure()
189 LOG_DBG("%p (prev %p)", config, spi->ctx.config); in spi_dw_configure()
191 if (spi_context_configured(&spi->ctx, config)) { in spi_dw_configure()
196 if (config->operation & SPI_HALF_DUPLEX) { in spi_dw_configure()
197 LOG_ERR("Half-duplex not supported"); in spi_dw_configure()
198 return -ENOTSUP; in spi_dw_configure()
202 if (config->operation & SPI_OP_MODE_SLAVE) { in spi_dw_configure()
203 if (!(info->serial_target)) { in spi_dw_configure()
205 return -ENOTSUP; in spi_dw_configure()
208 if (info->serial_target) { in spi_dw_configure()
210 return -ENOTSUP; in spi_dw_configure()
214 if ((config->operation & SPI_TRANSFER_LSB) || in spi_dw_configure()
216 (config->operation & (SPI_LINES_DUAL | in spi_dw_configure()
219 return -EINVAL; in spi_dw_configure()
222 if (info->max_xfer_size < SPI_WORD_SIZE_GET(config->operation)) { in spi_dw_configure()
223 LOG_ERR("Max xfer size is %u, word size of %u not allowed", in spi_dw_configure()
224 info->max_xfer_size, SPI_WORD_SIZE_GET(config->operation)); in spi_dw_configure()
225 return -ENOTSUP; in spi_dw_configure()
228 /* Word size */ in spi_dw_configure()
229 if (info->max_xfer_size == 32) { in spi_dw_configure()
230 ctrlr0 |= DW_SPI_CTRLR0_DFS_32(SPI_WORD_SIZE_GET(config->operation)); in spi_dw_configure()
232 ctrlr0 |= DW_SPI_CTRLR0_DFS_16(SPI_WORD_SIZE_GET(config->operation)); in spi_dw_configure()
235 /* Determine how many bytes are required per-frame */ in spi_dw_configure()
236 spi->dfs = SPI_WS_TO_DFS(SPI_WORD_SIZE_GET(config->operation)); in spi_dw_configure()
239 if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) { in spi_dw_configure()
243 if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) { in spi_dw_configure()
247 if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) { in spi_dw_configure()
255 spi->ctx.config = config; in spi_dw_configure()
259 write_baudr(dev, SPI_DW_CLK_DIVIDER(info->clock_frequency, in spi_dw_configure()
260 config->frequency)); in spi_dw_configure()
267 SPI_WORD_SIZE_GET(config->operation), spi->dfs, in spi_dw_configure()
268 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
270 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
272 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
277 config, config->frequency, in spi_dw_configure()
278 SPI_DW_CLK_DIVIDER(info->clock_frequency, in spi_dw_configure()
279 config->frequency), in spi_dw_configure()
280 SPI_WORD_SIZE_GET(config->operation), spi->dfs, in spi_dw_configure()
281 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
283 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
285 (SPI_MODE_GET(config->operation) & in spi_dw_configure()
287 config->slave); in spi_dw_configure()
298 for (; rx_count; rx_bufs++, rx_count--) { in spi_dw_compute_ndf()
299 if (len > (UINT16_MAX - rx_bufs->len)) { in spi_dw_compute_ndf()
303 len += rx_bufs->len; in spi_dw_compute_ndf()
307 return (len / dfs) - 1; in spi_dw_compute_ndf()
316 const struct spi_dw_config *info = dev->config; in spi_dw_update_txftlr()
317 uint32_t dw_spi_txftlr_dflt = (info->fifo_depth * 1) / 2; in spi_dw_update_txftlr()
321 if (!spi->ctx.tx_len) { in spi_dw_update_txftlr()
323 } else if (spi->ctx.tx_len < dw_spi_txftlr_dflt) { in spi_dw_update_txftlr()
324 reg_data = spi->ctx.tx_len - 1; in spi_dw_update_txftlr()
341 const struct spi_dw_config *info = dev->config; in transceive()
342 struct spi_dw_data *spi = dev->data; in transceive()
344 uint32_t dw_spi_rxftlr_dflt = (info->fifo_depth * 5) / 8; in transceive()
348 spi_context_lock(&spi->ctx, asynchronous, cb, userdata, config); in transceive()
362 if (!rx_bufs || !rx_bufs->buffers) { in transceive()
364 } else if (!tx_bufs || !tx_bufs->buffers) { in transceive()
372 reg_data = spi_dw_compute_ndf(rx_bufs->buffers, in transceive()
373 rx_bufs->count, in transceive()
374 spi->dfs); in transceive()
376 ret = -EINVAL; in transceive()
402 spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, spi->dfs); in transceive()
404 spi->fifo_diff = 0U; in transceive()
413 if (spi->ctx.rx_len && in transceive()
414 spi->ctx.rx_len < dw_spi_rxftlr_dflt) { in transceive()
415 reg_data = spi->ctx.rx_len - 1; in transceive()
418 if (spi->ctx.rx_len && spi->ctx.rx_len < info->fifo_depth) { in transceive()
419 reg_data = spi->ctx.rx_len - 1; in transceive()
435 spi_context_cs_control(&spi->ctx, true); in transceive()
437 write_ser(dev, BIT(config->slave)); in transceive()
444 ret = spi_context_wait_for_completion(&spi->ctx); in transceive()
447 if (spi_context_is_slave(&spi->ctx) && !ret) { in transceive()
448 ret = spi->ctx.recv_frames; in transceive()
453 spi_context_release(&spi->ctx, ret); in transceive()
487 struct spi_dw_data *spi = dev->data; in spi_dw_release()
489 if (!spi_context_configured(&spi->ctx, config)) { in spi_dw_release()
490 return -EINVAL; in spi_dw_release()
493 spi_context_unlock_unconditionally(&spi->ctx); in spi_dw_release()
505 LOG_DBG("SPI %p int_status 0x%x - (tx: %d, rx: %d)", dev, int_status, in spi_dw_isr()
509 error = -EIO; in spi_dw_isr()
542 const struct spi_dw_config *info = dev->config; in spi_dw_init()
543 struct spi_dw_data *spi = dev->data; in spi_dw_init()
546 pinctrl_apply_state(info->pcfg, PINCTRL_STATE_DEFAULT); in spi_dw_init()
551 info->config_func(); in spi_dw_init()
559 err = spi_context_cs_configure_all(&spi->ctx); in spi_dw_init()
564 spi_context_unlock_unconditionally(&spi->ctx); in spi_dw_init()