S3C2440 Linux驱动移植——SPI

发布者:凌晨2点369最新更新时间:2017-09-23 来源: eefocus关键字:S3C2440  Linux驱动  移植  SPI 手机看文章 扫描二维码
随时随地手机看文章

1. 配置内核

首先,修改arch/arm/plat-s3c24xx/Kconfig,这一步的目的是为了可以在内核中使能SPI0的配置函数。

修改后的内容如下:

config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
    bool  " S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"
    help
      SPI GPIO configuration code for BUS0 when connected to
      GPE11, GPE12 and GPE13.

接着配置内核,首先打开S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13选项,这样编译的时候会将

arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c一起进行编译。

该源文件中的函数void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,  int enable)将用于配置spi控制器0的管脚。



接着,使能SPI功能,这里打开2440的SPI控制器驱动和通用的protocol驱动spidev。


2. 修改源码

修改arch/arm/mach-s3c2440/mach-smdk2440.c

增加内容:

#include

#include

static struct s3c2410_spi_info s3c2410_spi0_platdata={

      .pin_cs = S3C2410_GPG(2),

      .num_cs = 1,

      .bus_num = 0,

      .gpio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,

};

static struct spi_board_info s3c2410_spi0_board[]={

   [0] = {

             .modalias = “spidev”,

             .bus_num = 0,

             .chip_select = 0,

             .max_speed_hz = 500 * 1000,

    },

};

在smdk2440_devices[]中增加

&s3c_device_spi0,

在smdk2440_mach_init函数中增加

s3c_device_spi0.dev.platform_data = &s3c2410_spi0_platdata;

spi_register_board_info(s3c2410_spi0_board,ARRAY_SIZE(s3c2410_spi0_board));

修改完毕以后,重新编译内核,并下载内核。查看下设备节点:

[root@yj423 /dev]#ls /dev/spidev0.0 
/dev/spidev0.0


3.测试

用杜邦线将MOSI和MISO管脚相连。

在内核源码中提供了SPI测试程序。源码位于Documentation/spi/spidev_test.c,编译之后,下到开发板并执行。

[root@yj423 yj423]#./spidev_test -D /dev/spidev0.0
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 
NOTE:如果你只是为了移植而移植,那么后面的内容就不要看了。想知道WHY,那请继续往下看。


4.原理

首先,在第二小结中我们看到定义了两个数据结构,之所以要定义那是因为驱动程序需要用到,详见

基于S3C2440的嵌入式Linux驱动——SPI子系统解读(二)

需要这两个数据结构的地方,均用红色字体说明了。

数据s3c2410_spi0_platdata是作为平台的私有数据,因此使用了s3c_device_spi0.dev.platform_data = &s3c2410_spi0_platdata来添加该数据。

而s3c2410_spi0_board必须通过函数spi_register_board_info添加到内核中,

最重要的一个问题,这些数据结构的值是怎么给出的?

先来看看这两个数据结构:


  1. struct spi_board_info {  

  2.     /* the device name and module name are coupled, like platform_bus; 

  3.      * "modalias" is normally the driver name. 

  4.      * 

  5.      * platform_data goes to spi_device.dev.platform_data, 

  6.      * controller_data goes to spi_device.controller_data, 

  7.      * irq is copied too 

  8.      */  

  9.     char        modalias[32];  

  10.     const void  *platform_data;  

  11.     void        *controller_data;  

  12.     int     irq;  

  13.   

  14.     /* slower signaling on noisy or low voltage boards */  

  15.     u32     max_speed_hz;  

  16.   

  17.   

  18.     /* bus_num is board specific and matches the bus_num of some 

  19.      * spi_master that will probably be registered later. 

  20.      * 

  21.      * chip_select reflects how this chip is wired to that master; 

  22.      * it's less than num_chipselect. 

  23.      */  

  24.     u16     bus_num;  

  25.     u16     chip_select;  

  26.   

  27.     /* mode becomes spi_device.mode, and is essential for chips 

  28.      * where the default of SPI_CS_HIGH = 0 is wrong. 

  29.      */  

  30.     u8      mode;  

  31.   

  32.     /* ... may need additional spi_device chip config data here. 

  33.      * avoid stuff protocol drivers can set; but include stuff 

  34.      * needed to behave without being bound to a driver: 

  35.      *  - quirks like clock rate mattering when not selected 

  36.      */  

  37. };  

  38.   

  39. struct s3c2410_spi_info {  

  40.     int             pin_cs;    /* simple gpio cs */  

  41.     unsigned int         num_cs;    /* total chipselects */  

  42.     int             bus_num;       /* bus number to use. */  

  43.   

  44.     void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);  

  45.     void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);  

  46. };  

4.1 s3c2410_spi_info


pin_cs:表示哪个管脚用输出片选信号,这里使用GPG2管脚,具体的管脚请参看你的datasheet。

bus_num:表示总线接口。这里使用0,表示使用SPI0控制器。S3C2440有两个SPI控制器,分别为SPI0和SPI1。

