1 // SPDX-License-Identifier: GPL-2.0-only
3 * SEGA Dreamcast controller driver
4 * Based on drivers/usb/iforce.c
6 * Copyright Yaegashi Takeshi, 2001
7 * Adrian McMenamin, 2008 - 2009
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/input.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/timer.h>
16 #include <linux/maple.h>
18 MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
19 MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
20 MODULE_LICENSE("GPL");
23 struct input_dev
*dev
;
24 struct maple_device
*mdev
;
27 static void dc_pad_callback(struct mapleq
*mq
)
29 unsigned short buttons
;
30 struct maple_device
*mapledev
= mq
->dev
;
31 struct dc_pad
*pad
= maple_get_drvdata(mapledev
);
32 struct input_dev
*dev
= pad
->dev
;
33 unsigned char *res
= mq
->recvbuf
->buf
;
35 buttons
= ~le16_to_cpup((__le16
*)(res
+ 8));
37 input_report_abs(dev
, ABS_HAT0Y
,
38 (buttons
& 0x0010 ? -1 : 0) + (buttons
& 0x0020 ? 1 : 0));
39 input_report_abs(dev
, ABS_HAT0X
,
40 (buttons
& 0x0040 ? -1 : 0) + (buttons
& 0x0080 ? 1 : 0));
41 input_report_abs(dev
, ABS_HAT1Y
,
42 (buttons
& 0x1000 ? -1 : 0) + (buttons
& 0x2000 ? 1 : 0));
43 input_report_abs(dev
, ABS_HAT1X
,
44 (buttons
& 0x4000 ? -1 : 0) + (buttons
& 0x8000 ? 1 : 0));
46 input_report_key(dev
, BTN_C
, buttons
& 0x0001);
47 input_report_key(dev
, BTN_B
, buttons
& 0x0002);
48 input_report_key(dev
, BTN_A
, buttons
& 0x0004);
49 input_report_key(dev
, BTN_START
, buttons
& 0x0008);
50 input_report_key(dev
, BTN_Z
, buttons
& 0x0100);
51 input_report_key(dev
, BTN_Y
, buttons
& 0x0200);
52 input_report_key(dev
, BTN_X
, buttons
& 0x0400);
53 input_report_key(dev
, BTN_SELECT
, buttons
& 0x0800);
55 input_report_abs(dev
, ABS_GAS
, res
[10]);
56 input_report_abs(dev
, ABS_BRAKE
, res
[11]);
57 input_report_abs(dev
, ABS_X
, res
[12]);
58 input_report_abs(dev
, ABS_Y
, res
[13]);
59 input_report_abs(dev
, ABS_RX
, res
[14]);
60 input_report_abs(dev
, ABS_RY
, res
[15]);
63 static int dc_pad_open(struct input_dev
*dev
)
65 struct dc_pad
*pad
= dev_get_platdata(&dev
->dev
);
67 maple_getcond_callback(pad
->mdev
, dc_pad_callback
, HZ
/20,
68 MAPLE_FUNC_CONTROLLER
);
73 static void dc_pad_close(struct input_dev
*dev
)
75 struct dc_pad
*pad
= dev_get_platdata(&dev
->dev
);
77 maple_getcond_callback(pad
->mdev
, dc_pad_callback
, 0,
78 MAPLE_FUNC_CONTROLLER
);
81 /* allow the controller to be used */
82 static int probe_maple_controller(struct device
*dev
)
84 static const short btn_bit
[32] = {
85 BTN_C
, BTN_B
, BTN_A
, BTN_START
, -1, -1, -1, -1,
86 BTN_Z
, BTN_Y
, BTN_X
, BTN_SELECT
, -1, -1, -1, -1,
87 -1, -1, -1, -1, -1, -1, -1, -1,
88 -1, -1, -1, -1, -1, -1, -1, -1,
91 static const short abs_bit
[32] = {
92 -1, -1, -1, -1, ABS_HAT0Y
, ABS_HAT0Y
, ABS_HAT0X
, ABS_HAT0X
,
93 -1, -1, -1, -1, ABS_HAT1Y
, ABS_HAT1Y
, ABS_HAT1X
, ABS_HAT1X
,
94 ABS_GAS
, ABS_BRAKE
, ABS_X
, ABS_Y
, ABS_RX
, ABS_RY
, -1, -1,
95 -1, -1, -1, -1, -1, -1, -1, -1,
98 struct maple_device
*mdev
= to_maple_dev(dev
);
99 struct maple_driver
*mdrv
= to_maple_driver(dev
->driver
);
102 struct input_dev
*idev
;
103 unsigned long data
= be32_to_cpu(mdev
->devinfo
.function_data
[0]);
105 pad
= kzalloc(sizeof(struct dc_pad
), GFP_KERNEL
);
106 idev
= input_allocate_device();
115 idev
->open
= dc_pad_open
;
116 idev
->close
= dc_pad_close
;
118 for (i
= 0; i
< 32; i
++) {
119 if (data
& (1 << i
)) {
121 __set_bit(btn_bit
[i
], idev
->keybit
);
122 else if (abs_bit
[i
] >= 0)
123 __set_bit(abs_bit
[i
], idev
->absbit
);
127 if (idev
->keybit
[BIT_WORD(BTN_JOYSTICK
)])
128 idev
->evbit
[0] |= BIT_MASK(EV_KEY
);
131 idev
->evbit
[0] |= BIT_MASK(EV_ABS
);
133 for (i
= ABS_X
; i
<= ABS_BRAKE
; i
++)
134 input_set_abs_params(idev
, i
, 0, 255, 0, 0);
136 for (i
= ABS_HAT0X
; i
<= ABS_HAT3Y
; i
++)
137 input_set_abs_params(idev
, i
, 1, -1, 0, 0);
139 idev
->dev
.platform_data
= pad
;
140 idev
->dev
.parent
= &mdev
->dev
;
141 idev
->name
= mdev
->product_name
;
142 idev
->id
.bustype
= BUS_HOST
;
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
);