linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] spi: SPI bus multiplexer
@ 2019-04-12  5:02 Chris Packham
  2019-04-12  5:02 ` [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Chris Packham
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Chris Packham @ 2019-04-12  5:02 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland
  Cc: Hamish Martin, linux-spi, devicetree, linux-kernel, Chris Packham

Hi All,

I have a hardware design where a single SPI chip select is steered by a
GPIO being asserted or de-asserted. On older kernels I was able to
(ab)use a gpio-hog and cs-gpios to deal with this.

Unfortunately recent changes have stopped my hacks from working. I've
tried adapting cs-gpios to work with my particular hardware but I came
to the realisation that the current cs-gpios support assumes a 1:1
mapping of gpio to SPI device whereas my hardware used the state of the
gpio selecting the device i.e. a 1:2 mapping.

This is my attempt to implement a driver to deal with this. One nice
property is that it is pretty much self contained. The only change to
the core SPI infrastructure is exposing a function I needed to lookup
the spi_controller instance.

Chris Packham (3):
  dt-bindings: spi: Add spi-mux-gpio
  spi: Make of_find_spi_controller_by_node visible
  spi: Add SPI bus gpio multiplexer

 .../devicetree/bindings/spi/spi-mux-gpio.txt  |  46 +++++
 drivers/spi/Kconfig                           |   7 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-mux-gpio.c                    | 169 ++++++++++++++++++
 drivers/spi/spi.c                             |   7 +-
 include/linux/spi/spi.h                       |   7 +
 6 files changed, 234 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
 create mode 100644 drivers/spi/spi-mux-gpio.c

-- 
2.21.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio
  2019-04-12  5:02 [PATCH 0/3] spi: SPI bus multiplexer Chris Packham
@ 2019-04-12  5:02 ` Chris Packham
  2019-04-29 21:37   ` Rob Herring
  2019-04-12  5:02 ` [PATCH 2/3] spi: Make of_find_spi_controller_by_node visible Chris Packham
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Chris Packham @ 2019-04-12  5:02 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland
  Cc: Hamish Martin, linux-spi, devicetree, linux-kernel, Chris Packham

Add binding documentation for spi-mux-gpio which is a slightly more
complicated hardware implementation of using gpios to steer SPI chip
selects.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
 .../devicetree/bindings/spi/spi-mux-gpio.txt  | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux-gpio.txt

diff --git a/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
new file mode 100644
index 000000000000..a32f25321d37
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
@@ -0,0 +1,45 @@
+SPI bus gpio multiplexer
+
+The SPI bus gpio multiplexer can be used to implement more complicated access
+logic than can be supported with the cs-gpios property of a SPI bus.
+
+In the example below we have a SoC with a single SPI CS that is gated by the
+state of a gpio to select the desired SPI device.
+
+     +----------+  CS    +-----+ CS0  +----+
+     |          |--------|     |------|    |
+     |          |        | \ / |      +----+
+     |   SoC    |        |  +  |
+     |          |  GPIO  | / \ | CS1  +----+
+     |          |--------|     |------|    |
+     +----------+        +-----+      +----+
+
+Required properties:
+- compatible	- must be "spi-mux-gpio"
+- gpios		- gpios used to implement the multiplexing logic
+- spi-parent-bus - parent spi bus to use
+
+Optional properties:
+- spi-parent-cs - chip select on parent bus to use. Defaults to 0 if not
+                  specified.
+
+Example for a multiplexer with a single gpio:
+
+	spi-mux {
+		compatible = "spi-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpios = <&gpio0 1 0>;
+		spi-parent-bus = <&spi0>;
+		spi-parent-cs = <0>;
+
+		spi-dev@0 {
+			compatible = "...";
+			reg = <0>;
+		}
+
+		spi-dev@1 {
+			compatible = "...";
+			reg = <1>;
+		}
+	};
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] spi: Make of_find_spi_controller_by_node visible
  2019-04-12  5:02 [PATCH 0/3] spi: SPI bus multiplexer Chris Packham
  2019-04-12  5:02 ` [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Chris Packham
@ 2019-04-12  5:02 ` Chris Packham
  2019-04-12  5:02 ` [PATCH 3/3] spi: Add SPI bus gpio multiplexer Chris Packham
  2019-04-12  8:29 ` [PATCH 0/3] spi: SPI bus multiplexer Mark Brown
  3 siblings, 0 replies; 9+ messages in thread
