// SPDX-License-Identifier: GPL-2.0+
/*
 * Platform driver for OneXPlayer, AOK ZOE, and Aya Neo Handhelds that expose
 * fan reading and control via hwmon sysfs.
 *
 * Old OXP boards have the same DMI strings and they are told apart by
 * the boot cpu vendor (Intel/AMD). Currently only AMD boards are
 * supported but the code is made to be simple to add other handheld
 * boards in the future.
 * Fan control is provided via pwm interface in the range [0-255].
 * Old AMD boards use [0-100] as range in the EC, the written value is
 * scaled to accommodate for that. Newer boards like the mini PRO and
 * AOK ZOE are not scaled but have the same EC layout.
 *
 * Copyright (C) 2022 Joaquín I. Aramendía <samsagax@gmail.com>
 */

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/processor.h>

/* Handle ACPI lock mechanism */
static u32 oxp_mutex;

#define ACPI_LOCK_DELAY_MS	500

static bool lock_global_acpi_lock(void)
{
	return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, &oxp_mutex));
}

static bool unlock_global_acpi_lock(void)
{
	return ACPI_SUCCESS(acpi_release_global_lock(oxp_mutex));
}

enum oxp_board {
	aok_zoe_a1 = 1,
	aya_neo_2,
	aya_neo_air,
	aya_neo_air_plus_mendo,
	aya_neo_air_pro,
	aya_neo_geek,
	oxp_mini_amd,
	oxp_mini_amd_a07,
	oxp_mini_amd_pro,
};

static enum oxp_board board;

/* Fan reading and PWM */
#define OXP_SENSOR_FAN_REG		0x76 /* Fan reading is 2 registers long */
#define OXP_SENSOR_PWM_ENABLE_REG	0x4A /* PWM enable is 1 register long */
#define OXP_SENSOR_PWM_REG		0x4B /* PWM reading is 1 register long */

/* Turbo button takeover function
 * Older boards have different values and EC registers
 * for the same function
 */
#define OXP_OLD_TURBO_SWITCH_REG	0x1E
#define OXP_OLD_TURBO_TAKE_VAL		0x01
#define OXP_OLD_TURBO_RETURN_VAL	0x00

#define OXP_TURBO_SWITCH_REG		0xF1
#define OXP_TURBO_TAKE_VAL		0x40
#define OXP_TURBO_RETURN_VAL		0x00

static const struct dmi_system_id dmi_table[] = {
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A1 AR07"),
		},
		.driver_data = (void *)aok_zoe_a1,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A1 Pro"),
		},
		.driver_data = (void *)aok_zoe_a1,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AYANEO 2"),
		},
		.driver_data = (void *)aya_neo_2,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"),
		},
		.driver_data = (void *)aya_neo_air,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AB05-Mendocino"),
		},
		.driver_data = (void *)aya_neo_air_plus_mendo,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR Pro"),
		},
		.driver_data = (void *)aya_neo_air_pro,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "GEEK"),
		},
		.driver_data = (void *)aya_neo_geek,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONE XPLAYER"),
		},
		.driver_data = (void *)oxp_mini_amd,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER mini A07"),
		},
		.driver_data = (void *)oxp_mini_amd_a07,
	},
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER Mini Pro"),
		},
		.driver_data = (void *)oxp_mini_amd_pro,
	},
	{},
};

/* Helper functions to handle EC read/write */
static int read_from_ec(u8 reg, int size, long *val)
{
	int i;
	int ret;
	u8 buffer;

	if (!lock_global_acpi_lock())
		return -EBUSY;

	*val = 0;
	for (i = 0; i < size; i++) {
		ret = ec_read(reg + i, &buffer);
		if (ret)
			return ret;
		*val <<= i * 8;
		*val += buffer;
	}

	if (!unlock_global_acpi_lock())
		return -EBUSY;

	return 0;
}

