Pregunta

I have been studying I2C driver (client) code for a while. I have seen this function "i2c_get_clientdata" and "i2c_set_clientdata" every where.

I have seen the this question here . Use of pointer to structure instead of creating static local copy

Some times i think like it is like "container_of" macro to get a pointer to the structure. But still i didn't understood properly why to use it and when to use it.

Below i am posting a sample code where I see its usage. If any one could help me understand why it is used there and when we shall use it when we write our own drivers.

struct max6875_data {
    struct i2c_client       *fake_client;
    struct mutex            update_lock;

    u32                     valid;
    u8                      data[USER_EEPROM_SIZE];
    unsigned long           last_updated[USER_EEPROM_SLICES];
};

static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
                        struct bin_attribute *bin_attr,
                        char *buf, loff_t off, size_t count)
{
    struct i2c_client *client = kobj_to_i2c_client(kobj);
    struct max6875_data *data = i2c_get_clientdata(client);
    int slice, max_slice;

    if (off > USER_EEPROM_SIZE)
            return 0;

    if (off + count > USER_EEPROM_SIZE)
            count = USER_EEPROM_SIZE - off;

    /* refresh slices which contain requested bytes */
    max_slice = (off + count - 1) >> SLICE_BITS;
    for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
            max6875_update_slice(client, slice);

    memcpy(buf, &data->data[off], count);

    return count;
}
¿Fue útil?

Solución

Those functions are used to get/set the void *driver_data pointer that is part of the struct device, itself part of struct i2c_client.

This is a void pointer that is for the driver to use. One would use this pointer mainly to pass driver related data around.

That is what is happening in your example. The max6875_read is a callback getting a structu kobject. That kobject is an i2c_client which is enough to communicate with the underlying device using the driver_data pointer here allows to get back the driver related data (instead of using global variables for example).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top