2 * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
3 * Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com>
5 * USB/RS232 I-Force joysticks and wheels.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Should you need to contact me, the author, you can do so either by
24 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
25 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
30 void iforce_serial_xmit(struct iforce
*iforce
)
36 if (test_and_set_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
)) {
37 set_bit(IFORCE_XMIT_AGAIN
, iforce
->xmit_flags
);
41 spin_lock_irqsave(&iforce
->xmit_lock
, flags
);
44 if (iforce
->xmit
.head
== iforce
->xmit
.tail
) {
45 clear_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
);
46 spin_unlock_irqrestore(&iforce
->xmit_lock
, flags
);
52 serio_write(iforce
->serio
, 0x2b);
54 serio_write(iforce
->serio
, iforce
->xmit
.buf
[iforce
->xmit
.tail
]);
55 cs
^= iforce
->xmit
.buf
[iforce
->xmit
.tail
];
56 XMIT_INC(iforce
->xmit
.tail
, 1);
58 for (i
=iforce
->xmit
.buf
[iforce
->xmit
.tail
]; i
>= 0; --i
) {
59 serio_write(iforce
->serio
, iforce
->xmit
.buf
[iforce
->xmit
.tail
]);
60 cs
^= iforce
->xmit
.buf
[iforce
->xmit
.tail
];
61 XMIT_INC(iforce
->xmit
.tail
, 1);
64 serio_write(iforce
->serio
, cs
);
66 if (test_and_clear_bit(IFORCE_XMIT_AGAIN
, iforce
->xmit_flags
))
69 clear_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
);
71 spin_unlock_irqrestore(&iforce
->xmit_lock
, flags
);
74 static void iforce_serio_write_wakeup(struct serio
*serio
)
76 struct iforce
*iforce
= serio_get_drvdata(serio
);
78 iforce_serial_xmit(iforce
);
81 static irqreturn_t
iforce_serio_irq(struct serio
*serio
,
82 unsigned char data
, unsigned int flags
)
84 struct iforce
*iforce
= serio_get_drvdata(serio
);
93 if (data
> 3 && data
!= 0xff)
101 if (data
> IFORCE_MAX_LENGTH
) {
110 if (iforce
->idx
< iforce
->len
) {
111 iforce
->csum
+= iforce
->data
[iforce
->idx
++] = data
;
115 if (iforce
->idx
== iforce
->len
) {
116 iforce_process_packet(iforce
, (iforce
->id
<< 8) | iforce
->idx
, iforce
->data
);
127 static int iforce_serio_connect(struct serio
*serio
, struct serio_driver
*drv
)
129 struct iforce
*iforce
;
132 iforce
= kzalloc(sizeof(struct iforce
), GFP_KERNEL
);
136 iforce
->bus
= IFORCE_232
;
137 iforce
->serio
= serio
;
139 serio_set_drvdata(serio
, iforce
);
141 err
= serio_open(serio
, drv
);
145 err
= iforce_init_device(iforce
);
151 fail2
: serio_close(serio
);
152 fail1
: serio_set_drvdata(serio
, NULL
);
157 static void iforce_serio_disconnect(struct serio
*serio
)
159 struct iforce
*iforce
= serio_get_drvdata(serio
);
161 input_unregister_device(iforce
->dev
);
163 serio_set_drvdata(serio
, NULL
);
167 static const struct serio_device_id iforce_serio_ids
[] = {
170 .proto
= SERIO_IFORCE
,
177 MODULE_DEVICE_TABLE(serio
, iforce_serio_ids
);
179 struct serio_driver iforce_serio_drv
= {
183 .description
= "RS232 I-Force joysticks and wheels driver",
184 .id_table
= iforce_serio_ids
,
185 .write_wakeup
= iforce_serio_write_wakeup
,
186 .interrupt
= iforce_serio_irq
,
187 .connect
= iforce_serio_connect
,
188 .disconnect
= iforce_serio_disconnect
,