Commit 48a732df authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID subsystem updates from Jiri Kosina:
 "HID subsystem and drivers update. Highlights:

   - new support of a group of Win7/Win8 multitouch devices, from
     Benjamin Tissoires

   - fix for compat interface brokenness in uhid, from Dmitry Torokhov

   - conversion of drivers to use hid_driver helper, by H Hartley
     Sweeten

   - HID over I2C transport received ACPI enumeration support, written
     by Mika Westerberg

   - there is an ongoing effort to make HID sensor hubs independent of
     USB transport.  The first self-contained part of this work is
     provided here, done by Mika Westerberg

   - a few smaller fixes here and there, support for a couple new
     devices added"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (43 commits)
  HID: Correct Logitech order in hid-ids.h
  HID: LG4FF: Remove unnecessary deadzone code
  HID: LG: Prevent the Logitech Gaming Wheels deadzone
  HID: LG: Fix detection of Logitech Speed Force Wireless (WiiWheel)
  HID: LG: Add support for Logitech Momo Force (Red) Wheel
  HID: hidraw: print message when succesfully initialized
  HID: logitech: split accel, brake for Driving Force wheel
  HID: logitech: add report descriptor for Driving Force wheel
  HID: add ThingM blink(1) USB RGB LED support
  HID: uhid: make creating devices work on 64/32 systems
  HID: wiimote: fix nunchuck button parser
  HID: blacklist Velleman data acquisition boards
  HID: sensor-hub: don't limit the driver only to USB bus
  HID: sensor-hub: get rid of unused sensor_hub_grabbed_usages[] table
  HID: extend autodetect to handle I2C sensors as well
  HID: ntrig: use input_configured() callback to set the name
  HID: multitouch: do not use pointers towards hid-core
  HID: add missing GENERIC_HARDIRQ dependency
  HID: multitouch: make MT_CLS_ALWAYS_TRUE the new default class
  HID: multitouch: fix protocol for Elo panels
  ...
