1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for the four N64 controllers. 4 * 5 * Copyright (c) 2021 Lauri Kasanen 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/errno.h> 11 #include <linux/init.h> 12 #include <linux/input.h> 13 #include <linux/limits.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/mutex.h> 17 #include <linux/platform_device.h> 18 #include <linux/slab.h> 19 #include <linux/timer.h> 20 21 MODULE_AUTHOR("Lauri Kasanen <cand@gmx.com>"); 22 MODULE_DESCRIPTION("Driver for N64 controllers"); 23 MODULE_LICENSE("GPL"); 24 25 #define PIF_RAM 0x1fc007c0 26 27 #define SI_DRAM_REG 0 28 #define SI_READ_REG 1 29 #define SI_WRITE_REG 4 30 #define SI_STATUS_REG 6 31 32 #define SI_STATUS_DMA_BUSY BIT(0) 33 #define SI_STATUS_IO_BUSY BIT(1) 34 35 #define N64_CONTROLLER_ID 0x0500 36 37 #define MAX_CONTROLLERS 4 38 39 static const char *n64joy_phys[MAX_CONTROLLERS] = { 40 "n64joy/port0", 41 "n64joy/port1", 42 "n64joy/port2", 43 "n64joy/port3", 44 }; 45 46 struct n64joy_priv { 47 u64 si_buf[8] ____cacheline_aligned; 48 struct timer_list timer; 49 struct mutex n64joy_mutex; 50 struct input_dev *n64joy_dev[MAX_CONTROLLERS]; 51 u32 __iomem *reg_base; 52 u8 n64joy_opened; 53 }; 54 55 struct joydata { 56 unsigned int: 16; /* unused */ 57 unsigned int err: 2; 58 unsigned int: 14; /* unused */ 59 60 union { 61 u32 data; 62 63 struct { 64 unsigned int a: 1; 65 unsigned int b: 1; 66 unsigned int z: 1; 67 unsigned int start: 1; 68 unsigned int up: 1; 69 unsigned int down: 1; 70 unsigned int left: 1; 71 unsigned int right: 1; 72 unsigned int: 2; /* unused */ 73 unsigned int l: 1; 74 unsigned int r: 1; 75 unsigned int c_up: 1; 76 unsigned int c_down: 1; 77 unsigned int c_left: 1; 78 unsigned int c_right: 1; 79 signed int x: 8; 80 signed int y: 8; 81 }; 82 }; 83 }; 84 85 static void n64joy_write_reg(u32 __iomem *reg_base, const u8 reg, const u32 value) 86 { 87 writel(value, reg_base + reg); 88 } 89 90 static u32 n64joy_read_reg(u32 __iomem *reg_base, const u8 reg) 91 { 92 return readl(reg_base + reg); 93 } 94 95 static void n64joy_wait_si_dma(u32 __iomem *reg_base) 96 { 97 while (n64joy_read_reg(reg_base, SI_STATUS_REG) & 98 (SI_STATUS_DMA_BUSY | SI_STATUS_IO_BUSY)) 99 cpu_relax(); 100 } 101 102 static void n64joy_exec_pif(struct n64joy_priv *priv, const u64 in[8]) 103 { 104 unsigned long flags; 105 106 dma_cache_wback_inv((unsigned long) in, 8 * 8); 107 dma_cache_inv((unsigned long) priv->si_buf, 8 * 8); 108 109 local_irq_save(flags); 110 111 n64joy_wait_si_dma(priv->reg_base); 112 113 barrier(); 114 n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(in)); 115 barrier(); 116 n64joy_write_reg(priv->reg_base, SI_WRITE_REG, PIF_RAM); 117 barrier(); 118 119 n64joy_wait_si_dma(priv->reg_base); 120 121 barrier(); 122 n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(priv->si_buf)); 123 barrier(); 124 n64joy_write_reg(priv->reg_base, SI_READ_REG, PIF_RAM); 125 barrier(); 126 127 n64joy_wait_si_dma(priv->reg_base); 128 129 local_irq_restore(flags); 130 } 131 132 static const u64 polldata[] ____cacheline_aligned = { 133 0xff010401ffffffff, 134 0xff010401ffffffff, 135 0xff010401ffffffff, 136 0xff010401ffffffff, 137 0xfe00000000000000, 138 0, 139 0, 140 1 141 }; 142 143 static void n64joy_poll(struct timer_list *t) 144 { 145 const struct joydata *data; 146 struct n64joy_priv *priv = container_of(t, struct n64joy_priv, timer); 147 struct input_dev *dev; 148 u32 i; 149 150 n64joy_exec_pif(priv, polldata); 151 152 data = (struct joydata *) priv->si_buf; 153 154 for (i = 0; i < MAX_CONTROLLERS; i++) { 155 if (!priv->n64joy_dev[i]) 156 continue; 157 158 dev = priv->n64joy_dev[i]; 159 160 /* d-pad */ 161 input_report_key(dev, BTN_DPAD_UP, data[i].up); 162 input_report_key(dev, BTN_DPAD_DOWN, data[i].down); 163 input_report_key(dev, BTN_DPAD_LEFT, data[i].left); 164 input_report_key(dev, BTN_DPAD_RIGHT, data[i].right); 165 166 /* c buttons */ 167 input_report_key(dev, BTN_FORWARD, data[i].c_up); 168 input_report_key(dev, BTN_BACK, data[i].c_down); 169 input_report_key(dev, BTN_LEFT, data[i].c_left); 170 input_report_key(dev, BTN_RIGHT, data[i].c_right); 171 172 /* matching buttons */ 173 input_report_key(dev, BTN_START, data[i].start); 174 input_report_key(dev, BTN_Z, data[i].z); 175 176 /* remaining ones: a, b, l, r */ 177 input_report_key(dev, BTN_0, data[i].a); 178 input_report_key(dev, BTN_1, data[i].b); 179 input_report_key(dev, BTN_2, data[i].l); 180 input_report_key(dev, BTN_3, data[i].r); 181 182 input_report_abs(dev, ABS_X, data[i].x); 183 input_report_abs(dev, ABS_Y, data[i].y); 184 185 input_sync(dev); 186 } 187 188 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16)); 189 } 190 191 static int n64joy_open(struct input_dev *dev) 192 { 193 struct n64joy_priv *priv = input_get_drvdata(dev); 194 195 scoped_guard(mutex_intr, &priv->n64joy_mutex) { 196 if (!priv->n64joy_opened) { 197 /* 198 * We could use the vblank irq, but it's not important 199 * if the poll point slightly changes. 200 */ 201 timer_setup(&priv->timer, n64joy_poll, 0); 202 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16)); 203 } 204 205 priv->n64joy_opened++; 206 return 0; 207 } 208 209 return -EINTR; 210 } 211 212 static void n64joy_close(struct input_dev *dev) 213 { 214 struct n64joy_priv *priv = input_get_drvdata(dev); 215 216 guard(mutex)(&priv->n64joy_mutex); 217 218 if (!--priv->n64joy_opened) 219 del_timer_sync(&priv->timer); 220 } 221 222 static const u64 __initconst scandata[] ____cacheline_aligned = { 223 0xff010300ffffffff, 224 0xff010300ffffffff, 225 0xff010300ffffffff, 226 0xff010300ffffffff, 227 0xfe00000000000000, 228 0, 229 0, 230 1 231 }; 232 233 /* 234 * The target device is embedded and RAM-constrained. We save RAM 235 * by initializing in __init code that gets dropped late in boot. 236 * For the same reason there is no module or unloading support. 237 */ 238 static int __init n64joy_probe(struct platform_device *pdev) 239 { 240 const struct joydata *data; 241 struct n64joy_priv *priv; 242 struct input_dev *dev; 243 int err = 0; 244 u32 i, j, found = 0; 245 246 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 247 if (!priv) 248 return -ENOMEM; 249 mutex_init(&priv->n64joy_mutex); 250 251 priv->reg_base = devm_platform_ioremap_resource(pdev, 0); 252 if (IS_ERR(priv->reg_base)) { 253 err = PTR_ERR(priv->reg_base); 254 goto fail; 255 } 256 257 /* The controllers are not hotpluggable, so we can scan in init */ 258 n64joy_exec_pif(priv, scandata); 259 260 data = (struct joydata *) priv->si_buf; 261 262 for (i = 0; i < MAX_CONTROLLERS; i++) { 263 if (!data[i].err && data[i].data >> 16 == N64_CONTROLLER_ID) { 264 found++; 265 266 dev = priv->n64joy_dev[i] = input_allocate_device(); 267 if (!priv->n64joy_dev[i]) { 268 err = -ENOMEM; 269 goto fail; 270 } 271 272 input_set_drvdata(dev, priv); 273 274 dev->name = "N64 controller"; 275 dev->phys = n64joy_phys[i]; 276 dev->id.bustype = BUS_HOST; 277 dev->id.vendor = 0; 278 dev->id.product = data[i].data >> 16; 279 dev->id.version = 0; 280 dev->dev.parent = &pdev->dev; 281 282 dev->open = n64joy_open; 283 dev->close = n64joy_close; 284 285 /* d-pad */ 286 input_set_capability(dev, EV_KEY, BTN_DPAD_UP); 287 input_set_capability(dev, EV_KEY, BTN_DPAD_DOWN); 288 input_set_capability(dev, EV_KEY, BTN_DPAD_LEFT); 289 input_set_capability(dev, EV_KEY, BTN_DPAD_RIGHT); 290 /* c buttons */ 291 input_set_capability(dev, EV_KEY, BTN_LEFT); 292 input_set_capability(dev, EV_KEY, BTN_RIGHT); 293 input_set_capability(dev, EV_KEY, BTN_FORWARD); 294 input_set_capability(dev, EV_KEY, BTN_BACK); 295 /* matching buttons */ 296 input_set_capability(dev, EV_KEY, BTN_START); 297 input_set_capability(dev, EV_KEY, BTN_Z); 298 /* remaining ones: a, b, l, r */ 299 input_set_capability(dev, EV_KEY, BTN_0); 300 input_set_capability(dev, EV_KEY, BTN_1); 301 input_set_capability(dev, EV_KEY, BTN_2); 302 input_set_capability(dev, EV_KEY, BTN_3); 303 304 for (j = 0; j < 2; j++) 305 input_set_abs_params(dev, ABS_X + j, 306 S8_MIN, S8_MAX, 0, 0); 307 308 err = input_register_device(dev); 309 if (err) { 310 input_free_device(dev); 311 goto fail; 312 } 313 } 314 } 315 316 pr_info("%u controller(s) connected\n", found); 317 318 if (!found) 319 return -ENODEV; 320 321 return 0; 322 fail: 323 for (i = 0; i < MAX_CONTROLLERS; i++) { 324 if (!priv->n64joy_dev[i]) 325 continue; 326 input_unregister_device(priv->n64joy_dev[i]); 327 } 328 return err; 329 } 330 331 static struct platform_driver n64joy_driver = { 332 .driver = { 333 .name = "n64joy", 334 }, 335 }; 336 337 static int __init n64joy_init(void) 338 { 339 return platform_driver_probe(&n64joy_driver, n64joy_probe); 340 } 341 342 module_init(n64joy_init); 343