drivers/input/touchscreen/goodix_fwupload.c
Source file repositories/reference/linux-study-clean/drivers/input/touchscreen/goodix_fwupload.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/touchscreen/goodix_fwupload.c- Extension
.c- Size
- 10527 bytes
- Lines
- 429
- Domain
- Driver Families
- Bucket
- drivers/input
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/firmware.hlinux/i2c.hgoodix.h
Detected Declarations
struct goodix_fw_headerfunction goodix_firmware_checksumfunction goodix_firmware_verifyfunction goodix_enter_upload_modefunction goodix_start_firmwarefunction goodix_firmware_uploadfunction goodix_prepare_bak_reffunction goodix_send_main_clockfunction goodix_firmware_checkfunction goodix_handle_fw_requestfunction goodix_save_bak_ref
Annotated Snippet
struct goodix_fw_header {
u8 hw_info[4];
u8 pid[8];
u8 vid[2];
} __packed;
static u16 goodix_firmware_checksum(const u8 *data, int size)
{
u16 checksum = 0;
int i;
for (i = 0; i < size; i += 2)
checksum += (data[i] << 8) + data[i + 1];
return checksum;
}
static int goodix_firmware_verify(struct device *dev, const struct firmware *fw)
{
const struct goodix_fw_header *fw_header;
size_t expected_size;
const u8 *data;
u16 checksum;
char buf[9];
expected_size = GOODIX_FW_HEADER_LENGTH + 4 * GOODIX_FW_SECTION_LENGTH +
GOODIX_FW_DSP_LENGTH;
if (fw->size != expected_size) {
dev_err(dev, "Firmware has wrong size, expected %zu got %zu\n",
expected_size, fw->size);
return -EINVAL;
}
data = fw->data + GOODIX_FW_HEADER_LENGTH;
checksum = goodix_firmware_checksum(data, 4 * GOODIX_FW_SECTION_LENGTH);
if (checksum) {
dev_err(dev, "Main firmware checksum error\n");
return -EINVAL;
}
data += 4 * GOODIX_FW_SECTION_LENGTH;
checksum = goodix_firmware_checksum(data, GOODIX_FW_DSP_LENGTH);
if (checksum) {
dev_err(dev, "DSP firmware checksum error\n");
return -EINVAL;
}
fw_header = (const struct goodix_fw_header *)fw->data;
dev_info(dev, "Firmware hardware info %02x%02x%02x%02x\n",
fw_header->hw_info[0], fw_header->hw_info[1],
fw_header->hw_info[2], fw_header->hw_info[3]);
/* pid is a 8 byte buffer containing a string, weird I know */
memcpy(buf, fw_header->pid, 8);
buf[8] = 0;
dev_info(dev, "Firmware PID: %s VID: %02x%02x\n", buf,
fw_header->vid[0], fw_header->vid[1]);
return 0;
}
static int goodix_enter_upload_mode(struct i2c_client *client)
{
int tries, error;
u8 val;
tries = 200;
do {
error = goodix_i2c_write_u8(client,
GOODIX_REG_MISCTL_SWRST, 0x0c);
if (error)
return error;
error = goodix_i2c_read(client,
GOODIX_REG_MISCTL_SWRST, &val, 1);
if (error)
return error;
if (val == 0x0c)
break;
} while (--tries);
if (!tries) {
dev_err(&client->dev, "Error could not hold ss51 & dsp\n");
return -EIO;
}
/* DSP_CK and DSP_ALU_CK PowerOn */
error = goodix_i2c_write_u8(client, GOODIX_REG_MISCTL_DSP_CTL, 0x00);
if (error)
return error;
Annotation
- Immediate include surface: `linux/device.h`, `linux/firmware.h`, `linux/i2c.h`, `goodix.h`.
- Detected declarations: `struct goodix_fw_header`, `function goodix_firmware_checksum`, `function goodix_firmware_verify`, `function goodix_enter_upload_mode`, `function goodix_start_firmware`, `function goodix_firmware_upload`, `function goodix_prepare_bak_ref`, `function goodix_send_main_clock`, `function goodix_firmware_check`, `function goodix_handle_fw_request`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.