@@ -103,6 +103,13 @@ static const struct iio_info si7020_info = {
.read_raw = si7020_read_raw,
};
+static void si7020_xfer_callback(void *data, int xfer_rc)
+{
+ /* Wait the maximum power-up time after software reset. */
+ if (!xfer_rc)
+ msleep(15);
+}
+
static int si7020_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -115,12 +122,13 @@ static int si7020_probe(struct i2c_client *client,
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EOPNOTSUPP;
+ i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
+ i2c_adapter_xfer_callback(client->adapter, si7020_xfer_callback, NULL);
/* Reset device, loads default settings. */
ret = i2c_smbus_write_byte(client, SI7020CMD_RESET);
+ i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
if (ret < 0)
return ret;
- /* Wait the maximum power-up time after software reset. */
- msleep(15);
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
While the SI7020 is starting up after power on or reset, any I2C commands on the bus can potentially upset the startup sequence. Therefore, the host needs to wait for the startup sequence to finish before issuing further i2c commands. This is impractical in cases where the SI7020 is on a shared bus or behind a mux, which may switch channels at any time (potentially generating I2C traffic). To resolve this, use the new transfer callback on the adapter to sleep the required interval. Signed-off-by: Eddie James <eajames@linux.ibm.com> --- drivers/iio/humidity/si7020.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)