package main

import "fmt"

func LenovoEC(ctx Context) {
	ap := Create(ctx, "acpi/platform.asl")
	defer ap.Close()

	wakeGPE := 13

	sbGPE := GuessECGPE(ctx)
	var GPE int
	var GPEUnsure bool
	if sbGPE < 0 {
		sbGPE = SouthBridge.EncodeGPE(1)
		GPE = 1
		GPEUnsure = true
		SouthBridge.NeedRouteGPIOManually()
	} else {
		GPE = SouthBridge.DecodeGPE(sbGPE)
		GPEUnsure = false
	}

	SouthBridge.EnableGPE(wakeGPE)
	SouthBridge.EnableGPE(GPE)

	GPEDefine := DSDTDefine{
		Key: "THINKPAD_EC_GPE",
	}

	GPEDefine.Value = fmt.Sprintf("%d", sbGPE)
	if GPEUnsure {
		GPEDefine.Comment = "FIXME: Check this"
	}

	DSDTDefines = append(DSDTDefines,
		DSDTDefine{
			Key:   "EC_LENOVO_H8_ME_WORKAROUND",
			Value: "1",
		}, GPEDefine)

	ap.WriteString(
		`Method(_WAK,1)
{
	/* ME may not be up yet.  */
	Store (0, \_TZ.MEB1)
	Store (0, \_TZ.MEB2)
	Return(Package(){0,0})
}

Method(_PTS,1)
{
	\_SB.PCI0.LPCB.EC.RADI(0)
}
`)

	si := Create(ctx, "acpi/superio.asl")
	defer si.Close()

	si.WriteString("#include <drivers/pc80/ps2_controller.asl>\n")

	dock := Create(ctx, "dock.c")
	defer dock.Close()

	AddRAMStageFile("dock.c", "")

	dock.WriteString(
		`#include <ec/lenovo/h8/h8.h>

void h8_mainboard_init_dock (void)
{
/* FIXME: fill this if needed.  */
}
`)

	/* FIXME:XX Move this to ec/lenovo.  */
	smi := Create(ctx, "smihandler.c")
	defer smi.Close()

	AddSMMFile("smihandler.c", "")

	smi.WriteString(
		`/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2008-2009 coresystems GmbH
 * Copyright (C) 2014 Vladimir Serbinenko
 *
 * 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.
 */

#include <arch/io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <ec/acpi/ec.h>
#include <ec/lenovo/h8/h8.h>
#include <delay.h>
#include <` + SouthBridge.GetGPIOHeader() + ">\n\n")

	if GPEUnsure {
		smi.WriteString("/* FIXME: check this */\n")
	}
	fmt.Fprintf(smi, "#define GPE_EC_SCI	%d\n", GPE)

	smi.WriteString("/* FIXME: check this */\n")
	fmt.Fprintf(smi, "#define GPE_EC_WAKE	%d\n", wakeGPE)

	smi.WriteString(`
static void mainboard_smm_init(void)
{
	printk(BIOS_DEBUG, "initializing SMI\n");
	/* Enable 0x1600/0x1600 register pair */
	ec_set_bit(0x00, 0x05);
}

int mainboard_io_trap_handler(int smif)
{
	static int smm_initialized;

	if (!smm_initialized) {
		mainboard_smm_init();
		smm_initialized = 1;
	}

	return 0;
}

static void mainboard_smi_handle_ec_sci(void)
{
	u8 status = inb(EC_SC);
	u8 event;

	if (!(status & EC_SCI_EVT))
		return;

	event = ec_query();
	printk(BIOS_DEBUG, "EC event %02x\n", event);
}

void mainboard_smi_gpi(u32 gpi_sts)
{
	if (gpi_sts & (1 << GPE_EC_SCI))
		mainboard_smi_handle_ec_sci();
}

int mainboard_smi_apmc(u8 data)
{
	switch (data) {
	case APM_CNT_ACPI_ENABLE:
		/* use 0x1600/0x1604 to prevent races with userspace */
		ec_set_ports(0x1604, 0x1600);
		/* route EC_SCI to SCI */
		gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI);
		/* discard all events, and enable attention */
		ec_write(0x80, 0x01);
		break;
	case APM_CNT_ACPI_DISABLE:
		/* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
		   provide a EC query function */
		ec_set_ports(0x66, 0x62);
		/* route EC_SCI to SMI */
		gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI);
		/* discard all events, and enable attention */
		ec_write(0x80, 0x01);
		break;
	default:
		break;
	}
	return 0;
}

void mainboard_smi_sleep(u8 slp_typ)
{
	if (slp_typ == 3) {
		u8 ec_wake = ec_read(0x32);
		/* If EC wake events are enabled, enable wake on EC WAKE GPE.  */
		if (ec_wake & 0x14) {
			/* Redirect EC WAKE GPE to SCI.  */
			gpi_route_interrupt(GPE_EC_WAKE, GPI_IS_SCI);
		}
	}
}
`)

	ec := Create(ctx, "acpi/ec.asl")
	defer ec.Close()

	ec.WriteString("#include <ec/lenovo/h8/acpi/ec.asl>\n")

	KconfigBool["EC_LENOVO_PMH7"] = true
	KconfigBool["EC_LENOVO_H8"] = true

	pmh := DevTreeNode{
		Chip: "ec/lenovo/pmh7",
		Registers: map[string]string{
			"backlight_enable":  "0x01",
			"dock_event_enable": "0x01",
		},
		Children: []DevTreeNode{
			DevTreeNode{
				Chip:    "pnp",
				Comment: "dummy",
				Dev:     0xff,
				Func:    1,
			},
		},
	}
	PutChip("lpc", pmh)

	ecs := ctx.InfoSource.GetEC()
	h8 := DevTreeNode{
		Chip: "ec/lenovo/h8",
		Children: []DevTreeNode{
			DevTreeNode{
				Chip:    "pnp",
				Comment: "dummy",
				Dev:     0xff,
				Func:    2,
				IOs: map[uint16]uint16{
					0x60: 0x62,
					0x62: 0x66,
					0x64: 0x1600,
					0x66: 0x1604,
				},
			},
		},
		Comment: "FIXME: has_keyboard_backlight, has_power_management_beeps, has_uwb",
		Registers: map[string]string{
			"config0":   FormatHex8(ecs[0]),
			"config1":   FormatHex8(ecs[1]),
			"config2":   FormatHex8(ecs[2]),
			"config3":   FormatHex8(ecs[3]),
			"beepmask0": FormatHex8(ecs[4]),
			"beepmask1": FormatHex8(ecs[5]),
		},
	}
	for i := 0; i < 0x10; i++ {
		if ecs[0x10+i] != 0 {
			h8.Registers[fmt.Sprintf("event%x_enable", i)] = FormatHex8(ecs[0x10+i])
		}
	}
	PutChip("lpc", h8)

	eeprom := DevTreeNode{
		Chip:    "drivers/i2c/at24rf08c",
		Comment: "eeprom, 8 virtual devices, same chip",
		Children: []DevTreeNode{
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x54,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x55,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x56,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x57,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x5c,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x5d,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x5e,
			},
			DevTreeNode{
				Chip: "i2c",
				Dev:  0x5f,
			},
		},
	}
	PutChip("smbus", eeprom)
}
