* [PATCH v3 0/1] iio: chemical: vz89x: rework i2c transfer reading
@ 2015-12-02 5:47 Matt Ranostay
2015-12-02 5:47 ` [PATCH v3 1/1] " Matt Ranostay
0 siblings, 1 reply; 3+ messages in thread
From: Matt Ranostay @ 2015-12-02 5:47 UTC (permalink / raw)
To: linux-iio, jic23; +Cc: Matt Ranostay
Changes from v2:
* change incorrect i2c_transfer function return check from message length
to messages executed
Matt Ranostay (1):
iio: chemical: vz89x: rework i2c transfer reading
drivers/iio/chemical/vz89x.c | 66 ++++++++++++++++++++++++++++++++++----------
1 file changed, 52 insertions(+), 14 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 1/1] iio: chemical: vz89x: rework i2c transfer reading
2015-12-02 5:47 [PATCH v3 0/1] iio: chemical: vz89x: rework i2c transfer reading Matt Ranostay
@ 2015-12-02 5:47 ` Matt Ranostay
2015-12-03 18:35 ` Jonathan Cameron
0 siblings, 1 reply; 3+ messages in thread
From: Matt Ranostay @ 2015-12-02 5:47 UTC (permalink / raw)
To: linux-iio, jic23; +Cc: Matt Ranostay
Add an optimized i2c transfer reading function, and fallback
to racey smbus transfers if client->adapter doesn't support this.
Signed-off-by: Matt Ranostay <mranostay@gmail.com>
---
drivers/iio/chemical/vz89x.c | 66 ++++++++++++++++++++++++++++++++++----------
1 file changed, 52 insertions(+), 14 deletions(-)
diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c
index 11e59a5..b8b8049 100644
--- a/drivers/iio/chemical/vz89x.c
+++ b/drivers/iio/chemical/vz89x.c
@@ -34,8 +34,9 @@
struct vz89x_data {
struct i2c_client *client;
struct mutex lock;
- unsigned long last_update;
+ int (*xfer)(struct vz89x_data *data, u8 cmd);
+ unsigned long last_update;
u8 buffer[VZ89X_REG_MEASUREMENT_SIZE];
};
@@ -100,27 +101,60 @@ static int vz89x_measurement_is_valid(struct vz89x_data *data)
return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0);
}
-static int vz89x_get_measurement(struct vz89x_data *data)
+static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd)
{
+ struct i2c_client *client = data->client;
+ struct i2c_msg msg[2];
int ret;
- int i;
+ u8 buf[3] = { cmd, 0, 0};
- /* sensor can only be polled once a second max per datasheet */
- if (!time_after(jiffies, data->last_update + HZ))
- return 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);
- ret = i2c_smbus_write_word_data(data->client,
- VZ89X_REG_MEASUREMENT, 0);
+ return (ret == 2) ? 0 : ret;
+}
+
+static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
+{
+ struct i2c_client *client = data->client;
+ int ret;
+ int i;
+
+ ret = i2c_smbus_write_word_data(client, cmd, 0);
if (ret < 0)
return ret;
for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) {
- ret = i2c_smbus_read_byte(data->client);
+ ret = i2c_smbus_read_byte(client);
if (ret < 0)
return ret;
data->buffer[i] = ret;
}
+ return 0;
+}
+
+static int vz89x_get_measurement(struct vz89x_data *data)
+{
+ int ret;
+
+ /* sensor can only be polled once a second max per datasheet */
+ if (!time_after(jiffies, data->last_update + HZ))
+ return 0;
+
+ ret = data->xfer(data, VZ89X_REG_MEASUREMENT);
+ if (ret < 0)
+ return ret;
+
ret = vz89x_measurement_is_valid(data);
if (ret)
return -EAGAIN;
@@ -204,15 +238,19 @@ static int vz89x_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct vz89x_data *data;
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BYTE))
- return -ENODEV;
-
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
-
data = iio_priv(indio_dev);
+
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ data->xfer = vz89x_i2c_xfer;
+ else if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE))
+ data->xfer = vz89x_smbus_xfer;
+ else
+ return -ENOTSUPP;
+
i2c_set_clientdata(client, indio_dev);
data->client = client;
data->last_update = jiffies - HZ;
--
1.9.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3 1/1] iio: chemical: vz89x: rework i2c transfer reading
2015-12-02 5:47 ` [PATCH v3 1/1] " Matt Ranostay
@ 2015-12-03 18:35 ` Jonathan Cameron
0 siblings, 0 replies; 3+ messages in thread
From: Jonathan Cameron @ 2015-12-03 18:35 UTC (permalink / raw)
To: Matt Ranostay, linux-iio
On 02/12/15 05:47, Matt Ranostay wrote:
> Add an optimized i2c transfer reading function, and fallback
> to racey smbus transfers if client->adapter doesn't support this.
>
> Signed-off-by: Matt Ranostay <mranostay@gmail.com>
Hmm. The change from V2 is always an interesting one... Partial transfers
are rather unusual and usually mean thoroughly broken hardware..
Ah well, I don't really care either way so applied this version to the togreg
branch of iio.git - pushed out as testing.
> ---
> drivers/iio/chemical/vz89x.c | 66 ++++++++++++++++++++++++++++++++++----------
> 1 file changed, 52 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c
> index 11e59a5..b8b8049 100644
> --- a/drivers/iio/chemical/vz89x.c
> +++ b/drivers/iio/chemical/vz89x.c
> @@ -34,8 +34,9 @@
> struct vz89x_data {
> struct i2c_client *client;
> struct mutex lock;
> - unsigned long last_update;
> + int (*xfer)(struct vz89x_data *data, u8 cmd);
>
> + unsigned long last_update;
> u8 buffer[VZ89X_REG_MEASUREMENT_SIZE];
> };
>
> @@ -100,27 +101,60 @@ static int vz89x_measurement_is_valid(struct vz89x_data *data)
> return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0);
> }
>
> -static int vz89x_get_measurement(struct vz89x_data *data)
> +static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd)
> {
> + struct i2c_client *client = data->client;
> + struct i2c_msg msg[2];
> int ret;
> - int i;
> + u8 buf[3] = { cmd, 0, 0};
>
> - /* sensor can only be polled once a second max per datasheet */
> - if (!time_after(jiffies, data->last_update + HZ))
> - return 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);
>
> - ret = i2c_smbus_write_word_data(data->client,
> - VZ89X_REG_MEASUREMENT, 0);
> + return (ret == 2) ? 0 : ret;
> +}
> +
> +static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
> +{
> + struct i2c_client *client = data->client;
> + int ret;
> + int i;
> +
> + ret = i2c_smbus_write_word_data(client, cmd, 0);
> if (ret < 0)
> return ret;
>
> for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) {
> - ret = i2c_smbus_read_byte(data->client);
> + ret = i2c_smbus_read_byte(client);
> if (ret < 0)
> return ret;
> data->buffer[i] = ret;
> }
>
> + return 0;
> +}
> +
> +static int vz89x_get_measurement(struct vz89x_data *data)
> +{
> + int ret;
> +
> + /* sensor can only be polled once a second max per datasheet */
> + if (!time_after(jiffies, data->last_update + HZ))
> + return 0;
> +
> + ret = data->xfer(data, VZ89X_REG_MEASUREMENT);
> + if (ret < 0)
> + return ret;
> +
> ret = vz89x_measurement_is_valid(data);
> if (ret)
> return -EAGAIN;
> @@ -204,15 +238,19 @@ static int vz89x_probe(struct i2c_client *client,
> struct iio_dev *indio_dev;
> struct vz89x_data *data;
>
> - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
> - I2C_FUNC_SMBUS_BYTE))
> - return -ENODEV;
> -
> indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> if (!indio_dev)
> return -ENOMEM;
> -
> data = iio_priv(indio_dev);
> +
> + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> + data->xfer = vz89x_i2c_xfer;
> + else if (i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE))
> + data->xfer = vz89x_smbus_xfer;
> + else
> + return -ENOTSUPP;
> +
> i2c_set_clientdata(client, indio_dev);
> data->client = client;
> data->last_update = jiffies - HZ;
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-12-03 18:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-02 5:47 [PATCH v3 0/1] iio: chemical: vz89x: rework i2c transfer reading Matt Ranostay
2015-12-02 5:47 ` [PATCH v3 1/1] " Matt Ranostay
2015-12-03 18:35 ` Jonathan Cameron
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.