9cbcd81546e59820940f8dba717eae9b109308b1
[openwrt/staging/ldir.git] /
1 From 7aebec709ea87dafb9776895c4c2626a659e043c Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 23 Apr 2020 10:17:18 +0100
4 Subject: [PATCH] drm/panel/raspberrypi-touchscreen: Use independent
5 I2C actions with delay.
6
7 We now have the hardware I2C controller pinmuxed to the drive the
8 display I2C, but this controller does not support clock stretching.
9 The Atmel micro-controller in the panel requires clock stretching
10 to allow it to prepare any data to be read.
11
12 Split the rpi_touchscreen_i2c_read into two independent transactions with
13 a delay between them for the Atmel to prepare the data.
14
15 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 ---
17 .../drm/panel/panel-raspberrypi-touchscreen.c | 30 ++++++++++++++++++-
18 1 file changed, 29 insertions(+), 1 deletion(-)
19
20 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
21 +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
22 @@ -220,7 +220,35 @@ static struct rpi_touchscreen *panel_to_
23
24 static int rpi_touchscreen_i2c_read(struct rpi_touchscreen *ts, u8 reg)
25 {
26 - return i2c_smbus_read_byte_data(ts->i2c, reg);
27 + struct i2c_client *client = ts->i2c;
28 + struct i2c_msg msgs[1];
29 + u8 addr_buf[1] = { reg };
30 + u8 data_buf[1] = { 0, };
31 + int ret;
32 +
33 + /* Write register address */
34 + msgs[0].addr = client->addr;
35 + msgs[0].flags = 0;
36 + msgs[0].len = ARRAY_SIZE(addr_buf);
37 + msgs[0].buf = addr_buf;
38 +
39 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
40 + if (ret != ARRAY_SIZE(msgs))
41 + return -EIO;
42 +
43 + usleep_range(100, 300);
44 +
45 + /* Read data from register */
46 + msgs[0].addr = client->addr;
47 + msgs[0].flags = I2C_M_RD;
48 + msgs[0].len = 1;
49 + msgs[0].buf = data_buf;
50 +
51 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
52 + if (ret != ARRAY_SIZE(msgs))
53 + return -EIO;
54 +
55 + return data_buf[0];
56 }
57
58 static void rpi_touchscreen_i2c_write(struct rpi_touchscreen *ts,