aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/joystick/a3d.c88
1 files changed, 46 insertions, 42 deletions
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index 4571ea3a4b92..4612d13ea756 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -57,7 +57,7 @@ static char *a3d_names[] = { NULL, "FP-Gaming Assassin 3D", "MadCatz Panther", "
57struct a3d { 57struct a3d {
58 struct gameport *gameport; 58 struct gameport *gameport;
59 struct gameport *adc; 59 struct gameport *adc;
60 struct input_dev dev; 60 struct input_dev *dev;
61 int axes[4]; 61 int axes[4];
62 int buttons; 62 int buttons;
63 int mode; 63 int mode;
@@ -115,7 +115,7 @@ static int a3d_csum(char *data, int count)
115 115
116static void a3d_read(struct a3d *a3d, unsigned char *data) 116static void a3d_read(struct a3d *a3d, unsigned char *data)
117{ 117{
118 struct input_dev *dev = &a3d->dev; 118 struct input_dev *dev = a3d->dev;
119 119
120 switch (a3d->mode) { 120 switch (a3d->mode) {
121 121
@@ -265,14 +265,20 @@ static void a3d_close(struct input_dev *dev)
265static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) 265static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
266{ 266{
267 struct a3d *a3d; 267 struct a3d *a3d;
268 struct input_dev *input_dev;
268 struct gameport *adc; 269 struct gameport *adc;
269 unsigned char data[A3D_MAX_LENGTH]; 270 unsigned char data[A3D_MAX_LENGTH];
270 int i; 271 int i;
271 int err; 272 int err;
272 273
273 if (!(a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL))) 274 a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL);
274 return -ENOMEM; 275 input_dev = input_allocate_device();
276 if (!a3d || !input_dev) {
277 err = -ENOMEM;
278 goto fail1;
279 }
275 280
281 a3d->dev = input_dev;
276 a3d->gameport = gameport; 282 a3d->gameport = gameport;
277 283
278 gameport_set_drvdata(gameport, a3d); 284 gameport_set_drvdata(gameport, a3d);
@@ -302,42 +308,48 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
302 308
303 sprintf(a3d->phys, "%s/input0", gameport->phys); 309 sprintf(a3d->phys, "%s/input0", gameport->phys);
304 310
311 input_dev->name = a3d_names[a3d->mode];
312 input_dev->phys = a3d->phys;
313 input_dev->id.bustype = BUS_GAMEPORT;
314 input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
315 input_dev->id.product = a3d->mode;
316 input_dev->id.version = 0x0100;
317 input_dev->cdev.dev = &gameport->dev;
318 input_dev->private = a3d;
319 input_dev->open = a3d_open;
320 input_dev->close = a3d_close;
321
305 if (a3d->mode == A3D_MODE_PXL) { 322 if (a3d->mode == A3D_MODE_PXL) {
306 323
307 int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; 324 int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER };
308 325
309 a3d->length = 33; 326 a3d->length = 33;
310 327
311 init_input_dev(&a3d->dev); 328 input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
312 329 input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
313 a3d->dev.evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); 330 input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
314 a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y); 331 | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
315 a3d->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER) 332 input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
316 | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y); 333 | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
317 334 input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP)
318 a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE) 335 | BIT(BTN_PINKIE);
319 | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
320
321 a3d->dev.keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_PINKIE);
322 336
323 a3d_read(a3d, data); 337 a3d_read(a3d, data);
324 338
325 for (i = 0; i < 4; i++) { 339 for (i = 0; i < 4; i++) {
326 if (i < 2) 340 if (i < 2)
327 input_set_abs_params(&a3d->dev, axes[i], 48, a3d->dev.abs[axes[i]] * 2 - 48, 0, 8); 341 input_set_abs_params(input_dev, axes[i], 48, input_dev->abs[axes[i]] * 2 - 48, 0, 8);
328 else 342 else
329 input_set_abs_params(&a3d->dev, axes[i], 2, 253, 0, 0); 343 input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0);
330 input_set_abs_params(&a3d->dev, ABS_HAT0X + i, -1, 1, 0, 0); 344 input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
331 } 345 }
332 346
333 } else { 347 } else {
334 a3d->length = 29; 348 a3d->length = 29;
335 349
336 init_input_dev(&a3d->dev); 350 input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
337 351 input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
338 a3d->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL); 352 input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
339 a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y);
340 a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
341 353
342 a3d_read(a3d, data); 354 a3d_read(a3d, data);
343 355
@@ -358,24 +370,17 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
358 } 370 }
359 } 371 }
360 372
361 a3d->dev.private = a3d; 373 err = input_register_device(a3d->dev);
362 a3d->dev.open = a3d_open; 374 if (err)
363 a3d->dev.close = a3d_close; 375 goto fail3;
364
365 a3d->dev.name = a3d_names[a3d->mode];
366 a3d->dev.phys = a3d->phys;
367 a3d->dev.id.bustype = BUS_GAMEPORT;
368 a3d->dev.id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
369 a3d->dev.id.product = a3d->mode;
370 a3d->dev.id.version = 0x0100;
371
372 input_register_device(&a3d->dev);
373 printk(KERN_INFO "input: %s on %s\n", a3d_names[a3d->mode], a3d->phys);
374 376
375 return 0; 377 return 0;
376 378
377fail2: gameport_close(gameport); 379 fail3: if (a3d->adc)
378fail1: gameport_set_drvdata(gameport, NULL); 380 gameport_unregister_port(a3d->adc);
381 fail2: gameport_close(gameport);
382 fail1: gameport_set_drvdata(gameport, NULL);
383 input_free_device(input_dev);
379 kfree(a3d); 384 kfree(a3d);
380 return err; 385 return err;
381} 386}
@@ -384,11 +389,9 @@ static void a3d_disconnect(struct gameport *gameport)
384{ 389{
385 struct a3d *a3d = gameport_get_drvdata(gameport); 390 struct a3d *a3d = gameport_get_drvdata(gameport);
386 391
387 input_unregister_device(&a3d->dev); 392 input_unregister_device(a3d->dev);
388 if (a3d->adc) { 393 if (a3d->adc)
389 gameport_unregister_port(a3d->adc); 394 gameport_unregister_port(a3d->adc);
390 a3d->adc = NULL;
391 }
392 gameport_close(gameport); 395 gameport_close(gameport);
393 gameport_set_drvdata(gameport, NULL); 396 gameport_set_drvdata(gameport, NULL);
394 kfree(a3d); 397 kfree(a3d);
@@ -397,6 +400,7 @@ static void a3d_disconnect(struct gameport *gameport)
397static struct gameport_driver a3d_drv = { 400static struct gameport_driver a3d_drv = {
398 .driver = { 401 .driver = {
399 .name = "adc", 402 .name = "adc",
403 .owner = THIS_MODULE,
400 }, 404 },
401 .description = DRIVER_DESC, 405 .description = DRIVER_DESC,
402 .connect = a3d_connect, 406 .connect = a3d_connect,