linux SPI源码剖析

本文深入剖析了Linux系统下的SPI框架,包括SPI总线结构、驱动注册、主控制器注册、设备注册以及用户空间接口。详细解释了spi_bus_type、spi_driver、spi_master、spi_device等关键结构,展示了如何通过 spi_register_driver 和 spi_register_master 进行驱动和主控制器注册,并探讨了用户空间通过spidev访问SPI设备的方法。
摘要由CSDN通过智能技术生成

1.      SPI

1.1.      Linux框架

Spi总线是主从控制方式,总体结构如下:


1.1.1.     Spi bus

<drivers/spi/spi.c>

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,

};

/*总线match方法:name匹配方法*/

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

{

         conststruct spi_device          *spi =to_spi_device(dev);

         conststruct spi_driver  *sdrv =to_spi_driver(drv);

 

         if(sdrv->id_table)/*根据驱动中定义一组name,匹配*/

                   return!!spi_match_id(sdrv->id_table, spi);

 

         returnstrcmp(spi->modalias, drv->name) == 0;/*根据别名进行匹配*/

}

1.1.2.     Spi驱动注册

<drivers/spi/spi.c>

int spi_register_driver(struct spi_driver*sdrv)

{

         sdrv->driver.bus= &spi_bus_type;

         if(sdrv->probe)

                   sdrv->driver.probe= spi_drv_probe;

         if(sdrv->remove)

                   sdrv->driver.remove= spi_drv_remove;

         if(sdrv->shutdown)

                   sdrv->driver.shutdown= spi_drv_shutdown;

         returndriver_register(&sdrv->driver);

}

/*驱动probe方法*/

static int spi_drv_probe(struct device *dev)

{

         conststruct spi_driver           *sdrv =to_spi_driver(dev->driver);

 

         returnsdrv->probe(to_spi_device(dev));//直接调用平台probe方法

}

1.1.3.     Master 控制器注册

<linux/spi/spi.h>

struct spi_master {

         structdevice  dev;

         s16                     bus_num;/*控制器序号*/

         u16                     num_chipselect;/*片选数量*/

         u16                     dma_alignment;

         /*spi_device.mode flags understood by this controller driver */

         u16                     mode_bits;

         /*other constraints relevant to this driver */

         u16                     flags;

#define SPI_MASTER_HALF_DUPLEX         BIT(0)                /*can't do full duplex */

#define SPI_MASTER_NO_RX     BIT(1)                /*can't do buffer read */

#define SPI_MASTER_NO_TX     BIT(2)                /*can't do buffer write */

         /*安装spi设备,配置如mode,clock等*/

         int                       (*setup)(structspi_device *spi);

         /*双向传输*/

         int                       (*transfer)(structspi_device *spi,

                                                        structspi_message *mesg);

         /*called on release() to free memory provided by spi_master */

         void                   (*cleanup)(struct spi_device*spi);

};

 

/*master注册*/

int spi_register_master(struct spi_master*master)

{

         staticatomic_t                 dyn_bus_id =ATOMIC_INIT((1<<15) - 1);

         structdevice           *dev =master->dev.parent;

         int                       status = -ENODEV;

         int                       dynamic = 0;

 

         if(!dev)

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值