/* SPDX-License-Identifier: GPL-2.0-only */

#define __SIMPLE_DEVICE__
#include <console/console.h>
#include <arch/io.h>
#include <device/pnp_ops.h>
#include <device/device.h>
#include <device/pnp.h>
#include <delay.h>
#include "dock.h"
#include <superio/nsc/pc87382/pc87382.h>

#include <southbridge/intel/i82801ix/i82801ix.h>
#include <ec/lenovo/h8/h8.h>
#include <ec/acpi/ec.h>

struct pin_config {
	u8 port;
	u8 mode;
};

static int poll_clk_stable(pnp_devfn_t dev, int timeout)
{
	/* Enable 14.318MHz CLK on CLKIN */
	pnp_write_config(dev, 0x29, 0xa0);
	while (!(pnp_read_config(dev, 0x29) & 0x10) && timeout--)
		udelay(1000);
	if (!timeout)
		return 1;

	return 0;
}

static int gpio_init(pnp_devfn_t gpio, u16 gpio_base,
	const struct pin_config pincfg[], int num_cfgs)
{
	int i;

	/* Enable GPIO LDN. */
	pnp_set_logical_device(gpio);
	pnp_set_iobase(gpio, PNP_IDX_IO0, gpio_base);
	pnp_set_enable(gpio, 1);

	for (i = 0; i < num_cfgs; i++) {
		pnp_write_config(gpio, 0xf0, pincfg[i].port);
		pnp_write_config(gpio, 0xf1, pincfg[i].mode);
		pnp_write_config(gpio, 0xf2, 0x0);
	}
	return 0;
}

static const pnp_devfn_t l_dlpc = PNP_DEV(0x164e, PC87382_DOCK);
static const pnp_devfn_t l_gpio = PNP_DEV(0x164e, PC87382_GPIO);

static int pc87382_init(pnp_devfn_t dlpc, u16 dlpc_base)
{
	/* Maximum 3300 LCLKs at 14.318MHz */
	int timeout = 230;

	/* Enable LPC bridge LDN. */
	pnp_set_logical_device(dlpc);
	pnp_set_iobase(dlpc, PNP_IDX_IO0, dlpc_base);
	pnp_set_enable(dlpc, 1);

	/* Reset docking state */
	outb(0x00, dlpc_base);
	outb(0x07, dlpc_base);
	while (!(inb(dlpc_base) & 8) && timeout--)
		udelay(1);
	if (!timeout)
		return 1;

	return 0;
}

static void pc87382_close(pnp_devfn_t dlpc)
{
	pnp_set_logical_device(dlpc);

	/* Disconnect LPC bus */
	u16 dlpc_base = pnp_read_iobase(dlpc, PNP_IDX_IO0);
	if (dlpc_base) {
		outb(0x00, dlpc_base);
		pnp_set_enable(dlpc, 0);
	}
}

static const struct pin_config local_gpio[] = {
	{0x00, 3},	{0x01, 3},	{0x02, 0},	{0x03, 3},
	{0x04, 4},	{0x20, 4},	{0x21, 4},	{0x23, 4},
};

/* Enable internal clock and configure GPIO LDN */
int pc87382_early(void)
{
	/* Wake-up time is 33 msec (maximum). */
	if (poll_clk_stable(l_gpio, 33) != 0)
		return 1;

	/* Set up GPIOs */
	if (gpio_init(l_gpio, DLPC_GPIO_BASE,
		local_gpio, ARRAY_SIZE(local_gpio)) != 0) {
		return 1;
	}

	return 0;
}

static int pc87382_connect(void)
{
	u8 reg;

	reg = inb(DLPC_GPDO0);
	reg |= D_PLTRST | D_LPCPD;
	/* Deassert D_PLTRST# and D_LPCPD# */
	outb(reg, DLPC_GPDO0);

	if (pc87382_init(l_dlpc, DLPC_CONTROL) != 0)
		return 1;

	/* Assert D_PLTRST# */
	reg &= ~D_PLTRST;
	outb(reg, DLPC_GPDO0);
	udelay(1000);

	/* Deassert D_PLTRST# */
	reg |= D_PLTRST;
	outb(reg, DLPC_GPDO0);
	mdelay(10);

	return 0;
}

static void pc87382_disconnect(void)
{
	pc87382_close(l_dlpc);

	/* Assert D_PLTRST# and D_LPCPD# */
	u8 reg = inb(DLPC_GPDO0);
	reg &= ~(D_PLTRST | D_LPCPD);
	outb(reg, DLPC_GPDO0);
}

/* Returns 3bit dock id */
static u8 dock_identify(void)
{
	u8 id;

	/* Make sure GPIO LDN is configured first ! */
	id = (inb(DLPC_GPDI0) >> 4) & 1;
	id |= (inb(DLPC_GPDI2) & 3) << 1;

	return id;
}

/* Docking station side. */

#include <superio/nsc/pc87384/pc87384.h>

static const pnp_devfn_t r_gpio = PNP_DEV(SUPERIO_DEV, PC87384_GPIO);
static const pnp_devfn_t r_serial = PNP_DEV(SUPERIO_DEV, PC87384_SP1);

static const struct pin_config remote_gpio[] = {
	{0x00, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
	{0x01, PC87384_GPIO_PIN_TYPE_PUSH_PULL | PC87384_GPIO_PIN_OE},
	{0x02, PC87384_GPIO_PIN_TYPE_PUSH_PULL | PC87384_GPIO_PIN_OE},
	{0x03, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
	{0x04, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
	{0x05, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
	{0x06, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
	{0x07, PC87384_GPIO_PIN_DEBOUNCE | PC87384_GPIO_PIN_PULLUP},
};

static int pc87384_init(void)
{
	if (poll_clk_stable(r_gpio, 1000) != 0)
		return 1;

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

	/* enable serial port */

	if (CONFIG_TTYS0_BASE > 0) {
		pnp_set_logical_device(r_serial);
		pnp_set_iobase(r_serial, PNP_IDX_IO0, CONFIG_TTYS0_BASE);
		pnp_set_enable(r_serial, 1);
	}

	if (gpio_init(r_gpio, DOCK_GPIO_BASE,
		remote_gpio, ARRAY_SIZE(remote_gpio)) != 0)
		return 1;

	/* no GPIO events enabled for PORT0 */
	outb(0x00, DOCK_GPIO_BASE + 0x02);
	/* clear GPIO events on PORT0 */
	outb(0xff, DOCK_GPIO_BASE + 0x03);
	outb(0xff, DOCK_GPIO_BASE + 0x04);

	/* no GPIO events enabled for PORT1 */
	outb(0x00, DOCK_GPIO_BASE + 0x06);
	/* clear GPIO events on PORT1*/
	outb(0xff, DOCK_GPIO_BASE + 0x07);
	outb(0x1f, DOCK_GPIO_BASE + 0x08);

	outb(0xfd, DOCK_GPIO_BASE + 0x00);

	return 0;
}

/* Mainboard */

void dock_connect(void)
{
	const u8 id = dock_identify();

	/* Dock type 2505 doesn't have serial, LPT port or LEDs */
	if (id == DOCK_TYPE_NONE || id == DOCK_TYPE_2505)
		return;

	if (pc87382_connect() != 0 || pc87384_init() != 0) {
		pc87382_disconnect();
		return;
	}

	ec_write(H8_LED_CONTROL,
		 H8_LED_CONTROL_OFF | H8_LED_CONTROL_DOCK_LED1);
	ec_write(H8_LED_CONTROL,
		 H8_LED_CONTROL_ON  | H8_LED_CONTROL_DOCK_LED2);
}

void dock_disconnect(void)
{
	pc87382_disconnect();

	ec_write(H8_LED_CONTROL,
		 H8_LED_CONTROL_OFF | H8_LED_CONTROL_DOCK_LED1);
	ec_write(H8_LED_CONTROL,
		 H8_LED_CONTROL_OFF | H8_LED_CONTROL_DOCK_LED2);
}

void dock_info(void)
{
	const u8 id = dock_identify();

	if (id != DOCK_TYPE_NONE)
		printk(BIOS_DEBUG, "DOCK: is present: id=%d\n", id);
	else
		printk(BIOS_DEBUG, "DOCK: not connected\n");
}
