mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 09:39:00 +00:00
69 lines
1.9 KiB
Diff
69 lines
1.9 KiB
Diff
|
From de0ad7df43a7399f9c09394b35d74bc75ebc60a4 Mon Sep 17 00:00:00 2001
|
||
|
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||
|
Date: Thu, 25 Nov 2021 14:50:10 +0000
|
||
|
Subject: [PATCH] regulator/rpi-panel-attiny: Use two transactions for
|
||
|
I2C read
|
||
|
|
||
|
The I2C to the Atmel is very fussy, and locks up easily on
|
||
|
Pi0-3 particularly on reads.
|
||
|
If running at 100kHz on Pi3, reading the ID register generally
|
||
|
locks up the Atmel, but splitting the register select write and
|
||
|
read into two transactions is reliable.
|
||
|
|
||
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||
|
---
|
||
|
.../regulator/rpi-panel-attiny-regulator.c | 35 ++++++++++++++++++-
|
||
|
1 file changed, 34 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/drivers/regulator/rpi-panel-attiny-regulator.c
|
||
|
+++ b/drivers/regulator/rpi-panel-attiny-regulator.c
|
||
|
@@ -234,6 +234,39 @@ static void attiny_gpio_set(struct gpio_
|
||
|
mutex_unlock(&state->lock);
|
||
|
}
|
||
|
|
||
|
+static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf)
|
||
|
+{
|
||
|
+ struct i2c_msg msgs[1];
|
||
|
+ u8 addr_buf[1] = { reg };
|
||
|
+ u8 data_buf[1] = { 0, };
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ /* Write register address */
|
||
|
+ msgs[0].addr = client->addr;
|
||
|
+ msgs[0].flags = 0;
|
||
|
+ msgs[0].len = ARRAY_SIZE(addr_buf);
|
||
|
+ msgs[0].buf = addr_buf;
|
||
|
+
|
||
|
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||
|
+ if (ret != ARRAY_SIZE(msgs))
|
||
|
+ return -EIO;
|
||
|
+
|
||
|
+ usleep_range(5000, 10000);
|
||
|
+
|
||
|
+ /* Read data from register */
|
||
|
+ msgs[0].addr = client->addr;
|
||
|
+ msgs[0].flags = I2C_M_RD;
|
||
|
+ msgs[0].len = 1;
|
||
|
+ msgs[0].buf = data_buf;
|
||
|
+
|
||
|
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||
|
+ if (ret != ARRAY_SIZE(msgs))
|
||
|
+ return -EIO;
|
||
|
+
|
||
|
+ *buf = data_buf[0];
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* I2C driver interface functions
|
||
|
*/
|
||
|
@@ -264,7 +297,7 @@ static int attiny_i2c_probe(struct i2c_c
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
- ret = regmap_read(regmap, REG_ID, &data);
|
||
|
+ ret = attiny_i2c_read(i2c, REG_ID, &data);
|
||
|
if (ret < 0) {
|
||
|
dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret);
|
||
|
goto error;
|