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.

OMAP-L137, can't send data via spidev.

Other Parts Discussed in Thread: OMAP-L137, DA8XX

Hello, I am trying to send data via spidev in Linux with kernel 4.4.8.

I've added support of spi in menuconfig (support of userspace operations and support of TI spi devices).

Also, I changed board-da-830-evm.c file:

static struct spi_board_info da830evm_spi_info[] = {
	[0] = {
		.modalias		= "m25p80",
		.platform_data		= &da830evm_spiflash_data,
		.controller_data	= &da830evm_spiflash_cfg,
		.mode			= SPI_MODE_0,
		.max_speed_hz		= 30000000,
		.bus_num		= 0,
		.chip_select		= 0,
	},
	[1] = {
		.modalias		= "spidev",
		.mode			= SPI_MODE_0 | SPI_NO_CS,	
		.controller_data	= &da830evm_spi1_cfg,
		.max_speed_hz		= 100000,
		.bus_num		= 1,
		.chip_select		= 0,
	},
};

...

    ret = davinci_cfg_reg_list(da830_spi1_pins);
    if (ret)
        pr_warn("%s: spi1 setup failed: %d\n", __func__, ret);    

    if (ret)
        pr_warn("%s: spi info registration failed: %d\n",
            __func__, ret);    

    ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info));
    if (ret)
        pr_warn("%s: spi 0 registration failed: %d\n", __func__, ret);

        
    ret = da8xx_register_spi_bus(1, 0);//ARRAY_SIZE(da830evm_spi_info));
    if (ret)
        pr_warn("%s: spi 1 registration failed: %d\n", __func__, ret);
    
        
    ret = spi_register_board_info(da830evm_spi_info,
                      ARRAY_SIZE(da830evm_spi_info));

And now I have spidev1.0 in /dev/ folder.

But I can't send data through it:

$ echo -ne test > /dev/spidev1.0 

spidev spi1.0: SPI transfer failed: -22
spi_master spi1: failed to transfer one message from queue
sh: write error: Invalid argument

And I can see, that the error happens  in file spi.c in the command:


            ret = master->transfer_one(master, msg->spi, xfer);

So, now I am trying to find transfer_one implementation for omap-l137, but I can't.

