Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: ati_remote2: Add channel support

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>

authored by

Peter Stokes and committed by
Greg Kroah-Hartman
13f6be01 ebcf3ede

+80 -9
+80 -9
drivers/usb/input/ati_remote2.c
··· 2 2 * ati_remote2 - ATI/Philips USB RF remote driver 3 3 * 4 4 * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> 5 + * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License version 2 ··· 12 11 #include <linux/usb/input.h> 13 12 14 13 #define DRIVER_DESC "ATI/Philips USB RF remote driver" 15 - #define DRIVER_VERSION "0.1" 14 + #define DRIVER_VERSION "0.2" 16 15 17 16 MODULE_DESCRIPTION(DRIVER_DESC); 18 17 MODULE_VERSION(DRIVER_VERSION); 19 18 MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); 20 19 MODULE_LICENSE("GPL"); 20 + 21 + /* 22 + * ATI Remote Wonder II Channel Configuration 23 + * 24 + * The remote control can by assigned one of sixteen "channels" in order to facilitate 25 + * the use of multiple remote controls within range of each other. 26 + * A remote's "channel" may be altered by pressing and holding the "PC" button for 27 + * approximately 3 seconds, after which the button will slowly flash the count of the 28 + * currently configured "channel", using the numeric keypad enter a number between 1 and 29 + * 16 and then the "PC" button again, the button will slowly flash the count of the 30 + * newly configured "channel". 31 + */ 32 + 33 + static unsigned int channel_mask = 0xFFFF; 34 + module_param(channel_mask, uint, 0644); 35 + MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); 21 36 22 37 static unsigned int mode_mask = 0x1F; 23 38 module_param(mode_mask, uint, 0644); ··· 163 146 { 164 147 struct input_dev *idev = ar2->idev; 165 148 u8 *data = ar2->buf[0]; 149 + int channel, mode; 166 150 167 - if (data[0] > 4) { 151 + channel = data[0] >> 4; 152 + 153 + if (!((1 << channel) & channel_mask)) 154 + return; 155 + 156 + mode = data[0] & 0x0F; 157 + 158 + if (mode > 4) { 168 159 dev_err(&ar2->intf[0]->dev, 169 160 "Unknown mode byte (%02x %02x %02x %02x)\n", 170 161 data[3], data[2], data[1], data[0]); 171 162 return; 172 163 } 173 164 174 - if (!((1 << data[0]) & mode_mask)) 165 + if (!((1 << mode) & mode_mask)) 175 166 return; 176 167 177 168 input_event(idev, EV_REL, REL_X, (s8) data[1]); ··· 202 177 { 203 178 struct input_dev *idev = ar2->idev; 204 179 u8 *data = ar2->buf[1]; 205 - int hw_code, index; 180 + int channel, mode, hw_code, index; 206 181 207 - if (data[0] > 4) { 182 + channel = data[0] >> 4; 183 + 184 + if (!((1 << channel) & channel_mask)) 185 + return; 186 + 187 + mode = data[0] & 0x0F; 188 + 189 + if (mode > 4) { 208 190 dev_err(&ar2->intf[1]->dev, 209 191 "Unknown mode byte (%02x %02x %02x %02x)\n", 210 192 data[3], data[2], data[1], data[0]); ··· 231 199 * events for the mouse pad so we filter out any subsequent 232 200 * events from the same mode key. 233 201 */ 234 - if (ar2->mode == data[0]) 202 + if (ar2->mode == mode) 235 203 return; 236 204 237 205 if (data[1] == 0) 238 - ar2->mode = data[0]; 206 + ar2->mode = mode; 239 207 240 - hw_code |= data[0] << 8; 208 + hw_code |= mode << 8; 241 209 } 242 210 243 - if (!((1 << data[0]) & mode_mask)) 211 + if (!((1 << mode) & mode_mask)) 244 212 return; 245 213 246 214 index = ati_remote2_lookup(hw_code); ··· 411 379 } 412 380 } 413 381 382 + static int ati_remote2_setup(struct ati_remote2 *ar2) 383 + { 384 + int r, i, channel; 385 + 386 + /* 387 + * Configure receiver to only accept input from remote "channel" 388 + * channel == 0 -> Accept input from any remote channel 389 + * channel == 1 -> Only accept input from remote channel 1 390 + * channel == 2 -> Only accept input from remote channel 2 391 + * ... 392 + * channel == 16 -> Only accept input from remote channel 16 393 + */ 394 + 395 + channel = 0; 396 + for (i = 0; i < 16; i++) { 397 + if ((1 << i) & channel_mask) { 398 + if (!(~(1 << i) & 0xFFFF & channel_mask)) 399 + channel = i + 1; 400 + break; 401 + } 402 + } 403 + 404 + r = usb_control_msg(ar2->udev, usb_sndctrlpipe(ar2->udev, 0), 405 + 0x20, 406 + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 407 + channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT); 408 + if (r) { 409 + dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n", 410 + __FUNCTION__, r); 411 + return r; 412 + } 413 + 414 + return 0; 415 + } 416 + 414 417 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) 415 418 { 416 419 struct usb_device *udev = interface_to_usbdev(interface); ··· 473 406 ar2->ep[1] = &alt->endpoint[0].desc; 474 407 475 408 r = ati_remote2_urb_init(ar2); 409 + if (r) 410 + goto fail2; 411 + 412 + r = ati_remote2_setup(ar2); 476 413 if (r) 477 414 goto fail2; 478 415