(一)spi總線設備驅動框架:
app: open() read() write()
------------------------------------------------------------------
系統調用
--------------------------------------------------------------------
spi設備驅動:xxx_open() 、xxx_write()、xxx_read()
--------------------------------------------------------------------
核心層: 向上提供統一的接口,向下提供管理函數
--------------------------------------------------------------------
spi總線驅動
---------------------------------------------------------------------
硬件:spi控制器1、spi控制器2... | 從設備1、從設備2....
(二)spi_s3c24xx.c文件分析:(\drivers\spi)
這個文件用到了 platform總線驅動模型,在platform_driver結構體的probe()函數中註冊了spi總線驅動,既然內核已經幫助我們完成了spi總線驅動模型,那麼我們要做的就是編寫spi設備驅動了,當然,我們也可以不用內核提供的總線驅動,自己編寫spi總線設備驅動。
s3c24xx_spi_init()
platform_driver_register
driver_register
bus_add_driver // bus_add_driver - Add a driver to the bus.
kobject_register
driver_attach // try to bind driver to devices.
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
//__driver_attach是一個函數指針,在該函數裏,會調用driver_probe_device()函數
driver_probe_device()
match()
really_probe()
drv->probe() //就會調用到s3c24xx_spi_probe(),在該函數裏面我們做真正的工作。
klist_iter_init_node
klist_add_tail
module_add_driver
driver_add_attrs
(三)s3c24xx_spi_probe() 函數分析:
struct spi_master *master;
struct spi_board_info *bi; //定義相關變量
spi_alloc_master()
spi_master_get_devdata()
spi_master_get()
相關設置
spi_bitbang_start() /* register our spi controller */
spi_new_device() /* register all the devices associated */
spi_master_put(hw->master);; //和spi_master_get()相對
3.1)spi_bitbang_start() 函數分析:
spi_register_master //總線驅動
class_device_add
class_device_get
class_device_add_attrs
class_device_add_groups
make_deprecated_class_device_links
list_add_tail
list_for_each_entry
scan_boardinfo
list_for_each_entry // chip->bus_num == master->bus_num
spi_new_device
device_register
device_add
device_add_attrs
bus_add_device //add device to bus
bus_attach_device //Try to attach to driver.
device_attach // try to attach device to a driver
bus_for_each_drv(dev->bus, NULL, dev, __device_attach)
__device_attach(struct device_driver * drv, void * data)
driver_probe_device(drv, dev);
drv->bus->match
really_probe
drv->probe
list_add_tail
list_for_each_entry
由此可見,當我們註冊spi總線驅動時,會自動的向內核添加設備。
(四)spi設備驅動程序編寫:
xxx_spi_dev.c
1、設置spi_board_info結構體
2、spi_register_board_info()
spi_match_master_to_boardinfo //master->bus_num == bi->bus_num,看數量是否相等
spi_new_device
xxx_spi_drv.c //純軟件概念,它的作用就是提供設備讀寫函數,設備掛接到總線上
1、分配 spi_driver 結構體
2、設置
3、註冊 spi_register_driver()
注:to_spi_device(struct device *dev) 得到 spi_device 結構體,spi_read()和spi_write()函數有可能要用到
probe函數傳進來的參數就是 spi_device結構體指針。
核心層提供的消息傳遞函數爲:spi_read()、spi_write()。
(五)spi總線驅動程序編寫(一般內核都有提供,不過我們也可以自己編寫)
xxx_spi_bus.c
1、分配 spi_master 結構體
2、設置 結構體成員
struct class_device cdev;
s16 bus_num;
u16 num_chipselect;
int (*setup)(struct spi_device *spi);
int (*transfer)(struct spi_device *spi,struct spi_message *mesg);
//這個成員函數很重要,spi核心層提供的讀寫函數最終都會調用到它。
void (*cleanup)(struct spi_device *spi);
3、註冊 spi_register_master()