drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c

Source file repositories/reference/linux-study-clean/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c

File Facts

System
Linux kernel
Corpus path
drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
Extension
.c
Size
53032 bytes
Lines
1838
Domain
Driver Families
Bucket
drivers/media
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.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (tag) {
		case 2: /* Video Data Block */
			/* Search for VIC 97 */
			if (memchr(edid + i + 1, 97, len))
				port->has_4kp60 = true;
			/* Search for VIC 95 */
			if (memchr(edid + i + 1, 95, len))
				port->has_4kp30 = true;
			break;

		case 7: /* Use Extended Tag */
			switch (edid[i + 1]) {
			case 0: /* Video Capability Data Block */
				if (edid[i + 2] & 0x80)
					port->has_qy = true;
				if (edid[i + 2] & 0x40)
					port->has_qs = true;
				break;
			}
			break;
		}
		i += len + 1;
	} while (i < end);
}

static int get_edid_tag_location(const u8 *edid, unsigned int size,
				 u8 want_tag, u8 ext_tag)
{
	unsigned int offset = 128;
	int i, end;
	u8 d;

	edid += offset;

	/* Return if not a CTA-861 extension block */
	if (size < 256 || edid[0] != 0x02 || edid[1] != 0x03)
		return -ENOENT;

	/* search tag */
	d = edid[0x02] & 0x7f;
	if (d <= 4)
		return -ENOENT;

	i = 0x04;
	end = 0x00 + d;

	do {
		unsigned char tag = edid[i] >> 5;
		unsigned char len = edid[i] & 0x1f;

		if (tag != want_tag || i + len > end) {
			i += len + 1;
			continue;
		}

		if (tag < 7 || (len >= 1 && edid[i + 1] == ext_tag))
			return offset + i;
		i += len + 1;
	} while (i < end);
	return -ENOENT;
}

static void extron_edid_crc(u8 *edid)
{
	u8 sum = 0;
	int offset;

	/* Update CRC */
	for (offset = 0; offset < 127; offset++)
		sum += edid[offset];
	edid[127] = 256 - sum;
}

/*
 * Fill in EDID string. As per VESA EDID-1.3, strings are at most 13 chars
 * long. If shorter then add a 0x0a character after the string and pad the
 * remainder with spaces.
 */
static void extron_set_edid_string(u8 *start, const char *s)
{
	const unsigned int max_len = 13;
	int len = strlen(s);

	memset(start, ' ', max_len);
	if (len > max_len)
		len = max_len;
	memcpy(start, s, len);
	if (len < max_len)
		start[len] = 0x0a;
}

Annotation

Implementation Notes