Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Support for the four N64 controllers.
0004  *
0005  * Copyright (c) 2021 Lauri Kasanen
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #include <linux/errno.h>
0011 #include <linux/init.h>
0012 #include <linux/input.h>
0013 #include <linux/limits.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/mutex.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/slab.h>
0019 #include <linux/timer.h>
0020 
0021 MODULE_AUTHOR("Lauri Kasanen <cand@gmx.com>");
0022 MODULE_DESCRIPTION("Driver for N64 controllers");
0023 MODULE_LICENSE("GPL");
0024 
0025 #define PIF_RAM 0x1fc007c0
0026 
0027 #define SI_DRAM_REG 0
0028 #define SI_READ_REG 1
0029 #define SI_WRITE_REG 4
0030 #define SI_STATUS_REG 6
0031 
0032 #define SI_STATUS_DMA_BUSY  BIT(0)
0033 #define SI_STATUS_IO_BUSY   BIT(1)
0034 
0035 #define N64_CONTROLLER_ID 0x0500
0036 
0037 #define MAX_CONTROLLERS 4
0038 
0039 static const char *n64joy_phys[MAX_CONTROLLERS] = {
0040     "n64joy/port0",
0041     "n64joy/port1",
0042     "n64joy/port2",
0043     "n64joy/port3",
0044 };
0045 
0046 struct n64joy_priv {
0047     u64 si_buf[8] ____cacheline_aligned;
0048     struct timer_list timer;
0049     struct mutex n64joy_mutex;
0050     struct input_dev *n64joy_dev[MAX_CONTROLLERS];
0051     u32 __iomem *reg_base;
0052     u8 n64joy_opened;
0053 };
0054 
0055 struct joydata {
0056     unsigned int: 16; /* unused */
0057     unsigned int err: 2;
0058     unsigned int: 14; /* unused */
0059 
0060     union {
0061         u32 data;
0062 
0063         struct {
0064             unsigned int a: 1;
0065             unsigned int b: 1;
0066             unsigned int z: 1;
0067             unsigned int start: 1;
0068             unsigned int up: 1;
0069             unsigned int down: 1;
0070             unsigned int left: 1;
0071             unsigned int right: 1;
0072             unsigned int: 2; /* unused */
0073             unsigned int l: 1;
0074             unsigned int r: 1;
0075             unsigned int c_up: 1;
0076             unsigned int c_down: 1;
0077             unsigned int c_left: 1;
0078             unsigned int c_right: 1;
0079             signed int x: 8;
0080             signed int y: 8;
0081         };
0082     };
0083 };
0084 
0085 static void n64joy_write_reg(u32 __iomem *reg_base, const u8 reg, const u32 value)
0086 {
0087     writel(value, reg_base + reg);
0088 }
0089 
0090 static u32 n64joy_read_reg(u32 __iomem *reg_base, const u8 reg)
0091 {
0092     return readl(reg_base + reg);
0093 }
0094 
0095 static void n64joy_wait_si_dma(u32 __iomem *reg_base)
0096 {
0097     while (n64joy_read_reg(reg_base, SI_STATUS_REG) &
0098            (SI_STATUS_DMA_BUSY | SI_STATUS_IO_BUSY))
0099         cpu_relax();
0100 }
0101 
0102 static void n64joy_exec_pif(struct n64joy_priv *priv, const u64 in[8])
0103 {
0104     unsigned long flags;
0105 
0106     dma_cache_wback_inv((unsigned long) in, 8 * 8);
0107     dma_cache_inv((unsigned long) priv->si_buf, 8 * 8);
0108 
0109     local_irq_save(flags);
0110 
0111     n64joy_wait_si_dma(priv->reg_base);
0112 
0113     barrier();
0114     n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(in));
0115     barrier();
0116     n64joy_write_reg(priv->reg_base, SI_WRITE_REG, PIF_RAM);
0117     barrier();
0118 
0119     n64joy_wait_si_dma(priv->reg_base);
0120 
0121     barrier();
0122     n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(priv->si_buf));
0123     barrier();
0124     n64joy_write_reg(priv->reg_base, SI_READ_REG, PIF_RAM);
0125     barrier();
0126 
0127     n64joy_wait_si_dma(priv->reg_base);
0128 
0129     local_irq_restore(flags);
0130 }
0131 
0132 static const u64 polldata[] ____cacheline_aligned = {
0133     0xff010401ffffffff,
0134     0xff010401ffffffff,
0135     0xff010401ffffffff,
0136     0xff010401ffffffff,
0137     0xfe00000000000000,
0138     0,
0139     0,
0140     1
0141 };
0142 
0143 static void n64joy_poll(struct timer_list *t)
0144 {
0145     const struct joydata *data;
0146     struct n64joy_priv *priv = container_of(t, struct n64joy_priv, timer);
0147     struct input_dev *dev;
0148     u32 i;
0149 
0150     n64joy_exec_pif(priv, polldata);
0151 
0152     data = (struct joydata *) priv->si_buf;
0153 
0154     for (i = 0; i < MAX_CONTROLLERS; i++) {
0155         if (!priv->n64joy_dev[i])
0156             continue;
0157 
0158         dev = priv->n64joy_dev[i];
0159 
0160         /* d-pad */
0161         input_report_key(dev, BTN_DPAD_UP, data[i].up);
0162         input_report_key(dev, BTN_DPAD_DOWN, data[i].down);
0163         input_report_key(dev, BTN_DPAD_LEFT, data[i].left);
0164         input_report_key(dev, BTN_DPAD_RIGHT, data[i].right);
0165 
0166         /* c buttons */
0167         input_report_key(dev, BTN_FORWARD, data[i].c_up);
0168         input_report_key(dev, BTN_BACK, data[i].c_down);
0169         input_report_key(dev, BTN_LEFT, data[i].c_left);
0170         input_report_key(dev, BTN_RIGHT, data[i].c_right);
0171 
0172         /* matching buttons */
0173         input_report_key(dev, BTN_START, data[i].start);
0174         input_report_key(dev, BTN_Z, data[i].z);
0175 
0176         /* remaining ones: a, b, l, r */
0177         input_report_key(dev, BTN_0, data[i].a);
0178         input_report_key(dev, BTN_1, data[i].b);
0179         input_report_key(dev, BTN_2, data[i].l);
0180         input_report_key(dev, BTN_3, data[i].r);
0181 
0182         input_report_abs(dev, ABS_X, data[i].x);
0183         input_report_abs(dev, ABS_Y, data[i].y);
0184 
0185         input_sync(dev);
0186     }
0187 
0188     mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16));
0189 }
0190 
0191 static int n64joy_open(struct input_dev *dev)
0192 {
0193     struct n64joy_priv *priv = input_get_drvdata(dev);
0194     int err;
0195 
0196     err = mutex_lock_interruptible(&priv->n64joy_mutex);
0197     if (err)
0198         return err;
0199 
0200     if (!priv->n64joy_opened) {
0201         /*
0202          * We could use the vblank irq, but it's not important if
0203          * the poll point slightly changes.
0204          */
0205         timer_setup(&priv->timer, n64joy_poll, 0);
0206         mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16));
0207     }
0208 
0209     priv->n64joy_opened++;
0210 
0211     mutex_unlock(&priv->n64joy_mutex);
0212     return err;
0213 }
0214 
0215 static void n64joy_close(struct input_dev *dev)
0216 {
0217     struct n64joy_priv *priv = input_get_drvdata(dev);
0218 
0219     mutex_lock(&priv->n64joy_mutex);
0220     if (!--priv->n64joy_opened)
0221         del_timer_sync(&priv->timer);
0222     mutex_unlock(&priv->n64joy_mutex);
0223 }
0224 
0225 static const u64 __initconst scandata[] ____cacheline_aligned = {
0226     0xff010300ffffffff,
0227     0xff010300ffffffff,
0228     0xff010300ffffffff,
0229     0xff010300ffffffff,
0230     0xfe00000000000000,
0231     0,
0232     0,
0233     1
0234 };
0235 
0236 /*
0237  * The target device is embedded and RAM-constrained. We save RAM
0238  * by initializing in __init code that gets dropped late in boot.
0239  * For the same reason there is no module or unloading support.
0240  */
0241 static int __init n64joy_probe(struct platform_device *pdev)
0242 {
0243     const struct joydata *data;
0244     struct n64joy_priv *priv;
0245     struct input_dev *dev;
0246     int err = 0;
0247     u32 i, j, found = 0;
0248 
0249     priv = kzalloc(sizeof(struct n64joy_priv), GFP_KERNEL);
0250     if (!priv)
0251         return -ENOMEM;
0252     mutex_init(&priv->n64joy_mutex);
0253 
0254     priv->reg_base = devm_platform_ioremap_resource(pdev, 0);
0255     if (IS_ERR(priv->reg_base)) {
0256         err = PTR_ERR(priv->reg_base);
0257         goto fail;
0258     }
0259 
0260     /* The controllers are not hotpluggable, so we can scan in init */
0261     n64joy_exec_pif(priv, scandata);
0262 
0263     data = (struct joydata *) priv->si_buf;
0264 
0265     for (i = 0; i < MAX_CONTROLLERS; i++) {
0266         if (!data[i].err && data[i].data >> 16 == N64_CONTROLLER_ID) {
0267             found++;
0268 
0269             dev = priv->n64joy_dev[i] = input_allocate_device();
0270             if (!priv->n64joy_dev[i]) {
0271                 err = -ENOMEM;
0272                 goto fail;
0273             }
0274 
0275             input_set_drvdata(dev, priv);
0276 
0277             dev->name = "N64 controller";
0278             dev->phys = n64joy_phys[i];
0279             dev->id.bustype = BUS_HOST;
0280             dev->id.vendor = 0;
0281             dev->id.product = data[i].data >> 16;
0282             dev->id.version = 0;
0283             dev->dev.parent = &pdev->dev;
0284 
0285             dev->open = n64joy_open;
0286             dev->close = n64joy_close;
0287 
0288             /* d-pad */
0289             input_set_capability(dev, EV_KEY, BTN_DPAD_UP);
0290             input_set_capability(dev, EV_KEY, BTN_DPAD_DOWN);
0291             input_set_capability(dev, EV_KEY, BTN_DPAD_LEFT);
0292             input_set_capability(dev, EV_KEY, BTN_DPAD_RIGHT);
0293             /* c buttons */
0294             input_set_capability(dev, EV_KEY, BTN_LEFT);
0295             input_set_capability(dev, EV_KEY, BTN_RIGHT);
0296             input_set_capability(dev, EV_KEY, BTN_FORWARD);
0297             input_set_capability(dev, EV_KEY, BTN_BACK);
0298             /* matching buttons */
0299             input_set_capability(dev, EV_KEY, BTN_START);
0300             input_set_capability(dev, EV_KEY, BTN_Z);
0301             /* remaining ones: a, b, l, r */
0302             input_set_capability(dev, EV_KEY, BTN_0);
0303             input_set_capability(dev, EV_KEY, BTN_1);
0304             input_set_capability(dev, EV_KEY, BTN_2);
0305             input_set_capability(dev, EV_KEY, BTN_3);
0306 
0307             for (j = 0; j < 2; j++)
0308                 input_set_abs_params(dev, ABS_X + j,
0309                              S8_MIN, S8_MAX, 0, 0);
0310 
0311             err = input_register_device(dev);
0312             if (err) {
0313                 input_free_device(dev);
0314                 goto fail;
0315             }
0316         }
0317     }
0318 
0319     pr_info("%u controller(s) connected\n", found);
0320 
0321     if (!found)
0322         return -ENODEV;
0323 
0324     return 0;
0325 fail:
0326     for (i = 0; i < MAX_CONTROLLERS; i++) {
0327         if (!priv->n64joy_dev[i])
0328             continue;
0329         input_unregister_device(priv->n64joy_dev[i]);
0330     }
0331     return err;
0332 }
0333 
0334 static struct platform_driver n64joy_driver = {
0335     .driver = {
0336         .name = "n64joy",
0337     },
0338 };
0339 
0340 static int __init n64joy_init(void)
0341 {
0342     return platform_driver_probe(&n64joy_driver, n64joy_probe);
0343 }
0344 
0345 module_init(n64joy_init);