在内核里表示i2c设备驱动的结构体有点小变化:
struct i2c_driver {
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
//当使用id_table进行匹配时, 会把匹配上的i2c_device_id变量地址传过来.
int (*remove)(struct i2c_client *);
int (*probe_new)(struct i2c_client *); //新的probe函数
//当使用driver的of_match_table进行匹配时, probe函数的i2c_device_id参数就是多余的了, 可以改成使用probe_new函数.
...
struct device_driver driver; //driver里的of_match_table用于指定与设备树里i2c设备的匹配
const struct i2c_device_id *id_table; //id_table也可用于与设备树里i2c设备名(也就是compatible属性值)进行匹配.
...
};
如dht12连接到第0个i2c控制器, 在设备树里的描述:
i2c0: i2c@01c2ac00 { /* 控制器的设备节点 */
...
mydht12 { /* 增加的设备子节点 */
compatible = "mydht12";
reg = <0x5c>; /* 设备地址 */
};
};
//通过i2c_driver的id_table与设备树里的i2c设备进行匹配.
/* mydrv.c */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
int myprobe(struct i2c_client *cli)
{
//读出dht12的温湿度数据
u8 reg = 0, datas[5];
int i;
struct i2c_msg msgs[2] = {
{cli->addr, 0, 1, ®},
{cli->addr, I2C_M_RD, sizeof(datas), datas},
};
if (i2c_transfer(cli->adapter, msgs, 2) < 0)
{
printk("i2c transfer failed\n");
return -ENODEV;
}
printk("in probe ...\n");
for (i = 0; i < sizeof(datas); i++)
printk("%02d\n", datas[i]);
return 0;
}
int myremove(struct i2c_client *cli)
{
printk("remove ...\n");
return 0;
}
struct of_device_id ids[] = {
{.compatible = "mydht12"},
{},
};
struct i2c_device_id ids2[] = {
{"mydht12"},
{},
};
struct i2c_driver mydrv = {
.probe_new = myprobe, //使用新的probe函数
.remove = myremove,
.driver = {
.owner = THIS_MODULE,
.name = "mydrv",
// .of_match_table = ids,
},
.id_table = ids2,
};
module_i2c_driver(mydrv);
MODULE_LICENSE("GPL");