hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/input/touchscreen/raydium_i2c_ts.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Raydium touchscreen I2C driver.
34 *
45 * Copyright (C) 2012-2014, Raydium Semiconductor Corporation.
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * version 2, and only version 2, as published by the
9
- * Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
156 *
167 * Raydium reserves the right to make changes without further notice
178 * to the materials described herein. Raydium does not assume any
....@@ -60,6 +51,7 @@
6051
6152 /* Touch relative info */
6253 #define RM_MAX_RETRIES 3
54
+#define RM_RETRY_DELAY_MS 20
6355 #define RM_MAX_TOUCH_NUM 10
6456 #define RM_BOOT_DELAY_MS 100
6557
....@@ -145,83 +137,134 @@
145137 bool wake_irq_enabled;
146138 };
147139
148
-static int raydium_i2c_send(struct i2c_client *client,
149
- u8 addr, const void *data, size_t len)
150
-{
151
- u8 *buf;
152
- int tries = 0;
153
- int ret;
140
+/*
141
+ * Header to be sent for RM_CMD_BANK_SWITCH command. This is used by
142
+ * raydium_i2c_{read|send} below.
143
+ */
144
+struct __packed raydium_bank_switch_header {
145
+ u8 cmd;
146
+ __be32 be_addr;
147
+};
154148
155
- buf = kmalloc(len + 1, GFP_KERNEL);
156
- if (!buf)
149
+static int raydium_i2c_xfer(struct i2c_client *client, u32 addr,
150
+ struct i2c_msg *xfer, size_t xfer_count)
151
+{
152
+ int ret;
153
+ /*
154
+ * If address is greater than 255, then RM_CMD_BANK_SWITCH needs to be
155
+ * sent first. Else, skip the header i.e. xfer[0].
156
+ */
157
+ int xfer_start_idx = (addr > 0xff) ? 0 : 1;
158
+ xfer_count -= xfer_start_idx;
159
+
160
+ ret = i2c_transfer(client->adapter, &xfer[xfer_start_idx], xfer_count);
161
+ if (likely(ret == xfer_count))
162
+ return 0;
163
+
164
+ return ret < 0 ? ret : -EIO;
165
+}
166
+
167
+static int raydium_i2c_send(struct i2c_client *client,
168
+ u32 addr, const void *data, size_t len)
169
+{
170
+ int tries = 0;
171
+ int error;
172
+ u8 *tx_buf;
173
+ u8 reg_addr = addr & 0xff;
174
+
175
+ tx_buf = kmalloc(len + 1, GFP_KERNEL);
176
+ if (!tx_buf)
157177 return -ENOMEM;
158178
159
- buf[0] = addr;
160
- memcpy(buf + 1, data, len);
179
+ tx_buf[0] = reg_addr;
180
+ memcpy(tx_buf + 1, data, len);
161181
162182 do {
163
- ret = i2c_master_send(client, buf, len + 1);
164
- if (likely(ret == len + 1))
165
- break;
183
+ struct raydium_bank_switch_header header = {
184
+ .cmd = RM_CMD_BANK_SWITCH,
185
+ .be_addr = cpu_to_be32(addr),
186
+ };
166187
167
- msleep(20);
188
+ /*
189
+ * Perform as a single i2c_transfer transaction to ensure that
190
+ * no other I2C transactions are initiated on the bus to any
191
+ * other device in between. Initiating transacations to other
192
+ * devices after RM_CMD_BANK_SWITCH is sent is known to cause
193
+ * issues. This is also why regmap infrastructure cannot be used
194
+ * for this driver. Regmap handles page(bank) switch and reads
195
+ * as separate i2c_transfer() operations. This can result in
196
+ * problems if the Raydium device is on a shared I2C bus.
197
+ */
198
+ struct i2c_msg xfer[] = {
199
+ {
200
+ .addr = client->addr,
201
+ .len = sizeof(header),
202
+ .buf = (u8 *)&header,
203
+ },
204
+ {
205
+ .addr = client->addr,
206
+ .len = len + 1,
207
+ .buf = tx_buf,
208
+ },
209
+ };
210
+
211
+ error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer));
212
+ if (likely(!error))
213
+ goto out;
214
+
215
+ msleep(RM_RETRY_DELAY_MS);
168216 } while (++tries < RM_MAX_RETRIES);
169217
170
- kfree(buf);
171
-
172
- if (unlikely(ret != len + 1)) {
173
- if (ret >= 0)
174
- ret = -EIO;
175
- dev_err(&client->dev, "%s failed: %d\n", __func__, ret);
176
- return ret;
177
- }
178
-
179
- return 0;
218
+ dev_err(&client->dev, "%s failed: %d\n", __func__, error);
219
+out:
220
+ kfree(tx_buf);
221
+ return error;
180222 }
181223
182224 static int raydium_i2c_read(struct i2c_client *client,
183
- u8 addr, void *data, size_t len)
225
+ u32 addr, void *data, size_t len)
184226 {
185
- struct i2c_msg xfer[] = {
186
- {
187
- .addr = client->addr,
188
- .len = 1,
189
- .buf = &addr,
190
- },
191
- {
192
- .addr = client->addr,
193
- .flags = I2C_M_RD,
194
- .len = len,
195
- .buf = data,
196
- }
197
- };
198
- int ret;
199
-
200
- ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
201
- if (unlikely(ret != ARRAY_SIZE(xfer)))
202
- return ret < 0 ? ret : -EIO;
203
-
204
- return 0;
205
-}
206
-
207
-static int raydium_i2c_read_message(struct i2c_client *client,
208
- u32 addr, void *data, size_t len)
209
-{
210
- __be32 be_addr;
211
- size_t xfer_len;
212227 int error;
213228
214229 while (len) {
215
- xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE);
230
+ u8 reg_addr = addr & 0xff;
231
+ struct raydium_bank_switch_header header = {
232
+ .cmd = RM_CMD_BANK_SWITCH,
233
+ .be_addr = cpu_to_be32(addr),
234
+ };
235
+ size_t xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE);
216236
217
- be_addr = cpu_to_be32(addr);
237
+ /*
238
+ * Perform as a single i2c_transfer transaction to ensure that
239
+ * no other I2C transactions are initiated on the bus to any
240
+ * other device in between. Initiating transacations to other
241
+ * devices after RM_CMD_BANK_SWITCH is sent is known to cause
242
+ * issues. This is also why regmap infrastructure cannot be used
243
+ * for this driver. Regmap handles page(bank) switch and writes
244
+ * as separate i2c_transfer() operations. This can result in
245
+ * problems if the Raydium device is on a shared I2C bus.
246
+ */
247
+ struct i2c_msg xfer[] = {
248
+ {
249
+ .addr = client->addr,
250
+ .len = sizeof(header),
251
+ .buf = (u8 *)&header,
252
+ },
253
+ {
254
+ .addr = client->addr,
255
+ .len = 1,
256
+ .buf = &reg_addr,
257
+ },
258
+ {
259
+ .addr = client->addr,
260
+ .len = xfer_len,
261
+ .buf = data,
262
+ .flags = I2C_M_RD,
263
+ }
264
+ };
218265
219
- error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH,
220
- &be_addr, sizeof(be_addr));
221
- if (!error)
222
- error = raydium_i2c_read(client, addr & 0xff,
223
- data, xfer_len);
224
- if (error)
266
+ error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer));
267
+ if (unlikely(error))
225268 return error;
226269
227270 len -= xfer_len;
....@@ -232,27 +275,13 @@
232275 return 0;
233276 }
234277
235
-static int raydium_i2c_send_message(struct i2c_client *client,
236
- u32 addr, const void *data, size_t len)
237
-{
238
- __be32 be_addr = cpu_to_be32(addr);
239
- int error;
240
-
241
- error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH,
242
- &be_addr, sizeof(be_addr));
243
- if (!error)
244
- error = raydium_i2c_send(client, addr & 0xff, data, len);
245
-
246
- return error;
247
-}
248
-
249278 static int raydium_i2c_sw_reset(struct i2c_client *client)
250279 {
251280 const u8 soft_rst_cmd = 0x01;
252281 int error;
253282
254
- error = raydium_i2c_send_message(client, RM_RESET_MSG_ADDR,
255
- &soft_rst_cmd, sizeof(soft_rst_cmd));
283
+ error = raydium_i2c_send(client, RM_RESET_MSG_ADDR, &soft_rst_cmd,
284
+ sizeof(soft_rst_cmd));
256285 if (error) {
257286 dev_err(&client->dev, "software reset failed: %d\n", error);
258287 return error;
....@@ -304,9 +333,8 @@
304333 if (error)
305334 continue;
306335
307
- error = raydium_i2c_read_message(client,
308
- le32_to_cpu(query_bank_addr),
309
- &ts->info, sizeof(ts->info));
336
+ error = raydium_i2c_read(client, le32_to_cpu(query_bank_addr),
337
+ &ts->info, sizeof(ts->info));
310338 if (error)
311339 continue;
312340
....@@ -844,8 +872,8 @@
844872 if (ts->boot_mode != RAYDIUM_TS_MAIN)
845873 goto out;
846874
847
- error = raydium_i2c_read_message(ts->client, ts->data_bank_addr,
848
- ts->report_data, ts->pkg_size);
875
+ error = raydium_i2c_read(ts->client, ts->data_bank_addr,
876
+ ts->report_data, ts->pkg_size);
849877 if (error)
850878 goto out;
851879