drivers/media/usb/gspca/se401.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/gspca/se401.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/gspca/se401.c
Extension
.c
Size
19498 bytes
Lines
731
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

struct sd {
	struct gspca_dev gspca_dev;	/* !! must be the first item */
	struct { /* exposure/freq control cluster */
		struct v4l2_ctrl *exposure;
		struct v4l2_ctrl *freq;
	};
	bool has_brightness;
	struct v4l2_pix_format fmts[MAX_MODES];
	int pixels_read;
	int packet_read;
	u8 packet[PACKET_SIZE];
	u8 restart_stream;
	u8 button_state;
	u8 resetlevel;
	u8 resetlevel_frame_count;
	int resetlevel_adjust_dir;
	int expo_change_state;
};


static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value,
			    int silent)
{
	int err;

	if (gspca_dev->usb_err < 0)
		return;

	err = usb_control_msg(gspca_dev->dev,
			      usb_sndctrlpipe(gspca_dev->dev, 0), req,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      value, 0, NULL, 0, 1000);
	if (err < 0) {
		if (!silent)
			pr_err("write req failed req %#04x val %#04x error %d\n",
			       req, value, err);
		gspca_dev->usb_err = err;
	}
}

static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent)
{
	int err;

	if (gspca_dev->usb_err < 0)
		return;

	if (USB_BUF_SZ < READ_REQ_SIZE) {
		pr_err("USB_BUF_SZ too small!!\n");
		gspca_dev->usb_err = -ENOBUFS;
		return;
	}

	err = usb_control_msg(gspca_dev->dev,
			      usb_rcvctrlpipe(gspca_dev->dev, 0), req,
			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0, 0, gspca_dev->usb_buf, READ_REQ_SIZE, 1000);
	if (err < 0) {
		if (!silent)
			pr_err("read req failed req %#04x error %d\n",
			       req, err);
		gspca_dev->usb_err = err;
		/*
		 * Make sure the buffer is zeroed to avoid uninitialized
		 * values.
		 */
		memset(gspca_dev->usb_buf, 0, READ_REQ_SIZE);
	}
}

static void se401_set_feature(struct gspca_dev *gspca_dev,
			      u16 selector, u16 param)
{
	int err;

	if (gspca_dev->usb_err < 0)
		return;

	err = usb_control_msg(gspca_dev->dev,
			      usb_sndctrlpipe(gspca_dev->dev, 0),
			      SE401_REQ_SET_EXT_FEATURE,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      param, selector, NULL, 0, 1000);
	if (err < 0) {
		pr_err("set feature failed sel %#04x param %#04x error %d\n",
		       selector, param, err);
		gspca_dev->usb_err = err;
	}
}

Annotation

Implementation Notes