Hi,
We are currently trying to enable the spidev driver for the 5 SPI interfaces on the MX6 nitrogen board under Linux. For now, I was having some problem adding SPI 2-5 into my configuration.
We are using Yocto with the kernel 3.0.35.
I enable the user mode interface in “menuconfig” and modify the following file
static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {
#if defined(CONFIG_MTD_M25P80)
{
.modalias = "spidev",
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
.chip_select = 0,
.platform_data = &imx6_sabrelite__spi_flash_data,
},
#endif
};
Just by changing the driver name to spidev, I can boot and see the spidev interface under /dev/.
I tried to add the pads for the ecspi2 interface and modify the bus_num to 1 to try to access the second SPI. After a couple of days with multiple attempts, I was still not able to get the spidev1.0 interface.
I was hoping someone can point us to some good documentation regarding the modifications required to enable the other SPI interfaces (2 to 5) under linux for the mx6.
Let me know if you need anything else in order to assist.
Best regards
Patrice
Solved! Go to Solution.
Hi,
I was finally able to figure out how to make this thing work. For others that could have the same problem, here is the code of the patch I made.
Index: git/arch/arm/mach-mx6/board-mx6q_sabrelite.c
===================================================================
--- git.orig/arch/arm/mach-mx6/board-mx6q_sabrelite.c 2012-12-19 11:40:56.461028612 -0500
+++ git/arch/arm/mach-mx6/board-mx6q_sabrelite.c 2012-12-19 15:06:35.913464999 -0500
@@ -79,6 +79,8 @@
#define MX6Q_SABRELITE_SD4_CD IMX_GPIO_NR(2, 6)
#define MX6Q_SABRELITE_SD4_WP IMX_GPIO_NR(2, 7)
#define MX6Q_SABRELITE_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6Q_SABRELITE_ECSPI2_CS0 IMX_GPIO_NR(5, 12)
+#define MX6Q_SABRELITE_ECSPI3_CS0 IMX_GPIO_NR(4, 24)
#define MX6Q_SABRELITE_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define MX6Q_SABRELITE_CAP_TCH_INT1 IMX_GPIO_NR(1, 9)
#define MX6Q_SABRELITE_USB_HUB_RESET IMX_GPIO_NR(7, 12)
@@ -132,6 +134,18 @@
MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+ /* ECSPI2 */
+ MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO,
+ MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI,
+ MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK,
+ MX6Q_PAD_DISP0_DAT18__GPIO_5_12, /*SS0*/
+
+ /* ECSPI3 */
+ MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO,
+ MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI,
+ MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK,
+ MX6Q_PAD_DISP0_DAT3__GPIO_4_24, /*SS0*/
+
/* ENET */
MX6Q_PAD_ENET_MDIO__ENET_MDIO,
MX6Q_PAD_ENET_MDC__ENET_MDC,
@@ -221,12 +235,12 @@
#endif
/* DISPLAY */
- MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+/* MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
- MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
- MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
- MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
- MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+/* MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
+/* MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
+/* MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
+/* MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
@@ -251,8 +265,8 @@
MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
MX6Q_PAD_GPIO_7__GPIO_1_7, /* J7 - Display Connector GP */
- MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
- MX6Q_PAD_NANDF_D0__GPIO_2_0, /* J6 - LVDS Display contrast */
+/* MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
+/* MX6Q_PAD_NANDF_D0__GPIO_2_0, /* J6 - LVDS Display contrast */
/* PWM1 */
@@ -469,13 +483,22 @@
.phy = PHY_INTERFACE_MODE_RGMII,
};
-static int mx6q_sabrelite_spi_cs[] = {
- MX6Q_SABRELITE_ECSPI1_CS1,
+static int mx6q_sabrelite_spi_cs2[] = {
+ MX6Q_SABRELITE_ECSPI2_CS0,
+};
+
+static const struct spi_imx_master mx6q_sabrelite_spi_data2 __initconst = {
+ .chipselect = mx6q_sabrelite_spi_cs2,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs2),
};
-static const struct spi_imx_master mx6q_sabrelite_spi_data __initconst = {
- .chipselect = mx6q_sabrelite_spi_cs,
- .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs),
+static int mx6q_sabrelite_spi_cs3[] = {
+ MX6Q_SABRELITE_ECSPI3_CS0,
+};
+
+static const struct spi_imx_master mx6q_sabrelite_spi_data3 __initconst = {
+ .chipselect = mx6q_sabrelite_spi_cs3,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs3),
};
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -489,7 +512,7 @@
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
- },
+ },
};
static struct flash_platform_data imx6_sabrelite__spi_flash_data = {
@@ -503,11 +526,20 @@
static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {
#if defined(CONFIG_MTD_M25P80)
{
- .modalias = "m25p80",
+ .modalias = "spidev",
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
+ .bus_num = 1,
.chip_select = 0,
- .platform_data = &imx6_sabrelite__spi_flash_data,
+ .mode = SPI_MODE_0,
+ /*.platform_data = &imx6_sabrelite__spi_flash_data,*/
+ },
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ /*.platform_data = &imx6_sabrelite__spi_flash_data,*/
},
#endif
};
@@ -1144,12 +1176,12 @@
mx6q_sabrelite_init_uart();
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
- imx6q_add_ipuv3(0, &ipu_data[0]);
+ /*imx6q_add_ipuv3(0, &ipu_data[0]);
imx6q_add_ipuv3(1, &ipu_data[1]);
for (i = 0; i < ARRAY_SIZE(sabrelite_fb_data); i++)
imx6q_add_ipuv3fb(i, &sabrelite_fb_data[i]);
-
+*/
imx6q_add_vdoa();
imx6q_add_lcdif(&lcdif_data);
imx6q_add_ldb(&ldb_data);
@@ -1172,7 +1204,8 @@
ARRAY_SIZE(mxc_i2c2_board_info));
/* SPI */
- imx6q_add_ecspi(0, &mx6q_sabrelite_spi_data);
+ imx6q_add_ecspi(1, &mx6q_sabrelite_spi_data2);
+ imx6q_add_ecspi(2, &mx6q_sabrelite_spi_data3);
spi_device_init();
imx6q_add_mxc_hdmi(&hdmi_data);
Hi,
I was finally able to figure out how to make this thing work. For others that could have the same problem, here is the code of the patch I made.
Index: git/arch/arm/mach-mx6/board-mx6q_sabrelite.c
===================================================================
--- git.orig/arch/arm/mach-mx6/board-mx6q_sabrelite.c 2012-12-19 11:40:56.461028612 -0500
+++ git/arch/arm/mach-mx6/board-mx6q_sabrelite.c 2012-12-19 15:06:35.913464999 -0500
@@ -79,6 +79,8 @@
#define MX6Q_SABRELITE_SD4_CD IMX_GPIO_NR(2, 6)
#define MX6Q_SABRELITE_SD4_WP IMX_GPIO_NR(2, 7)
#define MX6Q_SABRELITE_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6Q_SABRELITE_ECSPI2_CS0 IMX_GPIO_NR(5, 12)
+#define MX6Q_SABRELITE_ECSPI3_CS0 IMX_GPIO_NR(4, 24)
#define MX6Q_SABRELITE_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define MX6Q_SABRELITE_CAP_TCH_INT1 IMX_GPIO_NR(1, 9)
#define MX6Q_SABRELITE_USB_HUB_RESET IMX_GPIO_NR(7, 12)
@@ -132,6 +134,18 @@
MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+ /* ECSPI2 */
+ MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO,
+ MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI,
+ MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK,
+ MX6Q_PAD_DISP0_DAT18__GPIO_5_12, /*SS0*/
+
+ /* ECSPI3 */
+ MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO,
+ MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI,
+ MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK,
+ MX6Q_PAD_DISP0_DAT3__GPIO_4_24, /*SS0*/
+
/* ENET */
MX6Q_PAD_ENET_MDIO__ENET_MDIO,
MX6Q_PAD_ENET_MDC__ENET_MDC,
@@ -221,12 +235,12 @@
#endif
/* DISPLAY */
- MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+/* MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
- MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
- MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
- MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
- MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+/* MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
+/* MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
+/* MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
+/* MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
@@ -251,8 +265,8 @@
MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
MX6Q_PAD_GPIO_7__GPIO_1_7, /* J7 - Display Connector GP */
- MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
- MX6Q_PAD_NANDF_D0__GPIO_2_0, /* J6 - LVDS Display contrast */
+/* MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
+/* MX6Q_PAD_NANDF_D0__GPIO_2_0, /* J6 - LVDS Display contrast */
/* PWM1 */
@@ -469,13 +483,22 @@
.phy = PHY_INTERFACE_MODE_RGMII,
};
-static int mx6q_sabrelite_spi_cs[] = {
- MX6Q_SABRELITE_ECSPI1_CS1,
+static int mx6q_sabrelite_spi_cs2[] = {
+ MX6Q_SABRELITE_ECSPI2_CS0,
+};
+
+static const struct spi_imx_master mx6q_sabrelite_spi_data2 __initconst = {
+ .chipselect = mx6q_sabrelite_spi_cs2,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs2),
};
-static const struct spi_imx_master mx6q_sabrelite_spi_data __initconst = {
- .chipselect = mx6q_sabrelite_spi_cs,
- .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs),
+static int mx6q_sabrelite_spi_cs3[] = {
+ MX6Q_SABRELITE_ECSPI3_CS0,
+};
+
+static const struct spi_imx_master mx6q_sabrelite_spi_data3 __initconst = {
+ .chipselect = mx6q_sabrelite_spi_cs3,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs3),
};
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -489,7 +512,7 @@
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
- },
+ },
};
static struct flash_platform_data imx6_sabrelite__spi_flash_data = {
@@ -503,11 +526,20 @@
static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {
#if defined(CONFIG_MTD_M25P80)
{
- .modalias = "m25p80",
+ .modalias = "spidev",
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
+ .bus_num = 1,
.chip_select = 0,
- .platform_data = &imx6_sabrelite__spi_flash_data,
+ .mode = SPI_MODE_0,
+ /*.platform_data = &imx6_sabrelite__spi_flash_data,*/
+ },
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ /*.platform_data = &imx6_sabrelite__spi_flash_data,*/
},
#endif
};
@@ -1144,12 +1176,12 @@
mx6q_sabrelite_init_uart();
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
- imx6q_add_ipuv3(0, &ipu_data[0]);
+ /*imx6q_add_ipuv3(0, &ipu_data[0]);
imx6q_add_ipuv3(1, &ipu_data[1]);
for (i = 0; i < ARRAY_SIZE(sabrelite_fb_data); i++)
imx6q_add_ipuv3fb(i, &sabrelite_fb_data[i]);
-
+*/
imx6q_add_vdoa();
imx6q_add_lcdif(&lcdif_data);
imx6q_add_ldb(&ldb_data);
@@ -1172,7 +1204,8 @@
ARRAY_SIZE(mxc_i2c2_board_info));
/* SPI */
- imx6q_add_ecspi(0, &mx6q_sabrelite_spi_data);
+ imx6q_add_ecspi(1, &mx6q_sabrelite_spi_data2);
+ imx6q_add_ecspi(2, &mx6q_sabrelite_spi_data3);
spi_device_init();
imx6q_add_mxc_hdmi(&hdmi_data);
Hi patrice,
As my source and your base source are mismatching, can you please share the updated source code of arch/arm/mach-mx6/board-mx6q_sabrelite.c. Thanks in advance.
Regards
Arulpandiyan Vadivel
Hi Patrice.
How do you make the board-mx6q_sabrelite.c file to not me change during the compile?
I try to do some updates in this file. But after a compile I can see that the compiler has updated this file with the original file.
Regards,
Niklas
Hi Patrice.
How did you manage to get the device driver to show up in the /dev directory?
I'm using the LTIB image and I can see that the spi_imx driver has started (in /proc/iomem and /proc/interrupts), but I can't figure out how to call it?
I also tried to change the alias to spidev, but it didn't do anything.
How do I access this driver from my application code?
Thanks,
Niklas
Hi,
if you did all the configuration correctly, you should see the device appear in /dev/. It should be something like /dev/spidev0.0 or another number depending on which SPI you are trying to enable.
Also be sure you enable the option "CONFIG_SPI_SPIDEV=y" in your kernel
regards
Patrice
Hi Patrice.
Thanks for the update.
I have just switched from LTIB to YOCTO (seems like LTIB is not going to be supported any longer).
I just wanted to check which file this define should be included (to enable the option in the kernel)?
Regards,
Niklas