Last active 1739510751

Adrian's Avatar Adrian revised this gist 1739510750. Go to revision

3 files changed, 355 insertions

gistfile1.txt(file created)

@@ -0,0 +1,52 @@
1 + From 7d24a43841a62bae825d0f0c2742f19fdf0ccb37 Mon Sep 17 00:00:00 2001
2 + From: Jens Reidel <[email protected]>
3 + Date: Fri, 14 Feb 2025 05:55:19 +0100
4 + Subject: [PATCH v2 0/2] Add Goodix Berlin-A series support
5 +
6 + This series adds support for the Goodix Berlin-A series touch ICs
7 + (gt9897). This was tested on a Xiaomi 11 Lite 5G NE (xiaomi-lisa),
8 + which uses the gt9897 IC connected over SPI. I am not aware of any
9 + device that has gt9897 connected over I2C and therefore could not
10 + test it, so I didn't add a compatible in the I2C driver.
11 +
12 + Changes in v2:
13 + - Added Rob's A-b tag (patch no. 1)
14 + - Added Luca's T-b tag (patch no. 2)
15 + - Updated the i2c and spi device id tables with the driver data and
16 + switched to spi_get_device_match_data where possible (requested by
17 + Neil)
18 + - Switched to device_get_match_data in goodix_berlin_core.c
19 + - Move all revision specific addresses and other properties into the
20 + goodix_berlin_ic_data struct (requested by Dmitry)
21 + - Link to v1: https://lore.kernel.org/all/[email protected]/
22 +
23 + To: Dmitry Torokhov <[email protected]>
24 + To: Rob Herring <[email protected]>
25 + To: Krzysztof Kozlowski <krzk+[email protected]>
26 + To: Conor Dooley <conor+[email protected]>
27 + To: Bastien Nocera <[email protected]>
28 + To: Hans de Goede <[email protected]>
29 + To: Neil Armstrong <[email protected]>
30 + Cc: Luca Weiss <[email protected]>
31 + Cc: [email protected]
32 + Cc: [email protected]
33 + Cc: [email protected]
34 + Cc: [email protected]
35 + Cc: [email protected]
36 + Cc: ~postmarketos/[email protected]
37 + Signed-off-by: Jens Reidel <[email protected]>
38 +
39 + Jens Reidel (2):
40 + dt-bindings: input: goodix,gt9916: Document gt9897 compatible
41 + Input: goodix_berlin - Add support for Berlin-A series
42 +
43 + .../input/touchscreen/goodix,gt9916.yaml | 1 +
44 + drivers/input/touchscreen/goodix_berlin.h | 13 ++++++
45 + .../input/touchscreen/goodix_berlin_core.c | 15 ++++---
46 + drivers/input/touchscreen/goodix_berlin_i2c.c | 9 +++-
47 + drivers/input/touchscreen/goodix_berlin_spi.c | 45 ++++++++++++++-----
48 + 5 files changed, 62 insertions(+), 21 deletions(-)
49 +
50 + --
51 + 2.48.1
52 +

gistfile2.txt(file created)

@@ -0,0 +1,30 @@
1 + From 2fe231536c6e44037abc552e82c2d5c2b9724bc1 Mon Sep 17 00:00:00 2001
2 + From: Jens Reidel <[email protected]>
3 + Date: Mon, 3 Feb 2025 18:04:13 +0100
4 + Subject: [PATCH v2 1/2] dt-bindings: input: goodix,gt9916: Document gt9897
5 + compatible
6 +
7 + Document the Goodix GT9897 which is a Berlin-A series touchscreen
8 + controller IC by Goodix.
9 +
10 + Acked-by: Rob Herring (Arm) <[email protected]>
11 + Signed-off-by: Jens Reidel <[email protected]>
12 + ---
13 + .../devicetree/bindings/input/touchscreen/goodix,gt9916.yaml | 1 +
14 + 1 file changed, 1 insertion(+)
15 +
16 + diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml b/Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
17 + index d90f045ac06c..c40d92b7f4af 100644
18 + --- a/Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
19 + +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
20 + @@ -19,6 +19,7 @@ allOf:
21 + properties:
22 + compatible:
23 + enum:
24 + + - goodix,gt9897
25 + - goodix,gt9916
26 +
27 + reg:
28 + --
29 + 2.48.1
30 +