num_cs:表示该SPI控制器控制几个SPI从设备,这里为1,仅有一个设备。

s3c2410_spi_info作为平台数据,在s3c24xx_spi_probe函数中,bus_cs和bus_num将被复制给master中的相应字段。也就是说,该master为SPI0控制器,有1个从设备。

而pin_cs将由函数s3c24xx_spi_gpiocs使用,该函数使能片选信号。


  1. static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol)    

  2. {    

  3.     gpio_set_value(spi->pin_cs, pol);    

  4. }    

gpio_setup: 这里设置为函数s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, 该函数用于初始化SPI控制器的管脚。

该函数将在主控制驱动的s3c24xx_spi_initialsetup函数中被调用:



4.2 spi_board_info

首先,我们知道spi_board_info作为SPI设备的板级信息,在spi_new_device函数中将该板级信息全部复制给spi_device。

modalias:将用于绑定驱动和设备。我们看下match方法:


  1. static int spi_match_device(struct device *dev, struct device_driver *drv)    

  2. {    

  3.     const struct spi_device *spi = to_spi_device(dev);    

  4.     

  5.     return strcmp(spi->modalias, drv->name) == 0;    

  6. }    

而drv->name为在spi_driver中定义,如下



  1. static struct spi_driver spidev_spi = {    

  2.     .driver = {    

  3.         .name =        "spidev",    

  4.         .owner =    THIS_MODULE,    

  5.     },    

  6.     .probe =    spidev_probe,    

  7.     .remove =    __devexit_p(spidev_remove),    

  8.     

  9.     /* NOTE:  suspend/resume methods are not necessary here.  

  10.      * We don't do anything except pass the requests to/from  

  11.      * the underlying controller.  The refrigerator handles  

  12.      * most issues; the controller driver handles the rest.  

  13.      */    

  14. };    

可见,drv->name为spidev,因此spi-device的modalias字段也必须为spidev,而该字段是由板级信息的spi_board_info的modaias复制得来。这就是为什么modalias必须为spidev。


bus_num:用来匹配主控制器和属于该主控制器的SPI设备。


  1. static void scan_boardinfo(struct spi_master *master)    

  2. {    

  3.     struct boardinfo    *bi;    

  4.     

  5.     mutex_lock(&board_lock);    

  6.     /*以board_list为链表头,遍历所有的boardinfo结构,链表由spi_register_board_info添加*/    

  7.     list_for_each_entry(bi, &board_list, list) {        

  8.         struct spi_board_info    *chip = bi->board_info;    

  9.         unsigned        n;    

  10.         /*遍历该boardinfo指向的spi_board_info数组*/    

  11.         for (n = bi->n_board_info; n > 0; n--, chip++) {    

  12.             if (chip->bus_num != master->bus_num) /*通过bus_num对spi设备和master进行匹配*/    

  13.                 continue;    

  14.             /* NOTE: this relies on spi_new_device to  

  15.              * issue diagnostics when given bogus inputs  

  16.              */    

  17.              /*执行到此,表示匹配完成,SPI设备由该SPI接口来控制,开始创建spi_device*/    

  18.             (void) spi_new_device(master, chip);    

  19.         }    

  20.     }    

  21.     mutex_unlock(&board_lock);    

  22. }    

可见,master的bus_num和spi_board_info的bus_num必须相同,从上面我们又知道master的bus_num是由s3c2410_spi_info的bus_num复制而来,因此spi_board_info的bus_num的值必须和s3c2410_spi_info的bus_num相等。


chip_selest:该值表示这是该SPI接口上的第几个设备,这里是0,其实就是第一个设备。该值用于区分不同的设备。注意,该值必须小于s3c2410_spi_info的num_cs字段。

max_speed_hz:表示传输速率,这里设置的速度为500kHz。

其余的字段可以不设置。

5. 结束语

   本文给出了SPI驱动移植的步骤,并使用测试程序测试了该SPI驱动。最后,对移植的原理进行了讲解。


关键字:S3C2440  Linux驱动  移植  SPI 引用地址:S3C2440 Linux驱动移植——SPI

上一篇:基于S3C2440的嵌入式Linux驱动——SPI子系统解读(一)
下一篇:S3C2440 Linux驱动移植——LCD

推荐阅读最新更新时间:2024-03-16 15:38

