drivers/media/pci/cx88/cx88-input.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cx88/cx88-input.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cx88/cx88-input.c
Extension
.c
Size
16936 bytes
Lines
652
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cx88_IR {
	struct cx88_core *core;
	struct rc_dev *dev;

	int users;

	char name[32];
	char phys[32];

	/* sample from gpio pin 16 */
	u32 sampling;

	/* poll external decoder */
	int polling;
	struct hrtimer timer;
	u32 gpio_addr;
	u32 last_gpio;
	u32 mask_keycode;
	u32 mask_keydown;
	u32 mask_keyup;
};

static unsigned int ir_samplerate = 4;
module_param(ir_samplerate, uint, 0444);
MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4");

static int ir_debug;
module_param(ir_debug, int, 0644);	/* debug level [IR] */
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");

#define ir_dprintk(fmt, arg...)	do {					\
	if (ir_debug)							\
		printk(KERN_DEBUG "%s IR: " fmt, ir->core->name, ##arg);\
} while (0)

#define dprintk(fmt, arg...) do {					\
	if (ir_debug)							\
		printk(KERN_DEBUG "cx88 IR: " fmt, ##arg);		\
} while (0)

/* ---------------------------------------------------------------------- */

static void cx88_ir_handle_key(struct cx88_IR *ir)
{
	struct cx88_core *core = ir->core;
	u32 gpio, data, auxgpio;

	/* read gpio value */
	gpio = cx_read(ir->gpio_addr);
	switch (core->boardnr) {
	case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
		/*
		 * This board apparently uses a combination of 2 GPIO
		 * to represent the keys. Additionally, the second GPIO
		 * can be used for parity.
		 *
		 * Example:
		 *
		 * for key "5"
		 *	gpio = 0x758, auxgpio = 0xe5 or 0xf5
		 * for key "Power"
		 *	gpio = 0x758, auxgpio = 0xed or 0xfd
		 */

		auxgpio = cx_read(MO_GP1_IO);
		/* Take out the parity part */
		gpio = (gpio & 0x7fd) + (auxgpio & 0xef);
		break;
	case CX88_BOARD_WINFAST_DTV1000:
	case CX88_BOARD_WINFAST_DTV1800H:
	case CX88_BOARD_WINFAST_DTV1800H_XC4000:
	case CX88_BOARD_WINFAST_DTV2000H_PLUS:
	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
		gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
		auxgpio = gpio;
		break;
	default:
		auxgpio = gpio;
	}
	if (ir->polling) {
		if (ir->last_gpio == auxgpio)
			return;
		ir->last_gpio = auxgpio;
	}

	/* extract data */
	data = ir_extract_bits(gpio, ir->mask_keycode);
	ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",

Annotation

Implementation Notes