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()
一、问题: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