S3C2440 Linux驱动移植——按键
开发板:TQ2440 内核版本:2.6.32 1. 硬件链接图 四个输入引脚: EINT0-----( GPF0 )----INPUT---K4 EINT2-----( GPF2 )----INPUT---K3 EINT4-----( GPF4 )----INPUT---K2 EINT1-----( GPF1 )----INPUT---K1 2. 相关的数据结构 移植所需要的数据结构位于include/linux/gpio_keys.h中。 #ifndef _GPIO_KEYS_H #define
[单片机]
<font color='red'>S3C2440</font> <font color='red'>Linux</font><font color='red'>驱动</font><font color='red'>移植</font>——按键
mini2440一线总线移植tslib1.4
最近在学习中接触到了触摸库tslib,自己试着移植的时候发现网上分为两种方案,一种是使用2440自带AD的方案,另一种是友善的一线总线方案。我的液晶型号是TD35,默认的连接方案是一线总线,所以这里移植的是一线总线方案。 上网搜索的过程中发现网上可用的一线总线tslib并不是1.4版本的,但是编译后使用是没有问题的,抱着试一试的心态决定移植一下1.4版本的tslib到MINI2440,经过实验,成功将tslib的1.4版本移植到了mini2440. 移植主要是将友善提供的one_wire_ts_input.c文件添加到对应位置,修改配置文件就可以了。 下面列出补丁文件 diff -ru tslib/configur
[单片机]
S3C2416 Linux2.6.21 驱动移植--添加UART3 及波特率设置bug消除
一,移植环境 (红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 1.主机环境:Virtualbox 下ubuntu-10.10 2.编译编译环境:arm-linux-gcc v4.4.3 3.uboot : U-Boot 1.3.4(友坚提供) 4.linux内核版本:2.6.21.5 5.硬件平台:采用友坚UT2416CV02核心板开发的平台 6.参考: linux内核支持S3C2416的UART3 (http://www.itkee.com/os/detail-1677.html ) S3C2416 User's Manual, Revision 1.10 二,添加UART3 S
[单片机]
Cortex M3存储器映射
CM3 只有一个单一固定的存储器映射。这一点极大地方便了软件在各种 CM3 单片机间的移植。 存储空间的一些位置用于调试组件等私有外设,这个地址段被称为“私有外设区”。私有外设区的组件包括:闪存地址重载及断点单元(FPB),数据观察点单元(DWT),仪器化跟踪宏单元(ITM),嵌入式跟踪宏单元(ETM),跟踪端口接口单元(TPIU), ROM 表。 CM3的地址空间是 4GB, 程序可以在代码区,内部 SRAM 区以及外部 RAM 区中执行。但是因为指令总线与数据总线是分开的,最理想的是把程序放到代码区,从而使取指和数据访问各自使用自己的总线,并行不悖。 1、代码区 存放指令和数据,取指通过指令
[单片机]
Cortex M3存储器映射
基于S3c2440的I2C驱动与测试程序追踪交叉分析
VMware虚拟机+Fedora10, 硬件平台TQ2440, 内核2.6.30.4 对应的驱动程序豁然开朗, 然后自己添加了一些dev_dbg后, 对于不理解的地方也有了一定的参考提示, 记录下来与大家分享。 测试程序如下: /*i2c_test.c * hongtao_liu */ #include #include #include #include #include #include #include #include #define I2C_RETRIES 0x0701 #define I2C_ TI MEOUT 0x0702 #define I2C_RDWR 0x0707 /*********定义struct i
[单片机]
[linux 底层]u-boot EMMC驱动
山寨机的时代,很多年轻的朋友可能比较陌生,手机上会安装一个SD卡,做存储扩展;目前的智能手机会在PCB板上焊接一个EMMC芯片,做大容量数据存储,安全性好了很多,手机丢了也不用担心照片或者资料泄露的问题; 1、EMMC特性 -符合JEDEC/MMC标准版本5.0 -高级12信号接口 -x1、x4和x8I/O,可由主机选择 -SDR/DDR模式,可达52MHz时钟速度 -HS200/HS400模式 -命令类:class 0 (basic); class 2 (blockread); class 4 (block write); class 5 (erase);class 6 (write protecti
[单片机]
[<font color='red'>linux</font> 底层]u-boot EMMC<font color='red'>驱动</font>
s3c2440的IIC应用——读写AT24C02A
IIC(Inter-Integrated Circuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备,它的最主要优点是简单和有效。它只需要数据线SDA和时钟线SCL,就能够实现CPU与被控IC之间、IC与IC之间进行双向传送。 s3c2440内部有一个IIC总线接口,因此为我们连接带有IIC通信模块的外围设备提供了便利。它具有四种操作模式:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。在这里我们只把s3c2440当做IIC总线的主设备来使用,因此只介绍前两种操作模式。在主设备发送模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄
[单片机]
Windows CE.NET在S3C2410处理器上的移植简介
   本文分析了嵌入式操作系统Windows CE。NET的特点,并利用工具Platform Builder 4。2完成了其在以ARM920T为核心的S3C2410处理器上的定制。   1 Windows CE系统和Platform Builder 4.2   Windows CE是微软推出的一个32位、多线程、多任务的嵌入式操作系统,是微软专门为信息设备、移动应用、嵌入式应用等设计的嵌入式模块型操作系统。用户可选择、组合和配置Windows CE。NET的模块和组件来创建用户版的操作系统。    Windows CE。NET是WindOWS CE 3。0的后继产品,其系统组成如图1所示。Windows
[单片机]
Windows CE.NET在S3C2410处理器上的<font color='red'>移植</font>简介
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved