[PATCH] regulator: tps65185: wait for the IC to wake before the first I2C access

Mario Rugiero <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <[email protected]>
The probe drives WAKEUP high with GPIOD_OUT_HIGH, enables the input
supply, and then issues a regmap_update_bits() on INT_EN2 with no wait
anywhere in between. The TPS65185 data sheet (TI SLVSAQ8G, February
2011, revised September 2017), section 7.6 "Timing Requirements: Data
Transmission", Figure 2 "Power-Up and Power-Down Timing Diagram",
footnote 1, requires 1.8 ms minimum between the WAKEUP rising edge and
the IC being ready to accept an I2C transaction. The driver calls no
delay function anywhere, and nothing on that path is guaranteed to take
that long.

On an RK3026 board the first transfer was NAKed:

  tps65185 0-0068: error -ENXIO: failed to enable temp irq

-ENXIO here is rk3x_i2c reporting REG_INT_NAKRCV. Probe failed, so
vposneg never registered and its consumer deferred indefinitely.

Wait after the supply rather than at the gpiod_get(). Figure 2 times
that 1.8 ms from a WAKEUP edge with VIN already up, whereas this driver
asserts WAKEUP before enabling vin-supply; the data sheet does not
describe that order, so on a board whose vin-supply is a switched
regulator that was off, a wait placed at the gpiod_get() could elapse
before the part had power. Waiting from whichever of the two comes last
satisfies the specified case and is the conservative choice in the
other.

It also goes above the interrupt request rather than immediately before
the INT_EN2 write, because that write is not necessarily the first
transfer: tps65185_irq_thread() reads INT1 and INT2, and it is
requested with IRQF_TRIGGER_LOW, so it can run as soon as the handler
is installed.

Tested on an ONYX BOOX C67ML (RK3026): the chip now probes, all three
regulators register and the EPD controller comes up.

Fixes: b0fc1e770194 ("regulator: Add TPS65185 driver")
Signed-off-by: Mario Rugiero <[email protected]>
---
 drivers/regulator/tps65185.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c
index 1f13e4156cab..6a3130177e7a 100644
--- a/drivers/regulator/tps65185.c
+++ b/drivers/regulator/tps65185.c
@@ -5,6 +5,7 @@
 
 #include <linux/cleanup.h>
 #include <linux/completion.h>
+#include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
@@ -375,6 +376,11 @@ static int tps65185_probe(struct i2c_client *client)
 		return dev_err_probe(&client->dev, ret,
 				     "failed to get vin regulator\n");
 
+	// TPS65185x PMIC for E Ink Vizplex Enabled Electronic Paper Display Chapter 7.6 Figure 2:
+	// "Minimum delay time between WAKEUP rising edge and IC ready to accept I2C transaction."
+	// https://www.ti.com/lit/ds/symlink/tps65185.pdf
+	usleep_range(1800, 3000);
+
 	data->dev = &client->dev;
 	i2c_set_clientdata(client, data);
 
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.