linux iic总线驱动程序,linux-3.4.2IIC驱动程序详解

本文详细介绍了如何开发I2C设备驱动程序,包括如何使用detect函数在不知道设备适配器的情况下查找I2C设备,以及如何通过i2c_new_device注册i2c_client,并利用i2c_driver的probe函数进行设备匹配和初始化。同时,文章列举了IIC核心库提供的几种设备操作函数,如读写单字节和字数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

a.4 前面的2种方法都要事先确定适配器(I2C总线,I2C控制器)

如果我事先并不知道这个I2C设备在哪个适配器上,怎么办?去class表示的所有的适配器上查找

有上一些I2C设备的地址是一样,怎么继续分配它是哪一款?用detect函数

static struct i2c_driver at24cxx_driver = {

.class  = I2C_CLASS_HWMON,

.driver = {

.name = "100ask",

.owner = THIS_MODULE,

},

.probe = at24cxx_probe,

.remove = __devexit_p(at24cxx_remove),

.id_table = at24cxx_id_table,

.detect  =

at24cxx_detect,

.address_list = addr_list,

};

去"class表示的这一类"I2C适配器,用"detect函数"来确定能否找到"address_list里的设备",

如果能找到就调用i2c_new_device来注册i2c_client,

这会和i2c_driver的id_table比较,

如果匹配,调用probe

i2c_add_driver

i2c_register_driver

a. at24cxx_driver放入i2c_bus_type的drv链表

并且从dev链表里取出能匹配的i2c_client并调用probe

driver_register

b. 对于每一个适配器,调用__process_new_driver

对于每一个适配器,调用它的函数确定address_list里的设备是否存在

如果存在,再调用detect进一步确定、设置,然后i2c_new_device

i2c_for_each_dev(driver, __process_new_driver);

__process_new_driver

i2c_do_add_adapter

i2c_detect(adap, driver);

for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {

err = i2c_detect_address(temp_client, driver);

if (!i2c_default_probe(adapter, addr))

return 0;

memset(&info, 0, sizeof(struct i2c_board_info));

info.addr = addr;

// 设置info.type

err = driver->detect(temp_client, &info);

i2c_new_device

现在来具体写一个IIC设备驱动程序,驱动源码

static struct i2c_client *at24cxx_client;

static int at24cxx_dev_init(void)

{

struct i2c_adapter *i2c_adap;

i2c_adap = i2c_get_adapter(0);

at24cxx_client = i2c_new_device(i2c_adap,

&at24cxx_info);

i2c_put_adapter(i2c_adap);

return 0;

}

static struct i2c_driver at24cxx_driver = {

.driver = {

.name = "100ask",

.owner = THIS_MODULE,

},

.probe = at24cxx_probe,

.remove = __devexit_p(at24cxx_remove),

.id_table = at24cxx_id_table,

};

static int at24cxx_drv_init(void)

{

i2c_add_driver(&at24cxx_driver);

return 0;

}

i2c_add_driver

>i2c_register_driver

,i2c_register_driver函数里driver->driver.bus = &i2c_bus_type;

i2c_bus_type

>i2c_device_probe,

i2c_device_probe函数里 status

= driver->probe(client, i2c_match_id(driver->id_table,

client));调用了i2c_driver里的probe函数。

i2c_add_driver

>i2c_register_driver

>__process_new_driver

> i2c_do_add_adapter

> i2c_detect 里,

if (!driver->detect || !address_list)

return 0;

如果i2c_driver没有提供detect函数,则不创建i2c_client。

i2c_detect

>i2c_detect_address里i2c_new_device最终创建i2c_client对象。

iic_core.c文件里为我们封装了几种IIC设备的操作方式,如下

s32 i2c_smbus_read_byte(const struct i2c_client

*client)

读一个字节数据,不需要指定数据地址

s32 i2c_smbus_write_byte(const struct i2c_client *client, u8

value)

写一个字节数据,不需要指定数据地址

s32 i2c_smbus_read_byte_data(const struct i2c_client *client,

u8 command)

读一个字节数据,需要指定数据地址,参数command即为数据地址

s32 i2c_smbus_write_byte_data(const struct i2c_client *client,

u8 command,u8 value)

写一个字节数据,需要指定数据地址,指定数据值,参数command即为数据地址,参数value为数据值

s32 i2c_smbus_read_word_data(const struct i2c_client *client,

u8 command)

读一个字数据,需要指定数据地址,参数command即为数据地址

s32 i2c_smbus_write_word_data(const struct i2c_client *client,

u8 command,u16 value)

写一个字数据,需要指定数据地址,参数command即为数据地址,参数value为数据值,

注意(这里面的Word是16位的数据)

里面还封装了其他比如一块一块的读写数据的函数,这里就不一

一列出来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值