/*
 * Copyright 2020,2021,2025 Sony Corporation
 */

#include <asm/gpio.h>
#include <common.h>
#include <dm.h>

#include <dts_parser.h>
#include <panel.h>
#include <power/regulator.h>
#include <display.h>
#include <dm/pinctrl.h>
#include <debug_impl.h>
#include <linux/errno.h>

#include "Sony_be_boot_params.h"

struct be_boot_priv {
	uint32_t pwr_1_io;
	uint32_t pwr_2_io;
	uint32_t pwr_rst_io;
	uint32_t boot_up_io;
	uint32_t vb1_req_io;
	uint32_t vb1_lockn_io;
	uint32_t on_delay;
	uint32_t stable_delay;
};


static int sony_be_boot_params_ofdata_to_platdata(struct udevice *dev)
{
	struct be_boot_priv *priv = dev_get_priv(dev);
	int err;

	printf("parse_devicetree.\n");
	err = dev_read_u32(dev, "gpio_be_power_on_1", &priv->pwr_1_io);
	err = dev_read_u32(dev, "gpio_be_power_on_2", &priv->pwr_2_io);
	err = dev_read_u32(dev, "gpio_be_reset", &priv->pwr_rst_io);
	err = dev_read_u32(dev, "gpio_boot_up", &priv->boot_up_io);
	err = dev_read_u32(dev, "gpio_vb1_req", &priv->vb1_req_io);
	err = dev_read_u32(dev, "gpio_vb1_lockn", &priv->vb1_lockn_io);
	err = dev_read_u32(dev, "on_delay", &priv->on_delay);
	err = dev_read_u32(dev, "stable_delay", &priv->stable_delay);

	//T.B.D
	if (err != 0)
		printf("sony_be_boot_params_ofdata_to_platdata_fail\n");

	return 0;
}

int update_be_boot_params(struct udevice *dev)
{
	struct be_boot_priv *priv = dev_get_priv(dev);
	int err;

	err = parse_dt("/odm/sony_be_boot", integer_dt_parser, (void *)&priv->boot_up_io, "gpio_boot_up");
	if (err != 0) {
		printf("Failed to read gpio_boot_up from device tree\n");
		return err; //failue
	}

	err = parse_dt("/odm/sony_be_boot", integer_dt_parser, (void *)&priv->vb1_lockn_io, "gpio_vb1_lockn");
	if (err != 0) {
		printf("Failed to read gpio_vb1_lockn from device tree\n");
		return err; // failure
	}

	return 0; //success
}

int get_be_power_on_param(struct udevice *dev, struct be_boot_pwr_on *be_boot_param)
{
	struct be_boot_priv *priv = dev_get_priv(dev);

	printf("panel_sony_set_op_panel_enable start.\n");
	be_boot_param->pwr_1_io = priv->pwr_1_io;
	be_boot_param->pwr_2_io = priv->pwr_2_io;
	be_boot_param->pwr_rst_io = priv->pwr_rst_io;
	be_boot_param->on_delay = priv->on_delay;
	be_boot_param->stable_delay = priv->stable_delay;

	return 0;
}

unsigned int get_be_vb1lockn_io(struct udevice *dev)
{
	struct be_boot_priv *priv = dev_get_priv(dev);

	return priv->vb1_lockn_io;
}

unsigned int get_be_vb1req_io(struct udevice *dev)
{
	struct be_boot_priv *priv = dev_get_priv(dev);

	return priv->vb1_req_io;
}

unsigned int get_be_bootup_io(struct udevice *dev)
{
	struct be_boot_priv *priv = dev_get_priv(dev);

	return priv->boot_up_io;
}


static const struct udevice_id sony_be_boot_params_ids[] = {
	{ .compatible = "sony,be_boot" },
	{ },
};


U_BOOT_DRIVER(sony_be_boot_params) = {
	.name = "sony_be_boot_params",
	.id = UCLASS_NOP,
	.of_match = sony_be_boot_params_ids,
	.ofdata_to_platdata = sony_be_boot_params_ofdata_to_platdata,
	.priv_auto_alloc_size = sizeof(struct be_boot_priv),
};
