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

#include <console/console.h>
#include <device/device.h>
#include <device/i2c_bus.h>
#include <types.h>
#include <bootstate.h>

#include "ptn3460.h"

/**
 * \brief  This function selects one of 7 EDID-tables inside PTN3460
 *         which should be emulated on display port and turn emulation ON
 * @param  *dev		Pointer to the relevant I2C controller
 * @param  edid_num	Number of EDID to emulate (0..6)
 * @return PTN_SUCCESS or error code
 */
static int ptn_select_edid(struct device *dev, uint8_t edid_num)
{
	int status = 0;
	u8 val;

	if (edid_num > PTN_MAX_EDID_NUM)
		return PTN_INVALID_EDID;
	val = (edid_num << 1) | PTN_ENABLE_EMULATION;
	status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 4, val);
	return status ? (PTN_BUS_ERROR | status) : PTN_SUCCESS;
}

/**
 * \brief This function writes one EDID data structure to PTN3460
 * @param  *dev      Pointer to the relevant I2C controller
 * @param  edid_num  Number of EDID that must be written (0..6)
 * @param  *data     Pointer to a buffer where data to write is stored in
 * @return           PTN_SUCCESS on success or error code
 */
static int ptn3460_write_edid(struct device *dev, u8 edid_num, u8 *data)
{
	int status;
	int i;

	if (edid_num > PTN_MAX_EDID_NUM)
		return PTN_INVALID_EDID;

	/* First enable access to the desired EDID table */
	status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 5, edid_num);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Now we can simply write EDID data to ptn3460 */
	for (i = 0; i < PTN_EDID_LEN; i++) {
		status = i2c_dev_writeb_at(dev, PTN_EDID_OFF + i, data[i]);
		if (status)
			return (PTN_BUS_ERROR | status);
	}
	return PTN_SUCCESS;
}

/**
 * \brief This function sets up the DP2LVDS-converter to be used with the
 *         appropriate EDID data
 * @param  *dev	Pointer to the I2C controller where PTN3460 is attached
 */
static void ptn3460_init(struct device *dev)
{
	struct ptn_3460_config cfg;
	uint8_t edid_data[PTN_EDID_LEN], edid_tab, *ptr = (uint8_t *)&cfg;
	int i, val;

	/* Guard against re-initialization of the device */
	static bool init_done = false;

	if (init_done) {
		printk(BIOS_DEBUG, "Skipping PTN3460 init as it's already initialized\n");
		return;
	}

	/* Mainboard provides EDID data. */
	if (mb_get_edid(edid_data) != CB_SUCCESS) {
		printk(BIOS_ERR, "PTN3460 error: Unable to get EDID data from mainboard.\n");
		return;
	}

	/* Mainboard decides which EDID table has to be used. */
	edid_tab = mb_select_edid_table();
	if (edid_tab > PTN_MAX_EDID_NUM) {
		printk(BIOS_ERR, "PTN3460 error: invalid EDID table (%d) selected.\n",
		       edid_tab);
		return;
	}
	/* Write EDID data into PTN. */
	val = ptn3460_write_edid(dev, edid_tab, edid_data);
	if (val != PTN_SUCCESS) {
		printk(BIOS_ERR, "PTN3460 error: writing EDID data into device failed.\n");
		return;
	}
	/* Activate the selected EDID block. */
	ptn_select_edid(dev, edid_tab);
	/* Read out PTN configuration data. */
	for (i = 0; i < sizeof(struct ptn_3460_config); i++) {
		val = i2c_dev_readb_at(dev, PTN_CONFIG_OFF + i);
		if (val < 0) {
			printk(BIOS_ERR,
			       "PTN3460 error: Unable to read config data from device.\n");
			return;
		}
		*ptr++ = (uint8_t)val; /* fill config structure via ptr */
	}
	/* Mainboard can modify the configuration data.
	   Write back configuration data to PTN3460 if modified by mainboard */
	if (mb_adjust_cfg(&cfg) == CB_SUCCESS) {
		ptr = (uint8_t *)&cfg;
		for (i = 0; i < sizeof(struct ptn_3460_config); i++) {
			val = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + i, *ptr++);
			if (val < 0) {
				printk(BIOS_ERR,
				       "PTN3460 error: Unable to write config data.\n");
				return;
			}
		}
	}

	init_done = true;
}

__weak enum cb_err mb_get_edid(uint8_t edid_data[0x80])
{
	return CB_ERR;
}
__weak uint8_t mb_select_edid_table(void)
{
	return 0;
}
__weak enum cb_err mb_adjust_cfg(struct ptn_3460_config *cfg_ptr)
{
	return CB_ERR;
}

static struct device_operations ptn3460_ops = {
	.read_resources		= noop_read_resources,
	.set_resources		= noop_set_resources,
	.init			= ptn3460_init,
};

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

struct chip_operations drivers_i2c_ptn3460_ops = {
	CHIP_NAME("PTN3460")
	.enable_dev = ptn3460_enable
};

#if CONFIG(PTN3460_EARLY_INIT)

/**
 * \brief This function provides a callback for the boot state machine to initialize the
 *        PTN3460 DP-to-LVDS bridge before graphics initialization in order for the bootsplash
 *        logo to be shown.
 * @param  *unused	Unused argument for the callback.
 */

static void ptn3460_early_init(void *unused)
{
	struct device *ptn_dev;

	printk(BIOS_DEBUG, "Attempting PTN3460 early init.\n");
	ptn_dev = dev_find_slot_on_smbus(0, CONFIG_PTN3460_EARLY_ADDR);
	if (!ptn_dev) {
		printk(BIOS_ERR, "Failed to find the PTN3460 device!\n");
		return;
	}
	/* Initialize the I2C controller before it is used. */
	if (ptn_dev->bus && ptn_dev->bus->dev->ops && ptn_dev->bus->dev->ops->init)
		ptn_dev->bus->dev->ops->init(ptn_dev->bus->dev);
	ptn3460_init(ptn_dev);
}

BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, ptn3460_early_init, NULL);

#endif /* CONFIG(PTN3460_EARLY_INIT) */
