Re: [PATCHv3] ARM: dspi: Provide support for DSPI slave mode operation (Vybryd vf610)
From: Lukasz Majewski
Date: Sun Dec 02 2018 - 03:47:38 EST
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
Gentle ping on this patch. Comments are more than welcome.
>
> Signed-off-by: Lukasz Majewski <lukma@xxxxxxx>
> ---
> 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 3082e72e4f6c..94b6a9690062 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:
pgpBXLY1461ef.pgp
Description: OpenPGP digital signature