ae659c5011e6dc0a8a8e9f43a635e74228d6c97c
[oweals/openwrt.git] /
1 From fdedf53c61516a26f1b7efa85ca8b09ff7067af7 Mon Sep 17 00:00:00 2001
2 From: Hanno Zulla <abos@hanno.de>
3 Date: Thu, 23 Aug 2018 17:03:38 +0200
4 Subject: [PATCH 168/782] HID: hid-bigbenff: driver for BigBen Interactive
5  PS3OFMINIPAD gamepad
6
7 commit 256a90ed9e46b270bbc4e15ef05216ff049c3721 upstream.
8
9 This is a driver to fix input mapping and add LED & force feedback
10 support for the "BigBen Interactive Kid-friendly Wired Controller
11 PS3OFMINIPAD SONY" gamepad with USB id 146b:0902. It was originally
12 sold as a PS3 accessory and makes a very nice gamepad for Retropie.
13
14 Signed-off-by: Hanno Zulla <kontakt@hanno.de>
15 Signed-off-by: Jiri Kosina <jkosina@suse.cz>
16 ---
17  drivers/hid/Kconfig        |  13 ++
18  drivers/hid/Makefile       |   1 +
19  drivers/hid/hid-bigbenff.c | 414 +++++++++++++++++++++++++++++++++++++
20  drivers/hid/hid-ids.h      |   3 +
21  4 files changed, 431 insertions(+)
22  create mode 100644 drivers/hid/hid-bigbenff.c
23
24 --- a/drivers/hid/Kconfig
25 +++ b/drivers/hid/Kconfig
26 @@ -182,6 +182,19 @@ config HID_BETOP_FF
27         Currently the following devices are known to be supported:
28          - BETOP 2185 PC & BFM MODE
29  
30 +config HID_BIGBEN_FF
31 +       tristate "BigBen Interactive Kids' gamepad support"
32 +       depends on USB_HID
33 +       depends on NEW_LEDS
34 +       depends on LEDS_CLASS
35 +       select INPUT_FF_MEMLESS
36 +       default !EXPERT
37 +       help
38 +         Support for the "Kid-friendly Wired Controller" PS3OFMINIPAD
39 +         gamepad made by BigBen Interactive, originally sold as a PS3
40 +         accessory. This driver fixes input mapping and adds support for
41 +         force feedback effects and LEDs on the device.
42 +
43  config HID_CHERRY
44         tristate "Cherry Cymotion keyboard"
45         depends on HID
46 --- a/drivers/hid/Makefile
47 +++ b/drivers/hid/Makefile
48 @@ -31,6 +31,7 @@ obj-$(CONFIG_HID_ASUS)                += hid-asus.o
49  obj-$(CONFIG_HID_AUREAL)       += hid-aureal.o
50  obj-$(CONFIG_HID_BELKIN)       += hid-belkin.o
51  obj-$(CONFIG_HID_BETOP_FF)     += hid-betopff.o
52 +obj-$(CONFIG_HID_BIGBEN_FF)    += hid-bigbenff.o
53  obj-$(CONFIG_HID_CHERRY)       += hid-cherry.o
54  obj-$(CONFIG_HID_CHICONY)      += hid-chicony.o
55  obj-$(CONFIG_HID_CMEDIA)       += hid-cmedia.o
56 --- /dev/null
57 +++ b/drivers/hid/hid-bigbenff.c
58 @@ -0,0 +1,414 @@
59 +// SPDX-License-Identifier: GPL-2.0+
60 +
61 +/*
62 + *  LED & force feedback support for BigBen Interactive
63 + *
64 + *  0x146b:0x0902 "Bigben Interactive Bigben Game Pad"
65 + *  "Kid-friendly Wired Controller" PS3OFMINIPAD SONY
66 + *  sold for use with the PS3
67 + *
68 + *  Copyright (c) 2018 Hanno Zulla <kontakt@hanno.de>
69 + */
70 +
71 +#include <linux/input.h>
72 +#include <linux/slab.h>
73 +#include <linux/module.h>
74 +#include <linux/leds.h>
75 +#include <linux/hid.h>
76 +
77 +#include "hid-ids.h"
78 +
79 +
80 +/*
81 + * The original descriptor for 0x146b:0x0902
82 + *
83 + *   0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
84 + *   0x09, 0x05,        // Usage (Game Pad)
85 + *   0xA1, 0x01,        // Collection (Application)
86 + *   0x15, 0x00,        //   Logical Minimum (0)
87 + *   0x25, 0x01,        //   Logical Maximum (1)
88 + *   0x35, 0x00,        //   Physical Minimum (0)
89 + *   0x45, 0x01,        //   Physical Maximum (1)
90 + *   0x75, 0x01,        //   Report Size (1)
91 + *   0x95, 0x0D,        //   Report Count (13)
92 + *   0x05, 0x09,        //   Usage Page (Button)
93 + *   0x19, 0x01,        //   Usage Minimum (0x01)
94 + *   0x29, 0x0D,        //   Usage Maximum (0x0D)
95 + *   0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
96 + *   0x95, 0x03,        //   Report Count (3)
97 + *   0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
98 + *   0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
99 + *   0x25, 0x07,        //   Logical Maximum (7)
100 + *   0x46, 0x3B, 0x01,  //   Physical Maximum (315)
101 + *   0x75, 0x04,        //   Report Size (4)
102 + *   0x95, 0x01,        //   Report Count (1)
103 + *   0x65, 0x14,        //   Unit (System: English Rotation, Length: Centimeter)
104 + *   0x09, 0x39,        //   Usage (Hat switch)
105 + *   0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
106 + *   0x65, 0x00,        //   Unit (None)
107 + *   0x95, 0x01,        //   Report Count (1)
108 + *   0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
109 + *   0x26, 0xFF, 0x00,  //   Logical Maximum (255)
110 + *   0x46, 0xFF, 0x00,  //   Physical Maximum (255)
111 + *   0x09, 0x30,        //   Usage (X)
112 + *   0x09, 0x31,        //   Usage (Y)
113 + *   0x09, 0x32,        //   Usage (Z)
114 + *   0x09, 0x35,        //   Usage (Rz)
115 + *   0x75, 0x08,        //   Report Size (8)
116 + *   0x95, 0x04,        //   Report Count (4)
117 + *   0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
118 + *   0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
119 + *   0x09, 0x20,        //   Usage (0x20)
120 + *   0x09, 0x21,        //   Usage (0x21)
121 + *   0x09, 0x22,        //   Usage (0x22)
122 + *   0x09, 0x23,        //   Usage (0x23)
123 + *   0x09, 0x24,        //   Usage (0x24)
124 + *   0x09, 0x25,        //   Usage (0x25)
125 + *   0x09, 0x26,        //   Usage (0x26)
126 + *   0x09, 0x27,        //   Usage (0x27)
127 + *   0x09, 0x28,        //   Usage (0x28)
128 + *   0x09, 0x29,        //   Usage (0x29)
129 + *   0x09, 0x2A,        //   Usage (0x2A)
130 + *   0x09, 0x2B,        //   Usage (0x2B)
131 + *   0x95, 0x0C,        //   Report Count (12)
132 + *   0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
133 + *   0x0A, 0x21, 0x26,  //   Usage (0x2621)
134 + *   0x95, 0x08,        //   Report Count (8)
135 + *   0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
136 + *   0x0A, 0x21, 0x26,  //   Usage (0x2621)
137 + *   0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
138 + *   0x26, 0xFF, 0x03,  //   Logical Maximum (1023)
139 + *   0x46, 0xFF, 0x03,  //   Physical Maximum (1023)
140 + *   0x09, 0x2C,        //   Usage (0x2C)
141 + *   0x09, 0x2D,        //   Usage (0x2D)
142 + *   0x09, 0x2E,        //   Usage (0x2E)
143 + *   0x09, 0x2F,        //   Usage (0x2F)
144 + *   0x75, 0x10,        //   Report Size (16)
145 + *   0x95, 0x04,        //   Report Count (4)
146 + *   0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
147 + *   0xC0,              // End Collection
148 + */
149 +
150 +#define PID0902_RDESC_ORIG_SIZE 137
151 +
152 +/*
153 + * The fixed descriptor for 0x146b:0x0902
154 + *
155 + * - map buttons according to gamepad.rst
156 + * - assign right stick from Z/Rz to Rx/Ry
157 + * - map previously unused analog trigger data to Z/RZ
158 + * - simplify feature and output descriptor
159 + */
160 +static __u8 pid0902_rdesc_fixed[] = {
161 +       0x05, 0x01,        /* Usage Page (Generic Desktop Ctrls) */
162 +       0x09, 0x05,        /* Usage (Game Pad) */
163 +       0xA1, 0x01,        /* Collection (Application) */
164 +       0x15, 0x00,        /*   Logical Minimum (0) */
165 +       0x25, 0x01,        /*   Logical Maximum (1) */
166 +       0x35, 0x00,        /*   Physical Minimum (0) */
167 +       0x45, 0x01,        /*   Physical Maximum (1) */
168 +       0x75, 0x01,        /*   Report Size (1) */
169 +       0x95, 0x0D,        /*   Report Count (13) */
170 +       0x05, 0x09,        /*   Usage Page (Button) */
171 +       0x09, 0x05,        /*   Usage (BTN_WEST) */
172 +       0x09, 0x01,        /*   Usage (BTN_SOUTH) */
173 +       0x09, 0x02,        /*   Usage (BTN_EAST) */
174 +       0x09, 0x04,        /*   Usage (BTN_NORTH) */
175 +       0x09, 0x07,        /*   Usage (BTN_TL) */
176 +       0x09, 0x08,        /*   Usage (BTN_TR) */
177 +       0x09, 0x09,        /*   Usage (BTN_TL2) */
178 +       0x09, 0x0A,        /*   Usage (BTN_TR2) */
179 +       0x09, 0x0B,        /*   Usage (BTN_SELECT) */
180 +       0x09, 0x0C,        /*   Usage (BTN_START) */
181 +       0x09, 0x0E,        /*   Usage (BTN_THUMBL) */
182 +       0x09, 0x0F,        /*   Usage (BTN_THUMBR) */
183 +       0x09, 0x0D,        /*   Usage (BTN_MODE) */
184 +       0x81, 0x02,        /*   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
185 +       0x75, 0x01,        /*   Report Size (1) */
186 +       0x95, 0x03,        /*   Report Count (3) */
187 +       0x81, 0x01,        /*   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */
188 +       0x05, 0x01,        /*   Usage Page (Generic Desktop Ctrls) */
189 +       0x25, 0x07,        /*   Logical Maximum (7) */
190 +       0x46, 0x3B, 0x01,  /*   Physical Maximum (315) */
191 +       0x75, 0x04,        /*   Report Size (4) */
192 +       0x95, 0x01,        /*   Report Count (1) */
193 +       0x65, 0x14,        /*   Unit (System: English Rotation, Length: Centimeter) */
194 +       0x09, 0x39,        /*   Usage (Hat switch) */
195 +       0x81, 0x42,        /*   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) */
196 +       0x65, 0x00,        /*   Unit (None) */
197 +       0x95, 0x01,        /*   Report Count (1) */
198 +       0x81, 0x01,        /*   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */
199 +       0x26, 0xFF, 0x00,  /*   Logical Maximum (255) */
200 +       0x46, 0xFF, 0x00,  /*   Physical Maximum (255) */
201 +       0x09, 0x30,        /*   Usage (X) */
202 +       0x09, 0x31,        /*   Usage (Y) */
203 +       0x09, 0x33,        /*   Usage (Rx) */
204 +       0x09, 0x34,        /*   Usage (Ry) */
205 +       0x75, 0x08,        /*   Report Size (8) */
206 +       0x95, 0x04,        /*   Report Count (4) */
207 +       0x81, 0x02,        /*   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
208 +       0x95, 0x0A,        /*   Report Count (10) */
209 +       0x81, 0x01,        /*   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */
210 +       0x05, 0x01,        /*   Usage Page (Generic Desktop Ctrls) */
211 +       0x26, 0xFF, 0x00,  /*   Logical Maximum (255) */
212 +       0x46, 0xFF, 0x00,  /*   Physical Maximum (255) */
213 +       0x09, 0x32,        /*   Usage (Z) */
214 +       0x09, 0x35,        /*   Usage (Rz) */
215 +       0x95, 0x02,        /*   Report Count (2) */
216 +       0x81, 0x02,        /*   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
217 +       0x95, 0x08,        /*   Report Count (8) */
218 +       0x81, 0x01,        /*   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */
219 +       0x06, 0x00, 0xFF,  /*   Usage Page (Vendor Defined 0xFF00) */
220 +       0xB1, 0x02,        /*   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
221 +       0x0A, 0x21, 0x26,  /*   Usage (0x2621) */
222 +       0x95, 0x08,        /*   Report Count (8) */
223 +       0x91, 0x02,        /*   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) */
224 +       0x0A, 0x21, 0x26,  /*   Usage (0x2621) */
225 +       0x95, 0x08,        /*   Report Count (8) */
226 +       0x81, 0x02,        /*   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) */
227 +       0xC0,              /* End Collection */
228 +};
229 +
230 +#define NUM_LEDS 4
231 +
232 +struct bigben_device {
233 +       struct hid_device *hid;
234 +       struct hid_report *report;
235 +       u8 led_state;         /* LED1 = 1 .. LED4 = 8 */
236 +       u8 right_motor_on;    /* right motor off/on 0/1 */
237 +       u8 left_motor_force;  /* left motor force 0-255 */
238 +       struct led_classdev *leds[NUM_LEDS];
239 +       bool work_led;
240 +       bool work_ff;
241 +       struct work_struct worker;
242 +};
243 +
244 +
245 +static void bigben_worker(struct work_struct *work)
246 +{
247 +       struct bigben_device *bigben = container_of(work,
248 +               struct bigben_device, worker);
249 +       struct hid_field *report_field = bigben->report->field[0];
250 +
251 +       if (bigben->work_led) {
252 +               bigben->work_led = false;
253 +               report_field->value[0] = 0x01; /* 1 = led message */
254 +               report_field->value[1] = 0x08; /* reserved value, always 8 */
255 +               report_field->value[2] = bigben->led_state;
256 +               report_field->value[3] = 0x00; /* padding */
257 +               report_field->value[4] = 0x00; /* padding */
258 +               report_field->value[5] = 0x00; /* padding */
259 +               report_field->value[6] = 0x00; /* padding */
260 +               report_field->value[7] = 0x00; /* padding */
261 +               hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
262 +       }
263 +
264 +       if (bigben->work_ff) {
265 +               bigben->work_ff = false;
266 +               report_field->value[0] = 0x02; /* 2 = rumble effect message */
267 +               report_field->value[1] = 0x08; /* reserved value, always 8 */
268 +               report_field->value[2] = bigben->right_motor_on;
269 +               report_field->value[3] = bigben->left_motor_force;
270 +               report_field->value[4] = 0xff; /* duration 0-254 (255 = nonstop) */
271 +               report_field->value[5] = 0x00; /* padding */
272 +               report_field->value[6] = 0x00; /* padding */
273 +               report_field->value[7] = 0x00; /* padding */
274 +               hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT);
275 +       }
276 +}
277 +
278 +static int hid_bigben_play_effect(struct input_dev *dev, void *data,
279 +                        struct ff_effect *effect)
280 +{
281 +       struct bigben_device *bigben = data;
282 +       u8 right_motor_on;
283 +       u8 left_motor_force;
284 +
285 +       if (effect->type != FF_RUMBLE)
286 +               return 0;
287 +
288 +       right_motor_on   = effect->u.rumble.weak_magnitude ? 1 : 0;
289 +       left_motor_force = effect->u.rumble.strong_magnitude / 256;
290 +
291 +       if (right_motor_on != bigben->right_motor_on ||
292 +                       left_motor_force != bigben->left_motor_force) {
293 +               bigben->right_motor_on   = right_motor_on;
294 +               bigben->left_motor_force = left_motor_force;
295 +               bigben->work_ff = true;
296 +               schedule_work(&bigben->worker);
297 +       }
298 +
299 +       return 0;
300 +}
301 +
302 +static void bigben_set_led(struct led_classdev *led,
303 +       enum led_brightness value)
304 +{
305 +       struct device *dev = led->dev->parent;
306 +       struct hid_device *hid = to_hid_device(dev);
307 +       struct bigben_device *bigben = hid_get_drvdata(hid);
308 +       int n;
309 +       bool work;
310 +
311 +       if (!bigben) {
312 +               hid_err(hid, "no device data\n");
313 +               return;
314 +       }
315 +
316 +       for (n = 0; n < NUM_LEDS; n++) {
317 +               if (led == bigben->leds[n]) {
318 +                       if (value == LED_OFF) {
319 +                               work = (bigben->led_state & BIT(n));
320 +                               bigben->led_state &= ~BIT(n);
321 +                       } else {
322 +                               work = !(bigben->led_state & BIT(n));
323 +                               bigben->led_state |= BIT(n);
324 +                       }
325 +
326 +                       if (work) {
327 +                               bigben->work_led = true;
328 +                               schedule_work(&bigben->worker);
329 +                       }
330 +                       return;
331 +               }
332 +       }
333 +}
334 +
335 +static enum led_brightness bigben_get_led(struct led_classdev *led)
336 +{
337 +       struct device *dev = led->dev->parent;
338 +       struct hid_device *hid = to_hid_device(dev);
339 +       struct bigben_device *bigben = hid_get_drvdata(hid);
340 +       int n;
341 +
342 +       if (!bigben) {
343 +               hid_err(hid, "no device data\n");
344 +               return LED_OFF;
345 +       }
346 +
347 +       for (n = 0; n < NUM_LEDS; n++) {
348 +               if (led == bigben->leds[n])
349 +                       return (bigben->led_state & BIT(n)) ? LED_ON : LED_OFF;
350 +       }
351 +
352 +       return LED_OFF;
353 +}
354 +
355 +static void bigben_remove(struct hid_device *hid)
356 +{
357 +       struct bigben_device *bigben = hid_get_drvdata(hid);
358 +
359 +       cancel_work_sync(&bigben->worker);
360 +       hid_hw_close(hid);
361 +       hid_hw_stop(hid);
362 +}
363 +
364 +static int bigben_probe(struct hid_device *hid,
365 +       const struct hid_device_id *id)
366 +{
367 +       struct bigben_device *bigben;
368 +       struct hid_input *hidinput;
369 +       struct list_head *report_list;
370 +       struct led_classdev *led;
371 +       char *name;
372 +       size_t name_sz;
373 +       int n, error;
374 +
375 +       bigben = devm_kzalloc(&hid->dev, sizeof(*bigben), GFP_KERNEL);
376 +       if (!bigben)
377 +               return -ENOMEM;
378 +       hid_set_drvdata(hid, bigben);
379 +       bigben->hid = hid;
380 +
381 +       error = hid_parse(hid);
382 +       if (error) {
383 +               hid_err(hid, "parse failed\n");
384 +               return error;
385 +       }
386 +
387 +       error = hid_hw_start(hid, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
388 +       if (error) {
389 +               hid_err(hid, "hw start failed\n");
390 +               return error;
391 +       }
392 +
393 +       report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
394 +       bigben->report = list_entry(report_list->next,
395 +               struct hid_report, list);
396 +
397 +       hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
398 +       set_bit(FF_RUMBLE, hidinput->input->ffbit);
399 +
400 +       INIT_WORK(&bigben->worker, bigben_worker);
401 +
402 +       error = input_ff_create_memless(hidinput->input, bigben,
403 +               hid_bigben_play_effect);
404 +       if (error)
405 +               return error;
406 +
407 +       name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1;
408 +
409 +       for (n = 0; n < NUM_LEDS; n++) {
410 +               led = devm_kzalloc(
411 +                       &hid->dev,
412 +                       sizeof(struct led_classdev) + name_sz,
413 +                       GFP_KERNEL
414 +               );
415 +               if (!led)
416 +                       return -ENOMEM;
417 +               name = (void *)(&led[1]);
418 +               snprintf(name, name_sz,
419 +                       "%s:red:bigben%d",
420 +                       dev_name(&hid->dev), n + 1
421 +               );
422 +               led->name = name;
423 +               led->brightness = (n == 0) ? LED_ON : LED_OFF;
424 +               led->max_brightness = 1;
425 +               led->brightness_get = bigben_get_led;
426 +               led->brightness_set = bigben_set_led;
427 +               bigben->leds[n] = led;
428 +               error = devm_led_classdev_register(&hid->dev, led);
429 +               if (error)
430 +                       return error;
431 +       }
432 +
433 +       /* initial state: LED1 is on, no rumble effect */
434 +       bigben->led_state = BIT(0);
435 +       bigben->right_motor_on = 0;
436 +       bigben->left_motor_force = 0;
437 +       bigben->work_led = true;
438 +       bigben->work_ff = true;
439 +       schedule_work(&bigben->worker);
440 +
441 +       hid_info(hid, "LED and force feedback support for BigBen gamepad\n");
442 +
443 +       return 0;
444 +}
445 +
446 +static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc,
447 +       unsigned int *rsize)
448 +{
449 +       if (*rsize == PID0902_RDESC_ORIG_SIZE) {
450 +               rdesc = pid0902_rdesc_fixed;
451 +               *rsize = sizeof(pid0902_rdesc_fixed);
452 +       } else
453 +               hid_warn(hid, "unexpected rdesc, please submit for review\n");
454 +       return rdesc;
455 +}
456 +
457 +static const struct hid_device_id bigben_devices[] = {
458 +       { HID_USB_DEVICE(USB_VENDOR_ID_BIGBEN, USB_DEVICE_ID_BIGBEN_PS3OFMINIPAD) },
459 +       { }
460 +};
461 +MODULE_DEVICE_TABLE(hid, bigben_devices);
462 +
463 +static struct hid_driver bigben_driver = {
464 +       .name = "bigben",
465 +       .id_table = bigben_devices,
466 +       .probe = bigben_probe,
467 +       .report_fixup = bigben_report_fixup,
468 +       .remove = bigben_remove,
469 +};
470 +module_hid_driver(bigben_driver);
471 +
472 +MODULE_LICENSE("GPL");
473 --- a/drivers/hid/hid-ids.h
474 +++ b/drivers/hid/hid-ids.h
475 @@ -233,6 +233,9 @@
476  #define USB_VENDOR_ID_BETOP_2185V2PC   0x8380
477  #define USB_VENDOR_ID_BETOP_2185V2BFM  0x20bc
478  
479 +#define USB_VENDOR_ID_BIGBEN   0x146b
480 +#define USB_DEVICE_ID_BIGBEN_PS3OFMINIPAD      0x0902
481 +
482  #define USB_VENDOR_ID_BTC              0x046e
483  #define USB_DEVICE_ID_BTC_EMPREX_REMOTE        0x5578
484  #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2      0x5577