^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SEGA Dreamcast controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Based on drivers/usb/iforce.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright Yaegashi Takeshi, 2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Adrian McMenamin, 2008 - 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/maple.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct dc_pad {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct maple_device *mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void dc_pad_callback(struct mapleq *mq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned short buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct maple_device *mapledev = mq->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct dc_pad *pad = maple_get_drvdata(mapledev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct input_dev *dev = pad->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned char *res = mq->recvbuf->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) buttons = ~le16_to_cpup((__le16 *)(res + 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) input_report_abs(dev, ABS_HAT0Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) (buttons & 0x0010 ? -1 : 0) + (buttons & 0x0020 ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) input_report_abs(dev, ABS_HAT0X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) (buttons & 0x0040 ? -1 : 0) + (buttons & 0x0080 ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) input_report_abs(dev, ABS_HAT1Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (buttons & 0x1000 ? -1 : 0) + (buttons & 0x2000 ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) input_report_abs(dev, ABS_HAT1X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) (buttons & 0x4000 ? -1 : 0) + (buttons & 0x8000 ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) input_report_key(dev, BTN_C, buttons & 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) input_report_key(dev, BTN_B, buttons & 0x0002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) input_report_key(dev, BTN_A, buttons & 0x0004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) input_report_key(dev, BTN_START, buttons & 0x0008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) input_report_key(dev, BTN_Z, buttons & 0x0100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) input_report_key(dev, BTN_Y, buttons & 0x0200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) input_report_key(dev, BTN_X, buttons & 0x0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) input_report_key(dev, BTN_SELECT, buttons & 0x0800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) input_report_abs(dev, ABS_GAS, res[10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) input_report_abs(dev, ABS_BRAKE, res[11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) input_report_abs(dev, ABS_X, res[12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) input_report_abs(dev, ABS_Y, res[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) input_report_abs(dev, ABS_RX, res[14]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) input_report_abs(dev, ABS_RY, res[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int dc_pad_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct dc_pad *pad = dev_get_platdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MAPLE_FUNC_CONTROLLER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void dc_pad_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct dc_pad *pad = dev_get_platdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) maple_getcond_callback(pad->mdev, dc_pad_callback, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MAPLE_FUNC_CONTROLLER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* allow the controller to be used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int probe_maple_controller(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const short btn_bit[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static const short abs_bit[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) -1, -1, -1, -1, ABS_HAT0Y, ABS_HAT0Y, ABS_HAT0X, ABS_HAT0X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) -1, -1, -1, -1, ABS_HAT1Y, ABS_HAT1Y, ABS_HAT1X, ABS_HAT1X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ABS_GAS, ABS_BRAKE, ABS_X, ABS_Y, ABS_RX, ABS_RY, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) -1, -1, -1, -1, -1, -1, -1, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct maple_device *mdev = to_maple_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct maple_driver *mdrv = to_maple_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct dc_pad *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct input_dev *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) idev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!pad || !idev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pad->dev = idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pad->mdev = mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) idev->open = dc_pad_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) idev->close = dc_pad_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (data & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (btn_bit[i] >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) __set_bit(btn_bit[i], idev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else if (abs_bit[i] >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) __set_bit(abs_bit[i], idev->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (idev->keybit[BIT_WORD(BTN_JOYSTICK)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) idev->evbit[0] |= BIT_MASK(EV_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (idev->absbit[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) idev->evbit[0] |= BIT_MASK(EV_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (i = ABS_X; i <= ABS_BRAKE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) input_set_abs_params(idev, i, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) input_set_abs_params(idev, i, 1, -1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) idev->dev.platform_data = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) idev->dev.parent = &mdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) idev->name = mdev->product_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) idev->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) error = input_register_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mdev->driver = mdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) maple_set_drvdata(mdev, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) input_free_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kfree(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) maple_set_drvdata(mdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int remove_maple_controller(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct maple_device *mdev = to_maple_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct dc_pad *pad = maple_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mdev->callback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) input_unregister_device(pad->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) maple_set_drvdata(mdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) kfree(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static struct maple_driver dc_pad_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .function = MAPLE_FUNC_CONTROLLER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .name = "Dreamcast_controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .probe = probe_maple_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .remove = remove_maple_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int __init dc_pad_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return maple_driver_register(&dc_pad_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void __exit dc_pad_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) maple_driver_unregister(&dc_pad_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) module_init(dc_pad_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) module_exit(dc_pad_exit);