// SPDX-License-Identifier: GPL-2.0
/*
 * Arche Platform driver to control APB.
 *
 * Copyright 2014-2015 Google Inc.
 * Copyright 2014-2015 Linaro Ltd.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/regulator/consumer.h>
#include <linux/spinlock.h>
#include "arche_platform.h"


static void apb_bootret_deassert(struct device *dev);

struct arche_apb_ctrl_drvdata {
	/* Control GPIO signals to and from AP <=> AP Bridges */
	int resetn_gpio;
	int boot_ret_gpio;
	int pwroff_gpio;
	int wake_in_gpio;
	int wake_out_gpio;
	int pwrdn_gpio;

	enum arche_platform_state state;
	bool init_disabled;

	struct regulator *vcore;
	struct regulator *vio;

	int clk_en_gpio;
	struct clk *clk;

	struct pinctrl *pinctrl;
	struct pinctrl_state *pin_default;

	/* V2: SPI Bus control  */
	int spi_en_gpio;
	bool spi_en_polarity_high;
};

/*
 * Note that these low level api's are active high
 */
static inline void deassert_reset(unsigned int gpio)
{
	gpio_set_value(gpio, 1);
}

static inline void assert_reset(unsigned int gpio)
{
	gpio_set_value(gpio, 0);
}

/*
 * Note: Please do not modify the below sequence, as it is as per the spec
 */
static int coldboot_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
	int ret;

	if (apb->init_disabled ||
	    apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
		return 0;

	/* Hold APB in reset state */
	assert_reset(apb->resetn_gpio);

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
	    gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/* Enable power to APB */
	if (!IS_ERR(apb->vcore)) {
		ret = regulator_enable(apb->vcore);
		if (ret) {
			dev_err(dev, "failed to enable core regulator\n");
			return ret;
		}
	}

	if (!IS_ERR(apb->vio)) {
		ret = regulator_enable(apb->vio);
		if (ret) {
			dev_err(dev, "failed to enable IO regulator\n");
			return ret;
		}
	}

	apb_bootret_deassert(dev);

	/* On DB3 clock was not mandatory */
	if (gpio_is_valid(apb->clk_en_gpio))
		gpio_set_value(apb->clk_en_gpio, 1);

	usleep_range(100, 200);

	/* deassert reset to APB : Active-low signal */
	deassert_reset(apb->resetn_gpio);

	apb->state = ARCHE_PLATFORM_STATE_ACTIVE;

	return 0;
}

static int fw_flashing_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
	int ret;

	if (apb->init_disabled ||
	    apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
		return 0;

	ret = regulator_enable(apb->vcore);
	if (ret) {
		dev_err(dev, "failed to enable core regulator\n");
		return ret;
	}

	ret = regulator_enable(apb->vio);
	if (ret) {
		dev_err(dev, "failed to enable IO regulator\n");
		return ret;
	}

	if (gpio_is_valid(apb->spi_en_gpio)) {
		unsigned long flags;

		if (apb->spi_en_polarity_high)
			flags = GPIOF_OUT_INIT_HIGH;
		else
			flags = GPIOF_OUT_INIT_LOW;

		ret = devm_gpio_request_one(dev, apb->spi_en_gpio,
					    flags, "apb_spi_en");
		if (ret) {
			dev_err(dev, "Failed requesting SPI bus en gpio %d\n",
				apb->spi_en_gpio);
			return ret;
		}
	}

	/* for flashing device should be in reset state */
	assert_reset(apb->resetn_gpio);
	apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING;

	return 0;
}

static int standby_boot_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);

	if (apb->init_disabled)
		return 0;

	/*
	 * Even if it is in OFF state,
	 * then we do not want to change the state
	 */
	if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
	    apb->state == ARCHE_PLATFORM_STATE_OFF)
		return 0;

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
	    gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/*
	 * As per WDM spec, do nothing
	 *
	 * Pasted from WDM spec,
	 *  - A falling edge on POWEROFF_L is detected (a)
	 *  - WDM enters standby mode, but no output signals are changed
	 */

	/* TODO: POWEROFF_L is input to WDM module  */
	apb->state = ARCHE_PLATFORM_STATE_STANDBY;
	return 0;
}

static void poweroff_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);

	if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
		return;

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
	    gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/* disable the clock */
	if (gpio_is_valid(apb->clk_en_gpio))
		gpio_set_value(apb->clk_en_gpio, 0);

	if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
		regulator_disable(apb->vcore);

	if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
		regulator_disable(apb->vio);

	/* As part of exit, put APB back in reset state */
	assert_reset(apb->resetn_gpio);
	apb->state = ARCHE_PLATFORM_STATE_OFF;

	/* TODO: May have to send an event to SVC about this exit */
}

