aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/input
diff options
context:
space:
mode:
authorPeter Stokes <linux@dadeos.freeserve.co.uk>2007-04-12 01:33:10 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-04-12 01:33:10 -0400
commita1421d3c780c373d5f74a0ab99b0652041d61876 (patch)
tree83575af2572ecc4a66e77563150d0ca9502e8390 /drivers/usb/input
parent1b726a02d97cef2471521ae6947416f7374c6590 (diff)
Input: add logical channel support for ATI Remote Wonder II
The ATI Remote Wonder II can be configured with one of 16 unique logical channels. Allowing up to 16 remotes to be used independently within range of each other. This change adds functionality to configure the receiver and filter the input data to respond or exclude remotes configured with different logical channels. Signed-off-by: Peter Stokes <linux@dadeos.freeserve.co.uk> Acked-by: Ville Syrjala <syrjala@sci.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/usb/input')
-rw-r--r--drivers/usb/input/ati_remote2.c89
1 files changed, 80 insertions, 9 deletions
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
index 83f1f79db7c7..6459be90599c 100644
--- a/drivers/usb/input/ati_remote2.c
+++ b/drivers/usb/input/ati_remote2.c
@@ -2,6 +2,7 @@
2 * ati_remote2 - ATI/Philips USB RF remote driver 2 * ati_remote2 - ATI/Philips USB RF remote driver
3 * 3 *
4 * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> 4 * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
5 * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 8 * it under the terms of the GNU General Public License version 2
@@ -11,13 +12,29 @@
11#include <linux/usb/input.h> 12#include <linux/usb/input.h>
12 13
13#define DRIVER_DESC "ATI/Philips USB RF remote driver" 14#define DRIVER_DESC "ATI/Philips USB RF remote driver"
14#define DRIVER_VERSION "0.1" 15#define DRIVER_VERSION "0.2"
15 16
16MODULE_DESCRIPTION(DRIVER_DESC); 17MODULE_DESCRIPTION(DRIVER_DESC);
17MODULE_VERSION(DRIVER_VERSION); 18MODULE_VERSION(DRIVER_VERSION);
18MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); 19MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
19MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
20 21
22/*
23 * ATI Remote Wonder II Channel Configuration
24 *
25 * The remote control can by assigned one of sixteen "channels" in order to facilitate
26 * the use of multiple remote controls within range of each other.
27 * A remote's "channel" may be altered by pressing and holding the "PC" button for
28 * approximately 3 seconds, after which the button will slowly flash the count of the
29 * currently configured "channel", using the numeric keypad enter a number between 1 and
30 * 16 and then the "PC" button again, the button will slowly flash the count of the
31 * newly configured "channel".
32 */
33
34static unsigned int channel_mask = 0xFFFF;
35module_param(channel_mask, uint, 0644);
36MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
37
21static unsigned int mode_mask = 0x1F; 38static unsigned int mode_mask = 0x1F;
22module_param(mode_mask, uint, 0644); 39module_param(mode_mask, uint, 0644);
23MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); 40MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
@@ -146,15 +163,23 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
146{ 163{
147 struct input_dev *idev = ar2->idev; 164 struct input_dev *idev = ar2->idev;
148 u8 *data = ar2->buf[0]; 165 u8 *data = ar2->buf[0];
166 int channel, mode;
167
168 channel = data[0] >> 4;
169
170 if (!((1 << channel) & channel_mask))
171 return;
149 172
150 if (data[0] > 4) { 173 mode = data[0] & 0x0F;
174
175 if (mode > 4) {
151 dev_err(&ar2->intf[0]->dev, 176 dev_err(&ar2->intf[0]->dev,
152 "Unknown mode byte (%02x %02x %02x %02x)\n", 177 "Unknown mode byte (%02x %02x %02x %02x)\n",
153 data[3], data[2], data[1], data[0]); 178 data[3], data[2], data[1], data[0]);
154 return; 179 return;
155 } 180 }
156 181
157 if (!((1 << data[0]) & mode_mask)) 182 if (!((1 << mode) & mode_mask))
158 return; 183 return;
159 184
160 input_event(idev, EV_REL, REL_X, (s8) data[1]); 185 input_event(idev, EV_REL, REL_X, (s8) data[1]);
@@ -177,9 +202,16 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
177{ 202{
178 struct input_dev *idev = ar2->idev; 203 struct input_dev *idev = ar2->idev;
179 u8 *data = ar2->buf[1]; 204 u8 *data = ar2->buf[1];
180 int hw_code, index; 205 int channel, mode, hw_code, index;
206
207 channel = data[0] >> 4;
208
209 if (!((1 << channel) & channel_mask))
210 return;
181 211
182 if (data[0] > 4) { 212 mode = data[0] & 0x0F;
213
214 if (mode > 4) {
183 dev_err(&ar2->intf[1]->dev, 215 dev_err(&ar2->intf[1]->dev,
184 "Unknown mode byte (%02x %02x %02x %02x)\n", 216 "Unknown mode byte (%02x %02x %02x %02x)\n",
185 data[3], data[2], data[1], data[0]); 217 data[3], data[2], data[1], data[0]);
@@ -199,16 +231,16 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
199 * events for the mouse pad so we filter out any subsequent 231 * events for the mouse pad so we filter out any subsequent
200 * events from the same mode key. 232 * events from the same mode key.
201 */ 233 */
202 if (ar2->mode == data[0]) 234 if (ar2->mode == mode)
203 return; 235 return;
204 236
205 if (data[1] == 0) 237 if (data[1] == 0)
206 ar2->mode = data[0]; 238 ar2->mode = mode;
207 239
208 hw_code |= data[0] << 8; 240 hw_code |= mode << 8;
209 } 241 }
210 242
211 if (!((1 << data[0]) & mode_mask)) 243 if (!((1 << mode) & mode_mask))
212 return; 244 return;
213 245
214 index = ati_remote2_lookup(hw_code); 246 index = ati_remote2_lookup(hw_code);
@@ -379,6 +411,41 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
379 } 411 }
380} 412}
381 413
414static int ati_remote2_setup(struct ati_remote2 *ar2)
415{
416 int r, i, channel;
417
418 /*
419 * Configure receiver to only accept input from remote "channel"
420 * channel == 0 -> Accept input from any remote channel
421 * channel == 1 -> Only accept input from remote channel 1
422 * channel == 2 -> Only accept input from remote channel 2
423 * ...
424 * channel == 16 -> Only accept input from remote channel 16
425 */
426
427 channel = 0;
428 for (i = 0; i < 16; i++) {
429 if ((1 << i) & channel_mask) {
430 if (!(~(1 << i) & 0xFFFF & channel_mask))
431 channel = i + 1;
432 break;
433 }
434 }
435
436 r = usb_control_msg(ar2->udev, usb_sndctrlpipe(ar2->udev, 0),
437 0x20,
438 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
439 channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT);
440 if (r) {
441 dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n",
442 __FUNCTION__, r);
443 return r;
444 }
445
446 return 0;
447}
448
382static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) 449static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
383{ 450{
384 struct usb_device *udev = interface_to_usbdev(interface); 451 struct usb_device *udev = interface_to_usbdev(interface);
@@ -409,6 +476,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
409 if (r) 476 if (r)
410 goto fail2; 477 goto fail2;
411 478
479 r = ati_remote2_setup(ar2);
480 if (r)
481 goto fail2;
482
412 usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); 483 usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
413 strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); 484 strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
414 485