diff options
author | Greg Ungerer <gerg@linux-m68k.org> | 2017-07-11 00:22:11 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-08-29 16:09:03 -0400 |
commit | 602c8f4485cd1e6de67e41c78db96fa4f6808e53 (patch) | |
tree | 48520f23a5e8ca55000619767f47ad5870cb99f3 | |
parent | 5904c9d3c9bd52f79718d1806175271b4bd20718 (diff) |
spi: imx: fix use of native chip-selects with devicetree
The commonly used mechanism of specifying the hardware or native
chip-select on an SPI device in devicetree (that is "cs-gpios = <0>")
does not result in the native chip-select being configured for use.
So external SPI devices that require use of the native chip-select
will not work.
You can successfully specify native chip-selects if using a platform
setup by specifying the cs-gpio as negative offset by 32. And that
works correctly. You cannot use the same method in devicetree.
The logic in the spi-imx.c driver during probe uses core spi function
of_spi_register_master() in spi.c to parse the "cs-gpios" devicetree tag.
For valid GPIO values that will be recorded for use, all other entries in
the cs_gpios list will be set to -ENOENT. So entries like "<0>" will be
set to -ENOENT in the cs_gpios list.
When the SPI device registers are setup the code will use the GPIO
listed in the cs_gpios list for the desired chip-select. If the cs_gpio
is less then 0 then it is intended to be for a native chip-select, and
its cs_gpio value is added to 32 to get the chipselect number to use.
Problem is that with devicetree this can only ever be -ENOENT (which
is -2), and that alone results in an invalid chip-select number. But also
doesn't allow selection of the native chip-select at all.
To fix, if the cs_gpio specified for this spi device is not a
valid GPIO then use the "chip_select" (that is the native chip-select
number) for hardware setup.
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Tested-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-imx.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 6fcb6adf9565..babb15f07995 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -622,8 +622,8 @@ static int mx31_config(struct spi_device *spi) | |||
622 | reg |= MX31_CSPICTRL_POL; | 622 | reg |= MX31_CSPICTRL_POL; |
623 | if (spi->mode & SPI_CS_HIGH) | 623 | if (spi->mode & SPI_CS_HIGH) |
624 | reg |= MX31_CSPICTRL_SSPOL; | 624 | reg |= MX31_CSPICTRL_SSPOL; |
625 | if (spi->cs_gpio < 0) | 625 | if (!gpio_is_valid(spi->cs_gpio)) |
626 | reg |= (spi->cs_gpio + 32) << | 626 | reg |= (spi->chip_select) << |
627 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : | 627 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : |
628 | MX31_CSPICTRL_CS_SHIFT); | 628 | MX31_CSPICTRL_CS_SHIFT); |
629 | 629 | ||
@@ -714,8 +714,8 @@ static int mx21_config(struct spi_device *spi) | |||
714 | reg |= MX21_CSPICTRL_POL; | 714 | reg |= MX21_CSPICTRL_POL; |
715 | if (spi->mode & SPI_CS_HIGH) | 715 | if (spi->mode & SPI_CS_HIGH) |
716 | reg |= MX21_CSPICTRL_SSPOL; | 716 | reg |= MX21_CSPICTRL_SSPOL; |
717 | if (spi->cs_gpio < 0) | 717 | if (!gpio_is_valid(spi->cs_gpio)) |
718 | reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; | 718 | reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; |
719 | 719 | ||
720 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 720 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
721 | 721 | ||