Message ID | 20230724084752.371245-2-sandeep.cs@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Jiri Kosina |
Headers | show |
Series | HID Patchsets for Samsung driver | expand |
Hi Sandeep, On Jul 24 2023, sandeep.cs wrote: > This patch add support for the Samsung hid devices like keyboard, action mouse and gamepad over the Bluetooth connection. > > Bluetooth devices > > Vendor 04e8 (Samsung) > Device 7021 (Samsung Wireless Keyboard) > Device a000 (Samsung Wireless GamePad) > Device a004 (Samsung Wireless Action Mouse) > Device a005 (Samsung Wireless BookCover) > Device a006 (Samsung Wireless Universal Keyboard) > Device a064 (Samsung Wireless HOGP Keyboard) > > And also, special key processing on each Samsung Bluetooth devices. > > The changes in this commit adhere to the kernel coding guidelines. > > Signed-off-by: Sandeep C S <sandeep.cs@samsung.com> > Signed-off-by: Junwan Cho <junwan.cho@samsung.com> > Signed-off-by: Jitender Sajwan <jitender.s21@samsung.com> > --- > drivers/hid/hid-ids.h | 8 + > drivers/hid/hid-samsung.c | 412 ++++++++++++++++++++++++++++++++++++-- That's a huge patch. Way too big for me IMO. Please refactor the series with: 1. hid_is_usb() check being moved 2. fix the checkpatch complains without adding new devices 3+ split the remaining changes, one per device so we can track which device needs what. (1. and 2. can be done in any order) Cheers, Benjamin > 2 files changed, 399 insertions(+), 21 deletions(-) > > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h > index 8a310f8ff20f..35b2f50ba3c6 100644 > --- a/drivers/hid/hid-ids.h > +++ b/drivers/hid/hid-ids.h > @@ -1139,6 +1139,14 @@ > #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 > #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 > > +#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS 0x04e8 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD 0x7021 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD 0xa000 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE 0xa004 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER 0xa005 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006 > +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064 > + > #define USB_VENDOR_ID_SEMICO 0x1a2c > #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023 > #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027 > diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c > index cf5992e97094..33e963303d11 100644 > --- a/drivers/hid/hid-samsung.c > +++ b/drivers/hid/hid-samsung.c > @@ -67,20 +67,17 @@ static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, > rdesc[178] = 0x08; > rdesc[180] = 0x06; > rdesc[182] = 0x42; > - } else > - if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && > + } else if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && > rdesc[194] == 0x25 && rdesc[195] == 0x12) { > samsung_irda_dev_trace(hdev, 203); > rdesc[193] = 0x1; > rdesc[195] = 0xf; > - } else > - if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && > + } else if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && > rdesc[126] == 0x25 && rdesc[127] == 0x11) { > samsung_irda_dev_trace(hdev, 135); > rdesc[125] = 0x1; > rdesc[127] = 0xe; > - } else > - if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && > + } else if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && > rdesc[162] == 0x25 && rdesc[163] == 0x01) { > samsung_irda_dev_trace(hdev, 171); > rdesc[161] = 0x1; > @@ -107,17 +104,39 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev, > > switch (usage->hid & HID_USAGE) { > /* report 2 */ > - 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; > + 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; > default: > return 0; > } > @@ -125,10 +144,342 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev, > return 1; > } > > +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) { > + /* Only for UK keyboard */ > + /* key found */ > +#ifdef CONFIG_HID_KK_UPGRADE > + case 0x32: > + samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE); > + break; > + case 0x64: > + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); > + break; > +#else > + case 0x32: > + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); > + break; > + case 0x64: > + samsung_kbd_mouse_map_key_clear(KEY_102ND); > + break; > +#endif > + /* 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; > +} > + > +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; > +} > +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; > +} > +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) { > + /* Only for UK keyboard */ > + /* key found */ > +#ifdef CONFIG_HID_KK_UPGRADE > + case 0x32: > + samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE); > + break; > + case 0x64: > + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); > + break; > +#else > + case 0x32: > + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); > + break; > + case 0x64: > + samsung_kbd_mouse_map_key_clear(KEY_102ND); > + break; > +#endif > + /* 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; > +} > + > static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, > unsigned int *rsize) > { > - if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) > + if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) > rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize); > return rdesc; > } > @@ -139,10 +490,24 @@ static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi, > { > int ret = 0; > > - if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product) > + if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) > ret = samsung_kbd_mouse_input_mapping(hdev, > hi, field, usage, bit, max); > - > + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) > + ret = samsung_kbd_input_mapping(hdev, > + hi, field, usage, bit, max); > + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) > + ret = samsung_gamepad_input_mapping(hdev, > + hi, field, usage, bit, max); > + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) > + ret = samsung_actionmouse_input_mapping(hdev, > + hi, field, usage, bit, max); > + 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); > return ret; > } > > @@ -161,7 +526,7 @@ static int samsung_probe(struct hid_device *hdev, > goto err_free; > } > > - if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) { > + if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) { > if (hdev->rsize == 184) { > /* disable hidinput, force hiddev */ > cmask = (cmask & ~HID_CONNECT_HIDINPUT) | > @@ -183,6 +548,11 @@ static int samsung_probe(struct hid_device *hdev, > static const struct hid_device_id samsung_devices[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, > { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) }, > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) }, > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) }, > + { 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) }, > { } > }; > MODULE_DEVICE_TABLE(hid, samsung_devices); > -- > 2.25.1 >
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 8a310f8ff20f..35b2f50ba3c6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1139,6 +1139,14 @@ #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 +#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS 0x04e8 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD 0x7021 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD 0xa000 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE 0xa004 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER 0xa005 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006 +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064 + #define USB_VENDOR_ID_SEMICO 0x1a2c #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027 diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index cf5992e97094..33e963303d11 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -67,20 +67,17 @@ static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[178] = 0x08; rdesc[180] = 0x06; rdesc[182] = 0x42; - } else - if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && + } else if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && rdesc[194] == 0x25 && rdesc[195] == 0x12) { samsung_irda_dev_trace(hdev, 203); rdesc[193] = 0x1; rdesc[195] = 0xf; - } else - if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && + } else if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && rdesc[126] == 0x25 && rdesc[127] == 0x11) { samsung_irda_dev_trace(hdev, 135); rdesc[125] = 0x1; rdesc[127] = 0xe; - } else - if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && + } else if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && rdesc[162] == 0x25 && rdesc[163] == 0x01) { samsung_irda_dev_trace(hdev, 171); rdesc[161] = 0x1; @@ -107,17 +104,39 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev, switch (usage->hid & HID_USAGE) { /* report 2 */ - 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; + 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; default: return 0; } @@ -125,10 +144,342 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev, return 1; } +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) { + /* Only for UK keyboard */ + /* key found */ +#ifdef CONFIG_HID_KK_UPGRADE + case 0x32: + samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE); + break; + case 0x64: + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); + break; +#else + case 0x32: + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); + break; + case 0x64: + samsung_kbd_mouse_map_key_clear(KEY_102ND); + break; +#endif + /* 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; +} + +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; +} +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; +} +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) { + /* Only for UK keyboard */ + /* key found */ +#ifdef CONFIG_HID_KK_UPGRADE + case 0x32: + samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE); + break; + case 0x64: + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); + break; +#else + case 0x32: + samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH); + break; + case 0x64: + samsung_kbd_mouse_map_key_clear(KEY_102ND); + break; +#endif + /* 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; +} + static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) + if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize); return rdesc; } @@ -139,10 +490,24 @@ static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi, { int ret = 0; - if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product) + if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) ret = samsung_kbd_mouse_input_mapping(hdev, hi, field, usage, bit, max); - + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) + ret = samsung_kbd_input_mapping(hdev, + hi, field, usage, bit, max); + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) + ret = samsung_gamepad_input_mapping(hdev, + hi, field, usage, bit, max); + else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) + ret = samsung_actionmouse_input_mapping(hdev, + hi, field, usage, bit, max); + 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); return ret; } @@ -161,7 +526,7 @@ static int samsung_probe(struct hid_device *hdev, goto err_free; } - if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) { + if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) { if (hdev->rsize == 184) { /* disable hidinput, force hiddev */ cmask = (cmask & ~HID_CONNECT_HIDINPUT) | @@ -183,6 +548,11 @@ static int samsung_probe(struct hid_device *hdev, static const struct hid_device_id samsung_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) }, + { 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) }, { } }; MODULE_DEVICE_TABLE(hid, samsung_devices);