1 // SPDX-License-Identifier: GPL-2.0-only
3 * Goodix Touchscreen firmware upload support
5 * Copyright (c) 2021 Hans de Goede <hdegoede@redhat.com>
7 * This is a rewrite of gt9xx_update.c from the Allwinner H3 BSP which is:
8 * Copyright (c) 2010 - 2012 Goodix Technology.
9 * Author: andrew@goodix.com
12 #include <linux/device.h>
13 #include <linux/firmware.h>
14 #include <linux/i2c.h>
17 #define GOODIX_FW_HEADER_LENGTH sizeof(struct goodix_fw_header)
18 #define GOODIX_FW_SECTION_LENGTH 0x2000
19 #define GOODIX_FW_DSP_LENGTH 0x1000
20 #define GOODIX_FW_UPLOAD_ADDRESS 0xc000
22 #define GOODIX_CFG_LOC_HAVE_KEY 7
23 #define GOODIX_CFG_LOC_DRVA_NUM 27
24 #define GOODIX_CFG_LOC_DRVB_NUM 28
25 #define GOODIX_CFG_LOC_SENS_NUM 29
27 struct goodix_fw_header
{
33 static u16
goodix_firmware_checksum(const u8
*data
, int size
)
38 for (i
= 0; i
< size
; i
+= 2)
39 checksum
+= (data
[i
] << 8) + data
[i
+ 1];
44 static int goodix_firmware_verify(struct device
*dev
, const struct firmware
*fw
)
46 const struct goodix_fw_header
*fw_header
;
52 expected_size
= GOODIX_FW_HEADER_LENGTH
+ 4 * GOODIX_FW_SECTION_LENGTH
+
54 if (fw
->size
!= expected_size
) {
55 dev_err(dev
, "Firmware has wrong size, expected %zu got %zu\n",
56 expected_size
, fw
->size
);
60 data
= fw
->data
+ GOODIX_FW_HEADER_LENGTH
;
61 checksum
= goodix_firmware_checksum(data
, 4 * GOODIX_FW_SECTION_LENGTH
);
63 dev_err(dev
, "Main firmware checksum error\n");
67 data
+= 4 * GOODIX_FW_SECTION_LENGTH
;
68 checksum
= goodix_firmware_checksum(data
, GOODIX_FW_DSP_LENGTH
);
70 dev_err(dev
, "DSP firmware checksum error\n");
74 fw_header
= (const struct goodix_fw_header
*)fw
->data
;
75 dev_info(dev
, "Firmware hardware info %02x%02x%02x%02x\n",
76 fw_header
->hw_info
[0], fw_header
->hw_info
[1],
77 fw_header
->hw_info
[2], fw_header
->hw_info
[3]);
78 /* pid is a 8 byte buffer containing a string, weird I know */
79 memcpy(buf
, fw_header
->pid
, 8);
81 dev_info(dev
, "Firmware PID: %s VID: %02x%02x\n", buf
,
82 fw_header
->vid
[0], fw_header
->vid
[1]);
86 static int goodix_enter_upload_mode(struct i2c_client
*client
)
93 error
= goodix_i2c_write_u8(client
,
94 GOODIX_REG_MISCTL_SWRST
, 0x0c);
98 error
= goodix_i2c_read(client
,
99 GOODIX_REG_MISCTL_SWRST
, &val
, 1);
108 dev_err(&client
->dev
, "Error could not hold ss51 & dsp\n");
112 /* DSP_CK and DSP_ALU_CK PowerOn */
113 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_DSP_CTL
, 0x00);
117 /* Disable watchdog */
118 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_TMR0_EN
, 0x00);
122 /* Clear cache enable */
123 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_CACHE_EN
, 0x00);
127 /* Set boot from SRAM */
128 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_BOOTCTL
, 0x02);
132 /* Software reboot */
133 error
= goodix_i2c_write_u8(client
,
134 GOODIX_REG_MISCTL_CPU_SWRST_PULSE
, 0x01);
138 /* Clear control flag */
139 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_BOOTCTL
, 0x00);
144 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_BOOT_OPT
, 0x00);
148 /* Enable accessing code */
149 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_MEM_CD_EN
, 0x01);
156 static int goodix_start_firmware(struct i2c_client
*client
)
161 /* Init software watchdog */
162 error
= goodix_i2c_write_u8(client
, GOODIX_REG_SW_WDT
, 0xaa);
166 /* Release SS51 & DSP */
167 error
= goodix_i2c_write_u8(client
, GOODIX_REG_MISCTL_SWRST
, 0x00);
171 error
= goodix_i2c_read(client
, GOODIX_REG_SW_WDT
, &val
, 1);
175 /* The value we've written to SW_WDT should have been cleared now */
177 dev_err(&client
->dev
, "Error SW_WDT reg not cleared on fw startup\n");
181 /* Re-init software watchdog */
182 error
= goodix_i2c_write_u8(client
, GOODIX_REG_SW_WDT
, 0xaa);
189 static int goodix_firmware_upload(struct goodix_ts_data
*ts
)
191 const struct firmware
*fw
;
196 snprintf(fw_name
, sizeof(fw_name
), "goodix/%s", ts
->firmware_name
);
198 error
= request_firmware(&fw
, fw_name
, &ts
->client
->dev
);
200 dev_err(&ts
->client
->dev
, "Firmware request error %d\n", error
);
204 error
= goodix_firmware_verify(&ts
->client
->dev
, fw
);
208 error
= goodix_reset_no_int_sync(ts
);
212 error
= goodix_enter_upload_mode(ts
->client
);
216 /* Select SRAM bank 0 and upload section 1 & 2 */
217 error
= goodix_i2c_write_u8(ts
->client
,
218 GOODIX_REG_MISCTL_SRAM_BANK
, 0x00);
222 data
= fw
->data
+ GOODIX_FW_HEADER_LENGTH
;
223 error
= goodix_i2c_write(ts
->client
, GOODIX_FW_UPLOAD_ADDRESS
,
224 data
, 2 * GOODIX_FW_SECTION_LENGTH
);
228 /* Select SRAM bank 1 and upload section 3 & 4 */
229 error
= goodix_i2c_write_u8(ts
->client
,
230 GOODIX_REG_MISCTL_SRAM_BANK
, 0x01);
234 data
+= 2 * GOODIX_FW_SECTION_LENGTH
;
235 error
= goodix_i2c_write(ts
->client
, GOODIX_FW_UPLOAD_ADDRESS
,
236 data
, 2 * GOODIX_FW_SECTION_LENGTH
);
240 /* Select SRAM bank 2 and upload the DSP firmware */
241 error
= goodix_i2c_write_u8(ts
->client
,
242 GOODIX_REG_MISCTL_SRAM_BANK
, 0x02);
246 data
+= 2 * GOODIX_FW_SECTION_LENGTH
;
247 error
= goodix_i2c_write(ts
->client
, GOODIX_FW_UPLOAD_ADDRESS
,
248 data
, GOODIX_FW_DSP_LENGTH
);
252 error
= goodix_start_firmware(ts
->client
);
256 error
= goodix_int_sync(ts
);
258 release_firmware(fw
);
262 static int goodix_prepare_bak_ref(struct goodix_ts_data
*ts
)
264 u8 have_key
, driver_num
, sensor_num
;
267 return 0; /* Already done */
269 have_key
= (ts
->config
[GOODIX_CFG_LOC_HAVE_KEY
] & 0x01);
271 driver_num
= (ts
->config
[GOODIX_CFG_LOC_DRVA_NUM
] & 0x1f) +
272 (ts
->config
[GOODIX_CFG_LOC_DRVB_NUM
] & 0x1f);
276 sensor_num
= (ts
->config
[GOODIX_CFG_LOC_SENS_NUM
] & 0x0f) +
277 ((ts
->config
[GOODIX_CFG_LOC_SENS_NUM
] >> 4) & 0x0f);
279 dev_dbg(&ts
->client
->dev
, "Drv %d Sen %d Key %d\n",
280 driver_num
, sensor_num
, have_key
);
282 ts
->bak_ref_len
= (driver_num
* (sensor_num
- 2) + 2) * 2;
284 ts
->bak_ref
= devm_kzalloc(&ts
->client
->dev
,
285 ts
->bak_ref_len
, GFP_KERNEL
);
290 * The bak_ref array contains the backup of an array of (self/auto)
291 * calibration related values which the Android version of the driver
292 * stores on the filesystem so that it can be restored after reboot.
293 * The mainline kernel never writes directly to the filesystem like
294 * this, we always start will all the values which give a correction
295 * factor in approx. the -20 - +20 range (in 2s complement) set to 0.
297 * Note the touchscreen works fine without restoring the reference
298 * values after a reboot / power-cycle.
300 * The last 2 bytes are a 16 bits unsigned checksum which is expected
301 * to make the addition al all 16 bit unsigned values in the array add
302 * up to 1 (rather then the usual 0), so we must set the last byte to 1.
304 ts
->bak_ref
[ts
->bak_ref_len
- 1] = 1;
309 static int goodix_send_main_clock(struct goodix_ts_data
*ts
)
311 u32 main_clk
= 54; /* Default main clock */
315 device_property_read_u32(&ts
->client
->dev
,
316 "goodix,main-clk", &main_clk
);
318 for (i
= 0; i
< (GOODIX_MAIN_CLK_LEN
- 1); i
++) {
319 ts
->main_clk
[i
] = main_clk
;
320 checksum
+= main_clk
;
323 /* The value of all bytes combines must be 0 */
324 ts
->main_clk
[GOODIX_MAIN_CLK_LEN
- 1] = 256 - checksum
;
326 return goodix_i2c_write(ts
->client
, GOODIX_REG_MAIN_CLK
,
327 ts
->main_clk
, GOODIX_MAIN_CLK_LEN
);
330 int goodix_firmware_check(struct goodix_ts_data
*ts
)
332 device_property_read_string(&ts
->client
->dev
,
333 "firmware-name", &ts
->firmware_name
);
334 if (!ts
->firmware_name
)
337 if (ts
->irq_pin_access_method
== IRQ_PIN_ACCESS_NONE
) {
338 dev_err(&ts
->client
->dev
, "Error no IRQ-pin access method, cannot upload fw.\n");
342 dev_info(&ts
->client
->dev
, "Touchscreen controller needs fw-upload\n");
343 ts
->load_cfg_from_disk
= true;
345 return goodix_firmware_upload(ts
);
348 bool goodix_handle_fw_request(struct goodix_ts_data
*ts
)
353 error
= goodix_i2c_read(ts
->client
, GOODIX_REG_REQUEST
, &val
, 1);
358 case GOODIX_RQST_RESPONDED
:
360 * If we read back our own last ack the IRQ was not for
364 case GOODIX_RQST_CONFIG
:
365 error
= goodix_send_cfg(ts
, ts
->config
, ts
->chip
->config_len
);
370 case GOODIX_RQST_BAK_REF
:
371 error
= goodix_prepare_bak_ref(ts
);
375 error
= goodix_i2c_write(ts
->client
, GOODIX_REG_BAK_REF
,
376 ts
->bak_ref
, ts
->bak_ref_len
);
381 case GOODIX_RQST_RESET
:
382 error
= goodix_firmware_upload(ts
);
387 case GOODIX_RQST_MAIN_CLOCK
:
388 error
= goodix_send_main_clock(ts
);
393 case GOODIX_RQST_UNKNOWN
:
394 case GOODIX_RQST_IDLE
:
397 dev_err_ratelimited(&ts
->client
->dev
, "Unknown Request: 0x%02x\n", val
);
400 /* Ack the request */
401 goodix_i2c_write_u8(ts
->client
,
402 GOODIX_REG_REQUEST
, GOODIX_RQST_RESPONDED
);
406 void goodix_save_bak_ref(struct goodix_ts_data
*ts
)
411 if (!ts
->firmware_name
)
414 error
= goodix_i2c_read(ts
->client
, GOODIX_REG_STATUS
, &val
, 1);
421 error
= goodix_i2c_read(ts
->client
, GOODIX_REG_BAK_REF
,
422 ts
->bak_ref
, ts
->bak_ref_len
);
424 memset(ts
->bak_ref
, 0, ts
->bak_ref_len
);
425 ts
->bak_ref
[ts
->bak_ref_len
- 1] = 1;