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, 2007 Johann Deneux <johann.deneux@gmail.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 struct iforce
*iforce
= serio_get_drvdata(serio
);
80 iforce_serial_xmit(iforce
);
83 static irqreturn_t
iforce_serio_irq(struct serio
*serio
,
84 unsigned char data
, unsigned int flags
)
86 struct iforce
*iforce
= serio_get_drvdata(serio
);
95 if (data
> 3 && data
!= 0xff)
103 if (data
> IFORCE_MAX_LENGTH
) {
112 if (iforce
->idx
< iforce
->len
) {
113 iforce
->csum
+= iforce
->data
[iforce
->idx
++] = data
;
117 if (iforce
->idx
== iforce
->len
) {
118 iforce_process_packet(iforce
, (iforce
->id
<< 8) | iforce
->idx
, iforce
->data
);
129 static int iforce_serio_connect(struct serio
*serio
, struct serio_driver
*drv
)
131 struct iforce
*iforce
;
134 iforce
= kzalloc(sizeof(struct iforce
), GFP_KERNEL
);
138 iforce
->bus
= IFORCE_232
;
139 iforce
->serio
= serio
;
141 serio_set_drvdata(serio
, iforce
);
143 err
= serio_open(serio
, drv
);
147 err
= iforce_init_device(iforce
);
153 fail2
: serio_close(serio
);
154 fail1
: serio_set_drvdata(serio
, NULL
);
159 static void iforce_serio_disconnect(struct serio
*serio
)
161 struct iforce
*iforce
= serio_get_drvdata(serio
);
163 input_unregister_device(iforce
->dev
);
165 serio_set_drvdata(serio
, NULL
);
169 static struct serio_device_id iforce_serio_ids
[] = {
172 .proto
= SERIO_IFORCE
,
179 MODULE_DEVICE_TABLE(serio
, iforce_serio_ids
);
181 struct serio_driver iforce_serio_drv
= {
185 .description
= "RS232 I-Force joysticks and wheels driver",
186 .id_table
= iforce_serio_ids
,
187 .write_wakeup
= iforce_serio_write_wakeup
,
188 .interrupt
= iforce_serio_irq
,
189 .connect
= iforce_serio_connect
,
190 .disconnect
= iforce_serio_disconnect
,