LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   why couldn't i access spi_read,spi_write in spidev.c?? (https://www.linuxquestions.org/questions/linux-newbie-8/why-couldnt-i-access-spi_read-spi_write-in-spidev-c-936829/)

yixiaoyang 03-28-2012 03:20 AM

why couldn't i access spi_read,spi_write in spidev.c??
 
Iam writing a driver for RF module(spi controller interface) with linux2.6.30 on my Embeded board.I modified spidev.c,add some test code (use spi_read,spi_write).then I have passed test with http://www.kernel.org/doc/Documentation/spi/spidev_test.c ,but I found that the spi_read,spi_write not work in my kernel,but ioctl(fd, SPI_IOC_MESSAGE(1), &tr) is OK in the userspace testing code.why couldn't i access spi_read,spi_write in spidev.c??

Note: probe has been called normally!!!

test code in spidev_probe is following.
Code:

static int spidev_probe(struct spi_device *spi)
{
        struct spidev_data        *spidev;
        int                        status;
        unsigned long                minor;
        int i = 0;
        /* Allocate driver data */
        spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
        if (!spidev)
                return -ENOMEM;

        /* Initialize the driver data */
        spidev->spi = spi;
        spin_lock_init(&spidev->spi_lock);
        mutex_init(&spidev->buf_lock);

        INIT_LIST_HEAD(&spidev->device_entry);

        /* If we can allocate a minor number, hook up this device.
        * Reusing minors is fine so long as udev or mdev is working.
        */
        mutex_lock(&device_list_lock);
        minor = find_first_zero_bit(minors, N_SPI_MINORS);
        if (minor < N_SPI_MINORS) {
                struct device *dev;

                spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
                /*dev = device_create(spidev_class, &spi->dev, spidev->devt,
                                    spidev, "spidev%d.%d",
                                    spi->master->bus_num, spi->chip_select);
                */
                dev = device_create(spidev_class, &spi->dev, spidev->devt,
                                    spidev, this_device_name);
                status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
        } else {
                dev_dbg(&spi->dev, "no minor number available!\n");
                status = -ENODEV;
        }
        if (status == 0) {
                set_bit(minor, minors);
                list_add(&spidev->device_entry, &device_list);
        }
        mutex_unlock(&device_list_lock);

        if (status == 0){
                spi_set_drvdata(spi, spidev);
               
               
                /*test code*/
                printk("test 3 start!\n");
                if(spi_write(spidev->spi,tx_buf,8)< 0){
                        printk("spi_write write error!\n");
                }
                if(spi_read (spidev->spi,rx_buf,8)){
                        printk("spi_write read error!\n");
                }
                for(i = 0; i < 8; i++){
                        printk("{%2x}\n",rx_buf[i]);
                }
                printk("test 4 start!\n");
                for(i = 0; i < 8; i++){
                        printk("{%2x}\n",spi_w8r8(spidev->spi,i));
                }
                printk("test end!\n");

               
                #if 0
                RF_CHIP_INITIALIZE(spidev);
                RF_NET_CONFIG(spidev);
                #endif
        }else{
                kfree(spidev);
        }
       
        return status;
}


Note:
bellow is doc about IO interface in http://www.kernel.org/doc/Documentation/spi/spidev

Standard read() and write() operations are obviously only half-duplex, and
the chipselect is deactivated between those operations. Full-duplex access,and composite operation without chipselect de-activation, is available using the SPI_IOC_MESSAGE(N) request.

传统的read write使用的是半双工模式,需要cs片选;而 SPI_IOC_MESSAGE(N) 方式使用全双工,无须片选。

- At this time there is no async I/O support; everything is purely
synchronous.都是同步的?

pan64 03-28-2012 03:28 AM

do you have compile time error or runtime error?

yixiaoyang 03-28-2012 08:04 PM

Quote:

Originally Posted by pan64 (Post 4638462)
do you have compile time error or runtime error?

of course no compile error or runting error.
NOTE:I connect MISO wire with MOSI, and run test file http://www.kernel.org/doc/Documentat.../spidev_test.c in kernel. The result run on the ARM9 board as bellow:

Code:

[root@EmbedSky /test]# insmod lrf020.ko
2012-3-27 16:48
test 3 start!
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
test 4 start!
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
test end!

[root@EmbedSky /test]# ./spi_test3
test 1 start!
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}

test 2 start!
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
{ 0}
test end!

My test code in kernel with spi_read/write not work!

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D

It;s OK,so ioctl(fd, SPI_IOC_MESSAGE(1) works!

I wander whether somewhere not be set correctly or I have forgetten something important...
It seems strange:eek:

Compiling Message:
make -C /opt/linux/EmbedSky/linux-2.6.30.4 M=/opt/git-hub/linux_driver/lrf020-beta/lrf020-old modules -I /opt/linux/EmbedSky/linux-2.6.30.4/include
make[1]: 进入目录“/opt/linux/EmbedSky/linux-2.6.30.4”
CC [M] /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/rf.o
CC [M] /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/uz2400d.o
CC [M] /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/spidev.o
LD [M] /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/lrf020.o
Building modules, stage 2.
MODPOST 1 modules
CC /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/lrf020.mod.o
LD [M] /opt/git-hub/linux_driver/lrf020-beta/lrf020-old/lrf020.ko
make[1]: 离开目录“/opt/linux/EmbedSky/linux-2.6.30.4”
compiled ok!


All times are GMT -5. The time now is 05:04 AM.