/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/ps2.h>
#include <grub/fdtbus.h>
#include <grub/err.h>
#include <grub/machine/kernel.h>
#include <grub/at_keyboard.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/time.h>
#include <grub/ps2.h>
#include <grub/fdtbus.h>

static volatile grub_uint32_t *pl050_regs;

struct grub_ps2_state ps2_state;

static void
keyboard_controller_wait_until_ready (void)
{
  while (! (pl050_regs[1] & 0x40));
}

static grub_uint8_t
wait_ack (void)
{
  grub_uint64_t endtime;
  grub_uint8_t ack;

  endtime = grub_get_time_ms () + 20;
  do
    ack = pl050_regs[2];
  while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK
	 && grub_get_time_ms () < endtime);
  return ack;
}


static int
write_mode (int mode)
{
  unsigned i;
  for (i = 0; i < GRUB_AT_TRIES; i++)
    {
      grub_uint8_t ack;
      keyboard_controller_wait_until_ready ();
      pl050_regs[2] = 0xf0;
      keyboard_controller_wait_until_ready ();
      pl050_regs[2] = mode;
      keyboard_controller_wait_until_ready ();
      ack = wait_ack ();
      if (ack == GRUB_AT_NACK)
	continue;
      if (ack == GRUB_AT_ACK)
	break;
      return 0;
    }

  return (i != GRUB_AT_TRIES);
}

static int
query_mode (void)
{
  grub_uint8_t ret;
  int e;

  e = write_mode (0);
  if (!e)
    return 0;

  keyboard_controller_wait_until_ready ();

  do
    ret = pl050_regs[2];
  while (ret == GRUB_AT_ACK);

  /* QEMU translates the set even in no-translate mode.  */
  if (ret == 0x43 || ret == 1)
    return 1;
  if (ret == 0x41 || ret == 2)
    return 2;
  if (ret == 0x3f || ret == 3)
    return 3;
  return 0;
}

static void
set_scancodes (void)
{
  write_mode (2);
  ps2_state.current_set = query_mode ();
  grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
  if (ps2_state.current_set == 2)
    return;

  write_mode (1);
  ps2_state.current_set = query_mode ();
  grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
  if (ps2_state.current_set == 1)
    return;
  grub_dprintf ("atkeyb", "no supported scancode set found\n");
}

static void
keyboard_controller_led (grub_uint8_t leds)
{
  keyboard_controller_wait_until_ready ();
  pl050_regs[2] = 0xed;
  keyboard_controller_wait_until_ready ();
  pl050_regs[2] = leds & 0x7;
}

/* If there is a character pending, return it;
   otherwise return GRUB_TERM_NO_KEY.  */
static int
grub_pl050_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
  grub_uint8_t at_key;
  int ret;
  grub_uint8_t old_led;

  if (!(pl050_regs[1] & 0x10))
    return -1;
  at_key = pl050_regs[2];
  old_led = ps2_state.led_status;

  ret = grub_ps2_process_incoming_byte (&ps2_state, at_key);
  if (old_led != ps2_state.led_status)
    keyboard_controller_led (ps2_state.led_status);
  return ret;
}

static struct grub_term_input grub_pl050_keyboard_term =
  {
    .name = "pl050_keyboard",
    .getkey = grub_pl050_keyboard_getkey
  };

static grub_err_t
pl050_attach(const struct grub_fdtbus_dev *dev)
{
  const grub_uint32_t *reg;
  reg = grub_fdtbus_get_prop (dev, "reg", 0);

  /* Mouse.  Nothing to do.  */
  if (grub_be_to_cpu32 (*reg) == 0x7000)
    return 0;

  pl050_regs = grub_fdtbus_map_reg (dev, 0, 0);

  if (!grub_fdtbus_is_mapping_valid (pl050_regs))
    return grub_error (GRUB_ERR_IO, "could not map pl050");

  ps2_state.at_keyboard_status = 0;
  set_scancodes ();
  keyboard_controller_led (ps2_state.led_status);

  grub_term_register_input ("pl050_keyboard", &grub_pl050_keyboard_term);
  return GRUB_ERR_NONE;
}

struct grub_fdtbus_driver pl050 =
{
  .compatible = "arm,pl050",
  .attach = pl050_attach
};

void
grub_pl050_init (void)
{
  grub_fdtbus_register (&pl050);
}
