Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  HID driver for some petalynx "special" devices
0004  *
0005  *  Copyright (c) 1999 Andreas Gal
0006  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
0007  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
0008  *  Copyright (c) 2006-2007 Jiri Kosina
0009  *  Copyright (c) 2008 Jiri Slaby
0010  */
0011 
0012 /*
0013  */
0014 
0015 #include <linux/device.h>
0016 #include <linux/hid.h>
0017 #include <linux/module.h>
0018 
0019 #include "hid-ids.h"
0020 
0021 /* Petalynx Maxter Remote has maximum for consumer page set too low */
0022 static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
0023         unsigned int *rsize)
0024 {
0025     if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
0026             rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
0027             rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
0028         hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
0029         rdesc[60] = 0xfa;
0030         rdesc[40] = 0xfa;
0031     }
0032     return rdesc;
0033 }
0034 
0035 #define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
0036                     EV_KEY, (c))
0037 static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi,
0038         struct hid_field *field, struct hid_usage *usage,
0039         unsigned long **bit, int *max)
0040 {
0041     if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) {
0042         switch (usage->hid & HID_USAGE) {
0043         case 0x05a: pl_map_key_clear(KEY_TEXT);     break;
0044         case 0x05b: pl_map_key_clear(KEY_RED);      break;
0045         case 0x05c: pl_map_key_clear(KEY_GREEN);    break;
0046         case 0x05d: pl_map_key_clear(KEY_YELLOW);   break;
0047         case 0x05e: pl_map_key_clear(KEY_BLUE);     break;
0048         default:
0049             return 0;
0050         }
0051         return 1;
0052     }
0053 
0054     if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
0055         switch (usage->hid & HID_USAGE) {
0056         case 0x0f6: pl_map_key_clear(KEY_NEXT);     break;
0057         case 0x0fa: pl_map_key_clear(KEY_BACK);     break;
0058         default:
0059             return 0;
0060         }
0061         return 1;
0062     }
0063 
0064     return 0;
0065 }
0066 
0067 static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
0068 {
0069     int ret;
0070 
0071     hdev->quirks |= HID_QUIRK_NOGET;
0072 
0073     ret = hid_parse(hdev);
0074     if (ret) {
0075         hid_err(hdev, "parse failed\n");
0076         goto err_free;
0077     }
0078 
0079     ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
0080     if (ret) {
0081         hid_err(hdev, "hw start failed\n");
0082         goto err_free;
0083     }
0084 
0085     return 0;
0086 err_free:
0087     return ret;
0088 }
0089 
0090 static const struct hid_device_id pl_devices[] = {
0091     { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
0092     { }
0093 };
0094 MODULE_DEVICE_TABLE(hid, pl_devices);
0095 
0096 static struct hid_driver pl_driver = {
0097     .name = "petalynx",
0098     .id_table = pl_devices,
0099     .report_fixup = pl_report_fixup,
0100     .input_mapping = pl_input_mapping,
0101     .probe = pl_probe,
0102 };
0103 module_hid_driver(pl_driver);
0104 
0105 MODULE_LICENSE("GPL");