drivers/media/radio/radio-raremono.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/radio/radio-raremono.c
Extension
.c
Size
10677 bytes
Lines
390
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 raremono_device {
	struct usb_device *usbdev;
	struct usb_interface *intf;
	struct video_device vdev;
	struct v4l2_device v4l2_dev;
	struct mutex lock;

	u8 *buffer;
	u32 band;
	unsigned curfreq;
};

static inline struct raremono_device *to_raremono_dev(struct v4l2_device *v4l2_dev)
{
	return container_of(v4l2_dev, struct raremono_device, v4l2_dev);
}

/* Set frequency. */
static int raremono_cmd_main(struct raremono_device *radio, unsigned band, unsigned freq)
{
	unsigned band_offset;
	int ret;

	switch (band) {
	case BAND_FM:
		band_offset = 1;
		freq /= 10;
		break;
	case BAND_AM:
		band_offset = 0;
		break;
	default:
		band_offset = 2;
		break;
	}
	radio->buffer[0] = 0x04 + band_offset;
	radio->buffer[1] = freq >> 8;
	radio->buffer[2] = freq & 0xff;

	ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
			HID_REQ_SET_REPORT,
			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
			0x0300 + radio->buffer[0], 2,
			radio->buffer, 3, USB_TIMEOUT);

	if (ret < 0) {
		dev_warn(radio->v4l2_dev.dev, "%s failed (%d)\n", __func__, ret);
		return ret;
	}
	radio->curfreq = (band == BAND_FM) ? freq * 10 : freq;
	return 0;
}

/* Handle unplugging the device.
 * We call video_unregister_device in any case.
 * The last function called in this procedure is
 * usb_raremono_device_release.
 */
static void usb_raremono_disconnect(struct usb_interface *intf)
{
	struct raremono_device *radio = to_raremono_dev(usb_get_intfdata(intf));

	dev_info(&intf->dev, "Thanko's Raremono disconnected\n");

	mutex_lock(&radio->lock);
	usb_set_intfdata(intf, NULL);
	video_unregister_device(&radio->vdev);
	v4l2_device_disconnect(&radio->v4l2_dev);
	mutex_unlock(&radio->lock);
	v4l2_device_put(&radio->v4l2_dev);
}

/*
 * Linux Video interface
 */
static int vidioc_querycap(struct file *file, void *priv,
					struct v4l2_capability *v)
{
	struct raremono_device *radio = video_drvdata(file);

	strscpy(v->driver, "radio-raremono", sizeof(v->driver));
	strscpy(v->card, "Thanko's Raremono", sizeof(v->card));
	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
	return 0;
}

static int vidioc_enum_freq_bands(struct file *file, void *priv,
		struct v4l2_frequency_band *band)
{
	if (band->tuner != 0)

Annotation

Implementation Notes