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);