Skip to content

Commit 7ae4d09

Browse files
Marek Vasutbroonie
authored andcommitted
spi: spi-fsl-lpspi: Handle clock polarity and phase
The LPSPI driver currently does not support setting SPI bus clock polarity and phase, add support for it. It is important to configure correct initial clock polarity and phase before the GPIO chipselect toggles, otherwise a chip attached to the bus might recognize the first change of clock signal as the first clock cycle and get confused. In order to set up the correct polarity and phase on the clock signal before the GPIO chipselects get configured by the SPI core, the controller has to be briefly brought up in fsl_lpspi_prepare_message(). The fsl_lpspi_prepare_message() behaves like a zero-length transfer which always uses PIO and never DMA, and which leaves the clock signal in the correct state at the end of such transfer, which happens before the GPIO chipselect toggles. Signed-off-by: Marek Vasut <marex@nabladev.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260127222353.1452003-1-marex@nabladev.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 5c6808d commit 7ae4d09

1 file changed

Lines changed: 50 additions & 4 deletions

File tree

drivers/spi/spi-fsl-lpspi.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
281281
fsl_lpspi->rx(fsl_lpspi);
282282
}
283283

284-
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
284+
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
285+
struct spi_device *spi)
285286
{
286287
u32 temp = 0;
287288

@@ -303,6 +304,13 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
303304
temp |= TCR_CONTC;
304305
}
305306
}
307+
308+
if (spi->mode & SPI_CPOL)
309+
temp |= TCR_CPOL;
310+
311+
if (spi->mode & SPI_CPHA)
312+
temp |= TCR_CPHA;
313+
306314
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
307315

308316
dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
@@ -488,12 +496,45 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
488496

489497
fsl_lpspi->watermark = min(fsl_lpspi->txfifosize, t->len);
490498

499+
return fsl_lpspi_config(fsl_lpspi);
500+
}
501+
502+
static int fsl_lpspi_prepare_message(struct spi_controller *controller,
503+
struct spi_message *msg)
504+
{
505+
struct fsl_lpspi_data *fsl_lpspi =
506+
spi_controller_get_devdata(controller);
507+
struct spi_device *spi = msg->spi;
508+
struct spi_transfer *t;
509+
int ret;
510+
511+
t = list_first_entry_or_null(&msg->transfers, struct spi_transfer,
512+
transfer_list);
513+
if (!t)
514+
return 0;
515+
516+
fsl_lpspi->is_first_byte = true;
517+
fsl_lpspi->usedma = false;
518+
ret = fsl_lpspi_setup_transfer(controller, spi, t);
519+
491520
if (fsl_lpspi_can_dma(controller, spi, t))
492521
fsl_lpspi->usedma = true;
493522
else
494523
fsl_lpspi->usedma = false;
495524

496-
return fsl_lpspi_config(fsl_lpspi);
525+
if (ret < 0)
526+
return ret;
527+
528+
fsl_lpspi_set_cmd(fsl_lpspi, spi);
529+
530+
/* No IRQs */
531+
writel(0, fsl_lpspi->base + IMX7ULP_IER);
532+
533+
/* Controller disable, clear FIFOs, clear status */
534+
writel(CR_RRF | CR_RTF, fsl_lpspi->base + IMX7ULP_CR);
535+
writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR);
536+
537+
return 0;
497538
}
498539

499540
static int fsl_lpspi_target_abort(struct spi_controller *controller)
@@ -753,14 +794,18 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
753794
spi_controller_get_devdata(controller);
754795
int ret;
755796

756-
fsl_lpspi->is_first_byte = true;
797+
if (fsl_lpspi_can_dma(controller, spi, t))
798+
fsl_lpspi->usedma = true;
799+
else
800+
fsl_lpspi->usedma = false;
801+
757802
ret = fsl_lpspi_setup_transfer(controller, spi, t);
758803
if (ret < 0)
759804
return ret;
760805

761806
t->effective_speed_hz = fsl_lpspi->config.effective_speed_hz;
762807

763-
fsl_lpspi_set_cmd(fsl_lpspi);
808+
fsl_lpspi_set_cmd(fsl_lpspi, spi);
764809
fsl_lpspi->is_first_byte = false;
765810

766811
if (fsl_lpspi->usedma)
@@ -944,6 +989,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
944989
}
945990

946991
controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
992+
controller->prepare_message = fsl_lpspi_prepare_message;
947993
controller->transfer_one = fsl_lpspi_transfer_one;
948994
controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
949995
controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;

0 commit comments

Comments
 (0)