cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

maplecontrol.c (4950B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *	SEGA Dreamcast controller driver
      4 *	Based on drivers/usb/iforce.c
      5 *
      6 *	Copyright Yaegashi Takeshi, 2001
      7 *	Adrian McMenamin, 2008 - 2009
      8 */
      9
     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>
     17
     18MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
     19MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
     20MODULE_LICENSE("GPL");
     21
     22struct dc_pad {
     23	struct input_dev *dev;
     24	struct maple_device *mdev;
     25};
     26
     27static void dc_pad_callback(struct mapleq *mq)
     28{
     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;
     34
     35	buttons = ~le16_to_cpup((__le16 *)(res + 8));
     36
     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));
     45
     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);
     54
     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]);
     61}
     62
     63static int dc_pad_open(struct input_dev *dev)
     64{
     65	struct dc_pad *pad = dev_get_platdata(&dev->dev);
     66
     67	maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/20,
     68		MAPLE_FUNC_CONTROLLER);
     69
     70	return 0;
     71}
     72
     73static void dc_pad_close(struct input_dev *dev)
     74{
     75	struct dc_pad *pad = dev_get_platdata(&dev->dev);
     76
     77	maple_getcond_callback(pad->mdev, dc_pad_callback, 0,
     78		MAPLE_FUNC_CONTROLLER);
     79}
     80
     81/* allow the controller to be used */
     82static int probe_maple_controller(struct device *dev)
     83{
     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,
     89	};
     90
     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,
     96	};
     97
     98	struct maple_device *mdev = to_maple_dev(dev);
     99	struct maple_driver *mdrv = to_maple_driver(dev->driver);
    100	int i, error;
    101	struct dc_pad *pad;
    102	struct input_dev *idev;
    103	unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
    104
    105	pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
    106	idev = input_allocate_device();
    107	if (!pad || !idev) {
    108		error = -ENOMEM;
    109		goto fail;
    110	}
    111
    112	pad->dev = idev;
    113	pad->mdev = mdev;
    114
    115	idev->open = dc_pad_open;
    116	idev->close = dc_pad_close;
    117
    118	for (i = 0; i < 32; i++) {
    119		if (data & (1 << i)) {
    120			if (btn_bit[i] >= 0)
    121				__set_bit(btn_bit[i], idev->keybit);
    122			else if (abs_bit[i] >= 0)
    123				__set_bit(abs_bit[i], idev->absbit);
    124		}
    125	}
    126
    127	if (idev->keybit[BIT_WORD(BTN_JOYSTICK)])
    128		idev->evbit[0] |= BIT_MASK(EV_KEY);
    129
    130	if (idev->absbit[0])
    131		idev->evbit[0] |= BIT_MASK(EV_ABS);
    132
    133	for (i = ABS_X; i <= ABS_BRAKE; i++)
    134		input_set_abs_params(idev, i, 0, 255, 0, 0);
    135
    136	for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++)
    137		input_set_abs_params(idev, i, 1, -1, 0, 0);
    138
    139	idev->dev.platform_data = pad;
    140	idev->dev.parent = &mdev->dev;
    141	idev->name = mdev->product_name;
    142	idev->id.bustype = BUS_HOST;
    143
    144	error = input_register_device(idev);
    145	if (error)
    146		goto fail;
    147
    148	mdev->driver = mdrv;
    149	maple_set_drvdata(mdev, pad);
    150
    151	return 0;
    152
    153fail:
    154	input_free_device(idev);
    155	kfree(pad);
    156	maple_set_drvdata(mdev, NULL);
    157	return error;
    158}
    159
    160static int remove_maple_controller(struct device *dev)
    161{
    162	struct maple_device *mdev = to_maple_dev(dev);
    163	struct dc_pad *pad = maple_get_drvdata(mdev);
    164
    165	mdev->callback = NULL;
    166	input_unregister_device(pad->dev);
    167	maple_set_drvdata(mdev, NULL);
    168	kfree(pad);
    169
    170	return 0;
    171}
    172
    173static struct maple_driver dc_pad_driver = {
    174	.function =	MAPLE_FUNC_CONTROLLER,
    175	.drv = {
    176		.name	= "Dreamcast_controller",
    177		.probe	= probe_maple_controller,
    178		.remove	= remove_maple_controller,
    179	},
    180};
    181
    182static int __init dc_pad_init(void)
    183{
    184	return maple_driver_register(&dc_pad_driver);
    185}
    186
    187static void __exit dc_pad_exit(void)
    188{
    189	maple_driver_unregister(&dc_pad_driver);
    190}
    191
    192module_init(dc_pad_init);
    193module_exit(dc_pad_exit);