Dear All, > The NXP's Vybryd vf610 can work as a SPI slave device (the CS and > clock signals are provided by master). > > It is possible to specify a single device to work in that mode. As we > do use DMA for transferring data, the RX channel must be prepared for > incoming data. > Moreover, in slave mode we just set a subset of control fields in > configuration registers (CTAR0, PUSHR). > > For testing the spidev_test program has been used. > Test script for this patch can be found here: > https://github.com/lmajewski/tests-spi/blob/master/tests/spi/spi_tests.sh > > Signed-off-by: Lukasz Majewski <lukma@xxxxxxx> > --- > Changes for v5: > > - Rebase to v5.0-rc1 (no code changes needed) Is there any interest in adding new code (or fixes) to VF610 ? The first version of this patch was posted more than 4 months ago with no feedback on the VF610 dspi controller part (after I've rewritten it to use the generic SPI slave code after comments from Geert [1]). I do have a feeling that upstreaming this code takes a bit too long ... [1] - https://lkml.org/lkml/2018/9/26/836 > > Changes for v4: > > - Rebase to v4.20-rc5 (no code changes needed) > > Changes for v3: > > - Rebase to v4.20-rc2 (no code changes needed) > > Changes for v2: > > - Remove patch which adds extra NXP specific DTS property to support > slave mode and reuse the generic one (spi-slave) > - Remove patch which brings back the mcr_register local copy. It is > not needed as generic SPI slave infrastructure is used. > - Rewrite the code to use spi_controller_is_slave() helper functions > --- > drivers/spi/spi-fsl-dspi.c | 40 > ++++++++++++++++++++++++++++++---------- 1 file changed, 30 > insertions(+), 10 deletions(-) > > diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c > index 5e10dc5c93a5..348682be9dd5 100644 > --- a/drivers/spi/spi-fsl-dspi.c > +++ b/drivers/spi/spi-fsl-dspi.c > @@ -233,6 +233,9 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi > *dspi) { > u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi); > > + if (spi_controller_is_slave(dspi->master)) > + return data; > + > if (dspi->len > 0) > cmd |= SPI_PUSHR_CMD_CONT; > return cmd << 16 | data; > @@ -329,6 +332,11 @@ static int dspi_next_xfer_dma_submit(struct > fsl_dspi *dspi) dma_async_issue_pending(dma->chan_rx); > dma_async_issue_pending(dma->chan_tx); > > + if (spi_controller_is_slave(dspi->master)) { > + > wait_for_completion_interruptible(&dspi->dma->cmd_rx_complete); > + return 0; > + } > + > time_left = > wait_for_completion_timeout(&dspi->dma->cmd_tx_complete, > DMA_COMPLETION_TIMEOUT); if (time_left == 0) { > @@ -798,14 +806,18 @@ static int dspi_setup(struct spi_device *spi) > ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate); > > chip->ctar_val = SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0) > - | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0) > - | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0) > - | SPI_CTAR_PCSSCK(pcssck) > - | SPI_CTAR_CSSCK(cssck) > - | SPI_CTAR_PASC(pasc) > - | SPI_CTAR_ASC(asc) > - | SPI_CTAR_PBR(pbr) > - | SPI_CTAR_BR(br); > + | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0); > + > + if (!spi_controller_is_slave(dspi->master)) { > + chip->ctar_val |= SPI_CTAR_LSBFE(spi->mode & > + SPI_LSB_FIRST ? 1 : > 0) > + | SPI_CTAR_PCSSCK(pcssck) > + | SPI_CTAR_CSSCK(cssck) > + | SPI_CTAR_PASC(pasc) > + | SPI_CTAR_ASC(asc) > + | SPI_CTAR_PBR(pbr) > + | SPI_CTAR_BR(br); > + } > > spi_set_ctldata(spi, chip); > > @@ -970,8 +982,13 @@ static const struct regmap_config > dspi_xspi_regmap_config[] = { > static void dspi_init(struct fsl_dspi *dspi) > { > - regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | > SPI_MCR_PCSIS | > - (dspi->devtype_data->xspi_mode ? SPI_MCR_XSPI : > 0)); > + unsigned int mcr = SPI_MCR_PCSIS | > + (dspi->devtype_data->xspi_mode ? SPI_MCR_XSPI : 0); > + > + if (!spi_controller_is_slave(dspi->master)) > + mcr |= SPI_MCR_MASTER; > + > + regmap_write(dspi->regmap, SPI_MCR, mcr); > regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); > if (dspi->devtype_data->xspi_mode) > regmap_write(dspi->regmap, SPI_CTARE(0), > @@ -1027,6 +1044,9 @@ static int dspi_probe(struct platform_device > *pdev) } > master->bus_num = bus_num; > > + if (of_property_read_bool(np, "spi-slave")) > + master->slave = true; > + > dspi->devtype_data = > of_device_get_match_data(&pdev->dev); if (!dspi->devtype_data) { > dev_err(&pdev->dev, "can't get > devtype_data\n"); Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@xxxxxxx
Attachment:
pgpIw5iToGaqk.pgp
Description: OpenPGP digital signature