diff mbox series

[RFC,2/2] iio: humidity: si7020: Use core transfer callback to sleep after reset

Message ID 20220518204119.38943-3-eajames@linux.ibm.com (mailing list archive)
State Changes Requested
Headers show
Series i2c: core and si7020: Add adapter transfer callback | expand

Commit Message

Eddie James May 18, 2022, 8:41 p.m. UTC
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(-)
diff mbox series


diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c
index ab6537f136ba..f19e88818bd6 100644
--- a/drivers/iio/humidity/si7020.c
+++ b/drivers/iio/humidity/si7020.c
@@ -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,
 		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)