基于S3C2440的Linux SPI驱动移植笔记

来源:互联网 发布:js中什么是原型链 编辑:程序博客网 时间:2024/05/18 03:43
参考:
http://blog.csdn.net/woshixingaaa/article/details/6574215
http://blog.163.com/joyrain_06/blog/static/1788253920113823524293/

Linux内核版本:2.6.30.4
测试平台:EmbedSky TQ2440

在2.6.30.4内核源码中,已经给出了S3C2440的SPI驱动,但是TQ2440并没有启用这个驱动,因此要在arch/arm/mach-s3c2440/mach-tq2440.c中加入SPI的支持。网上参考的文章只将S3C2440的SPI0进行了配置,如果需要使用到两个SPI Master,就需要进行进一步配置。首先增加如下结构定义:

static struct spi_board_info s3c2410_spi0_board[] = {
        [0] = {
                 .modalias = "spidev",
                .bus_num        = 0,
                .chip_select        = 0,
                .irq = IRQ_EINT10,
                .max_speed_hz         = 500*1000,
        },
};

static struct s3c2410_spi_info s3c2410_spi0_platdata = {
        .pin_cs = S3C2410_GPG2,
        .num_cs = 1,
        .bus_num = 0,
};

static struct spi_board_info s3c2410_spi1_board[] = {
        [0] = {
                 .modalias = "spidev",
                .bus_num        = 1,
                .chip_select        = 0,
                .irq = IRQ_EINT11,
                .max_speed_hz         = 500*1000,
        },
};

static struct s3c2410_spi_info s3c2410_spi1_platdata = {
        .pin_cs = S3C2410_GPG3,
        .num_cs = 1,
        .bus_num = 1,
};

这几个结构与前述参考内容不太一样,主要对pin_cs进行了修改,将其改回S3C2440的两个nSS脚。另外,spi1的配置需要将bus_num改为1,否则后面装载驱动会出错,另外,将两个中断源改为相应的nSS脚占用的外部中断号,但尚未验证其不同选择对驱动的影响。

然后,在tq2440_devices中增加下面两行:
        &s3c_device_spi0,
        &s3c_device_spi1,
这两个结构体在内核源码arch/arm/plat-s3c24xx/devs.c中定义,主要负责将S3C2440的SPI控制寄存器及中断资源进行描述。

在tq2440_machine_init函数中增加SPI设备注册代码:
static void __init tq2440_machine_init(void)
{
        s3c24xx_fb_set_platdata(&tq2440_fb_info);
        s3c_i2c0_set_platdata(NULL);

        platform_add_devices(tq2440_devices, ARRAY_SIZE(tq2440_devices));
        EmbedSky_machine_init();
        s3c_device_spi0.dev.platform_data= &s3c2410_spi0_platdata;
        spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board));
        s3c_device_spi1.dev.platform_data= &s3c2410_spi1_platdata;
        spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board));
        s3c2410_gpio_setpin(S3C2410_GPG12, 0);
        s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPIO_OUTPUT);
        s3c24xx_udc_set_platdata(&EmbedSky_udc_cfg);
}

在mach-tq2440.c文件前面增加头文件include:
#include <../mach-s3c2410/include/mach/spi.h>
#include <linux/spi/spi.h>

完成上述修改后就可以编译内核了。
当然,这样编译的内核是不能支持spi的,还需要对SPI设备驱动进行编译。make menuconfig,进入Device Drivers-->SPI Support,将下述三项都选上:
基于S3C2440的Linux <wbr>SPI驱动移植笔记

当然,如果想将这三个模块都编译进内核就将其标注为*。
保存退出后make modules,在drivers/spi目录生成三个ko文件:spi_bitbang.ko  spidev.ko spi_s3c24xx.ko。
spi_bitbang.ko是基础驱动,spi_s3c24xx.ko依赖于这个驱动提供的功能,spi_s3c24xx.ko是S3C2440 SPI的核心驱动,基本功能都由这个驱动实现,但是这个是SPI Master驱动,只有它还无法完成SPI的操作,spidev.ko实现了/dev/spidevX.X设备,依赖于spi_s3c24xx.ko提供的功能,在用户侧可以进行调用。

这几个驱动编译完毕后,下载到单板进行装载,由于驱动之间存在依存关系,所以一定要按照下面顺序装载:
insmod spi_bitbang.ko
insmod spi_s3c24xx.ko
insmod spidev.ko
装载完毕后,如果能够在/dev下看到spidev0.0和spidev1.0就OK了。

在内核源码中的Documents/spi目录下有SPI驱动测试程序,将里面的设备名称修改为上面两个设备名称:
static const char *device = "/dev/spidev0.0";
// static const char *device = "/dev/spidev1.0";
编译后下载到单板分别进行验证,在SPI输入输出环回的情况下,验证OK:
[root@EmbedSky /root]# ./spidev_test
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

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

[root@EmbedSky /root]# ./spidev_test
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

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
阅读全文
0 0
原创粉丝点击