[U-Boot] [PATCH V2 3/9] spi: mxc: fix sf probe when using mxc_spi

Nikita Kiryanov nikita at compulab.co.il
Thu Aug 7 15:05:30 CEST 2014


MXC SPI driver has a feature whereas a GPIO line can be used to force CS high
across multiple transactions. This is set up by embedding the GPIO information
in the CS value:

cs = (cs | gpio << 8)

This merge of cs and gpio data into one value breaks the sf probe command:
if the use of gpio is required, invoking "sf probe <cs>" will not work, because
the CS argument doesn't have the GPIO information in it. Instead, the user must
use "sf probe <cs | gpio << 8>". For example, if bank 2 gpio 30 is used to force
cs high on cs 0, bus 0, then instead of typing "sf probe 0" the user now must
type "sf probe 15872".

This is inconsistent with the description of the sf probe command, and forces
the user to be aware of implementaiton details.

Fix this by introducing a new board function: board_spi_cs_gpio(), which will
accept a naked CS value, and provide the driver with the relevant GPIO, if one
is necessary.

Cc: Jagannadha Sutradharudu Teki <jagannadh.teki at gmail.com>
Cc: Eric Nelson <eric.nelson at boundarydevices.com>
Cc: Eric Benard <eric at eukrea.com>
Cc: Fabio Estevam <fabio.estevam at freescale.com>
Cc: Tim Harvey <tharvey at gateworks.com>
Cc: Stefano Babic <sbabic at denx.de>
Cc: Tom Rini <trini at ti.com>
Cc: Marek Vasut <marex at denx.de>
Signed-off-by: Nikita Kiryanov <nikita at compulab.co.il>
---
Changes in V2:
	- Rewrote commit message, renaming the patch in the process (originally
	  "sf: fix sf probe").

 board/boundary/nitrogen6x/nitrogen6x.c        |  5 +++
 board/embest/mx6boards/mx6boards.c            |  5 +++
 board/freescale/mx6qsabreauto/mx6qsabreauto.c |  7 ++++
 board/freescale/mx6sabresd/mx6sabresd.c       |  7 ++++
 board/freescale/mx6slevk/mx6slevk.c           |  5 +++
 board/gateworks/gw_ventana/gw_ventana.c       |  7 +++-
 board/genesi/mx51_efikamx/efikamx.c           |  5 +++
 board/ttcontrol/vision2/vision2.c             |  5 +++
 drivers/spi/mxc_spi.c                         | 48 ++++++++++++++-------------
 include/configs/embestmx6boards.h             |  2 +-
 include/configs/gw_ventana.h                  |  2 +-
 include/configs/mx51_efikamx.h                |  4 +--
 include/configs/mx6sabre_common.h             |  2 +-
 include/configs/mx6slevk.h                    |  2 +-
 include/configs/nitrogen6x.h                  |  2 +-
 include/configs/vision2.h                     |  4 +--
 16 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c
index 84294db..aadddb9 100644
--- a/board/boundary/nitrogen6x/nitrogen6x.c
+++ b/board/boundary/nitrogen6x/nitrogen6x.c
@@ -328,6 +328,11 @@ int board_mmc_init(bd_t *bis)
 #endif
 
 #ifdef CONFIG_MXC_SPI
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
+}
+
 iomux_v3_cfg_t const ecspi1_pads[] = {
 	/* SS1 */
 	MX6_PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(NO_PAD_CTRL),
diff --git a/board/embest/mx6boards/mx6boards.c b/board/embest/mx6boards/mx6boards.c
index d06b57d..e8a11c2 100644
--- a/board/embest/mx6boards/mx6boards.c
+++ b/board/embest/mx6boards/mx6boards.c
@@ -284,6 +284,11 @@ iomux_v3_cfg_t const ecspi1_pads[] = {
 	MX6_PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(2, 30)) : -1;
+}
+
 static void setup_spi(void)
 {
 	imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index 928dadf..836d722 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -259,6 +259,13 @@ int board_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_MXC_SPI
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
+}
+#endif
+
 #ifdef CONFIG_CMD_BMODE
 static const struct boot_mode board_boot_modes[] = {
 	/* 4 bit bus width */
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index d7c4b4f..c5f10f7 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -513,6 +513,13 @@ static int pfuze_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_MXC_SPI
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
+}
+#endif
+
 #ifdef CONFIG_CMD_BMODE
 static const struct boot_mode board_boot_modes[] = {
 	/* 4 bit bus width */
diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index d2b64cc..ec63d9e 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -82,6 +82,11 @@ static iomux_v3_cfg_t ecspi1_pads[] = {
 	MX6_PAD_ECSPI1_SS0__GPIO4_IO11  | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 11)) : -1;
