2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-06-25 22:31:48 +02:00
/*
* HID driver for some samsung " 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
2010-05-17 11:42:39 +01:00
* Copyright ( c ) 2010 Don Prince < dhprince . devel @ yahoo . co . uk >
*
* This driver supports several HID devices :
*
* [ 041 9 : 0001 ] Samsung IrDA remote controller ( reports as Cypress USB Mouse ) .
* various hid report fixups for different variants .
*
* [ 041 9 : 0600 ] Creative Desktop Wireless 6000 keyboard / mouse combo
* several key mappings used from the consumer usage page
* deviate from the USB HUT 1.12 standard .
2008-06-25 22:31:48 +02:00
*/
/*
*/
# include <linux/device.h>
2010-05-17 11:42:39 +01:00
# include <linux/usb.h>
2008-06-25 22:31:48 +02:00
# include <linux/hid.h>
# include <linux/module.h>
# include "hid-ids.h"
/*
2009-06-23 11:26:48 +02:00
* There are several variants for 041 9 : 0001 :
*
* 1. 184 byte report descriptor
2008-06-25 22:31:48 +02:00
* Vendor specific report # 4 has a size of 48 bit ,
* and therefore is not accepted when inspecting the descriptors .
* As a workaround we reinterpret the report as :
* Variable type , count 6 , size 8 bit , log . maximum 255
* The burden to reconstruct the data is moved into user space .
2009-06-23 11:26:48 +02:00
*
* 2. 203 byte report descriptor
* Report # 4 has an array field with logical range 0. .18 instead of 1. .15 .
*
* 3. 135 byte report descriptor
* Report # 4 has an array field with logical range 0. .17 instead of 1. .14 .
2009-12-11 00:37:11 +01:00
*
* 4. 171 byte report descriptor
* Report # 3 has an array field with logical range 0. .1 instead of 1. .3 .
2008-06-25 22:31:48 +02:00
*/
2010-05-17 11:42:39 +01:00
static inline void samsung_irda_dev_trace ( struct hid_device * hdev ,
2009-12-11 00:37:11 +01:00
unsigned int rsize )
{
2010-12-09 19:29:03 -08:00
hid_info ( hdev , " fixing up Samsung IrDA %d byte report descriptor \n " ,
rsize ) ;
2009-12-11 00:37:11 +01:00
}
2010-08-06 23:03:06 +04:00
static __u8 * samsung_irda_report_fixup ( struct hid_device * hdev , __u8 * rdesc ,
unsigned int * rsize )
2008-06-25 22:31:48 +02:00
{
2024-01-25 10:06:25 +05:30
if ( * rsize = = 184 & & ! memcmp ( & rdesc [ 175 ] , " \x25 \x40 \x75 \x30 \x95 \x01 " , 6 ) & &
2008-06-25 22:31:48 +02:00
rdesc [ 182 ] = = 0x40 ) {
2010-05-17 11:42:39 +01:00
samsung_irda_dev_trace ( hdev , 184 ) ;
2008-06-25 22:31:48 +02:00
rdesc [ 176 ] = 0xff ;
rdesc [ 178 ] = 0x08 ;
rdesc [ 180 ] = 0x06 ;
rdesc [ 182 ] = 0x42 ;
2024-01-25 10:06:25 +05:30
} else if ( * rsize = = 203 & & ! memcmp ( & rdesc [ 192 ] , " \x15 \x00 \x25 \x12 " , 4 ) ) {
2010-05-17 11:42:39 +01:00
samsung_irda_dev_trace ( hdev , 203 ) ;
2024-01-25 10:06:25 +05:30
rdesc [ 193 ] = 0x01 ;
rdesc [ 195 ] = 0x0f ;
} else if ( * rsize = = 135 & & ! memcmp ( & rdesc [ 124 ] , " \x15 \x00 \x25 \x11 " , 4 ) ) {
2010-05-17 11:42:39 +01:00
samsung_irda_dev_trace ( hdev , 135 ) ;
2024-01-25 10:06:25 +05:30
rdesc [ 125 ] = 0x01 ;
rdesc [ 127 ] = 0x0e ;
} else if ( * rsize = = 171 & & ! memcmp ( & rdesc [ 160 ] , " \x15 \x00 \x25 \x01 " , 4 ) ) {
2010-05-17 11:42:39 +01:00
samsung_irda_dev_trace ( hdev , 171 ) ;
2024-01-25 10:06:25 +05:30
rdesc [ 161 ] = 0x01 ;
rdesc [ 163 ] = 0x03 ;
2008-06-25 22:31:48 +02:00
}
2010-08-06 23:03:06 +04:00
return rdesc ;
2008-06-25 22:31:48 +02:00
}
2010-05-17 11:42:39 +01:00
# define samsung_kbd_mouse_map_key_clear(c) \
hid_map_usage_clear ( hi , usage , bit , max , EV_KEY , ( c ) )
static int samsung_kbd_mouse_input_mapping ( struct hid_device * hdev ,
struct hid_input * hi , struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
struct usb_interface * intf = to_usb_interface ( hdev - > dev . parent ) ;
unsigned short ifnum = intf - > cur_altsetting - > desc . bInterfaceNumber ;
2024-01-25 10:06:25 +05:30
if ( ifnum ! = 1 | | HID_UP_CONSUMER ! = ( usage - > hid & HID_USAGE_PAGE ) )
2010-05-17 11:42:39 +01:00
return 0 ;
dbg_hid ( " samsung wireless keyboard/mouse input mapping event [0x%x] \n " ,
usage - > hid & HID_USAGE ) ;
switch ( usage - > hid & HID_USAGE ) {
/* report 2 */
2024-01-25 10:06:25 +05:30
case 0x183 :
samsung_kbd_mouse_map_key_clear ( KEY_MEDIA ) ;
break ;
case 0x195 :
samsung_kbd_mouse_map_key_clear ( KEY_EMAIL ) ;
break ;
case 0x196 :
samsung_kbd_mouse_map_key_clear ( KEY_CALC ) ;
break ;
case 0x197 :
samsung_kbd_mouse_map_key_clear ( KEY_COMPUTER ) ;
break ;
case 0x22b :
samsung_kbd_mouse_map_key_clear ( KEY_SEARCH ) ;
break ;
case 0x22c :
samsung_kbd_mouse_map_key_clear ( KEY_WWW ) ;
break ;
case 0x22d :
samsung_kbd_mouse_map_key_clear ( KEY_BACK ) ;
break ;
case 0x22e :
samsung_kbd_mouse_map_key_clear ( KEY_FORWARD ) ;
break ;
case 0x22f :
samsung_kbd_mouse_map_key_clear ( KEY_FAVORITES ) ;
break ;
case 0x230 :
samsung_kbd_mouse_map_key_clear ( KEY_REFRESH ) ;
break ;
case 0x231 :
samsung_kbd_mouse_map_key_clear ( KEY_STOP ) ;
break ;
2010-05-17 11:42:39 +01:00
default :
return 0 ;
}
return 1 ;
}
2024-01-25 10:06:26 +05:30
static int samsung_kbd_input_mapping ( struct hid_device * hdev ,
struct hid_input * hi , struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
if ( ! ( HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) | |
HID_UP_KEYBOARD = = ( usage - > hid & HID_USAGE_PAGE ) ) )
return 0 ;
dbg_hid ( " samsung wireless keyboard input mapping event [0x%x] \n " ,
usage - > hid & HID_USAGE ) ;
if ( HID_UP_KEYBOARD = = ( usage - > hid & HID_USAGE_PAGE ) ) {
set_bit ( EV_REP , hi - > input - > evbit ) ;
switch ( usage - > hid & HID_USAGE ) {
case 0x32 :
samsung_kbd_mouse_map_key_clear ( KEY_BACKSLASH ) ;
break ;
case 0x64 :
samsung_kbd_mouse_map_key_clear ( KEY_102ND ) ;
break ;
/* Only for BR keyboard */
case 0x87 :
samsung_kbd_mouse_map_key_clear ( KEY_RO ) ;
break ;
default :
return 0 ;
}
}
if ( HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) ) {
switch ( usage - > hid & HID_USAGE ) {
/* report 2 */
/* MENU */
case 0x040 :
samsung_kbd_mouse_map_key_clear ( KEY_MENU ) ;
break ;
case 0x18a :
samsung_kbd_mouse_map_key_clear ( KEY_MAIL ) ;
break ;
case 0x196 :
samsung_kbd_mouse_map_key_clear ( KEY_WWW ) ;
break ;
case 0x19e :
samsung_kbd_mouse_map_key_clear ( KEY_SCREENLOCK ) ;
break ;
case 0x221 :
samsung_kbd_mouse_map_key_clear ( KEY_SEARCH ) ;
break ;
case 0x223 :
samsung_kbd_mouse_map_key_clear ( KEY_HOMEPAGE ) ;
break ;
/* Smtart Voice Key */
case 0x300 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY13 ) ;
break ;
/* RECENTAPPS */
case 0x301 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY1 ) ;
break ;
/* APPLICATION */
case 0x302 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY2 ) ;
break ;
/* Voice search */
case 0x305 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY4 ) ;
break ;
/* QPANEL on/off */
case 0x306 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY5 ) ;
break ;
/* SIP on/off */
case 0x307 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY3 ) ;
break ;
/* LANG */
case 0x308 :
samsung_kbd_mouse_map_key_clear ( KEY_LANGUAGE ) ;
break ;
case 0x30a :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSDOWN ) ;
break ;
case 0x30b :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSUP ) ;
break ;
default :
return 0 ;
}
}
return 1 ;
}
2024-01-25 10:06:27 +05:30
static int samsung_gamepad_input_mapping ( struct hid_device * hdev ,
struct hid_input * hi , struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
if ( ! ( HID_UP_BUTTON = = ( usage - > hid & HID_USAGE_PAGE ) | |
HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) ) )
return 0 ;
dbg_hid ( " samsung wireless gamepad input mapping event [0x%x], %ld, %ld, [0x%x] \n " ,
usage - > hid & HID_USAGE , hi - > input - > evbit [ 0 ] , hi - > input - > absbit [ 0 ] , usage - > hid & HID_USAGE_PAGE ) ;
if ( HID_UP_BUTTON = = ( usage - > hid & HID_USAGE_PAGE ) ) {
switch ( usage - > hid & HID_USAGE ) {
case 0x01 :
samsung_kbd_mouse_map_key_clear ( BTN_A ) ;
break ;
case 0x02 :
samsung_kbd_mouse_map_key_clear ( BTN_B ) ;
break ;
case 0x03 :
samsung_kbd_mouse_map_key_clear ( BTN_C ) ;
break ;
case 0x04 :
samsung_kbd_mouse_map_key_clear ( BTN_X ) ;
break ;
case 0x05 :
samsung_kbd_mouse_map_key_clear ( BTN_Y ) ;
break ;
case 0x06 :
samsung_kbd_mouse_map_key_clear ( BTN_Z ) ;
break ;
case 0x07 :
samsung_kbd_mouse_map_key_clear ( BTN_TL ) ;
break ;
case 0x08 :
samsung_kbd_mouse_map_key_clear ( BTN_TR ) ;
break ;
case 0x09 :
samsung_kbd_mouse_map_key_clear ( BTN_TL2 ) ;
break ;
case 0x0a :
samsung_kbd_mouse_map_key_clear ( BTN_TR2 ) ;
break ;
case 0x0b :
samsung_kbd_mouse_map_key_clear ( BTN_SELECT ) ;
break ;
case 0x0c :
samsung_kbd_mouse_map_key_clear ( BTN_START ) ;
break ;
case 0x0d :
samsung_kbd_mouse_map_key_clear ( BTN_MODE ) ;
break ;
case 0x0e :
samsung_kbd_mouse_map_key_clear ( BTN_THUMBL ) ;
break ;
case 0x0f :
samsung_kbd_mouse_map_key_clear ( BTN_THUMBR ) ;
break ;
case 0x10 :
samsung_kbd_mouse_map_key_clear ( 0x13f ) ;
break ;
default :
return 0 ;
}
}
if ( HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) ) {
switch ( usage - > hid & HID_USAGE ) {
case 0x040 :
samsung_kbd_mouse_map_key_clear ( KEY_MENU ) ;
break ;
case 0x223 :
samsung_kbd_mouse_map_key_clear ( KEY_HOMEPAGE ) ;
break ;
case 0x224 :
samsung_kbd_mouse_map_key_clear ( KEY_BACK ) ;
break ;
/* Screen Capture */
case 0x303 :
samsung_kbd_mouse_map_key_clear ( KEY_SYSRQ ) ;
break ;
default :
return 0 ;
}
}
return 1 ;
}
2024-01-25 10:06:28 +05:30
static int samsung_actionmouse_input_mapping ( struct hid_device * hdev ,
struct hid_input * hi , struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
dbg_hid ( " samsung wireless actionmouse input mapping event [0x%x], [0x%x], %ld, %ld, [0x%x] \n " ,
usage - > hid , usage - > hid & HID_USAGE , hi - > input - > evbit [ 0 ] , hi - > input - > absbit [ 0 ] ,
usage - > hid & HID_USAGE_PAGE ) ;
if ( ( ( usage - > hid & HID_USAGE_PAGE ) ! = HID_UP_CONSUMER ) & & ( ( usage - > hid & HID_USAGE_PAGE ) ! = HID_UP_BUTTON ) )
return 0 ;
switch ( usage - > hid & HID_USAGE ) {
case 0x301 :
samsung_kbd_mouse_map_key_clear ( 254 ) ;
break ;
default :
return 0 ;
}
return 1 ;
}
2024-01-25 10:06:29 +05:30
static int samsung_universal_kbd_input_mapping ( struct hid_device * hdev ,
struct hid_input * hi , struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
if ( ! ( HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) | |
HID_UP_KEYBOARD = = ( usage - > hid & HID_USAGE_PAGE ) ) )
return 0 ;
dbg_hid ( " samsung wireless keyboard input mapping event [0x%x] \n " ,
usage - > hid & HID_USAGE ) ;
if ( HID_UP_KEYBOARD = = ( usage - > hid & HID_USAGE_PAGE ) ) {
set_bit ( EV_REP , hi - > input - > evbit ) ;
switch ( usage - > hid & HID_USAGE ) {
case 0x32 :
samsung_kbd_mouse_map_key_clear ( KEY_BACKSLASH ) ;
break ;
case 0x64 :
samsung_kbd_mouse_map_key_clear ( KEY_102ND ) ;
break ;
/* Only for BR keyboard */
case 0x87 :
samsung_kbd_mouse_map_key_clear ( KEY_RO ) ;
break ;
default :
return 0 ;
}
}
if ( HID_UP_CONSUMER = = ( usage - > hid & HID_USAGE_PAGE ) ) {
switch ( usage - > hid & HID_USAGE ) {
/* report 2 */
/* MENU */
case 0x040 :
samsung_kbd_mouse_map_key_clear ( KEY_MENU ) ;
break ;
case 0x18a :
samsung_kbd_mouse_map_key_clear ( KEY_MAIL ) ;
break ;
case 0x196 :
samsung_kbd_mouse_map_key_clear ( KEY_WWW ) ;
break ;
case 0x19e :
samsung_kbd_mouse_map_key_clear ( KEY_SCREENLOCK ) ;
break ;
case 0x221 :
samsung_kbd_mouse_map_key_clear ( KEY_SEARCH ) ;
break ;
case 0x223 :
samsung_kbd_mouse_map_key_clear ( KEY_HOMEPAGE ) ;
break ;
/* RECENTAPPS */
case 0x301 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY1 ) ;
break ;
/* APPLICATION */
case 0x302 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY2 ) ;
break ;
/* Voice search */
case 0x305 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY4 ) ;
break ;
/* QPANEL on/off */
case 0x306 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY5 ) ;
break ;
/* SIP on/off */
case 0x307 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY3 ) ;
break ;
/* LANG */
case 0x308 :
samsung_kbd_mouse_map_key_clear ( KEY_LANGUAGE ) ;
break ;
case 0x30a :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSDOWN ) ;
break ;
case 0x070 :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSDOWN ) ;
break ;
case 0x30b :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSUP ) ;
break ;
case 0x06f :
samsung_kbd_mouse_map_key_clear ( KEY_BRIGHTNESSUP ) ;
break ;
/* S-Finder */
case 0x304 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY7 ) ;
break ;
/* Screen Capture */
case 0x303 :
samsung_kbd_mouse_map_key_clear ( KEY_SYSRQ ) ;
break ;
/* Multi Window */
case 0x309 :
samsung_kbd_mouse_map_key_clear ( BTN_TRIGGER_HAPPY9 ) ;
break ;
/* HotKey App 1 */
case 0x071 :
samsung_kbd_mouse_map_key_clear ( 0x2f5 ) ;
break ;
/* HotKey App 2 */
case 0x072 :
samsung_kbd_mouse_map_key_clear ( 0x2f6 ) ;
break ;
/* HotKey App 3 */
case 0x073 :
samsung_kbd_mouse_map_key_clear ( 0x2f7 ) ;
break ;
/* Dex */
case 0x06e :
samsung_kbd_mouse_map_key_clear ( 0x2bd ) ;
break ;
default :
return 0 ;
}
}
return 1 ;
}
2010-08-06 23:03:06 +04:00
static __u8 * samsung_report_fixup ( struct hid_device * hdev , __u8 * rdesc ,
unsigned int * rsize )
2010-05-17 11:42:39 +01:00
{
2024-01-25 10:06:25 +05:30
if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_IR_REMOTE & & hid_is_usb ( hdev ) )
2010-08-06 23:03:06 +04:00
rdesc = samsung_irda_report_fixup ( hdev , rdesc , rsize ) ;
return rdesc ;
2010-05-17 11:42:39 +01:00
}
static int samsung_input_mapping ( struct hid_device * hdev , struct hid_input * hi ,
struct hid_field * field , struct hid_usage * usage ,
unsigned long * * bit , int * max )
{
int ret = 0 ;
2024-01-25 10:06:25 +05:30
if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE & & hid_is_usb ( hdev ) )
2010-05-17 11:42:39 +01:00
ret = samsung_kbd_mouse_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
2024-01-25 10:06:26 +05:30
else if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD )
ret = samsung_kbd_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
2024-01-25 10:06:27 +05:30
else if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD )
ret = samsung_gamepad_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
2024-01-25 10:06:28 +05:30
else if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE )
ret = samsung_actionmouse_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
2024-01-25 10:06:29 +05:30
else if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD )
ret = samsung_universal_kbd_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
else if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD )
ret = samsung_universal_kbd_input_mapping ( hdev ,
hi , field , usage , bit , max ) ;
2010-05-17 11:42:39 +01:00
return ret ;
}
2008-06-25 22:31:48 +02:00
static int samsung_probe ( struct hid_device * hdev ,
const struct hid_device_id * id )
{
int ret ;
2009-06-23 11:26:48 +02:00
unsigned int cmask = HID_CONNECT_DEFAULT ;
2008-06-25 22:31:48 +02:00
ret = hid_parse ( hdev ) ;
if ( ret ) {
2010-12-09 19:29:03 -08:00
hid_err ( hdev , " parse failed \n " ) ;
2008-06-25 22:31:48 +02:00
goto err_free ;
}
2024-01-25 10:06:25 +05:30
if ( hdev - > product = = USB_DEVICE_ID_SAMSUNG_IR_REMOTE ) {
2024-01-25 10:06:24 +05:30
if ( ! hid_is_usb ( hdev ) ) {
ret = - EINVAL ;
goto err_free ;
}
2010-05-17 11:42:39 +01:00
if ( hdev - > rsize = = 184 ) {
/* disable hidinput, force hiddev */
cmask = ( cmask & ~ HID_CONNECT_HIDINPUT ) |
HID_CONNECT_HIDDEV_FORCE ;
}
2009-06-23 11:26:48 +02:00
}
ret = hid_hw_start ( hdev , cmask ) ;
2008-06-25 22:31:48 +02:00
if ( ret ) {
2010-12-09 19:29:03 -08:00
hid_err ( hdev , " hw start failed \n " ) ;
2008-06-25 22:31:48 +02:00
goto err_free ;
}
return 0 ;
err_free :
return ret ;
}
static const struct hid_device_id samsung_devices [ ] = {
{ HID_USB_DEVICE ( USB_VENDOR_ID_SAMSUNG , USB_DEVICE_ID_SAMSUNG_IR_REMOTE ) } ,
2010-05-17 11:42:39 +01:00
{ HID_USB_DEVICE ( USB_VENDOR_ID_SAMSUNG , USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE ) } ,
2024-01-25 10:06:26 +05:30
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_SAMSUNG_ELECTRONICS , USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD ) } ,
2024-01-25 10:06:27 +05:30
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_SAMSUNG_ELECTRONICS , USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD ) } ,
2024-01-25 10:06:28 +05:30
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_SAMSUNG_ELECTRONICS , USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE ) } ,
2024-01-25 10:06:29 +05:30
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_SAMSUNG_ELECTRONICS , USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD ) } ,
{ HID_BLUETOOTH_DEVICE ( USB_VENDOR_ID_SAMSUNG_ELECTRONICS , USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD ) } ,
2008-06-25 22:31:48 +02:00
{ }
} ;
MODULE_DEVICE_TABLE ( hid , samsung_devices ) ;
static struct hid_driver samsung_driver = {
. name = " samsung " ,
. id_table = samsung_devices ,
. report_fixup = samsung_report_fixup ,
2010-05-17 11:42:39 +01:00
. input_mapping = samsung_input_mapping ,
2008-06-25 22:31:48 +02:00
. probe = samsung_probe ,
} ;
2012-12-17 15:28:26 -07:00
module_hid_driver ( samsung_driver ) ;
2008-06-25 22:31:48 +02:00
MODULE_LICENSE ( " GPL " ) ;