From: Chris Packham @ 2019-04-12  5:02 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland
  Cc: Hamish Martin, linux-spi, devicetree, linux-kernel, Chris Packham

Drop the static and add of_find_spi_controller_by_node() to spi.h. Also
move it outside of the CONFIG_OF_DYNAMIC so it is available with just
CONFIG_OF.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
 drivers/spi/spi.c       | 7 ++++---
 include/linux/spi/spi.h | 7 +++++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 93986f879b09..19929163a45b 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3531,16 +3531,14 @@ struct spi_device *of_find_spi_device_by_node(struct device_node *node)
 	return dev ? to_spi_device(dev) : NULL;
 }
 EXPORT_SYMBOL_GPL(of_find_spi_device_by_node);
-#endif /* IS_ENABLED(CONFIG_OF) */
 
-#if IS_ENABLED(CONFIG_OF_DYNAMIC)
 static int __spi_of_controller_match(struct device *dev, const void *data)
 {
 	return dev->of_node == data;
 }
 
 /* the spi controllers are not using spi_bus, so we find it with another way */
-static struct spi_controller *of_find_spi_controller_by_node(struct device_node *node)
+struct spi_controller *of_find_spi_controller_by_node(struct device_node *node)
 {
 	struct device *dev;
 
@@ -3555,7 +3553,10 @@ static struct spi_controller *of_find_spi_controller_by_node(struct device_node
 	/* reference got in class_find_device */
 	return container_of(dev, struct spi_controller, dev);
 }
+EXPORT_SYMBOL_GPL(of_find_spi_controller_by_node);
+#endif /* IS_ENABLED(CONFIG_OF) */
 
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
 static int of_spi_notify(struct notifier_block *nb, unsigned long action,
 			 void *arg)
 {
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 662b336aa2e4..e763290767ea 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1334,6 +1334,8 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer)
 extern struct spi_device *
 of_find_spi_device_by_node(struct device_node *node);
 
+extern struct spi_controller *
+of_find_spi_controller_by_node(struct device_node *node);
 #else
 
 static inline struct spi_device *
@@ -1342,6 +1344,11 @@ of_find_spi_device_by_node(struct device_node *node)
 	return NULL;
 }
 
+static inline struct spi_controller *
+of_find_spi_controller_by_node(struct device_node *node)
+{
+	return NULL;
+}
 #endif /* IS_ENABLED(CONFIG_OF) */
 
 /* Compatibility layer */
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] spi: Add SPI bus gpio multiplexer
  2019-04-12  5:02 [PATCH 0/3] spi: SPI bus multiplexer Chris Packham
  2019-04-12  5:02 ` [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Chris Packham
  2019-04-12  5:02 ` [PATCH 2/3] spi: Make of_find_spi_controller_by_node visible Chris Packham
@ 2019-04-12  5:02 ` Chris Packham
  2019-04-12  8:29 ` [PATCH 0/3] spi: SPI bus multiplexer Mark Brown
  3 siblings, 0 replies; 9+ messages in thread
From: Chris Packham @ 2019-04-12  5:02 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland
  Cc: Hamish Martin, linux-spi, devicetree, linux-kernel, Chris Packham

This add support for a gpio based multiplexer for SPI buses. This can be
used in situations where the cs-gpios property does not work with the
hardware design. In particular this support situations where a single
gpio is used to select between two possible devices.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
 drivers/spi/Kconfig        |   7 ++
 drivers/spi/Makefile       |   1 +
 drivers/spi/spi-mux-gpio.c | 169 +++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+)
 create mode 100644 drivers/spi/spi-mux-gpio.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f761655e2a36..bfb4bd5bc2f3 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -426,6 +426,13 @@ config SPI_MT65XX
 	  say Y or M here.If you are not sure, say N.
 	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
 
+config SPI_MUX_GPIO
+	tristate "SPI bus gpio multiplexer"
+	help
+	  This selects the SPI bus gpio multiplexer.
+	  If you have a hardware design that requires multiplexing
+	  on the SPI bus say Y or M here. If you are not sure, say N.
+
 config SPI_NPCM_PSPI
 	tristate "Nuvoton NPCM PSPI Controller"
 	depends on ARCH_NPCM || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d8fc03c9faa2..32d831374e1f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_SPI_MPC52xx)		+= spi-mpc52xx.o
 obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
 obj-$(CONFIG_SPI_MXIC)			+= spi-mxic.o
 obj-$(CONFIG_SPI_MXS)			+= spi-mxs.o
