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

#include <acpi/acpi.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <stdio.h>
#include <string.h>
#include <smbios.h>
#include <option.h>
#include <pc80/keyboard.h>
#include <types.h>

#include "h8.h"
#include "chip.h"

void h8_trackpoint_enable(int on)
{
	ec_write(H8_TRACKPOINT_CTRL,
		 on ? H8_TRACKPOINT_ON : H8_TRACKPOINT_OFF);
}

/* Controls radio-off pin in WLAN MiniPCIe slot.  */
void h8_wlan_enable(int on)
{
	if (on)
		ec_set_bit(0x3a, 5);
	else
		ec_clr_bit(0x3a, 5);
}

/* Controls radio-off pin in UWB MiniPCIe slot.  */
static void h8_uwb_enable(int on)
{
	if (on)
		ec_set_bit(0x31, 2);
	else
		ec_clr_bit(0x31, 2);
}

static void h8_fn_ctrl_swap(int on)
{
	if (on)
		ec_set_bit(0xce, 4);
	else
		ec_clr_bit(0xce, 4);
}

enum battery {
	SECONDARY_BATTERY = 0,
	PRIMARY_BATTERY = 1,
};

/* h8 charge priority. Defines if primary or secondary
 * battery is charged first.
 * Because NVRAM is complete the other way around as this register,
 * it's inverted by if
 */
static void h8_charge_priority(enum battery battery)
{
	if (battery == PRIMARY_BATTERY)
		ec_clr_bit(0x0, 4);
	else
		ec_set_bit(0x0, 4);
}

static void h8_sticky_fn(int on)
{
	if (on)
		ec_set_bit(0x0, 3);
	else
		ec_clr_bit(0x0, 3);
}

static void f1_to_f12_as_primary(int on)
{
	if (on)
		ec_set_bit(0x3b, 3);
	else
		ec_clr_bit(0x3b, 3);
}

static void h8_log_ec_version(void)
{
	char ecfw[17];
	u8 len;
	u16 fwvh, fwvl;

	len = h8_build_id_and_function_spec_version(ecfw, sizeof(ecfw) - 1);
	ecfw[len] = 0;

	fwvh = ec_read(0xe9);
	fwvl = ec_read(0xe8);

	printk(BIOS_INFO, "H8: EC Firmware ID %s, Version %d.%d%d%c\n", ecfw,
	       fwvh >> 4, fwvh & 0x0f, fwvl >> 4, 0x41 + (fwvl & 0xf));
}

void h8_set_audio_mute(int mute)
{
	if (mute)
		ec_set_bit(0x3a, 0);
	else
		ec_clr_bit(0x3a, 0);
}

void h8_enable_event(int event)
{
	if (event < 0 || event > 127)
		return;

	ec_set_bit(0x10 + (event >> 3), event & 7);
}

void h8_disable_event(int event)
{
	if (event < 0 || event > 127)
		return;

	ec_clr_bit(0x10 + (event >> 3), event & 7);
}

void h8_usb_always_on_enable(enum usb_always_on on)
{
	u8 val;

	switch (on) {
	case UAO_OFF:
		val = ec_read(H8_USB_ALWAYS_ON);
		// Clear bits 0,2,3
		val &= ~(H8_USB_ALWAYS_ON_ENABLE | H8_USB_ALWAYS_ON_AC_ONLY);
		ec_write(H8_USB_ALWAYS_ON, val);
		break;

	case UAO_AC_AND_BATTERY:
		val = ec_read(H8_USB_ALWAYS_ON);
		val |= H8_USB_ALWAYS_ON_ENABLE; // Set bit 0
		val &= ~H8_USB_ALWAYS_ON_AC_ONLY; // Clear bits 2 and 3
		ec_write(H8_USB_ALWAYS_ON, val);
		break;

	case UAO_AC_ONLY:
		val = ec_read(H8_USB_ALWAYS_ON);
		// Set bits 0,2,3
		val |= (H8_USB_ALWAYS_ON_ENABLE | H8_USB_ALWAYS_ON_AC_ONLY);
		ec_write(H8_USB_ALWAYS_ON, val);
		break;
	}
}

void h8_usb_power_enable(int onoff)
{
	if (onoff)
		ec_set_bit(0x3b, 4);
	else
		ec_clr_bit(0x3b, 4);
}

int h8_ultrabay_device_present(void)
{
	return ec_read(H8_STATUS1) & 0x5 ? 0 : 1;
}

u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len)
{
	u8 i, c;
	char str[16 + 1]; /* 16 ASCII chars + \0 */

	/* Build ID */
	for (i = 0; i < 8; i++) {
		c = ec_read(0xf0 + i);
		if (c < 0x20 || c > 0x7f) {
			i = snprintf(str, sizeof(str), "*INVALID");
			break;
		}
		str[i] = c;
	}

	/* EC firmware function specification version */
	i += snprintf(str + i, sizeof(str) - i, "-%u.%u", ec_read(0xef), ec_read(0xeb));

	i = MIN(buf_len, i);
	memcpy(buf, str, i);

	return i;
}