parents 9afa3195 0d69a3c7
What: /sys/class/leds/SRWS1::<serial>::RPM1
What: /sys/class/leds/SRWS1::<serial>::RPM2
What: /sys/class/leds/SRWS1::<serial>::RPM3
What: /sys/class/leds/SRWS1::<serial>::RPM4
What: /sys/class/leds/SRWS1::<serial>::RPM5
What: /sys/class/leds/SRWS1::<serial>::RPM6
What: /sys/class/leds/SRWS1::<serial>::RPM7
What: /sys/class/leds/SRWS1::<serial>::RPM8
What: /sys/class/leds/SRWS1::<serial>::RPM9
What: /sys/class/leds/SRWS1::<serial>::RPM10
What: /sys/class/leds/SRWS1::<serial>::RPM11
What: /sys/class/leds/SRWS1::<serial>::RPM12
What: /sys/class/leds/SRWS1::<serial>::RPM13
What: /sys/class/leds/SRWS1::<serial>::RPM14
What: /sys/class/leds/SRWS1::<serial>::RPM15
What: /sys/class/leds/SRWS1::<serial>::RPMALL
Date: Jan 2013
KernelVersion: 3.9
Contact: Simon Wood <simon@mungewell.org>
Description: Provides a control for turning on/off the LEDs which form
an RPM meter on the front of the controller
What: /sys/class/leds/blink1::<serial>/rgb
Date: January 2013
Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Description: The ThingM blink1 is an USB RGB LED. The color notation is
3-byte hexadecimal. Read this attribute to get the last set
color. Write the 24-bit hexadecimal color to change the current
LED color. The default color is full white (0xFFFFFF).
For instance, set the color to green with: echo 00FF00 > rgb
What: /sys/class/leds/blink1::<serial>/fade
Date: January 2013
Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Description: This attribute allows to set a fade time in milliseconds for
the next color change. Read the attribute to know the current
fade time. The default value is set to 0 (no fade time). For
instance, set a fade time of 2 seconds with: echo 2000 > fade
What: /sys/class/leds/blink1::<serial>/play
Date: January 2013
Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Description: This attribute is used to play/pause the light patterns. Write 1
to start playing, 0 to stop. Reading this attribute returns the
current playing status.
......@@ -7611,6 +7611,11 @@ S: Supported
F: drivers/thermal/
F: include/linux/thermal.h
THINGM BLINK(1) USB RGB LED DRIVER
M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
S: Maintained
F: drivers/hid/hid-thingm.c
THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
......
......@@ -596,6 +596,12 @@ config HID_SPEEDLINK
---help---
Support for Speedlink Vicious and Divine Cezanne mouse.
config HID_STEELSERIES
tristate "Steelseries SRW-S1 steering wheel support"
depends on USB_HID
---help---
Support for Steelseries SRW-S1 steering wheel
config HID_SUNPLUS
tristate "Sunplus wireless desktop"
depends on USB_HID
......@@ -655,6 +661,16 @@ config HID_TOPSEED
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
CLLRCMCE remote control.
config HID_THINGM
tristate "ThingM blink(1) USB RGB LED"
depends on USB_HID
depends on LEDS_CLASS
---help---
Support for the ThingM blink(1) USB RGB LED. This driver registers a
Linux LED class instance, plus additional sysfs attributes to control
RGB colors, fade time and playing. The device is exposed through hidraw
to access other functions.
config HID_THRUSTMASTER
tristate "ThrustMaster devices support"
depends on USB_HID
......@@ -719,7 +735,7 @@ config HID_ZYDACRON
config HID_SENSOR_HUB
tristate "HID Sensors framework support"
depends on USB_HID
depends on USB_HID && GENERIC_HARDIRQS
select MFD_CORE
default n
-- help---
......
......@@ -101,8 +101,10 @@ obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
obj-$(CONFIG_HID_SONY) += hid-sony.o
obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o
obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
obj-$(CONFIG_HID_THINGM) += hid-thingm.o
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
......
......@@ -146,17 +146,6 @@ static struct hid_driver a4_driver = {
.probe = a4_probe,
.remove = a4_remove,
};
module_hid_driver(a4_driver);
static int __init a4_init(void)
{
return hid_register_driver(&a4_driver);
}
static void __exit a4_exit(void)
{
hid_unregister_driver(&a4_driver);
}
module_init(a4_init);
module_exit(a4_exit);
MODULE_LICENSE("GPL");
......@@ -555,23 +555,6 @@ static struct hid_driver apple_driver = {
.input_mapping = apple_input_mapping,
.input_mapped = apple_input_mapped,
};
module_hid_driver(apple_driver);
static int __init apple_init(void)
{
int ret;
ret = hid_register_driver(&apple_driver);
if (ret)
pr_err("can't register apple driver\n");
return ret;
}
static void __exit apple_exit(void)
{
hid_unregister_driver(&apple_driver);
}
module_init(apple_init);
module_exit(apple_exit);
MODULE_LICENSE("GPL");
......@@ -37,17 +37,6 @@ static struct hid_driver aureal_driver = {
.id_table = aureal_devices,
.report_fixup = aureal_report_fixup,
};
module_hid_driver(aureal_driver);
static int __init aureal_init(void)
{
return hid_register_driver(&aureal_driver);
}
static void __exit aureal_exit(void)
{
hid_unregister_driver(&aureal_driver);
}
module_init(aureal_init);
module_exit(aureal_exit);
MODULE_LICENSE("GPL");
......@@ -192,19 +192,7 @@ static struct hid_driver ax_driver = {
.probe = ax_probe,
.remove = ax_remove,
};
static int __init ax_init(void)
{
return hid_register_driver(&ax_driver);
}
static void __exit ax_exit(void)
{
hid_unregister_driver(&ax_driver);
}
module_init(ax_init);
module_exit(ax_exit);
module_hid_driver(ax_driver);
MODULE_AUTHOR("Sergei Kolzun");
MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers");
......
......@@ -86,17 +86,6 @@ static struct hid_driver belkin_driver = {
.input_mapping = belkin_input_mapping,
.probe = belkin_probe,
};
module_hid_driver(belkin_driver);
static int __init belkin_init(void)
{
return hid_register_driver(&belkin_driver);
}
static void __exit belkin_exit(void)
{
hid_unregister_driver(&belkin_driver);
}
module_init(belkin_init);
module_exit(belkin_exit);
MODULE_LICENSE("GPL");
......@@ -69,17 +69,6 @@ static struct hid_driver ch_driver = {
.report_fixup = ch_report_fixup,
.input_mapping = ch_input_mapping,
};
module_hid_driver(ch_driver);
static int __init ch_init(void)
{
return hid_register_driver(&ch_driver);
}
static void __exit ch_exit(void)
{
hid_unregister_driver(&ch_driver);
}
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
......@@ -70,17 +70,6 @@ static struct hid_driver ch_driver = {
.id_table = ch_devices,
.input_mapping = ch_input_mapping,
};
module_hid_driver(ch_driver);
static int __init ch_init(void)
{
return hid_register_driver(&ch_driver);
}
static void __exit ch_exit(void)
{
hid_unregister_driver(&ch_driver);
}
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
......@@ -729,7 +729,7 @@ static int hid_scan_report(struct hid_device *hid)
item.type == HID_ITEM_TYPE_MAIN &&
item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
(item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL &&
hid->bus == BUS_USB)
(hid->bus == BUS_USB || hid->bus == BUS_I2C))
hid->group = HID_GROUP_SENSOR_HUB;
}
......@@ -1195,6 +1195,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
{
struct hid_report_enum *report_enum = hid->report_enum + type;
struct hid_report *report;
struct hid_driver *hdrv;
unsigned int a;
int rsize, csize = size;
u8 *cdata = data;
......@@ -1231,6 +1232,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
if (hid->claimed != HID_CLAIMED_HIDRAW) {
for (a = 0; a < report->maxfield; a++)
hid_input_field(hid, report->field[a], cdata, interrupt);
hdrv = hid->driver;
if (hdrv && hdrv->report)
hdrv->report(hid, report);
}
if (hid->claimed & HID_CLAIMED_INPUT)
......@@ -1599,6 +1603,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
......@@ -1697,7 +1702,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
......@@ -2228,6 +2235,14 @@ bool hid_ignore(struct hid_device *hdev)
hdev->type != HID_TYPE_USBMOUSE)
return true;
break;
case USB_VENDOR_ID_VELLEMAN:
/* These are not HID devices. They are handled by comedi. */
if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST &&
hdev->product <= USB_DEVICE_ID_VELLEMAN_K8055_LAST) ||
(hdev->product >= USB_DEVICE_ID_VELLEMAN_K8061_FIRST &&
hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST))
return true;
break;
}
if (hdev->type == HID_TYPE_USBMOUSE &&
......
......@@ -144,17 +144,6 @@ static struct hid_driver cp_driver = {
.event = cp_event,
.probe = cp_probe,
};
module_hid_driver(cp_driver);
static int __init cp_init(void)
{
return hid_register_driver(&cp_driver);
}
static void __exit cp_exit(void)
{
hid_unregister_driver(&cp_driver);
}
module_init(cp_init);
module_exit(cp_exit);
MODULE_LICENSE("GPL");
......@@ -297,17 +297,6 @@ static struct hid_driver dr_driver = {
.report_fixup = dr_report_fixup,
.probe = dr_probe,
};
module_hid_driver(dr_driver);
static int __init dr_init(void)
{
return hid_register_driver(&dr_driver);
}
static void __exit dr_exit(void)
{
hid_unregister_driver(&dr_driver);
}
module_init(dr_init);
module_exit(dr_exit);
MODULE_LICENSE("GPL");
......@@ -41,17 +41,6 @@ static struct hid_driver elecom_driver = {
.id_table = elecom_devices,
.report_fixup = elecom_report_fixup
};
module_hid_driver(elecom_driver);
static int __init elecom_init(void)
{
return hid_register_driver(&elecom_driver);
}
static void __exit elecom_exit(void)
{
hid_unregister_driver(&elecom_driver);
}
module_init(elecom_init);
module_exit(elecom_exit);
MODULE_LICENSE("GPL");
......@@ -150,18 +150,7 @@ static struct hid_driver ems_driver = {
.id_table = ems_devices,
.probe = ems_probe,
};
module_hid_driver(ems_driver);
static int ems_init(void)
{
return hid_register_driver(&ems_driver);
}
static void ems_exit(void)
{
hid_unregister_driver(&ems_driver);
}
module_init(ems_init);
module_exit(ems_exit);
MODULE_LICENSE("GPL");
......@@ -76,17 +76,6 @@ static struct hid_driver ez_driver = {
.input_mapping = ez_input_mapping,
.event = ez_event,
};
module_hid_driver(ez_driver);
static int __init ez_init(void)
{
return hid_register_driver(&ez_driver);
}
static void __exit ez_exit(void)
{
hid_unregister_driver(&ez_driver);
}
module_init(ez_init);
module_exit(ez_exit);
MODULE_LICENSE("GPL");
......@@ -176,17 +176,6 @@ static struct hid_driver ga_driver = {
.id_table = ga_devices,
.probe = ga_probe,
};
module_hid_driver(ga_driver);
static int __init ga_init(void)
{
return hid_register_driver(&ga_driver);
}
static void __exit ga_exit(void)
{
hid_unregister_driver(&ga_driver);
}
module_init(ga_init);
module_exit(ga_exit);
MODULE_LICENSE("GPL");
......@@ -34,19 +34,7 @@ static struct hid_driver hid_generic = {
.name = "hid-generic",
.id_table = hid_table,
};
static int __init hid_init(void)
{
return hid_register_driver(&hid_generic);
}
static void __exit hid_exit(void)
{
hid_unregister_driver(&hid_generic);
}
module_init(hid_init);
module_exit(hid_exit);
module_hid_driver(hid_generic);
MODULE_AUTHOR("Henrik Rydberg");
MODULE_DESCRIPTION("HID generic driver");
......
......@@ -88,17 +88,6 @@ static struct hid_driver gyration_driver = {
.input_mapping = gyration_input_mapping,
.event = gyration_event,
};
module_hid_driver(gyration_driver);
static int __init gyration_init(void)
{
return hid_register_driver(&gyration_driver);
}
static void __exit gyration_exit(void)
{
hid_unregister_driver(&gyration_driver);
}
module_init(gyration_init);
module_exit(gyration_exit);
MODULE_LICENSE("GPL");
......@@ -167,17 +167,6 @@ static struct hid_driver holtek_kbd_driver = {
.report_fixup = holtek_kbd_report_fixup,
.probe = holtek_kbd_probe
};
module_hid_driver(holtek_kbd_driver);
static int __init holtek_kbd_init(void)
{
return hid_register_driver(&holtek_kbd_driver);
}
static void __exit holtek_kbd_exit(void)
{
hid_unregister_driver(&holtek_kbd_driver);
}
module_exit(holtek_kbd_exit);
module_init(holtek_kbd_init);
MODULE_LICENSE("GPL");
......@@ -224,17 +224,4 @@ static struct hid_driver holtek_driver = {
.id_table = holtek_devices,
.probe = holtek_probe,
};
static int __init holtek_init(void)
{
return hid_register_driver(&holtek_driver);
}
static void __exit holtek_exit(void)
{
hid_unregister_driver(&holtek_driver);
}
module_init(holtek_init);
module_exit(holtek_exit);
module_hid_driver(holtek_driver);
......@@ -235,25 +235,8 @@ static struct hid_driver icade_driver = {
.input_mapped = icade_input_mapped,
.input_mapping = icade_input_mapping,
};
module_hid_driver(icade_driver);
static int __init icade_init(void)
{
int ret;
ret = hid_register_driver(&icade_driver);
if (ret)
pr_err("can't register icade driver\n");
return ret;
}
static void __exit icade_exit(void)
{
hid_unregister_driver(&icade_driver);
}
module_init(icade_init);
module_exit(icade_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
MODULE_DESCRIPTION("ION iCade input driver");
......@@ -445,6 +445,9 @@
#define USB_VENDOR_ID_JESS 0x0c45
#define USB_DEVICE_ID_JESS_YUREX 0x1010
#define USB_VENDOR_ID_JESS2 0x0f30
#define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
......@@ -525,8 +528,8 @@
#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283
#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286
#define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287
#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298
#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
......@@ -597,6 +600,9 @@
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
#define USB_VENDOR_ID_NEXIO 0x1870
#define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d
#define USB_VENDOR_ID_NEXTWINDOW 0x1926
#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
......@@ -709,6 +715,7 @@
#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
......@@ -726,6 +733,9 @@
#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403
#define USB_DEVICE_ID_MTP_SITRONIX 0x5001
#define USB_VENDOR_ID_STEELSERIES 0x1038
#define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410
#define USB_VENDOR_ID_SUN 0x0430
#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
......@@ -747,6 +757,9 @@
#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010
#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013
#define USB_VENDOR_ID_THINGM 0x27b8
#define USB_DEVICE_ID_BLINK1 0x01ed
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
#define USB_VENDOR_ID_TIVO 0x150a
......@@ -794,6 +807,12 @@
#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19
#define USB_VENDOR_ID_VELLEMAN 0x10cf
#define USB_DEVICE_ID_VELLEMAN_K8055_FIRST 0x5500
#define USB_DEVICE_ID_VELLEMAN_K8055_LAST 0x5503
#define USB_DEVICE_ID_VELLEMAN_K8061_FIRST 0x8061
#define USB_DEVICE_ID_VELLEMAN_K8061_LAST 0x8068
#define USB_VENDOR_ID_VERNIER 0x08f7
#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
......
......@@ -47,17 +47,6 @@ static struct hid_driver ks_driver = {
.id_table = ks_devices,
.input_mapping = ks_input_mapping,
};
module_hid_driver(ks_driver);
static int __init ks_init(void)
{
return hid_register_driver(&ks_driver);
}
static void __exit ks_exit(void)
{
hid_unregister_driver(&ks_driver);
}
module_init(ks_init);
module_exit(ks_exit);
MODULE_LICENSE("GPL");
......@@ -49,18 +49,7 @@ static struct hid_driver keytouch_driver = {
.id_table = keytouch_devices,
.report_fixup = keytouch_report_fixup,
};
module_hid_driver(keytouch_driver);
static int __init keytouch_init(void)
{
return hid_register_driver(&keytouch_driver);
}
static void __exit keytouch_exit(void)
{
hid_unregister_driver(&keytouch_driver);
}
module_init(keytouch_init);
module_exit(keytouch_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiri Kosina");
......@@ -419,17 +419,6 @@ static struct hid_driver kye_driver = {
.probe = kye_probe,
.report_fixup = kye_report_fixup,
};
module_hid_driver(kye_driver);
static int __init kye_init(void)
{
return hid_register_driver(&kye_driver);
}
static void __exit kye_exit(void)
{
hid_unregister_driver(&kye_driver);
}
module_init(kye_init);
module_exit(kye_exit);
MODULE_LICENSE("GPL");
......@@ -54,17 +54,6 @@ static struct hid_driver ts_driver = {
.id_table = ts_devices,
.input_mapping = ts_input_mapping,
};
module_hid_driver(ts_driver);
static int __init ts_init(void)
{
return hid_register_driver(&ts_driver);
}
static void __exit ts_exit(void)
{
hid_unregister_driver(&ts_driver);
}
module_init(ts_init);
module_exit(ts_exit);
MODULE_LICENSE("GPL");
......@@ -468,18 +468,6 @@ static struct hid_driver tpkbd_driver = {
.probe = tpkbd_probe,
.remove = tpkbd_remove,
};
static int __init tpkbd_init(void)
{
return hid_register_driver(&tpkbd_driver);
}
static void __exit tpkbd_exit(void)
{
hid_unregister_driver(&tpkbd_driver);
}
module_init(tpkbd_init);
module_exit(tpkbd_exit);
module_hid_driver(tpkbd_driver);
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -43,11 +43,6 @@
#define G27_REV_MAJ 0x12
#define G27_REV_MIN 0x38
#define DFP_X_MIN 0
#define DFP_X_MAX 16383
#define DFP_PEDAL_MIN 0
#define DFP_PEDAL_MAX 255
#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev)
static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
......@@ -598,18 +593,6 @@ int lg4ff_init(struct hid_device *hid)
return error;
dbg_hid("sysfs interface created\n");
/* Set default axes parameters */
switch (lg4ff_devices[i].product_id) {
case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
dbg_hid("Setting axes parameters for Driving Force Pro\n");
input_set_abs_params(dev, ABS_X, DFP_X_MIN, DFP_X_MAX, 0, 0);
input_set_abs_params(dev, ABS_Y, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0);
input_set_abs_params(dev, ABS_RZ, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0);
break;
default:
break;
}
/* Set the maximum range to start with */
entry->range = entry->max_range;
if (entry->set_range != NULL)
......
......@@ -569,23 +569,6 @@ static struct hid_driver magicmouse_driver = {
.raw_event = magicmouse_raw_event,
.input_mapping = magicmouse_input_mapping,
};
module_hid_driver(magicmouse_driver);
static int __init magicmouse_init(void)
{
int ret;
ret = hid_register_driver(&magicmouse_driver);
if (ret)
pr_err("can't register magicmouse driver\n");
return ret;
}
static void __exit magicmouse_exit(void)
{
hid_unregister_driver(&magicmouse_driver);
}
module_init(magicmouse_init);
module_exit(magicmouse_exit);
MODULE_LICENSE("GPL");
......@@ -221,17 +221,6 @@ static struct hid_driver ms_driver = {
.event = ms_event,
.probe = ms_probe,
};
module_hid_driver(ms_driver);
static int __init ms_init(void)
{
return hid_register_driver(&ms_driver);
}
static void __exit ms_exit(void)
{
hid_unregister_driver(&ms_driver);
}
module_init(ms_init);
module_exit(ms_exit);
MODULE_LICENSE("GPL");
......@@ -63,17 +63,6 @@ static struct hid_driver mr_driver = {
.report_fixup = mr_report_fixup,
.input_mapping = mr_input_mapping,
};
module_hid_driver(mr_driver);
static int __init mr_init(void)
{
return hid_register_driver(&mr_driver);
}
static void __exit mr_exit(void)
{
hid_unregister_driver(&mr_driver);
}
module_init(mr_init);
module_exit(mr_exit);
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -858,12 +858,43 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
return 1;
}
static void ntrig_input_configured(struct hid_device *hid,
struct hid_input *hidinput)
{
struct input_dev *input = hidinput->input;
if (hidinput->report->maxfield < 1)
return;
switch (hidinput->report->field[0]->application) {
case HID_DG_PEN:
input->name = "N-Trig Pen";
break;
case HID_DG_TOUCHSCREEN:
/* These keys are redundant for fingers, clear them
* to prevent incorrect identification */
__clear_bit(BTN_TOOL_PEN, input->keybit);
__clear_bit(BTN_TOOL_FINGER, input->keybit);
__clear_bit(BTN_0, input->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
/*
* The physical touchscreen (single touch)
* input has a value for physical, whereas
* the multitouch only has logical input
* fields.
*/
input->name = (hidinput->report->field[0]->physical) ?
"N-Trig Touchscreen" :
"N-Trig MultiTouch";
break;
}
}
static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
struct ntrig_data *nd;
struct hid_input *hidinput;
struct input_dev *input;
struct hid_report *report;
if (id->driver_data)
......@@ -901,38 +932,6 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free;
}
list_for_each_entry(hidinput, &hdev->inputs, list) {
if (hidinput->report->maxfield < 1)
continue;
input = hidinput->input;
switch (hidinput->report->field[0]->application) {
case HID_DG_PEN:
input->name = "N-Trig Pen";
break;
case HID_DG_TOUCHSCREEN:
/* These keys are redundant for fingers, clear them
* to prevent incorrect identification */
__clear_bit(BTN_TOOL_PEN, input->keybit);
__clear_bit(BTN_TOOL_FINGER, input->keybit);
__clear_bit(BTN_0, input->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
/*
* The physical touchscreen (single touch)
* input has a value for physical, whereas
* the multitouch only has logical input
* fields.
*/
input->name =
(hidinput->report->field[0]
->physical) ?
"N-Trig Touchscreen" :
"N-Trig MultiTouch";
break;
}
}
/* This is needed for devices with more recent firmware versions */
report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
if (report) {
......@@ -1023,20 +1022,10 @@ static struct hid_driver ntrig_driver = {
.remove = ntrig_remove,
.input_mapping = ntrig_input_mapping,
.input_mapped = ntrig_input_mapped,
.input_configured = ntrig_input_configured,
.usage_table = ntrig_grabbed_usages,
.event = ntrig_event,
};
module_hid_driver(ntrig_driver);
static int __init ntrig_init(void)
{
return hid_register_driver(&ntrig_driver);
}
static void __exit ntrig_exit(void)
{
hid_unregister_driver(&ntrig_driver);
}
module_init(ntrig_init);
module_exit(ntrig_exit);
MODULE_LICENSE("GPL");
......@@ -50,17 +50,6 @@ static struct hid_driver ortek_driver = {
.id_table = ortek_devices,
.report_fixup = ortek_report_fixup
};
module_hid_driver(ortek_driver);
static int __init ortek_init(void)
{
return hid_register_driver(&ortek_driver);
}
static void __exit ortek_exit(void)
{
hid_unregister_driver(&ortek_driver);
}
module_init(ortek_init);
module_exit(ortek_exit);
MODULE_LICENSE("GPL");
......@@ -103,17 +103,6 @@ static struct hid_driver pl_driver = {
.input_mapping = pl_input_mapping,
.probe = pl_probe,
};
module_hid_driver(pl_driver);
static int __init pl_init(void)
{
return hid_register_driver(&pl_driver);
}
static void __exit pl_exit(void)
{
hid_unregister_driver(&pl_driver);
}
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
......@@ -672,18 +672,7 @@ static struct hid_driver picolcd_driver = {
.reset_resume = picolcd_reset_resume,
#endif
};
module_hid_driver(picolcd_driver);
static int __init picolcd_init(void)
{
return hid_register_driver(&picolcd_driver);
}
static void __exit picolcd_exit(void)
{
hid_unregister_driver(&picolcd_driver);
}
module_init(picolcd_init);
module_exit(picolcd_exit);
MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
MODULE_LICENSE("GPL v2");
......@@ -14,6 +14,8 @@
* 0e8f:0003 "GASIA USB Gamepad"
* - another version of the König gamepad
*
* 0f30:0111 "Saitek Color Rumble Pad"
*
* Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
*/
......@@ -51,6 +53,7 @@
struct plff_device {
struct hid_report *report;
s32 maxval;
s32 *strong;
s32 *weak;
};
......@@ -66,8 +69,8 @@ static int hid_plff_play(struct input_dev *dev, void *data,
right = effect->u.rumble.weak_magnitude;
debug("called with 0x%04x 0x%04x", left, right);
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
left = left * plff->maxval / 0xffff;
right = right * plff->maxval / 0xffff;
*plff->strong = left;
*plff->weak = right;
......@@ -87,6 +90,7 @@ static int plff_init(struct hid_device *hid)
struct list_head *report_ptr = report_list;
struct input_dev *dev;
int error;
s32 maxval;
s32 *strong;
s32 *weak;
......@@ -123,6 +127,7 @@ static int plff_init(struct hid_device *hid)
return -ENODEV;
}
maxval = 0x7f;
if (report->field[0]->report_count >= 4) {
report->field[0]->value[0] = 0x00;
report->field[0]->value[1] = 0x00;
......@@ -135,6 +140,8 @@ static int plff_init(struct hid_device *hid)
report->field[1]->value[0] = 0x00;
strong = &report->field[2]->value[0];
weak = &report->field[3]->value[0];
if (hid->vendor == USB_VENDOR_ID_JESS2)
maxval = 0xff;
debug("detected 4-field device");
} else {
hid_err(hid, "not enough fields or values\n");
......@@ -158,6 +165,7 @@ static int plff_init(struct hid_device *hid)
plff->report = report;
plff->strong = strong;
plff->weak = weak;
plff->maxval = maxval;
*strong = 0x00;
*weak = 0x00;
......@@ -207,6 +215,7 @@ static const struct hid_device_id pl_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
.driver_data = 1 }, /* Twin USB Joystick */
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD), },
{ }
};
MODULE_DEVICE_TABLE(hid, pl_devices);
......@@ -216,17 +225,6 @@ static struct hid_driver pl_driver = {
.id_table = pl_devices,
.probe = pl_probe,
};
module_hid_driver(pl_driver);
static int __init pl_init(void)
{
return hid_register_driver(&pl_driver);
}
static void __exit pl_exit(void)
{
hid_unregister_driver(&pl_driver);
}
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
......@@ -75,18 +75,7 @@ static struct hid_driver px_driver = {
.id_table = px_devices,
.raw_event = px_raw_event,
};
module_hid_driver(px_driver);
static int __init px_init(void)
{
return hid_register_driver(&px_driver);
}
static void __exit px_exit(void)
{
hid_unregister_driver(&px_driver);
}
module_init(px_init);
module_exit(px_exit);
MODULE_AUTHOR("Terry Lambert <tlambert@google.com>");
MODULE_LICENSE("GPL");
......@@ -889,23 +889,6 @@ static struct hid_driver pk_driver = {
.probe = pk_probe,
.remove = pk_remove,
};
module_hid_driver(pk_driver);
static int pk_init(void)
{
int ret;
ret = hid_register_driver(&pk_driver);
if (ret)
pr_err("can't register prodikeys driver\n");
return ret;
}
static void pk_exit(void)
{
hid_unregister_driver(&pk_driver);
}
module_init(pk_init);
module_exit(pk_exit);
MODULE_LICENSE("GPL");
......@@ -198,18 +198,7 @@ static struct hid_driver ps3remote_driver = {
.report_fixup = ps3remote_fixup,
.input_mapping = ps3remote_mapping,
};
module_hid_driver(ps3remote_driver);
static int __init ps3remote_init(void)
{
return hid_register_driver(&ps3remote_driver);
}
static void __exit ps3remote_exit(void)
{
hid_unregister_driver(&ps3remote_driver);
}
module_init(ps3remote_init);
module_exit(ps3remote_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");
......@@ -208,19 +208,7 @@ static struct hid_driver lua_driver = {
.probe = lua_probe,
.remove = lua_remove
};
static int __init lua_init(void)
{
return hid_register_driver(&lua_driver);
}
static void __exit lua_exit(void)
{
hid_unregister_driver(&lua_driver);
}
module_init(lua_init);
module_exit(lua_exit);
module_hid_driver(lua_driver);
MODULE_AUTHOR("Stefan Achatz");
MODULE_DESCRIPTION("USB Roccat Lua driver");
......
......@@ -54,17 +54,6 @@ static struct hid_driver saitek_driver = {
.id_table = saitek_devices,
.report_fixup = saitek_report_fixup
};
module_hid_driver(saitek_driver);
static int __init saitek_init(void)
{
return hid_register_driver(&saitek_driver);
}
static void __exit saitek_exit(void)
{
hid_unregister_driver(&saitek_driver);
}
module_init(saitek_init);
module_exit(saitek_exit);
MODULE_LICENSE("GPL");
......@@ -196,17 +196,6 @@ static struct hid_driver samsung_driver = {
.input_mapping = samsung_input_mapping,
.probe = samsung_probe,
};
module_hid_driver(samsung_driver);
static int __init samsung_init(void)
{
return hid_register_driver(&samsung_driver);
}
static void __exit samsung_exit(void)
{
hid_unregister_driver(&samsung_driver);
}
module_init(samsung_init);
module_exit(samsung_exit);
MODULE_LICENSE("GPL");
......@@ -605,16 +605,12 @@ static void sensor_hub_remove(struct hid_device *hdev)
}
static const struct hid_device_id sensor_hub_devices[] = {
{ HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) },
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
HID_ANY_ID) },
{ }
};
MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
static const struct hid_usage_id sensor_hub_grabbed_usages[] = {
{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
};
static struct hid_driver sensor_hub_driver = {
.name = "hid-sensor-hub",
.id_table = sensor_hub_devices,
......@@ -627,19 +623,7 @@ static struct hid_driver sensor_hub_driver = {
.reset_resume = sensor_hub_reset_resume,
#endif
};
static int __init sensor_hub_init(void)
{
return hid_register_driver(&sensor_hub_driver);
}
static void __exit sensor_hub_exit(void)
{
hid_unregister_driver(&sensor_hub_driver);
}
module_init(sensor_hub_init);
module_exit(sensor_hub_exit);
module_hid_driver(sensor_hub_driver);
MODULE_DESCRIPTION("HID Sensor Hub driver");
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
......
......@@ -177,19 +177,8 @@ static struct hid_driver sjoy_driver = {
.id_table = sjoy_devices,
.probe = sjoy_probe,
};
module_hid_driver(sjoy_driver);
static int __init sjoy_init(void)
{
return hid_register_driver(&sjoy_driver);
}
static void __exit sjoy_exit(void)
{
hid_unregister_driver(&sjoy_driver);
}
module_init(sjoy_init);
module_exit(sjoy_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jussi Kivilinna");
......@@ -33,6 +33,28 @@ static const u8 sixaxis_rdesc_fixup[] = {
0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
};
static const u8 sixaxis_rdesc_fixup2[] = {
0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
0xb1, 0x02, 0xc0, 0xc0,
};
struct sony_sc {
unsigned long quirks;
};
......@@ -43,9 +65,19 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
{
struct sony_sc *sc = hid_get_drvdata(hdev);
if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
*rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
/*
* Some Sony RF receivers wrongly declare the mouse pointer as a
* a constant non-data variable.
*/
if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
/* usage page: generic desktop controls */
/* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
/* usage: mouse */
rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
/* input (usage page for x,y axes): constant, variable, relative */
rdesc[54] == 0x81 && rdesc[55] == 0x07) {
hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
/* input: data, variable, relative */
rdesc[55] = 0x06;
}
......@@ -56,6 +88,12 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
sizeof(sixaxis_rdesc_fixup));
} else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
*rsize > sizeof(sixaxis_rdesc_fixup2)) {
hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
*rsize, (int)sizeof(sixaxis_rdesc_fixup2));
*rsize = sizeof(sixaxis_rdesc_fixup2);
memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
}
return rdesc;
}
......@@ -217,6 +255,8 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = SIXAXIS_CONTROLLER_BT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
{ }
};
MODULE_DEVICE_TABLE(hid, sony_devices);
......@@ -229,17 +269,6 @@ static struct hid_driver sony_driver = {
.report_fixup = sony_report_fixup,
.raw_event = sony_raw_event
};
module_hid_driver(sony_driver);
static int __init sony_init(void)
{
return hid_register_driver(&sony_driver);
}
static void __exit sony_exit(void)
{
hid_unregister_driver(&sony_driver);
}
module_init(sony_init);
module_exit(sony_exit);
MODULE_LICENSE("GPL");
......@@ -73,17 +73,6 @@ static struct hid_driver speedlink_driver = {
.input_mapping = speedlink_input_mapping,
.event = speedlink_event,
};
module_hid_driver(speedlink_driver);
static int __init speedlink_init(void)
{
return hid_register_driver(&speedlink_driver);
}
static void __exit speedlink_exit(void)
{
hid_unregister_driver(&speedlink_driver);
}
module_init(speedlink_init);
module_exit(speedlink_exit);
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -63,17 +63,6 @@ static struct hid_driver sp_driver = {
.report_fixup = sp_report_fixup,
.input_mapping = sp_input_mapping,
};
module_hid_driver(sp_driver);
static int __init sp_init(void)
{
return hid_register_driver(&sp_driver);
}
static void __exit sp_exit(void)
{
hid_unregister_driver(&sp_driver);
}
module_init(sp_init);
module_exit(sp_exit);
MODULE_LICENSE("GPL");
/*
* ThingM blink(1) USB RGB LED driver
*
* Copyright 2013 Savoir-faire Linux Inc.
* Vivien Didelot <vivien.didelot@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*/
#include <linux/hid.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "hid-ids.h"
#define BLINK1_CMD_SIZE 9
#define blink1_rgb_to_r(rgb) ((rgb & 0xFF0000) >> 16)
#define blink1_rgb_to_g(rgb) ((rgb & 0x00FF00) >> 8)
#define blink1_rgb_to_b(rgb) ((rgb & 0x0000FF) >> 0)
/**
* struct blink1_data - blink(1) device specific data
* @hdev: HID device.
* @led_cdev: LED class instance.
* @rgb: 8-bit per channel RGB notation.
* @fade: fade time in hundredths of a second.
* @brightness: brightness coefficient.
* @play: play/pause in-memory patterns.
*/
struct blink1_data {
struct hid_device *hdev;
struct led_classdev led_cdev;
u32 rgb;
u16 fade;
u8 brightness;
bool play;
};
static int blink1_send_command(struct blink1_data *data,
u8 buf[BLINK1_CMD_SIZE])
{
int ret;
hid_dbg(data->hdev, "command: %d%c%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
buf[0], buf[1], buf[2], buf[3], buf[4],
buf[5], buf[6], buf[7], buf[8]);
ret = data->hdev->hid_output_raw_report(data->hdev, buf,
BLINK1_CMD_SIZE, HID_FEATURE_REPORT);
return ret < 0 ? ret : 0;
}
static int blink1_update_color(struct blink1_data *data)
{
u8 buf[BLINK1_CMD_SIZE] = { 1, 'n', 0, 0, 0, 0, 0, 0, 0 };
if (data->brightness) {
unsigned int coef = DIV_ROUND_CLOSEST(255, data->brightness);
buf[2] = DIV_ROUND_CLOSEST(blink1_rgb_to_r(data->rgb), coef);
buf[3] = DIV_ROUND_CLOSEST(blink1_rgb_to_g(data->rgb), coef);
buf[4] = DIV_ROUND_CLOSEST(blink1_rgb_to_b(data->rgb), coef);
}
if (data->fade) {
buf[1] = 'c';
buf[5] = (data->fade & 0xFF00) >> 8;
buf[6] = (data->fade & 0x00FF);
}
return blink1_send_command(data, buf);
}
static void blink1_led_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent);
data->brightness = brightness;
if (blink1_update_color(data))
hid_err(data->hdev, "failed to update color\n");
}
static enum led_brightness blink1_led_get(struct led_classdev *led_cdev)
{
struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent);
return data->brightness;
}
static ssize_t blink1_show_rgb(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
return sprintf(buf, "%.6X\n", data->rgb);
}
static ssize_t blink1_store_rgb(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
long unsigned int rgb;
int ret;
ret = kstrtoul(buf, 16, &rgb);
if (ret)
return ret;
/* RGB triplet notation is 24-bit hexadecimal */
if (rgb > 0xFFFFFF)
return -EINVAL;
data->rgb = rgb;
ret = blink1_update_color(data);
return ret ? ret : count;
}
static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR, blink1_show_rgb, blink1_store_rgb);
static ssize_t blink1_show_fade(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
return sprintf(buf, "%d\n", data->fade * 10);
}
static ssize_t blink1_store_fade(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
long unsigned int fade;
int ret;
ret = kstrtoul(buf, 10, &fade);
if (ret)
return ret;
/* blink(1) accepts 16-bit fade time, number of 10ms ticks */
fade = DIV_ROUND_CLOSEST(fade, 10);
if (fade > 65535)
return -EINVAL;
data->fade = fade;
return count;
}
static DEVICE_ATTR(fade, S_IRUGO | S_IWUSR,
blink1_show_fade, blink1_store_fade);
static ssize_t blink1_show_play(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
return sprintf(buf, "%d\n", data->play);
}
static ssize_t blink1_store_play(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct blink1_data *data = dev_get_drvdata(dev->parent);
u8 cmd[BLINK1_CMD_SIZE] = { 1, 'p', 0, 0, 0, 0, 0, 0, 0 };
long unsigned int play;
int ret;
ret = kstrtoul(buf, 10, &play);
if (ret)
return ret;
data->play = !!play;
cmd[2] = data->play;
ret = blink1_send_command(data, cmd);
return ret ? ret : count;
}
static DEVICE_ATTR(play, S_IRUGO | S_IWUSR,
blink1_show_play, blink1_store_play);
static const struct attribute_group blink1_sysfs_group = {
.attrs = (struct attribute *[]) {
&dev_attr_rgb.attr,
&dev_attr_fade.attr,
&dev_attr_play.attr,
NULL
},
};
static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
struct blink1_data *data;
struct led_classdev *led;
char led_name[13];
int ret;
data = devm_kzalloc(&hdev->dev, sizeof(struct blink1_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
hid_set_drvdata(hdev, data);
data->hdev = hdev;
data->rgb = 0xFFFFFF; /* set a default white color */
ret = hid_parse(hdev);
if (ret)
goto error;
ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
if (ret)
goto error;
/* blink(1) serial numbers range is 0x1A001000 to 0x1A002FFF */
led = &data->led_cdev;
snprintf(led_name, sizeof(led_name), "blink1::%s", hdev->uniq + 4);
led->name = led_name;
led->brightness_set = blink1_led_set;
led->brightness_get = blink1_led_get;
ret = led_classdev_register(&hdev->dev, led);
if (ret)
goto stop;
ret = sysfs_create_group(&led->dev->kobj, &blink1_sysfs_group);
if (ret)
goto remove_led;
return 0;
remove_led:
led_classdev_unregister(led);
stop:
hid_hw_stop(hdev);
error:
return ret;
}
static void thingm_remove(struct hid_device *hdev)
{
struct blink1_data *data = hid_get_drvdata(hdev);
struct led_classdev *led = &data->led_cdev;
sysfs_remove_group(&led->dev->kobj, &blink1_sysfs_group);
led_classdev_unregister(led);
hid_hw_stop(hdev);
}
static const struct hid_device_id thingm_table[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
{ }
};
MODULE_DEVICE_TABLE(hid, thingm_table);
static struct hid_driver thingm_driver = {
.name = "thingm",
.probe = thingm_probe,
.remove = thingm_remove,
.id_table = thingm_table,
};
module_hid_driver(thingm_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>");
MODULE_DESCRIPTION("ThingM blink(1) USB RGB LED driver");
......@@ -73,18 +73,7 @@ static struct hid_driver tivo_driver = {
.id_table = tivo_devices,
.input_mapping = tivo_input_mapping,
};
module_hid_driver(tivo_driver);
static int __init tivo_init(void)
{
return hid_register_driver(&tivo_driver);
}
static void __exit tivo_exit(void)
{
hid_unregister_driver(&tivo_driver);
}
module_init(tivo_init);
module_exit(tivo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
......@@ -261,17 +261,6 @@ static struct hid_driver tm_driver = {
.id_table = tm_devices,
.probe = tm_probe,
};
module_hid_driver(tm_driver);
static int __init tm_init(void)
{
return hid_register_driver(&tm_driver);
}
static void __exit tm_exit(void)
{
hid_unregister_driver(&tm_driver);
}
module_init(tm_init);
module_exit(tm_exit);
MODULE_LICENSE("GPL");
......@@ -76,17 +76,6 @@ static struct hid_driver ts_driver = {
.id_table = ts_devices,
.input_mapping = ts_input_mapping,
};
module_hid_driver(ts_driver);
static int __init ts_init(void)
{
return hid_register_driver(&ts_driver);
}
static void __exit ts_exit(void)
{
hid_unregister_driver(&ts_driver);
}
module_init(ts_init);
module_exit(ts_exit);
MODULE_LICENSE("GPL");
......@@ -131,17 +131,6 @@ static struct hid_driver twinhan_driver = {
.id_table = twinhan_devices,
.input_mapping = twinhan_input_mapping,
};
module_hid_driver(twinhan_driver);
static int __init twinhan_init(void)
{
return hid_register_driver(&twinhan_driver);
}
static void __exit twinhan_exit(void)
{
hid_unregister_driver(&twinhan_driver);
}
module_init(twinhan_init);
module_exit(twinhan_exit);
MODULE_LICENSE("GPL");
......@@ -650,17 +650,6 @@ static struct hid_driver uclogic_driver = {
.id_table = uclogic_devices,
.report_fixup = uclogic_report_fixup,
};
module_hid_driver(uclogic_driver);
static int __init uclogic_init(void)
{
return hid_register_driver(&uclogic_driver);
}
static void __exit uclogic_exit(void)
{
hid_unregister_driver(&uclogic_driver);
}
module_init(uclogic_init);
module_exit(uclogic_exit);
MODULE_LICENSE("GPL");
......@@ -953,23 +953,7 @@ static struct hid_driver wacom_driver = {
.raw_event = wacom_raw_event,
.input_mapped = wacom_input_mapped,
};
module_hid_driver(wacom_driver);
static int __init wacom_init(void)
{
int ret;
ret = hid_register_driver(&wacom_driver);
if (ret)
pr_err("can't register wacom driver\n");
return ret;
}
static void __exit wacom_exit(void)
{
hid_unregister_driver(&wacom_driver);
}
module_init(wacom_init);
module_exit(wacom_exit);
MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
MODULE_LICENSE("GPL");
......@@ -779,17 +779,6 @@ static struct hid_driver waltop_driver = {
.report_fixup = waltop_report_fixup,
.raw_event = waltop_raw_event,
};
module_hid_driver(waltop_driver);
static int __init waltop_init(void)
{
return hid_register_driver(&waltop_driver);
}
static void __exit waltop_exit(void)
{
hid_unregister_driver(&waltop_driver);
}
module_init(waltop_init);
module_exit(waltop_exit);
MODULE_LICENSE("GPL");
......@@ -1294,25 +1294,8 @@ static struct hid_driver wiimote_hid_driver = {
.remove = wiimote_hid_remove,
.raw_event = wiimote_hid_event,
};
module_hid_driver(wiimote_hid_driver);
static int __init wiimote_init(void)
{
int ret;
ret = hid_register_driver(&wiimote_hid_driver);
if (ret)
pr_err("Can't register wiimote hid driver\n");
return ret;
}
static void __exit wiimote_exit(void)
{
hid_unregister_driver(&wiimote_hid_driver);
}
module_init(wiimote_init);
module_exit(wiimote_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
......@@ -31,7 +31,7 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
unsigned long flags;
ssize_t ret;
char buf[16];
__u16 size;
__u16 size = 0;
if (s == 0)
return -EINVAL;
......
......@@ -403,14 +403,14 @@ static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
if (ext->motionp) {
input_report_key(ext->input,
wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04));
wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04));
input_report_key(ext->input,
wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08));
wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08));
} else {
input_report_key(ext->input,
wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01));
wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01));
input_report_key(ext->input,
wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02));
wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02));
}
input_sync(ext->input);
......
......@@ -152,17 +152,6 @@ static struct hid_driver zp_driver = {
.id_table = zp_devices,
.probe = zp_probe,
};
module_hid_driver(zp_driver);
static int __init zp_init(void)
{
return hid_register_driver(&zp_driver);
}
static void __exit zp_exit(void)
{
hid_unregister_driver(&zp_driver);
}
module_init(zp_init);
module_exit(zp_exit);
MODULE_LICENSE("GPL");
......@@ -219,17 +219,6 @@ static struct hid_driver zc_driver = {
.probe = zc_probe,
.remove = zc_remove,
};
module_hid_driver(zc_driver);
static int __init zc_init(void)
{
return hid_register_driver(&zc_driver);
}
static void __exit zc_exit(void)
{
hid_unregister_driver(&zc_driver);
}
module_init(zc_init);
module_exit(zc_exit);
MODULE_LICENSE("GPL");
......@@ -581,6 +581,7 @@ int __init hidraw_init(void)
if (result < 0)
goto error_class;
printk(KERN_INFO "hidraw: raw HID events driver (C) Jiri Kosina\n");
out:
return result;
......
......@@ -34,6 +34,7 @@
#include <linux/kernel.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <linux/i2c/i2c-hid.h>
......@@ -139,6 +140,8 @@ struct i2c_hid {
unsigned long flags; /* device flags */
wait_queue_head_t wait; /* For waiting the interrupt */
struct i2c_hid_platform_data pdata;
};
static int __i2c_hid_command(struct i2c_client *client,
......@@ -821,6 +824,70 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
return 0;
}
#ifdef CONFIG_ACPI
static int i2c_hid_acpi_pdata(struct i2c_client *client,
struct i2c_hid_platform_data *pdata)
{
static u8 i2c_hid_guid[] = {
0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
};
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object params[4], *obj;
struct acpi_object_list input;
struct acpi_device *adev;
acpi_handle handle;
handle = ACPI_HANDLE(&client->dev);
if (!handle || acpi_bus_get_device(handle, &adev))
return -ENODEV;
input.count = ARRAY_SIZE(params);
input.pointer = params;
params[0].type = ACPI_TYPE_BUFFER;
params[0].buffer.length = sizeof(i2c_hid_guid);
params[0].buffer.pointer = i2c_hid_guid;
params[1].type = ACPI_TYPE_INTEGER;
params[1].integer.value = 1;
params[2].type = ACPI_TYPE_INTEGER;
params[2].integer.value = 1; /* HID function */
params[3].type = ACPI_TYPE_INTEGER;
params[3].integer.value = 0;
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) {
dev_err(&client->dev, "device _DSM execution failed\n");
return -ENODEV;
}
obj = (union acpi_object *)buf.pointer;
if (obj->type != ACPI_TYPE_INTEGER) {
dev_err(&client->dev, "device _DSM returned invalid type: %d\n",
obj->type);
kfree(buf.pointer);
return -EINVAL;
}
pdata->hid_descriptor_address = obj->integer.value;
kfree(buf.pointer);
return 0;
}
static const struct acpi_device_id i2c_hid_acpi_match[] = {
{"ACPI0C50", 0 },
{"PNP0C50", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
#else
static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
struct i2c_hid_platform_data *pdata)
{
return -ENODEV;
}
#endif
static int i2c_hid_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
......@@ -832,11 +899,6 @@ static int i2c_hid_probe(struct i2c_client *client,
dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
if (!platform_data) {
dev_err(&client->dev, "HID register address not provided\n");
return -EINVAL;
}
if (!client->irq) {
dev_err(&client->dev,
"HID over i2c has not been provided an Int IRQ\n");
......@@ -847,11 +909,22 @@ static int i2c_hid_probe(struct i2c_client *client,
if (!ihid)
return -ENOMEM;
if (!platform_data) {
ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
if (ret) {
dev_err(&client->dev,
"HID register address not provided\n");
goto err;
}
} else {
ihid->pdata = *platform_data;
}
i2c_set_clientdata(client, ihid);
ihid->client = client;
hidRegister = platform_data->hid_descriptor_address;
hidRegister = ihid->pdata.hid_descriptor_address;
ihid->wHIDDescRegister = cpu_to_le16(hidRegister);
init_waitqueue_head(&ihid->wait);
......@@ -884,6 +957,7 @@ static int i2c_hid_probe(struct i2c_client *client,
hid->hid_get_raw_report = i2c_hid_get_raw_report;
hid->hid_output_raw_report = i2c_hid_output_raw_report;
hid->dev.parent = &client->dev;
ACPI_HANDLE_SET(&hid->dev, ACPI_HANDLE(&client->dev));
hid->bus = BUS_I2C;
hid->version = le16_to_cpu(ihid->hdesc.bcdVersion);
hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID);
......@@ -975,6 +1049,7 @@ static struct i2c_driver i2c_hid_driver = {
.name = "i2c_hid",
.owner = THIS_MODULE,
.pm = &i2c_hid_pm,
.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
},
.probe = i2c_hid_probe,
......
......@@ -11,6 +11,7 @@
*/
#include <linux/atomic.h>
#include <linux/compat.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/hid.h>
......@@ -276,6 +277,94 @@ static struct hid_ll_driver uhid_hid_driver = {
.parse = uhid_hid_parse,
};
#ifdef CONFIG_COMPAT
/* Apparently we haven't stepped on these rakes enough times yet. */
struct uhid_create_req_compat {
__u8 name[128];
__u8 phys[64];
__u8 uniq[64];
compat_uptr_t rd_data;
__u16 rd_size;
__u16 bus;
__u32 vendor;
__u32 product;
__u32 version;
__u32 country;
} __attribute__((__packed__));
static int uhid_event_from_user(const char __user *buffer, size_t len,
struct uhid_event *event)
{
if (is_compat_task()) {
u32 type;
if (get_user(type, buffer))
return -EFAULT;
if (type == UHID_CREATE) {
/*
* This is our messed up request with compat pointer.
* It is largish (more than 256 bytes) so we better
* allocate it from the heap.
*/
struct uhid_create_req_compat *compat;
compat = kmalloc(sizeof(*compat), GFP_KERNEL);
if (!compat)
return -ENOMEM;
buffer += sizeof(type);
len -= sizeof(type);
if (copy_from_user(compat, buffer,
min(len, sizeof(*compat)))) {
kfree(compat);
return -EFAULT;
}
/* Shuffle the data over to proper structure */
event->type = type;
memcpy(event->u.create.name, compat->name,
sizeof(compat->name));
memcpy(event->u.create.phys, compat->phys,
sizeof(compat->phys));
memcpy(event->u.create.uniq, compat->uniq,
sizeof(compat->uniq));
event->u.create.rd_data = compat_ptr(compat->rd_data);
event->u.create.rd_size = compat->rd_size;
event->u.create.bus = compat->bus;
event->u.create.vendor = compat->vendor;
event->u.create.product = compat->product;
event->u.create.version = compat->version;
event->u.create.country = compat->country;
kfree(compat);
return 0;
}
/* All others can be copied directly */
}
if (copy_from_user(event, buffer, min(len, sizeof(*event))))
return -EFAULT;
return 0;
}
#else
static int uhid_event_from_user(const char __user *buffer, size_t len,
struct uhid_event *event)
{
if (copy_from_user(event, buffer, min(len, sizeof(*event))))
return -EFAULT;
return 0;
}
#endif
static int uhid_dev_create(struct uhid_device *uhid,
const struct uhid_event *ev)
{
......@@ -498,10 +587,10 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
len = min(count, sizeof(uhid->input_buf));
if (copy_from_user(&uhid->input_buf, buffer, len)) {
ret = -EFAULT;
ret = uhid_event_from_user(buffer, len, &uhid->input_buf);
if (ret)
goto unlock;
}
switch (uhid->input_buf.type) {
case UHID_CREATE:
......
......@@ -589,6 +589,7 @@ struct hid_usage_id {
* @raw_event: if report in report_table, this hook is called (NULL means nop)
* @usage_table: on which events to call event (NULL means all)
* @event: if usage in usage_table, this hook is called (NULL means nop)
* @report: this hook is called after parsing a report (NULL means nop)
* @report_fixup: called before report descriptor parsing (NULL means nop)
* @input_mapping: invoked on input registering before mapping an usage
* @input_mapped: invoked on input registering after mapping an usage
......@@ -627,6 +628,7 @@ struct hid_driver {
const struct hid_usage_id *usage_table;
int (*event)(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value);
void (*report)(struct hid_device *hdev, struct hid_report *report);
__u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf,
unsigned int *size);
......@@ -700,6 +702,18 @@ extern int __must_check __hid_register_driver(struct hid_driver *,
extern void hid_unregister_driver(struct hid_driver *);
/**
* module_hid_driver() - Helper macro for registering a HID driver
* @__hid_driver: hid_driver struct
*
* Helper macro for HID drivers which do not do anything special in module
* init/exit. This eliminates a lot of boilerplate. Each module may only
* use this macro once, and calling it replaces module_init() and module_exit()
*/
#define module_hid_driver(__hid_driver) \
module_driver(__hid_driver, hid_register_driver, \
hid_unregister_driver)
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
extern int hidinput_connect(struct hid_device *hid, unsigned int force);
......@@ -872,9 +886,6 @@ static inline int hid_hw_power(struct hid_device *hdev, int level)
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
int interrupt);
extern int hid_generic_init(void);
extern void hid_generic_exit(void);
/* HID quirks API */
u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
int usbhid_quirks_init(char **quirks_param);
......
......@@ -86,7 +86,7 @@ struct uhid_feature_answer_req {
__u16 err;
__u16 size;
__u8 data[UHID_DATA_MAX];
};
} __attribute__((__packed__));
struct uhid_event {
__u32 type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment