29 #include <linux/kernel.h>
30 #include <linux/slab.h>
31 #include <linux/module.h>
34 #include <linux/gameport.h>
35 #include <linux/input.h>
38 #define DRIVER_DESC "Guillemot Digital joystick driver"
44 #define GUILLEMOT_MAX_START 600
45 #define GUILLEMOT_MAX_STROBE 60
46 #define GUILLEMOT_MAX_LENGTH 17
48 static short guillemot_abs_pad[] =
51 static short guillemot_btn_pad[] =
52 {
BTN_A,
BTN_B,
BTN_C,
BTN_X,
BTN_Y,
BTN_Z,
BTN_TL,
BTN_TR,
BTN_MODE,
BTN_SELECT, -1 };
57 } guillemot_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
69 struct input_dev *
dev;
78 { 0x00, guillemot_abs_pad, guillemot_btn_pad, 1,
"Guillemot Pad" },
100 gameport_trigger(gameport);
101 v = gameport_read(gameport);
103 while (t > 0 && i < GUILLEMOT_MAX_LENGTH * 8) {
105 u =
v; v = gameport_read(gameport);
107 data[i >> 3] |= ((v >> 5) & 1) << (i & 7);
122 static void guillemot_poll(
struct gameport *gameport)
125 struct input_dev *
dev = guillemot->
dev;
131 if (guillemot_read_packet(guillemot->
gameport, data) != GUILLEMOT_MAX_LENGTH * 8 ||
132 data[0] != 0x55 || data[16] != 0xaa) {
136 for (i = 0; i < 6 && guillemot->
type->abs[
i] >= 0; i++)
137 input_report_abs(dev, guillemot->
type->abs[i], data[i + 5]);
139 if (guillemot->
type->hat) {
140 input_report_abs(dev,
ABS_HAT0X, guillemot_hat_to_axis[data[4] >> 4].
x);
141 input_report_abs(dev,
ABS_HAT0Y, guillemot_hat_to_axis[data[4] >> 4].
y);
144 for (i = 0; i < 16 && guillemot->
type->btn[
i] >= 0; i++)
145 input_report_key(dev, guillemot->
type->btn[i], (data[2 + (i >> 3)] >> (i & 7)) & 1);
155 static int guillemot_open(
struct input_dev *dev)
157 struct guillemot *guillemot = input_get_drvdata(dev);
167 static void guillemot_close(
struct input_dev *dev)
169 struct guillemot *guillemot = input_get_drvdata(dev);
178 static int guillemot_connect(
struct gameport *gameport,
struct gameport_driver *drv)
180 struct guillemot *guillemot;
181 struct input_dev *input_dev;
186 guillemot = kzalloc(
sizeof(
struct guillemot),
GFP_KERNEL);
187 input_dev = input_allocate_device();
188 if (!guillemot || !input_dev) {
194 guillemot->
dev = input_dev;
196 gameport_set_drvdata(gameport, guillemot);
202 i = guillemot_read_packet(gameport, data);
204 if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa) {
209 for (i = 0; guillemot_type[
i].
name; i++)
210 if (guillemot_type[i].
id == data[11])
213 if (!guillemot_type[i].
name) {
214 printk(
KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
215 gameport->
phys, data[12], data[13], data[11], data[14], data[15]);
220 gameport_set_poll_handler(gameport, guillemot_poll);
221 gameport_set_poll_interval(gameport, 20);
224 guillemot->
type = guillemot_type +
i;
226 input_dev->name = guillemot_type[
i].
name;
227 input_dev->phys = guillemot->
phys;
230 input_dev->id.product = guillemot_type[
i].
id;
231 input_dev->id.version = (
int)data[14] << 8 | data[15];
232 input_dev->dev.parent = &gameport->
dev;
234 input_set_drvdata(input_dev, guillemot);
236 input_dev->open = guillemot_open;
237 input_dev->close = guillemot_close;
241 for (i = 0; (t = guillemot->
type->abs[
i]) >= 0; i++)
242 input_set_abs_params(input_dev, t, 0, 255, 0, 0);
244 if (guillemot->
type->hat) {
245 input_set_abs_params(input_dev,
ABS_HAT0X, -1, 1, 0, 0);
246 input_set_abs_params(input_dev,
ABS_HAT0Y, -1, 1, 0, 0);
249 for (i = 0; (t = guillemot->
type->btn[
i]) >= 0; i++)
252 err = input_register_device(guillemot->
dev);
259 fail1: gameport_set_drvdata(gameport,
NULL);
260 input_free_device(input_dev);
265 static void guillemot_disconnect(
struct gameport *gameport)
267 struct guillemot *guillemot = gameport_get_drvdata(gameport);
270 input_unregister_device(guillemot->
dev);
280 .connect = guillemot_connect,
281 .disconnect = guillemot_disconnect,