2013-05-21 03:31:08 +04:00
/*
* HID driver for Holtek gaming mice
* Copyright ( c ) 2013 Christian Ohm
* Heavily inspired by various other HID drivers that adjust the report
* descriptor .
*/
/*
* 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 ; either version 2 of the License , or ( at your option )
* any later version .
*/
# include <linux/hid.h>
# include <linux/module.h>
# include <linux/usb.h>
# include "hid-ids.h"
/*
* The report descriptor of some Holtek based gaming mice specifies an
* excessively large number of consumer usages ( 2 ^ 15 ) , which is more than
* HID_MAX_USAGES . This prevents proper parsing of the report descriptor .
*
2013-05-21 03:31:09 +04:00
* This driver fixes the report descriptor for :
* - USB ID 04 d9 : a067 , sold as Sharkoon Drakonia and Perixx MX - 2000
* - USB ID 04 d9 : a04a , sold as Tracer Sniper TRM - 503 , NOVA Gaming Slider X200
* and Zalman ZM - GM1
2013-10-01 21:22:05 +04:00
* - USB ID 04 d9 : a081 , sold as SHARKOON DarkGlider Gaming mouse
2013-10-22 01:42:22 +04:00
* - USB ID 04 d9 : a072 , sold as LEETGION Hellion Gaming Mouse
2014-09-05 19:13:17 +04:00
* - USB ID 04 d9 : a0c2 , sold as ETEKCITY Scroll T - 140 Gaming Mouse
2013-05-21 03:31:08 +04:00
*/
static __u8 * holtek_mouse_report_fixup ( struct hid_device * hdev , __u8 * rdesc ,
unsigned int * rsize )
{
struct usb_interface * intf = to_usb_interface ( hdev - > dev . parent ) ;
if ( intf - > cur_altsetting - > desc . bInterfaceNumber = = 1 ) {
/* Change usage maximum and logical maximum from 0x7fff to
* 0x2fff , so they don ' t exceed HID_MAX_USAGES */
2013-05-21 03:31:09 +04:00
switch ( hdev - > product ) {
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 :
2013-10-22 01:42:22 +04:00
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 :
2014-09-05 19:13:17 +04:00
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 :
2013-05-21 03:31:09 +04:00
if ( * rsize > = 122 & & rdesc [ 115 ] = = 0xff & & rdesc [ 116 ] = = 0x7f
& & rdesc [ 120 ] = = 0xff & & rdesc [ 121 ] = = 0x7f ) {
hid_info ( hdev , " Fixing up report descriptor \n " ) ;
rdesc [ 116 ] = rdesc [ 121 ] = 0x2f ;
}
break ;
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A :
2014-01-14 16:09:09 +04:00
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 :
2013-10-01 21:22:05 +04:00
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 :
2013-05-21 03:31:09 +04:00
if ( * rsize > = 113 & & rdesc [ 106 ] = = 0xff & & rdesc [ 107 ] = = 0x7f
& & rdesc [ 111 ] = = 0xff & & rdesc [ 112 ] = = 0x7f ) {
hid_info ( hdev , " Fixing up report descriptor \n " ) ;
rdesc [ 107 ] = rdesc [ 112 ] = 0x2f ;
}
break ;
2013-05-21 03:31:08 +04:00
}
2013-05-21 03:31:09 +04:00
2013-05-21 03:31:08 +04:00
}
return rdesc ;
}
static const struct hid_device_id holtek_mouse_devices [ ] = {
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 ) } ,
2014-01-14 16:09:09 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 ) } ,
2013-05-21 03:31:09 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A ) } ,
2013-10-22 01:42:22 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 ) } ,
2013-10-01 21:22:05 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 ) } ,
2014-09-05 19:13:17 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_HOLTEK_ALT ,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 ) } ,
2013-05-21 03:31:08 +04:00
{ }
} ;
MODULE_DEVICE_TABLE ( hid , holtek_mouse_devices ) ;
static struct hid_driver holtek_mouse_driver = {
. name = " holtek_mouse " ,
. id_table = holtek_mouse_devices ,
. report_fixup = holtek_mouse_report_fixup ,
} ;
2013-05-29 14:09:22 +04:00
module_hid_driver ( holtek_mouse_driver ) ;
2013-05-21 03:31:08 +04:00
MODULE_LICENSE ( " GPL " ) ;