diff mbox

[PATCHv2,2/2] spi: orion: Add multiple chip select support to spi-orion

Message ID 1421032440-15335-3-git-send-email-ken.wilson@opengear.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ken Wilson Jan. 12, 2015, 3:14 a.m. UTC
This commit adds support for multiple hardware chip selects to spi-orion.
The number of supported chip selects varies based on the SoC and pin
configuration, so it is set using the num-cs device tree binding.

Signed-off-by: Ken Wilson <ken.wilson@opengear.com>
---
 Documentation/devicetree/bindings/spi/spi-orion.txt |  3 +++
 drivers/spi/spi-orion.c                             | 17 +++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

Comments

Mark Brown Jan. 14, 2015, 8:06 p.m. UTC | #1
On Mon, Jan 12, 2015 at 01:14:00PM +1000, Ken Wilson wrote:

> +- num-cs     : The total number of chip selects used by this platform.
> +		If unset, this defaults to 1.

So, this is intended to be the number of hardware chip selects that can
be configured but the first commit mentioned GPIOs as an option too so
we should at least say that this is specifically the controller
supported ones.  However...

> +#define ORION_SPI_CS_MASK	0x1C
> +#define ORION_SPI_CS_SHIFT	2
> +#define ORION_SPI_CS(cs)	((cs << ORION_SPI_CS_SHIFT) & \
> +					ORION_SPI_CS_MASK)

...given that we have a fixed bitfield here which we know and doesn't
appear to depend on configuration do we even need this to be
configurable - given that we're going to need an explicit node for any
slave can't we just accept any sane chip select for a slave without
extending the binding?
Ken Wilson Jan. 15, 2015, 1:07 a.m. UTC | #2
On 15/01/15 06:06, Mark Brown wrote:
> On Mon, Jan 12, 2015 at 01:14:00PM +1000, Ken Wilson wrote:
>
>> +- num-cs     : The total number of chip selects used by this platform.
>> +		If unset, this defaults to 1.
> So, this is intended to be the number of hardware chip selects that can
> be configured but the first commit mentioned GPIOs as an option too so
> we should at least say that this is specifically the controller
> supported ones.  However...
>
>> +#define ORION_SPI_CS_MASK	0x1C
>> +#define ORION_SPI_CS_SHIFT	2
>> +#define ORION_SPI_CS(cs)	((cs << ORION_SPI_CS_SHIFT) & \
>> +					ORION_SPI_CS_MASK)
> ...given that we have a fixed bitfield here which we know and doesn't
> appear to depend on configuration do we even need this to be
> configurable - given that we're going to need an explicit node for any
> slave can't we just accept any sane chip select for a slave without
> extending the binding?
The different implementations that use this driver (Marvell Kirkwood, 
Armada 370/375) all
have a different number of supported chip selects, that fit into this 
bit mask. There are also
multiple SPI controllers on each SoC which support different numbers of 
chip selects.
For example, on the Armada 375, SPI0 supports 3 chip selects, while SPI1 
only has 1.

I agree that we could support any sane chip select for a slave, since 
the slave addresses do need
to be explicitly defined. I'm happy with whatever your preference is.

Thanks,
Ken
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown Jan. 15, 2015, 11:22 a.m. UTC | #3
On Thu, Jan 15, 2015 at 11:07:12AM +1000, Ken Wilson wrote:

> I agree that we could support any sane chip select for a slave, since the
> slave addresses do need
> to be explicitly defined. I'm happy with whatever your preference is.

Just accepting anything seems easier both for users and in
implementation.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt
index 50c3a3d..0f8fd7e 100644
--- a/Documentation/devicetree/bindings/spi/spi-orion.txt
+++ b/Documentation/devicetree/bindings/spi/spi-orion.txt
@@ -6,6 +6,8 @@  Required properties:
 - cell-index : Which of multiple SPI controllers is this.
 Optional properties:
 - interrupts : Is currently not used.
+- num-cs     : The total number of chip selects used by this platform.
+		If unset, this defaults to 1.
 
 Example:
        spi@10600 {
@@ -15,5 +17,6 @@  Example:
 	       cell-index = <0>;
 	       reg = <0x10600 0x28>;
 	       interrupts = <23>;
+	       num-cs = <1>;
 	       status = "disabled";
        };
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index e6ac9d5..1c28152 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -28,7 +28,6 @@ 
 /* Runtime PM autosuspend timeout: PM is fairly light on this driver */
 #define SPI_AUTOSUSPEND_TIMEOUT		200
 
-#define ORION_NUM_CHIPSELECTS		1 /* only one slave is supported*/
 #define ORION_SPI_WAIT_RDY_MAX_LOOP	2000 /* in usec */
 
 #define ORION_SPI_IF_CTRL_REG		0x00
@@ -44,6 +43,10 @@ 
 #define ARMADA_SPI_CLK_PRESCALE_MASK	0xDF
 #define ORION_SPI_MODE_MASK		(ORION_SPI_MODE_CPOL | \
 					 ORION_SPI_MODE_CPHA)
+#define ORION_SPI_CS_MASK	0x1C
+#define ORION_SPI_CS_SHIFT	2
+#define ORION_SPI_CS(cs)	((cs << ORION_SPI_CS_SHIFT) & \
+					ORION_SPI_CS_MASK)
 
 enum orion_spi_type {
 	ORION_SPI,
@@ -221,6 +224,10 @@  static void orion_spi_set_cs(struct spi_device *spi, bool enable)
 
 	orion_spi = spi_master_get_devdata(spi->master);
 
+	orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
+	orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
+				ORION_SPI_CS(spi->chip_select));
+
 	/* Chip select logic is inverted from spi_set_cs */
 	if (!enable)
 		orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
@@ -406,17 +413,23 @@  static int orion_spi_probe(struct platform_device *pdev)
 		master->bus_num = pdev->id;
 	if (pdev->dev.of_node) {
 		u32 cell_index;
+		u32 num_cs;
 
 		if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
 					  &cell_index))
 			master->bus_num = cell_index;
+
+		if (!of_property_read_u32(pdev->dev.of_node, "num_cs",
+					  &num_cs))
+			master->num_chipselect = num_cs;
+		else
+			master->num_chipselect = 1;
 	}
 
 	/* we support only mode 0, and no options */
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 	master->set_cs = orion_spi_set_cs;
 	master->transfer_one = orion_spi_transfer_one;
-	master->num_chipselect = ORION_NUM_CHIPSELECTS;
 	master->setup = orion_spi_setup;
 	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 	master->auto_runtime_pm = true;