drivers/media/radio/si470x/radio-si470x-usb.c
Source file repositories/reference/linux-study-clean/drivers/media/radio/si470x/radio-si470x-usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/radio/si470x/radio-si470x-usb.c- Extension
.c- Size
- 23725 bytes
- Lines
- 850
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/usb.hlinux/hid.hlinux/slab.hradio-si470x.h
Detected Declarations
function si470x_get_reportfunction si470x_set_reportfunction si470x_get_registerfunction si470x_set_registerfunction si470x_get_all_registersfunction si470x_set_led_statefunction si470x_get_scratch_page_versionsfunction si470x_int_in_callbackfunction si470x_fops_openfunction si470x_fops_releasefunction si470x_usb_releasefunction si470x_vidioc_querycapfunction si470x_start_usbfunction si470x_usb_driver_probefunction si470x_usb_driver_suspendfunction si470x_usb_driver_resumefunction si470x_usb_driver_disconnect
Annotated Snippet
if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
/* No RDS group ready, better luck next time */
goto resubmit;
}
if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
/* RDS decoder not synchronized */
goto resubmit;
}
for (blocknum = 0; blocknum < 4; blocknum++) {
switch (blocknum) {
default:
bler = (radio->registers[STATUSRSSI] &
STATUSRSSI_BLERA) >> 9;
rds = radio->registers[RDSA];
break;
case 1:
bler = (radio->registers[READCHAN] &
READCHAN_BLERB) >> 14;
rds = radio->registers[RDSB];
break;
case 2:
bler = (radio->registers[READCHAN] &
READCHAN_BLERC) >> 12;
rds = radio->registers[RDSC];
break;
case 3:
bler = (radio->registers[READCHAN] &
READCHAN_BLERD) >> 10;
rds = radio->registers[RDSD];
break;
}
/* Fill the V4L2 RDS buffer */
put_unaligned_le16(rds, &tmpbuf);
tmpbuf[2] = blocknum; /* offset name */
tmpbuf[2] |= blocknum << 3; /* received offset */
if (bler > max_rds_errors)
tmpbuf[2] |= 0x80; /* uncorrectable errors */
else if (bler > 0)
tmpbuf[2] |= 0x40; /* corrected error(s) */
/* copy RDS block to internal buffer */
memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
radio->wr_index += 3;
/* wrap write pointer */
if (radio->wr_index >= radio->buf_size)
radio->wr_index = 0;
/* check for overflow */
if (radio->wr_index == radio->rd_index) {
/* increment and wrap read pointer */
radio->rd_index += 3;
if (radio->rd_index >= radio->buf_size)
radio->rd_index = 0;
}
}
if (radio->wr_index != radio->rd_index)
wake_up_interruptible(&radio->read_queue);
}
resubmit:
/* Resubmit if we're still running. */
if (radio->int_in_running && radio->usbdev) {
retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
if (retval) {
dev_warn(&radio->intf->dev,
"resubmitting urb failed (%d)", retval);
radio->int_in_running = 0;
}
}
radio->status_rssi_auto_update = radio->int_in_running;
}
static int si470x_fops_open(struct file *file)
{
return v4l2_fh_open(file);
}
static int si470x_fops_release(struct file *file)
{
return v4l2_fh_release(file);
}
static void si470x_usb_release(struct v4l2_device *v4l2_dev)
{
struct si470x_device *radio =
container_of(v4l2_dev, struct si470x_device, v4l2_dev);
Annotation
- Immediate include surface: `linux/usb.h`, `linux/hid.h`, `linux/slab.h`, `radio-si470x.h`.
- Detected declarations: `function si470x_get_report`, `function si470x_set_report`, `function si470x_get_register`, `function si470x_set_register`, `function si470x_get_all_registers`, `function si470x_set_led_state`, `function si470x_get_scratch_page_versions`, `function si470x_int_in_callback`, `function si470x_fops_open`, `function si470x_fops_release`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.