drivers/media/rc/sunxi-cir.c
Source file repositories/reference/linux-study-clean/drivers/media/rc/sunxi-cir.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/rc/sunxi-cir.c- Extension
.c- Size
- 10818 bytes
- Lines
- 431
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/clk.hlinux/interrupt.hlinux/io.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/reset.hmedia/rc-core.h
Detected Declarations
struct sunxi_ir_quirksstruct sunxi_irfunction sunxi_ir_irqfunction sunxi_ithr_to_usecfunction sunxi_usec_to_ithrfunction sunxi_ir_set_timeoutfunction sunxi_ir_hw_initfunction sunxi_ir_hw_exitfunction sunxi_ir_suspendfunction sunxi_ir_resumefunction sunxi_ir_probefunction sunxi_ir_removefunction sunxi_ir_shutdown
Annotated Snippet
struct sunxi_ir_quirks {
bool has_reset;
int fifo_size;
};
struct sunxi_ir {
struct rc_dev *rc;
void __iomem *base;
int irq;
int fifo_size;
struct clk *clk;
struct clk *apb_clk;
struct reset_control *rst;
const char *map_name;
};
static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
{
unsigned long status;
unsigned char dt;
unsigned int cnt, rc;
struct sunxi_ir *ir = dev_id;
struct ir_raw_event rawir = {};
status = readl(ir->base + SUNXI_IR_RXSTA_REG);
/* clean all pending statuses */
writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
if (status & (REG_RXSTA_RA | REG_RXSTA_RPE)) {
/* How many messages in fifo */
rc = REG_RXSTA_GET_AC(status);
/* Sanity check */
rc = rc > ir->fifo_size ? ir->fifo_size : rc;
/* If we have data */
for (cnt = 0; cnt < rc; cnt++) {
/* for each bit in fifo */
dt = readb(ir->base + SUNXI_IR_RXFIFO_REG);
rawir.pulse = (dt & 0x80) != 0;
rawir.duration = ((dt & 0x7f) + 1) *
ir->rc->rx_resolution;
ir_raw_event_store_with_filter(ir->rc, &rawir);
}
}
if (status & REG_RXSTA_ROI) {
ir_raw_event_overflow(ir->rc);
} else if (status & REG_RXSTA_RPE) {
ir_raw_event_set_idle(ir->rc, true);
ir_raw_event_handle(ir->rc);
} else {
ir_raw_event_handle(ir->rc);
}
return IRQ_HANDLED;
}
/* Convert idle threshold to usec */
static unsigned int sunxi_ithr_to_usec(unsigned int base_clk, unsigned int ithr)
{
return DIV_ROUND_CLOSEST(USEC_PER_SEC * (ithr + 1),
base_clk / (128 * 64));
}
/* Convert usec to idle threshold */
static unsigned int sunxi_usec_to_ithr(unsigned int base_clk, unsigned int usec)
{
/* make sure we don't end up with a timeout less than requested */
return DIV_ROUND_UP((base_clk / (128 * 64)) * usec, USEC_PER_SEC) - 1;
}
static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
{
struct sunxi_ir *ir = rc_dev->priv;
unsigned int base_clk = clk_get_rate(ir->clk);
unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
/* Set noise threshold and idle threshold */
writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
ir->base + SUNXI_IR_CIR_REG);
rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
return 0;
}
static int sunxi_ir_hw_init(struct device *dev)
Annotation
- Immediate include surface: `linux/clk.h`, `linux/interrupt.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/reset.h`, `media/rc-core.h`.
- Detected declarations: `struct sunxi_ir_quirks`, `struct sunxi_ir`, `function sunxi_ir_irq`, `function sunxi_ithr_to_usec`, `function sunxi_usec_to_ithr`, `function sunxi_ir_set_timeout`, `function sunxi_ir_hw_init`, `function sunxi_ir_hw_exit`, `function sunxi_ir_suspend`, `function sunxi_ir_resume`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.