root/drivers/hid/hid-zydacron.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zc_report_fixup
  2. zc_input_mapping
  3. zc_raw_event
  4. zc_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 *  HID driver for zydacron remote control
   4 *
   5 *  Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
   6 */
   7 
   8 /*
   9 */
  10 
  11 #include <linux/device.h>
  12 #include <linux/hid.h>
  13 #include <linux/module.h>
  14 
  15 #include "hid-ids.h"
  16 
  17 struct zc_device {
  18         struct input_dev        *input_ep81;
  19         unsigned short          last_key[4];
  20 };
  21 
  22 
  23 /*
  24 * Zydacron remote control has an invalid HID report descriptor,
  25 * that needs fixing before we can parse it.
  26 */
  27 static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
  28         unsigned int *rsize)
  29 {
  30         if (*rsize >= 253 &&
  31                 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
  32                 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
  33                 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
  34                         hid_info(hdev,
  35                                 "fixing up zydacron remote control report descriptor\n");
  36                         rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
  37                         rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
  38                 }
  39         return rdesc;
  40 }
  41 
  42 #define zc_map_key_clear(c) \
  43         hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
  44 
  45 static int zc_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  46         struct hid_field *field, struct hid_usage *usage,
  47         unsigned long **bit, int *max)
  48 {
  49         int i;
  50         struct zc_device *zc = hid_get_drvdata(hdev);
  51         zc->input_ep81 = hi->input;
  52 
  53         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
  54                 return 0;
  55 
  56         dbg_hid("zynacron input mapping event [0x%x]\n",
  57                 usage->hid & HID_USAGE);
  58 
  59         switch (usage->hid & HID_USAGE) {
  60         /* report 2 */
  61         case 0x10:
  62                 zc_map_key_clear(KEY_MODE);
  63                 break;
  64         case 0x30:
  65                 zc_map_key_clear(KEY_SCREEN);
  66                 break;
  67         case 0x70:
  68                 zc_map_key_clear(KEY_INFO);
  69                 break;
  70         /* report 3 */
  71         case 0x04:
  72                 zc_map_key_clear(KEY_RADIO);
  73                 break;
  74         /* report 4 */
  75         case 0x0d:
  76                 zc_map_key_clear(KEY_PVR);
  77                 break;
  78         case 0x25:
  79                 zc_map_key_clear(KEY_TV);
  80                 break;
  81         case 0x47:
  82                 zc_map_key_clear(KEY_AUDIO);
  83                 break;
  84         case 0x49:
  85                 zc_map_key_clear(KEY_AUX);
  86                 break;
  87         case 0x4a:
  88                 zc_map_key_clear(KEY_VIDEO);
  89                 break;
  90         case 0x48:
  91                 zc_map_key_clear(KEY_DVD);
  92                 break;
  93         case 0x24:
  94                 zc_map_key_clear(KEY_MENU);
  95                 break;
  96         case 0x32:
  97                 zc_map_key_clear(KEY_TEXT);
  98                 break;
  99         default:
 100                 return 0;
 101         }
 102 
 103         for (i = 0; i < 4; i++)
 104                 zc->last_key[i] = 0;
 105 
 106         return 1;
 107 }
 108 
 109 static int zc_raw_event(struct hid_device *hdev, struct hid_report *report,
 110          u8 *data, int size)
 111 {
 112         struct zc_device *zc = hid_get_drvdata(hdev);
 113         int ret = 0;
 114         unsigned key;
 115         unsigned short index;
 116 
 117         if (report->id == data[0]) {
 118 
 119                 /* break keys */
 120                 for (index = 0; index < 4; index++) {
 121                         key = zc->last_key[index];
 122                         if (key) {
 123                                 input_event(zc->input_ep81, EV_KEY, key, 0);
 124                                 zc->last_key[index] = 0;
 125                         }
 126                 }
 127 
 128                 key = 0;
 129                 switch (report->id) {
 130                 case 0x02:
 131                 case 0x03:
 132                         switch (data[1]) {
 133                         case 0x10:
 134                                 key = KEY_MODE;
 135                                 index = 0;
 136                                 break;
 137                         case 0x30:
 138                                 key = KEY_SCREEN;
 139                                 index = 1;
 140                                 break;
 141                         case 0x70:
 142                                 key = KEY_INFO;
 143                                 index = 2;
 144                                 break;
 145                         case 0x04:
 146                                 key = KEY_RADIO;
 147                                 index = 3;
 148                                 break;
 149                         }
 150 
 151                         if (key) {
 152                                 input_event(zc->input_ep81, EV_KEY, key, 1);
 153                                 zc->last_key[index] = key;
 154                         }
 155 
 156                         ret = 1;
 157                         break;
 158                 }
 159         }
 160 
 161         return ret;
 162 }
 163 
 164 static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)
 165 {
 166         int ret;
 167         struct zc_device *zc;
 168 
 169         zc = devm_kzalloc(&hdev->dev, sizeof(*zc), GFP_KERNEL);
 170         if (zc == NULL) {
 171                 hid_err(hdev, "can't alloc descriptor\n");
 172                 return -ENOMEM;
 173         }
 174 
 175         hid_set_drvdata(hdev, zc);
 176 
 177         ret = hid_parse(hdev);
 178         if (ret) {
 179                 hid_err(hdev, "parse failed\n");
 180                 return ret;
 181         }
 182 
 183         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 184         if (ret) {
 185                 hid_err(hdev, "hw start failed\n");
 186                 return ret;
 187         }
 188 
 189         return 0;
 190 }
 191 
 192 static const struct hid_device_id zc_devices[] = {
 193         { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
 194         { }
 195 };
 196 MODULE_DEVICE_TABLE(hid, zc_devices);
 197 
 198 static struct hid_driver zc_driver = {
 199         .name = "zydacron",
 200         .id_table = zc_devices,
 201         .report_fixup = zc_report_fixup,
 202         .input_mapping = zc_input_mapping,
 203         .raw_event = zc_raw_event,
 204         .probe = zc_probe,
 205 };
 206 module_hid_driver(zc_driver);
 207 
 208 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */