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.18-rc4 523 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 = kzalloc(sizeof(struct lgff_device), GFP_KERNEL); 158 if (!private) 159 return -1; 160 hid->ff_private = private; 161 162 /* Input init */ 163 hid_lgff_input_init(hid); 164 165 166 private->constant = hid_lgff_duplicate_report(report); 167 if (!private->constant) { 168 kfree(private); 169 return -1; 170 } 171 private->constant->field[0]->value[0] = 0x51; 172 private->constant->field[0]->value[1] = 0x08; 173 private->constant->field[0]->value[2] = 0x7f; 174 private->constant->field[0]->value[3] = 0x7f; 175 176 private->rumble = hid_lgff_duplicate_report(report); 177 if (!private->rumble) { 178 hid_lgff_delete_report(private->constant); 179 kfree(private); 180 return -1; 181 } 182 private->rumble->field[0]->value[0] = 0x42; 183 184 185 private->condition = hid_lgff_duplicate_report(report); 186 if (!private->condition) { 187 hid_lgff_delete_report(private->rumble); 188 hid_lgff_delete_report(private->constant); 189 kfree(private); 190 return -1; 191 } 192 193 private->hid = hid; 194 195 spin_lock_init(&private->lock); 196 init_timer(&private->timer); 197 private->timer.data = (unsigned long)private; 198 private->timer.function = hid_lgff_timer; 199 200 /* Event and exit callbacks */ 201 hid->ff_exit = hid_lgff_exit; 202 hid->ff_event = hid_lgff_event; 203 204 /* Start the update task */ 205 private->timer.expires = RUN_AT(PERIOD); 206 add_timer(&private->timer); /*TODO: only run the timer when at least 207 one effect is playing */ 208 209 printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n"); 210 211 return 0; 212} 213 214static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report) 215{ 216 struct hid_report* ret; 217 218 ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL); 219 if (!ret) 220 return NULL; 221 *ret = *report; 222 223 ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL); 224 if (!ret->field[0]) { 225 kfree(ret); 226 return NULL; 227 } 228 *ret->field[0] = *report->field[0]; 229 230 ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL); 231 if (!ret->field[0]->value) { 232 kfree(ret->field[0]); 233 kfree(ret); 234 return NULL; 235 } 236 237 return ret; 238} 239 240static void hid_lgff_delete_report(struct hid_report* report) 241{ 242 if (report) { 243 kfree(report->field[0]->value); 244 kfree(report->field[0]); 245 kfree(report); 246 } 247} 248 249static void hid_lgff_input_init(struct hid_device* hid) 250{ 251 struct device_type* dev = devices; 252 signed short* ff; 253 u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor); 254 u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct); 255 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); 256 struct input_dev *input_dev = hidinput->input; 257 258 while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct)) 259 dev++; 260 261 for (ff = dev->ff; *ff >= 0; ff++) 262 set_bit(*ff, input_dev->ffbit); 263 264 input_dev->upload_effect = hid_lgff_upload_effect; 265 input_dev->flush = hid_lgff_flush; 266 267 set_bit(EV_FF, input_dev->evbit); 268 input_dev->ff_effects_max = LGFF_EFFECTS; 269} 270 271static void hid_lgff_exit(struct hid_device* hid) 272{ 273 struct lgff_device *lgff = hid->ff_private; 274 275 set_bit(DEVICE_CLOSING, lgff->flags); 276 del_timer_sync(&lgff->timer); 277 278 hid_lgff_delete_report(lgff->condition); 279 hid_lgff_delete_report(lgff->rumble); 280 hid_lgff_delete_report(lgff->constant); 281 282 kfree(lgff); 283} 284 285static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, 286 unsigned int type, unsigned int code, int value) 287{ 288 struct lgff_device *lgff = hid->ff_private; 289 struct lgff_effect *effect = lgff->effects + code; 290 unsigned long flags; 291 292 if (type != EV_FF) return -EINVAL; 293 if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES; 294 if (value < 0) return -EINVAL; 295 296 spin_lock_irqsave(&lgff->lock, flags); 297 298 if (value > 0) { 299 if (test_bit(EFFECT_STARTED, effect->flags)) { 300 spin_unlock_irqrestore(&lgff->lock, flags); 301 return -EBUSY; 302 } 303 if (test_bit(EFFECT_PLAYING, effect->flags)) { 304 spin_unlock_irqrestore(&lgff->lock, flags); 305 return -EBUSY; 306 } 307 308 effect->count = value; 309 310 if (effect->effect.replay.delay) { 311 set_bit(EFFECT_STARTED, effect->flags); 312 } else { 313 set_bit(EFFECT_PLAYING, effect->flags); 314 } 315 effect->started_at = jiffies; 316 } 317 else { /* value == 0 */ 318 clear_bit(EFFECT_STARTED, effect->flags); 319 clear_bit(EFFECT_PLAYING, effect->flags); 320 } 321 322 spin_unlock_irqrestore(&lgff->lock, flags); 323 324 return 0; 325 326} 327 328/* Erase all effects this process owns */ 329static int hid_lgff_flush(struct input_dev *dev, struct file *file) 330{ 331 struct hid_device *hid = dev->private; 332 struct lgff_device *lgff = hid->ff_private; 333 int i; 334 335 for (i=0; i<dev->ff_effects_max; ++i) { 336 337 /*NOTE: no need to lock here. The only times EFFECT_USED is 338 modified is when effects are uploaded or when an effect is 339 erased. But a process cannot close its dev/input/eventX fd 340 and perform ioctls on the same fd all at the same time */ 341 if ( current->pid == lgff->effects[i].owner 342 && test_bit(EFFECT_USED, lgff->effects[i].flags)) { 343 344 if (hid_lgff_erase(dev, i)) 345 warn("erase effect %d failed", i); 346 } 347 348 } 349 350 return 0; 351} 352 353static int hid_lgff_erase(struct input_dev *dev, int id) 354{ 355 struct hid_device *hid = dev->private; 356 struct lgff_device *lgff = hid->ff_private; 357 unsigned long flags; 358 359 if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES; 360 361 spin_lock_irqsave(&lgff->lock, flags); 362 lgff->effects[id].flags[0] = 0; 363 spin_unlock_irqrestore(&lgff->lock, flags); 364 365 return 0; 366} 367 368static int hid_lgff_upload_effect(struct input_dev* input, 369 struct ff_effect* effect) 370{ 371 struct hid_device *hid = input->private; 372 struct lgff_device *lgff = hid->ff_private; 373 struct lgff_effect new; 374 int id; 375 unsigned long flags; 376 377 dbg("ioctl rumble"); 378 379 if (!test_bit(effect->type, input->ffbit)) return -EINVAL; 380 381 spin_lock_irqsave(&lgff->lock, flags); 382 383 if (effect->id == -1) { 384 int i; 385 386 for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i); 387 if (i >= LGFF_EFFECTS) { 388 spin_unlock_irqrestore(&lgff->lock, flags); 389 return -ENOSPC; 390 } 391 392 effect->id = i; 393 lgff->effects[i].owner = current->pid; 394 lgff->effects[i].flags[0] = 0; 395 set_bit(EFFECT_USED, lgff->effects[i].flags); 396 } 397 else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) { 398 spin_unlock_irqrestore(&lgff->lock, flags); 399 return -EACCES; 400 } 401 402 id = effect->id; 403 new = lgff->effects[id]; 404 405 new.effect = *effect; 406 407 if (test_bit(EFFECT_STARTED, lgff->effects[id].flags) 408 || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) { 409 410 /* Changing replay parameters is not allowed (for the time 411 being) */ 412 if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay 413 || new.effect.replay.length != lgff->effects[id].effect.replay.length) { 414 spin_unlock_irqrestore(&lgff->lock, flags); 415 return -ENOSYS; 416 } 417 418 lgff->effects[id] = new; 419 420 } else { 421 lgff->effects[id] = new; 422 } 423 424 spin_unlock_irqrestore(&lgff->lock, flags); 425 return 0; 426} 427 428static void hid_lgff_timer(unsigned long timer_data) 429{ 430 struct lgff_device *lgff = (struct lgff_device*)timer_data; 431 struct hid_device *hid = lgff->hid; 432 unsigned long flags; 433 int x = 0x7f, y = 0x7f; // Coordinates of constant effects 434 unsigned int left = 0, right = 0; // Rumbling 435 int i; 436 437 spin_lock_irqsave(&lgff->lock, flags); 438 439 for (i=0; i<LGFF_EFFECTS; ++i) { 440 struct lgff_effect* effect = lgff->effects +i; 441 442 if (test_bit(EFFECT_PLAYING, effect->flags)) { 443 444 switch (effect->effect.type) { 445 case FF_CONSTANT: { 446 //TODO: handle envelopes 447 int degrees = effect->effect.direction * 360 >> 16; 448 x += fixp_mult(fixp_sin(degrees), 449 fixp_new16(effect->effect.u.constant.level)); 450 y += fixp_mult(-fixp_cos(degrees), 451 fixp_new16(effect->effect.u.constant.level)); 452 } break; 453 case FF_RUMBLE: 454 right += effect->effect.u.rumble.strong_magnitude; 455 left += effect->effect.u.rumble.weak_magnitude; 456 break; 457 }; 458 459 /* One run of the effect is finished playing */ 460 if (time_after(jiffies, 461 effect->started_at 462 + effect->effect.replay.delay*HZ/1000 463 + effect->effect.replay.length*HZ/1000)) { 464 dbg("Finished playing once %d", i); 465 if (--effect->count <= 0) { 466 dbg("Stopped %d", i); 467 clear_bit(EFFECT_PLAYING, effect->flags); 468 } 469 else { 470 dbg("Start again %d", i); 471 if (effect->effect.replay.length != 0) { 472 clear_bit(EFFECT_PLAYING, effect->flags); 473 set_bit(EFFECT_STARTED, effect->flags); 474 } 475 effect->started_at = jiffies; 476 } 477 } 478 479 } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) { 480 /* Check if we should start playing the effect */ 481 if (time_after(jiffies, 482 lgff->effects[i].started_at 483 + lgff->effects[i].effect.replay.delay*HZ/1000)) { 484 dbg("Now playing %d", i); 485 clear_bit(EFFECT_STARTED, lgff->effects[i].flags); 486 set_bit(EFFECT_PLAYING, lgff->effects[i].flags); 487 } 488 } 489 } 490 491#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff 492 493 // Clamp values 494 CLAMP(x); 495 CLAMP(y); 496 CLAMP(left); 497 CLAMP(right); 498 499#undef CLAMP 500 501 if (x != lgff->constant->field[0]->value[2] 502 || y != lgff->constant->field[0]->value[3]) { 503 lgff->constant->field[0]->value[2] = x; 504 lgff->constant->field[0]->value[3] = y; 505 dbg("(x,y)=(%04x, %04x)", x, y); 506 hid_submit_report(hid, lgff->constant, USB_DIR_OUT); 507 } 508 509 if (left != lgff->rumble->field[0]->value[2] 510 || right != lgff->rumble->field[0]->value[3]) { 511 lgff->rumble->field[0]->value[2] = left; 512 lgff->rumble->field[0]->value[3] = right; 513 dbg("(left,right)=(%04x, %04x)", left, right); 514 hid_submit_report(hid, lgff->rumble, USB_DIR_OUT); 515 } 516 517 if (!test_bit(DEVICE_CLOSING, lgff->flags)) { 518 lgff->timer.expires = RUN_AT(PERIOD); 519 add_timer(&lgff->timer); 520 } 521 522 spin_unlock_irqrestore(&lgff->lock, flags); 523}