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)
return-ENODEV;
&nbs