生活随笔
收集整理的這篇文章主要介紹了
New Linux2.6 I2C Driver Model Example
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? 閑話不說,先給出完整的示例代碼,加好注釋,后面再進一步解釋。
????????????????????#include?<linux/kernel.h>??#include?<linux/module.h>??#include?<linux/fs.h>??#include?<linux/slab.h>??#include?<linux/init.h>??#include?<linux/list.h>??#include?<linux/i2c.h>??#include?<linux/i2c-dev.h>??#include?<linux/smp_lock.h>??#include?<linux/jiffies.h>??#include?<asm/uaccess.h>??#include?<linux/delay.h>????#define?I2C_DEV_NAME?"MyDevice"?//這個名字要跟board_info中的名字一致,才會與I2C_Client匹配????static?struct?i2c_device_id?my_id[]?=?{??????{I2C_DEV_NAME,0},??????{}??};????MODULE_DEVICE_TABLE(i2c,?my_id);?????static?struct?i2c_client?*my_client;?????static?int?my_i2c_probe(struct?i2c_client?*client,?const?struct?i2c_device_id?*id)??{???????????my_client?=?client;????????return?0;??}????static int my_i2c_remove(struct i2c_client *client) { //釋放I2C Client對象 if( my_client != NULL ) {i2c_unregister_device(my_client);} return?0;?? }??static?struct?i2c_driver?my_driver?=?{??????.driver???=?{??????????.name??=?"my?i2c?driver",??????????.owner?=?THIS_MODULE,??????},??????.probe????=?my_i2c_probe,??????.remove???=?__devexit_p(my_i2c_remove),??????.id_table?=?my_id,??};????static?int?__init?my_i2c_init(void)??{???????????return?i2c_add_driver(&my_driver);??}????static?void?__exit?my_i2c_exit(void)??{???????????i2c_del_driver(&my_driver);??}????int?my_i2c_write(?uint8_t?reg,uint8_t?data?)??{??????unsigned?char?buffer[2];??????buffer[0]?=?reg;??????buffer[1]?=?data;????????if(?2!=?i2c_master_send(my_client,buffer,2)?)?{??????????printk(?KERN_ERR?"my?i2c?send?fail!?\n"?);??????????return?-1;??????}??????return?0;??}????int?my_i2c_read(?uint8_t?reg,uint8_t?*data?)??{???????????if(?1!=?i2c_master_send(my_client,®,1)?)?{??????????printk(?KERN_ERR?"my?i2c?recv?fail!?\n"?);??????????return?-1;??????}???????????msleep(10);???????????if(?1!=?i2c_master_recv(my_client,data,1)?)?{??????????printk(?KERN_ERR?"my?i2c?recv?fail!?\n"?);??????????return?-1;??????}????????return?0;??}????MODULE_DESCRIPTION("my?i2c?driver");??MODULE_AUTHOR("Lujun?@HUST");??MODULE_LICENSE("GPL");????module_init(my_i2c_init);??module_exit(my_i2c_exit);??? ? 上面的代碼還不能完全成功運行,因為還沒有添加自己的I2C設備信息到系統中,模塊Probe函數不會被調用執行。注釋中已經提到,i2c_add_driver的時候會掃描本模塊的 id_table 中的名稱是否與注冊到系統中的boardinfo列表中有名稱匹配的client,如果有,則會構造 i2c_client 對象,并調用本模塊的 probe 函數。
? ??那么,如何注冊自己的i2c設備信息到系統的 boardinfo 列表中呢?Linux內核文檔:Documentation/i2c/instantiating-devices 中講了多種方式,我在此只說2種方式。
? ??第一種方式,在內核的初始化中定義你的I2C設備的信息。比如在/arch/arm/mach-xxxx/board_xxxx.c 中添加一個新的 Boardinfo信息:
static?struct?i2c_board_info?__initdata?i2c_info[]?=??{?????????{?????????????????I2C_BOARD_INFO("24c256",?0x50),?????????????????.platform_data??=?&eeprom_info,?????????},?????????{?????????????????I2C_BOARD_INFO("MyDevice",?(0xbc>>1)),?????????????????.platform_data??=?NULL,?????????},?};?? ? ?注意,添加的新的 I2C_BOARD_INFO的名稱一定要與本模塊的driver的名稱字符串一致,地址是I2C設備地址右移1位以后的地址。
? ? ?第二種方式,使用i2c_new_device()。相關函數如下:
?struct?i2c_client?*?i2c_new_device(struct?i2c_adapter?*adap,?struct?i2c_board_info?const?*info);???struct?i2c_adapter*?i2c_get_adapter(int?id);???ls?/sys/class/i2c-adapter/???? ? ?那么,使用第二種方式的示例代碼如下,在?my_i2c_init 函數開頭,添加如下代碼,動態注冊 I2C 設備信息到內核 Boardinfo 列表中。? ? ?
?static?struct?i2c_board_info?my_dev_info[]?__initdata?=?{??????{??????????I2C_BOARD_INFO(I2C_DEV_NAME,I2C_DEV_ADDR),???????????.platform_data=?NULL,?????????},??};?????static?int?sys_adap_bus_num?=?0;?????static?int?__init?my_i2c_init(void)??{??????struct?i2c_adapter*?adap?=?i2c_get_adapter(sys_adap_bus_num);?????????if(adap==NULL)?{??????????printk("[LUJUN-DEBUG]?i2c_get_adapter?fail!\n");??????????return?-1;??????}?????????????my_client?=?i2c_new_device(adap,?&my_dev_info[0]);??????if(?my_client==NULL?){??????????printk("[LUJUN-DEBUG]?i2c_new_device?fail!\n");??????????return?-1;??????}?????????????????i2c_put_adapter(adap);?????????????return?i2c_add_driver(&my_driver);??}??本文轉自 Jhuster 51CTO博客,原文鏈接:http://blog.51cto.com/ticktick/971738,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的New Linux2.6 I2C Driver Model Example的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。