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

#include <console/console.h>
#include <device/device.h>
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <option.h>

#include "ec.h"
#include "chip.h"

typedef struct ec_kontron_it8516e_config config_t;

enum { /* EC commands */
	IT8516E_CMD_SET_SYSTEMP_TYPE	= 0x06,
	IT8516E_CMD_GET_SYSTEMP_TYPE	= 0x07,
	IT8516E_CMD_GET_FAN_MODE	= 0x10,
	IT8516E_CMD_SET_FAN_MODE	= 0x11,
	IT8516E_CMD_GET_FAN_PWM		= 0x12,
	IT8516E_CMD_SET_FAN_PWM		= 0x13,
	IT8516E_CMD_GET_FAN_SPEED	= 0x14,
	IT8516E_CMD_SET_FAN_SPEED	= 0x15,
	IT8516E_CMD_GET_FAN_TEMP	= 0x16,
	IT8516E_CMD_SET_FAN_TEMP	= 0x17,
	IT8516E_CMD_SET_FAN_LIMITS	= 0x1a,
};

/**
 * Sets the type of the external temperature sensor used
 *
 * @param type Type of sensor to set
 */
static void it8516e_set_systemp_type(const u8 type)
{
	if (send_ec_command(IT8516E_CMD_SET_SYSTEMP_TYPE))
		return;
	send_ec_data(type);
}

/**
 * Sets the operating mode of a fan
 *
 * @param idx Selects the fan; 0: CPU, 1: System
 * @param mode Mode to set
 */
static void it8516e_set_fan_mode(const u8 idx, const u8 mode)
{
	if (send_ec_command(IT8516E_CMD_SET_FAN_MODE))
		return;
	if (send_ec_data(idx))
		return;
	send_ec_data(mode);
}

/**
 * Sets the PWM rate of a fan in IT8516E_MODE_PWM
 *
 * @param idx Selects the fan; 0: CPU, 1: System
 * @param pwm PWM rate measured in 255ths
 */
static void it8516e_set_fan_pwm(const u8 idx, const u8 pwm)
{
	if (send_ec_command(IT8516E_CMD_SET_FAN_PWM))
		return;
	if (send_ec_data(idx))
		return;
	send_ec_data(pwm);
}

/**
 * Sets the target speed in RPM for a fan in IT8516E_MODE_SPEED
 *
 * @param idx Selects the fan; 0: CPU, 1: System
 * @param speed Speed in RPM
 */
static void it8516e_set_fan_speed(const u8 idx, const u16 speed)
{
	if (send_ec_command(IT8516E_CMD_SET_FAN_SPEED))
		return;
	if (send_ec_data(idx))
		return;
	if (send_ec_data(speed & 0xff))
		return;
	send_ec_data(speed >> 8);
}

/**
 * Sets the target temperature for a fan in IT8516E_MODE_THERMAL
 *
 * @param idx Selects the fan; 0: CPU, 1: System
 * @param temp Temperature in 64ths degree C
 */
static void it8516e_set_fan_temperature(const u8 idx, const u16 temp)
{
	if (send_ec_command(IT8516E_CMD_SET_FAN_TEMP))
		return;
	if (send_ec_data(idx))
		return;
	if (send_ec_data(temp & 0xff))
		return;
	send_ec_data(temp >> 8);
}

/**
 * Sets the minimum and maximum PWM rate of a fan in IT8516E_MODE_THERMAL
 *
 * @param idx Selects the fan; 0: CPU, 1: System
 * @param min Minimum PWM rate in %
 * @param max Maximum PWM rate in %
 */
static void it8516e_set_fan_limits(const u8 idx, const u8 min, const u8 max)
{
	if (send_ec_command(IT8516E_CMD_SET_FAN_LIMITS))
		return;
	if (send_ec_data(idx))
		return;
	if (send_ec_data(min))
		return;
	send_ec_data(max);
}