Can you help me with this problem?

  • Dear Denis,
    Have you tried with our latest SDK linux kernel version 3.3 ?
    I don't think it won't be kernel version issue but worth to try with latest SDK and EVM board and it would help us to identify the problem.

    linux/Documentation/spi/spidev_test.c
    arm-arago-linux-gnueabihf-gcc -o spidev_test spidev_test.c
    ./spidev_test -D /dev/spidev1.0

    Refer to the following TI e2e post.
    e2e.ti.com/.../1255212
  • I can't compile now kernel 3.3, but I found that when I do:
    spidev_test.o -D /dev/spidev1.0
    I have an error:
    can't set spi mode: Inappropriate ioctl for device
    Aborted

  • spidev_test.o -D /dev/spidev1.0
    I have an error:
    can't set spi mode: Inappropriate ioctl for device

    Can you please try to modify 'bits' 8 to 16 in "spidev_test.c" file then try ?


    I can't compile now kernel 3.3, but I found that when I do:

    What problem you are getting while building the kernel ?
  • During a compilation of linux 3.3 I have an error:
    In file included from include/linux/compiler.h:48:0,
    from include/linux/stddef.h:4,
    from include/linux/posix_types.h:4,
    from include/linux/types.h:17,
    from include/linux/page-flags.h:8,
    from kernel/bounds.c:9:
    include/linux/compiler-gcc.h:99:30: fatal error: linux/compiler-gcc5.h: No such file or directory.

    With other older compilers I have another errors.


    I've changed 'bits' in spidev_test.c, now I have the same mistake which I had in shell:
    / # /bin/spidev_test.o -N -D /dev/spidev1.0
    spi mode: 0x40

    bits per word: 16
    max speed: spidev spi1.0: SPI transfer failed: -22
    500000 Hz (500 KHz)
    spi_master spi1: failed to transfer one message from queue
    can't send spi message: Invalid argument
    Aborted

  • During a compilation of linux 3.3 I have an error:
    In file included from include/linux/compiler.h:48:0,
    from include/linux/stddef.h:4,
    from include/linux/posix_types.h:4,
    from include/linux/types.h:17,
    from include/linux/page-flags.h:8,
    from kernel/bounds.c:9:
    include/linux/compiler-gcc.h:99:30: fatal error: linux/compiler-gcc5.h: No such file or directory.

    With other older compilers I have another errors.

    What are the commands you were used and what document you referred and kernel version etc., ?


    I've changed 'bits' in spidev_test.c, now I have the same mistake which I had in shell:
    / # /bin/spidev_test.o -N -D /dev/spidev1.0
    spi mode: 0x40

    bits per word: 16
    max speed: spidev spi1.0: SPI transfer failed: -22
    500000 Hz (500 KHz)
    spi_master spi1: failed to transfer one message from queue
    can't send spi message: Invalid argument
    Aborted

    What board are you using ?
    OMAPL137 SDI EVM board or custom board ?

    In DA830/OMAPL137 EVM board uses the SPI0 for SPI flash for booting purpose, so you can use SPI1 for SPIDEV testing.

    Try to modify the board file like below.

    static struct spi_board_info da830evm_spi1_info[] = {
    {
    .modalias = "spidev",
    .max_speed_hz = 2500000,
    .bus_num = 1,
    .chip_select = 2,
    .mode = SPI_MODE_1,
    },
    };

    ret = da8xx_register_spi(1, da830evm_spi1_info,
    ARRAY_SIZE(da830evm_spi1_info));
  • Please refer to the following e2e post.
    e2e.ti.com/.../1408097
  • I use vanilla Linux kernel v4.4.8.

    I made makeconfig omap_all_defconfig and added spi userspace support.

    I compiled it with a custom toolchain (gcc 5.1.0) and it seems that all works(uart0,2), except of spi1.

    I use SD OMAP-L137 EVM board.


    static struct spi_board_info da830evm_spi1_info[] = {
    {
    .modalias = "spidev",
    .max_speed_hz = 2500000,
    .bus_num = 1,
    .chip_select = 2,
    .mode = SPI_MODE_1,
    },
    };

    ret = da8xx_register_spi(1, da830evm_spi1_info,
    ARRAY_SIZE(da830evm_spi1_info));

    Yes, I've tried it in this way, but it didn't work either. Spidev just didn't appear in /dev/ directory (probe function wasn't called).

    Also, in modern linux kernels there is no such a function da8xx_register_spi, instead of it, there is a da8xx_register_spi_bus.

  • Again, I can't find an implementation for a transfer_one function.

    For example, in spi-omap2-mcspi.c there is a code:

    	/* the spi->mode bits understood by this driver: */
    	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
    	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
    	master->setup = omap2_mcspi_setup;
    	master->auto_runtime_pm = true;
    	master->prepare_message = omap2_mcspi_prepare_message;
    	master->transfer_one = omap2_mcspi_transfer_one;
    	master->set_cs = omap2_mcspi_set_cs;
    	master->cleanup = omap2_mcspi_cleanup;
    	master->dev.of_node = node;
    	master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
    	master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
    
    	platform_set_drvdata(pdev, master);
    

    but in spi-davinci.c:

    	master->dev.of_node = pdev->dev.of_node;
    	master->bus_num = pdev->id;
    	master->num_chipselect = pdata->num_chipselect;
    	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
    	master->setup = davinci_spi_setup;
    	master->cleanup = davinci_spi_cleanup;
    

    So, there is no setting for master->transfer_one (I can't find it), at the same time a default implementation of transfer_one_message is used (it means that implementation of transfer_one should_be provided). Am I wrong? What should I do to make spidev work?

  • If you are newer kernel version, then you may need to use device tree source file to enable spidev support.