static void apb_bootret_deassert(struct device *dev)
{
	struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);

	gpio_set_value(apb->boot_ret_gpio, 0);
}

int apb_ctrl_coldboot(struct device *dev)
{
	return coldboot_seq(to_platform_device(dev));
}

int apb_ctrl_fw_flashing(struct device *dev)
{
	return fw_flashing_seq(to_platform_device(dev));
}

int apb_ctrl_standby_boot(struct device *dev)
{
	return standby_boot_seq(to_platform_device(dev));
}

void apb_ctrl_poweroff(struct device *dev)
{
	poweroff_seq(to_platform_device(dev));
}

static ssize_t state_store(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
	int ret = 0;
	bool is_disabled;

	if (sysfs_streq(buf, "off")) {
		if (apb->state == ARCHE_PLATFORM_STATE_OFF)
			return count;

		poweroff_seq(pdev);
	} else if (sysfs_streq(buf, "active")) {
		if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
			return count;

		poweroff_seq(pdev);
		is_disabled = apb->init_disabled;
		apb->init_disabled = false;
		ret = coldboot_seq(pdev);
		if (ret)
			apb->init_disabled = is_disabled;
	} else if (sysfs_streq(buf, "standby")) {
		if (apb->state == ARCHE_PLATFORM_STATE_STANDBY)
			return count;

		ret = standby_boot_seq(pdev);
	} else if (sysfs_streq(buf, "fw_flashing")) {
		if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
			return count;

		/*
		 * First we want to make sure we power off everything
		 * and then enter FW flashing state
		 */
		poweroff_seq(pdev);
		ret = fw_flashing_seq(pdev);
	} else {
		dev_err(dev, "unknown state\n");
		ret = -EINVAL;
	}

	return ret ? ret : count;
}

static ssize_t state_show(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);

	switch (apb->state) {
	case ARCHE_PLATFORM_STATE_OFF:
		return sprintf(buf, "off%s\n",
				apb->init_disabled ? ",disabled" : "");
	case ARCHE_PLATFORM_STATE_ACTIVE:
		return sprintf(buf, "active\n");
	case ARCHE_PLATFORM_STATE_STANDBY:
		return sprintf(buf, "standby\n");
	case ARCHE_PLATFORM_STATE_FW_FLASHING:
		return sprintf(buf, "fw_flashing\n");
	default:
		return sprintf(buf, "unknown state\n");
	}
}

static DEVICE_ATTR_RW(state);

static int apb_ctrl_get_devtree_data(struct platform_device *pdev,
				     struct arche_apb_ctrl_drvdata *apb)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	int ret;

	apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0);
	if (apb->resetn_gpio < 0) {
		dev_err(dev, "failed to get reset gpio\n");
		return apb->resetn_gpio;
	}
	ret = devm_gpio_request_one(dev, apb->resetn_gpio,
				    GPIOF_OUT_INIT_LOW, "apb-reset");
	if (ret) {
		dev_err(dev, "Failed requesting reset gpio %d\n",
			apb->resetn_gpio);
		return ret;
	}

	apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0);
	if (apb->boot_ret_gpio < 0) {
		dev_err(dev, "failed to get boot retention gpio\n");
		return apb->boot_ret_gpio;
	}
	ret = devm_gpio_request_one(dev, apb->boot_ret_gpio,
				    GPIOF_OUT_INIT_LOW, "boot retention");
	if (ret) {
		dev_err(dev, "Failed requesting bootret gpio %d\n",
			apb->boot_ret_gpio);
		return ret;
	}

	/* It's not mandatory to support power management interface */
	apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0);
	if (apb->pwroff_gpio < 0) {
		dev_err(dev, "failed to get power off gpio\n");
		return apb->pwroff_gpio;
	}
	ret = devm_gpio_request_one(dev, apb->pwroff_gpio,
				    GPIOF_IN, "pwroff_n");
	if (ret) {
		dev_err(dev, "Failed requesting pwroff_n gpio %d\n",
			apb->pwroff_gpio);
		return ret;
	}

	/* Do not make clock mandatory as of now (for DB3) */
	apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0);
	if (apb->clk_en_gpio < 0) {
		dev_warn(dev, "failed to get clock en gpio\n");
	} else if (gpio_is_valid(apb->clk_en_gpio)) {
		ret = devm_gpio_request_one(dev, apb->clk_en_gpio,
					    GPIOF_OUT_INIT_LOW, "apb_clk_en");
		if (ret) {
			dev_warn(dev, "Failed requesting APB clock en gpio %d\n",
				 apb->clk_en_gpio);
			return ret;
		}
	}

	apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0);
	if (apb->pwrdn_gpio < 0)
		dev_warn(dev, "failed to get power down gpio\n");

	/* Regulators are optional, as we may have fixed supply coming in */
	apb->vcore = devm_regulator_get(dev, "vcore");
	if (IS_ERR(apb->vcore))
		dev_warn(dev, "no core regulator found\n");

	apb->vio = devm_regulator_get(dev, "vio");
	if (IS_ERR(apb->vio))
		dev_warn(dev, "no IO regulator found\n");

	apb->pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(apb->pinctrl)) {
		dev_err(&pdev->dev, "could not get pinctrl handle\n");
		return PTR_ERR(apb->pinctrl);
	}
	apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default");
	if (IS_ERR(apb->pin_default)) {
		dev_err(&pdev->dev, "could not get default pin state\n");
		return PTR_ERR(apb->pin_default);
	}

	/* Only applicable for platform >= V2 */
	apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0);
	if (apb->spi_en_gpio >= 0) {
		if (of_property_read_bool(pdev->dev.of_node,
					  "spi-en-active-high"))
			apb->spi_en_polarity_high = true;
	}

	return 0;
}

