linux/drivers/input/serio/libps2.c
<<
>>
Prefs
   1/*
   2 * PS/2 driver library
   3 *
   4 * Copyright (c) 1999-2002 Vojtech Pavlik
   5 * Copyright (c) 2004 Dmitry Torokhov
   6 */
   7
   8/*
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of the GNU General Public License version 2 as published by
  11 * the Free Software Foundation.
  12 */
  13
  14#include <linux/delay.h>
  15#include <linux/module.h>
  16#include <linux/sched.h>
  17#include <linux/interrupt.h>
  18#include <linux/input.h>
  19#include <linux/serio.h>
  20#include <linux/i8042.h>
  21#include <linux/init.h>
  22#include <linux/libps2.h>
  23
  24#define DRIVER_DESC     "PS/2 driver library"
  25
  26MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
  27MODULE_DESCRIPTION("PS/2 driver library");
  28MODULE_LICENSE("GPL");
  29
  30/*
  31 * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
  32 * It doesn't handle retransmission, though it could - because if there
  33 * is a need for retransmissions device has to be replaced anyway.
  34 *
  35 * ps2_sendbyte() can only be called from a process context.
  36 */
  37
  38int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
  39{
  40        serio_pause_rx(ps2dev->serio);
  41        ps2dev->nak = 1;
  42        ps2dev->flags |= PS2_FLAG_ACK;
  43        serio_continue_rx(ps2dev->serio);
  44
  45        if (serio_write(ps2dev->serio, byte) == 0)
  46                wait_event_timeout(ps2dev->wait,
  47                                   !(ps2dev->flags & PS2_FLAG_ACK),
  48                                   msecs_to_jiffies(timeout));
  49
  50        serio_pause_rx(ps2dev->serio);
  51        ps2dev->flags &= ~PS2_FLAG_ACK;
  52        serio_continue_rx(ps2dev->serio);
  53
  54        return -ps2dev->nak;
  55}
  56EXPORT_SYMBOL(ps2_sendbyte);
  57
  58void ps2_begin_command(struct ps2dev *ps2dev)
  59{
  60        mutex_lock(&ps2dev->cmd_mutex);
  61
  62        if (i8042_check_port_owner(ps2dev->serio))
  63                i8042_lock_chip();
  64}
  65EXPORT_SYMBOL(ps2_begin_command);
  66
  67void ps2_end_command(struct ps2dev *ps2dev)
  68{
  69        if (i8042_check_port_owner(ps2dev->serio))
  70                i8042_unlock_chip();
  71
  72        mutex_unlock(&ps2dev->cmd_mutex);
  73}
  74EXPORT_SYMBOL(ps2_end_command);
  75
  76/*
  77 * ps2_drain() waits for device to transmit requested number of bytes
  78 * and discards them.
  79 */
  80
  81void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
  82{
  83        if (maxbytes > sizeof(ps2dev->cmdbuf)) {
  84                WARN_ON(1);
  85                maxbytes = sizeof(ps2dev->cmdbuf);
  86        }
  87
  88        ps2_begin_command(ps2dev);
  89
  90        serio_pause_rx(ps2dev->serio);
  91        ps2dev->flags = PS2_FLAG_CMD;
  92        ps2dev->cmdcnt = maxbytes;
  93        serio_continue_rx(ps2dev->serio);
  94
  95        wait_event_timeout(ps2dev->wait,
  96                           !(ps2dev->flags & PS2_FLAG_CMD),
  97                           msecs_to_jiffies(timeout));
  98
  99        ps2_end_command(ps2dev);
 100}
 101EXPORT_SYMBOL(ps2_drain);
 102
 103/*
 104 * ps2_is_keyboard_id() checks received ID byte against the list of
 105 * known keyboard IDs.
 106 */
 107
 108int ps2_is_keyboard_id(char id_byte)
 109{
 110        static const char keyboard_ids[] = {
 111                0xab,   /* Regular keyboards            */
 112                0xac,   /* NCD Sun keyboard             */
 113                0x2b,   /* Trust keyboard, translated   */
 114                0x5d,   /* Trust keyboard               */
 115                0x60,   /* NMB SGI keyboard, translated */
 116                0x47,   /* NMB SGI keyboard             */
 117        };
 118
 119        return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
 120}
 121EXPORT_SYMBOL(ps2_is_keyboard_id);
 122
 123/*
 124 * ps2_adjust_timeout() is called after receiving 1st byte of command
 125 * response and tries to reduce remaining timeout to speed up command
 126 * completion.
 127 */
 128
 129static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
 130{
 131        switch (command) {
 132                case PS2_CMD_RESET_BAT:
 133                        /*
 134                         * Device has sent the first response byte after
 135                         * reset command, reset is thus done, so we can
 136                         * shorten the timeout.
 137                         * The next byte will come soon (keyboard) or not
 138                         * at all (mouse).
 139                         */
 140                        if (timeout > msecs_to_jiffies(100))
 141                                timeout = msecs_to_jiffies(100);
 142                        break;
 143
 144                case PS2_CMD_GETID:
 145                        /*
 146                         * Microsoft Natural Elite keyboard responds to
 147                         * the GET ID command as it were a mouse, with
 148                         * a single byte. Fail the command so atkbd will
 149                         * use alternative probe to detect it.
 150                         */
 151                        if (ps2dev->cmdbuf[1] == 0xaa) {
 152                                serio_pause_rx(ps2dev->serio);
 153                                ps2dev->flags = 0;
 154                                serio_continue_rx(ps2dev->serio);
 155                                timeout = 0;
 156                        }
 157
 158                        /*
 159                         * If device behind the port is not a keyboard there
 160                         * won't be 2nd byte of ID response.
 161                         */
 162                        if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
 163                                serio_pause_rx(ps2dev->serio);
 164                                ps2dev->flags = ps2dev->cmdcnt = 0;
 165                                serio_continue_rx(ps2dev->serio);
 166                                timeout = 0;
 167                        }
 168                        break;
 169
 170                default:
 171                        break;
 172        }
 173
 174        return timeout;
 175}
 176
 177/*
 178 * ps2_command() sends a command and its parameters to the mouse,
 179 * then waits for the response and puts it in the param array.
 180 *
 181 * ps2_command() can only be called from a process context
 182 */
 183
 184int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 185{
 186        int timeout;
 187        int send = (command >> 12) & 0xf;
 188        int receive = (command >> 8) & 0xf;
 189        int rc = -1;
 190        int i;
 191
 192        if (receive > sizeof(ps2dev->cmdbuf)) {
 193                WARN_ON(1);
 194                return -1;
 195        }
 196
 197        if (send && !param) {
 198                WARN_ON(1);
 199                return -1;
 200        }
 201
 202        serio_pause_rx(ps2dev->serio);
 203        ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
 204        ps2dev->cmdcnt = receive;
 205        if (receive && param)
 206                for (i = 0; i < receive; i++)
 207                        ps2dev->cmdbuf[(receive - 1) - i] = param[i];
 208        serio_continue_rx(ps2dev->serio);
 209
 210        /*
 211         * Some devices (Synaptics) peform the reset before
 212         * ACKing the reset command, and so it can take a long
 213         * time before the ACK arrives.
 214         */
 215        if (ps2_sendbyte(ps2dev, command & 0xff,
 216                         command == PS2_CMD_RESET_BAT ? 1000 : 200))
 217                goto out;
 218
 219        for (i = 0; i < send; i++)
 220                if (ps2_sendbyte(ps2dev, param[i], 200))
 221                        goto out;
 222
 223        /*
 224         * The reset command takes a long time to execute.
 225         */
 226        timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
 227
 228        timeout = wait_event_timeout(ps2dev->wait,
 229                                     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
 230
 231        if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
 232
 233                timeout = ps2_adjust_timeout(ps2dev, command, timeout);
 234                wait_event_timeout(ps2dev->wait,
 235                                   !(ps2dev->flags & PS2_FLAG_CMD), timeout);
 236        }
 237
 238        if (param)
 239                for (i = 0; i < receive; i++)
 240                        param[i] = ps2dev->cmdbuf[(receive - 1) - i];
 241
 242        if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
 243                goto out;
 244
 245        rc = 0;
 246
 247 out:
 248        serio_pause_rx(ps2dev->serio);
 249        ps2dev->flags = 0;
 250        serio_continue_rx(ps2dev->serio);
 251
 252        return rc;
 253}
 254EXPORT_SYMBOL(__ps2_command);
 255
 256int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 257{
 258        int rc;
 259
 260        ps2_begin_command(ps2dev);
 261        rc = __ps2_command(ps2dev, param, command);
 262        ps2_end_command(ps2dev);
 263
 264        return rc;
 265}
 266EXPORT_SYMBOL(ps2_command);
 267
 268/*
 269 * ps2_init() initializes ps2dev structure
 270 */
 271
 272void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
 273{
 274        mutex_init(&ps2dev->cmd_mutex);
 275        lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
 276        init_waitqueue_head(&ps2dev->wait);
 277        ps2dev->serio = serio;
 278}
 279EXPORT_SYMBOL(ps2_init);
 280
 281/*
 282 * ps2_handle_ack() is supposed to be used in interrupt handler
 283 * to properly process ACK/NAK of a command from a PS/2 device.
 284 */
 285
 286int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
 287{
 288        switch (data) {
 289                case PS2_RET_ACK:
 290                        ps2dev->nak = 0;
 291                        break;
 292
 293                case PS2_RET_NAK:
 294                        ps2dev->flags |= PS2_FLAG_NAK;
 295                        ps2dev->nak = PS2_RET_NAK;
 296                        break;
 297
 298                case PS2_RET_ERR:
 299                        if (ps2dev->flags & PS2_FLAG_NAK) {
 300                                ps2dev->flags &= ~PS2_FLAG_NAK;
 301                                ps2dev->nak = PS2_RET_ERR;
 302                                break;
 303                        }
 304
 305                /*
 306                 * Workaround for mice which don't ACK the Get ID command.
 307                 * These are valid mouse IDs that we recognize.
 308                 */
 309                case 0x00:
 310                case 0x03:
 311                case 0x04:
 312                        if (ps2dev->flags & PS2_FLAG_WAITID) {
 313                                ps2dev->nak = 0;
 314                                break;
 315                        }
 316                        /* Fall through */
 317                default:
 318                        return 0;
 319        }
 320
 321
 322        if (!ps2dev->nak) {
 323                ps2dev->flags &= ~PS2_FLAG_NAK;
 324                if (ps2dev->cmdcnt)
 325                        ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
 326        }
 327
 328        ps2dev->flags &= ~PS2_FLAG_ACK;
 329        wake_up(&ps2dev->wait);
 330
 331        if (data != PS2_RET_ACK)
 332                ps2_handle_response(ps2dev, data);
 333
 334        return 1;
 335}
 336EXPORT_SYMBOL(ps2_handle_ack);
 337
 338/*
 339 * ps2_handle_response() is supposed to be used in interrupt handler
 340 * to properly store device's response to a command and notify process
 341 * waiting for completion of the command.
 342 */
 343
 344int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
 345{
 346        if (ps2dev->cmdcnt)
 347                ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
 348
 349        if (ps2dev->flags & PS2_FLAG_CMD1) {
 350                ps2dev->flags &= ~PS2_FLAG_CMD1;
 351                if (ps2dev->cmdcnt)
 352                        wake_up(&ps2dev->wait);
 353        }
 354
 355        if (!ps2dev->cmdcnt) {
 356                ps2dev->flags &= ~PS2_FLAG_CMD;
 357                wake_up(&ps2dev->wait);
 358        }
 359
 360        return 1;
 361}
 362EXPORT_SYMBOL(ps2_handle_response);
 363
 364void ps2_cmd_aborted(struct ps2dev *ps2dev)
 365{
 366        if (ps2dev->flags & PS2_FLAG_ACK)
 367                ps2dev->nak = 1;
 368
 369        if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
 370                wake_up(&ps2dev->wait);
 371
 372        /* reset all flags except last nack */
 373        ps2dev->flags &= PS2_FLAG_NAK;
 374}
 375EXPORT_SYMBOL(ps2_cmd_aborted);
 376