This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Getting spidev going

Other Parts Discussed in Thread: AM1808, OMAP-L138, TMS320C6748

Davinci, linux-03.20.00.13, Logic AM1808 EVM board. Code Sourcery Lite.

I want to send / recieve data from the SPI.  spidev seems to be the way to get this to happen easily.  On Spi1, I want to use chip select 1, since chip select 0 selects the flash/eeprom memory.  There's several partial threads on this subject, but not quite this.  Read spi-summary.txt, but even confused the situation even more.

 

board-da850-evm.c:

static struct spi_board_info da850_spi_board_info[] = {
    [0] = {
        .modalias = "m25p80",
        .platform_data = &spi_flash_data,
        .mode = SPI_MODE_0,
        .max_speed_hz = 30000000,       /* max sample rate at 3V */
        .bus_num = 1,
        .chip_select = 0,
    },
    [1] = {
        .modalias = "spidev",
        //#.platform_data = &spi_flash_data,
        .mode = SPI_MODE_0,
        .max_speed_hz = 30000000,       /* max sample rate at 3V */
        .bus_num = 1,
        .chip_select = 1,
    },

};

Also:

    da850_init_spi1(BIT(0), da850_spi_board_info,
            ARRAY_SIZE(da850_spi_board_info));
    da850_init_spi1(BIT(1), da850_spi_board_info,
            ARRAY_SIZE(da850_spi_board_info));

device-da8xx.c

static struct platform_device da850_spi1_device = {
    .name = "spi_davinci",
    .id = 1,
    .resource = da850_spi1_resources,
    .num_resources = ARRAY_SIZE(da850_spi1_resources),
    .dev = {
        .platform_data = &da850_spi1_pdata,
    },
};

static struct platform_device da850_spi11_device = {
    .name = "spidev",
    .id = 32,
    .resource = da850_spi1_resources,
    .num_resources = ARRAY_SIZE(da850_spi1_resources),
    .dev = {
        .platform_data = &da850_spi11_pdata,
    },
};

void __init da850_init_spi1(unsigned chipselect_mask,
        struct spi_board_info *info, unsigned len)
{
    spi_register_board_info(info, len);

    platform_device_register(&da850_spi1_device);
    platform_device_register(&da850_spi11_device);
}


recompiled the uImage and copied it up.  spidev is a selected to load, not as a .ko module.

make uImage ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
make modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
make modules_install INSTALL_MOD_PATH=/home/wtpatrick/Work/am1808/boot_fs ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

be careful, you have to manually delete the device-da8xx.o file and the board-da850-evm.o file, because the make file doesn't seem to check.

 

I'm getting part way there now,

in /sys/bus/spi/drivers I see spidev and m25p80

in /sys/class I see spidev

in /sys/devices/platform I see spidev.32

I don't see anything in /dev so I typed: mknod -m 666 /dev/spi c 153 32