static int arche_apb_ctrl_probe(struct platform_device *pdev)
{
	int ret;
	struct arche_apb_ctrl_drvdata *apb;
	struct device *dev = &pdev->dev;

	apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL);
	if (!apb)
		return -ENOMEM;

	ret = apb_ctrl_get_devtree_data(pdev, apb);
	if (ret) {
		dev_err(dev, "failed to get apb devicetree data %d\n", ret);
		return ret;
	}

	/* Initially set APB to OFF state */
	apb->state = ARCHE_PLATFORM_STATE_OFF;
	/* Check whether device needs to be enabled on boot */
	if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable"))
		apb->init_disabled = true;

	platform_set_drvdata(pdev, apb);

	/* Create sysfs interface to allow user to change state dynamically */
	ret = device_create_file(dev, &dev_attr_state);
	if (ret) {
		dev_err(dev, "failed to create state file in sysfs\n");
		return ret;
	}

	dev_info(&pdev->dev, "Device registered successfully\n");
	return 0;
}

static int arche_apb_ctrl_remove(struct platform_device *pdev)
{
	device_remove_file(&pdev->dev, &dev_attr_state);
	poweroff_seq(pdev);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev)
{
	/*
	 * If timing profile permits, we may shutdown bridge
	 * completely
	 *
	 * TODO: sequence ??
	 *
	 * Also, need to make sure we meet precondition for unipro suspend
	 * Precondition: Definition ???
	 */
	return 0;
}

static int __maybe_unused arche_apb_ctrl_resume(struct device *dev)
{
	/*
	 * Atleast for ES2 we have to meet the delay requirement between
	 * unipro switch and AP bridge init, depending on whether bridge is in
	 * OFF state or standby state.
	 *
	 * Based on whether bridge is in standby or OFF state we may have to
	 * assert multiple signals. Please refer to WDM spec, for more info.
	 *
	 */
	return 0;
}

static void arche_apb_ctrl_shutdown(struct platform_device *pdev)
{
	apb_ctrl_poweroff(&pdev->dev);
}

static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend,
			 arche_apb_ctrl_resume);

static const struct of_device_id arche_apb_ctrl_of_match[] = {
	{ .compatible = "usbffff,2", },
	{ },
};

static struct platform_driver arche_apb_ctrl_device_driver = {
	.probe		= arche_apb_ctrl_probe,
	.remove		= arche_apb_ctrl_remove,
	.shutdown	= arche_apb_ctrl_shutdown,
	.driver		= {
		.name	= "arche-apb-ctrl",
		.pm	= &arche_apb_ctrl_pm_ops,
		.of_match_table = arche_apb_ctrl_of_match,
	}
};

int __init arche_apb_init(void)
{
	return platform_driver_register(&arche_apb_ctrl_device_driver);
}

void __exit arche_apb_exit(void)
{
	platform_driver_unregister(&arche_apb_ctrl_device_driver);
}
