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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.15-rc1 525 lines 14 kB view raw
1/* 2 * $$ 3 * 4 * Force feedback support for hid-compliant for some of the devices from 5 * Logitech, namely: 6 * - WingMan Cordless RumblePad 7 * - WingMan Force 3D 8 * 9 * Copyright (c) 2002-2004 Johann Deneux 10 */ 11 12/* 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * 27 * Should you need to contact me, the author, you can do so by 28 * e-mail - mail your message to <johann.deneux@it.uu.se> 29 */ 30 31#include <linux/input.h> 32#include <linux/sched.h> 33 34//#define DEBUG 35#include <linux/usb.h> 36 37#include <linux/circ_buf.h> 38 39#include "hid.h" 40#include "fixp-arith.h" 41 42 43/* Periodicity of the update */ 44#define PERIOD (HZ/10) 45 46#define RUN_AT(t) (jiffies + (t)) 47 48/* Effect status */ 49#define EFFECT_STARTED 0 /* Effect is going to play after some time 50 (ff_replay.delay) */ 51#define EFFECT_PLAYING 1 /* Effect is being played */ 52#define EFFECT_USED 2 53 54// For lgff_device::flags 55#define DEVICE_CLOSING 0 /* The driver is being unitialised */ 56 57/* Check that the current process can access an effect */ 58#define CHECK_OWNERSHIP(effect) (current->pid == 0 \ 59 || effect.owner == current->pid) 60 61#define LGFF_CHECK_OWNERSHIP(i, l) \ 62 (i>=0 && i<LGFF_EFFECTS \ 63 && test_bit(EFFECT_USED, l->effects[i].flags) \ 64 && CHECK_OWNERSHIP(l->effects[i])) 65 66#define LGFF_EFFECTS 8 67 68struct device_type { 69 u16 idVendor; 70 u16 idProduct; 71 signed short *ff; 72}; 73 74struct lgff_effect { 75 pid_t owner; 76 77 struct ff_effect effect; 78 79 unsigned long flags[1]; 80 unsigned int count; /* Number of times left to play */ 81 unsigned long started_at; /* When the effect started to play */ 82}; 83 84struct lgff_device { 85 struct hid_device* hid; 86 87 struct hid_report* constant; 88 struct hid_report* rumble; 89 struct hid_report* condition; 90 91 struct lgff_effect effects[LGFF_EFFECTS]; 92 spinlock_t lock; /* device-level lock. Having locks on 93 a per-effect basis could be nice, but 94 isn't really necessary */ 95 96 unsigned long flags[1]; /* Contains various information about the 97 state of the driver for this device */ 98 99 struct timer_list timer; 100}; 101 102/* Callbacks */ 103static void hid_lgff_exit(struct hid_device* hid); 104static int hid_lgff_event(struct hid_device *hid, struct input_dev *input, 105 unsigned int type, unsigned int code, int value); 106static int hid_lgff_flush(struct input_dev *input, struct file *file); 107static int hid_lgff_upload_effect(struct input_dev *input, 108 struct ff_effect *effect); 109static int hid_lgff_erase(struct input_dev *input, int id); 110 111/* Local functions */ 112static void hid_lgff_input_init(struct hid_device* hid); 113static void hid_lgff_timer(unsigned long timer_data); 114static struct hid_report* hid_lgff_duplicate_report(struct hid_report*); 115static void hid_lgff_delete_report(struct hid_report*); 116 117static signed short ff_rumble[] = { 118 FF_RUMBLE, 119 -1 120}; 121 122static signed short ff_joystick[] = { 123 FF_CONSTANT, 124 -1 125}; 126 127static struct device_type devices[] = { 128 {0x046d, 0xc211, ff_rumble}, 129 {0x046d, 0xc219, ff_rumble}, 130 {0x046d, 0xc283, ff_joystick}, 131 {0x0000, 0x0000, ff_joystick} 132}; 133 134int hid_lgff_init(struct hid_device* hid) 135{ 136 struct lgff_device *private; 137 struct hid_report* report; 138 struct hid_field* field; 139 140 /* Find the report to use */ 141 if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) { 142 err("No output report found"); 143 return -1; 144 } 145 /* Check that the report looks ok */ 146 report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next; 147 if (!report) { 148 err("NULL output report"); 149 return -1; 150 } 151 field = report->field[0]; 152 if (!field) { 153 err("NULL field"); 154 return -1; 155 } 156 157 private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); 158 if (!private) 159 return -1; 160 memset(private, 0, sizeof(struct lgff_device)); 161 hid->ff_private = private; 162 163 /* Input init */ 164 hid_lgff_input_init(hid); 165 166 167 private->constant = hid_lgff_duplicate_report(report); 168 if (!private->constant) { 169 kfree(private); 170 return -1; 171 } 172 private->constant->field[0]->value[0] = 0x51; 173 private->constant->field[0]->value[1] = 0x08; 174 private->constant->field[0]->value[2] = 0x7f; 175 private->constant->field[0]->value[3] = 0x7f; 176 177 private->rumble = hid_lgff_duplicate_report(report); 178 if (!private->rumble) { 179 hid_lgff_delete_report(private->constant); 180 kfree(private); 181 return -1; 182 } 183 private->rumble->field[0]->value[0] = 0x42; 184 185 186 private->condition = hid_lgff_duplicate_report(report); 187 if (!private->condition) { 188 hid_lgff_delete_report(private->rumble); 189 hid_lgff_delete_report(private->constant); 190 kfree(private); 191 return -1; 192 } 193 194 private->hid = hid; 195 196 spin_lock_init(&private->lock); 197 init_timer(&private->timer); 198 private->timer.data = (unsigned long)private; 199 private->timer.function = hid_lgff_timer; 200 201 /* Event and exit callbacks */ 202 hid->ff_exit = hid_lgff_exit; 203 hid->ff_event = hid_lgff_event; 204 205 /* Start the update task */ 206 private->timer.expires = RUN_AT(PERIOD); 207 add_timer(&private->timer); /*TODO: only run the timer when at least 208 one effect is playing */ 209 210 printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n"); 211 212 return 0; 213} 214 215static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report) 216{ 217 struct hid_report* ret; 218 219 ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); 220 if (!ret) 221 return NULL; 222 *ret = *report; 223 224 ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL); 225 if (!ret->field[0]) { 226 kfree(ret); 227 return NULL; 228 } 229 *ret->field[0] = *report->field[0]; 230 231 ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL); 232 if (!ret->field[0]->value) { 233 kfree(ret->field[0]); 234 kfree(ret); 235 return NULL; 236 } 237 memset(ret->field[0]->value, 0, sizeof(s32[8])); 238 239 return ret; 240} 241 242static void hid_lgff_delete_report(struct hid_report* report) 243{ 244 if (report) { 245 kfree(report->field[0]->value); 246 kfree(report->field[0]); 247 kfree(report); 248 } 249} 250 251static void hid_lgff_input_init(struct hid_device* hid) 252{ 253 struct device_type* dev = devices; 254 signed short* ff; 255 u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor); 256 u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct); 257 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); 258 struct input_dev *input_dev = hidinput->input; 259 260 while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct)) 261 dev++; 262 263 for (ff = dev->ff; *ff >= 0; ff++) 264 set_bit(*ff, input_dev->ffbit); 265 266 input_dev->upload_effect = hid_lgff_upload_effect; 267 input_dev->flush = hid_lgff_flush; 268 269 set_bit(EV_FF, input_dev->evbit); 270 input_dev->ff_effects_max = LGFF_EFFECTS; 271} 272 273static void hid_lgff_exit(struct hid_device* hid) 274{ 275 struct lgff_device *lgff = hid->ff_private; 276 277 set_bit(DEVICE_CLOSING, lgff->flags); 278 del_timer_sync(&lgff->timer); 279 280 hid_lgff_delete_report(lgff->condition); 281 hid_lgff_delete_report(lgff->rumble); 282 hid_lgff_delete_report(lgff->constant); 283 284 kfree(lgff); 285} 286 287static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, 288 unsigned int type, unsigned int code, int value) 289{ 290 struct lgff_device *lgff = hid->ff_private; 291 struct lgff_effect *effect = lgff->effects + code; 292 unsigned long flags; 293 294 if (type != EV_FF) return -EINVAL; 295 if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES; 296 if (value < 0) return -EINVAL; 297 298 spin_lock_irqsave(&lgff->lock, flags); 299 300 if (value > 0) { 301 if (test_bit(EFFECT_STARTED, effect->flags)) { 302 spin_unlock_irqrestore(&lgff->lock, flags); 303 return -EBUSY; 304 } 305 if (test_bit(EFFECT_PLAYING, effect->flags)) { 306 spin_unlock_irqrestore(&lgff->lock, flags); 307 return -EBUSY; 308 } 309 310 effect->count = value; 311 312 if (effect->effect.replay.delay) { 313 set_bit(EFFECT_STARTED, effect->flags); 314 } else { 315 set_bit(EFFECT_PLAYING, effect->flags); 316 } 317 effect->started_at = jiffies; 318 } 319 else { /* value == 0 */ 320 clear_bit(EFFECT_STARTED, effect->flags); 321 clear_bit(EFFECT_PLAYING, effect->flags); 322 } 323 324 spin_unlock_irqrestore(&lgff->lock, flags); 325 326 return 0; 327 328} 329 330/* Erase all effects this process owns */ 331static int hid_lgff_flush(struct input_dev *dev, struct file *file) 332{ 333 struct hid_device *hid = dev->private; 334 struct lgff_device *lgff = hid->ff_private; 335 int i; 336 337 for (i=0; i<dev->ff_effects_max; ++i) { 338 339 /*NOTE: no need to lock here. The only times EFFECT_USED is 340 modified is when effects are uploaded or when an effect is 341 erased. But a process cannot close its dev/input/eventX fd 342 and perform ioctls on the same fd all at the same time */ 343 if ( current->pid == lgff->effects[i].owner 344 && test_bit(EFFECT_USED, lgff->effects[i].flags)) { 345 346 if (hid_lgff_erase(dev, i)) 347 warn("erase effect %d failed", i); 348 } 349 350 } 351 352 return 0; 353} 354 355static int hid_lgff_erase(struct input_dev *dev, int id) 356{ 357 struct hid_device *hid = dev->private; 358 struct lgff_device *lgff = hid->ff_private; 359 unsigned long flags; 360 361 if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES; 362 363 spin_lock_irqsave(&lgff->lock, flags); 364 lgff->effects[id].flags[0] = 0; 365 spin_unlock_irqrestore(&lgff->lock, flags); 366 367 return 0; 368} 369 370static int hid_lgff_upload_effect(struct input_dev* input, 371 struct ff_effect* effect) 372{ 373 struct hid_device *hid = input->private; 374 struct lgff_device *lgff = hid->ff_private; 375 struct lgff_effect new; 376 int id; 377 unsigned long flags; 378 379 dbg("ioctl rumble"); 380 381 if (!test_bit(effect->type, input->ffbit)) return -EINVAL; 382 383 spin_lock_irqsave(&lgff->lock, flags); 384 385 if (effect->id == -1) { 386 int i; 387 388 for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i); 389 if (i >= LGFF_EFFECTS) { 390 spin_unlock_irqrestore(&lgff->lock, flags); 391 return -ENOSPC; 392 } 393 394 effect->id = i; 395 lgff->effects[i].owner = current->pid; 396 lgff->effects[i].flags[0] = 0; 397 set_bit(EFFECT_USED, lgff->effects[i].flags); 398 } 399 else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) { 400 spin_unlock_irqrestore(&lgff->lock, flags); 401 return -EACCES; 402 } 403 404 id = effect->id; 405 new = lgff->effects[id]; 406 407 new.effect = *effect; 408 409 if (test_bit(EFFECT_STARTED, lgff->effects[id].flags) 410 || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) { 411 412 /* Changing replay parameters is not allowed (for the time 413 being) */ 414 if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay 415 || new.effect.replay.length != lgff->effects[id].effect.replay.length) { 416 spin_unlock_irqrestore(&lgff->lock, flags); 417 return -ENOSYS; 418 } 419 420 lgff->effects[id] = new; 421 422 } else { 423 lgff->effects[id] = new; 424 } 425 426 spin_unlock_irqrestore(&lgff->lock, flags); 427 return 0; 428} 429 430static void hid_lgff_timer(unsigned long timer_data) 431{ 432 struct lgff_device *lgff = (struct lgff_device*)timer_data; 433 struct hid_device *hid = lgff->hid; 434 unsigned long flags; 435 int x = 0x7f, y = 0x7f; // Coordinates of constant effects 436 unsigned int left = 0, right = 0; // Rumbling 437 int i; 438 439 spin_lock_irqsave(&lgff->lock, flags); 440 441 for (i=0; i<LGFF_EFFECTS; ++i) { 442 struct lgff_effect* effect = lgff->effects +i; 443 444 if (test_bit(EFFECT_PLAYING, effect->flags)) { 445 446 switch (effect->effect.type) { 447 case FF_CONSTANT: { 448 //TODO: handle envelopes 449 int degrees = effect->effect.direction * 360 >> 16; 450 x += fixp_mult(fixp_sin(degrees), 451 fixp_new16(effect->effect.u.constant.level)); 452 y += fixp_mult(-fixp_cos(degrees), 453 fixp_new16(effect->effect.u.constant.level)); 454 } break; 455 case FF_RUMBLE: 456 right += effect->effect.u.rumble.strong_magnitude; 457 left += effect->effect.u.rumble.weak_magnitude; 458 break; 459 }; 460 461 /* One run of the effect is finished playing */ 462 if (time_after(jiffies, 463 effect->started_at 464 + effect->effect.replay.delay*HZ/1000 465 + effect->effect.replay.length*HZ/1000)) { 466 dbg("Finished playing once %d", i); 467 if (--effect->count <= 0) { 468 dbg("Stopped %d", i); 469 clear_bit(EFFECT_PLAYING, effect->flags); 470 } 471 else { 472 dbg("Start again %d", i); 473 if (effect->effect.replay.length != 0) { 474 clear_bit(EFFECT_PLAYING, effect->flags); 475 set_bit(EFFECT_STARTED, effect->flags); 476 } 477 effect->started_at = jiffies; 478 } 479 } 480 481 } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) { 482 /* Check if we should start playing the effect */ 483 if (time_after(jiffies, 484 lgff->effects[i].started_at 485 + lgff->effects[i].effect.replay.delay*HZ/1000)) { 486 dbg("Now playing %d", i); 487 clear_bit(EFFECT_STARTED, lgff->effects[i].flags); 488 set_bit(EFFECT_PLAYING, lgff->effects[i].flags); 489 } 490 } 491 } 492 493#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff 494 495 // Clamp values 496 CLAMP(x); 497 CLAMP(y); 498 CLAMP(left); 499 CLAMP(right); 500 501#undef CLAMP 502 503 if (x != lgff->constant->field[0]->value[2] 504 || y != lgff->constant->field[0]->value[3]) { 505 lgff->constant->field[0]->value[2] = x; 506 lgff->constant->field[0]->value[3] = y; 507 dbg("(x,y)=(%04x, %04x)", x, y); 508 hid_submit_report(hid, lgff->constant, USB_DIR_OUT); 509 } 510 511 if (left != lgff->rumble->field[0]->value[2] 512 || right != lgff->rumble->field[0]->value[3]) { 513 lgff->rumble->field[0]->value[2] = left; 514 lgff->rumble->field[0]->value[3] = right; 515 dbg("(left,right)=(%04x, %04x)", left, right); 516 hid_submit_report(hid, lgff->rumble, USB_DIR_OUT); 517 } 518 519 if (!test_bit(DEVICE_CLOSING, lgff->flags)) { 520 lgff->timer.expires = RUN_AT(PERIOD); 521 add_timer(&lgff->timer); 522 } 523 524 spin_unlock_irqrestore(&lgff->lock, flags); 525}