I2C Driver Example
The following demo shows how to implement a I2C driver and transfer data using I2C APIs
of Linux. In this demo, “xxx” represents the name of the I2C
client
device.
static int write_reg(struct i2c_client *client, u16 reg, u8 val)
{
struct i2c_msg msg;
u8 buf[3];
int ret;
buf[0] = reg >> 8;
buf[1] = reg & 0xff;
buf[2] = val;
msg.addr = client->addr;
msg.flags = client->flags;
msg.buf = buf;
msg.len = sizeof(buf);
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret < 0) {
dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
__func__, reg, val);
return ret;
}
return 0;
}
static int read_reg(struct i2c_client *client, u16 reg, u8 *val)
{
struct i2c_msg msg[2];
u8 buf[2];
int ret;
buf[0] = reg >> 8;
buf[1] = reg & 0xff;
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].buf = buf;
msg[0].len = sizeof(buf);
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].buf = buf;
msg[1].len = 1;
ret = i2c_transfer(client->adapter, msg, 2);
if (ret < 0) {
dev_err(&client->dev, "%s: error: reg=%x\n",
__func__, reg);
return ret;
}
*val = buf[0];
return 0;
}
//...
//use function write_reg(), read_reg() to operate registers
//...
//Achieve function probe_new() and remove() of i2c_driver
static int xxx_probe(struct i2c_client *client);
static int xxx_remove(struct i2c_client *client);
static const struct i2c_device_id xxx_id[] = {
{"xxx", 0},
{},
};
MODULE_DEVICE_TABLE(i2c, xxx_id);
static const struct of_device_id xxx_dt_ids[] = {
{ .compatible = "xxx" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, xxx_dt_ids);
static struct i2c_driver xxx_i2c_driver = {
.driver = {
.name = "xxx",
.of_match_table = xxx_dt_ids,
},
.id_table = xxx_id,
.probe_new = xxx_probe,
.remove = xxx_remove,
};
module_i2c_driver(xxx_i2c_driver);
