1.SPI子系统框图详解:

    SPI总线上有两类设备:一类是主控端,通常作为SOC系统的一个子模块出现,比如很多嵌入式MPU中都常常包含SPI模块。一类是受控端,例如一些SPI接口的Flash、传感器等等。主控端是SPI总线的控制者,通过使用SPI协议主动发起SPI总线上的会话。而受控端则被动接受SPI主控端的指令,并作出响应的响应



如图1所示,linux下的spi子系统主要涉及3个部分:spi核心、spiprotocol驱动和spi主控制器驱动。如图1.1spi核心负责抽象出所有控制器都具备的功能代码,同时向上为spiprotocol驱动提供接口比如spi_messagespi_transferspi_async等,具体可参见linux/spi/spi.h文件,需要自己写客户驱动的可以详细了解一下spi.h文件。


spi控制器驱动负责与具体的控制器硬件沟通,进行bit级的数据传输。

spi客户驱动,即protocol驱动负责从控制器端接收数据,然后按照“protocol”将其解释为有意义的数据格式


2则显示了LinuxSPI子系统所涉及的大部分结构和函数调用,其中一些细节可以在这里找到你想要得。


2. SPI驱动移植

   平台:mini2440

    kernellinux-2.6.32.2

    MasterSPI0

    Slaveof

从图2中我们看出,要进行驱动移植,大致要做的就是完成上面的6个主要结构的注册,使系统能够识别他们。

首先:在LinuxSource Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入头文件:

#include<linux/spi/spi.h>
#include<../mach-s3c2410/include/mach/spi.h>

接着是各个结构的注册:

  1. s3c_device_spi0:在devs.c中定义,需要在板级文件mach-mini2440.cmini2440_devices[]平台数组中添加如下代码:

    &s3c_device_spi0,

    s3c2410_spi_info:就是s3c_device_spi0platform_data,用来初始化master,给出了总线有几条,和其相连的slave数量,设置片选的函数...也需要在mach-mini2440.c中加入:

    static structs3c2410_spi_info s3c2410_spi0_platdata = {
        .pin_cs= S3C2410_GPG(2),//这个得看你的板子具体情形了
        .num_cs= 1, //有一个slave
        .bus_num= 0, //只有一条SPI总线
        .gpio_setup =s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,
    };

    接着在mini2440_machine_init中加入:

    s3c_device_spi0.dev.platform_data=&s3c2410_spi0_platdata;

  1. controller的平台驱动:s3c24xx_spi_driver,makemenuconfig时打开便好;

  2. 总线spi_bus_typespi核心,在makemenuconfig时打开便好;

  3. controller驱动:也不需要动;

  4. 板级设备信息,即你的slave和总线的连接:

    spi_board_info:在mach-mini2440.c中加入s3c2410_spi0_board,如下
    static structspi_board_info s3c2410_spi0_board[] = {
        [0] = {
            .modalias= "adns3080", //需要和你的驱动一致
            .bus_num= 0,
            .platform_data =&adns3080_data,
            .chip_select= 0,
            .irq =IRQ_EINT9,
            .max_speed_hz= 500 * 1000,
        }
    };

    外加头文件(有必要的话):adns3080.h

    #ifndef __SPI_PLATFORM_ADNS3080_H__
    #define __SPI_PLATFORM_ADNS3080_H__
    struct adns3080_platform_data{
        your_data_0;
    };
    #endif
    static structadns3080_platform_data adns3080_data = {
        .your_data_0 =your_data,
    };

    接着在mini2440_machine_init中加入:

    spi_register_board_info(s3c2410_spi0_board,ARRAY_SIZE(s3c2410_spi0_board));

    6. my_driver:其实可以没有my_driver这一步,这需要你自己写的,在module_init中会注册的...也可以使用kernel自带的spidev.c驱动,这就需要打开SPIDEV的支持:

    makemenuconfig时:

    Device Drivers

        SPI support

            User mode SPIdevicedriver support //打开这一项

然后是板级信息:

  1. 7.接着就不是结构注册,上面如果是板级,下面就得是芯片级了。配置文件的改动:

    需要修改arch/arm/plat-s3c24xx/KConfig文件

    找到如下代码段:


    configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
        bool
        help
        SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.
    configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
        bool
        help
        SPI GPIOconfiguration code for BUS 1 when connected to GPG5, GPG6 andGPG7.
    修改为
    configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
        bool"S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13" // 管脚可以看芯片手册
        help
        SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.  //spi_bus0
    
    configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
        bool"S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"
        help
        SPI GPIOconfiguration code for BUS 1 when connected to GPG5,GPG6 and GPG7. //spi_bus1
    
    

  1. 最后的make menuconfig
  1.     ...
  1.          

Logo

更多推荐