/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpigen.h>
#include <boot/coreboot_tables.h>
#include <cbmem.h>
#include <console/console.h>
#include <intelblocks/acpi.h>

#include "chip.h"

/* Number of registered connectors */
static size_t total_conn_count;

static void conn_init(struct device *dev)
{
	total_conn_count++;
}

static unsigned int get_usb_port_number(const struct device *usb_port)
{
	return usb_port->path.usb.port_id + 1;
}

static struct type_c_info *conn_get_cbmem_buffer(void)
{
	struct type_c_info *info;
	size_t size;

	info = cbmem_find(CBMEM_ID_TYPE_C_INFO);
	if (info)
		return info;

	size = sizeof(struct type_c_info) + total_conn_count * sizeof(struct type_c_port_info);
	info = cbmem_add(CBMEM_ID_TYPE_C_INFO, size);

	if (!info)
		return NULL;

	memset(info, 0, size);
	return info;
}

static void conn_write_cbmem_entry(struct device *dev)
{
	const struct drivers_intel_pmc_mux_conn_config *config = dev->chip_info;
	struct type_c_port_info *port_info;
	struct type_c_info *info;
	size_t count;

	/*
	 * Do not re-run this code on resume as the cbmem data is populated on boot-up
	 * (non-S3 path) and stays intact across S3 suspend/resume.
	 */
	if (acpi_is_wakeup_s3())
		return;

	info = conn_get_cbmem_buffer();
	if (!info || (info->port_count >= total_conn_count)) {
		printk(BIOS_ERR, "ERROR: No space for Type-C port info!\n");
		return;
	}

	count = info->port_count;
	port_info = &info->port_info[count];
	port_info->usb2_port_number = get_usb_port_number(config->usb2_port);
	port_info->usb3_port_number = get_usb_port_number(config->usb3_port);
	port_info->sbu_orientation = config->sbu_orientation;
	port_info->data_orientation = config->hsl_orientation;

	printk(BIOS_INFO, "added type-c port%ld info to cbmem: usb2:%d usb3:%d sbu:%d data:%d\n",
			count, port_info->usb2_port_number, port_info->usb3_port_number,
			port_info->sbu_orientation, port_info->data_orientation);

	info->port_count++;
}

static const char *conn_acpi_name(const struct device *dev)
{
	static char name[5];
	snprintf(name, sizeof(name), "CON%1X", dev->path.generic.id);
	return name;
}

static const char *orientation_to_str(enum type_c_orientation ori)
{
	switch (ori) {
	case TYPEC_ORIENTATION_NORMAL:
		return "normal";
	case TYPEC_ORIENTATION_REVERSE:
		return "reverse";
	case TYPEC_ORIENTATION_NONE: /* Intentional fallthrough */
	default:
		return "";
	}
}

static void conn_fill_ssdt(const struct device *dev)
{
	struct drivers_intel_pmc_mux_conn_config *config = dev->chip_info;
	struct acpi_dp *dsd;
	const char *scope;
	const char *name;

	/* Reference the existing scope and write CONx device */
	scope = acpi_device_scope(dev);
	name = acpi_device_name(dev);
	if (!scope || !name)
		return;

	acpigen_write_scope(scope);
	acpigen_write_device(name);

	acpigen_write_name_integer("_ADR", dev->path.generic.id);

	/* _DSD, Device-Specific Data */
	dsd = acpi_dp_new_table("_DSD");
	acpi_dp_add_integer(dsd, "usb2-port-number", get_usb_port_number(config->usb2_port));
	acpi_dp_add_integer(dsd, "usb3-port-number", get_usb_port_number(config->usb3_port));

	/*
	 * The kernel assumes that these Type-C signals (SBUs and HSLs) follow the CC lines,
	 * unless they are explicitly called out otherwise.
	 */
	if (config->sbu_orientation != TYPEC_ORIENTATION_NONE)
		acpi_dp_add_string(dsd, "sbu-orientation",
				   orientation_to_str(config->sbu_orientation));

	if (config->hsl_orientation != TYPEC_ORIENTATION_NONE)
		acpi_dp_add_string(dsd, "hsl-orientation",
				   orientation_to_str(config->hsl_orientation));

	acpi_dp_write(dsd);

	acpigen_pop_len(); /* CONx Device */
	acpigen_pop_len(); /* Scope */

	printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
	       dev_path(dev));
}

static struct device_operations conn_dev_ops = {
	.read_resources	= noop_read_resources,
	.set_resources	= noop_set_resources,
	.acpi_name	= conn_acpi_name,
	.acpi_fill_ssdt	= conn_fill_ssdt,
	.init		= conn_init,
	.final		= conn_write_cbmem_entry,
};

static void conn_enable(struct device *dev)
{
	dev->ops = &conn_dev_ops;
}

struct chip_operations drivers_intel_pmc_mux_conn_ops = {
	CHIP_NAME("Intel PMC MUX CONN Driver")
	.enable_dev	= conn_enable,
};

bool intel_pmc_mux_conn_get_ports(const struct device *conn, unsigned int *usb2_port,
					unsigned int *usb3_port)
{
	const struct drivers_intel_pmc_mux_conn_config *mux_config;

	if (!conn->chip_info || conn->chip_ops != &drivers_intel_pmc_mux_conn_ops)
		return false;

	mux_config = conn->chip_info;
	*usb2_port = get_usb_port_number(mux_config->usb2_port);
	*usb3_port = get_usb_port_number(mux_config->usb3_port);

	return true;
};
