33 #include <linux/kernel.h>
34 #include <linux/slab.h>
35 #include <linux/module.h>
37 #include <linux/gameport.h>
38 #include <linux/input.h>
41 #define DRIVER_DESC "ThrustMaster DirectConnect joystick driver"
47 #define TMDC_MAX_START 600
48 #define TMDC_MAX_STROBE 60
49 #define TMDC_MAX_LENGTH 13
51 #define TMDC_MODE_M3DI 1
52 #define TMDC_MODE_3DRP 3
53 #define TMDC_MODE_AT 4
54 #define TMDC_MODE_FM 8
55 #define TMDC_MODE_FGP 163
57 #define TMDC_BYTE_ID 10
58 #define TMDC_BYTE_REV 11
59 #define TMDC_BYTE_DEF 12
62 #define TMDC_ABS_HAT 4
65 static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
66 static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
68 static const signed char tmdc_abs[
TMDC_ABS] =
72 static const signed char tmdc_abs_at[
TMDC_ABS] =
74 static const signed char tmdc_abs_fm[
TMDC_ABS] =
77 static const short tmdc_btn_pad[
TMDC_BTN] =
79 static const short tmdc_btn_joy[
TMDC_BTN] =
82 static const short tmdc_btn_fm[
TMDC_BTN] =
84 static const short tmdc_btn_at[
TMDC_BTN] =
91 } tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}};
93 static const struct tmdc_model {
100 const signed char *axes;
103 { 1,
"ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
104 { 3,
"ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
105 { 4,
"ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
106 { 8,
"ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
107 { 163,
"Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
108 { 0,
"Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }
128 struct input_dev *
dev[2];
134 unsigned char absc[2];
135 unsigned char btnc[2][4];
136 unsigned char btno[2][4];
149 unsigned char u,
v,
w,
x;
151 int i[2],
j[2],
t[2],
p,
k;
155 for (k = 0; k < 2; k++) {
161 gameport_trigger(gameport);
163 w = gameport_read(gameport) >> 4;
167 w = gameport_read(gameport) >> 4;
169 for (k = 0, v = w, u = x; k < 2; k++, v >>= 2, u >>= 2) {
171 if (t[k] <= 0 || i[k] >= TMDC_MAX_LENGTH)
continue;
174 if (~v & 1) t[
k] = 0;
175 data[
k][i[
k]] = 0; j[
k]++;
continue;
179 j[
k] = 0; i[
k]++;
continue;
181 data[
k][i[
k]] |= (~v & 1) << (j[k]++ - 1);
185 }
while (t[0] > 0 || t[1] > 0);
199 for (i = 0; i < port->
absc; i++) {
200 if (port->
abs[i] < 0)
203 input_report_abs(port->
dev, port->
abs[i], data[tmdc_byte_a[i]]);
206 switch (port->
mode) {
211 input_report_abs(port->
dev,
ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1));
212 input_report_abs(port->
dev,
ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i] & 1));
218 input_report_abs(port->
dev,
ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x);
219 input_report_abs(port->
dev,
ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y);
224 for (k = l = 0; k < 4; k++) {
225 for (i = 0; i < port->
btnc[
k]; i++)
226 input_report_key(port->
dev, port->
btn[i + l],
227 ((data[tmdc_byte_d[k]] >> (i + port->
btno[k])) & 1));
231 input_sync(port->
dev);
240 static void tmdc_poll(
struct gameport *gameport)
243 struct tmdc *
tmdc = gameport_get_drvdata(gameport);
244 unsigned char r,
bad = 0;
252 for (i = 0; i < 2; i++) {
253 if (r & (1 << i) & tmdc->
exists) {
255 if (tmdc_parse_packet(tmdc->
port[i], data[i]))
264 static int tmdc_open(
struct input_dev *
dev)
266 struct tmdc *tmdc = input_get_drvdata(dev);
272 static void tmdc_close(
struct input_dev *
dev)
274 struct tmdc *tmdc = input_get_drvdata(dev);
279 static int tmdc_setup_port(
struct tmdc *tmdc,
int idx,
unsigned char *data)
281 const struct tmdc_model *
model;
283 struct input_dev *input_dev;
288 input_dev = input_allocate_device();
289 if (!port || !input_dev) {
296 for (model = tmdc_models; model->id && model->id != port->
mode; model++)
299 port->
abs = model->axes;
300 port->
btn = model->buttons;
304 for (i = 0; i < 4; i++)
307 port->
absc = model->abs;
308 for (i = 0; i < 4; i++)
309 port->
btnc[i] = model->btnc[i];
312 for (i = 0; i < 4; i++)
313 port->
btno[i] = model->btno[i];
319 port->
dev = input_dev;
321 input_dev->name = port->
name;
322 input_dev->phys = port->
phys;
325 input_dev->id.product = model->id;
326 input_dev->id.version = 0x0100;
327 input_dev->dev.parent = &tmdc->
gameport->dev;
329 input_set_drvdata(input_dev, tmdc);
331 input_dev->open = tmdc_open;
332 input_dev->close = tmdc_close;
337 if (port->
abs[i] >= 0)
338 input_set_abs_params(input_dev, port->
abs[i], 8, 248, 2, 4);
341 input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0);
343 for (i = 0; i < 4; i++) {
349 err = input_register_device(port->
dev);
355 fail: input_free_device(input_dev);
364 static int tmdc_connect(
struct gameport *gameport,
struct gameport_driver *drv)
371 if (!(tmdc = kzalloc(
sizeof(
struct tmdc),
GFP_KERNEL)))
376 gameport_set_drvdata(gameport, tmdc);
382 if (!(tmdc->
exists = tmdc_read_packet(gameport, data))) {
387 gameport_set_poll_handler(gameport, tmdc_poll);
388 gameport_set_poll_interval(gameport, 20);
390 for (i = 0; i < 2; i++) {
391 if (tmdc->
exists & (1 << i)) {
393 err = tmdc_setup_port(tmdc, i, data[i]);
401 fail3:
while (--i >= 0) {
403 input_unregister_device(tmdc->
port[i]->dev);
408 fail1: gameport_set_drvdata(gameport,
NULL);
413 static void tmdc_disconnect(
struct gameport *gameport)
415 struct tmdc *tmdc = gameport_get_drvdata(gameport);
418 for (i = 0; i < 2; i++) {
420 input_unregister_device(tmdc->
port[i]->dev);
425 gameport_set_drvdata(gameport,
NULL);
435 .connect = tmdc_connect,
436 .disconnect = tmdc_disconnect,