2 * SEGA Dreamcast controller driver
3 * Based on drivers/usb/iforce.c
5 * Copyright Yaegashi Takeshi, 2001
6 * Adrian McMenamin, 2008 - 2009
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/input.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/timer.h>
15 #include <linux/maple.h>
17 MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
18 MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
19 MODULE_LICENSE("GPL");
22 struct input_dev
*dev
;
23 struct maple_device
*mdev
;
26 static void dc_pad_callback(struct mapleq
*mq
)
28 unsigned short buttons
;
29 struct maple_device
*mapledev
= mq
->dev
;
30 struct dc_pad
*pad
= maple_get_drvdata(mapledev
);
31 struct input_dev
*dev
= pad
->dev
;
32 unsigned char *res
= mq
->recvbuf
->buf
;
34 buttons
= ~le16_to_cpup((__le16
*)(res
+ 8));
36 input_report_abs(dev
, ABS_HAT0Y
,
37 (buttons
& 0x0010 ? -1 : 0) + (buttons
& 0x0020 ? 1 : 0));
38 input_report_abs(dev
, ABS_HAT0X
,
39 (buttons
& 0x0040 ? -1 : 0) + (buttons
& 0x0080 ? 1 : 0));
40 input_report_abs(dev
, ABS_HAT1Y
,
41 (buttons
& 0x1000 ? -1 : 0) + (buttons
& 0x2000 ? 1 : 0));
42 input_report_abs(dev
, ABS_HAT1X
,
43 (buttons
& 0x4000 ? -1 : 0) + (buttons
& 0x8000 ? 1 : 0));
45 input_report_key(dev
, BTN_C
, buttons
& 0x0001);
46 input_report_key(dev
, BTN_B
, buttons
& 0x0002);
47 input_report_key(dev
, BTN_A
, buttons
& 0x0004);
48 input_report_key(dev
, BTN_START
, buttons
& 0x0008);
49 input_report_key(dev
, BTN_Z
, buttons
& 0x0100);
50 input_report_key(dev
, BTN_Y
, buttons
& 0x0200);
51 input_report_key(dev
, BTN_X
, buttons
& 0x0400);
52 input_report_key(dev
, BTN_SELECT
, buttons
& 0x0800);
54 input_report_abs(dev
, ABS_GAS
, res
[10]);
55 input_report_abs(dev
, ABS_BRAKE
, res
[11]);
56 input_report_abs(dev
, ABS_X
, res
[12]);
57 input_report_abs(dev
, ABS_Y
, res
[13]);
58 input_report_abs(dev
, ABS_RX
, res
[14]);
59 input_report_abs(dev
, ABS_RY
, res
[15]);
62 static int dc_pad_open(struct input_dev
*dev
)
64 struct dc_pad
*pad
= dev_get_platdata(&dev
->dev
);
66 maple_getcond_callback(pad
->mdev
, dc_pad_callback
, HZ
/20,
67 MAPLE_FUNC_CONTROLLER
);
72 static void dc_pad_close(struct input_dev
*dev
)
74 struct dc_pad
*pad
= dev_get_platdata(&dev
->dev
);
76 maple_getcond_callback(pad
->mdev
, dc_pad_callback
, 0,
77 MAPLE_FUNC_CONTROLLER
);
80 /* allow the controller to be used */
81 static int probe_maple_controller(struct device
*dev
)
83 static const short btn_bit
[32] = {
84 BTN_C
, BTN_B
, BTN_A
, BTN_START
, -1, -1, -1, -1,
85 BTN_Z
, BTN_Y
, BTN_X
, BTN_SELECT
, -1, -1, -1, -1,
86 -1, -1, -1, -1, -1, -1, -1, -1,
87 -1, -1, -1, -1, -1, -1, -1, -1,
90 static const short abs_bit
[32] = {
91 -1, -1, -1, -1, ABS_HAT0Y
, ABS_HAT0Y
, ABS_HAT0X
, ABS_HAT0X
,
92 -1, -1, -1, -1, ABS_HAT1Y
, ABS_HAT1Y
, ABS_HAT1X
, ABS_HAT1X
,
93 ABS_GAS
, ABS_BRAKE
, ABS_X
, ABS_Y
, ABS_RX
, ABS_RY
, -1, -1,
94 -1, -1, -1, -1, -1, -1, -1, -1,
97 struct maple_device
*mdev
= to_maple_dev(dev
);
98 struct maple_driver
*mdrv
= to_maple_driver(dev
->driver
);
101 struct input_dev
*idev
;
102 unsigned long data
= be32_to_cpu(mdev
->devinfo
.function_data
[0]);
104 pad
= kzalloc(sizeof(struct dc_pad
), GFP_KERNEL
);
105 idev
= input_allocate_device();
114 idev
->open
= dc_pad_open
;
115 idev
->close
= dc_pad_close
;
117 for (i
= 0; i
< 32; i
++) {
118 if (data
& (1 << i
)) {
120 __set_bit(btn_bit
[i
], idev
->keybit
);
121 else if (abs_bit
[i
] >= 0)
122 __set_bit(abs_bit
[i
], idev
->absbit
);
126 if (idev
->keybit
[BIT_WORD(BTN_JOYSTICK
)])
127 idev
->evbit
[0] |= BIT_MASK(EV_KEY
);
130 idev
->evbit
[0] |= BIT_MASK(EV_ABS
);
132 for (i
= ABS_X
; i
<= ABS_BRAKE
; i
++)
133 input_set_abs_params(idev
, i
, 0, 255, 0, 0);
135 for (i
= ABS_HAT0X
; i
<= ABS_HAT3Y
; i
++)
136 input_set_abs_params(idev
, i
, 1, -1, 0, 0);
138 idev
->dev
.platform_data
= pad
;
139 idev
->dev
.parent
= &mdev
->dev
;
140 idev
->name
= mdev
->product_name
;
141 idev
->id
.bustype
= BUS_HOST
;
142 input_set_drvdata(idev
, pad
);
144 error
= input_register_device(idev
);
149 maple_set_drvdata(mdev
, pad
);
154 input_free_device(idev
);
156 maple_set_drvdata(mdev
, NULL
);
160 static int remove_maple_controller(struct device
*dev
)
162 struct maple_device
*mdev
= to_maple_dev(dev
);
163 struct dc_pad
*pad
= maple_get_drvdata(mdev
);
165 mdev
->callback
= NULL
;
166 input_unregister_device(pad
->dev
);
167 maple_set_drvdata(mdev
, NULL
);
173 static struct maple_driver dc_pad_driver
= {
174 .function
= MAPLE_FUNC_CONTROLLER
,
176 .name
= "Dreamcast_controller",
177 .probe
= probe_maple_controller
,
178 .remove
= remove_maple_controller
,
182 static int __init
dc_pad_init(void)
184 return maple_driver_register(&dc_pad_driver
);
187 static void __exit
dc_pad_exit(void)
189 maple_driver_unregister(&dc_pad_driver
);
192 module_init(dc_pad_init
);
193 module_exit(dc_pad_exit
);