From: Rob Herring <robh@kernel.org>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Mark Brown <broonie@kernel.org>,
linux-spi@vger.kernel.org, Mark Rutland <mark.rutland@arm.com>,
devicetree@vger.kernel.org,
Mika Westerberg <mika.westerberg@linux.intel.com>,
Jarkko Nikula <jarkko.nikula@linux.intel.com>,
Ferry Toth <fntoth@gmail.com>
Subject: Re: [RFC][PATCH v1] spi: Introduce custom GPIO chip select for slave devices
Date: Sun, 31 Mar 2019 01:42:22 -0500 [thread overview]
Message-ID: <5ca0614f.1c69fb81.67416.5f0d@mx.google.com> (raw)
In-Reply-To: <20190326212918.18541-1-andriy.shevchenko@linux.intel.com>
On Tue, Mar 26, 2019 at 11:29:18PM +0200, Andy Shevchenko wrote:
> The SPI hardware interface requires to have clock, data, and chip select
> lines to communicate with a certain chip on the bus.
>
> Historically the chip select lines were related to the SPI controller
> itself ("native" mode), however there is no technical obstacles to make
> any controllable pin as chip select. And thus no limitation to the
> amount of chip select pins should be put in such case.
>
> As a result here is a proposal to logically split "native" and GPIO chip
> select pins and make it possible for slave device to choose which pin it
> will use.
Doesn't the h/w design choose?
>
> Rationale points here are:
> - it's actually not a business of the SPI controller to know what
> resource might be used as a chip select except "native" ones
Not the business of the slave to know either.
> - some of the controllers would like to request GPIOs as soon as the
> controller itself is being registered, which is an artificial limitation
> of what GPIOs and when can be used as CS pins
Fix the controller driver implementation then?
> - as a continuation of previous point the CS pin can't be reused at
> runtime until entire controller will gone, the easy example that can
> come up is MMC SPI where we can multiplex GPIO CS based on card
> detection
> - (I dunno if DT overlays allow to expand amount of CS pins at run-time)
In theory yes, but the problem with much of it is whether the kernel can
deal with new or changing properties (hint: it can't).
> - last, but not least, is a firmware, that can't be modified by user on
> a board where some pins still available for general purpose use and user
> would like to re-use them for custom SPI slave device
>
> The split itself is simple an introduction of the "spi-cs-gpios"
> property for the slave device. SPI core will handle this for all
> supported controllers.
>
> Known issues / TODO list:
> - needs flag to handle such cases to avoid freeing controller owned
> GPIO descriptors
> - clean up is not correct in error path
> - device tree support
I'm not seeing anything new we can't already accomplish with DT
bindings.
> - split patch to device tree bindings and main part
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> - it is sent as RFC to gather opinions
> - it has been tested on x86 hardware with 74x164 SPI GPIO expander connected
>
> .../devicetree/bindings/spi/spi-bus.txt | 5 ++++-
> drivers/spi/spi.c | 18 +++++++++++++++---
> 2 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
> index 1f6e86f787ef..7f5ff64efc7d 100644
> --- a/Documentation/devicetree/bindings/spi/spi-bus.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
> @@ -69,6 +69,8 @@ All slave nodes can contain the following optional properties:
> phase (CPHA) mode.
> - spi-cs-high - Empty property indicating device requires chip select
> active high.
> +- spi-cs-gpios - Custom chip select for this device, when provided reg
> + property must be 0.
Having multiple nodes at address 0 is not valid in DT. So this wouldn't
work it CS0 is used or you wanted to do this with multiple slaves.
> - spi-3wire - Empty property indicating device requires 3-wire mode.
> - spi-lsb-first - Empty property indicating device requires LSB first mode.
> - spi-tx-bus-width - The bus width (number of data wires) that is used for MOSI.
> @@ -86,7 +88,8 @@ only 1 (SINGLE), 2 (DUAL) and 4 (QUAD).
> Dual/Quad mode is not allowed when 3-wire mode is used.
>
> If a gpio chipselect is used for the SPI slave the gpio number will be passed
> -via the SPI master node cs-gpios property.
> +via the SPI master node cs-gpios property or, when it's not possible, via
> +spi-cs-gpios property in slave configuration.
>
> SPI example for an MPC5200 SPI bus:
> spi@f00 {
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 93986f879b09..111e9705eb96 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -535,7 +535,8 @@ static int spi_dev_check(struct device *dev, void *data)
> struct spi_device *new_spi = data;
>
> if (spi->controller == new_spi->controller &&
> - spi->chip_select == new_spi->chip_select)
> + spi->chip_select == new_spi->chip_select &&
> + !new_spi->cs_gpiod)
> return -EBUSY;
> return 0;
> }
> @@ -580,7 +581,9 @@ int spi_add_device(struct spi_device *spi)
> }
>
> /* Descriptors take precedence */
> - if (ctlr->cs_gpiods)
> + if (spi->cs_gpiod)
> + dev_dbg(dev, "chipselect is provided by slave\n");
> + else if (ctlr->cs_gpiods)
> spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
> else if (ctlr->cs_gpios)
> spi->cs_gpio = ctlr->cs_gpios[spi->chip_select];
> @@ -693,8 +696,11 @@ void spi_unregister_device(struct spi_device *spi)
> of_node_clear_flag(spi->dev.of_node, OF_POPULATED);
> of_node_put(spi->dev.of_node);
> }
> - if (ACPI_COMPANION(&spi->dev))
> + if (ACPI_COMPANION(&spi->dev)) {
> + gpiod_put(spi->cs_gpiod);
> + spi->cs_gpiod = NULL;
> acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev));
> + }
> device_unregister(&spi->dev);
> }
> EXPORT_SYMBOL_GPL(spi_unregister_device);
> @@ -1910,6 +1916,12 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
> if (spi->irq < 0)
> spi->irq = acpi_dev_gpio_irq_get(adev, 0);
>
> + spi->cs_gpiod = gpiod_get_optional(&spi->dev, "spi-cs", GPIOD_ASIS);
> + if (IS_ERR(spi->cs_gpiod)) {
> + spi_dev_put(spi);
> + return AE_OK;
> + }
> +
> acpi_device_set_enumerated(adev);
>
> adev->power.flags.ignore_parent = true;
> --
> 2.20.1
>
prev parent reply other threads:[~2019-03-31 6:42 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-26 21:29 [RFC][PATCH v1] spi: Introduce custom GPIO chip select for slave devices Andy Shevchenko
2019-03-31 6:42 ` Rob Herring [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5ca0614f.1c69fb81.67416.5f0d@mx.google.com \
--to=robh@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=broonie@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fntoth@gmail.com \
--cc=jarkko.nikula@linux.intel.com \
--cc=linux-spi@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mika.westerberg@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).