云昴

【Linux I2C】设备驱动(ADS1110)

| 【专业·学习】LinuxI2C

i2c_driver结构体对象

每一个I2C设备驱动都必须先创造一个i2c_driver结构体对象。

static struct i2c_driver ads1110_driver = {
    .driver = {
        .name = "ads1110",
    },
    .attach_adapter = &ads1110_attach_adapter,
    .detach_client = &ads1110_detach_client,
};

name 表示本驱动的名称,attach_adapter和detach_client字段为函数指针,这两个函数在I2C设备注册的时候会自动调用,需要自己实现这两个函数,后面将详细讲述。

i2c_client 结构体对象

上面定义的i2c_driver对象,抽象为一个i2c的驱动模型,提供对i2C设备的探测和注销方法,而i2c_client结构体则是代表着一个具体的i2c设备,该结构体有一个data指针,可以指向任何私有的设备数据,在复杂点的驱动中可能会用到。示例如下:

static struct ads1110_obj
{
    struct i2c_client client;
    int users;
} * g_ads1110_obj;

其中,users为示例,用户可以自己在tvp5158_obj这个结构体里面添加感兴趣的字段,但是i2c_client字段不可少。

设备注册及探测功能

这一步很关键,按照标准的要求来写,则Linux系统会自动调用相关的代码去探测你的I2C设备,并且添加到系统的I2C设备列表中以供后面访问。

我们知道,每一个I2C设备芯片,都通过硬件连接设定好了该设备的I2C设备地址。因此,I2C设备的探测一般是靠设备地址来完成的。那么,首先要在驱动代码中声明你要探测的I2C设备地址列表,以及一个宏。示例如下:

static unsigned short normal_i2c[] = {  
        0x4a,  
        I2C_CLIENT_END  
};  
I2C_CLIENT_INSMOD;

normal_i2c 数组包含了你需要探测的I2C设备地址列表,并且必须以I2C_CLIENT_END作为结尾,注意,上述代码中的0xbc和0xbe是我在硬件上为我的tvp5158分配的地址,硬件上我支持通过跳线将该地址设置为 0xbc 或者 0xbe,所以把这两个地址均写入到探测列表中,让系统进行探测。如果你的I2C设备的地址是固定的,那么,这里可以只写你自己的I2C设备地址,注意必须向右移位1。

宏 I2C_CLIENT_INSMOD 的作用网上有许多文章进行了详细的讲解,这里我就不详细描述了,记得加上就行,我们重点关注实现。

下一步就应该编写第1步中的两个回调函数,一个用于注册设备,一个用于注销设备。探测函数示例如下:

待补充

云昴