spi總線設備驅動模型詳解(Linux3.4)

(一)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()


                
                
    
        
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章