Re: [PATCH] iio: chemical: vz89x: rework i2c transfer reading

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Nov 22, 2015 at 1:32 AM, Jonathan Cameron <jic23@xxxxxxxxxx> wrote:
> On 18/11/15 01:49, Matt Ranostay wrote:
>> Remove racey i2c_smbus_read_byte() calls in measurement
>> reading function with an single i2c_transfer.
>>
>> Signed-off-by: Matt Ranostay <mranostay@xxxxxxxxx>
> As with the lidar sensor, this requires a more sophisticated I2C master
> so you should be checking if it is capable of doing what you need here.
> Also, ideally provide a fallback to smbus for those cases where the
> controller isn't sophisticated enough with appropriate locking to protect
> the device...

Ok should be simple enough. Is there an example of an iio driver doing
this currently that I could use a reference?

Thanks,

Matt

>
> Jonathan
>> ---
>>  drivers/iio/chemical/vz89x.c | 33 +++++++++++++++++++++++----------
>>  1 file changed, 23 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c
>> index 11e59a5..c03f988 100644
>> --- a/drivers/iio/chemical/vz89x.c
>> +++ b/drivers/iio/chemical/vz89x.c
>> @@ -100,27 +100,40 @@ static int vz89x_measurement_is_valid(struct vz89x_data *data)
>>       return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0);
>>  }
>>
>> +static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd)
>> +{
>> +     struct i2c_client *client = data->client;
>> +     struct i2c_msg msg[2];
>> +     int ret;
>> +     u8 buf[3] = { cmd, 0, 0};
>> +
>> +     msg[0].addr = client->addr;
>> +     msg[0].flags = client->flags;
>> +     msg[0].len = 3;
>> +     msg[0].buf  = (char *) &buf;
>> +
>> +     msg[1].addr = client->addr;
>> +     msg[1].flags = client->flags | I2C_M_RD;
>> +     msg[1].len = VZ89X_REG_MEASUREMENT_SIZE;
>> +     msg[1].buf = (char *) &data->buffer;
>> +
>> +     ret = i2c_transfer(client->adapter, msg, 2);
>> +
>> +     return (ret == VZ89X_REG_MEASUREMENT_SIZE) ? 0 : ret;
>> +}
>> +
>>  static int vz89x_get_measurement(struct vz89x_data *data)
>>  {
>>       int ret;
>> -     int i;
>>
>>       /* sensor can only be polled once a second max per datasheet */
>>       if (!time_after(jiffies, data->last_update + HZ))
>>               return 0;
>>
>> -     ret = i2c_smbus_write_word_data(data->client,
>> -                                     VZ89X_REG_MEASUREMENT, 0);
>> +     ret = vz89x_i2c_xfer(data, VZ89X_REG_MEASUREMENT);
>>       if (ret < 0)
>>               return ret;
>>
>> -     for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) {
>> -             ret = i2c_smbus_read_byte(data->client);
>> -             if (ret < 0)
>> -                     return ret;
>> -             data->buffer[i] = ret;
>> -     }
>> -
>>       ret = vz89x_measurement_is_valid(data);
>>       if (ret)
>>               return -EAGAIN;
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux