drivers/media/usb/hdpvr/hdpvr-core.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/hdpvr/hdpvr-core.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/hdpvr/hdpvr-core.c
Extension
.c
Size
11706 bytes
Lines
440
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 (idx & 0x3) {
		case 0x3:
			bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
			bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
			break;
		case 0x1:
			bytes[0] *= 8;
			bytes[0] += 7*idx + 4;
			bytes[6] += bytes[3] * 3;
			break;
		case 0x0:
			bytes[3 - (idx >> 3)] = bytes[idx >> 2];
			bytes[5] += bytes[6] * 3;
			for (i = 0; i < 3; i++)
				bytes[3] *= bytes[3] + 1;
			break;
		case 0x2:
			for (i = 0; i < 3; i++)
				bytes[1] *= bytes[6] + 1;
			for (i = 0; i < 3; i++) {
				i64P = (__le64 *)bytes;
				tmp64 = le64_to_cpup(i64P);
				tmp64 = tmp64 + (tmp64 << (bytes[7] & 0x0f));
				*i64P = cpu_to_le64(tmp64);
			}
			break;
		}
	}
}

/* try to init the device like the windows driver */
static int device_authorization(struct hdpvr_device *dev)
{

	int ret, retval = -ENOMEM;
	char request_type = 0x38, rcv_request = 0x81;
	char *response;

	mutex_lock(&dev->usbc_mutex);
	ret = usb_control_msg(dev->udev,
			      usb_rcvctrlpipe(dev->udev, 0),
			      rcv_request, 0x80 | request_type,
			      0x0400, 0x0003,
			      dev->usbc_buf, 46,
			      10000);
	if (ret != 46) {
		v4l2_err(&dev->v4l2_dev,
			 "unexpected answer of status request, len %d\n", ret);
		goto unlock;
	}
#ifdef HDPVR_DEBUG
	else {
		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
			 "Status request returned, len %d: %46ph\n",
			 ret, dev->usbc_buf);
	}
#endif

	dev->fw_ver = dev->usbc_buf[1];

	dev->usbc_buf[46] = '\0';
	v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
			  dev->fw_ver, &dev->usbc_buf[2]);

	if (dev->fw_ver > 0x15) {
		dev->options.brightness	= 0x80;
		dev->options.contrast	= 0x40;
		dev->options.hue	= 0xf;
		dev->options.saturation	= 0x40;
		dev->options.sharpness	= 0x80;
	}

	switch (dev->fw_ver) {
	case HDPVR_FIRMWARE_VERSION:
		dev->flags &= ~HDPVR_FLAG_AC3_CAP;
		break;
	case HDPVR_FIRMWARE_VERSION_AC3:
	case HDPVR_FIRMWARE_VERSION_0X12:
	case HDPVR_FIRMWARE_VERSION_0X15:
	case HDPVR_FIRMWARE_VERSION_0X1E:
		dev->flags |= HDPVR_FLAG_AC3_CAP;
		break;
	default:
		v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might not work.\n");
		if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3)
			dev->flags |= HDPVR_FLAG_AC3_CAP;
		else
			dev->flags &= ~HDPVR_FLAG_AC3_CAP;
	}

Annotation

Implementation Notes