/*
 * Copyright 2014 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program 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 2 of
 * the License, or (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 */

#include <assert.h>
#include <libpayload.h>

#include "drivers/gpio/sysinfo.h"
#include "drivers/gpio/tegra.h"
#include "drivers/input/pseudo/keyboard.h"

/* GPIOs for reading status of buttons */
static GpioOps *pwr_btn_gpio, *vol_down_gpio, *vol_up_gpio;

/* Unique state ids for all possible states in state machine */
enum {
	STATE_ID_START,
	STATE_ID_CTRL_D,
	STATE_ID_CTRL_U,
	STATE_ID_CR,
	STATE_ID_SPC,
	STATE_ID_CTRL_L,
	STATE_ID_TAB,
	STATE_ID_S1,
	STATE_NUM,
};

/* Intermediate stages */
static const int int_states[] = {
	STATE_ID_S1,
};

/* Final stages that map to key/modifier codes */
static const struct pk_final_state final_states[] = {
	{STATE_ID_CTRL_D, MODIFIER_CTRL, 'D'},
	{STATE_ID_CTRL_U, MODIFIER_CTRL, 'U'},
	{STATE_ID_CR, MODIFIER_NONE, '\r'},
	{STATE_ID_SPC, MODIFIER_NONE, ' '},
	{STATE_ID_CTRL_L, MODIFIER_CTRL, 'L'},
	{STATE_ID_TAB, MODIFIER_NONE, '\t'},
};

/*
 * Input is formatted as follows:
 * Bit 0 - Vol down
 * Bit 1 - Vol Up
 * Bit 2 - Pwr btn
 *
 * Pwr btn is active high, whereas vol up and down are active low, thus we need
 * to mask the input we read for active low buttons to ensure we interpret them
 * right.
 *
 */
#define KEYSET(pwr, vup, vdn)	  ((pwr) | (vup) | (vdn))

enum {
	VOL_DOWN_SHIFT,
	VOL_UP_SHIFT,
	PWR_BTN_SHIFT,
	VOL_DOWN = (1 << VOL_DOWN_SHIFT),
	VOL_UP = (1 << VOL_UP_SHIFT),
	PWR_BTN = (1 << PWR_BTN_SHIFT),
	NO_BTN_PRESSED = KEYSET(0,0,0),
};

/*
 * Key definitions are as follows:
 * Buttons:
 * Pwr = Power button
 * Vup = Volume Up button
 * Vdn = Volume Down button
 *
 * Ctrl - D = Pwr + Vup
 * Ctrl - U = Pwr + Vdn
 * CR       = Vup
 * Space    = Vdn
 * Ctrl - L = Pwr -> Vup
 * Tab      = Pwr -> Vdn
 */
static const struct pk_trans trans_arr[] = {
	{STATE_ID_START, KEYSET(PWR_BTN, VOL_UP, 0), STATE_ID_CTRL_D},
	{STATE_ID_START, KEYSET(PWR_BTN, 0, VOL_DOWN), STATE_ID_CTRL_U},
	{STATE_ID_START, KEYSET(0, VOL_UP, 0), STATE_ID_CR},
	{STATE_ID_START, KEYSET(0, 0, VOL_DOWN), STATE_ID_SPC},
	{STATE_ID_START, KEYSET(PWR_BTN, 0, 0), STATE_ID_S1},
	{STATE_ID_S1, KEYSET(0, VOL_UP, 0), STATE_ID_CTRL_L},
	{STATE_ID_S1, KEYSET(0, 0, VOL_DOWN), STATE_ID_TAB},
};

static void ryu_sm_init(struct pk_sm_desc *desc)
{
	desc->total_states_count = STATE_NUM;
	desc->start_state = STATE_ID_START;
	desc->int_states_count = ARRAY_SIZE(int_states);
	desc->int_states_arr = int_states;
	desc->final_states_count = ARRAY_SIZE(final_states);
	desc->final_states_arr = final_states;
	desc->trans_count = ARRAY_SIZE(trans_arr);
	desc->trans_arr = trans_arr;
}

void mainboard_keyboard_init(struct pk_sm_desc *desc)
{
	pwr_btn_gpio = sysinfo_lookup_gpio("power", 1,
					   new_tegra_gpio_input_from_coreboot);
	die_if(!pwr_btn_gpio, "No GPIO for power!!\n");

	/* Inputs volup and voldown are active low. */
	vol_down_gpio = new_gpio_not(&new_tegra_gpio_input(GPIO(Q, 6))->ops);
	vol_up_gpio = new_gpio_not(&new_tegra_gpio_input(GPIO(Q, 7))->ops);

	ryu_sm_init(desc);
}

int mainboard_read_input(void)
{
	int input;

	input = (pwr_btn_gpio->get(pwr_btn_gpio) << PWR_BTN_SHIFT) |
		(vol_up_gpio->get(vol_up_gpio) << VOL_UP_SHIFT) |
		(vol_down_gpio->get(vol_down_gpio) << VOL_DOWN_SHIFT);

	if (input == NO_BTN_PRESSED)
		input = -1;

	return input;
}