+obj-$(CONFIG_SPI_MUX_GPIO)		+= spi-mux-gpio.o
 obj-$(CONFIG_SPI_NPCM_PSPI)		+= spi-npcm-pspi.o
 obj-$(CONFIG_SPI_NUC900)		+= spi-nuc900.o
 obj-$(CONFIG_SPI_NXP_FLEXSPI)		+= spi-nxp-fspi.o
diff --git a/drivers/spi/spi-mux-gpio.c b/drivers/spi/spi-mux-gpio.c
new file mode 100644
index 000000000000..3666863a4e3f
--- /dev/null
+++ b/drivers/spi/spi-mux-gpio.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Allied Telesis
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio/consumer.h>
+
+struct spi_mux_gpio {
+	struct gpio_descs *gpios;
+	struct spi_controller *ctlr;
+	struct spi_controller *parent_ctlr;
+	int chip_select;
+};
+
+static void spi_mux_set_cs(struct spi_device *spi, bool enable)
+{
+	DECLARE_BITMAP(values, BITS_PER_TYPE(spi->chip_select));
+	struct spi_mux_gpio *mux = spi_master_get_devdata(spi->controller);
+	struct spi_device spidev = *spi;
+
+	values[0] = spi->chip_select;
+
+	gpiod_set_array_value_cansleep(mux->gpios->ndescs,
+				       mux->gpios->desc,
+				       mux->gpios->info, values);
+
+	spidev.controller = mux->parent_ctlr;
+	spidev.master = mux->parent_ctlr;
+	spidev.chip_select = mux->chip_select;
+
+	mux->parent_ctlr->set_cs(&spidev, enable);
+}
+
+static int spi_mux_transfer_one(struct spi_controller *ctlr,
+				struct spi_device *spi,
+				struct spi_transfer *transfer)
+{
+	struct spi_mux_gpio *mux = spi_master_get_devdata(ctlr);
+	struct spi_device spidev = *spi;
+
+	spidev.controller = mux->parent_ctlr;
+	spidev.master = mux->parent_ctlr;
+	spidev.chip_select = mux->chip_select;
+
+	return mux->parent_ctlr->transfer_one(mux->parent_ctlr, &spidev, transfer);
+
+}
+
+static int spi_mux_setup(struct spi_device *spi)
+{
+	struct spi_mux_gpio *mux = spi_master_get_devdata(spi->controller);
+	struct spi_device spidev = *spi;
+
+	spidev.controller = mux->parent_ctlr;
+	spidev.master = mux->parent_ctlr;
+	spidev.chip_select = mux->chip_select;
+
+	return mux->parent_ctlr->setup(&spidev);
+}
+
+static int spi_mux_gpio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *parent;
+	struct spi_controller *parent_ctlr;
+	struct spi_controller *ctlr;
+	struct spi_mux_gpio *mux;
+	struct gpio_descs *gpios;
+	int ret;
+
+	gpios = devm_gpiod_get_array(&pdev->dev, NULL, GPIOD_OUT_LOW);
+	if (IS_ERR(gpios))
+		return PTR_ERR(gpios);
+
+	parent = of_parse_phandle(np, "spi-parent-bus", 0);
+	if (!parent)
+		return -ENODEV;
+
+	parent_ctlr = of_find_spi_controller_by_node(parent);
+	if (!parent_ctlr) {
+		ret = -EPROBE_DEFER;
+		goto err_put_node;
+	}
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*mux));
+	if (!ctlr) {
+		ret = -ENOMEM;
+		goto err_put_device;
+	}
+	mux = spi_master_get_devdata(ctlr);
+	platform_set_drvdata(pdev, mux);
+
+	ctlr->mode_bits = parent_ctlr->mode_bits;
+	ctlr->bits_per_word_mask = parent_ctlr->bits_per_word_mask;
+	ctlr->auto_runtime_pm = parent_ctlr->auto_runtime_pm;
+	ctlr->flags = parent_ctlr->flags;
+	ctlr->set_cs = spi_mux_set_cs;
+	ctlr->transfer_one = spi_mux_transfer_one;
+	ctlr->setup = spi_mux_setup;
+	ctlr->num_chipselect = of_get_available_child_count(np);
+	ctlr->bus_num = -1;
+
+	mux->gpios = gpios;
+	mux->ctlr = ctlr;
+	mux->parent_ctlr = parent_ctlr;
+	ret = of_property_read_u32(np, "spi-parent-cs",
+				   &mux->chip_select);
+	if (ret)
+		mux->chip_select = 0;
+
+	ctlr->dev.of_node = np;
+	ret = devm_spi_register_controller(&pdev->dev, ctlr);
+	if (ret) {
+		dev_err(&pdev->dev, "Error: failed to register SPI bus %pOF %d\n",
+			np, ret);
+		goto err_put_ctlr;
+	}
+
+	return 0;
+
+err_put_ctlr:
+	spi_controller_put(ctlr);
+err_put_device:
+	put_device(&parent_ctlr->dev);
+err_put_node:
+	of_node_put(parent);
+
+	return ret;
+}
+
+static int spi_mux_gpio_remove(struct platform_device *pdev)
+{
+	struct spi_mux_gpio *mux = platform_get_drvdata(pdev);
+
+	spi_controller_put(mux->ctlr);
+	put_device(&mux->parent_ctlr->dev);
+
+	return 0;
+}
+
+static const struct of_device_id spi_mux_gpio_of_match[] = {
+	{ .compatible = "spi-mux-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, spi_mux_gpio_of_match);
+
+static struct platform_driver spi_mux_gpio_driver = {
+	.probe	= spi_mux_gpio_probe,
+	.remove	= spi_mux_gpio_remove,
+	.driver	= {
+		.name	= "spi-mux-gpio",
+		.of_match_table = spi_mux_gpio_of_match,
+	},
+};
+
+module_platform_driver(spi_mux_gpio_driver);
+
+MODULE_DESCRIPTION("SPI bus mutliplexer driver");
+MODULE_AUTHOR("Allied Telesis");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:spi-mux-gpio");
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] spi: SPI bus multiplexer
  2019-04-12  5:02 [PATCH 0/3] spi: SPI bus multiplexer Chris Packham
                   ` (2 preceding siblings ...)
  2019-04-12  5:02 ` [PATCH 3/3] spi: Add SPI bus gpio multiplexer Chris Packham
@ 2019-04-12  8:29 ` Mark Brown
  2019-04-28 22:28   ` Chris Packham
  3 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2019-04-12  8:29 UTC (permalink / raw)
  To: Chris Packham
  Cc: robh+dt, mark.rutland, Hamish Martin, linux-spi, devicetree,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

On Fri, Apr 12, 2019 at 05:02:10PM +1200, Chris Packham wrote:

> Unfortunately recent changes have stopped my hacks from working. I've
> tried adapting cs-gpios to work with my particular hardware but I came
> to the realisation that the current cs-gpios support assumes a 1:1
> mapping of gpio to SPI device whereas my hardware used the state of the
> gpio selecting the device i.e. a 1:2 mapping.

> This is my attempt to implement a driver to deal with this. One nice
> property is that it is pretty much self contained. The only change to
> the core SPI infrastructure is exposing a function I needed to lookup
> the spi_controller instance.

Why not implement the device that demuxes the GPIOs you're using for
chip select as a GPIO controller?  Presumably it might get used for
things other than chip selects.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] spi: SPI bus multiplexer
  2019-04-12  8:29 ` [PATCH 0/3] spi: SPI bus multiplexer Mark Brown
@ 2019-04-28 22:28   ` Chris Packham
  2019-05-02  2:45     ` Mark Brown
  0 siblings, 1 reply; 9+ messages in thread
From: Chris Packham @ 2019-04-28 22:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: robh+dt, mark.rutland, Hamish Martin, linux-spi, devicetree,
	linux-kernel, tthayer

On 12/04/19 8:29 PM, Mark Brown wrote:
> On Fri, Apr 12, 2019 at 05:02:10PM +1200, Chris Packham wrote:
> 
>> Unfortunately recent changes have stopped my hacks from working. I've
>> tried adapting cs-gpios to work with my particular hardware but I came
>> to the realisation that the current cs-gpios support assumes a 1:1
>> mapping of gpio to SPI device whereas my hardware used the state of the
>> gpio selecting the device i.e. a 1:2 mapping.
> 
>> This is my attempt to implement a driver to deal with this. One nice
>> property is that it is pretty much self contained. The only change to
>> the core SPI infrastructure is exposing a function I needed to lookup
>> the spi_controller instance.
> 
> Why not implement the device that demuxes the GPIOs you're using for
> chip select as a GPIO controller?  Presumably it might get used for
> things other than chip selects.
> 

Hmm a gpio-gpio driver. Interesting.

One other problem that I encounter is the interaction between cs-gpio 
and SPI_MASTER_GPIO_SS. Having cs-gpio automatically sets SPI_CS_HIGH 
which has the undesired side-effect that now my real chip select is 
inverted. I actually wonder if this change breaks commit 8eee6b9dd30d 
("spi: Add Flag to Enable Slave Select with GPIO Chip Select.") since 
now there is an extra inversion on the CS enable.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio
  2019-04-12  5:02 ` [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Chris Packham
@ 2019-04-29 21:37   ` Rob Herring
  2020-01-13  3:43     ` Chris Packham
  0 siblings, 1 reply; 9+ messages in thread
From: Rob Herring @ 2019-04-29 21:37 UTC (permalink / raw)
  To: Chris Packham
  Cc: broonie, mark.rutland, Hamish Martin, linux-spi, devicetree,
	linux-kernel

On Fri, Apr 12, 2019 at 05:02:11PM +1200, Chris Packham wrote:
> Add binding documentation for spi-mux-gpio which is a slightly more
> complicated hardware implementation of using gpios to steer SPI chip
> selects.
> 
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>  .../devicetree/bindings/spi/spi-mux-gpio.txt  | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> new file mode 100644
> index 000000000000..a32f25321d37
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> @@ -0,0 +1,45 @@
> +SPI bus gpio multiplexer
> +
> +The SPI bus gpio multiplexer can be used to implement more complicated access
> +logic than can be supported with the cs-gpios property of a SPI bus.
> +
> +In the example below we have a SoC with a single SPI CS that is gated by the
> +state of a gpio to select the desired SPI device.
> +
> +     +----------+  CS    +-----+ CS0  +----+
> +     |          |--------|     |------|    |
> +     |          |        | \ / |      +----+
> +     |   SoC    |        |  +  |
> +     |          |  GPIO  | / \ | CS1  +----+
> +     |          |--------|     |------|    |
> +     +----------+        +-----+      +----+
> +
> +Required properties:
> +- compatible	- must be "spi-mux-gpio"
> +- gpios		- gpios used to implement the multiplexing logic
> +- spi-parent-bus - parent spi bus to use
> +
> +Optional properties:
> +- spi-parent-cs - chip select on parent bus to use. Defaults to 0 if not
> +                  specified.
> +
> +Example for a multiplexer with a single gpio:
> +
> +	spi-mux {
> +		compatible = "spi-mux-gpio";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		gpios = <&gpio0 1 0>;
> +		spi-parent-bus = <&spi0>;
> +		spi-parent-cs = <0>;

Why is this out of band? We can do something similar to I2C and use the 
mux-control binding:

spi {
	mux@0 {
		compatible = "spi-mux";
		reg "0"; 
		mux-controls = ...;

		spi-dev@0 {};
		spi-dev@1 {};
	};

	spi-dev@1 {};

};

Rob

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] spi: SPI bus multiplexer
  2019-04-28 22:28   ` Chris Packham
@ 2019-05-02  2:45     ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2019-05-02  2:45 UTC (permalink / raw)
  To: Chris Packham
  Cc: robh+dt, mark.rutland, Hamish Martin, linux-spi, devicetree,
	linux-kernel, tthayer

[-- Attachment #1: Type: text/plain, Size: 833 bytes --]

On Sun, Apr 28, 2019 at 10:28:16PM +0000, Chris Packham wrote:

> One other problem that I encounter is the interaction between cs-gpio 
> and SPI_MASTER_GPIO_SS. Having cs-gpio automatically sets SPI_CS_HIGH 
> which has the undesired side-effect that now my real chip select is 
> inverted. I actually wonder if this change breaks commit 8eee6b9dd30d 
> ("spi: Add Flag to Enable Slave Select with GPIO Chip Select.") since 
> now there is an extra inversion on the CS enable.

That sounds like a framework bug which should just be fixed - we
shouldn't be disrupting users of real chip selects when using a GPIO
chip select.  Depending on the hardware we might need a chip select
assigned that isn't connected to anything for use while the GPIOs are
doing the real work but otherwise we shouldn't be breaking things.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio
  2019-04-29 21:37   ` Rob Herring
@ 2020-01-13  3:43     ` Chris Packham
  0 siblings, 0 replies; 9+ messages in thread
From: Chris Packham @ 2020-01-13  3:43 UTC (permalink / raw)
  To: robh
  Cc: linux-spi, mark.rutland, linux-kernel, broonie, anthony.derosa,
	devicetree

Hi Rob,

On Mon, 2019-04-29 at 16:37 -0500, Rob Herring wrote:
> On Fri, Apr 12, 2019 at 05:02:11PM +1200, Chris Packham wrote:
> > Add binding documentation for spi-mux-gpio which is a slightly more
> > complicated hardware implementation of using gpios to steer SPI chip
> > selects.
> > 
> > Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> > ---
> >  .../devicetree/bindings/spi/spi-mux-gpio.txt  | 45 +++++++++++++++++++
> >  1 file changed, 45 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> > new file mode 100644
> > index 000000000000..a32f25321d37
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/spi/spi-mux-gpio.txt
> > @@ -0,0 +1,45 @@
> > +SPI bus gpio multiplexer
> > +
> > +The SPI bus gpio multiplexer can be used to implement more complicated access
> > +logic than can be supported with the cs-gpios property of a SPI bus.
> > +
> > +In the example below we have a SoC with a single SPI CS that is gated by the
> > +state of a gpio to select the desired SPI device.
> > +
> > +     +----------+  CS    +-----+ CS0  +----+
> > +     |          |--------|     |------|    |
> > +     |          |        | \ / |      +----+
> > +     |   SoC    |        |  +  |
> > +     |          |  GPIO  | / \ | CS1  +----+
> > +     |          |--------|     |------|    |
> > +     +----------+        +-----+      +----+
> > +
> > +Required properties:
> > +- compatible	- must be "spi-mux-gpio"
> > +- gpios		- gpios used to implement the multiplexing logic
> > +- spi-parent-bus - parent spi bus to use
> > +
> > +Optional properties:
> > +- spi-parent-cs - chip select on parent bus to use. Defaults to 0 if not
> > +                  specified.
> > +
> > +Example for a multiplexer with a single gpio:
> > +
> > +	spi-mux {
> > +		compatible = "spi-mux-gpio";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		gpios = <&gpio0 1 0>;
> > +		spi-parent-bus = <&spi0>;
> > +		spi-parent-cs = <0>;
> 
> Why is this out of band? We can do something similar to I2C and use the 
> mux-control binding:
> 
> spi {
> 	mux@0 {
> 		compatible = "spi-mux";
> 		reg "0"; 
> 		mux-controls = ...;
> 
> 		spi-dev@0 {};
> 		spi-dev@1 {};
> 	};
> 
> 	spi-dev@1 {};
> 
> };

I've been re-visiting this thread and an older one[1] with an eye on
implementing a solution with mux-controls.

One thing I'm confused about is your comment that the mux should be in-
band like i2c. Looking at the one user of i2c-mux (at91-natte.dtsi) it
also appears out of band and determine the parent bus with a i2c-parent 
property (similar to how I did it in my original submission). I also
can't see how the mux would work in-band since it lacks the correct
#address-cells etc for a spi device.

I'm wondering if I've missed something obvious.

--
[1] - https://patchwork.kernel.org/patch/2706151/

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-01-13  3:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-12  5:02 [PATCH 0/3] spi: SPI bus multiplexer Chris Packham
2019-04-12  5:02 ` [PATCH 1/3] dt-bindings: spi: Add spi-mux-gpio Chris Packham
2019-04-29 21:37   ` Rob Herring
2020-01-13  3:43     ` Chris Packham
2019-04-12  5:02 ` [PATCH 2/3] spi: Make of_find_spi_controller_by_node visible Chris Packham
2019-04-12  5:02 ` [PATCH 3/3] spi: Add SPI bus gpio multiplexer Chris Packham
2019-04-12  8:29 ` [PATCH 0/3] spi: SPI bus multiplexer Mark Brown
2019-04-28 22:28   ` Chris Packham
2019-05-02  2:45     ` Mark Brown

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).