1 // SPDX-License-Identifier: GPL-2.0-only
3 * SEGA Dreamcast mouse driver
4 * Based on drivers/usb/usbmouse.c
6 * Copyright (c) Yaegashi Takeshi, 2001
7 * Copyright (c) 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 mouse driver");
20 MODULE_LICENSE("GPL");
23 struct input_dev
*dev
;
24 struct maple_device
*mdev
;
27 static void dc_mouse_callback(struct mapleq
*mq
)
29 int buttons
, relx
, rely
, relz
;
30 struct maple_device
*mapledev
= mq
->dev
;
31 struct dc_mouse
*mse
= maple_get_drvdata(mapledev
);
32 struct input_dev
*dev
= mse
->dev
;
33 unsigned char *res
= mq
->recvbuf
->buf
;
36 relx
= *(unsigned short *)(res
+ 12) - 512;
37 rely
= *(unsigned short *)(res
+ 14) - 512;
38 relz
= *(unsigned short *)(res
+ 16) - 512;
40 input_report_key(dev
, BTN_LEFT
, buttons
& 4);
41 input_report_key(dev
, BTN_MIDDLE
, buttons
& 9);
42 input_report_key(dev
, BTN_RIGHT
, buttons
& 2);
43 input_report_rel(dev
, REL_X
, relx
);
44 input_report_rel(dev
, REL_Y
, rely
);
45 input_report_rel(dev
, REL_WHEEL
, relz
);
49 static int dc_mouse_open(struct input_dev
*dev
)
51 struct dc_mouse
*mse
= maple_get_drvdata(to_maple_dev(&dev
->dev
));
53 maple_getcond_callback(mse
->mdev
, dc_mouse_callback
, HZ
/50,
59 static void dc_mouse_close(struct input_dev
*dev
)
61 struct dc_mouse
*mse
= maple_get_drvdata(to_maple_dev(&dev
->dev
));
63 maple_getcond_callback(mse
->mdev
, dc_mouse_callback
, 0,
67 /* allow the mouse to be used */
68 static int probe_maple_mouse(struct device
*dev
)
70 struct maple_device
*mdev
= to_maple_dev(dev
);
71 struct maple_driver
*mdrv
= to_maple_driver(dev
->driver
);
73 struct input_dev
*input_dev
;
76 mse
= kzalloc(sizeof(struct dc_mouse
), GFP_KERNEL
);
82 input_dev
= input_allocate_device();
91 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_REL
);
92 input_dev
->keybit
[BIT_WORD(BTN_MOUSE
)] = BIT_MASK(BTN_LEFT
) |
93 BIT_MASK(BTN_RIGHT
) | BIT_MASK(BTN_MIDDLE
);
94 input_dev
->relbit
[0] = BIT_MASK(REL_X
) | BIT_MASK(REL_Y
) |
96 input_dev
->open
= dc_mouse_open
;
97 input_dev
->close
= dc_mouse_close
;
98 input_dev
->name
= mdev
->product_name
;
99 input_dev
->id
.bustype
= BUS_HOST
;
100 error
= input_register_device(input_dev
);
105 maple_set_drvdata(mdev
, mse
);
110 input_free_device(input_dev
);
117 static int remove_maple_mouse(struct device
*dev
)
119 struct maple_device
*mdev
= to_maple_dev(dev
);
120 struct dc_mouse
*mse
= maple_get_drvdata(mdev
);
122 mdev
->callback
= NULL
;
123 input_unregister_device(mse
->dev
);
124 maple_set_drvdata(mdev
, NULL
);
130 static struct maple_driver dc_mouse_driver
= {
131 .function
= MAPLE_FUNC_MOUSE
,
133 .name
= "Dreamcast_mouse",
134 .probe
= probe_maple_mouse
,
135 .remove
= remove_maple_mouse
,
139 static int __init
dc_mouse_init(void)
141 return maple_driver_register(&dc_mouse_driver
);
144 static void __exit
dc_mouse_exit(void)
146 maple_driver_unregister(&dc_mouse_driver
);
149 module_init(dc_mouse_init
);
150 module_exit(dc_mouse_exit
);