static void it8516e_set_fan_from_options(const config_t *const config,
					 const u8 fan_idx)
{
	static char fanX_mode[]		= "fanX_mode";
	static char fanX_target[]	= "fanX_target";
	static char fanX_min[]		= "fanX_min";
	static char fanX_max[]		= "fanX_max";

	u8 fan_mode	= config->default_fan_mode[fan_idx];
	u16 fan_target	= config->default_fan_target[fan_idx];
	u8 fan_min	= config->default_fan_min[fan_idx];
	u8 fan_max	= config->default_fan_max[fan_idx];

	fanX_mode[3] = '1' + fan_idx;
	fan_mode = get_int_option(fanX_mode, fan_mode);
	if (!fan_mode)
		fan_mode = IT8516E_MODE_AUTO;
	it8516e_set_fan_mode(fan_idx, fan_mode);

	fanX_target[3] = '1' + fan_idx;
	fan_target = get_int_option(fanX_target, fan_target);
	switch (fan_mode) {
	case IT8516E_MODE_AUTO:
		printk(BIOS_DEBUG,
		       "Setting it8516e fan%d "
		       "control to auto.\n",
		       fan_idx + 1);
		break;
	case IT8516E_MODE_PWM:
		printk(BIOS_DEBUG,
		       "Setting it8516e fan%d "
		       "control to %d%% PWM.\n",
		       fan_idx + 1, fan_target);
		if (fan_target > 100)		/* Constrain to 100% */
			fan_target = 100;
		it8516e_set_fan_pwm(fan_idx, (fan_target * 255) / 100);
		break;
	case IT8516E_MODE_SPEED:
		printk(BIOS_DEBUG,
		       "Setting it8516e fan%d "
		       "control to %d RPMs.\n",
		       fan_idx + 1, fan_target);
		it8516e_set_fan_speed(fan_idx, fan_target);
		break;
	case IT8516E_MODE_THERMAL:
		printk(BIOS_DEBUG,
		       "Setting it8516e fan%d control to %d C.\n",
		       fan_idx + 1, fan_target);
		if (fan_target > 1024)		/* Constrain to 1K */
			fan_target = 1024;
		it8516e_set_fan_temperature(fan_idx, fan_target * 64);

		fanX_min[3] = '1' + fan_idx;
		fanX_max[3] = '1' + fan_idx;
		fan_min = get_int_option(fanX_min, fan_min);
		fan_max = get_int_option(fanX_max, fan_max);

		if (!fan_max || fan_max > 100)	/* Constrain fan_max to 100% */
			fan_max = 100;
		if (fan_min >= 100)		/* Constrain fan_min to  99% */
			fan_min = 99;
		if (fan_max <= fan_min)	/* If fan_min is the higher of the two,
					   it's safer for the hardware to keep
					   its value. Therefore, update fan_max. */
			fan_max = fan_min + 1;

		printk(BIOS_DEBUG,
		       "Setting it8516e fan%d limits to %d%% - %d%% PWM.\n",
		       fan_idx + 1, fan_min, fan_max);
		it8516e_set_fan_limits(fan_idx, fan_min, fan_max);
		break;
	}
}

static void it8516e_pm2_init(struct device *dev)
{
	const config_t *const config = dev->chip_info;

	/* TODO: Set frequency / divider? */

	ec_set_ports(find_resource(dev, PNP_IDX_IO1)->base,
		     find_resource(dev, PNP_IDX_IO0)->base);

	u8 systemp_type = get_int_option("systemp_type", config->default_systemp);
	if (systemp_type >= IT8516E_SYSTEMP_LASTPLUSONE)
		systemp_type = IT8516E_SYSTEMP_NONE;
	it8516e_set_systemp_type(systemp_type);

	it8516e_set_fan_from_options(config, 0);
	it8516e_set_fan_from_options(config, 1);
}

static struct device_operations it8516e_pm2_ops = {
	.read_resources   = pnp_read_resources,
	.set_resources    = pnp_set_resources,
	.enable_resources = pnp_enable_resources,
	.enable           = pnp_enable,
	.init             = it8516e_pm2_init
};

static struct pnp_info it8516e_dev_infos[] = {
	{ NULL,             IT8516E_LDN_UART1, PNP_IO0 | PNP_IRQ0, 0x07f8, },
	{ NULL,             IT8516E_LDN_UART2, PNP_IO0 | PNP_IRQ0, 0x07f8, },
	{ NULL,             IT8516E_LDN_SWUC,  PNP_IO0 | PNP_IRQ0, 0xffe0, },
	{ NULL,             IT8516E_LDN_MOUSE, PNP_IRQ0, },
	{ NULL,             IT8516E_LDN_KBD,   PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
	{ NULL,             IT8516E_LDN_SMFI,  PNP_IO0 | PNP_IRQ0, 0xfff0, },
	{ NULL,             IT8516E_LDN_BRAM,  PNP_IO0 | PNP_IO1, 0xfffe, 0xfffe, },
	{ NULL,             IT8516E_LDN_PM1,   PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
	{ &it8516e_pm2_ops, IT8516E_LDN_PM2,   PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
	{ NULL,             IT8516E_LDN_PM3,   PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
};

static void it8516e_enable(struct device *dev)
{
	pnp_enable_devices(dev, &pnp_ops,
			   ARRAY_SIZE(it8516e_dev_infos), it8516e_dev_infos);
}

const struct chip_operations ec_kontron_it8516e_ops = {
	CHIP_NAME("Kontron (Fintec/ITE) IT8516E EC")
	.enable_dev = it8516e_enable
};