now I see /dev/spi.  (maybe that's the source of the spidev.32 above ?)

But, when I ./echo "hello" > /dev/spi  I don't see anything on any of the SPI lines. 

Ideas?

  • So, I know platform_device_register() is being called, and spidev_init() is being called.

    root@arago:/sys# ls -R | grep spi
    spi
    spidev.32
    ./bus/spi:
    ./bus/spi/devices:
    ./bus/spi/drivers:
    spidev
    ./bus/spi/drivers/m25p80:
    ./bus/spi/drivers/spidev:
    spi_master
    spidev
    ./class/spi_master:
    ./class/spidev:
    spidev.32
    ./devices/platform/spidev.32:
    ./devices/platform/spidev.32/power:
    spidev
    ./module/spidev:
    ./module/spidev/parameters:

    And, I can control the spidev.32, to be whatever number I want it to be.

    But, spidev_probe() is never getting called.

    What does it take to get udev to call spidev_probe().  And, how can I dump a list of platform devices, that udev has access too??????

  • Wade Patrick,

    Could you point me to URL of the source files you are referring to?

    Also, I'm assuming that you enabled "User Mode SPI device driver support" during menuconfig.

     

    Regards

    Mansoor

     

  • Hi Wade Patrick,

    Please find the attached patch for enabling spidev device node interface. Please discard all your changes, there is no need to add new platform device. The attached patch is based DaVinci-PSP-SDK-03.20.00.13 release and make sure to enable "User Mode SPI device driver support" in menuconfig as mentioned by Mansoor.

    Regards,

    Prakash

  • So basically, up the number of chip selects to 2, enter the board_info for spidev, and disable DMA.  All using the patch.  Verified SPI "User Mode SPI device driver support" was selected. Rebuilt with "make uImage ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-"  and rebooted.

     

    Did all of that, and /dev doesn't have any SPIDEV?.? entries.   I can see spidev in the /sys files.   Am I missing a mknod, or is there anyway udev's rules need manually configuring?

  • I, too, and trying to puzzle out the same problem.  I'm trying to add another SPI flash (32Mbit S25FL032P) to SPI1 using SCS1.

    I've pretty much gone through the same procedure as you. Mine isn't working quite yet either, but here's what I've done.

    in devices-da8xx.c:

    static struct davinci_spi_platform_data da850_spi1_pdata = {
            .version        = SPI_VERSION_2,
            .num_chipselect = 2,
            .wdelay         = 0,
            .odd_parity     = 0,
            .parity_enable  = 0,
            .wait_enable    = 0,
            .timer_disable  = 0,
            .clk_internal   = 1,
            .cs_hold        = 1,
            .intr_level     = 0,
            .poll_mode      = 1,
            .use_dma        = 1,
            .c2tdelay       = 8,
            .t2cdelay       = 8,
    };

    In board-da850-evm.c:

    static struct mtd_partition spi_flash_partitions[] = {
        [0] = {
            .name = "U-Boot",
            .offset = 0,
            .size = SZ_256K,
            .mask_flags = MTD_WRITEABLE,
        },
        [1] = {
            .name = "U-Boot Environment",
            .offset = MTDPART_OFS_APPEND,
            .size = SZ_64K,
            .mask_flags = MTD_WRITEABLE,
        },
        [2] = {
            .name = "Linux",
            .offset = MTDPART_OFS_NXTBLK,
            .size = SZ_8M - (SZ_256K + SZ_64K + SZ_64K),
            .mask_flags = 0,
        },
        [3] = {
            .name = "MAC Address",
            .offset = MTDPART_OFS_NXTBLK,
            .size = SZ_64K,
            .mask_flags = MTD_WRITEABLE,
            .setup = davinci_get_mac_addr,
            .context = (void *)0,
        },
    };

    static struct mtd_partition fpga_spi_flash_partitions[] = {
            [0] = {
                    .name = "spartan6 fpga prom",
                    .offset = 0,
                    .size = MTDPART_SIZ_FULL,
                    .mask_flags = 0,
            },
    };



    static struct flash_platform_data spi_flash_data = {
        .name = "m25p80",
        .parts = spi_flash_partitions,
        .nr_parts = ARRAY_SIZE(spi_flash_partitions),
        .type = "m25p64",
    };

    static struct flash_platform_data fpga_spi_flash_data = {
            .name = "m25p80",
            .parts = fpga_spi_flash_partitions,
            .nr_parts = ARRAY_SIZE(fpga_spi_flash_partitions),
            .type = "s25sl032a", /* really an s25fl032p, but they're compatible */
    };


    static struct spi_board_info da850_spi_board_info[] = {
        [0] = {
            .modalias = "m25p80",
            .platform_data = &spi_flash_data,
            .mode = SPI_MODE_0,
            .max_speed_hz = 30000000,       /* max sample rate at 3V */
            .bus_num = 1,
            .chip_select = 0,
        },
        [1] = {
            .modalias = "m25p80",
                    .platform_data = &fpga_spi_flash_data,
                    .mode = SPI_MODE_0,
                    .max_speed_hz = 30000000,       /* max sample rate at 3V */
                    .bus_num = 1,
                    .chip_select = 1,
            },

    };

    I also think you have add SCS1 to be initialized in the pin mux.

    In arch/arm/mach-davinci/include/mach/mux.h

    enum davinci_da850_index {
        /* UART0 function */
        DA850_NUART0_CTS,
        DA850_NUART0_RTS,
        DA850_UART0_RXD,
        DA850_UART0_TXD,

    ...
    ...

        /* SPI1 CS for FPGA prom */
        DA850_SPI1_CS_1,

    };

     

    in arch/arm/mach-davinci/da850.c:

    static const struct mux_config da850_pins[] = {
    #ifdef CONFIG_DAVINCI_MUX
        /* UART0 function */
        MUX_CFG(DA850, NUART0_CTS,    3,    24,    15,    2,    false)
        MUX_CFG(DA850, NUART0_RTS,    3,    28,    15,    2,    false)
        MUX_CFG(DA850, UART0_RXD,    3,    16,    15,    2,    false)
        MUX_CFG(DA850, UART0_TXD,    3,    20,    15,    2,    false)

    ...
    ...

        MUX_CFG(DA850, SPI1_CS_1,     5,    0,    15,    1,    false)
    #endif
    };

    that way, when you put the SCS1 into the da850_spi1_pins[] array, you have the configuration already defined:

    const short da850_spi1_pins[] __initdata = {
        DA850_SPI1_CS_0, DA850_SPI1_CS_1, DA850_SPI1_CLK, DA850_SPI1_SOMI, DA850_SPI1_SIMO,
        -1
    };

     

     

  • I don't think the call da850_init_spi1() cares about the first value (chipselect_mask).  It doesn't seem to do anything with it.

    in devices-da8xx.c:

    void __init da850_init_spi1(unsigned chipselect_mask,
                    struct spi_board_info *info, unsigned len)
    {
            spi_register_board_info(info, len);

            platform_device_register(&da850_spi1_device);
    }

    So, your call to it:

        da850_init_spi1(BIT(1), da850_spi_board_info,
                ARRAY_SIZE(da850_spi_board_info));

    Just calls the function a second time.

  • I could able to see device node(/dev/spidev1.1). Could you please give try with attached uImage and file system arago-demo-image-glibc-ipk-2009.11-da850-omapl138-evm.rootfs.tar.gz from below link:

    http://www.arago-project.org/files/releases/2009.11/images/da850-omapl138-evm/

    With regards,

    Prakash

    uImage.tar.gz
  • Prakash,

    I was able to use your kernel and fs and see spidev1.1.  Thanks.

    Any reason why user mode driver has to be selected and DMA disabled?

    Any idea on how one might add extra spi flashes to spi1 and use them as mtd devices?

    John

  • I was able to make this work by turning off the dma. 

    static struct davinci_spi_platform_data da850_spi1_pdata = {
        .version     = SPI_VERSION_2,
        .num_chipselect = 2,
        .wdelay        = 0,
        .odd_parity    = 0,
        .parity_enable    = 0,
        .wait_enable    = 0,
        .timer_disable  = 0,
        .clk_internal    = 1,
        .cs_hold    = 1,
        .intr_level    = 0,
        .poll_mode    = 1,
        .use_dma    = 0,
        .c2tdelay    = 8,
        .t2cdelay    = 8,
    };

    I can now see both SPI flash devices and the MTD layer creates a partition for the second device.

    Now, I'm not sure I'm reading the data correctly from the second device yet.

     

  • FYI - This procedure did work.  I can now read and write to the additional SPI flash on SPI1.

  • User mode driver is the one which gives the character driver interface for accessing SPI devices from userspace IO calls.

    You can enable DMA by allocating separate DMA resource for each device. Otherwise second device registration will fail since DMA resource is allocated for first device

    Regards,

    Prakash

  •  

    I am attempting to have another device connected to SPI1, the same that is communicating with the SPI flash on evm OMAP-L138.

    I made this steps :

    1. Enable User Mode SPI devices on kernel configuration
    2. Apply patch EnableSpidev
    3. Change configuration of pin mux to enable SPI1_CS_1
    4. compile ...
    5. verify value of register pinmux5: 0x80110111
    6. cat /dev/mtdblock3  | hexdump -> prints the mac address, a lot of FF and
    I see the lines with a osciloscope change 0<->1
    7. echo "hello" > /dev/spidev1.1 -> nothing happens on oscilocospe :-/
    8. the execution of spidev_test -D /dev/spidev1.1 -s 30000000 returns FF

    Can anyone point me what I am doing wrong ?

    Not so related with precious issues on this topic, how I can put a GPIO controlling the chip select ?

     

  • I am trying also trying to enable spidev on a DM365 EVM rev f board using MV5 PSP 2-10_00-14and Kernel ver 2.6.18_pro

    I have applied all the patches (that apply) and followed the directions on this thread. I see spidev.0 under devices but I cannot see any of the SPI(1)  lines toggling on J18 using a scope when I access the spidev device.

    I am assuming that I will see this device on SPI1 since SPI 0 on my baord is connected to a nand spi device

    Has anyone gotten this running in the configuration I am using ?

    I have double checked that I have followed the instructions correctly in this thread but so far I am not having much luck

     

    thanks in advance

  • 3884.spidev_test.c

    5633.spidev.c

    Hi, I am in the same issue, the difference is that I try to solved it in a different way, in the menuconfig I select the "User Mode SPI device driver support" option but I don't chooseto iclude in de uimage, I select it to be built as module and I succes, now I have the spidev.ko, I copy that into the board, I write:

    insmod spidev.ko

    but I get the following response:

    spidev: Unknown symbol spi_register_driver (err 0)                              
    spidev: Unknown symbol spi_async (err 0)
    spidev: Unknown symbol spi_setup (err 0)
    insmod: error inserting 'spidev.ko': -1 Unknown symbol in module

    And I don't get it, What can I do? How can I change the code in order to make it work? (I am using the Omap-l138/tms320c6748 evm).

    And other thing is that in the documentacion the spidev_test.c opens the /dev/spidev1.1, so I thing that I should change it to "/dev/spidev" to make it work.