1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 1999-2001 Vojtech Pavlik 4 * 5 * Based on the work of: 6 * David Thompson 7 * Joseph Krahn 8 */ 9 10 /* 11 * SpaceTec SpaceBall 2003/3003/4000 FLX driver for Linux 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/module.h> 17 #include <linux/input.h> 18 #include <linux/serio.h> 19 #include <asm/unaligned.h> 20 21 #define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver" 22 23 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 24 MODULE_DESCRIPTION(DRIVER_DESC); 25 MODULE_LICENSE("GPL"); 26 27 /* 28 * Constants. 29 */ 30 31 #define SPACEBALL_MAX_LENGTH 128 32 #define SPACEBALL_MAX_ID 9 33 34 #define SPACEBALL_1003 1 35 #define SPACEBALL_2003B 3 36 #define SPACEBALL_2003C 4 37 #define SPACEBALL_3003C 7 38 #define SPACEBALL_4000FLX 8 39 #define SPACEBALL_4000FLX_L 9 40 41 static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY }; 42 static char *spaceball_names[] = { 43 "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B", 44 "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController", 45 "SpaceTec SpaceBall 3003C", "SpaceTec SpaceBall 4000FLX", "SpaceTec SpaceBall 4000FLX Lefty" }; 46 47 /* 48 * Per-Ball data. 49 */ 50 51 struct spaceball { 52 struct input_dev *dev; 53 int idx; 54 int escape; 55 unsigned char data[SPACEBALL_MAX_LENGTH]; 56 char phys[32]; 57 }; 58 59 /* 60 * spaceball_process_packet() decodes packets the driver receives from the 61 * SpaceBall. 62 */ 63 64 static void spaceball_process_packet(struct spaceball* spaceball) 65 { 66 struct input_dev *dev = spaceball->dev; 67 unsigned char *data = spaceball->data; 68 int i; 69 70 if (spaceball->idx < 2) return; 71 72 switch (spaceball->data[0]) { 73 74 case 'D': /* Ball data */ 75 if (spaceball->idx != 15) return; 76 /* 77 * Skip first three bytes; read six axes worth of data. 78 * Axis values are signed 16-bit big-endian. 79 */ 80 data += 3; 81 for (i = 0; i < ARRAY_SIZE(spaceball_axes); i++) { 82 input_report_abs(dev, spaceball_axes[i], 83 (__s16)get_unaligned_be16(&data[i * 2])); 84 } 85 break; 86 87 case 'K': /* Button data */ 88 if (spaceball->idx != 3) return; 89 input_report_key(dev, BTN_1, (data[2] & 0x01) || (data[2] & 0x20)); 90 input_report_key(dev, BTN_2, data[2] & 0x02); 91 input_report_key(dev, BTN_3, data[2] & 0x04); 92 input_report_key(dev, BTN_4, data[2] & 0x08); 93 input_report_key(dev, BTN_5, data[1] & 0x01); 94 input_report_key(dev, BTN_6, data[1] & 0x02); 95 input_report_key(dev, BTN_7, data[1] & 0x04); 96 input_report_key(dev, BTN_8, data[1] & 0x10); 97 break; 98 99 case '.': /* Advanced button data */ 100 if (spaceball->idx != 3) return; 101 input_report_key(dev, BTN_1, data[2] & 0x01); 102 input_report_key(dev, BTN_2, data[2] & 0x02); 103 input_report_key(dev, BTN_3, data[2] & 0x04); 104 input_report_key(dev, BTN_4, data[2] & 0x08); 105 input_report_key(dev, BTN_5, data[2] & 0x10); 106 input_report_key(dev, BTN_6, data[2] & 0x20); 107 input_report_key(dev, BTN_7, data[2] & 0x80); 108 input_report_key(dev, BTN_8, data[1] & 0x01); 109 input_report_key(dev, BTN_9, data[1] & 0x02); 110 input_report_key(dev, BTN_A, data[1] & 0x04); 111 input_report_key(dev, BTN_B, data[1] & 0x08); 112 input_report_key(dev, BTN_C, data[1] & 0x10); 113 input_report_key(dev, BTN_MODE, data[1] & 0x20); 114 break; 115 116 case 'E': /* Device error */ 117 spaceball->data[spaceball->idx - 1] = 0; 118 printk(KERN_ERR "spaceball: Device error. [%s]\n", spaceball->data + 1); 119 break; 120 121 case '?': /* Bad command packet */ 122 spaceball->data[spaceball->idx - 1] = 0; 123 printk(KERN_ERR "spaceball: Bad command. [%s]\n", spaceball->data + 1); 124 break; 125 } 126 127 input_sync(dev); 128 } 129 130 /* 131 * Spaceball 4000 FLX packets all start with a one letter packet-type decriptor, 132 * and end in 0x0d. It uses '^' as an escape for CR, XOFF and XON characters which 133 * can occur in the axis values. 134 */ 135 136 static irqreturn_t spaceball_interrupt(struct serio *serio, 137 unsigned char data, unsigned int flags) 138 { 139 struct spaceball *spaceball = serio_get_drvdata(serio); 140 141 switch (data) { 142 case 0xd: 143 spaceball_process_packet(spaceball); 144 spaceball->idx = 0; 145 spaceball->escape = 0; 146 break; 147 case '^': 148 if (!spaceball->escape) { 149 spaceball->escape = 1; 150 break; 151 } 152 spaceball->escape = 0; 153 fallthrough; 154 case 'M': 155 case 'Q': 156 case 'S': 157 if (spaceball->escape) { 158 spaceball->escape = 0; 159 data &= 0x1f; 160 } 161 fallthrough; 162 default: 163 if (spaceball->escape) 164 spaceball->escape = 0; 165 if (spaceball->idx < SPACEBALL_MAX_LENGTH) 166 spaceball->data[spaceball->idx++] = data; 167 break; 168 } 169 return IRQ_HANDLED; 170 } 171 172 /* 173 * spaceball_disconnect() is the opposite of spaceball_connect() 174 */ 175 176 static void spaceball_disconnect(struct serio *serio) 177 { 178 struct spaceball* spaceball = serio_get_drvdata(serio); 179 180 serio_close(serio); 181 serio_set_drvdata(serio, NULL); 182 input_unregister_device(spaceball->dev); 183 kfree(spaceball); 184 } 185 186 /* 187 * spaceball_connect() is the routine that is called when someone adds a 188 * new serio device that supports Spaceball protocol and registers it as 189 * an input device. 190 */ 191 192 static int spaceball_connect(struct serio *serio, struct serio_driver *drv) 193 { 194 struct spaceball *spaceball; 195 struct input_dev *input_dev; 196 int err = -ENOMEM; 197 int i, id; 198 199 if ((id = serio->id.id) > SPACEBALL_MAX_ID) 200 return -ENODEV; 201 202 spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); 203 input_dev = input_allocate_device(); 204 if (!spaceball || !input_dev) 205 goto fail1; 206 207 spaceball->dev = input_dev; 208 snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); 209 210 input_dev->name = spaceball_names[id]; 211 input_dev->phys = spaceball->phys; 212 input_dev->id.bustype = BUS_RS232; 213 input_dev->id.vendor = SERIO_SPACEBALL; 214 input_dev->id.product = id; 215 input_dev->id.version = 0x0100; 216 input_dev->dev.parent = &serio->dev; 217 218 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 219 220 switch (id) { 221 case SPACEBALL_4000FLX: 222 case SPACEBALL_4000FLX_L: 223 input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_9); 224 input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) | 225 BIT_MASK(BTN_B) | BIT_MASK(BTN_C) | 226 BIT_MASK(BTN_MODE); 227 fallthrough; 228 default: 229 input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) | 230 BIT_MASK(BTN_3) | BIT_MASK(BTN_4) | 231 BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | 232 BIT_MASK(BTN_7) | BIT_MASK(BTN_8); 233 fallthrough; 234 case SPACEBALL_3003C: 235 input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) | 236 BIT_MASK(BTN_8); 237 } 238 239 for (i = 0; i < 3; i++) { 240 input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40); 241 input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8); 242 } 243 244 serio_set_drvdata(serio, spaceball); 245 246 err = serio_open(serio, drv); 247 if (err) 248 goto fail2; 249 250 err = input_register_device(spaceball->dev); 251 if (err) 252 goto fail3; 253 254 return 0; 255 256 fail3: serio_close(serio); 257 fail2: serio_set_drvdata(serio, NULL); 258 fail1: input_free_device(input_dev); 259 kfree(spaceball); 260 return err; 261 } 262 263 /* 264 * The serio driver structure. 265 */ 266 267 static const struct serio_device_id spaceball_serio_ids[] = { 268 { 269 .type = SERIO_RS232, 270 .proto = SERIO_SPACEBALL, 271 .id = SERIO_ANY, 272 .extra = SERIO_ANY, 273 }, 274 { 0 } 275 }; 276 277 MODULE_DEVICE_TABLE(serio, spaceball_serio_ids); 278 279 static struct serio_driver spaceball_drv = { 280 .driver = { 281 .name = "spaceball", 282 }, 283 .description = DRIVER_DESC, 284 .id_table = spaceball_serio_ids, 285 .interrupt = spaceball_interrupt, 286 .connect = spaceball_connect, 287 .disconnect = spaceball_disconnect, 288 }; 289 290 module_serio_driver(spaceball_drv); 291