diff mbox series

spi: dw: support 4-16 bits per word

Message ID 20180808071421.32707-1-simon.k.r.goldschmidt@gmail.com (mailing list archive)
State New, archived
Headers show
Series spi: dw: support 4-16 bits per word | expand

Commit Message

Simon Goldschmidt Aug. 8, 2018, 7:14 a.m. UTC
The spi-dw driver currently only supports 8 or 16 bits per word.

Since the hardware supports 4-16 bits per word, adapt the driver
to also support this.

Tested on socfpga cyclone5 with a 9-bit SPI display.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
---
 drivers/spi/spi-dw.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Andy Shevchenko Aug. 8, 2018, 9:45 a.m. UTC | #1
On Wed, Aug 8, 2018 at 10:14 AM, Simon Goldschmidt
<simon.k.r.goldschmidt@gmail.com> wrote:
> The spi-dw driver currently only supports 8 or 16 bits per word.
>
> Since the hardware supports 4-16 bits per word, adapt the driver
> to also support this.
>
> Tested on socfpga cyclone5 with a 9-bit SPI display.

> +       if ((transfer->bits_per_word < 4) || (transfer->bits_per_word > 16))
> +               return -EINVAL;

> +       if (transfer->bits_per_word <= 8) {
>                 dws->n_bytes = 1;
>                 dws->dma_width = 1;
> -       } else if (transfer->bits_per_word == 16) {
> +       } else {
>                 dws->n_bytes = 2;
>                 dws->dma_width = 2;
>         }

Now these can be just

n_bytes = round_up(8);
dma_width = round_up(8);
Simon Goldschmidt Aug. 8, 2018, 11:58 a.m. UTC | #2
On Wed, Aug 8, 2018 at 11:45 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Wed, Aug 8, 2018 at 10:14 AM, Simon Goldschmidt
> <simon.k.r.goldschmidt@gmail.com> wrote:
> > The spi-dw driver currently only supports 8 or 16 bits per word.
> >
> > Since the hardware supports 4-16 bits per word, adapt the driver
> > to also support this.
> >
> > Tested on socfpga cyclone5 with a 9-bit SPI display.
>
> > +       if ((transfer->bits_per_word < 4) || (transfer->bits_per_word > 16))
> > +               return -EINVAL;
>
> > +       if (transfer->bits_per_word <= 8) {
> >                 dws->n_bytes = 1;
> >                 dws->dma_width = 1;
> > -       } else if (transfer->bits_per_word == 16) {
> > +       } else {
> >                 dws->n_bytes = 2;
> >                 dws->dma_width = 2;
> >         }
>
> Now these can be just
>
> n_bytes = round_up(8);
> dma_width = round_up(8);

I guess you mean:

n_bytes = round_up(transfer->bits_per_word, 8);

But that would yield 8 or 16 where we need 1 or 2.

Reading spi-imx.c, this might work:

n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);


Simon
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andy Shevchenko Aug. 8, 2018, 12:26 p.m. UTC | #3
On Wed, Aug 8, 2018 at 2:58 PM, Simon Goldschmidt
<simon.k.r.goldschmidt@gmail.com> wrote:
> On Wed, Aug 8, 2018 at 11:45 AM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
>> On Wed, Aug 8, 2018 at 10:14 AM, Simon Goldschmidt
>> <simon.k.r.goldschmidt@gmail.com> wrote:

>> n_bytes = round_up(8);
>> dma_width = round_up(8);
>
> I guess you mean:
>
> n_bytes = round_up(transfer->bits_per_word, 8);
>
> But that would yield 8 or 16 where we need 1 or 2.

Indeed.

> Reading spi-imx.c, this might work:
>
> n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);

Yes.
diff mbox series

Patch

diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index f693bfe95ab9..2ecbb6b19cea 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -307,14 +307,14 @@  static int dw_spi_transfer_one(struct spi_controller *master,
 		dws->current_freq = transfer->speed_hz;
 		spi_set_clk(dws, chip->clk_div);
 	}
-	if (transfer->bits_per_word == 8) {
+	if ((transfer->bits_per_word < 4) || (transfer->bits_per_word > 16))
+		return -EINVAL;
+	if (transfer->bits_per_word <= 8) {
 		dws->n_bytes = 1;
 		dws->dma_width = 1;
-	} else if (transfer->bits_per_word == 16) {
+	} else {
 		dws->n_bytes = 2;
 		dws->dma_width = 2;
-	} else {
-		return -EINVAL;
 	}
 	/* Default SPI mode is SCPOL = 0, SCPH = 0 */
 	cr0 = (transfer->bits_per_word - 1)
@@ -493,7 +493,7 @@  int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
 	}
 
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
-	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+	master->bits_per_word_mask =  SPI_BPW_RANGE_MASK(4, 16);
 	master->bus_num = dws->bus_num;
 	master->num_chipselect = dws->num_cs;
 	master->setup = dw_spi_setup;