drivers/media/rc/st_rc.c

Source file repositories/reference/linux-study-clean/drivers/media/rc/st_rc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/rc/st_rc.c
Extension
.c
Size
11336 bytes
Lines
419
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 st_rc_device {
	struct device			*dev;
	int				irq;
	int				irq_wake;
	struct clk			*sys_clock;
	void __iomem			*base;	/* Register base address */
	void __iomem			*rx_base;/* RX Register base address */
	struct rc_dev			*rdev;
	bool				overclocking;
	int				sample_mult;
	int				sample_div;
	bool				rxuhfmode;
	struct	reset_control		*rstc;
};

/* Registers */
#define IRB_SAMPLE_RATE_COMM	0x64	/* sample freq divisor*/
#define IRB_CLOCK_SEL		0x70	/* clock select       */
#define IRB_CLOCK_SEL_STATUS	0x74	/* clock status       */
/* IRB IR/UHF receiver registers */
#define IRB_RX_ON               0x40	/* pulse time capture */
#define IRB_RX_SYS              0X44	/* sym period capture */
#define IRB_RX_INT_EN           0x48	/* IRQ enable (R/W)   */
#define IRB_RX_INT_STATUS       0x4c	/* IRQ status (R/W)   */
#define IRB_RX_EN               0x50	/* Receive enable     */
#define IRB_MAX_SYM_PERIOD      0x54	/* max sym value      */
#define IRB_RX_INT_CLEAR        0x58	/* overrun status     */
#define IRB_RX_STATUS           0x6c	/* receive status     */
#define IRB_RX_NOISE_SUPPR      0x5c	/* noise suppression  */
#define IRB_RX_POLARITY_INV     0x68	/* polarity inverter  */

/*
 * IRQ set: Enable full FIFO                 1  -> bit  3;
 *          Enable overrun IRQ               1  -> bit  2;
 *          Enable last symbol IRQ           1  -> bit  1:
 *          Enable RX interrupt              1  -> bit  0;
 */
#define IRB_RX_INTS		0x0f
#define IRB_RX_OVERRUN_INT	0x04
 /* maximum symbol period (microsecs),timeout to detect end of symbol train */
#define MAX_SYMB_TIME		0x5000
#define IRB_SAMPLE_FREQ		10000000
#define	IRB_FIFO_NOT_EMPTY	0xff00
#define IRB_OVERFLOW		0x4
#define IRB_TIMEOUT		0xffff
#define IR_ST_NAME "st-rc"

static void st_rc_send_lirc_timeout(struct rc_dev *rdev)
{
	struct ir_raw_event ev = { .timeout = true, .duration = rdev->timeout };
	ir_raw_event_store(rdev, &ev);
}

/*
 * RX graphical example to better understand the difference between ST IR block
 * output and standard definition used by LIRC (and most of the world!)
 *
 *           mark                                     mark
 *      |-IRB_RX_ON-|                            |-IRB_RX_ON-|
 *      ___  ___  ___                            ___  ___  ___             _
 *      | |  | |  | |                            | |  | |  | |             |
 *      | |  | |  | |         space 0            | |  | |  | |   space 1   |
 * _____| |__| |__| |____________________________| |__| |__| |_____________|
 *
 *      |--------------- IRB_RX_SYS -------------|------ IRB_RX_SYS -------|
 *
 *      |------------- encoding bit 0 -----------|---- encoding bit 1 -----|
 *
 * ST hardware returns mark (IRB_RX_ON) and total symbol time (IRB_RX_SYS), so
 * convert to standard mark/space we have to calculate space=(IRB_RX_SYS-mark)
 * The mark time represents the amount of time the carrier (usually 36-40kHz)
 * is detected.The above examples shows Pulse Width Modulation encoding where
 * bit 0 is represented by space>mark.
 */

static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
{
	unsigned long timeout;
	unsigned int symbol, mark = 0;
	struct st_rc_device *dev = data;
	int last_symbol = 0;
	u32 status, int_status;
	struct ir_raw_event ev = {};

	if (dev->irq_wake)
		pm_wakeup_event(dev->dev, 0);

	/* FIXME: is 10ms good enough ? */
	timeout = jiffies +  msecs_to_jiffies(10);
	do {

Annotation

Implementation Notes