static int write_to_ec(u8 reg, u8 value)
{
	int ret;

	if (!lock_global_acpi_lock())
		return -EBUSY;

	ret = ec_write(reg, value);

	if (!unlock_global_acpi_lock())
		return -EBUSY;

	return ret;
}

/* Turbo button toggle functions */
static int tt_toggle_enable(void)
{
	u8 reg;
	u8 val;

	switch (board) {
	case oxp_mini_amd_a07:
		reg = OXP_OLD_TURBO_SWITCH_REG;
		val = OXP_OLD_TURBO_TAKE_VAL;
		break;
	case oxp_mini_amd_pro:
	case aok_zoe_a1:
		reg = OXP_TURBO_SWITCH_REG;
		val = OXP_TURBO_TAKE_VAL;
		break;
	default:
		return -EINVAL;
	}
	return write_to_ec(reg, val);
}

static int tt_toggle_disable(void)
{
	u8 reg;
	u8 val;

	switch (board) {
	case oxp_mini_amd_a07:
		reg = OXP_OLD_TURBO_SWITCH_REG;
		val = OXP_OLD_TURBO_RETURN_VAL;
		break;
	case oxp_mini_amd_pro:
	case aok_zoe_a1:
		reg = OXP_TURBO_SWITCH_REG;
		val = OXP_TURBO_RETURN_VAL;
		break;
	default:
		return -EINVAL;
	}
	return write_to_ec(reg, val);
}

/* Callbacks for turbo toggle attribute */
static umode_t tt_toggle_is_visible(struct kobject *kobj,
				    struct attribute *attr, int n)
{
	switch (board) {
	case aok_zoe_a1:
	case oxp_mini_amd_a07:
	case oxp_mini_amd_pro:
		return attr->mode;
	default:
		break;
	}
	return 0;
}

static ssize_t tt_toggle_store(struct device *dev,
			       struct device_attribute *attr, const char *buf,
			       size_t count)
{
	int rval;
	bool value;

	rval = kstrtobool(buf, &value);
	if (rval)
		return rval;

	if (value) {
		rval = tt_toggle_enable();
	} else {
		rval = tt_toggle_disable();
	}
	if (rval)
		return rval;

	return count;
}

static ssize_t tt_toggle_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	int retval;
	u8 reg;
	long val;

	switch (board) {
	case oxp_mini_amd_a07:
		reg = OXP_OLD_TURBO_SWITCH_REG;
		break;
	case oxp_mini_amd_pro:
	case aok_zoe_a1:
		reg = OXP_TURBO_SWITCH_REG;
		break;
	default:
		return -EINVAL;
	}

	retval = read_from_ec(reg, 1, &val);
	if (retval)
		return retval;

	return sysfs_emit(buf, "%d\n", !!val);
}

static DEVICE_ATTR_RW(tt_toggle);

/* PWM enable/disable functions */
static int oxp_pwm_enable(void)
{
	return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, 0x01);
}

static int oxp_pwm_disable(void)
{
	return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, 0x00);
}

/* Callbacks for hwmon interface */
static umode_t oxp_ec_hwmon_is_visible(const void *drvdata,
				       enum hwmon_sensor_types type, u32 attr, int channel)
{
	switch (type) {
	case hwmon_fan:
		return 0444;
	case hwmon_pwm:
		return 0644;
	default:
		return 0;
	}
}

static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
			     u32 attr, int channel, long *val)
{
	int ret;

	switch (type) {
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
			return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
		default:
			break;
		}
		break;
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
			ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
			if (ret)
				return ret;
			switch (board) {
			case aya_neo_2:
			case aya_neo_air:
			case aya_neo_air_plus_mendo:
			case aya_neo_air_pro:
			case aya_neo_geek:
			case oxp_mini_amd:
			case oxp_mini_amd_a07:
				*val = (*val * 255) / 100;
				break;
			case oxp_mini_amd_pro:
			case aok_zoe_a1:
			default:
				break;
			}
			return 0;
		case hwmon_pwm_enable:
			return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val);
		default:
			break;
		}
		break;
	default:
		break;
	}
	return -EOPNOTSUPP;
}

