Linux内核版本:Linux 4.4.153
设备树:
hello@3e {
compatible = "HELLO1,HELLO2";
reg = <0x3e>;
};
驱动代码:
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
struct hello_data {
struct i2c_client *client;
};
/* 从i2c读数据 */
static int hello_i2c_reg_read(struct i2c_client *client, unsigned char addr)
{
return i2c_smbus_read_byte_data(client, addr & 0xff);
}
/* 向i2c写数据 */
static int hello_i2c_reg_write(struct i2c_client *client,
unsigned char addr, unsigned char val)
{
return i2c_smbus_write_byte_data(client, addr & 0xff, val);
}
static int hello_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct hello_data* hello;
hello = kzalloc(sizeof(struct hello_data), GFP_KERNEL);
if (!hello) {
err("alloc hello err!");
return -ENOMEM;
}
hello->client = client;
printk(KERN_DEBUG "enter! addr=0x%x, name=%s\n",
client->addr, client->name);
return 0;
}
static int hello_remove(struct i2c_client *client)
{
return 0;
}
static int __maybe_unused hello_suspend(struct device *dev)
{
return 0;
}
static int __maybe_unused hello_resume(struct device *dev)
{
return 0;
}
static SIMPLE_DEV_PM_OPS(hello_pm, hello_suspend,
hello_resume);
static const struct of_device_id hello_of_match[] = {
{.compatible = "HELLO1,HELLO2",},
{}
};
static const struct i2c_device_id hello_id_table[] = {
{ "hello_i2c", 0 },
{}
};
MODULE_DEVICE_TABLE(i2c, hello_id_table);
static struct i2c_driver hello_driver = {
.driver = {
.name = "hello",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(hello_of_match),
.pm = &hello_pm,
},
.probe = hello_probe,
.remove = hello_remove,
.id_table = hello_id_table,
};
module_i2c_driver(hello_driver);
MODULE_DESCRIPTION("xxxxxx hello driver");
MODULE_AUTHOR("Liuguichao");
MODULE_LICENSE("GPL");
笔记:
1. 设备树中的compatible属性在I2C中的使用
假如设备树中 compatible = "x1x1,x2x2x2x2,x3x3";
在struct i2c_client *client中,
client->name = "x2x2x2x2,x3x3";
client->name限定在20个字符以内,不管compatible有多长,都会显示第一个逗号后面19个字符加一个'\0'字符。
2. struct i2c_client *client->adapter->nr
这个值标记了当前所用的I2C是第几组I2C,对应设备树种的i2c_1,i2c_2等等后面这个数字。