首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

Linux SPI框架(下)

2012-07-28 
Linux SPI框架(上) 水平有限,描述不当之处还请指出,转载请注明出处http://blog.csdn.net/vanbreaker/artic

Linux SPI框架(上)

 水平有限,描述不当之处还请指出,转载请注明出处http://blog.csdn.net/vanbreaker/article/details/7733476

       Linux的SPI子系统采用主机驱动和外设驱动分离的思想,首先主机SPI控制器是一种平台设备,因此它以platform的方式注册进内核,外设的信息是以boardinfo形式静态定义的,在创建spi_master时,会根据外设的bus_num和主机的bus_num是否相等,来选择是否将该外设挂接在该SPI主控制器下。先看SPI子系统中几个关键的数据结构:

struct spi_master用来描述一个SPI主控制器

struct spi_master {struct device    dev;s16    bus_num; /*总线编号*/u16    num_chipselect;/*支持的外设数量*/u16    dma_alignment;int   (*transfer)(struct spi_device *spi, struct spi_message *mesg);/*用于将消息添加到队列*/void  (*cleanup)(struct spi_device *spi);};


struct spi_device用来描述一个SPI从设备

struct spi_device {struct devicedev;struct spi_master*master;                 /*从设备所属的SPI主控器*/u32max_speed_hz;   /*最大传输频率*/u8chip_select;    /*片选号,用于区别其他从设备*/u8mode;           /*传输模式*//*各个mode的定义*/#defineSPI_CPHA0x01 /* clock phase */#defineSPI_CPOL0x02 /* clock polarity */#defineSPI_MODE_0(0|0) /* (original MicroWire) */#defineSPI_MODE_1(0|SPI_CPHA)#defineSPI_MODE_2(SPI_CPOL|0)#defineSPI_MODE_3(SPI_CPOL|SPI_CPHA)#defineSPI_CS_HIGH0x04 /* chipselect active high? */#defineSPI_LSB_FIRST0x08 /* per-word bits-on-wire */#defineSPI_3WIRE0x10 /* SI/SO signals shared */#defineSPI_LOOP0x20 /* loopback mode */u8bits_per_word; /*每个字的比特数*/intirq;           /*所使用的中断*/void*controller_state;void*controller_data;charmodalias[32];  /*设备名,在和从设备驱动匹配时会用到*/};


struct spi_driver用来描述一个SPI从设备的驱动,它的形式和struct platform_driver是一致的

struct spi_driver {int(*probe)(struct spi_device *spi);int(*remove)(struct spi_device *spi);void(*shutdown)(struct spi_device *spi);int(*suspend)(struct spi_device *spi, pm_message_t mesg);int(*resume)(struct spi_device *spi);struct device_driverdriver;};


SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下

static int __init spi_init(void){intstatus;buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);if (!buf) {status = -ENOMEM;goto err0;}status = bus_register(&spi_bus_type);//注册SPI总线if (status < 0)goto err1;status = class_register(&spi_master_class);//注册spi_master类if (status < 0)goto err2;return 0;err2:bus_unregister(&spi_bus_type);err1:kfree(buf);buf = NULL;err0:return status;}


我们来看spi_bus_type的定义

struct bus_type spi_bus_type = {.name= "spi",.dev_attrs= spi_dev_attrs,.match= spi_match_device,.uevent= spi_uevent,.suspend= spi_suspend,.resume= spi_resume,};

来看挂接在SPI总线下的从设备和从设备驱动是如何匹配的,也就是spi_match_device函数

static int spi_match_device(struct device *dev, struct device_driver *drv){const struct spi_device*spi = to_spi_device(dev);return strcmp(spi->modalias, drv->name) == 0;}


这里可以看到是将struct device_driver中的name字段与struct spi_device中的modalias字段进行匹配

 

这里已经完成了SPI子系统初始化的第一步,也就是注册SPI总线,这一步是和平台无关的,第二步是和平台相关的初始化,下一节再做介绍。

 

 

 

 

1楼zi776424755天前 19:44
依然在吧……

热点排行