GMMOS: I2C keyboards, and every keyboard at once
The second micro driver: i2c_hid.c with everything but reading a keyboard's input reports taken out. No ACPI -- AML cannot run on a dead kernel -- so the live driver hands over what it found at boot (i2c_hid_keyboards): the DesignWare controller, the address, the report size, the AMD GPIO pin if there is one, and the parsed report descriptor. No power commands, no reset, a read-only transfer. usb_hid.c's report-protocol rewrite is split out as hid_boot_report(), which does nothing but rewrite, and kernel/gmmos/hidkeys.c turns boot reports into keys for this and the USB micro drivers to come. GMMOS now probes every micro driver and polls all that answer. Not run: QEMU has no DesignWare I2C, and the laptops at hand have PS/2 keyboards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
cb9b06d46f
commit
c6d90e69fa
8 changed files with 387 additions and 17 deletions
|
|
@ -12,6 +12,13 @@ void *hid_attach(const uchar *desc, int n, const char *what);
|
|||
// One input report, report ID included when the device uses them.
|
||||
void hid_attached_input(void *h, const uchar *rep, int len);
|
||||
|
||||
// For GMMOS, after a panic: whether a device is a keyboard, and one of its
|
||||
// reports rewritten into the 8-byte boot layout (modifiers, reserved, six
|
||||
// usages) with nothing else done -- no queue, no lock, no events. 0 when the
|
||||
// report was not a keyboard's.
|
||||
int hid_is_keyboard(void *h);
|
||||
int hid_boot_report(void *h, const uchar *rep, int len, uchar *boot);
|
||||
|
||||
// I2C-HID: the touchpads (and some keyboards) of laptops. Started once ACPI
|
||||
// and kernel threads are up; see kernel/drivers/i2c/i2c_hid.c.
|
||||
void i2c_hid_start(void);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,33 @@ struct gmmos_kbd {
|
|||
};
|
||||
|
||||
extern const struct gmmos_kbd gmmos_ps2;
|
||||
extern const struct gmmos_kbd gmmos_i2c;
|
||||
|
||||
// A USB or I2C keyboard report in the boot layout -- modifiers, a reserved
|
||||
// byte, six usages -- turned into keys. A report is a state, not an event, so
|
||||
// a key is a usage that was not in the previous one. kernel/gmmos/hidkeys.c.
|
||||
struct gmmos_hidkeys {
|
||||
uchar prev[8];
|
||||
int q[16];
|
||||
int qh, qt;
|
||||
};
|
||||
void gmmos_hid_report(struct gmmos_hidkeys *k, const uchar *boot);
|
||||
int gmmos_hid_next(struct gmmos_hidkeys *k);
|
||||
|
||||
// I2C keyboards, as kernel/acpi/i2c_hid.c found them at boot. GMMOS cannot run
|
||||
// ACPI to find them again, so the live driver hands over what it learnt: the
|
||||
// DesignWare controller, the device's address, its input report size, the
|
||||
// interrupt pin when there is one, and the parsed report descriptor.
|
||||
struct gmmos_i2c_kbd {
|
||||
volatile uint32 *regs;
|
||||
int txdepth, rxdepth;
|
||||
int addr;
|
||||
uint32 maxin;
|
||||
volatile uint32 *pin; // AMD GPIO pin register, or 0: poll blindly
|
||||
int active_low;
|
||||
void *hid;
|
||||
};
|
||||
int i2c_hid_keyboards(struct gmmos_i2c_kbd *out, int max);
|
||||
|
||||
// From kernel/core/panic.c: draw the report again, and where its closing
|
||||
// lines are, which GMMOS writes its status and its keys into.
|
||||
|
|
|
|||
Loading…
Reference in a new issue