hi
Board: i.mx28 kernel: 2.6.35.3-571
I have compiled these two modules as a part of the kernel
if i use this command
cat /sys/bus/spi/devices/spi1.0/modalias the answer is m25p80 (An SPI flash)
if i use this command cat /proc/devices
i see the major number is 153
and i use mknod /dev/spidev1.1 c 153 0
and try to run spidev_fdx it's fail to open the device
can't open '/dev/spidev1.1': No such device or address
My question is how can i access the device using spidev interface ?
已解决! 转到解答。
I don't think you can use SPI-ROM driver and User mode SPI driver simultaneously.
SPI device is bind with SPI driver in linux-2.6.35.3/arch/arm/mach-mx28/mx28evk.c.
Take a look at struct spi_board_info definition.
static struct spi_board_info spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
{
/* the modalias must be the same as spi device driver name */
.modalias = "m25p80", /* Name of spi_driver for this device */
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.bus_num = 1, /* Framework bus number */
.chip_select = 0, /* Framework chip select. */
.platform_data = &mx28_spi_flash_data,
},
#endif
};
The "bus_num" defines which SPI device (in this case spidev.1) and "modalias" defines what driver is linked with this particular SPI device (in this case SPI ROM driver m25p80, which is defined in
linux-2.6.35.3/drivers/mtd/devices/m25p80.c.
In order to use the user-mode SPI driver, you must bind modalias "spidev" with the SPI device you want to use.
Change the definition of static struct spi_board_info as below then rebuild the Kernel. It will enable you to open /dev/spidev device, which is now bind with the SPI device.
.modalias = "spidev", /* Name of spi_driver for this device */
Note that If your Linux system must NOT boot from the SPI ROM.
I don't think you can use SPI-ROM driver and User mode SPI driver simultaneously.
SPI device is bind with SPI driver in linux-2.6.35.3/arch/arm/mach-mx28/mx28evk.c.
Take a look at struct spi_board_info definition.
static struct spi_board_info spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
{
/* the modalias must be the same as spi device driver name */
.modalias = "m25p80", /* Name of spi_driver for this device */
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.bus_num = 1, /* Framework bus number */
.chip_select = 0, /* Framework chip select. */
.platform_data = &mx28_spi_flash_data,
},
#endif
};
The "bus_num" defines which SPI device (in this case spidev.1) and "modalias" defines what driver is linked with this particular SPI device (in this case SPI ROM driver m25p80, which is defined in
linux-2.6.35.3/drivers/mtd/devices/m25p80.c.
In order to use the user-mode SPI driver, you must bind modalias "spidev" with the SPI device you want to use.
Change the definition of static struct spi_board_info as below then rebuild the Kernel. It will enable you to open /dev/spidev device, which is now bind with the SPI device.
.modalias = "spidev", /* Name of spi_driver for this device */
Note that If your Linux system must NOT boot from the SPI ROM.
Why can't I use m25p80 and spidev simultaneously?
If each one of them is in separate bus (SSP2 and SSP3), for example?
static struct spi_board_info spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
{
/* the modalias must be the same as spi device driver name */
.modalias = "m25p80", /* Name of spi_driver for this device */
.max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
.bus_num = 1, /* Framework bus number */
.chip_select = 0, /* Framework chip select. */
.platform_data = &mx28_spi_flash_data,
},
#endif
{
.modalias = "spidev",
.max_speed_hz = 20000000,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
},
};
static struct mxs_spi_platform_data spi1_data = {
.clk = "ssp.3",
.slave_mode = 0,
};
static struct resource ssp3_resources[] = {
{
.start = SSP3_PHYS_ADDR,
.end = SSP3_PHYS_ADDR + 0x2000 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = MXS_DMA_CHANNEL_AHB_APBH_SSP3,
.end = MXS_DMA_CHANNEL_AHB_APBH_SSP3,
.flags = IORESOURCE_DMA,
}, {
.start = IRQ_SSP3_DMA,
.end = IRQ_SSP3_DMA,
.flags = IORESOURCE_IRQ,
}, {
.start = IRQ_SSP3,
.end = IRQ_SSP3,
.flags = IORESOURCE_IRQ,
},
};
static void __init mx28_init_spi1(void)
{
struct platform_device *pdev;
pdev = mxs_get_device("mxs-spi", 1);
if (pdev == NULL || IS_ERR(pdev))
return;
pdev->resource = ssp3_resources;
pdev->num_resources = ARRAY_SIZE(ssp3_resources);
pdev->dev.platform_data = &spi1_data;
mxs_add_device(pdev, 3);
}
#if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
static struct pin_desc mx28evk_spi_pins[] = {
{
.name = "SSP2 MOSI",
.id = PINID_SSP2_MOSI,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP2 MISO",
.id = PINID_SSP2_MISO,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP2 SCK",
.id = PINID_SSP2_SCK,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP2 SS0",
.id = PINID_SSP2_SS0,
.fun = PIN_FUN1,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP3 MOSI",
.id = PINID_SSP3_MOSI,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP3 MISO",
.id = PINID_SSP3_MISO,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP3 SCK",
.id = PINID_SSP3_SCK,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP3 SS0",
.id = PINID_SSP3_SS0,
.fun = PIN_FUN1,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.drive = 1,
},
};
#endif
But still SPIDEV won't create the device driver...
The m25p80 is working fine though...
Thanks a lot for anyone's help with this.....