static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
			      u32 attr, int channel, long val)
{
	switch (type) {
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_enable:
			if (val == 1)
				return oxp_pwm_enable();
			else if (val == 0)
				return oxp_pwm_disable();
			return -EINVAL;
		case hwmon_pwm_input:
			if (val < 0 || val > 255)
				return -EINVAL;
			switch (board) {
			case aya_neo_2:
			case aya_neo_air:
			case aya_neo_air_plus_mendo:
			case aya_neo_air_pro:
			case aya_neo_geek:
			case oxp_mini_amd:
			case oxp_mini_amd_a07:
				val = (val * 100) / 255;
				break;
			case aok_zoe_a1:
			case oxp_mini_amd_pro:
			default:
				break;
			}
			return write_to_ec(OXP_SENSOR_PWM_REG, val);
		default:
			break;
		}
		break;
	default:
		break;
	}
	return -EOPNOTSUPP;
}

/* Known sensors in the OXP EC controllers */
static const struct hwmon_channel_info * const oxp_platform_sensors[] = {
	HWMON_CHANNEL_INFO(fan,
			   HWMON_F_INPUT),
	HWMON_CHANNEL_INFO(pwm,
			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
	NULL,
};

static struct attribute *oxp_ec_attrs[] = {
	&dev_attr_tt_toggle.attr,
	NULL
};

static struct attribute_group oxp_ec_attribute_group = {
	.is_visible = tt_toggle_is_visible,
	.attrs = oxp_ec_attrs,
};

static const struct attribute_group *oxp_ec_groups[] = {
	&oxp_ec_attribute_group,
	NULL
};

static const struct hwmon_ops oxp_ec_hwmon_ops = {
	.is_visible = oxp_ec_hwmon_is_visible,
	.read = oxp_platform_read,
	.write = oxp_platform_write,
};

static const struct hwmon_chip_info oxp_ec_chip_info = {
	.ops = &oxp_ec_hwmon_ops,
	.info = oxp_platform_sensors,
};

/* Initialization logic */
static int oxp_platform_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device *hwdev;

	hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL,
						     &oxp_ec_chip_info, NULL);

	return PTR_ERR_OR_ZERO(hwdev);
}

static struct platform_driver oxp_platform_driver = {
	.driver = {
		.name = "oxp-platform",
		.dev_groups = oxp_ec_groups,
	},
	.probe = oxp_platform_probe,
};

static struct platform_device *oxp_platform_device;

static int __init oxp_platform_init(void)
{
	const struct dmi_system_id *dmi_entry;

	/*
	 * Have to check for AMD processor here because DMI strings are the
	 * same between Intel and AMD boards, the only way to tell them apart
	 * is the CPU.
	 * Intel boards seem to have different EC registers and values to
	 * read/write.
	 */
	dmi_entry = dmi_first_match(dmi_table);
	if (!dmi_entry || boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
		return -ENODEV;

	board = (enum oxp_board)(unsigned long)dmi_entry->driver_data;

	oxp_platform_device =
		platform_create_bundle(&oxp_platform_driver,
				       oxp_platform_probe, NULL, 0, NULL, 0);

	return PTR_ERR_OR_ZERO(oxp_platform_device);
}

static void __exit oxp_platform_exit(void)
{
	platform_device_unregister(oxp_platform_device);
	platform_driver_unregister(&oxp_platform_driver);
}

MODULE_DEVICE_TABLE(dmi, dmi_table);

module_init(oxp_platform_init);
module_exit(oxp_platform_exit);

MODULE_AUTHOR("Joaquín Ignacio Aramendía <samsagax@gmail.com>");
MODULE_DESCRIPTION("Platform driver that handles EC sensors of OneXPlayer devices");
MODULE_LICENSE("GPL");
