Commit 602c8f44 authored by Greg Ungerer's avatar Greg Ungerer Committed by Mark Brown

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: default avatarGreg Ungerer <gerg@linux-m68k.org>
Reviewed-by: default avatarVladimir Zapolskiy <vz@mleia.com>
Tested-by: default avatarVladimir Zapolskiy <vz@mleia.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5904c9d3
...@@ -622,8 +622,8 @@ static int mx31_config(struct spi_device *spi) ...@@ -622,8 +622,8 @@ static int mx31_config(struct spi_device *spi)
reg |= MX31_CSPICTRL_POL; reg |= MX31_CSPICTRL_POL;
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
reg |= MX31_CSPICTRL_SSPOL; reg |= MX31_CSPICTRL_SSPOL;
if (spi->cs_gpio < 0) if (!gpio_is_valid(spi->cs_gpio))
reg |= (spi->cs_gpio + 32) << reg |= (spi->chip_select) <<
(is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT :
MX31_CSPICTRL_CS_SHIFT); MX31_CSPICTRL_CS_SHIFT);
...@@ -714,8 +714,8 @@ static int mx21_config(struct spi_device *spi) ...@@ -714,8 +714,8 @@ static int mx21_config(struct spi_device *spi)
reg |= MX21_CSPICTRL_POL; reg |= MX21_CSPICTRL_POL;
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
reg |= MX21_CSPICTRL_SSPOL; reg |= MX21_CSPICTRL_SSPOL;
if (spi->cs_gpio < 0) if (!gpio_is_valid(spi->cs_gpio))
reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT;
writel(reg, spi_imx->base + MXC_CSPICTRL); writel(reg, spi_imx->base + MXC_CSPICTRL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment