drivers/media/radio/radio-shark2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/radio/radio-shark2.c
Extension
.c
Size
10475 bytes
Lines
396
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 shark_device {
	struct usb_device *usbdev;
	struct v4l2_device v4l2_dev;
	struct radio_tea5777 tea;

#ifdef SHARK_USE_LEDS
	struct work_struct led_work;
	struct led_classdev leds[NO_LEDS];
	char led_names[NO_LEDS][64];
	atomic_t brightness[NO_LEDS];
	unsigned long brightness_new;
#endif

	u8 *transfer_buffer;
};

static atomic_t shark_instance = ATOMIC_INIT(0);

static int shark_write_reg(struct radio_tea5777 *tea, u64 reg)
{
	struct shark_device *shark = tea->private_data;
	int i, res, actual_len;

	memset(shark->transfer_buffer, 0, TB_LEN);
	shark->transfer_buffer[0] = 0x81; /* Write register command */
	for (i = 0; i < 6; i++)
		shark->transfer_buffer[i + 1] = (reg >> (40 - i * 8)) & 0xff;

	v4l2_dbg(1, debug, tea->v4l2_dev, "shark2-write: %*ph\n",
		 7, shark->transfer_buffer);

	res = usb_interrupt_msg(shark->usbdev,
				usb_sndintpipe(shark->usbdev, SHARK_OUT_EP),
				shark->transfer_buffer, TB_LEN,
				&actual_len, 1000);
	if (res < 0) {
		v4l2_err(tea->v4l2_dev, "write error: %d\n", res);
		return res;
	}

	return 0;
}

static int shark_read_reg(struct radio_tea5777 *tea, u32 *reg_ret)
{
	struct shark_device *shark = tea->private_data;
	int i, res, actual_len;
	u32 reg = 0;

	memset(shark->transfer_buffer, 0, TB_LEN);
	shark->transfer_buffer[0] = 0x82;
	res = usb_interrupt_msg(shark->usbdev,
				usb_sndintpipe(shark->usbdev, SHARK_OUT_EP),
				shark->transfer_buffer, TB_LEN,
				&actual_len, 1000);
	if (res < 0) {
		v4l2_err(tea->v4l2_dev, "request-read error: %d\n", res);
		return res;
	}

	res = usb_interrupt_msg(shark->usbdev,
				usb_rcvintpipe(shark->usbdev, SHARK_IN_EP),
				shark->transfer_buffer, TB_LEN,
				&actual_len, 1000);
	if (res < 0) {
		v4l2_err(tea->v4l2_dev, "read error: %d\n", res);
		return res;
	}

	for (i = 0; i < 3; i++)
		reg |= shark->transfer_buffer[i] << (16 - i * 8);

	v4l2_dbg(1, debug, tea->v4l2_dev, "shark2-read: %*ph\n",
		 3, shark->transfer_buffer);

	*reg_ret = reg;
	return 0;
}

static const struct radio_tea5777_ops shark_tea_ops = {
	.write_reg = shark_write_reg,
	.read_reg  = shark_read_reg,
};

#ifdef SHARK_USE_LEDS
static void shark_led_work(struct work_struct *work)
{
	struct shark_device *shark =
		container_of(work, struct shark_device, led_work);
	int i, res, brightness, actual_len;

Annotation

Implementation Notes