drivers/staging/media/av7110/av7110_ir.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/av7110/av7110_ir.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/av7110/av7110_ir.c
Extension
.c
Size
3842 bytes
Lines
159
Domain
Driver Families
Bucket
drivers/staging
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

switch (av7110->ir.ir_config) {
		case IR_RC5: /* RC5: 5 bits device address, 6 bits command */
			command = ircom & 0x3f;
			addr = (ircom >> 6) & 0x1f;
			scancode = RC_SCANCODE_RC5(addr, command);
			toggle = ircom & 0x0800;
			proto = RC_PROTO_RC5;
			break;

		case IR_RCMM: /* RCMM: 32 bits scancode */
			scancode = ircom & ~0x8000;
			toggle = ircom & 0x8000;
			proto = RC_PROTO_RCMM32;
			break;

		case IR_RC5_EXT:
			/*
			 * extended RC5: 5 bits device address, 7 bits command
			 *
			 * Extended RC5 uses only one start bit. The second
			 * start bit is re-assigned bit 6 of the command bit.
			 */
			command = ircom & 0x3f;
			addr = (ircom >> 6) & 0x1f;
			if (!(ircom & 0x1000))
				command |= 0x40;
			scancode = RC_SCANCODE_RC5(addr, command);
			toggle = ircom & 0x0800;
			proto = RC_PROTO_RC5;
			break;
		default:
			dprintk(2, "unknown ir config %d\n", av7110->ir.ir_config);
			return;
		}

		rc_keydown(rcdev, proto, scancode, toggle != 0);
	}
}

int av7110_set_ir_config(struct av7110 *av7110)
{
	dprintk(4, "ir config = %08x\n", av7110->ir.ir_config);

	return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER,
			     AV7110_SET_IR, 1, av7110->ir.ir_config);
}

static int change_protocol(struct rc_dev *rcdev, u64 *rc_type)
{
	struct av7110 *av7110 = rcdev->priv;
	u32 ir_config;

	if (*rc_type & RC_PROTO_BIT_RCMM32) {
		ir_config = IR_RCMM;
		*rc_type = RC_PROTO_BIT_RCMM32;
	} else if (*rc_type & RC_PROTO_BIT_RC5) {
		if (FW_VERSION(av7110->arm_app) >= 0x2620)
			ir_config = IR_RC5_EXT;
		else
			ir_config = IR_RC5;
		*rc_type = RC_PROTO_BIT_RC5;
	} else {
		return -EINVAL;
	}

	if (ir_config == av7110->ir.ir_config)
		return 0;

	av7110->ir.ir_config = ir_config;

	return av7110_set_ir_config(av7110);
}

int av7110_ir_init(struct av7110 *av7110)
{
	struct rc_dev *rcdev;
	struct pci_dev *pci;
	int ret;

	rcdev = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!rcdev)
		return -ENOMEM;

	pci = av7110->dev->pci;

	snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
		 "pci-%s/ir0", pci_name(pci));

	rcdev->device_name = av7110->card_name;
	rcdev->driver_name = KBUILD_MODNAME;

Annotation

Implementation Notes