162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * HID driver for some sunplus "special" devices 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 1999 Andreas Gal 662306a36Sopenharmony_ci * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 762306a36Sopenharmony_ci * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 862306a36Sopenharmony_ci * Copyright (c) 2006-2007 Jiri Kosina 962306a36Sopenharmony_ci * Copyright (c) 2008 Jiri Slaby 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/device.h> 1662306a36Sopenharmony_ci#include <linux/hid.h> 1762306a36Sopenharmony_ci#include <linux/module.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "hid-ids.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 2262306a36Sopenharmony_ci unsigned int *rsize) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && 2562306a36Sopenharmony_ci rdesc[106] == 0x03) { 2662306a36Sopenharmony_ci hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); 2762306a36Sopenharmony_ci rdesc[105] = rdesc[110] = 0x03; 2862306a36Sopenharmony_ci rdesc[106] = rdesc[111] = 0x21; 2962306a36Sopenharmony_ci } 3062306a36Sopenharmony_ci return rdesc; 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 3462306a36Sopenharmony_ci EV_KEY, (c)) 3562306a36Sopenharmony_cistatic int sp_input_mapping(struct hid_device *hdev, struct hid_input *hi, 3662306a36Sopenharmony_ci struct hid_field *field, struct hid_usage *usage, 3762306a36Sopenharmony_ci unsigned long **bit, int *max) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 4062306a36Sopenharmony_ci return 0; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci switch (usage->hid & HID_USAGE) { 4362306a36Sopenharmony_ci case 0x2003: sp_map_key_clear(KEY_ZOOMIN); break; 4462306a36Sopenharmony_ci case 0x2103: sp_map_key_clear(KEY_ZOOMOUT); break; 4562306a36Sopenharmony_ci default: 4662306a36Sopenharmony_ci return 0; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci return 1; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic const struct hid_device_id sp_devices[] = { 5262306a36Sopenharmony_ci { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 5362306a36Sopenharmony_ci { } 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(hid, sp_devices); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic struct hid_driver sp_driver = { 5862306a36Sopenharmony_ci .name = "sunplus", 5962306a36Sopenharmony_ci .id_table = sp_devices, 6062306a36Sopenharmony_ci .report_fixup = sp_report_fixup, 6162306a36Sopenharmony_ci .input_mapping = sp_input_mapping, 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_cimodule_hid_driver(sp_driver); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 66