Re: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mark,

czw., 17 gru 2020 o 12:27 <kostap@xxxxxxxxxxx> napisał(a):
>
> From: Marcin Wojtas <mw@xxxxxxxxxxxx>
>
> Some SPI devices, such as SLIC (Subscriber Line Interface Card)
> require toggling the CS every transferred byte. Enable such
> possibility by creating a new DT property and enabling SPI
> device mode update. Add according support in the spi-orion driver.
>
> Signed-off-by: Marcin Wojtas <mw@xxxxxxxxxxxx>
> Signed-off-by: Konstantin Porotchkin <kostap@xxxxxxxxxxx>
> ---
>  drivers/spi/spi-orion.c | 20 +++++++++++++++++++-
>  drivers/spi/spi.c       |  6 ++++--
>  include/linux/spi/spi.h |  1 +
>  3 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
> index 3bfda4225d45..7db9034b0879 100644
> --- a/drivers/spi/spi-orion.c
> +++ b/drivers/spi/spi-orion.c
> @@ -369,8 +369,15 @@ orion_spi_write_read_8bit(struct spi_device *spi,
>  {
>         void __iomem *tx_reg, *rx_reg, *int_reg;
>         struct orion_spi *orion_spi;
> +       bool cs_single_byte;
> +
> +       cs_single_byte = spi->mode & SPI_1BYTE_CS;
>
>         orion_spi = spi_master_get_devdata(spi->master);
> +
> +       if (cs_single_byte)
> +               orion_spi_set_cs(spi, 0);
> +
>         tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG);
>         rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG);
>         int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG);
> @@ -384,6 +391,11 @@ orion_spi_write_read_8bit(struct spi_device *spi,
>                 writel(0, tx_reg);
>
>         if (orion_spi_wait_till_ready(orion_spi) < 0) {
> +               if (cs_single_byte) {
> +                       orion_spi_set_cs(spi, 1);
> +                       /* Satisfy some SLIC devices requirements */
> +                       udelay(4);
> +               }
>                 dev_err(&spi->dev, "TXS timed out\n");
>                 return -1;
>         }
> @@ -391,6 +403,12 @@ orion_spi_write_read_8bit(struct spi_device *spi,
>         if (rx_buf && *rx_buf)
>                 *(*rx_buf)++ = readl(rx_reg);
>
> +       if (cs_single_byte) {
> +               orion_spi_set_cs(spi, 1);
> +               /* Satisfy some SLIC devices requirements */
> +               udelay(4);
> +       }
> +
>         return 1;
>  }
>
> @@ -626,7 +644,7 @@ static int orion_spi_probe(struct platform_device *pdev)
>         }
>
>         /* we support all 4 SPI modes and LSB first option */
> -       master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST;
> +       master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST | SPI_1BYTE_CS;
>         master->set_cs = orion_spi_set_cs;
>         master->transfer_one = orion_spi_transfer_one;
>         master->num_chipselect = ORION_NUM_CHIPSELECTS;
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 51d7c004fbab..998579807a04 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1937,6 +1937,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
>                 spi->mode |= SPI_LSB_FIRST;
>         if (of_property_read_bool(nc, "spi-cs-high"))
>                 spi->mode |= SPI_CS_HIGH;
> +       if (of_find_property(nc, "spi-1byte-cs", NULL))
> +               spi->mode |= SPI_1BYTE_CS;

Regarding your comment from patch 3/3 that "spi-1byte-cs" should be
replaced by handling based on the compatible string - do you mean
dropping above parsing and updating SPI bus mode field with
SPI_1BYTE_CS flag in the relevant SPI device driver?

Best regards,
Marcin

>
>         /* Device DUAL/QUAD mode */
>         if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
> @@ -3419,15 +3421,15 @@ int spi_setup(struct spi_device *spi)
>                 spi_set_thread_rt(spi->controller);
>         }
>
> -       dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",
> +       dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%s%u bits/w, %u Hz max --> %d\n",
>                         (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
>                         (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
>                         (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
>                         (spi->mode & SPI_3WIRE) ? "3wire, " : "",
>                         (spi->mode & SPI_LOOP) ? "loopback, " : "",
> +                       (spi->mode & SPI_1BYTE_CS) ? "single_cs_byte, " : "",
>                         spi->bits_per_word, spi->max_speed_hz,
>                         status);
> -
>         return status;
>  }
>  EXPORT_SYMBOL_GPL(spi_setup);
> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> index aa09fdc8042d..7f65ff6fc25d 100644
> --- a/include/linux/spi/spi.h
> +++ b/include/linux/spi/spi.h
> @@ -186,6 +186,7 @@ struct spi_device {
>  #define        SPI_TX_OCTAL    0x2000                  /* transmit with 8 wires */
>  #define        SPI_RX_OCTAL    0x4000                  /* receive with 8 wires */
>  #define        SPI_3WIRE_HIZ   0x8000                  /* high impedance turnaround */
> +#define        SPI_1BYTE_CS    0x10000                 /* toggle cs after each byte */
>         int                     irq;
>         void                    *controller_state;
>         void                    *controller_data;
> --
> 2.17.1
>




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux