/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
 *
 * 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; version 2 of
 * the License.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <console/console.h>
#include <device/device.h>
#include <arch/io.h>
#include <delay.h>
#include "dock.h"
#include "superio/nsc/pc87384/pc87384.h"
#include "ec/acpi/ec.h"
#include "ec/lenovo/pmh7/pmh7.h"
#include "southbridge/intel/i82801gx/i82801gx.h"

#define DLPC_CONTROL 0x164c

static void dlpc_write_register(int reg, int value)
{
	outb(reg, 0x164e);
	outb(value, 0x164f);
}

static u8 dlpc_read_register(int reg)
{
	outb(reg, 0x164e);
	return inb(0x164f);
}

static void dock_write_register(int reg, int value)
{
	outb(reg, 0x2e);
	outb(value, 0x2f);
}

static u8 dock_read_register(int reg)
{
	outb(reg, 0x2e);
	return inb(0x2f);
}

static void dlpc_gpio_set_mode(int port, int mode)
{
	dlpc_write_register(0xf0, port);
	dlpc_write_register(0xf1, mode);
}

static void dock_gpio_set_mode(int port, int mode, int irq)
{
	dock_write_register(0xf0, port);
	dock_write_register(0xf1, mode);
	dock_write_register(0xf2, irq);
}

static void dlpc_gpio_init(void)
{
	/* Select GPIO module */
	dlpc_write_register(0x07, 0x07);
	/* GPIO Base Address 0x1680 */
	dlpc_write_register(0x60, 0x16);
	dlpc_write_register(0x61, 0x80);

	/* Activate GPIO */
	dlpc_write_register(0x30, 0x01);

	dlpc_gpio_set_mode(0x00, 3);
	dlpc_gpio_set_mode(0x01, 3);
	dlpc_gpio_set_mode(0x02, 0);
	dlpc_gpio_set_mode(0x03, 3);
	dlpc_gpio_set_mode(0x04, 4);
	dlpc_gpio_set_mode(0x20, 4);
	dlpc_gpio_set_mode(0x21, 4);
	dlpc_gpio_set_mode(0x23, 4);
}

int dlpc_init(void)
{
	int timeout = 1000;

	/* Enable 14.318MHz CLK on CLKIN */
	dlpc_write_register(0x29, 0xa0);
	while(!(dlpc_read_register(0x29) & 0x10) && timeout--)
		udelay(1000);

	if (!timeout)
		return 1;

	/* Select DLPC module */
	dlpc_write_register(0x07, 0x19);
	/* DLPC Base Address */
	dlpc_write_register(0x60, (DLPC_CONTROL >> 8) & 0xff);
	dlpc_write_register(0x61, DLPC_CONTROL & 0xff);
	/* Activate DLPC */
	dlpc_write_register(0x30, 0x01);

	/* Reset docking state */
	outb(0x00, DLPC_CONTROL);

	dlpc_gpio_init();
	return 0;
}

static int dock_superio_init(void)
{
	int timeout = 1000;
	/* startup 14.318MHz Clock */
	dock_write_register(0x29, 0xa0);
	/* wait until clock is settled */
	while(!(dock_read_register(0x29) & 0x10) && timeout--)
		udelay(1000);

	if (!timeout)
		return 1;

	/* set GPIO pins to Serial/Parallel Port
	 * functions
	 */
	dock_write_register(0x22, 0xa9);

	dock_write_register(0x07, PC87384_GPIO);
	dock_write_register(0x60, 0x16);
	dock_write_register(0x61, 0x20);
	/* enable GPIO */
	dock_write_register(0x30, 0x01);

	dock_gpio_set_mode(0x00, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);

	dock_gpio_set_mode(0x01, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
			   PC87384_GPIO_PIN_OE, 0x00);

	dock_gpio_set_mode(0x02, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
			   PC87384_GPIO_PIN_OE, 0x00);

	dock_gpio_set_mode(0x03, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);

	dock_gpio_set_mode(0x04, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);

	dock_gpio_set_mode(0x05, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);

	dock_gpio_set_mode(0x06, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);

	dock_gpio_set_mode(0x07, PC87384_GPIO_PIN_DEBOUNCE |
			   PC87384_GPIO_PIN_PULLUP, 0x00);


	/* no GPIO events enabled for PORT0 */
	outb(0x00, 0x1622);
	/* clear GPIO events on PORT0 */
	outb(0xff, 0x1623);
	outb(0xff, 0x1624);
	/* no GPIO events enabled for PORT1 */
	outb(0x00, 0x1626);

	/* clear GPIO events on PORT1*/
	outb(0xff, 0x1627);
	outb(0x1F, 0x1628);
	outb(0xfd, 0x1620);
	return 0;
}

int dock_connect(void)
{
	int timeout = 1000;

	outb(0x07, DLPC_CONTROL);

	timeout = 1000;

	while(!(inb(DLPC_CONTROL) & 8) && timeout--)
		udelay(1000);

	if (!timeout) {
		/* docking failed, disable DLPC switch */
		outb(0x00, DLPC_CONTROL);
		dlpc_write_register(0x30, 0x00);
		return 1;
	}

	/* Assert D_PLTRST# */
	outb(0xfe, 0x1680);
	udelay(1000);
	/* Deassert D_PLTRST# */
	outb(0xff, 0x1680);
	udelay(10000);

	return dock_superio_init();
}

void dock_disconnect(void)
{
	/* disconnect LPC bus */
	outb(0x00, DLPC_CONTROL);
	/* Assert PLTRST and DLPCPD */
	outb(0xfc, 0x1680);
}

int dock_present(void)
{
	return pmh7_register_read(0x61) & 1;
}

int legacy_io_present(void)
{
	return !(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40);
}

void legacy_io_init(void)
{
	/* Enable Power for Ultrabay slot */
	pmh7_ultrabay_power_enable(1);
	udelay(100000);
	dock_superio_init();
}
