drivers/input/serio/parkbd.c

Source file repositories/reference/linux-study-clean/drivers/input/serio/parkbd.c

File Facts

System
Linux kernel
Corpus path
drivers/input/serio/parkbd.c
Extension
.c
Size
5352 bytes
Lines
223
Domain
Driver Families
Bucket
drivers/input
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

if (parkbd_counter && ((parkbd_counter == 11) || time_after(jiffies, parkbd_last + HZ/100))) {
			parkbd_counter = 0;
			parkbd_buffer = 0;
			parkbd_writing = 0;
			parkbd_writelines(3);
			return;
		}

		parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);

		if (parkbd_counter == 11) {
			parkbd_counter = 0;
			parkbd_buffer = 0;
			parkbd_writing = 0;
			parkbd_writelines(3);
		}

	} else {

		if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
			parkbd_counter = 0;
			parkbd_buffer = 0;
		}

		parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;

		if (parkbd_counter == parkbd_mode + 10)
			serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0);
	}

	parkbd_last = jiffies;
}

static int parkbd_getport(struct parport *pp)
{
	struct pardev_cb parkbd_parport_cb;

	memset(&parkbd_parport_cb, 0, sizeof(parkbd_parport_cb));
	parkbd_parport_cb.irq_func = parkbd_interrupt;
	parkbd_parport_cb.flags = PARPORT_FLAG_EXCL;

	parkbd_dev = parport_register_dev_model(pp, "parkbd",
						&parkbd_parport_cb, 0);

	if (!parkbd_dev)
		return -ENODEV;

	if (parport_claim(parkbd_dev)) {
		parport_unregister_device(parkbd_dev);
		return -EBUSY;
	}

	parkbd_start = jiffies;

	return 0;
}

static struct serio *parkbd_allocate_serio(void)
{
	struct serio *serio;

	serio = kzalloc_obj(*serio);
	if (serio) {
		serio->id.type = parkbd_mode;
		serio->write = parkbd_write;
		strscpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
		snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
	}

	return serio;
}

static void parkbd_attach(struct parport *pp)
{
	if (pp->number != parkbd_pp_no) {
		pr_debug("Not using parport%d.\n", pp->number);
		return;
	}

	if (parkbd_getport(pp))
		return;

	parkbd_port = parkbd_allocate_serio();
	if (!parkbd_port) {
		parport_release(parkbd_dev);
		parport_unregister_device(parkbd_dev);
		return;
	}

	parkbd_writelines(3);

Annotation

Implementation Notes