2 * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $
4 * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
5 * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com>
7 * USB/RS232 I-Force joysticks and wheels.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Should you need to contact me, the author, you can do so either by
26 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
27 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
32 void iforce_serial_xmit(struct iforce
*iforce
)
38 if (test_and_set_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
)) {
39 set_bit(IFORCE_XMIT_AGAIN
, iforce
->xmit_flags
);
43 spin_lock_irqsave(&iforce
->xmit_lock
, flags
);
46 if (iforce
->xmit
.head
== iforce
->xmit
.tail
) {
47 clear_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
);
48 spin_unlock_irqrestore(&iforce
->xmit_lock
, flags
);
54 serio_write(iforce
->serio
, 0x2b);
56 serio_write(iforce
->serio
, iforce
->xmit
.buf
[iforce
->xmit
.tail
]);
57 cs
^= iforce
->xmit
.buf
[iforce
->xmit
.tail
];
58 XMIT_INC(iforce
->xmit
.tail
, 1);
60 for (i
=iforce
->xmit
.buf
[iforce
->xmit
.tail
]; i
>= 0; --i
) {
61 serio_write(iforce
->serio
, iforce
->xmit
.buf
[iforce
->xmit
.tail
]);
62 cs
^= iforce
->xmit
.buf
[iforce
->xmit
.tail
];
63 XMIT_INC(iforce
->xmit
.tail
, 1);
66 serio_write(iforce
->serio
, cs
);
68 if (test_and_clear_bit(IFORCE_XMIT_AGAIN
, iforce
->xmit_flags
))
71 clear_bit(IFORCE_XMIT_RUNNING
, iforce
->xmit_flags
);
73 spin_unlock_irqrestore(&iforce
->xmit_lock
, flags
);
76 static void iforce_serio_write_wakeup(struct serio
*serio
)
78 iforce_serial_xmit((struct iforce
*)serio
->private);
81 static irqreturn_t
iforce_serio_irq(struct serio
*serio
,
82 unsigned char data
, unsigned int flags
, struct pt_regs
*regs
)
84 struct iforce
* iforce
= serio
->private;
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
, regs
);
127 static void iforce_serio_connect(struct serio
*serio
, struct serio_driver
*drv
)
129 struct iforce
*iforce
;
130 if (serio
->type
!= (SERIO_RS232
| SERIO_IFORCE
))
133 if (!(iforce
= kmalloc(sizeof(struct iforce
), GFP_KERNEL
))) return;
134 memset(iforce
, 0, sizeof(struct iforce
));
136 iforce
->bus
= IFORCE_232
;
137 iforce
->serio
= serio
;
138 serio
->private = iforce
;
140 if (serio_open(serio
, drv
)) {
145 if (iforce_init_device(iforce
)) {
152 static void iforce_serio_disconnect(struct serio
*serio
)
154 struct iforce
* iforce
= serio
->private;
156 input_unregister_device(&iforce
->dev
);
161 struct serio_driver iforce_serio_drv
= {
165 .description
= "RS232 I-Force joysticks and wheels driver",
166 .write_wakeup
= iforce_serio_write_wakeup
,
167 .interrupt
= iforce_serio_irq
,
168 .connect
= iforce_serio_connect
,
169 .disconnect
= iforce_serio_disconnect
,