#if CONFIG(GENERATE_SMBIOS_TABLES)
static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t)
{
	char tpec[] = "IBM ThinkPad Embedded Controller -[                 ]-";

	h8_build_id_and_function_spec_version(tpec + 35, 17);

	t->count = smbios_add_string(t->eos, tpec);
}
#endif

static void h8_init(struct device *dev)
{
	pc_keyboard_init(NO_AUX_DEVICE);
}

#if CONFIG(HAVE_ACPI_TABLES)
static const char *h8_acpi_name(const struct device *dev)
{
	return "EC";
}
#endif

struct device_operations h8_dev_ops = {
#if CONFIG(GENERATE_SMBIOS_TABLES)
	.get_smbios_strings = h8_smbios_strings,
#endif
#if CONFIG(HAVE_ACPI_TABLES)
	.acpi_fill_ssdt = h8_ssdt_generator,
	.acpi_name = h8_acpi_name,
#endif
	.init = h8_init,
};

void __weak h8_mb_init(void){ /* NOOP */ }

static void h8_enable(struct device *dev)
{
	struct ec_lenovo_h8_config *conf = dev->chip_info;
	u8 val;
	u8 beepmask0, beepmask1, reg8;

	dev->ops = &h8_dev_ops;

	ec_clear_out_queue();
	h8_log_ec_version();

	/* Always enable I/O range 0x1600-0x160f and thermal management */
	reg8 = conf->config0;
	reg8 |= H8_CONFIG0_SMM_H8_ENABLE;
	reg8 |= H8_CONFIG0_TC_ENABLE;
	ec_write(H8_CONFIG0, reg8);

	reg8 = conf->config1;
	if (conf->has_keyboard_backlight) {
		/* Default to both backlights */
		reg8 = (reg8 & 0xf3) | ((get_uint_option("backlight", 0) & 0x3) << 2);
	}
	ec_write(H8_CONFIG1, reg8);
	ec_write(H8_CONFIG2, conf->config2);
	ec_write(H8_CONFIG3, conf->config3);

	beepmask0 = conf->beepmask0;
	beepmask1 = conf->beepmask1;

	if (conf->has_power_management_beeps) {
		if (get_uint_option("power_management_beeps", 1) == 0) {
			beepmask0 = 0x00;
			beepmask1 = 0x00;
		}
	}

	if (conf->has_power_management_beeps) {
		if (get_uint_option("low_battery_beep", 1))
			beepmask0 |= 2;
		else
			beepmask0 &= ~2;
	}

	ec_write(H8_SOUND_ENABLE0, beepmask0);
	ec_write(H8_SOUND_ENABLE1, beepmask1);

	/* silence sounds in queue */
	ec_write(H8_SOUND_REPEAT, 0x00);
	ec_write(H8_SOUND_REG, 0x00);

	ec_write(0x10, conf->event0_enable);
	ec_write(0x11, conf->event1_enable);
	ec_write(0x12, conf->event2_enable);
	ec_write(0x13, conf->event3_enable);
	ec_write(0x14, conf->event4_enable);
	ec_write(0x15, conf->event5_enable);
	ec_write(0x16, conf->event6_enable);
	ec_write(0x17, conf->event7_enable);
	ec_write(0x18, conf->event8_enable);
	ec_write(0x19, conf->event9_enable);
	ec_write(0x1a, conf->eventa_enable);
	ec_write(0x1b, conf->eventb_enable);
	ec_write(0x1c, conf->eventc_enable);
	ec_write(0x1d, conf->eventd_enable);
	ec_write(0x1e, conf->evente_enable);
	ec_write(0x1f, conf->eventf_enable);

	ec_write(H8_FAN_CONTROL, H8_FAN_CONTROL_AUTO);

	h8_usb_always_on_enable(get_uint_option("usb_always_on", 0));

	h8_wlan_enable(get_uint_option("wlan", 1));

	h8_trackpoint_enable(1);
	h8_usb_power_enable(1);

	unsigned int volume = get_uint_option("volume", ~0);
	if (volume <= 0xff && !acpi_is_wakeup_s3())
		ec_write(H8_VOLUME_CONTROL, volume);

	val = (CONFIG(H8_SUPPORT_BT_ON_WIFI) || h8_has_bdc(dev)) &&
		h8_bluetooth_nv_enable();
	h8_bluetooth_enable(val);

	val = h8_has_wwan(dev) && h8_wwan_nv_enable();
	h8_wwan_enable(val);

	if (conf->has_uwb)
		h8_uwb_enable(get_uint_option("uwb", 1));

	h8_fn_ctrl_swap(get_uint_option("fn_ctrl_swap", CONFIG(H8_FN_CTRL_SWAP)));

	h8_sticky_fn(get_uint_option("sticky_fn", 0));

	if (CONFIG(H8_HAS_PRIMARY_FN_KEYS))
		f1_to_f12_as_primary(get_uint_option("f1_to_f12_as_primary", 1));

	h8_charge_priority(get_uint_option("first_battery", PRIMARY_BATTERY));

	h8_set_audio_mute(0);
	h8_mb_init();
}

struct chip_operations ec_lenovo_h8_ops = {
	.name = "Lenovo H8 EC",
	.enable_dev = h8_enable,
};
