drivers/media/radio/radio-tea5777.c
Source file repositories/reference/linux-study-clean/drivers/media/radio/radio-tea5777.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/radio/radio-tea5777.c- Extension
.c- Size
- 16182 bytes
- Lines
- 588
- Domain
- Driver Families
- Bucket
- drivers/media
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/init.hlinux/module.hlinux/sched.hlinux/slab.hmedia/v4l2-device.hmedia/v4l2-dev.hmedia/v4l2-fh.hmedia/v4l2-ioctl.hmedia/v4l2-event.hradio-tea5777.h
Detected Declarations
function tea5777_freq_to_v4l2_freqfunction radio_tea5777_set_freqfunction radio_tea5777_update_read_regfunction vidioc_querycapfunction vidioc_enum_freq_bandsfunction vidioc_g_tunerfunction vidioc_s_tunerfunction vidioc_g_frequencyfunction vidioc_s_frequencyfunction vidioc_s_hw_freq_seekfunction tea575x_s_ctrlfunction radio_tea5777_initfunction radio_tea5777_exitexport radio_tea5777_initexport radio_tea5777_exit
Annotated Snippet
if (tea->freq < rangelow || tea->freq > rangehigh) {
tea->freq = clamp(tea->freq, rangelow,
rangehigh);
res = radio_tea5777_set_freq(tea);
if (res)
return res;
}
} else {
rangelow = bands[tea->band].rangelow;
rangehigh = bands[tea->band].rangehigh;
}
spacing = (tea->band == BAND_AM) ? (5 * 16) : (200 * 16); /* kHz */
orig_freq = tea->freq;
tea->write_reg |= TEA5777_W_PROGBLIM_MASK;
if (tea->seek_rangelow != rangelow) {
tea->write_reg &= ~TEA5777_W_UPDWN_MASK;
tea->freq = rangelow;
res = radio_tea5777_set_freq(tea);
if (res)
goto leave;
tea->seek_rangelow = rangelow;
}
if (tea->seek_rangehigh != rangehigh) {
tea->write_reg |= TEA5777_W_UPDWN_MASK;
tea->freq = rangehigh;
res = radio_tea5777_set_freq(tea);
if (res)
goto leave;
tea->seek_rangehigh = rangehigh;
}
tea->write_reg &= ~TEA5777_W_PROGBLIM_MASK;
tea->write_reg |= TEA5777_W_SEARCH_MASK;
if (a->seek_upward) {
tea->write_reg |= TEA5777_W_UPDWN_MASK;
tea->freq = orig_freq + spacing;
} else {
tea->write_reg &= ~TEA5777_W_UPDWN_MASK;
tea->freq = orig_freq - spacing;
}
res = radio_tea5777_set_freq(tea);
if (res)
goto leave;
timeout = jiffies + msecs_to_jiffies(5000);
for (;;) {
if (time_after(jiffies, timeout)) {
res = -ENODATA;
break;
}
res = radio_tea5777_update_read_reg(tea, 100);
if (res)
break;
/*
* Note we use tea->freq to track how far we've searched sofar
* this is necessary to ensure we continue seeking at the right
* point, in the write_before_read case.
*/
tea->freq = (tea->read_reg & TEA5777_R_FM_PLL_MASK);
tea->freq = tea5777_freq_to_v4l2_freq(tea, tea->freq);
if ((tea->read_reg & TEA5777_R_SFOUND_MASK)) {
tea->write_reg &= ~TEA5777_W_SEARCH_MASK;
return 0;
}
if (tea->read_reg & TEA5777_R_BLIM_MASK) {
res = -ENODATA;
break;
}
/* Force read_reg update */
tea->read_reg = -1;
}
leave:
tea->write_reg &= ~TEA5777_W_PROGBLIM_MASK;
tea->write_reg &= ~TEA5777_W_SEARCH_MASK;
tea->freq = orig_freq;
radio_tea5777_set_freq(tea);
return res;
}
static int tea575x_s_ctrl(struct v4l2_ctrl *c)
{
struct radio_tea5777 *tea =
container_of(c->handler, struct radio_tea5777, ctrl_handler);
Annotation
- Immediate include surface: `linux/delay.h`, `linux/init.h`, `linux/module.h`, `linux/sched.h`, `linux/slab.h`, `media/v4l2-device.h`, `media/v4l2-dev.h`, `media/v4l2-fh.h`.
- Detected declarations: `function tea5777_freq_to_v4l2_freq`, `function radio_tea5777_set_freq`, `function radio_tea5777_update_read_reg`, `function vidioc_querycap`, `function vidioc_enum_freq_bands`, `function vidioc_g_tuner`, `function vidioc_s_tuner`, `function vidioc_g_frequency`, `function vidioc_s_frequency`, `function vidioc_s_hw_freq_seek`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: integration implementation candidate.
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.