// SPDX-License-Identifier: GPL-2.0
/*
* HID driver for Maltron L90
*
* Copyright ( c ) 1999 Andreas Gal
* Copyright ( c ) 2000 - 2005 Vojtech Pavlik < vojtech @ suse . cz >
* Copyright ( c ) 2005 Michael Haboustak < mike - @ cinci . rr . com > for Concept2 , Inc
* Copyright ( c ) 2008 Jiri Slaby
* Copyright ( c ) 2012 David Dillow < dave @ thedillows . org >
* Copyright ( c ) 2006 - 2013 Jiri Kosina
* Copyright ( c ) 2013 Colin Leitner < colin . leitner @ gmail . com >
* Copyright ( c ) 2014 - 2016 Frank Praznik < frank . praznik @ gmail . com >
* Copyright ( c ) 2010 Richard Nauber < Richard . Nauber @ gmail . com >
* Copyright ( c ) 2016 Yuxuan Shui < yshuiv7 @ gmail . com >
* Copyright ( c ) 2018 William Whistler < wtbw @ wtbw . co . uk >
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include "hid-ids.h"
/* The original buggy USB descriptor */
static const u8 maltron_rdesc_o[] = {
0 x05, 0 x01, /* Usage Page (Generic Desktop Ctrls) */
0 x09, 0 x80, /* Usage (Sys Control) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x02, /* Report ID (2) */
0 x75, 0 x01, /* Report Size (1) */
0 x95, 0 x01, /* Report Count (1) */
0 x15, 0 x00, /* Logical Minimum (0) */
0 x25, 0 x01, /* Logical Maximum (1) */
0 x09, 0 x82, /* Usage (Sys Sleep) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x09, 0 x82, /* Usage (Sys Sleep) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x09, 0 x83, /* Usage (Sys Wake Up) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x75, 0 x05, /* Report Size (5) */
0 x81, 0 x01, /* Input (Const,Array,Abs) */
0 xC0, /* End Collection */
0 x05, 0 x0C, /* Usage Page (Consumer) */
0 x09, 0 x01, /* Usage (Consumer Control) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x03, /* Report ID (3) */
0 x95, 0 x01, /* Report Count (1) */
0 x75, 0 x10, /* Report Size (16) */
0 x19, 0 x00, /* Usage Minimum (Unassigned) */
0 x2A, 0 xFF, 0 x7F, /* Usage Maximum (0x7FFF) */
0 x81, 0 x00, /* Input (Data,Array,Abs) */
0 xC0, /* End Collection */
0 x06, 0 x7F, 0 xFF, /* Usage Page (Vendor Defined 0xFF7F) */
0 x09, 0 x01, /* Usage (0x01) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x04, /* Report ID (4) */
0 x95, 0 x01, /* Report Count (1) */
0 x75, 0 x10, /* Report Size (16) */
0 x19, 0 x00, /* Usage Minimum (0x00) */
0 x2A, 0 xFF, 0 x7F, /* Usage Maximum (0x7FFF) */
0 x81, 0 x00, /* Input (Data,Array,Abs) */
0 x75, 0 x02, /* Report Size (2) */
0 x25, 0 x02, /* Logical Maximum (2) */
0 x09, 0 x90, /* Usage (0x90) */
0 xB1, 0 x02, /* Feature (Data,Var,Abs) */
0 x75, 0 x06, /* Report Size (6) */
0 xB1, 0 x01, /* Feature (Const,Array,Abs) */
0 x75, 0 x01, /* Report Size (1) */
0 x25, 0 x01, /* Logical Maximum (1) */
0 x05, 0 x08, /* Usage Page (LEDs) */
0 x09, 0 x2A, /* Usage (On-Line) */
0 x91, 0 x02, /* Output (Data,Var,Abs) */
0 x09, 0 x4B, /* Usage (Generic Indicator) */
0 x91, 0 x02, /* Output (Data,Var,Abs) */
0 x75, 0 x06, /* Report Size (6) */
0 x95, 0 x01, /* Report Count (1) */
0 x91, 0 x01, /* Output (Const,Array,Abs) */
0 xC0 /* End Collection */
};
/* The patched descriptor, allowing media key events to be accepted as valid */
static const u8 maltron_rdesc[] = {
0 x05, 0 x01, /* Usage Page (Generic Desktop Ctrls) */
0 x09, 0 x80, /* Usage (Sys Control) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x02, /* Report ID (2) */
0 x75, 0 x01, /* Report Size (1) */
0 x95, 0 x01, /* Report Count (1) */
0 x15, 0 x00, /* Logical Minimum (0) */
0 x25, 0 x01, /* Logical Maximum (1) */
0 x09, 0 x82, /* Usage (Sys Sleep) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x09, 0 x82, /* Usage (Sys Sleep) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x09, 0 x83, /* Usage (Sys Wake Up) */
0 x81, 0 x06, /* Input (Data,Var,Rel) */
0 x75, 0 x05, /* Report Size (5) */
0 x81, 0 x01, /* Input (Const,Array,Abs) */
0 xC0, /* End Collection */
0 x05, 0 x0C, /* Usage Page (Consumer) */
0 x09, 0 x01, /* Usage (Consumer Control) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x03, /* Report ID (3) */
0 x15, 0 x00, /* Logical Minimum (0) - changed */
0 x26, 0 xFF, 0 x7F, /* Logical Maximum (32767) - changed */
0 x95, 0 x01, /* Report Count (1) */
0 x75, 0 x10, /* Report Size (16) */
0 x19, 0 x00, /* Usage Minimum (Unassigned) */
0 x2A, 0 xFF, 0 x7F, /* Usage Maximum (0x7FFF) */
0 x81, 0 x00, /* Input (Data,Array,Abs) */
0 xC0, /* End Collection */
0 x06, 0 x7F, 0 xFF, /* Usage Page (Vendor Defined 0xFF7F) */
0 x09, 0 x01, /* Usage (0x01) */
0 xA1, 0 x01, /* Collection (Application) */
0 x85, 0 x04, /* Report ID (4) */
0 x95, 0 x01, /* Report Count (1) */
0 x75, 0 x10, /* Report Size (16) */
0 x19, 0 x00, /* Usage Minimum (0x00) */
0 x2A, 0 xFF, 0 x7F, /* Usage Maximum (0x7FFF) */
0 x81, 0 x00, /* Input (Data,Array,Abs) */
0 x75, 0 x02, /* Report Size (2) */
0 x25, 0 x02, /* Logical Maximum (2) */
0 x09, 0 x90, /* Usage (0x90) */
0 xB1, 0 x02, /* Feature (Data,Var,Abs) */
0 x75, 0 x06, /* Report Size (6) */
0 xB1, 0 x01, /* Feature (Const,Array,Abs) */
0 x75, 0 x01, /* Report Size (1) */
0 x25, 0 x01, /* Logical Maximum (1) */
0 x05, 0 x08, /* Usage Page (LEDs) */
0 x09, 0 x2A, /* Usage (On-Line) */
0 x91, 0 x02, /* Output (Data,Var,Abs) */
0 x09, 0 x4B, /* Usage (Generic Indicator) */
0 x91, 0 x02, /* Output (Data,Var,Abs) */
0 x75, 0 x06, /* Report Size (6) */
0 x95, 0 x01, /* Report Count (1) */
0 x91, 0 x01, /* Output (Const,Array,Abs) */
0 xC0 /* End Collection */
};
static const __u8 *maltron_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize == sizeof (maltron_rdesc_o) &&
!memcmp(maltron_rdesc_o, rdesc, sizeof (maltron_rdesc_o))) {
hid_info(hdev, "Replacing Maltron L90 keyboard report descriptor\n" );
*rsize = sizeof (maltron_rdesc);
return maltron_rdesc;
}
return rdesc;
}
static const struct hid_device_id maltron_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_MALTRON_KB)},
{ }
};
MODULE_DEVICE_TABLE(hid, maltron_devices);
static struct hid_driver maltron_driver = {
.name = "maltron" ,
.id_table = maltron_devices,
.report_fixup = maltron_report_fixup
};
module_hid_driver(maltron_driver);
MODULE_DESCRIPTION("HID driver for Maltron L90" );
MODULE_LICENSE("GPL" );
Messung V0.5 in Prozent C=33 H=100 G=74
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland