Linux SPI 子系统驱动笔记
——Linux spi设备驱动与SPI控制器驱动的匹配问题
前面总结了Linux SPI 子系统框架:
1.注册平台设备
2.注册平台驱动
.probe()函数中注册描述spi控制器的spi_master
3.注册spi设备:spi_board_info
4.注册spi_driver
.probe()函数中注册描述外设的设备结构体,如char设备
5.用户操作API实现。read()/write()
1.注册平台设备
2.注册平台驱动
.probe()函数中注册描述spi控制器的spi_master
3.注册spi设备:spi_board_info
4.注册spi_driver
.probe()函数中注册描述外设的设备结构体,如char设备
5.用户操作API实现。read()/write()
一、问题:SPI协议层驱动是怎么与SPI控制器(spi_master)匹配的。
注册流程:
1.在SPI协议层中,spi_device是通过spi_register_board_info来注册的(注:上述做法需要在注册spi控制器驱动即spi_master之前)。首先创建一个spi_board_info结构描述spi设备板级信息,然后调spi_register_board_info()将其添加到board_list中。
2.然后才继续调用spi_register_master注册SPI控制器驱动spi_master,此时会调用scan_boardinfo扫描board_list,根据 spi_board_info调用spi_new_device生成spi_device结构,并用spi_add_device添加设备。
3. 调用spi_register_driver注册spi_driver,通过“设备名”与spi_device匹配。
二、spi控制器是怎么区分多个spi设备的
spi控制器是通过片选信号来区分多个spi设备的
可以通过如下例子来理解:
(参考博文:http://www.cnblogs.com/tfanalysis/articles/3780286.html)
struct spi_board_info {
char modalias[32];
const void *platform_data;
void *controller_data;
int irq;
u32 max_speed_hz;
u16 bus_num;
u16 chip_select;
u8 mode;
};
#define SPI_AK4104 \
{ \
.modalias = "ak4104-codec", \设备名
.max_speed_hz = 10000, \波特率
.bus_num = 0, \SPI A, B, C ,D
.chip_select = 0, \片选(0~7)
.controller_data = (void *) GPIO_SPDIF_CS,\平台数据
}
#define SPI_DAC7512 \
{ \
.modalias = "dac7512", \设备名
.max_speed_hz = 1000000, \波特率
.bus_num = 0, \ SPI A, B, C ,D
.chip_select = 2, \片选(0~7)
.controller_data = (void *) GPIO_MCLK_DAC_CS, \
}
static struct spi_board_info connector_spi_devices[] __initdata = {
SPI_AK4104,
SPI_DAC7512,
};
spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
分析上面的例子,可以看出:
1. spi bus A上挂了上面两个设备: AK4104/DAC7512
2.SPI接口信号线:
SCK_A: 时钟,同两个设备的时钟信号接在一起SIN_A: data in; 同两个设备的data out信号接在一起SOUT_A: data out; 同两个设备的data in信号接在一起PCS0_A: bus A chip select 0, 接AK4104的片选PCS2_A: bus A chip select 2,接DAC7512的片选
如果选中chip select 0, 后续操作就会作用于设备AK4104
如果选中chip select 2, 后续操作就会作用于设备DAC7512