drivers/input/keyboard/sunkbd.c

Source file repositories/reference/linux-study-clean/drivers/input/keyboard/sunkbd.c

File Facts

System
Linux kernel
Corpus path
drivers/input/keyboard/sunkbd.c
Extension
.c
Size
8912 bytes
Lines
377
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

struct sunkbd {
	unsigned char keycode[ARRAY_SIZE(sunkbd_keycode)];
	struct input_dev *dev;
	struct serio *serio;
	struct work_struct tq;
	wait_queue_head_t wait;
	char name[64];
	char phys[32];
	char type;
	bool enabled;
	volatile s8 reset;
	volatile s8 layout;
};

/*
 * sunkbd_interrupt() is called by the low level driver when a character
 * is received.
 */

static irqreturn_t sunkbd_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct sunkbd *sunkbd = serio_get_drvdata(serio);

	if (sunkbd->reset <= -1) {
		/*
		 * If cp[i] is 0xff, sunkbd->reset will stay -1.
		 * The keyboard sends 0xff 0xff 0xID on powerup.
		 */
		sunkbd->reset = data;
		wake_up_interruptible(&sunkbd->wait);
		goto out;
	}

	if (sunkbd->layout == -1) {
		sunkbd->layout = data;
		wake_up_interruptible(&sunkbd->wait);
		goto out;
	}

	switch (data) {

	case SUNKBD_RET_RESET:
		if (sunkbd->enabled)
			schedule_work(&sunkbd->tq);
		sunkbd->reset = -1;
		break;

	case SUNKBD_RET_LAYOUT:
		sunkbd->layout = -1;
		break;

	case SUNKBD_RET_ALLUP: /* All keys released */
		break;

	default:
		if (!sunkbd->enabled)
			break;

		if (sunkbd->keycode[data & SUNKBD_KEY]) {
			input_report_key(sunkbd->dev,
					 sunkbd->keycode[data & SUNKBD_KEY],
					 !(data & SUNKBD_RELEASE));
			input_sync(sunkbd->dev);
		} else {
			printk(KERN_WARNING
				"sunkbd.c: Unknown key (scancode %#x) %s.\n",
				data & SUNKBD_KEY,
				data & SUNKBD_RELEASE ? "released" : "pressed");
		}
	}
out:
	return IRQ_HANDLED;
}

/*
 * sunkbd_event() handles events from the input module.
 */

static int sunkbd_event(struct input_dev *dev,
			unsigned int type, unsigned int code, int value)
{
	struct sunkbd *sunkbd = input_get_drvdata(dev);

	switch (type) {

	case EV_LED:

		serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
		serio_write(sunkbd->serio,

Annotation

Implementation Notes