drivers/media/radio/si4713/radio-usb-si4713.c

Source file repositories/reference/linux-study-clean/drivers/media/radio/si4713/radio-usb-si4713.c

File Facts

System
Linux kernel
Corpus path
drivers/media/radio/si4713/radio-usb-si4713.c
Extension
.c
Size
14947 bytes
Lines
523
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 si4713_usb_device {
	struct usb_device	*usbdev;
	struct usb_interface	*intf;
	struct video_device	vdev;
	struct v4l2_device	v4l2_dev;
	struct v4l2_subdev	*v4l2_subdev;
	struct mutex		lock;
	struct i2c_adapter	i2c_adapter;

	u8			*buffer;
};

static inline struct si4713_usb_device *to_si4713_dev(struct v4l2_device *v4l2_dev)
{
	return container_of(v4l2_dev, struct si4713_usb_device, v4l2_dev);
}

static int vidioc_querycap(struct file *file, void *priv,
					struct v4l2_capability *v)
{
	struct si4713_usb_device *radio = video_drvdata(file);

	strscpy(v->driver, "radio-usb-si4713", sizeof(v->driver));
	strscpy(v->card, "Si4713 FM Transmitter", sizeof(v->card));
	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
	return 0;
}

static int vidioc_g_modulator(struct file *file, void *priv,
				struct v4l2_modulator *vm)
{
	struct si4713_usb_device *radio = video_drvdata(file);

	return v4l2_subdev_call(radio->v4l2_subdev, tuner, g_modulator, vm);
}

static int vidioc_s_modulator(struct file *file, void *priv,
				const struct v4l2_modulator *vm)
{
	struct si4713_usb_device *radio = video_drvdata(file);

	return v4l2_subdev_call(radio->v4l2_subdev, tuner, s_modulator, vm);
}

static int vidioc_s_frequency(struct file *file, void *priv,
				const struct v4l2_frequency *vf)
{
	struct si4713_usb_device *radio = video_drvdata(file);

	return v4l2_subdev_call(radio->v4l2_subdev, tuner, s_frequency, vf);
}

static int vidioc_g_frequency(struct file *file, void *priv,
				struct v4l2_frequency *vf)
{
	struct si4713_usb_device *radio = video_drvdata(file);

	return v4l2_subdev_call(radio->v4l2_subdev, tuner, g_frequency, vf);
}

static const struct v4l2_ioctl_ops usb_si4713_ioctl_ops = {
	.vidioc_querycap	  = vidioc_querycap,
	.vidioc_g_modulator	  = vidioc_g_modulator,
	.vidioc_s_modulator	  = vidioc_s_modulator,
	.vidioc_g_frequency	  = vidioc_g_frequency,
	.vidioc_s_frequency	  = vidioc_s_frequency,
	.vidioc_log_status	  = v4l2_ctrl_log_status,
	.vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};

/* File system interface */
static const struct v4l2_file_operations usb_si4713_fops = {
	.owner		= THIS_MODULE,
	.open           = v4l2_fh_open,
	.release        = v4l2_fh_release,
	.poll           = v4l2_ctrl_poll,
	.unlocked_ioctl	= video_ioctl2,
};

static void usb_si4713_video_device_release(struct v4l2_device *v4l2_dev)
{
	struct si4713_usb_device *radio = to_si4713_dev(v4l2_dev);
	struct i2c_adapter *adapter = &radio->i2c_adapter;

	i2c_del_adapter(adapter);
	v4l2_device_unregister(&radio->v4l2_dev);
	kfree(radio->buffer);
	kfree(radio);
}

Annotation

Implementation Notes