声明:本文为本人参考韦东山spi驱动课程,并结合内核代码分析所作
1、枚举过程
(1)设备端(dev)
/drivers/spi/spi.c
spi_register_board_info
/*对于每一个spi_master,调用spi_match_master_to_boardinfo*/
list_for_each_entry(master, &spi_master_list, list)
spi_match_master_to_boardinfo(master, &bi->board_info);
/*board_info里面有bus_num成员,如果跟某个spi_master的bus_num一致,则创建一个新的spi_device*/
if (master->bus_num == bi->busnum)
spi_new_device
spi_alloc_device
/* 记录bi信息, 比如片选,MODE,MAX HZ */
spi_add_device /* 根据名字找到spi_driver, 调用它的probe函数 */
spi_setup(spi);
device_add /* 会绑定到一个spi_driver */
对于每一个spi_master,比较新注册的设备的bus_num和spi_master的bus_num,一致则创建一个新的spi_device
申请一个spi_device的内存,记录设备信息,如片选、模式和MAX HZ等
spi_add_device函数代码太长不好截图,大概说一下该函数的所做的工作,spi_add_device通过调用spi_setup做一些相关参数的判断和设置,然后调用device_add函数,device_add函数将spi_device 加入设备队列,通过名字寻找绑定spi_driver并调用spi_driver的probe函数。
spi_add_device
spi_setup
device_add
bus_add_device //将spi_device加入spi设备队列
bus_probe_device
device_attach
device_bind_driver //绑定dev和drv
bus_for_each_drv //对于每一个drv,调用__device_attach函数
__device_attach
driver_match_device //匹配操作
driver_probe_device
really_probe
drv->probe //drv->probe即为自己定义的probe函数
(2)驱动端(drv)
/drivers/spi/spi.c
spi_register_driver
driver_register
bus_add_driver
driver_attach
bus_for_each_dev //对每个dev,调用__driver_attach函数
__driver_attach
driver_match_device //匹配操作
driver_probe_device
really_probe
drv->probe //drv->probe即为自己定义的probe函数
2、数据收发过程
spi_message_init(&m); //初始化一个spi_message,spi_message是一个不可打断的传输过程,一个spi_message由多个spi_transfer组成
spi_message_add_tail(&t, &m); /* spi_transfe是SPI上传输的单方向1个或多个字节 */
spi_sync(spi, &m); /* 启动传输并等待完成 */
(1)spi_write
(2)spi_read
(3)spi_write_then_read
3、spi_driver如何调用spi_controller
spi_sync
__spi_sync
spi_async_locked
__spi_async
master->transfer(spi, message);
wait_for_completion