gistfile3.txt(file created)

@@ -0,0 +1,273 @@
1 + From 7d24a43841a62bae825d0f0c2742f19fdf0ccb37 Mon Sep 17 00:00:00 2001
2 + From: Jens Reidel <[email protected]>
3 + Date: Sun, 22 Dec 2024 17:08:18 +0100
4 + Subject: [PATCH v2 2/2] Input: goodix_berlin - Add support for Berlin-A series
5 +
6 + The current implementation of the goodix_berlin driver lacks support for
7 + revisions A and B of the Berlin IC. This change adds support for the
8 + gt9897 IC, which is a Berlin-A revision part.
9 +
10 + The differences between revision D and A are rather minor, a handful of
11 + address changes and a slightly larger read buffer. They were taken from
12 + the driver published by Goodix, which does a few more things that don't
13 + appear to be necessary for the touchscreen to work properly.
14 +
15 + Signed-off-by: Jens Reidel <[email protected]>
16 + Tested-by: Luca Weiss <[email protected]>
17 + ---
18 + drivers/input/touchscreen/goodix_berlin.h | 13 ++++++
19 + .../input/touchscreen/goodix_berlin_core.c | 15 ++++---
20 + drivers/input/touchscreen/goodix_berlin_i2c.c | 9 +++-
21 + drivers/input/touchscreen/goodix_berlin_spi.c | 45 ++++++++++++++-----
22 + 4 files changed, 61 insertions(+), 21 deletions(-)
23 +
24 + diff --git a/drivers/input/touchscreen/goodix_berlin.h b/drivers/input/touchscreen/goodix_berlin.h
25 + index 38b6f9ddbdef..b186a7fb3586 100644
26 + --- a/drivers/input/touchscreen/goodix_berlin.h
27 + +++ b/drivers/input/touchscreen/goodix_berlin.h
28 + @@ -12,6 +12,19 @@
29 +
30 + #include <linux/pm.h>
31 +
32 + +#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR_A 0x1000C
33 + +#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D 0x10014
34 + +
35 + +#define GOODIX_BERLIN_IC_INFO_ADDR_A 0x10068
36 + +#define GOODIX_BERLIN_IC_INFO_ADDR_D 0x10070
37 + +
38 + +struct goodix_berlin_ic_data {
39 + + int fw_version_info_addr;
40 + + int ic_info_addr;
41 + + ssize_t read_dummy_len;
42 + + ssize_t read_prefix_len;
43 + +};
44 + +
45 + struct device;
46 + struct input_id;
47 + struct regmap;
48 + diff --git a/drivers/input/touchscreen/goodix_berlin_core.c b/drivers/input/touchscreen/goodix_berlin_core.c
49 + index 3fc03cf0ca23..f9fbde63ab52 100644
50 + --- a/drivers/input/touchscreen/goodix_berlin_core.c
51 + +++ b/drivers/input/touchscreen/goodix_berlin_core.c
52 + @@ -12,7 +12,7 @@
53 + * to the previous generations.
54 + *
55 + * Currently the driver only handles Multitouch events with already
56 + - * programmed firmware and "config" for "Revision D" Berlin IC.
57 + + * programmed firmware and "config" for "Revision A/D" Berlin IC.
58 + *
59 + * Support is missing for:
60 + * - ESD Management
61 + @@ -20,7 +20,7 @@
62 + * - "Config" update/flashing
63 + * - Stylus Events
64 + * - Gesture Events
65 + - * - Support for older revisions (A & B)
66 + + * - Support for revision B
67 + */
68 +
69 + #include <linux/bitfield.h>
70 + @@ -28,6 +28,7 @@
71 + #include <linux/input.h>
72 + #include <linux/input/mt.h>
73 + #include <linux/input/touchscreen.h>
74 + +#include <linux/property.h>
75 + #include <linux/regmap.h>
76 + #include <linux/regulator/consumer.h>
77 + #include <linux/sizes.h>
78 + @@ -53,10 +54,8 @@
79 +
80 + #define GOODIX_BERLIN_DEV_CONFIRM_VAL 0xAA
81 + #define GOODIX_BERLIN_BOOTOPTION_ADDR 0x10000
82 + -#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR 0x10014
83 +
84 + #define GOODIX_BERLIN_IC_INFO_MAX_LEN SZ_1K
85 + -#define GOODIX_BERLIN_IC_INFO_ADDR 0x10070
86 +
87 + #define GOODIX_BERLIN_CHECKSUM_SIZE sizeof(u16)
88 +
89 + @@ -297,9 +296,10 @@ static void goodix_berlin_power_off(struct goodix_berlin_core *cd)
90 +
91 + static int goodix_berlin_read_version(struct goodix_berlin_core *cd)
92 + {
93 + + const struct goodix_berlin_ic_data *ic_data = device_get_match_data(cd->dev);
94 + int error;
95 +
96 + - error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_FW_VERSION_INFO_ADDR,
97 + + error = regmap_raw_read(cd->regmap, ic_data->fw_version_info_addr,
98 + &cd->fw_version, sizeof(cd->fw_version));
99 + if (error) {
100 + dev_err(cd->dev, "error reading fw version, %d\n", error);
101 + @@ -358,6 +358,7 @@ static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd,
102 +
103 + static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
104 + {
105 + + const struct goodix_berlin_ic_data *ic_data = device_get_match_data(cd->dev);
106 + u8 *afe_data __free(kfree) = NULL;
107 + __le16 length_raw;
108 + u16 length;
109 + @@ -367,7 +368,7 @@ static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
110 + if (!afe_data)
111 + return -ENOMEM;
112 +
113 + - error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
114 + + error = regmap_raw_read(cd->regmap, ic_data->ic_info_addr,
115 + &length_raw, sizeof(length_raw));
116 + if (error) {
117 + dev_err(cd->dev, "failed get ic info length, %d\n", error);
118 + @@ -380,7 +381,7 @@ static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
119 + return -EINVAL;
120 + }
121 +
122 + - error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
123 + + error = regmap_raw_read(cd->regmap, ic_data->ic_info_addr,
124 + afe_data, length);
125 + if (error) {
126 + dev_err(cd->dev, "failed get ic info data, %d\n", error);
127 + diff --git a/drivers/input/touchscreen/goodix_berlin_i2c.c b/drivers/input/touchscreen/goodix_berlin_i2c.c
128 + index ad7a60d94338..7db234c74db8 100644
129 + --- a/drivers/input/touchscreen/goodix_berlin_i2c.c
130 + +++ b/drivers/input/touchscreen/goodix_berlin_i2c.c
131 + @@ -46,15 +46,20 @@ static int goodix_berlin_i2c_probe(struct i2c_client *client)
132 + return 0;
133 + }
134 +
135 + +static const struct goodix_berlin_ic_data gt9916_data = {
136 + + .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D,
137 + + .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_D,
138 + +};
139 + +
140 + static const struct i2c_device_id goodix_berlin_i2c_id[] = {
141 + - { "gt9916" },
142 + + { .name = "gt9916", .driver_data = (long)&gt9916_data },
143 + { }
144 + };
145 +
146 + MODULE_DEVICE_TABLE(i2c, goodix_berlin_i2c_id);
147 +
148 + static const struct of_device_id goodix_berlin_i2c_of_match[] = {
149 + - { .compatible = "goodix,gt9916", },
150 + + { .compatible = "goodix,gt9916", .data = &gt9916_data },
151 + { }
152 + };
153 + MODULE_DEVICE_TABLE(of, goodix_berlin_i2c_of_match);
154 + diff --git a/drivers/input/touchscreen/goodix_berlin_spi.c b/drivers/input/touchscreen/goodix_berlin_spi.c
155 + index 0662e87b8692..a5e77e6585e8 100644
156 + --- a/drivers/input/touchscreen/goodix_berlin_spi.c
157 + +++ b/drivers/input/touchscreen/goodix_berlin_spi.c
158 + @@ -18,10 +18,14 @@
159 +
160 + #define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN 1
161 + #define GOODIX_BERLIN_REGISTER_WIDTH 4
162 + -#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN 3
163 + -#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
164 + +#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A 4
165 + +#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D 3
166 + +#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
167 + GOODIX_BERLIN_REGISTER_WIDTH + \
168 + - GOODIX_BERLIN_SPI_READ_DUMMY_LEN)
169 + + GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A)
170 + +#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
171 + + GOODIX_BERLIN_REGISTER_WIDTH + \
172 + + GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D)
173 + #define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
174 + GOODIX_BERLIN_REGISTER_WIDTH)
175 +
176 + @@ -33,6 +37,7 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
177 + size_t val_size)
178 + {
179 + struct spi_device *spi = context;
180 + + const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
181 + struct spi_transfer xfers;
182 + struct spi_message spi_msg;
183 + const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
184 + @@ -42,23 +47,22 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
185 + return -EINVAL;
186 +
187 + u8 *buf __free(kfree) =
188 + - kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size,
189 + - GFP_KERNEL);
190 + + kzalloc(ic_data->read_prefix_len + val_size, GFP_KERNEL);
191 + if (!buf)
192 + return -ENOMEM;
193 +
194 + spi_message_init(&spi_msg);
195 + memset(&xfers, 0, sizeof(xfers));
196 +
197 + - /* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
198 + + /* buffer format: 0xF1 + addr(4bytes) + dummy(3/4bytes) + data */
199 + buf[0] = GOODIX_BERLIN_SPI_READ_FLAG;
200 + put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
201 + memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH,
202 + - 0xff, GOODIX_BERLIN_SPI_READ_DUMMY_LEN);
203 + + 0xff, ic_data->read_dummy_len);
204 +
205 + xfers.tx_buf = buf;
206 + xfers.rx_buf = buf;
207 + - xfers.len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size;
208 + + xfers.len = ic_data->read_prefix_len + val_size;
209 + xfers.cs_change = 0;
210 + spi_message_add_tail(&xfers, &spi_msg);
211 +
212 + @@ -68,7 +72,7 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
213 + return error;
214 + }
215 +
216 + - memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);
217 + + memcpy(val_buf, buf + ic_data->read_prefix_len, val_size);
218 + return error;
219 + }
220 +
221 + @@ -123,6 +127,7 @@ static const struct input_id goodix_berlin_spi_input_id = {
222 +
223 + static int goodix_berlin_spi_probe(struct spi_device *spi)
224 + {
225 + + const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
226 + struct regmap_config regmap_config;
227 + struct regmap *regmap;
228 + size_t max_size;
229 + @@ -137,7 +142,7 @@ static int goodix_berlin_spi_probe(struct spi_device *spi)
230 + max_size = spi_max_transfer_size(spi);
231 +
232 + regmap_config = goodix_berlin_spi_regmap_conf;
233 + - regmap_config.max_raw_read = max_size - GOODIX_BERLIN_SPI_READ_PREFIX_LEN;
234 + + regmap_config.max_raw_read = max_size - ic_data->read_prefix_len;
235 + regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN;
236 +
237 + regmap = devm_regmap_init(&spi->dev, NULL, spi, &regmap_config);
238 + @@ -152,14 +157,30 @@ static int goodix_berlin_spi_probe(struct spi_device *spi)
239 + return 0;
240 + }
241 +
242 + +static const struct goodix_berlin_ic_data gt9897_data = {
243 + + .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_A,
244 + + .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_A,
245 + + .read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A,
246 + + .read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A,
247 + +};
248 + +
249 + +static const struct goodix_berlin_ic_data gt9916_data = {
250 + + .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D,
251 + + .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_D,
252 + + .read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D,
253 + + .read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D,
254 + +};
255 + +
256 + static const struct spi_device_id goodix_berlin_spi_ids[] = {
257 + - { "gt9916" },
258 + + { .name = "gt9897", .driver_data = (long)&gt9897_data },
259 + + { .name = "gt9916", .driver_data = (long)&gt9916_data },
260 + { },
261 + };
262 + MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids);
263 +
264 + static const struct of_device_id goodix_berlin_spi_of_match[] = {
265 + - { .compatible = "goodix,gt9916", },
266 + + { .compatible = "goodix,gt9897", .data = &gt9897_data },
267 + + { .compatible = "goodix,gt9916", .data = &gt9916_data },
268 + { }
269 + };
270 + MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match);
271 + --
272 + 2.48.1
273 +
Newer Older