+}
+
 static void setup_spi(void)
 {
 	imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 9d2651f..054f904 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -353,9 +353,14 @@ iomux_v3_cfg_t const ecspi1_pads[] = {
 	IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
 };
 
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
+}
+
 static void setup_spi(void)
 {
-	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
+	gpio_direction_output(IMX_GPIO_NR(3, 19), 1);
 	SETUP_IOMUX_PADS(ecspi1_pads);
 }
 #endif
diff --git a/board/genesi/mx51_efikamx/efikamx.c b/board/genesi/mx51_efikamx/efikamx.c
index 16769e5..137e4ed 100644
--- a/board/genesi/mx51_efikamx/efikamx.c
+++ b/board/genesi/mx51_efikamx/efikamx.c
@@ -152,6 +152,11 @@ static iomux_v3_cfg_t const efikamx_spi_pads[] = {
  * PMIC configuration
  */
 #ifdef CONFIG_MXC_SPI
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 1) ? 121 : -1;
+}
+
 static void power_init(void)
 {
 	unsigned int val;
diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c
index b4d3994..b5249e7 100644
--- a/board/ttcontrol/vision2/vision2.c
+++ b/board/ttcontrol/vision2/vision2.c
@@ -144,6 +144,11 @@ static void setup_uart(void)
 }
 
 #ifdef CONFIG_MXC_SPI
