spi: mxc: fix sf probe when using mxc_spi
authorNikita Kiryanov <nikita@compulab.co.il>
Wed, 20 Aug 2014 12:08:50 +0000 (15:08 +0300)
committerJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Wed, 24 Sep 2014 11:55:39 +0000 (17:25 +0530)
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: Eric Nelson <eric.nelson@boundarydevices.com>
Cc: Eric Benard <eric@eukrea.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Tim Harvey <tharvey@gateworks.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Tom Rini <trini@ti.com>
Cc: Marek Vasut <marex@denx.de>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
16 files changed:
board/boundary/nitrogen6x/nitrogen6x.c
board/embest/mx6boards/mx6boards.c
board/freescale/mx6qsabreauto/mx6qsabreauto.c
board/freescale/mx6sabresd/mx6sabresd.c
board/freescale/mx6slevk/mx6slevk.c
board/gateworks/gw_ventana/gw_ventana.c
board/genesi/mx51_efikamx/efikamx.c
board/ttcontrol/vision2/vision2.c
drivers/spi/mxc_spi.c
include/configs/embestmx6boards.h
include/configs/gw_ventana.h
include/configs/mx51_efikamx.h
include/configs/mx6sabre_common.h
include/configs/mx6slevk.h
include/configs/nitrogen6x.h
include/configs/vision2.h

index 60a09f4bb3e85cb7833c2900ecc1f53aab79c7c7..7edfe19367521dcee2d3a56f9d953fa5790d33ed 100644 (file)
@@ -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),
index 530ea4f3c48d6205916977856d5f7f95f1be77f6..a725f15a2eb8172b540aac191b4b38ca6d1626df 100644 (file)
@@ -285,6 +285,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));
index 928dadf80936b7fa179e7b99bd536bdf836eeb9b..836d7221b09c7388764dd57f9ced8efd97632d0d 100644 (file)
@@ -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 */
index 80c8ebdafcc39da661abaf0833ad11e70ce04ee9..81dcd6e5ddb879ae3aa4ed9e8a0e800b63929459 100644 (file)
@@ -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 */
index a990b4cea8ee744abafa7cade88bfb1725402472..a0832f4a201e63ce6e8ec99b4d87b99667b2e1dd 100644 (file)
@@ -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));
index 8d086f84abea5381b185d70558de0cc633b3d82f..1038d9d975a4347e8e48a575fc06f96f2919d800 100644 (file)
@@ -356,9 +356,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
index 16769e53327edf187cfced3c397d8a9b9e7243d0..137e4ed661030b9ede7f194f2f7f865429ebce1d 100644 (file)
@@ -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;
index b4d3994158da0d6417e211273ad62ce3cea1c5b9..b5249e74a779a3a1b1f16a9be3a5c9a9c5c32521 100644 (file)
@@ -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[] = {
index 2d5f3850da8e95b41f7bcbfb227eb9958c8d15c6..026f680d80d90e60591d04bb3b092058df371883 100644 (file)
@@ -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
@@ -371,31 +376,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,
@@ -415,14 +419,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);
index a7fd43bc7b8e56a8a8b0c1257a5dc69b1b57858d..185edbe7fea538995c92c090f7bd4af07860fcc3 100644 (file)
 #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
index 0e5c20097d1cfd0781e68d2883fcac031921664b..620f9501d255741c921d699713fd779a3e9b4774 100644 (file)
@@ -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)
index 0f2a4ef973fee989c50f4ff1249028e4d31a9f61..fce7ead977a5caebb7c09a098b116a1d66358241 100644 (file)
 
 #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)
index e59a3b4b058768d1f641ba4e73f2f85a9e26c575..2d93d6c70076fb2a18423773192afa68936084bc 100644 (file)
@@ -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
index 194d7bdb76e3b22935f13cf1bf8068819b243d69..4208ba156331b51219484886f93d2dac8bfeeac5 100644 (file)
 #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
index d4b0ac9fdb189150aa42d6c37aa0c3d47502eaeb..39d5bb34bb2995928a5bb686028c3d183218b812 100644 (file)
@@ -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
index 6891bf8b153b2da04aac092532aeaf10d9b76409..3f35076f9e6cfc677649b316a1314732492001a7 100644 (file)
  * 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