2008年4月28日 星期一

Linux SPI subsystem (3)

在上二篇的文章中我們提到了 Linux SPI 子系統的架構以及如何撰寫 master driver,接下來則是要討論如何撰寫 protocol driver。

如同 master driver,要讓核心能夠使用 protocol driver,必須先註冊我們所要驅動的硬體以及對應的驅動程式。硬體裝置的註冊有兩種方法:

  1. 事先在核心平台相關初始化程式碼中,填入相關的周邊硬體資訊在 spi_board_info 結構中。該結構的宣告如下:

    struct spi_board_info {
        char modalias[KOBJ_NAME_LEN];
        const void *platform_data;
        void *controller_data;
        int irq;
        u32 max_speed_hz;
        u16 bus_num;
        u16 chip_select;
        u8 mode;
    }

    其中 modalias 必須與 protocol driver 的名稱相同以供核心比對;其他欄位的意義可參照 include/spi/spi.h 檔案中的說明。完成後呼叫 spi_register_board_info 來註冊這些裝置。
  2. 若是無法確定會接上什麼裝置,則可以在核心模組程式碼中,填入上述的結構,但改為呼叫 spi_new_device 來註冊該裝置。函式中的 master 參數可透過呼叫 spi_busnum_to_master 來取得。
在註冊時,核心會為每個裝置配置一個 spi_device 結構,將上述 spi_board_info 結構中的資訊填入對應的欄位中。

接下來我們要將我們所撰寫的 protocol driver 回呼函式填入 spi_driver 結構中,如下所示:

struct spi_driver mydriver {
    .probe = mydriver_probe,
    .remove = mydriver_remove,
    .driver = {
        .name = "mydriver",
        .owner = THIS_MODULE,
    }
}

接著呼叫 spi_register_driver 來註冊新的 protocol driver。

結語
從這一系列文章,我們可以了解到,即使是像 SPI 如此簡單的硬體介面,為了讓驅動程式更具可移植性及模組化,核心開發者設計了分層式的架構,讓每個驅動程式能夠各司其職,互不干擾。這樣的架構在其他核心子系統中也常會見到,也許名稱不同,但基本理念仍是相同的。