2008-06-24 22:42:25 +04:00
/*
* HID driver for some cherry " special " devices
*
* 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 ) 2006 - 2007 Jiri Kosina
* Copyright ( c ) 2008 Jiri Slaby
*/
/*
* 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/device.h>
# include <linux/hid.h>
# include <linux/module.h>
# include "hid-ids.h"
/*
* Cherry Cymotion keyboard have an invalid HID report descriptor ,
* that needs fixing before we can parse it .
*/
2010-08-06 23:03:06 +04:00
static __u8 * ch_report_fixup ( struct hid_device * hdev , __u8 * rdesc ,
unsigned int * rsize )
2008-06-24 22:42:25 +04:00
{
2010-08-06 23:03:06 +04:00
if ( * rsize > = 17 & & rdesc [ 11 ] = = 0x3c & & rdesc [ 12 ] = = 0x02 ) {
2010-12-10 06:29:03 +03:00
hid_info ( hdev , " fixing up Cherry Cymotion report descriptor \n " ) ;
2008-06-24 22:42:25 +04:00
rdesc [ 11 ] = rdesc [ 16 ] = 0xff ;
rdesc [ 12 ] = rdesc [ 17 ] = 0x03 ;
}
2010-08-06 23:03:06 +04:00
return rdesc ;
2008-06-24 22:42:25 +04:00
}
# define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
EV_KEY , ( c ) )
static int ch_input_mapping ( struct hid_device * hdev , struct hid_input * hi ,
struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
if ( ( usage - > hid & HID_USAGE_PAGE ) ! = HID_UP_CONSUMER )
return 0 ;
switch ( usage - > hid & HID_USAGE ) {
case 0x301 : ch_map_key_clear ( KEY_PROG1 ) ; break ;
case 0x302 : ch_map_key_clear ( KEY_PROG2 ) ; break ;
case 0x303 : ch_map_key_clear ( KEY_PROG3 ) ; break ;
default :
return 0 ;
}
return 1 ;
}
static const struct hid_device_id ch_devices [ ] = {
{ HID_USB_DEVICE ( USB_VENDOR_ID_CHERRY , USB_DEVICE_ID_CHERRY_CYMOTION ) } ,
2010-04-08 15:40:52 +04:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_CHERRY , USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR ) } ,
2008-06-24 22:42:25 +04:00
{ }
} ;
MODULE_DEVICE_TABLE ( hid , ch_devices ) ;
static struct hid_driver ch_driver = {
. name = " cherry " ,
. id_table = ch_devices ,
. report_fixup = ch_report_fixup ,
. input_mapping = ch_input_mapping ,
} ;
2009-07-02 21:08:38 +04:00
static int __init ch_init ( void )
2008-06-24 22:42:25 +04:00
{
return hid_register_driver ( & ch_driver ) ;
}
2009-07-02 21:08:38 +04:00
static void __exit ch_exit ( void )
2008-06-24 22:42:25 +04:00
{
hid_unregister_driver ( & ch_driver ) ;
}
module_init ( ch_init ) ;
module_exit ( ch_exit ) ;
MODULE_LICENSE ( " GPL " ) ;