+int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return (bus == 0 && cs == 1) ? 121 : -1;
+}
+
 void spi_io_init(void)
 {
 	static const iomux_v3_cfg_t spi_pads[] = {
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index f3f029d..9583ef0 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -25,6 +25,11 @@ static unsigned long spi_bases[] = {
 	MXC_SPI_BASE_ADDRESSES
 };
 
+__weak int board_spi_cs_gpio(unsigned bus, unsigned cs)
+{
+	return -1;
+}
+
 #define OUT	MXC_GPIO_DIRECTION_OUT
 
 #define reg_read readl
@@ -358,31 +363,30 @@ void spi_init(void)
 {
 }
 
-static int decode_cs(struct mxc_spi_slave *mxcs, unsigned int cs)
+/*
+ * Some SPI devices require active chip-select over multiple
+ * transactions, we achieve this using a GPIO. Still, the SPI
+ * controller has to be configured to use one of its own chipselects.
+ * To use this feature you have to implement board_spi_cs_gpio() to assign
+ * a gpio value for each cs (-1 if cs doesn't need to use gpio).
+ * You must use some unused on this SPI controller cs between 0 and 3.
+ */
+static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
+			 unsigned int bus, unsigned int cs)
 {
 	int ret;
 
-	/*
-	 * Some SPI devices require active chip-select over multiple
-	 * transactions, we achieve this using a GPIO. Still, the SPI
-	 * controller has to be configured to use one of its own chipselects.
-	 * To use this feature you have to call spi_setup_slave() with
-	 * cs = internal_cs | (gpio << 8), and you have to use some unused
-	 * on this SPI controller cs between 0 and 3.
-	 */
-	if (cs > 3) {
-		mxcs->gpio = cs >> 8;
-		cs &= 3;
-		ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
-		if (ret) {
-			printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
-			return -EINVAL;
-		}
-	} else {
-		mxcs->gpio = -1;
+	mxcs->gpio = board_spi_cs_gpio(bus, cs);
+	if (mxcs->gpio == -1)
+		return 0;
+
+	ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
+	if (ret) {
+		printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
+		return -EINVAL;
 	}
 
-	return cs;
+	return 0;
 }
 
 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
@@ -402,14 +406,12 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 
 	mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
 
-	ret = decode_cs(mxcs, cs);
+	ret = setup_cs_gpio(mxcs, bus, cs);
 	if (ret < 0) {
 		free(mxcs);
 		return NULL;
 	}
 
-	cs = ret;
-
 	mxcs->base = spi_bases[bus];
 
 	ret = spi_cfg_mxc(mxcs, cs, max_hz, mode);
diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
index f1000f3..bcd5ea4 100644
--- a/include/configs/embestmx6boards.h
+++ b/include/configs/embestmx6boards.h
@@ -100,7 +100,7 @@
 #define CONFIG_SPI_FLASH_SST
 #define CONFIG_MXC_SPI
 #define CONFIG_SF_DEFAULT_BUS		0
-#define CONFIG_SF_DEFAULT_CS		(0 | (IMX_GPIO_NR(2, 30) << 8))
+#define CONFIG_SF_DEFAULT_CS		0
 #define CONFIG_SF_DEFAULT_SPEED		20000000
 #define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
 #endif
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
index 8197a72..97398a8 100644
--- a/include/configs/gw_ventana.h
+++ b/include/configs/gw_ventana.h
@@ -61,7 +61,7 @@
   #define CONFIG_SPI_FLASH_BAR
   #define CONFIG_SPI_FLASH_WINBOND
   #define CONFIG_SF_DEFAULT_BUS              0
-  #define CONFIG_SF_DEFAULT_CS               (0|(IMX_GPIO_NR(3, 19)<<8))
+  #define CONFIG_SF_DEFAULT_CS               0
 					     /* GPIO 3-19 (21248) */
   #define CONFIG_SF_DEFAULT_SPEED            30000000
   #define CONFIG_SF_DEFAULT_MODE             (SPI_MODE_0)
diff --git a/include/configs/mx51_efikamx.h b/include/configs/mx51_efikamx.h
index 0f2a4ef..fce7ead 100644
--- a/include/configs/mx51_efikamx.h
+++ b/include/configs/mx51_efikamx.h
@@ -96,11 +96,11 @@
 
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_SST
-#define CONFIG_SF_DEFAULT_CS		(1 | 121 << 8)
+#define CONFIG_SF_DEFAULT_CS		1
 #define CONFIG_SF_DEFAULT_MODE		(SPI_MODE_0)
 #define CONFIG_SF_DEFAULT_SPEED		25000000
 
-#define CONFIG_ENV_SPI_CS		(1 | 121 << 8)
+#define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
 #define CONFIG_ENV_SPI_BUS		0
 #define CONFIG_ENV_SPI_MAX_HZ		25000000
 #define CONFIG_ENV_SPI_MODE		(SPI_MODE_0)
diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h
index e59a3b4..2d93d6c 100644
--- a/include/configs/mx6sabre_common.h
+++ b/include/configs/mx6sabre_common.h
@@ -74,7 +74,7 @@
 #define CONFIG_SPI_FLASH_STMICRO
 #define CONFIG_MXC_SPI
 #define CONFIG_SF_DEFAULT_BUS		0
-#define CONFIG_SF_DEFAULT_CS		(0 | (IMX_GPIO_NR(4, 9) << 8))
+#define CONFIG_SF_DEFAULT_CS		0
 #define CONFIG_SF_DEFAULT_SPEED		20000000
 #define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
 #endif
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index 3d05a64..5b8309b 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -203,7 +203,7 @@
 #define CONFIG_SPI_FLASH_STMICRO
 #define CONFIG_MXC_SPI
 #define CONFIG_SF_DEFAULT_BUS		0
-#define CONFIG_SF_DEFAULT_CS		(0 | (IMX_GPIO_NR(4, 11) << 8))
+#define CONFIG_SF_DEFAULT_CS		0
 #define CONFIG_SF_DEFAULT_SPEED		20000000
 #define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
 #endif
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index b2b17ce..d266f7d 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -53,7 +53,7 @@
 #define CONFIG_SPI_FLASH_SST
 #define CONFIG_MXC_SPI
 #define CONFIG_SF_DEFAULT_BUS  0
-#define CONFIG_SF_DEFAULT_CS   (0|(IMX_GPIO_NR(3, 19)<<8))
+#define CONFIG_SF_DEFAULT_CS   0
 #define CONFIG_SF_DEFAULT_SPEED 25000000
 #define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
 #endif
diff --git a/include/configs/vision2.h b/include/configs/vision2.h
index 6891bf8..3f35076 100644
--- a/include/configs/vision2.h
+++ b/include/configs/vision2.h
@@ -57,11 +57,11 @@
  * Use gpio 4 pin 25 as chip select for SPI flash
  * This corresponds to gpio 121
  */
-#define CONFIG_SF_DEFAULT_CS	(1 | (121 << 8))
+#define CONFIG_SF_DEFAULT_CS	 1
 #define CONFIG_SF_DEFAULT_MODE   SPI_MODE_0
 #define CONFIG_SF_DEFAULT_SPEED  25000000
 
-#define CONFIG_ENV_SPI_CS	(1 | (121 << 8))
+#define CONFIG_ENV_SPI_CS	CONFIG_SF_DEFAULT_CS
 #define CONFIG_ENV_SPI_BUS      0
 #define CONFIG_ENV_SPI_MAX_HZ	25000000
 #define CONFIG_ENV_SPI_MODE	SPI_MODE_0
-- 
1.9.1



More information about the U-Boot mailing list