drivers/media/rc/ir_toy.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/rc/ir_toy.c
Extension
.c
Size
13064 bytes
Lines
553
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 irtoy {
	struct device *dev;
	struct usb_device *usbdev;

	struct rc_dev *rc;
	struct urb *urb_in, *urb_out;

	u8 *in;
	u8 *out;
	struct completion command_done;

	bool pulse;
	enum state state;

	void *tx_buf;
	uint tx_len;

	uint emitted;
	uint hw_version;
	uint sw_version;
	uint proto_version;

	char phys[64];
};

static void irtoy_response(struct irtoy *irtoy, u32 len)
{
	switch (irtoy->state) {
	case STATE_COMMAND:
		if (len == LEN_VERSION && irtoy->in[0] == REPLY_VERSION) {
			uint version;

			irtoy->in[LEN_VERSION] = 0;

			if (kstrtouint(irtoy->in + 1, 10, &version)) {
				dev_err(irtoy->dev, "invalid version %*phN. Please make sure you are using firmware v20 or higher",
					LEN_VERSION, irtoy->in);
				break;
			}

			dev_dbg(irtoy->dev, "version %s\n", irtoy->in);

			irtoy->hw_version = version / 100;
			irtoy->sw_version = version % 100;

			irtoy->state = STATE_IRDATA;
			complete(&irtoy->command_done);
		} else if (len == LEN_SAMPLEMODEPROTO &&
			   irtoy->in[0] == REPLY_SAMPLEMODEPROTO) {
			uint version;

			irtoy->in[LEN_SAMPLEMODEPROTO] = 0;

			if (kstrtouint(irtoy->in + 1, 10, &version)) {
				dev_err(irtoy->dev, "invalid sample mode response %*phN",
					LEN_SAMPLEMODEPROTO, irtoy->in);
				return;
			}

			dev_dbg(irtoy->dev, "protocol %s\n", irtoy->in);

			irtoy->proto_version = version;

			irtoy->state = STATE_IRDATA;
			complete(&irtoy->command_done);
		} else {
			dev_err(irtoy->dev, "unexpected response to command: %*phN\n",
				len, irtoy->in);
		}
		break;
	case STATE_COMMAND_NO_RESP:
	case STATE_IRDATA: {
		struct ir_raw_event rawir = { .pulse = irtoy->pulse };
		__be16 *in = (__be16 *)irtoy->in;
		int i;

		for (i = 0; i < len / sizeof(__be16); i++) {
			u16 v = be16_to_cpu(in[i]);

			if (v == 0xffff) {
				rawir.pulse = false;
			} else {
				rawir.duration = v * UNIT_US;
				ir_raw_event_store_with_timeout(irtoy->rc,
								&rawir);
			}

			rawir.pulse = !rawir.pulse;
		}

Annotation

Implementation Notes