2 * $Id: iforce.c,v 1.7 2000/06/04 14:03:36 vojtech Exp $
4 * Copyright (c) 2000 Vojtech Pavlik
6 * USB/RS232 I-Force joysticks and wheels.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Should you need to contact me, the author, you can do so either by
27 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
28 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
31 #include <linux/kernel.h>
32 #include <linux/malloc.h>
33 #include <linux/input.h>
34 #include <linux/module.h>
35 #include <linux/init.h>
36 #include <linux/usb.h>
37 #include <linux/serio.h>
38 #include <linux/config.h>
40 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
41 MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
43 #define USB_VENDOR_ID_LOGITECH 0x046d
44 #define USB_DEVICE_ID_LOGITECH_WMFORCE 0xc281
46 #define IFORCE_MAX_LENGTH 16
48 #if defined(CONFIG_INPUT_IFORCE_232) || defined(CONFIG_INPUT_IFORCE_232_MODULE)
51 #if defined(CONFIG_INPUT_IFORCE_USB) || defined(CONFIG_INPUT_IFORCE_USB_MODULE)
56 signed char data
[IFORCE_MAX_LENGTH
];
60 int idx
, pkt
, len
, id
;
67 } iforce_hat_to_axis
[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
69 static char *iforce_name
= "I-Force joystick/wheel";
71 static void iforce_process_packet(struct input_dev
*dev
, unsigned char id
, int idx
, unsigned char *data
)
75 case 1: /* joystick position data */
76 case 3: /* wheel position data */
79 input_report_abs(dev
, ABS_X
, (__s16
) (((__s16
)data
[1] << 8) | data
[0]));
80 input_report_abs(dev
, ABS_Y
, (__s16
) (((__s16
)data
[3] << 8) | data
[2]));
81 input_report_abs(dev
, ABS_THROTTLE
, 255 - data
[4]);
83 input_report_abs(dev
, ABS_WHEEL
, (__s16
) (((__s16
)data
[1] << 8) | data
[0]));
84 input_report_abs(dev
, ABS_GAS
, 255 - data
[2]);
85 input_report_abs(dev
, ABS_BRAKE
, 255 - data
[3]);
88 input_report_abs(dev
, ABS_HAT0X
, iforce_hat_to_axis
[data
[6] >> 4].x
);
89 input_report_abs(dev
, ABS_HAT0Y
, iforce_hat_to_axis
[data
[6] >> 4].y
);
91 input_report_key(dev
, BTN_TRIGGER
, data
[5] & 0x01);
92 input_report_key(dev
, BTN_TOP
, data
[5] & 0x02);
93 input_report_key(dev
, BTN_THUMB
, data
[5] & 0x04);
94 input_report_key(dev
, BTN_TOP2
, data
[5] & 0x08);
95 input_report_key(dev
, BTN_BASE
, data
[5] & 0x10);
96 input_report_key(dev
, BTN_BASE2
, data
[5] & 0x20);
97 input_report_key(dev
, BTN_BASE3
, data
[5] & 0x40);
98 input_report_key(dev
, BTN_BASE4
, data
[5] & 0x80);
99 input_report_key(dev
, BTN_BASE5
, data
[6] & 0x01);
100 input_report_key(dev
, BTN_A
, data
[6] & 0x02);
101 input_report_key(dev
, BTN_B
, data
[6] & 0x04);
102 input_report_key(dev
, BTN_C
, data
[6] & 0x08);
105 case 2: /* force feedback effect status */
111 static int iforce_open(struct input_dev
*dev
)
113 struct iforce
*iforce
= dev
->private;
115 if (dev
->idbus
== BUS_USB
&& !iforce
->open
++)
116 if (usb_submit_urb(&iforce
->irq
))
122 static void iforce_close(struct input_dev
*dev
)
124 struct iforce
*iforce
= dev
->private;
126 if (dev
->idbus
== BUS_USB
&& !--iforce
->open
)
127 usb_unlink_urb(&iforce
->irq
);
130 static void iforce_input_setup(struct iforce
*iforce
)
134 iforce
->dev
.evbit
[0] = BIT(EV_KEY
) | BIT(EV_ABS
);
135 iforce
->dev
.keybit
[LONG(BTN_JOYSTICK
)] |= BIT(BTN_TRIGGER
) | BIT(BTN_TOP
) | BIT(BTN_THUMB
) | BIT(BTN_TOP2
) |
136 BIT(BTN_BASE
) | BIT(BTN_BASE2
) | BIT(BTN_BASE3
) | BIT(BTN_BASE4
) | BIT(BTN_BASE5
);
137 iforce
->dev
.keybit
[LONG(BTN_GAMEPAD
)] |= BIT(BTN_A
) | BIT(BTN_B
) | BIT(BTN_C
);
138 iforce
->dev
.absbit
[0] = BIT(ABS_X
) | BIT(ABS_Y
) | BIT(ABS_THROTTLE
) | BIT(ABS_HAT0X
) | BIT(ABS_HAT0Y
)
139 | BIT(ABS_WHEEL
) | BIT(ABS_GAS
) | BIT(ABS_BRAKE
);
141 for (i
= ABS_X
; i
<= ABS_Y
; i
++) {
142 iforce
->dev
.absmax
[i
] = 1920;
143 iforce
->dev
.absmin
[i
] = -1920;
144 iforce
->dev
.absflat
[i
] = 128;
145 iforce
->dev
.absfuzz
[i
] = 16;
148 for (i
= ABS_THROTTLE
; i
<= ABS_RUDDER
; i
++) {
149 iforce
->dev
.absmax
[i
] = 255;
150 iforce
->dev
.absmin
[i
] = 0;
153 for (i
= ABS_HAT0X
; i
<= ABS_HAT0Y
; i
++) {
154 iforce
->dev
.absmax
[i
] = 1;
155 iforce
->dev
.absmin
[i
] = -1;
158 iforce
->dev
.private = iforce
;
159 iforce
->dev
.open
= iforce_open
;
160 iforce
->dev
.close
= iforce_close
;
162 input_register_device(&iforce
->dev
);
167 static void iforce_usb_irq(struct urb
*urb
)
169 struct iforce
*iforce
= urb
->context
;
170 if (urb
->status
) return;
171 iforce_process_packet(&iforce
->dev
, iforce
->data
[0], 8, iforce
->data
+ 1);
174 static void *iforce_usb_probe(struct usb_device
*dev
, unsigned int ifnum
)
176 struct usb_endpoint_descriptor
*endpoint
;
177 struct iforce
*iforce
;
179 if (dev
->descriptor
.idVendor
!= USB_VENDOR_ID_LOGITECH
||
180 dev
->descriptor
.idProduct
!= USB_DEVICE_ID_LOGITECH_WMFORCE
)
183 endpoint
= dev
->config
[0].interface
[ifnum
].altsetting
[0].endpoint
+ 0;
185 if (!(iforce
= kmalloc(sizeof(struct iforce
), GFP_KERNEL
))) return NULL
;
186 memset(iforce
, 0, sizeof(struct iforce
));
188 iforce
->dev
.name
= iforce_name
;
189 iforce
->dev
.idbus
= BUS_USB
;
190 iforce
->dev
.idvendor
= dev
->descriptor
.idVendor
;
191 iforce
->dev
.idproduct
= dev
->descriptor
.idProduct
;
192 iforce
->dev
.idversion
= dev
->descriptor
.bcdDevice
;
194 FILL_INT_URB(&iforce
->irq
, dev
, usb_rcvintpipe(dev
, endpoint
->bEndpointAddress
),
195 iforce
->data
, 8, iforce_usb_irq
, iforce
, endpoint
->bInterval
);
197 iforce_input_setup(iforce
);
199 printk(KERN_INFO
"input%d: %s on usb%d:%d.%d\n",
200 iforce
->dev
.number
, iforce_name
, dev
->bus
->busnum
, dev
->devnum
, ifnum
);
205 static void iforce_usb_disconnect(struct usb_device
*dev
, void *ptr
)
207 struct iforce
*iforce
= ptr
;
208 usb_unlink_urb(&iforce
->irq
);
209 input_unregister_device(&iforce
->dev
);
213 static struct usb_driver iforce_usb_driver
= {
215 probe
: iforce_usb_probe
,
216 disconnect
: iforce_usb_disconnect
,
223 static void iforce_serio_irq(struct serio
*serio
, unsigned char data
, unsigned int flags
)
225 struct iforce
* iforce
= serio
->private;
245 if (data
> IFORCE_MAX_LENGTH
) {
254 if (iforce
->idx
< iforce
->len
) {
255 iforce
->csum
+= iforce
->data
[iforce
->idx
++] = data
;
259 if (iforce
->idx
== iforce
->len
) {
260 iforce_process_packet(&iforce
->dev
, iforce
->id
, iforce
->idx
, iforce
->data
);
269 static void iforce_serio_connect(struct serio
*serio
, struct serio_dev
*dev
)
271 struct iforce
*iforce
;
273 if (serio
->type
!= (SERIO_RS232
| SERIO_IFORCE
))
276 if (!(iforce
= kmalloc(sizeof(struct iforce
), GFP_KERNEL
))) return;
277 memset(iforce
, 0, sizeof(struct iforce
));
279 iforce
->dev
.name
= iforce_name
;
280 iforce
->dev
.idbus
= BUS_RS232
;
281 iforce
->dev
.idvendor
= SERIO_IFORCE
;
282 iforce
->dev
.idproduct
= 0x0001;
283 iforce
->dev
.idversion
= 0x0100;
285 serio
->private = iforce
;
287 if (serio_open(serio
, dev
)) {
292 iforce_input_setup(iforce
);
294 printk(KERN_INFO
"input%d: %s on serio%d\n",
295 iforce
->dev
.number
, iforce_name
, serio
->number
);
298 static void iforce_serio_disconnect(struct serio
*serio
)
300 struct iforce
* iforce
= serio
->private;
301 input_unregister_device(&iforce
->dev
);
306 static struct serio_dev iforce_serio_dev
= {
307 interrupt
: iforce_serio_irq
,
308 connect
: iforce_serio_connect
,
309 disconnect
: iforce_serio_disconnect
,
314 static int __init
iforce_init(void)
317 usb_register(&iforce_usb_driver
);
320 serio_register_device(&iforce_serio_dev
);
325 static void __exit
iforce_exit(void)
328 usb_deregister(&iforce_usb_driver
);
331 serio_unregister_device(&iforce_serio_dev
);
335 module_init(iforce_init
);
336 module_exit(iforce_exit
);