1bf21cd93STycho Nightingale /*- 24c87aefeSPatrick Mooney * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 34c87aefeSPatrick Mooney * 4bf21cd93STycho Nightingale * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 5bf21cd93STycho Nightingale * Copyright (c) 2015 Nahanni Systems Inc. 6bf21cd93STycho Nightingale * All rights reserved. 7bf21cd93STycho Nightingale * 8bf21cd93STycho Nightingale * Redistribution and use in source and binary forms, with or without 9bf21cd93STycho Nightingale * modification, are permitted provided that the following conditions 10bf21cd93STycho Nightingale * are met: 11bf21cd93STycho Nightingale * 1. Redistributions of source code must retain the above copyright 12bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer. 13bf21cd93STycho Nightingale * 2. Redistributions in binary form must reproduce the above copyright 14bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer in the 15bf21cd93STycho Nightingale * documentation and/or other materials provided with the distribution. 16bf21cd93STycho Nightingale * 17bf21cd93STycho Nightingale * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 18bf21cd93STycho Nightingale * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19bf21cd93STycho Nightingale * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20bf21cd93STycho Nightingale * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21bf21cd93STycho Nightingale * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22bf21cd93STycho Nightingale * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23bf21cd93STycho Nightingale * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24bf21cd93STycho Nightingale * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25bf21cd93STycho Nightingale * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26bf21cd93STycho Nightingale * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27bf21cd93STycho Nightingale * SUCH DAMAGE. 28bf21cd93STycho Nightingale */ 29bf21cd93STycho Nightingale 30bf21cd93STycho Nightingale #include <sys/cdefs.h> 31bf21cd93STycho Nightingale __FBSDID("$FreeBSD$"); 32bf21cd93STycho Nightingale 33bf21cd93STycho Nightingale #include <sys/types.h> 34bf21cd93STycho Nightingale 35bf21cd93STycho Nightingale #include <assert.h> 36bf21cd93STycho Nightingale #include <stdbool.h> 37bf21cd93STycho Nightingale #include <stdio.h> 38bf21cd93STycho Nightingale #include <stdlib.h> 39bf21cd93STycho Nightingale #include <strings.h> 40bf21cd93STycho Nightingale #include <pthread.h> 41bf21cd93STycho Nightingale #include <pthread_np.h> 42bf21cd93STycho Nightingale 43bf21cd93STycho Nightingale #include "atkbdc.h" 44bf21cd93STycho Nightingale #include "console.h" 45*59d65d31SAndy Fiddaman #include "debug.h" 46*59d65d31SAndy Fiddaman #include "ps2mouse.h" 47bf21cd93STycho Nightingale 48bf21cd93STycho Nightingale /* mouse device commands */ 49bf21cd93STycho Nightingale #define PS2MC_RESET_DEV 0xff 50bf21cd93STycho Nightingale #define PS2MC_SET_DEFAULTS 0xf6 51bf21cd93STycho Nightingale #define PS2MC_DISABLE 0xf5 52bf21cd93STycho Nightingale #define PS2MC_ENABLE 0xf4 53bf21cd93STycho Nightingale #define PS2MC_SET_SAMPLING_RATE 0xf3 54bf21cd93STycho Nightingale #define PS2MC_SEND_DEV_ID 0xf2 55bf21cd93STycho Nightingale #define PS2MC_SET_REMOTE_MODE 0xf0 56bf21cd93STycho Nightingale #define PS2MC_SEND_DEV_DATA 0xeb 57bf21cd93STycho Nightingale #define PS2MC_SET_STREAM_MODE 0xea 58bf21cd93STycho Nightingale #define PS2MC_SEND_DEV_STATUS 0xe9 59bf21cd93STycho Nightingale #define PS2MC_SET_RESOLUTION 0xe8 60bf21cd93STycho Nightingale #define PS2MC_SET_SCALING1 0xe7 61bf21cd93STycho Nightingale #define PS2MC_SET_SCALING2 0xe6 62bf21cd93STycho Nightingale 63bf21cd93STycho Nightingale #define PS2MC_BAT_SUCCESS 0xaa 64bf21cd93STycho Nightingale #define PS2MC_ACK 0xfa 65bf21cd93STycho Nightingale 66bf21cd93STycho Nightingale /* mouse device id */ 67bf21cd93STycho Nightingale #define PS2MOUSE_DEV_ID 0x0 68bf21cd93STycho Nightingale 694c87aefeSPatrick Mooney /* mouse data bits */ 704c87aefeSPatrick Mooney #define PS2M_DATA_Y_OFLOW 0x80 714c87aefeSPatrick Mooney #define PS2M_DATA_X_OFLOW 0x40 724c87aefeSPatrick Mooney #define PS2M_DATA_Y_SIGN 0x20 734c87aefeSPatrick Mooney #define PS2M_DATA_X_SIGN 0x10 744c87aefeSPatrick Mooney #define PS2M_DATA_AONE 0x08 754c87aefeSPatrick Mooney #define PS2M_DATA_MID_BUTTON 0x04 764c87aefeSPatrick Mooney #define PS2M_DATA_RIGHT_BUTTON 0x02 774c87aefeSPatrick Mooney #define PS2M_DATA_LEFT_BUTTON 0x01 784c87aefeSPatrick Mooney 79bf21cd93STycho Nightingale /* mouse status bits */ 80bf21cd93STycho Nightingale #define PS2M_STS_REMOTE_MODE 0x40 81bf21cd93STycho Nightingale #define PS2M_STS_ENABLE_DEV 0x20 82bf21cd93STycho Nightingale #define PS2M_STS_SCALING_21 0x10 83bf21cd93STycho Nightingale #define PS2M_STS_MID_BUTTON 0x04 84bf21cd93STycho Nightingale #define PS2M_STS_RIGHT_BUTTON 0x02 85bf21cd93STycho Nightingale #define PS2M_STS_LEFT_BUTTON 0x01 86bf21cd93STycho Nightingale 87bf21cd93STycho Nightingale #define PS2MOUSE_FIFOSZ 16 88bf21cd93STycho Nightingale 89bf21cd93STycho Nightingale struct fifo { 90bf21cd93STycho Nightingale uint8_t buf[PS2MOUSE_FIFOSZ]; 91bf21cd93STycho Nightingale int rindex; /* index to read from */ 92bf21cd93STycho Nightingale int windex; /* index to write to */ 93bf21cd93STycho Nightingale int num; /* number of bytes in the fifo */ 94bf21cd93STycho Nightingale int size; /* size of the fifo */ 95bf21cd93STycho Nightingale }; 96bf21cd93STycho Nightingale 97bf21cd93STycho Nightingale struct ps2mouse_softc { 98bf21cd93STycho Nightingale struct atkbdc_softc *atkbdc_sc; 99bf21cd93STycho Nightingale pthread_mutex_t mtx; 100bf21cd93STycho Nightingale 101bf21cd93STycho Nightingale uint8_t status; 102bf21cd93STycho Nightingale uint8_t resolution; 103bf21cd93STycho Nightingale uint8_t sampling_rate; 1044c87aefeSPatrick Mooney int ctrlenable; 105bf21cd93STycho Nightingale struct fifo fifo; 106bf21cd93STycho Nightingale 107bf21cd93STycho Nightingale uint8_t curcmd; /* current command for next byte */ 108bf21cd93STycho Nightingale 109bf21cd93STycho Nightingale int cur_x, cur_y; 110bf21cd93STycho Nightingale int delta_x, delta_y; 111bf21cd93STycho Nightingale }; 112bf21cd93STycho Nightingale 113bf21cd93STycho Nightingale static void 114bf21cd93STycho Nightingale fifo_init(struct ps2mouse_softc *sc) 115bf21cd93STycho Nightingale { 116bf21cd93STycho Nightingale struct fifo *fifo; 117bf21cd93STycho Nightingale 118bf21cd93STycho Nightingale fifo = &sc->fifo; 119bf21cd93STycho Nightingale fifo->size = sizeof(((struct fifo *)0)->buf); 120bf21cd93STycho Nightingale } 121bf21cd93STycho Nightingale 122bf21cd93STycho Nightingale static void 123bf21cd93STycho Nightingale fifo_reset(struct ps2mouse_softc *sc) 124bf21cd93STycho Nightingale { 125bf21cd93STycho Nightingale struct fifo *fifo; 126bf21cd93STycho Nightingale 127bf21cd93STycho Nightingale fifo = &sc->fifo; 128bf21cd93STycho Nightingale bzero(fifo, sizeof(struct fifo)); 129bf21cd93STycho Nightingale fifo->size = sizeof(((struct fifo *)0)->buf); 130bf21cd93STycho Nightingale } 131bf21cd93STycho Nightingale 132bf21cd93STycho Nightingale static void 133bf21cd93STycho Nightingale fifo_put(struct ps2mouse_softc *sc, uint8_t val) 134bf21cd93STycho Nightingale { 135bf21cd93STycho Nightingale struct fifo *fifo; 136bf21cd93STycho Nightingale 137bf21cd93STycho Nightingale fifo = &sc->fifo; 138bf21cd93STycho Nightingale if (fifo->num < fifo->size) { 139bf21cd93STycho Nightingale fifo->buf[fifo->windex] = val; 140bf21cd93STycho Nightingale fifo->windex = (fifo->windex + 1) % fifo->size; 141bf21cd93STycho Nightingale fifo->num++; 142bf21cd93STycho Nightingale } 143bf21cd93STycho Nightingale } 144bf21cd93STycho Nightingale 145bf21cd93STycho Nightingale static int 146bf21cd93STycho Nightingale fifo_get(struct ps2mouse_softc *sc, uint8_t *val) 147bf21cd93STycho Nightingale { 148bf21cd93STycho Nightingale struct fifo *fifo; 149bf21cd93STycho Nightingale 150bf21cd93STycho Nightingale fifo = &sc->fifo; 151bf21cd93STycho Nightingale if (fifo->num > 0) { 152bf21cd93STycho Nightingale *val = fifo->buf[fifo->rindex]; 153bf21cd93STycho Nightingale fifo->rindex = (fifo->rindex + 1) % fifo->size; 154bf21cd93STycho Nightingale fifo->num--; 155bf21cd93STycho Nightingale return (0); 156bf21cd93STycho Nightingale } 157bf21cd93STycho Nightingale 158bf21cd93STycho Nightingale return (-1); 159bf21cd93STycho Nightingale } 160bf21cd93STycho Nightingale 161bf21cd93STycho Nightingale static void 162bf21cd93STycho Nightingale movement_reset(struct ps2mouse_softc *sc) 163bf21cd93STycho Nightingale { 164bf21cd93STycho Nightingale assert(pthread_mutex_isowned_np(&sc->mtx)); 165bf21cd93STycho Nightingale 166bf21cd93STycho Nightingale sc->delta_x = 0; 167bf21cd93STycho Nightingale sc->delta_y = 0; 168bf21cd93STycho Nightingale } 169bf21cd93STycho Nightingale 170bf21cd93STycho Nightingale static void 171bf21cd93STycho Nightingale movement_update(struct ps2mouse_softc *sc, int x, int y) 172bf21cd93STycho Nightingale { 173bf21cd93STycho Nightingale sc->delta_x += x - sc->cur_x; 174bf21cd93STycho Nightingale sc->delta_y += sc->cur_y - y; 175bf21cd93STycho Nightingale sc->cur_x = x; 176bf21cd93STycho Nightingale sc->cur_y = y; 177bf21cd93STycho Nightingale } 178bf21cd93STycho Nightingale 179bf21cd93STycho Nightingale static void 180bf21cd93STycho Nightingale movement_get(struct ps2mouse_softc *sc) 181bf21cd93STycho Nightingale { 182bf21cd93STycho Nightingale uint8_t val0, val1, val2; 183bf21cd93STycho Nightingale 184bf21cd93STycho Nightingale assert(pthread_mutex_isowned_np(&sc->mtx)); 185bf21cd93STycho Nightingale 1864c87aefeSPatrick Mooney val0 = PS2M_DATA_AONE; 1874c87aefeSPatrick Mooney val0 |= sc->status & (PS2M_DATA_LEFT_BUTTON | 1884c87aefeSPatrick Mooney PS2M_DATA_RIGHT_BUTTON | PS2M_DATA_MID_BUTTON); 189bf21cd93STycho Nightingale 190bf21cd93STycho Nightingale if (sc->delta_x >= 0) { 191bf21cd93STycho Nightingale if (sc->delta_x > 255) { 1924c87aefeSPatrick Mooney val0 |= PS2M_DATA_X_OFLOW; 193bf21cd93STycho Nightingale val1 = 255; 194bf21cd93STycho Nightingale } else 195bf21cd93STycho Nightingale val1 = sc->delta_x; 196bf21cd93STycho Nightingale } else { 1974c87aefeSPatrick Mooney val0 |= PS2M_DATA_X_SIGN; 198bf21cd93STycho Nightingale if (sc->delta_x < -255) { 1994c87aefeSPatrick Mooney val0 |= PS2M_DATA_X_OFLOW; 200bf21cd93STycho Nightingale val1 = 255; 201bf21cd93STycho Nightingale } else 202bf21cd93STycho Nightingale val1 = sc->delta_x; 203bf21cd93STycho Nightingale } 204bf21cd93STycho Nightingale sc->delta_x = 0; 205bf21cd93STycho Nightingale 206bf21cd93STycho Nightingale if (sc->delta_y >= 0) { 207bf21cd93STycho Nightingale if (sc->delta_y > 255) { 2084c87aefeSPatrick Mooney val0 |= PS2M_DATA_Y_OFLOW; 209bf21cd93STycho Nightingale val2 = 255; 210bf21cd93STycho Nightingale } else 211bf21cd93STycho Nightingale val2 = sc->delta_y; 212bf21cd93STycho Nightingale } else { 2134c87aefeSPatrick Mooney val0 |= PS2M_DATA_Y_SIGN; 214bf21cd93STycho Nightingale if (sc->delta_y < -255) { 2154c87aefeSPatrick Mooney val0 |= PS2M_DATA_Y_OFLOW; 216bf21cd93STycho Nightingale val2 = 255; 217bf21cd93STycho Nightingale } else 218bf21cd93STycho Nightingale val2 = sc->delta_y; 219bf21cd93STycho Nightingale } 220bf21cd93STycho Nightingale sc->delta_y = 0; 221bf21cd93STycho Nightingale 2224c87aefeSPatrick Mooney if (sc->fifo.num < (sc->fifo.size - 3)) { 223bf21cd93STycho Nightingale fifo_put(sc, val0); 224bf21cd93STycho Nightingale fifo_put(sc, val1); 225bf21cd93STycho Nightingale fifo_put(sc, val2); 226bf21cd93STycho Nightingale } 2274c87aefeSPatrick Mooney } 228bf21cd93STycho Nightingale 229bf21cd93STycho Nightingale static void 230bf21cd93STycho Nightingale ps2mouse_reset(struct ps2mouse_softc *sc) 231bf21cd93STycho Nightingale { 232bf21cd93STycho Nightingale assert(pthread_mutex_isowned_np(&sc->mtx)); 233bf21cd93STycho Nightingale fifo_reset(sc); 234bf21cd93STycho Nightingale movement_reset(sc); 2354c87aefeSPatrick Mooney sc->status = PS2M_STS_ENABLE_DEV; 236bf21cd93STycho Nightingale sc->resolution = 4; 237bf21cd93STycho Nightingale sc->sampling_rate = 100; 238bf21cd93STycho Nightingale 239bf21cd93STycho Nightingale sc->cur_x = 0; 240bf21cd93STycho Nightingale sc->cur_y = 0; 241bf21cd93STycho Nightingale sc->delta_x = 0; 242bf21cd93STycho Nightingale sc->delta_y = 0; 243bf21cd93STycho Nightingale } 244bf21cd93STycho Nightingale 245bf21cd93STycho Nightingale int 246bf21cd93STycho Nightingale ps2mouse_read(struct ps2mouse_softc *sc, uint8_t *val) 247bf21cd93STycho Nightingale { 248bf21cd93STycho Nightingale int retval; 249bf21cd93STycho Nightingale 250bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 251bf21cd93STycho Nightingale retval = fifo_get(sc, val); 252bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 253bf21cd93STycho Nightingale 254bf21cd93STycho Nightingale return (retval); 255bf21cd93STycho Nightingale } 256bf21cd93STycho Nightingale 2574c87aefeSPatrick Mooney int 2584c87aefeSPatrick Mooney ps2mouse_fifocnt(struct ps2mouse_softc *sc) 2594c87aefeSPatrick Mooney { 2604c87aefeSPatrick Mooney return (sc->fifo.num); 2614c87aefeSPatrick Mooney } 2624c87aefeSPatrick Mooney 263bf21cd93STycho Nightingale void 2644c87aefeSPatrick Mooney ps2mouse_toggle(struct ps2mouse_softc *sc, int enable) 265bf21cd93STycho Nightingale { 266bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 2674c87aefeSPatrick Mooney if (enable) 2684c87aefeSPatrick Mooney sc->ctrlenable = 1; 2694c87aefeSPatrick Mooney else { 2704c87aefeSPatrick Mooney sc->ctrlenable = 0; 2714c87aefeSPatrick Mooney sc->fifo.rindex = 0; 2724c87aefeSPatrick Mooney sc->fifo.windex = 0; 2734c87aefeSPatrick Mooney sc->fifo.num = 0; 2744c87aefeSPatrick Mooney } 2754c87aefeSPatrick Mooney pthread_mutex_unlock(&sc->mtx); 2764c87aefeSPatrick Mooney } 2774c87aefeSPatrick Mooney 2784c87aefeSPatrick Mooney void 2794c87aefeSPatrick Mooney ps2mouse_write(struct ps2mouse_softc *sc, uint8_t val, int insert) 2804c87aefeSPatrick Mooney { 2814c87aefeSPatrick Mooney pthread_mutex_lock(&sc->mtx); 2824c87aefeSPatrick Mooney fifo_reset(sc); 283bf21cd93STycho Nightingale if (sc->curcmd) { 284bf21cd93STycho Nightingale switch (sc->curcmd) { 285bf21cd93STycho Nightingale case PS2MC_SET_SAMPLING_RATE: 286bf21cd93STycho Nightingale sc->sampling_rate = val; 287bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 288bf21cd93STycho Nightingale break; 289bf21cd93STycho Nightingale case PS2MC_SET_RESOLUTION: 290bf21cd93STycho Nightingale sc->resolution = val; 291bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 292bf21cd93STycho Nightingale break; 293bf21cd93STycho Nightingale default: 294154972afSPatrick Mooney EPRINTLN("Unhandled ps2 mouse current " 295154972afSPatrick Mooney "command byte 0x%02x", val); 296bf21cd93STycho Nightingale break; 297bf21cd93STycho Nightingale } 298bf21cd93STycho Nightingale sc->curcmd = 0; 2994c87aefeSPatrick Mooney 3004c87aefeSPatrick Mooney } else if (insert) { 3014c87aefeSPatrick Mooney fifo_put(sc, val); 302bf21cd93STycho Nightingale } else { 303bf21cd93STycho Nightingale switch (val) { 3044c87aefeSPatrick Mooney case 0x00: 3054c87aefeSPatrick Mooney fifo_put(sc, PS2MC_ACK); 3064c87aefeSPatrick Mooney break; 307bf21cd93STycho Nightingale case PS2MC_RESET_DEV: 308bf21cd93STycho Nightingale ps2mouse_reset(sc); 309bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 310bf21cd93STycho Nightingale fifo_put(sc, PS2MC_BAT_SUCCESS); 311bf21cd93STycho Nightingale fifo_put(sc, PS2MOUSE_DEV_ID); 312bf21cd93STycho Nightingale break; 313bf21cd93STycho Nightingale case PS2MC_SET_DEFAULTS: 314bf21cd93STycho Nightingale ps2mouse_reset(sc); 315bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 316bf21cd93STycho Nightingale break; 317bf21cd93STycho Nightingale case PS2MC_DISABLE: 318bf21cd93STycho Nightingale fifo_reset(sc); 319bf21cd93STycho Nightingale sc->status &= ~PS2M_STS_ENABLE_DEV; 320bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 321bf21cd93STycho Nightingale break; 322bf21cd93STycho Nightingale case PS2MC_ENABLE: 323bf21cd93STycho Nightingale fifo_reset(sc); 324bf21cd93STycho Nightingale sc->status |= PS2M_STS_ENABLE_DEV; 325bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 326bf21cd93STycho Nightingale break; 327bf21cd93STycho Nightingale case PS2MC_SET_SAMPLING_RATE: 328bf21cd93STycho Nightingale sc->curcmd = val; 329bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 330bf21cd93STycho Nightingale break; 331bf21cd93STycho Nightingale case PS2MC_SEND_DEV_ID: 332bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 333bf21cd93STycho Nightingale fifo_put(sc, PS2MOUSE_DEV_ID); 334bf21cd93STycho Nightingale break; 335bf21cd93STycho Nightingale case PS2MC_SET_REMOTE_MODE: 336bf21cd93STycho Nightingale sc->status |= PS2M_STS_REMOTE_MODE; 337bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 338bf21cd93STycho Nightingale break; 339bf21cd93STycho Nightingale case PS2MC_SEND_DEV_DATA: 340bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 341bf21cd93STycho Nightingale movement_get(sc); 342bf21cd93STycho Nightingale break; 343bf21cd93STycho Nightingale case PS2MC_SET_STREAM_MODE: 344bf21cd93STycho Nightingale sc->status &= ~PS2M_STS_REMOTE_MODE; 345bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 346bf21cd93STycho Nightingale break; 347bf21cd93STycho Nightingale case PS2MC_SEND_DEV_STATUS: 348bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 349bf21cd93STycho Nightingale fifo_put(sc, sc->status); 350bf21cd93STycho Nightingale fifo_put(sc, sc->resolution); 351bf21cd93STycho Nightingale fifo_put(sc, sc->sampling_rate); 352bf21cd93STycho Nightingale break; 353bf21cd93STycho Nightingale case PS2MC_SET_RESOLUTION: 354bf21cd93STycho Nightingale sc->curcmd = val; 355bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 356bf21cd93STycho Nightingale break; 357bf21cd93STycho Nightingale case PS2MC_SET_SCALING1: 358bf21cd93STycho Nightingale case PS2MC_SET_SCALING2: 359bf21cd93STycho Nightingale fifo_put(sc, PS2MC_ACK); 360bf21cd93STycho Nightingale break; 361bf21cd93STycho Nightingale default: 3624c87aefeSPatrick Mooney fifo_put(sc, PS2MC_ACK); 363154972afSPatrick Mooney EPRINTLN("Unhandled ps2 mouse command " 364154972afSPatrick Mooney "0x%02x", val); 365bf21cd93STycho Nightingale break; 366bf21cd93STycho Nightingale } 367bf21cd93STycho Nightingale } 368bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 369bf21cd93STycho Nightingale } 370bf21cd93STycho Nightingale 371bf21cd93STycho Nightingale static void 372bf21cd93STycho Nightingale ps2mouse_event(uint8_t button, int x, int y, void *arg) 373bf21cd93STycho Nightingale { 374bf21cd93STycho Nightingale struct ps2mouse_softc *sc = arg; 375bf21cd93STycho Nightingale 376bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 377bf21cd93STycho Nightingale movement_update(sc, x, y); 378bf21cd93STycho Nightingale 379bf21cd93STycho Nightingale sc->status &= ~(PS2M_STS_LEFT_BUTTON | 380bf21cd93STycho Nightingale PS2M_STS_RIGHT_BUTTON | PS2M_STS_MID_BUTTON); 381bf21cd93STycho Nightingale if (button & (1 << 0)) 382bf21cd93STycho Nightingale sc->status |= PS2M_STS_LEFT_BUTTON; 383bf21cd93STycho Nightingale if (button & (1 << 1)) 384bf21cd93STycho Nightingale sc->status |= PS2M_STS_MID_BUTTON; 385bf21cd93STycho Nightingale if (button & (1 << 2)) 386bf21cd93STycho Nightingale sc->status |= PS2M_STS_RIGHT_BUTTON; 387bf21cd93STycho Nightingale 3884c87aefeSPatrick Mooney if ((sc->status & PS2M_STS_ENABLE_DEV) == 0 || !sc->ctrlenable) { 389bf21cd93STycho Nightingale /* no data reporting */ 390bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 391bf21cd93STycho Nightingale return; 392bf21cd93STycho Nightingale } 393bf21cd93STycho Nightingale 394bf21cd93STycho Nightingale movement_get(sc); 395bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 396bf21cd93STycho Nightingale 3974c87aefeSPatrick Mooney if (sc->fifo.num > 0) 3984c87aefeSPatrick Mooney atkbdc_event(sc->atkbdc_sc, 0); 399bf21cd93STycho Nightingale } 400bf21cd93STycho Nightingale 401bf21cd93STycho Nightingale struct ps2mouse_softc * 402bf21cd93STycho Nightingale ps2mouse_init(struct atkbdc_softc *atkbdc_sc) 403bf21cd93STycho Nightingale { 404bf21cd93STycho Nightingale struct ps2mouse_softc *sc; 405bf21cd93STycho Nightingale 406bf21cd93STycho Nightingale sc = calloc(1, sizeof (struct ps2mouse_softc)); 407bf21cd93STycho Nightingale pthread_mutex_init(&sc->mtx, NULL); 408bf21cd93STycho Nightingale fifo_init(sc); 409bf21cd93STycho Nightingale sc->atkbdc_sc = atkbdc_sc; 410bf21cd93STycho Nightingale 411bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 412bf21cd93STycho Nightingale ps2mouse_reset(sc); 413bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 414bf21cd93STycho Nightingale 4154c87aefeSPatrick Mooney console_ptr_register(ps2mouse_event, sc, 1); 416bf21cd93STycho Nightingale 417bf21cd93STycho Nightingale return (sc); 418bf21cd93STycho Nightingale } 419bf21cd93STycho Nightingale 4204c87aefeSPatrick Mooney 421