Lines Matching refs:ps2dev

43 static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte,  in ps2_do_sendbyte()  argument
45 __releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock) in ps2_do_sendbyte()
50 lockdep_assert_held(&ps2dev->serio->lock); in ps2_do_sendbyte()
53 ps2dev->nak = 1; in ps2_do_sendbyte()
54 ps2dev->flags |= PS2_FLAG_ACK; in ps2_do_sendbyte()
56 serio_continue_rx(ps2dev->serio); in ps2_do_sendbyte()
58 error = serio_write(ps2dev->serio, byte); in ps2_do_sendbyte()
60 dev_dbg(&ps2dev->serio->dev, in ps2_do_sendbyte()
63 wait_event_timeout(ps2dev->wait, in ps2_do_sendbyte()
64 !(ps2dev->flags & PS2_FLAG_ACK), in ps2_do_sendbyte()
67 serio_pause_rx(ps2dev->serio); in ps2_do_sendbyte()
68 } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts); in ps2_do_sendbyte()
70 ps2dev->flags &= ~PS2_FLAG_ACK; in ps2_do_sendbyte()
73 switch (ps2dev->nak) { in ps2_do_sendbyte()
89 dev_dbg(&ps2dev->serio->dev, in ps2_do_sendbyte()
91 byte, error, ps2dev->nak, attempt); in ps2_do_sendbyte()
107 int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) in ps2_sendbyte() argument
111 serio_pause_rx(ps2dev->serio); in ps2_sendbyte()
113 retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1); in ps2_sendbyte()
114 dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak); in ps2_sendbyte()
116 serio_continue_rx(ps2dev->serio); in ps2_sendbyte()
129 void ps2_begin_command(struct ps2dev *ps2dev) in ps2_begin_command() argument
131 struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; in ps2_begin_command()
141 void ps2_end_command(struct ps2dev *ps2dev) in ps2_end_command() argument
143 struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; in ps2_end_command()
156 void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) in ps2_drain() argument
158 if (maxbytes > sizeof(ps2dev->cmdbuf)) { in ps2_drain()
160 maxbytes = sizeof(ps2dev->cmdbuf); in ps2_drain()
163 ps2_begin_command(ps2dev); in ps2_drain()
165 serio_pause_rx(ps2dev->serio); in ps2_drain()
166 ps2dev->flags = PS2_FLAG_CMD; in ps2_drain()
167 ps2dev->cmdcnt = maxbytes; in ps2_drain()
168 serio_continue_rx(ps2dev->serio); in ps2_drain()
170 wait_event_timeout(ps2dev->wait, in ps2_drain()
171 !(ps2dev->flags & PS2_FLAG_CMD), in ps2_drain()
174 ps2_end_command(ps2dev); in ps2_drain()
203 static int ps2_adjust_timeout(struct ps2dev *ps2dev, in ps2_adjust_timeout() argument
226 if (ps2dev->cmdbuf[1] == 0xaa) { in ps2_adjust_timeout()
227 serio_pause_rx(ps2dev->serio); in ps2_adjust_timeout()
228 ps2dev->flags = 0; in ps2_adjust_timeout()
229 serio_continue_rx(ps2dev->serio); in ps2_adjust_timeout()
237 if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) { in ps2_adjust_timeout()
238 serio_pause_rx(ps2dev->serio); in ps2_adjust_timeout()
239 ps2dev->flags = ps2dev->cmdcnt = 0; in ps2_adjust_timeout()
240 serio_continue_rx(ps2dev->serio); in ps2_adjust_timeout()
265 int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) in __ps2_command() argument
274 if (receive > sizeof(ps2dev->cmdbuf)) { in __ps2_command()
286 serio_pause_rx(ps2dev->serio); in __ps2_command()
288 ps2dev->cmdcnt = receive; in __ps2_command()
296 ps2dev->flags = PS2_FLAG_WAITID; in __ps2_command()
302 ps2dev->flags = PS2_FLAG_PASS_NOACK; in __ps2_command()
306 ps2dev->flags = 0; in __ps2_command()
312 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; in __ps2_command()
315 ps2dev->cmdbuf[(receive - 1) - i] = param[i]; in __ps2_command()
325 rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2); in __ps2_command()
331 rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2); in __ps2_command()
336 serio_continue_rx(ps2dev->serio); in __ps2_command()
343 timeout = wait_event_timeout(ps2dev->wait, in __ps2_command()
344 !(ps2dev->flags & PS2_FLAG_CMD1), timeout); in __ps2_command()
346 if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) { in __ps2_command()
348 timeout = ps2_adjust_timeout(ps2dev, command, timeout); in __ps2_command()
349 wait_event_timeout(ps2dev->wait, in __ps2_command()
350 !(ps2dev->flags & PS2_FLAG_CMD), timeout); in __ps2_command()
353 serio_pause_rx(ps2dev->serio); in __ps2_command()
357 param[i] = ps2dev->cmdbuf[(receive - 1) - i]; in __ps2_command()
361 if (ps2dev->cmdcnt && in __ps2_command()
362 (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) { in __ps2_command()
370 ps2dev->flags = 0; in __ps2_command()
371 serio_continue_rx(ps2dev->serio); in __ps2_command()
373 dev_dbg(&ps2dev->serio->dev, in __ps2_command()
376 ps2dev->nak, ps2dev->flags, in __ps2_command()
401 int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) in ps2_command() argument
405 ps2_begin_command(ps2dev); in ps2_command()
406 rc = __ps2_command(ps2dev, param, command); in ps2_command()
407 ps2_end_command(ps2dev); in ps2_command()
423 int ps2_sliced_command(struct ps2dev *ps2dev, u8 command) in ps2_sliced_command() argument
428 ps2_begin_command(ps2dev); in ps2_sliced_command()
430 retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11); in ps2_sliced_command()
436 retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES); in ps2_sliced_command()
442 dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval); in ps2_sliced_command()
443 ps2_end_command(ps2dev); in ps2_sliced_command()
457 void ps2_init(struct ps2dev *ps2dev, struct serio *serio, in ps2_init() argument
461 ps2dev->pre_receive_handler = pre_receive_handler; in ps2_init()
462 ps2dev->receive_handler = receive_handler; in ps2_init()
464 mutex_init(&ps2dev->cmd_mutex); in ps2_init()
465 lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); in ps2_init()
466 init_waitqueue_head(&ps2dev->wait); in ps2_init()
467 ps2dev->serio = serio; in ps2_init()
468 serio_set_drvdata(serio, ps2dev); in ps2_init()
479 static void ps2_handle_response(struct ps2dev *ps2dev, u8 data) in ps2_handle_response() argument
481 if (ps2dev->cmdcnt) in ps2_handle_response()
482 ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; in ps2_handle_response()
484 if (ps2dev->flags & PS2_FLAG_CMD1) { in ps2_handle_response()
485 ps2dev->flags &= ~PS2_FLAG_CMD1; in ps2_handle_response()
486 if (ps2dev->cmdcnt) in ps2_handle_response()
487 wake_up(&ps2dev->wait); in ps2_handle_response()
490 if (!ps2dev->cmdcnt) { in ps2_handle_response()
491 ps2dev->flags &= ~PS2_FLAG_CMD; in ps2_handle_response()
492 wake_up(&ps2dev->wait); in ps2_handle_response()
501 static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data) in ps2_handle_ack() argument
505 ps2dev->nak = 0; in ps2_handle_ack()
509 ps2dev->flags |= PS2_FLAG_NAK; in ps2_handle_ack()
510 ps2dev->nak = PS2_RET_NAK; in ps2_handle_ack()
514 if (ps2dev->flags & PS2_FLAG_NAK) { in ps2_handle_ack()
515 ps2dev->flags &= ~PS2_FLAG_NAK; in ps2_handle_ack()
516 ps2dev->nak = PS2_RET_ERR; in ps2_handle_ack()
528 if (ps2dev->flags & PS2_FLAG_WAITID) { in ps2_handle_ack()
529 ps2dev->nak = 0; in ps2_handle_ack()
547 dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); in ps2_handle_ack()
548 if (ps2dev->flags & PS2_FLAG_PASS_NOACK) in ps2_handle_ack()
549 ps2dev->receive_handler(ps2dev, data); in ps2_handle_ack()
550 ps2dev->flags &= ~(PS2_FLAG_WAITID | PS2_FLAG_PASS_NOACK); in ps2_handle_ack()
554 if (!ps2dev->nak) in ps2_handle_ack()
555 ps2dev->flags &= ~PS2_FLAG_NAK; in ps2_handle_ack()
557 ps2dev->flags &= ~PS2_FLAG_ACK; in ps2_handle_ack()
559 if (!ps2dev->nak && data != PS2_RET_ACK) in ps2_handle_ack()
560 ps2_handle_response(ps2dev, data); in ps2_handle_ack()
562 wake_up(&ps2dev->wait); in ps2_handle_ack()
569 static void ps2_cleanup(struct ps2dev *ps2dev) in ps2_cleanup() argument
571 unsigned long old_flags = ps2dev->flags; in ps2_cleanup()
574 ps2dev->flags &= PS2_FLAG_NAK; in ps2_cleanup()
577 ps2dev->nak = 1; in ps2_cleanup()
580 wake_up(&ps2dev->wait); in ps2_cleanup()
595 struct ps2dev *ps2dev = serio_get_drvdata(serio); in ps2_interrupt() local
598 rc = ps2dev->pre_receive_handler(ps2dev, data, flags); in ps2_interrupt()
601 ps2_cleanup(ps2dev); in ps2_interrupt()
608 if (ps2dev->flags & PS2_FLAG_ACK) in ps2_interrupt()
609 ps2_handle_ack(ps2dev, data); in ps2_interrupt()
610 else if (ps2dev->flags & PS2_FLAG_CMD) in ps2_interrupt()
611 ps2_handle_response(ps2dev, data); in ps2_interrupt()
613 ps2dev->receive_handler(ps2dev, data); in ps2_interrupt()