root/drivers/hid/hid-icade.c

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

DEFINITIONS

This source file includes following definitions.
  1. icade_find_translation
  2. icade_event
  3. icade_input_mapping
  4. icade_input_mapped

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  ION iCade input driver
   4  *
   5  *  Copyright (c) 2012 Bastien Nocera <hadess@hadess.net>
   6  *  Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
   7  */
   8 
   9 /*
  10  */
  11 
  12 #include <linux/device.h>
  13 #include <linux/hid.h>
  14 #include <linux/module.h>
  15 
  16 #include "hid-ids.h"
  17 
  18 /*
  19  *   ↑      A C Y L
  20  *  ← →
  21  *   ↓      B X Z R
  22  *
  23  *
  24  *  UP ON,OFF  = w,e
  25  *  RT ON,OFF  = d,c
  26  *  DN ON,OFF  = x,z
  27  *  LT ON,OFF  = a,q
  28  *  A  ON,OFF  = y,t
  29  *  B  ON,OFF  = h,r
  30  *  C  ON,OFF  = u,f
  31  *  X  ON,OFF  = j,n
  32  *  Y  ON,OFF  = i,m
  33  *  Z  ON,OFF  = k,p
  34  *  L  ON,OFF  = o,g
  35  *  R  ON,OFF  = l,v
  36  */
  37 
  38 /* The translation code uses HID usage instead of input layer
  39  * keys. This code generates a lookup table that makes
  40  * translation quick.
  41  *
  42  * #include <linux/input.h>
  43  * #include <stdio.h>
  44  * #include <assert.h>
  45  *
  46  * #define unk     KEY_UNKNOWN
  47  *
  48  * < copy of hid_keyboard[] from hid-input.c >
  49  *
  50  * struct icade_key_translation {
  51  *     int         from;
  52  *     const char *to;
  53  *     int         press;
  54  * };
  55  *
  56  * static const struct icade_key_translation icade_keys[] = {
  57  *    { KEY_W,        "KEY_UP",         1 },
  58  *    { KEY_E,        "KEY_UP",         0 },
  59  *    { KEY_D,        "KEY_RIGHT",      1 },
  60  *    { KEY_C,        "KEY_RIGHT",      0 },
  61  *    { KEY_X,        "KEY_DOWN",       1 },
  62  *    { KEY_Z,        "KEY_DOWN",       0 },
  63  *    { KEY_A,        "KEY_LEFT",       1 },
  64  *    { KEY_Q,        "KEY_LEFT",       0 },
  65  *    { KEY_Y,        "BTN_A",          1 },
  66  *    { KEY_T,        "BTN_A",          0 },
  67  *    { KEY_H,        "BTN_B",          1 },
  68  *    { KEY_R,        "BTN_B",          0 },
  69  *    { KEY_U,        "BTN_C",          1 },
  70  *    { KEY_F,        "BTN_C",          0 },
  71  *    { KEY_J,        "BTN_X",          1 },
  72  *    { KEY_N,        "BTN_X",          0 },
  73  *    { KEY_I,        "BTN_Y",          1 },
  74  *    { KEY_M,        "BTN_Y",          0 },
  75  *    { KEY_K,        "BTN_Z",          1 },
  76  *    { KEY_P,        "BTN_Z",          0 },
  77  *    { KEY_O,        "BTN_THUMBL",     1 },
  78  *    { KEY_G,        "BTN_THUMBL",     0 },
  79  *    { KEY_L,        "BTN_THUMBR",     1 },
  80  *    { KEY_V,        "BTN_THUMBR",     0 },
  81  *
  82  *    { }
  83  * };
  84  *
  85  * static int
  86  * usage_for_key (int key)
  87  * {
  88  *     int i;
  89  *     for (i = 0; i < 256; i++) {
  90  *     if (hid_keyboard[i] == key)
  91  *         return i;
  92  *     }
  93  *     assert(0);
  94  * }
  95  *
  96  * int main (int argc, char **argv)
  97  * {
  98  *     const struct icade_key_translation *trans;
  99  *     int max_usage = 0;
 100  *
 101  *     for (trans = icade_keys; trans->from; trans++) {
 102  *         int usage = usage_for_key (trans->from);
 103  *         max_usage = usage > max_usage ? usage : max_usage;
 104  *     }
 105  *
 106  *     printf ("#define ICADE_MAX_USAGE %d\n\n", max_usage);
 107  *     printf ("struct icade_key {\n");
 108  *     printf ("\tu16 to;\n");
 109  *     printf ("\tu8 press:1;\n");
 110  *     printf ("};\n\n");
 111  *     printf ("static const struct icade_key "
 112  *             "icade_usage_table[%d] = {\n", max_usage + 1);
 113  *     for (trans = icade_keys; trans->from; trans++) {
 114  *         printf ("\t[%d] = { %s, %d },\n",
 115  *                 usage_for_key (trans->from), trans->to, trans->press);
 116  *     }
 117  *     printf ("};\n");
 118  *
 119  *     return 0;
 120  * }
 121  */
 122 
 123 #define ICADE_MAX_USAGE 29
 124 
 125 struct icade_key {
 126         u16 to;
 127         u8 press:1;
 128 };
 129 
 130 static const struct icade_key icade_usage_table[30] = {
 131         [26] = { KEY_UP, 1 },
 132         [8] = { KEY_UP, 0 },
 133         [7] = { KEY_RIGHT, 1 },
 134         [6] = { KEY_RIGHT, 0 },
 135         [27] = { KEY_DOWN, 1 },
 136         [29] = { KEY_DOWN, 0 },
 137         [4] = { KEY_LEFT, 1 },
 138         [20] = { KEY_LEFT, 0 },
 139         [28] = { BTN_A, 1 },
 140         [23] = { BTN_A, 0 },
 141         [11] = { BTN_B, 1 },
 142         [21] = { BTN_B, 0 },
 143         [24] = { BTN_C, 1 },
 144         [9] = { BTN_C, 0 },
 145         [13] = { BTN_X, 1 },
 146         [17] = { BTN_X, 0 },
 147         [12] = { BTN_Y, 1 },
 148         [16] = { BTN_Y, 0 },
 149         [14] = { BTN_Z, 1 },
 150         [19] = { BTN_Z, 0 },
 151         [18] = { BTN_THUMBL, 1 },
 152         [10] = { BTN_THUMBL, 0 },
 153         [15] = { BTN_THUMBR, 1 },
 154         [25] = { BTN_THUMBR, 0 },
 155 };
 156 
 157 static const struct icade_key *icade_find_translation(u16 from)
 158 {
 159         if (from > ICADE_MAX_USAGE)
 160                 return NULL;
 161         return &icade_usage_table[from];
 162 }
 163 
 164 static int icade_event(struct hid_device *hdev, struct hid_field *field,
 165                 struct hid_usage *usage, __s32 value)
 166 {
 167         const struct icade_key *trans;
 168 
 169         if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
 170                         !usage->type)
 171                 return 0;
 172 
 173         /* We ignore the fake key up, and act only on key down */
 174         if (!value)
 175                 return 1;
 176 
 177         trans = icade_find_translation(usage->hid & HID_USAGE);
 178 
 179         if (!trans)
 180                 return 1;
 181 
 182         input_event(field->hidinput->input, usage->type,
 183                         trans->to, trans->press);
 184 
 185         return 1;
 186 }
 187 
 188 static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 189                 struct hid_field *field, struct hid_usage *usage,
 190                 unsigned long **bit, int *max)
 191 {
 192         const struct icade_key *trans;
 193 
 194         if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
 195                 trans = icade_find_translation(usage->hid & HID_USAGE);
 196 
 197                 if (!trans)
 198                         return -1;
 199 
 200                 hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to);
 201                 set_bit(trans->to, hi->input->keybit);
 202 
 203                 return 1;
 204         }
 205 
 206         /* ignore others */
 207         return -1;
 208 
 209 }
 210 
 211 static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 212                 struct hid_field *field, struct hid_usage *usage,
 213                 unsigned long **bit, int *max)
 214 {
 215         if (usage->type == EV_KEY)
 216                 set_bit(usage->type, hi->input->evbit);
 217 
 218         return -1;
 219 }
 220 
 221 static const struct hid_device_id icade_devices[] = {
 222         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
 223 
 224         { }
 225 };
 226 MODULE_DEVICE_TABLE(hid, icade_devices);
 227 
 228 static struct hid_driver icade_driver = {
 229         .name = "icade",
 230         .id_table = icade_devices,
 231         .event = icade_event,
 232         .input_mapped = icade_input_mapped,
 233         .input_mapping = icade_input_mapping,
 234 };
 235 module_hid_driver(icade_driver);
 236 
 237 MODULE_LICENSE("GPL");
 238 MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
 239 MODULE_DESCRIPTION("ION iCade input driver");

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