Skip to content

Commit 69f4e4e

Browse files
driver: spi: update SPI TLX driver
Updated SPI TLX driver Signed-off-by: Serhii Salamakha <serhii.salamakha@gmail.com>
1 parent 29d8489 commit 69f4e4e

1 file changed

Lines changed: 49 additions & 8 deletions

File tree

drivers/spi/spi_tlx.c

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ LOG_MODULE_REGISTER(spi_telink);
3333
#define CHIP_SELECT_COUNT 3u
3434
#define SPI_WORD_SIZE 8u
3535
#define SPI_WR_RD_CHUNK_SIZE_MAX 16u
36+
#define SPI_ERROR_TIMEOUT 1000000u
3637

3738
/* SPI configuration structure */
3839
struct spi_tlx_cfg {
@@ -204,7 +205,7 @@ _attribute_ram_code_sec_ static void spi_tlx_rx(uint8_t peripheral_id, struct sp
204205
}
205206

206207
/* SPI transceive internal */
207-
_attribute_ram_code_sec_ static void spi_tlx_txrx(const struct device *dev, uint32_t len)
208+
_attribute_ram_code_sec_ static void spi_tlx_txrx_multibufs(const struct device *dev, uint32_t len)
208209
{
209210
unsigned int chunk_size = SPI_WR_RD_CHUNK_SIZE_MAX;
210211
struct spi_tlx_cfg *cfg = SPI_CFG(dev);
@@ -248,13 +249,50 @@ _attribute_ram_code_sec_ static void spi_tlx_txrx(const struct device *dev, uint
248249
BM_SET(reg_spi_status(cfg->peripheral_id), FLD_SPI_RXF_CLR_LEVEL);
249250
#endif
250251
}
252+
}
253+
254+
static bool spi_tlx_is_simple_buf(size_t count, const uint8_t *buf, size_t len, uint32_t total_len)
255+
{
256+
return (count == 1) && (buf != NULL) && (len == total_len);
257+
}
258+
259+
/* SPI transceive internal */
260+
_attribute_ram_code_sec_ static void spi_tlx_txrx(const struct device *dev, uint32_t len)
261+
{
262+
int err = 0;
263+
struct spi_tlx_cfg *cfg = SPI_CFG(dev);
264+
struct spi_context *ctx = &SPI_DATA(dev)->ctx;
265+
266+
bool simple_tx = spi_tlx_is_simple_buf(ctx->tx_count, ctx->tx_buf, ctx->tx_len, len);
267+
bool simple_rx = spi_tlx_is_simple_buf(ctx->rx_count, ctx->rx_buf, ctx->rx_len, len);
268+
269+
if (simple_tx && simple_rx) {
270+
/* fast path: full duplex, vendor-proven chunking + offset compensation */
271+
spi_master_write_read_full_duplex(cfg->peripheral_id,
272+
(uint8_t *)ctx->tx_buf, ctx->rx_buf, len);
273+
spi_context_update_tx(ctx, 1, len);
274+
spi_context_update_rx(ctx, 1, len);
275+
} else if (simple_tx && !spi_context_rx_on(ctx)) {
276+
/* fast path: write only */
277+
spi_master_write(cfg->peripheral_id, (uint8_t *)ctx->tx_buf, len);
278+
spi_context_update_tx(ctx, 1, len);
279+
} else if (simple_rx && !spi_context_tx_on(ctx)) {
280+
/* fast path: read only */
281+
spi_master_read(cfg->peripheral_id, ctx->rx_buf, len);
282+
spi_context_update_rx(ctx, 1, len);
283+
} else {
284+
/* fallback: scatter-gather / dummy-fill / discard case */
285+
spi_tlx_txrx_multibufs(dev, len);
286+
}
251287

252-
/* wait fot SPI is ready */
253-
while (spi_is_busy(cfg->peripheral_id)) {
254-
};
288+
if (!WAIT_FOR(!spi_is_busy(cfg->peripheral_id), SPI_ERROR_TIMEOUT, NULL)) {
289+
LOG_ERR("SPI is busy timeout");
290+
spi_hw_fsm_reset(cfg->peripheral_id);
291+
err = -ETIMEDOUT;
292+
}
255293

256294
/* context complete */
257-
spi_context_complete(ctx, dev, 0);
295+
spi_context_complete(ctx, dev, err);
258296
}
259297

260298
/* Check for supported configuration */
@@ -301,7 +339,7 @@ static bool spi_tlx_is_config_supported(const struct spi_config *config,
301339
/* check for slave configuration */
302340
if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) {
303341
LOG_ERR("SPI Slave is not implemented");
304-
return -ENOTSUP;
342+
return false;
305343
}
306344

307345
return true;
@@ -398,6 +436,8 @@ static int spi_tlx_init(const struct device *dev)
398436

399437
spi_context_unlock_unconditionally(&data->ctx);
400438

439+
spi_set_error_timeout(SPI_ERROR_TIMEOUT);
440+
401441
return 0;
402442
}
403443

@@ -409,14 +449,15 @@ static int spi_tlx_transceive(const struct device *dev, const struct spi_config
409449
struct spi_tlx_data *data = SPI_DATA(dev);
410450
uint32_t txrx_len = spi_tlx_get_txrx_len(tx_bufs, rx_bufs);
411451

452+
/* context setup */
453+
spi_context_lock(&data->ctx, false, NULL, NULL, config);
454+
412455
/* set configuration */
413456
status = spi_tlx_config(dev, config);
414457
if (status) {
415458
return status;
416459
}
417460

418-
/* context setup */
419-
spi_context_lock(&data->ctx, false, NULL, NULL, config);
420461
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1);
421462

422463
/* if cs is defined: software cs control, set active true */

0 commit comments

Comments
 (0)