The Allwinner A23/A33 SoCs contain an SPI controller that is largely identical to the one in the A31. The major differences from A31 to A23/A33 are:
- The TX and RX FIFOs on the A23/A33 are only 64 Bytes deep compared to 128 Bytes on the A31. - On A23/A33, the SPI_INTCTL register provides an additional "Master Sample Data Mode" configuration option. Currently the FIFO depth is hardcoded to 128 Bytes in the driver; this patch moves it into SoC-specific platform data instead of defining it globally and adds a new compatible "allwinner,sun8i-a23-spi". Signed-off-by: Karsten Merker <mer...@debian.org> --- .../devicetree/bindings/spi/spi-sun6i.txt | 6 ++- drivers/spi/spi-sun6i.c | 43 +++++++++++++++++++--- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-sun6i.txt b/Documentation/devicetree/bindings/spi/spi-sun6i.txt index 21de73d..4d3eb86 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun6i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt @@ -1,7 +1,9 @@ -Allwinner A31 SPI controller +Allwinner A31/A23 SPI controller Required properties: -- compatible: Should be "allwinner,sun6i-a31-spi". +- compatible: Should be one of + - "allwinner,sun6i-a31-spi" + - "allwinner,sun8i-a23-spi" - reg: Should contain register location and length. - interrupts: Should contain interrupt. - clocks: phandle to the clocks feeding the SPI controller. Two are diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 9918a57..c6d88c9 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -5,6 +5,8 @@ * Copyright (C) 2014 Maxime Ripard * Maxime Ripard <maxime.rip...@free-electrons.com> * + * Copyright (C) 2016 Karsten Merker <merker@@debian.org> + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of @@ -24,6 +26,7 @@ #include <linux/spi/spi.h> #define SUN6I_FIFO_DEPTH 128 +#define SUN8I_A23_FIFO_DEPTH 64 #define SUN6I_GBL_CTL_REG 0x04 #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) @@ -92,6 +95,18 @@ struct sun6i_spi { int len; }; +struct sun6i_spi_platform_data { + int fifo_depth; +}; + +static struct sun6i_spi_platform_data sun6i_a31_spi_platform_data = { + .fifo_depth = SUN6I_FIFO_DEPTH, +}; + +static struct sun6i_spi_platform_data sun8i_a23_spi_platform_data = { + .fifo_depth = SUN8I_A23_FIFO_DEPTH, +}; + static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) { return readl(sspi->base_addr + reg); @@ -155,7 +170,10 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) { - return SUN6I_FIFO_DEPTH - 1; + struct sun6i_spi_platform_data *pdata; + + pdata = spi->dev.platform_data; + return (pdata->fifo_depth - 1); } static int sun6i_spi_transfer_one(struct spi_master *master, @@ -168,9 +186,14 @@ static int sun6i_spi_transfer_one(struct spi_master *master, unsigned int tx_len = 0; int ret = 0; u32 reg; + int fifo_depth; + struct sun6i_spi_platform_data *pdata; /* We don't support transfer larger than the FIFO */ - if (tfr->len > SUN6I_FIFO_DEPTH) + pdata = spi->dev.platform_data; + fifo_depth = pdata->fifo_depth; + + if (tfr->len > fifo_depth) return -EINVAL; reinit_completion(&sspi->done); @@ -265,7 +288,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, SUN6I_BURST_CTL_CNT_STC(tx_len)); /* Fill the TX FIFO */ - sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); + sun6i_spi_fill_fifo(sspi, fifo_depth); /* Enable the interrupts */ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); @@ -288,7 +311,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, goto out; } - sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); + sun6i_spi_drain_fifo(sspi, fifo_depth); out: sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); @@ -470,7 +493,14 @@ static int sun6i_spi_remove(struct platform_device *pdev) } static const struct of_device_id sun6i_spi_match[] = { - { .compatible = "allwinner,sun6i-a31-spi", }, + { + .compatible = "allwinner,sun6i-a31-spi", + .data = &sun6i_a31_spi_platform_data, + }, + { + .compatible = "allwinner,sun8i-a23-spi", + .data = &sun8i_a23_spi_platform_data, + }, {} }; MODULE_DEVICE_TABLE(of, sun6i_spi_match); @@ -493,5 +523,6 @@ module_platform_driver(sun6i_spi_driver); MODULE_AUTHOR("Pan Nan <pan...@allwinnertech.com>"); MODULE_AUTHOR("Maxime Ripard <maxime.rip...@free-electrons.com>"); -MODULE_DESCRIPTION("Allwinner A31 SPI controller driver"); +MODULE_AUTHOR("Karsten Merker <mer...@debian.org>"); +MODULE_DESCRIPTION("Allwinner A31/A23 SPI controller driver"); MODULE_LICENSE("GPL"); -- 2.1.4 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.