1. 程式人生 > >i2c裝置驅動的四種構造方法

i2c裝置驅動的四種構造方法

i2c裝置驅動屬於字元裝置驅動,其構造自然是跟字元裝置的結構一樣了,字元裝置:1、 分配字元裝置號(主次裝置號),設定為0,表示自動分配裝置號 

2、構造file_operatios 3、註冊裝置,register_chrdev(1,2,3),三個引數分別是裝置號,名稱(不重要,隨便起),構造的file_operations。

i2c匯流排驅動:核心層:提供統一的介面函式。介面卡:提供硬體介面,及其硬體i2c介面

i2c的裝置驅動模型 i2c_bus_type ,在這個總線上左右掛載分別是i2c_client和i2c_driver的連結串列,通過各自注冊介面進行註冊,在i2c_client 和i2c_driver的原型如下

struct i2c_client {
unsigned short flags;/* div., see below*/
unsigned short addr;/* chip address - NOTE: 7bit*/
/* addresses are stored in the*/
/* _LOWER_ 7 bits*/
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter;/* the adapter we sit on*/
struct i2c_driver *driver;/* and our access routines*/
struct device dev;/* the device structure*/
int irq; /* irq issued by device*/
struct list_head detected;
};

struct i2c_driver {
unsigned int class;


/* Notifies the driver that a new bus has appeared. You should avoid
* using this, it will be removed in a near future.
*/
int (*attach_adapter)(struct i2c_adapter *) __deprecated;


/* Standard driver model interfaces */
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);


/* driver model interfaces that don't relate to enumeration  */
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t mesg);
int (*resume)(struct i2c_client *);


/* Alert callback, for example for the SMBus alert protocol.
* The format and meaning of the data value depends on the protocol.
* For the SMBus alert protocol, there is a single bit of data passed
* as the alert response's low bit ("event flag").
*/
void (*alert)(struct i2c_client *, unsigned int data);


/* a ioctl like command that can be used to perform specific functions
* with the device.
*/
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);


struct device_driver driver;
const struct i2c_device_id *id_table;


/* Device detection callback for automatic device creation */
int (*detect)(struct i2c_client *, struct i2c_board_info *);
const unsigned short *address_list;
struct list_head clients;
};

i2c_client 和i2c_driver 兩個結構體之間通過name 連線在一起,只有對應的name匹配正確,才能夠呼叫i2c_driver 中的probe函式。例如

實現i2c_dev.c和i2c_drv.c兩個檔案中實現at24cxx的i2c驅動程式碼:



一旦這兩個檔案的at24c8這個名字出現不同,那麼這個驅動絕對不會載入成功。

以i2c裝置at24c80為例分析i2c程式碼

1、構造/設定i2c_driver

2、註冊i2c_driver

這是實現i2c裝置驅動的右邊部分,



然後實現根據要求實現i2c_driver中的函式,加入函數出口函式及其部分關鍵修飾


那麼整個i2c_driver就實現了

但是這個實現,編譯載入成功後,並沒有在裝置檔案中產生可操作的介面,使用ls /dev/at24c08檢視,並沒有產生一個裝置

這個就需要我們實現左邊部分i2c_client\

程式碼如下


分別為驅動的入口和出口,入口函式at24cxx_dev_init中實現了介面卡的分派,大多開發板中的i2c_dev介面卡只有i2c-0,所以直接分派介面卡即可,

i2c_new_device這是整個程式的核心,只有啟動呼叫它,才會呼叫函式probe。這個函式的作用主要是強制認為裝置存在。所以一旦name匹配,他就

一定能夠啟動probe函式

和他具有同等功能的還有一個函式:i2c_new_probed_device,區別是,這個函式用於“對於已經識別出來的裝置”才會建立,即確定裝置是真實存在的。

i2c_put_adapter函式和i2c_get_adapter相對應的函式,它用來釋放介面卡。

方法二:使用i2c_register_board_info 的板級檔案構造i2c裝置

方法三:直接在使用者空間操作i2c裝置。使用open和ioctl函式

方法四:查詢所有的adpater