sh: maple: add support for Maple controller as a joystick
Subsystems (2)
PATCH 1/1 sh: maple: add support for Maple controller as a joystick
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
---
drivers/input/joystick/Kconfig +13 -0
@@ -294,4 +294,17 @@ config JOYSTICK_XPAD_LEDS This option enables support for the LED which surrounds the Big X on XBox 360 controller. +config JOYSTICK_MAPLE + tristate "Dreamcast control pad" + depends on SH_DREAMCAST + select MAPLE + help + Say Y here if you have a SEGA Dreamcast and want to use your + controller as a joystick. + + Most Dreamcast users will say Y. + + To compile this as a module choose M here: the module will be called + maplecontrol. + endif
drivers/input/joystick/Makefile +1 -0
@@ -10,6 +10,7 @@ obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o obj-$(CONFIG_JOYSTICK_DB9) += db9.o +obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o obj-$(CONFIG_JOYSTICK_GAMECON) += gamecon.o obj-$(CONFIG_JOYSTICK_GF2K) += gf2k.o obj-$(CONFIG_JOYSTICK_GRIP) += grip.o
drivers/input/joystick/maplecontrol.c new file +193 -0
193 lines not on this page · raw message
Quoted 3 lines · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
drivers/input/joystick/maplecontrol.c line 35
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 )); +
I may be wrong but shouldn't this use the I/O accessor functions?
Quoted 7 lines
drivers/input/joystick/maplecontrol.c new file +7
-0+ + pad =kzalloc (sizeof (struct dc_pad ),GFP_KERNEL ); + idev =input_allocate_device (); +if (!pad || !idev){ + error =ENOMEM ; + goto fail; + }
[snip]
drivers/input/joystick/maplecontrol.c line 155
Quoted 2 lines
drivers/input/joystick/maplecontrol.c new file +2
-0+fail: +input_free_device (pad->dev);
Possible NULL pointer dereference?
Quoted 7 lines · Matt Fleming
Quoted 3 lines · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
Quoted 9 lines
drivers/input/joystick/maplecontrol.c line 35
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 )); +I may be wrong but shouldn't this use the I/O accessor functions?
It's not iomemory, so I don't think so. The maple bus writes to a buffer in the physical RAM.
Quoted 10 lines
Quoted 7 lines
drivers/input/joystick/maplecontrol.c new file +7
-0+ + pad =kzalloc (sizeof (struct dc_pad ),GFP_KERNEL ); + idev =input_allocate_device (); +if (!pad || !idev){ + error =ENOMEM ; + goto fail; + }[snip]
Quoted 4 lines
drivers/input/joystick/maplecontrol.c line 155
Quoted 2 lines
drivers/input/joystick/maplecontrol.c new file +2
-0+fail: +input_free_device (pad->dev);Possible NULL pointer dereference?
No, because input_free_device is:
void input_free_device(struct input_dev *dev)
{
if (dev)
input_put_device(dev);
}EXPORT_SYMBOL(input_free_device);
Dmitry Torokhov
maintainerQuoted 15 lines · On Saturday 20 December 2008 08:07:27 Adrian McMenamin wrote:
Quoted 5 lines · Matt Fleming
Quoted 1 line · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
Quoted 8 lines
drivers/input/joystick/maplecontrol.c line 35
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 )); +I may be wrong but shouldn't this use the I/O accessor functions?
Quoted 3 lines
It's not iomemory, so I don't think so. The maple bus writes to a buffer in the physical RAM.
Hmm, but why we are going _from_ cpu order to le16??? I'd expect we wanted to do conversion the other way around. I pulled it out of 'next' for now.
Quoted 15 lines
Quoted 10 lines
Quoted 7 lines
drivers/input/joystick/maplecontrol.c new file +7
-0+ + pad =kzalloc (sizeof (struct dc_pad ),GFP_KERNEL ); + idev =input_allocate_device (); +if (!pad || !idev){ + error =ENOMEM ; + goto fail; + }[snip]
Quoted 4 lines
drivers/input/joystick/maplecontrol.c line 155
Quoted 2 lines
drivers/input/joystick/maplecontrol.c new file +2
-0+fail: +input_free_device (pad->dev);Possible NULL pointer dereference?
Quoted 8 lines
No, because
input_free_deviceis:void
input_free_device(struct input_dev *dev){ if (dev) input_put_device(dev); }
EXPORT_SYMBOL(input_free_device);
But we need to be freeing idev, not pad->dev because pad might be NULL.
Signature · 1 line
Dmitry
Quoted 16 lines · Dmitry Torokhov
Quoted 15 lines · On Saturday 20 December 2008 08:07:27 Adrian McMenamin wrote:
Quoted 13 lines · Matt Fleming
Quoted 1 line · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
drivers/input/joystick/maplecontrol.c line 35
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 )); +I may be wrong but shouldn't this use the I/O accessor functions?
Quoted 8 lines
Quoted 3 lines
It's not iomemory, so I don't think so. The maple bus writes to a buffer in the physical RAM.
Hmm, but why we are going _from_ cpu order to le16??? I'd expect we wanted to do conversion the other way around. I pulled it out of 'next' for now.
The data is transmitted here by the bus in 32 bit little endian blocks but makes sense in le16 bit lumps. Off is 1 and on is 0 - hence the ~
The first 16 bits are the button data the next 16 bits are the (start of) the axis data. Both cpu and bus data (in this case - it can vary) are little endian.
Dmitry Torokhov
maintainerOn Dec 20, 2008, at 12:47 PM, Adrian McMenamin <[email protected]
Quoted 29 lines
wrote:
Quoted 21 lines · Dmitry Torokhov
Quoted 15 lines · On Saturday 20 December 2008 08:07:27 Adrian McMenamin wrote:
Quoted 5 lines · Matt Fleming
Quoted 1 line · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
Quoted 8 lines
drivers/input/joystick/maplecontrol.c line 35
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 )); +I may be wrong but shouldn't this use the I/O accessor functions?
Quoted 4 lines
It's not iomemory, so I don't think so. The maple bus writes to a buffer
in the physical RAM.Quoted 5 lines
Hmm, but why we are going _from_ cpu order to le16??? I'd expect we wanted to do conversion the other way around. I pulled it out of 'next'
for now.
Quoted 6 lines
The data is transmitted here by the bus in 32 bit little endian blocks but makes sense in le16 bit lumps. Off is 1 and on is 0 - hence the ~
The first 16 bits are the button data the next 16 bits are the (start of) the axis data. Both cpu and bus data (in this case - it can vary) are little endian.
Right, so I think we need le16_to_cpu here, you want the data in native CPU order to manipulate it.
Signature · 1 line
Dmitry
Quoted 14 lines · Adrian McMenamin
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
Signed-off-by Adrian McMenamin <[email protected]>---
drivers/input/joystick/Kconfig +0
-0
drivers/input/joystick/Kconfig config JOYSTICK_XPAD_LEDS · line 301
Quoted 8 lines
drivers/input/joystick/Kconfig +5
-0@@ -294,4 +294,17 @@ config JOYSTICK_XPAD_LEDS This option enables support for the LED which surrounds the Big X on XBox 360 controller. +config JOYSTICK_MAPLE + tristate "Dreamcast control pad" + depends on SH_DREAMCAST + select MAPLE + help
Please don't do this kind of dependency garbage. The only dependency this device has is on the maple bus, there is nothing inherently dreamcast specific about it.
CONFIG_MAPLE already has the dreamcast dependency in this case, and I would speculate the only reason that you added the dreamcast dependency was to work around the fact that select would complain on plaforms where the MAPLE symbol is not visible.
This is an indicator that select is not the thing you should be using here in the first place. So, just change this to depends on MAPLE and be done with it. As soon as you have to start mixing and matching depends/selects that already have a dependency on each other, you have already lost.
Quoted 1 line · Adrian McMenamin
Add support for the SEGA Dreamcast Maple controller as a joystick
[snip]
Quoted 8 lines
drivers/input/joystick/maplecontrol.c new file +8
-0+ + pad =kzalloc (sizeof (struct dc_pad ),GFP_KERNEL ); + idev =input_allocate_device (); +if (!pad || !idev){ + error =ENOMEM ; + goto fail; + } +
[snip]
Quoted 6 lines
drivers/input/joystick/maplecontrol.c new file +6
-0+ + error =input_register_device (idev); +if (error) + goto fail; + + mdev->driver = mdrv;
drivers/input/joystick/maplecontrol.c line 159
Quoted 10 lines
drivers/input/joystick/maplecontrol.c new file +10
-0+maple_set_drvdata (mdev, pad); + +return error; + +fail: +input_free_device (pad->dev); +kfree (pad); +maple_set_drvdata (mdev,NULL ); +return -error; +}
This will incorrectly negate the already negative error code from input_register_device.
Rabin
Quoted 8 lines · On Fri, 19 Dec 2008 23:15:42 +0000 Adrian McMenamin…
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
...
drivers/input/joystick/maplecontrol.c line 34
Quoted 9 lines
drivers/input/joystick/maplecontrol.c new file +9
-0+static void dc_pad_callback (struct mapleq *mq) +{ +unsigned short buttons; +struct maple_device *mapledev = mq->dev; +struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 ));
hm, could that be simplified?
Quoted 58 lines
drivers/input/joystick/maplecontrol.c new file +58
-0+input_report_abs (dev,ABS_HAT0Y , + (buttons &0x0010 ?-1 :0 ) + (buttons &0x0020 ?1 :0 )); +input_report_abs (dev,ABS_HAT0X , + (buttons &0x0040 ?-1 :0 ) + (buttons &0x0080 ?1 :0 )); +input_report_abs (dev,ABS_HAT1Y , + (buttons &0x1000 ?-1 :0 ) + (buttons &0x2000 ?1 :0 )); +input_report_abs (dev,ABS_HAT1X , + (buttons &0x4000 ?-1 :0 ) + (buttons &0x8000 ?1 :0 )); + +input_report_key (dev,BTN_C , buttons &0x0001 ); +input_report_key (dev,BTN_B , buttons &0x0002 ); +input_report_key (dev,BTN_A , buttons &0x0004 ); +input_report_key (dev,BTN_START , buttons &0x0008 ); +input_report_key (dev,BTN_Z , buttons &0x0100 ); +input_report_key (dev,BTN_Y , buttons &0x0200 ); +input_report_key (dev,BTN_X , buttons &0x0400 ); +input_report_key (dev,BTN_SELECT , buttons &0x0800 ); + +input_report_abs (dev,ABS_GAS , res[10 ]); +input_report_abs (dev,ABS_BRAKE , res[11 ]); +input_report_abs (dev,ABS_X , res[12 ]); +input_report_abs (dev,ABS_Y , res[13 ]); +input_report_abs (dev,ABS_RX , res[14 ]); +input_report_abs (dev,ABS_RY , res[15 ]); +} + +static int dc_pad_open (struct input_dev *dev) +{ +struct dc_pad *pad; + + pad = dev->dev.platform_data; +maple_getcond_callback (pad->mdev, dc_pad_callback,HZ /20 , +MAPLE_FUNC_CONTROLLER ); +return 0 ; +} + +static void dc_pad_close (struct input_dev *dev) +{ +struct dc_pad *pad; + + pad = dev->dev.platform_data; +maple_getcond_callback (pad->mdev, dc_pad_callback,0 , +MAPLE_FUNC_CONTROLLER ); +} + +/* allow the controller to be used */ +static int probe_maple_controller (struct device *dev) +{ +struct maple_device *mdev =to_maple_dev (dev); +struct maple_driver *mdrv =to_maple_driver (dev->driver); +int i, error; +struct dc_pad *pad; +struct input_dev *idev; +unsigned long data =be32_to_cpu (mdev->devinfo.function_data[0 ]); + +const short btn_bit[32 ] = { +BTN_C ,BTN_B ,BTN_A ,BTN_START ,-1 ,-1 ,-1 ,-1 , +BTN_Z ,BTN_Y ,BTN_X ,BTN_SELECT ,-1 ,-1 ,-1 ,-1 ,
drivers/input/joystick/maplecontrol.c line 103
Quoted 10 lines
drivers/input/joystick/maplecontrol.c new file +10
-0+-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , + -1, -1, -1, -1, -1, -1, -1, -1, + }; + +const short abs_bit[32 ] = { +-1 ,-1 ,-1 ,-1 ,ABS_HAT0Y ,ABS_HAT0Y ,ABS_HAT0X ,ABS_HAT0X , +-1 ,-1 ,-1 ,-1 ,ABS_HAT1Y ,ABS_HAT1Y ,ABS_HAT1X ,ABS_HAT1X , +ABS_GAS ,ABS_BRAKE ,ABS_X ,ABS_Y ,ABS_RX ,ABS_RY ,-1 ,-1 , +-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , + };
These could be made static.
There's a risk that the compiler will go and assemble these arrays on the stack each time this function is called. gcc (some versions, at least) will actually internally turn these into static arrays (assembled at compile time) but it's best to do this explicitly.
drivers/input/joystick/maplecontrol.c line 158
Quoted 8 lines
drivers/input/joystick/maplecontrol.c new file +5
-0+ pad =kzalloc (sizeof (struct dc_pad ),GFP_KERNEL ); + idev =input_allocate_device (); +if (!pad || !idev){ + error =ENOMEM ; +return -error;
Please don't do this. People occasionally grep the tree for instances of 'EFOO' which are missing the "-" sign, which is a useful service. The above trick just makes things harder for them.
Quoted 3 lines
...
Quoted 11 lines · Andrew Morton
Quoted 8 lines · On Fri, 19 Dec 2008 23:15:42 +0000 Adrian McMenamin…
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
...
Quoted 11 lines
drivers/input/joystick/maplecontrol.c line 34
Quoted 9 lines
drivers/input/joystick/maplecontrol.c new file +9
-0+static void dc_pad_callback (struct mapleq *mq) +{ +unsigned short buttons; +struct maple_device *mapledev = mq->dev; +struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 ));hm, could that be simplified?
And as a bonus fix the obvious sparse warning:
buttons = ~le16_to_cpup((__le16 *)(res + 8));
Cheers,
Harvey
Dmitry Torokhov
maintainerQuoted 24 lines · Harvey Harrison
Quoted 11 lines · Andrew Morton
Quoted 8 lines · On Fri, 19 Dec 2008 23:15:42 +0000 Adrian McMenamin…
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
...
Quoted 11 lines
Review
Quoted 9 lines
(quoted diff) +9
-0+static void dc_pad_callback(struct mapleq *mq) +{ + unsigned short buttons; + struct maple_device *mapledev = mq->dev; + struct dc_pad *pad = maple_get_drvdata(mapledev); + struct input_dev *dev = pad->dev; + unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16(*(unsigned short *)(res + 8));hm, could that be simplified?
Quoted 4 lines
And as a bonus fix the obvious sparse warning:
buttons = ~le16_to_cpup((__le16 *)(res + 8));
Below is what I woudl like to apply unless you see more issues with the patch. Andrew, if you could test it on your hardware to make sure it still works that woudl be great.
Thanks!
Signature · 16 lines
Dmitry Input: add support for Maple controller as a joystick From: Adrian McMenamin <[email protected]> Add support for the SEGA Dreamcast Maple controller as a joystick Signed-off-by: Adrian McMenamin <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> --- drivers/input/joystick/Kconfig | 12 ++ drivers/input/joystick/Makefile | 1 drivers/input/joystick/maplecontrol.c | 193 +++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 0 deletions(-) create mode 100644 drivers/input/joystick/maplecontrol.c
drivers/input/joystick/Kconfig +12 -0
@@ -306,4 +306,16 @@ config JOYSTICK_WALKERA0701 To compile this driver as a module, choose M here: the module will be called walkera0701. +config JOYSTICK_MAPLE + tristate "Dreamcast control pad" + depends on MAPLE + help + Say Y here if you have a SEGA Dreamcast and want to use your + controller as a joystick. + + Most Dreamcast users will say Y. + + To compile this as a module choose M here: the module will be called + maplecontrol. + endif
drivers/input/joystick/Makefile +1 -0
@@ -10,6 +10,7 @@ obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o obj-$(CONFIG_JOYSTICK_DB9) += db9.o +obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o obj-$(CONFIG_JOYSTICK_GAMECON) += gamecon.o obj-$(CONFIG_JOYSTICK_GF2K) += gf2k.o obj-$(CONFIG_JOYSTICK_GRIP) += grip.o
drivers/input/joystick/maplecontrol.c new file +193 -0
193 lines not on this page · raw message
Quoted 27 lines · Dmitry Torokhov
Quoted 26 lines · Harvey Harrison
Quoted 11 lines · Andrew Morton
Quoted 8 lines · On Fri, 19 Dec 2008 23:15:42 +0000 Adrian McMenamin…
Not sure what happened with earlier submissions, so here is an up-to-date patch for the Dreamcast Maple controlled.
Add support for the SEGA Dreamcast Maple controller as a joystick
...
Quoted 11 lines
drivers/input/joystick/maplecontrol.c
Quoted 9 lines
drivers/input/joystick/maplecontrol.c new file +9
-0+static void dc_pad_callback (struct mapleq *mq) +{ +unsigned short buttons; +struct maple_device *mapledev = mq->dev; +struct dc_pad *pad =maple_get_drvdata (mapledev); +struct input_dev *dev = pad->dev; +unsigned char *res = mq->recvbuf; + + buttons = ~cpu_to_le16 (*(unsigned short *)(res +8 ));hm, could that be simplified?
And as a bonus fix the obvious sparse warning:
Quoted 9 lines
Quoted 2 lines
buttons = ~le16_to_cpup((__le16 *)(res + 8));Below is what I woudl like to apply unless you see more issues with the patch. Andrew, if you could test it on your hardware to make sure it still works that woudl be great.
Thanks!
Just to say I've tested this with jstest now and it seems to be in good working order. There is a calibration issue on one axis, but I think that's my hardware :-)