Hi Qleksij,
On 24/07/17 16:21, Oleksij Rempel wrote:
On Thu, Jul 20, 2017 at 11:00:49PM +1000, Greg Ungerer wrote:
Hi Oleksij,
On 20/07/17 16:34, Oleksij Rempel wrote:
Hi Greg,
On Tue, Jul 18, 2017 at 09:53:58PM -0300, Fabio Estevam wrote:
Adding Pengutronix folks on Cc.
On Tue, Jul 11, 2017 at 1:22 AM, Greg Ungerer <gerg@xxxxxxxxxxxxxx> wrote:
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@xxxxxxxxxxxxxx>
---
drivers/spi/spi-imx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index b402530..f4fe66c 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -524,8 +524,8 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config)
reg |= MX31_CSPICTRL_POL;
if (spi->mode & SPI_CS_HIGH)
reg |= MX31_CSPICTRL_SSPOL;
- if (spi->cs_gpio < 0)
- reg |= (spi->cs_gpio + 32) <<
+ if (!gpio_is_valid(spi->cs_gpio))
+ reg |= (spi->chip_select) <<
(is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT :
MX31_CSPICTRL_CS_SHIFT);
@@ -616,8 +616,8 @@ static int mx21_config(struct spi_device *spi, struct spi_imx_config *config)
reg |= MX21_CSPICTRL_POL;
if (spi->mode & SPI_CS_HIGH)
reg |= MX21_CSPICTRL_SSPOL;
- if (spi->cs_gpio < 0)
- reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT;
+ if (!gpio_is_valid(spi->cs_gpio))
+ reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT;
writel(reg, spi_imx->base + MXC_CSPICTRL);
hm... do I see this correctly, all native chip_selects should
be registered before gpio based CS?
I don't follow. The "<0>" must be in the position in the list where
you want to use the native chip select. You can't arbitrarily change
the order.
For example like this?
cs-gpios = <0>, <&gpio1 1 0>, <&gpio1 2 0>;
Looks like we don't have any sanity checks for this kind of
configuration:
cs-gpios = <&gpio1 1 0>, <&gpio1 2 0>, <0>;
The chip_select is sanity checked in spi_add_device().
We may shift some wired numbers here:
reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT;
I am not sure I see how that can be the case?
old and new version of iMX have different amount of native CS.
I can't find the code which is actually checking if we use right native
CS-index.
May be i'm blind :)
I don't think I entirely understand what you are saying. The code at the
top of spi_add_device() [drivers/spi/spi.c] looks like this:
/* Chipselects are numbered 0..max; validate. */
if (spi->chip_select >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
ctlr->num_chipselect);
return -EINVAL;
}
So it will range check the spi device (spi->chip_select) to be within
the range valid for this SPI controller. That is the very same
spi->chip_select that is used in spi-imx.c to set the register bits
when using a native chip select.
Regards
Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html