/*
 * Allwinner sun4i USB phy driver
 *
 * Copyright (C) 2014-2015 Hans de Goede <hdegoede@redhat.com>
 *
 * Based on code from
 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
 *
 * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/extcon.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/phy/phy.h>
#include <linux/phy/phy-sun4i-usb.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/workqueue.h>

#define REG_ISCR			0x00
#define REG_PHYCTL			0x04
#define REG_PHYBIST			0x08
#define REG_PHYTUNE			0x0c

#define PHYCTL_DATA			BIT(7)

#define SUNXI_AHB_ICHR8_EN		BIT(10)
#define SUNXI_AHB_INCR4_BURST_EN	BIT(9)
#define SUNXI_AHB_INCRX_ALIGN_EN	BIT(8)
#define SUNXI_ULPI_BYPASS_EN		BIT(0)

/* ISCR, Interface Status and Control bits */
#define ISCR_ID_PULLUP_EN		(1 << 17)
#define ISCR_DPDM_PULLUP_EN	(1 << 16)
/* sunxi has the phy id/vbus pins not connected, so we use the force bits */
#define ISCR_FORCE_ID_MASK	(3 << 14)
#define ISCR_FORCE_ID_LOW		(2 << 14)
#define ISCR_FORCE_ID_HIGH	(3 << 14)
#define ISCR_FORCE_VBUS_MASK	(3 << 12)
#define ISCR_FORCE_VBUS_LOW	(2 << 12)
#define ISCR_FORCE_VBUS_HIGH	(3 << 12)

/* Common Control Bits for Both PHYs */
#define PHY_PLL_BW			0x03
#define PHY_RES45_CAL_EN		0x0c

/* Private Control Bits for Each PHY */
#define PHY_TX_AMPLITUDE_TUNE		0x20
#define PHY_TX_SLEWRATE_TUNE		0x22
#define PHY_VBUSVALID_TH_SEL		0x25
#define PHY_PULLUP_RES_SEL		0x27
#define PHY_OTG_FUNC_EN			0x28
#define PHY_VBUS_DET_EN			0x29
#define PHY_DISCON_TH_SEL		0x2a
#define PHY_SQUELCH_DETECT		0x3c

#define MAX_PHYS			3

/*
 * Note do not raise the debounce time, we must report Vusb high within 100ms
 * otherwise we get Vbus errors
 */
#define DEBOUNCE_TIME			msecs_to_jiffies(50)
#define POLL_TIME			msecs_to_jiffies(250)

struct sun4i_usb_phy_data {
	void __iomem *base;
	struct mutex mutex;
	int num_phys;
	u32 disc_thresh;
	struct sun4i_usb_phy {
		struct phy *phy;
		void __iomem *pmu;
		struct regulator *vbus;
		struct reset_control *reset;
		struct clk *clk;
		bool regulator_on;
		int index;
	} phys[MAX_PHYS];
	/* phy0 / otg related variables */
	struct extcon_dev *extcon;
	bool phy0_init;
	bool phy0_poll;
	struct gpio_desc *id_det_gpio;
	struct gpio_desc *vbus_det_gpio;
	int id_det_irq;
	int vbus_det_irq;
	int id_det;
	int vbus_det;
	struct delayed_work detect;
};

#define to_sun4i_usb_phy_data(phy) \
	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])

static void sun4i_usb_phy0_update_iscr(struct phy *_phy, u32 clr, u32 set)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
	u32 iscr;

	iscr = readl(data->base + REG_ISCR);
	iscr &= ~clr;
	iscr |= set;
	writel(iscr, data->base + REG_ISCR);
}

static void sun4i_usb_phy0_set_id_detect(struct phy *phy, u32 val)
{
	if (val)
		val = ISCR_FORCE_ID_HIGH;
	else
		val = ISCR_FORCE_ID_LOW;

	sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_ID_MASK, val);
}

static void sun4i_usb_phy0_set_vbus_detect(struct phy *phy, u32 val)
{
	if (val)
		val = ISCR_FORCE_VBUS_HIGH;
	else
		val = ISCR_FORCE_VBUS_LOW;

	sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_VBUS_MASK, val);
}

static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
				int len)
{
	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
	u32 temp, usbc_bit = BIT(phy->index * 2);
	int i;

	mutex_lock(&phy_data->mutex);

	for (i = 0; i < len; i++) {
		temp = readl(phy_data->base + REG_PHYCTL);

		/* clear the address portion */
		temp &= ~(0xff << 8);

		/* set the address */
		temp |= ((addr + i) << 8);
		writel(temp, phy_data->base + REG_PHYCTL);

		/* set the data bit and clear usbc bit*/
		temp = readb(phy_data->base + REG_PHYCTL);
		if (data & 0x1)
			temp |= PHYCTL_DATA;
		else
			temp &= ~PHYCTL_DATA;
		temp &= ~usbc_bit;
		writeb(temp, phy_data->base + REG_PHYCTL);

		/* pulse usbc_bit */
		temp = readb(phy_data->base + REG_PHYCTL);
		temp |= usbc_bit;
		writeb(temp, phy_data->base + REG_PHYCTL);

		temp = readb(phy_data->base + REG_PHYCTL);
		temp &= ~usbc_bit;
		writeb(temp, phy_data->base + REG_PHYCTL);

		data >>= 1;
	}
	mutex_unlock(&phy_data->mutex);
}

static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
{
	u32 bits, reg_value;

	if (!phy->pmu)
		return;

	bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
		SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;

	reg_value = readl(phy->pmu);

	if (enable)
		reg_value |= bits;
	else
		reg_value &= ~bits;

	writel(reg_value, phy->pmu);
}

static int sun4i_usb_phy_init(struct phy *_phy)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
	int ret;

	ret = clk_prepare_enable(phy->clk);
	if (ret)
		return ret;

	ret = reset_control_deassert(phy->reset);
	if (ret) {
		clk_disable_unprepare(phy->clk);
		return ret;
	}

	/* Enable USB 45 Ohm resistor calibration */
	if (phy->index == 0)
		sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);

	/* Adjust PHY's magnitude and rate */
	sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);

	/* Disconnect threshold adjustment */
	sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2);

	sun4i_usb_phy_passby(phy, 1);

	if (phy->index == 0) {
		data->phy0_init = true;

		/* Enable pull-ups */
		sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN);
		sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN);

		if (data->id_det_gpio) {
			/* OTG mode, force ISCR and cable state updates */
			data->id_det = -1;
			data->vbus_det = -1;
			queue_delayed_work(system_wq, &data->detect, 0);
		} else {
			/* Host only mode */
			sun4i_usb_phy0_set_id_detect(_phy, 0);
			sun4i_usb_phy0_set_vbus_detect(_phy, 1);
		}
	}

	return 0;
}

static int sun4i_usb_phy_exit(struct phy *_phy)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);

	if (phy->index == 0) {
		/* Disable pull-ups */
		sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0);
		sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0);
		data->phy0_init = false;
	}

	sun4i_usb_phy_passby(phy, 0);
	reset_control_assert(phy->reset);
	clk_disable_unprepare(phy->clk);

	return 0;
}

static int sun4i_usb_phy_power_on(struct phy *_phy)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
	int ret;

	if (!phy->vbus || phy->regulator_on)
		return 0;

	/* For phy0 only turn on Vbus if we don't have an ext. Vbus */
	if (phy->index == 0 && data->vbus_det)
		return 0;

	ret = regulator_enable(phy->vbus);
	if (ret)
		return ret;

	phy->regulator_on = true;

	/* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
	if (phy->index == 0 && data->phy0_poll)
		mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);

	return 0;
}

static int sun4i_usb_phy_power_off(struct phy *_phy)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);

	if (!phy->vbus || !phy->regulator_on)
		return 0;

	regulator_disable(phy->vbus);
	phy->regulator_on = false;

	/*
	 * phy0 vbus typically slowly discharges, sometimes this causes the
	 * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
	 */
	if (phy->index == 0 && !data->phy0_poll)
		mod_delayed_work(system_wq, &data->detect, POLL_TIME);

	return 0;
}

void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
{
	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);

	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
}

static struct phy_ops sun4i_usb_phy_ops = {
	.init		= sun4i_usb_phy_init,
	.exit		= sun4i_usb_phy_exit,
	.power_on	= sun4i_usb_phy_power_on,
	.power_off	= sun4i_usb_phy_power_off,
	.owner		= THIS_MODULE,
};

static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
{
	struct sun4i_usb_phy_data *data =
		container_of(work, struct sun4i_usb_phy_data, detect.work);
	struct phy *phy0 = data->phys[0].phy;
	int id_det, vbus_det, id_notify = 0, vbus_notify = 0;

	id_det = gpiod_get_value_cansleep(data->id_det_gpio);
	vbus_det = gpiod_get_value_cansleep(data->vbus_det_gpio);

	mutex_lock(&phy0->mutex);

	if (!data->phy0_init) {
		mutex_unlock(&phy0->mutex);
		return;
	}

	if (id_det != data->id_det) {
		sun4i_usb_phy0_set_id_detect(phy0, id_det);
		data->id_det = id_det;
		id_notify = 1;
	}

	if (vbus_det != data->vbus_det) {
		sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det);
		data->vbus_det = vbus_det;
		vbus_notify = 1;
	}

	mutex_unlock(&phy0->mutex);

	if (id_notify)
		extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
					!id_det);

	if (vbus_notify)
		extcon_set_cable_state_(data->extcon, EXTCON_USB, vbus_det);

	if (data->phy0_poll)
		queue_delayed_work(system_wq, &data->detect, POLL_TIME);
}

static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id)
{
	struct sun4i_usb_phy_data *data = dev_id;

	/* vbus or id changed, let the pins settle and then scan them */
	mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);

	return IRQ_HANDLED;
}

static struct phy *sun4i_usb_phy_xlate(struct device *dev,
					struct of_phandle_args *args)
{
	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);

	if (args->args[0] >= data->num_phys)
		return ERR_PTR(-ENODEV);

	return data->phys[args->args[0]].phy;
}

static int sun4i_usb_phy_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);

	if (data->id_det_irq >= 0)
		devm_free_irq(dev, data->id_det_irq, data);
	if (data->vbus_det_irq >= 0)
		devm_free_irq(dev, data->vbus_det_irq, data);

	cancel_delayed_work_sync(&data->detect);

	return 0;
}

static const unsigned int sun4i_usb_phy0_cable[] = {
	EXTCON_USB,
	EXTCON_USB_HOST,
	EXTCON_NONE,
};

static int sun4i_usb_phy_probe(struct platform_device *pdev)
{
	struct sun4i_usb_phy_data *data;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct phy_provider *phy_provider;
	bool dedicated_clocks;
	struct resource *res;
	int i, ret;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	mutex_init(&data->mutex);
	INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
	dev_set_drvdata(dev, data);

	if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy"))
		data->num_phys = 2;
	else
		data->num_phys = 3;

	if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") ||
	    of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy"))
		data->disc_thresh = 3;
	else
		data->disc_thresh = 2;

	if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy"))
		dedicated_clocks = true;
	else
		dedicated_clocks = false;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl");
	data->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(data->base))
		return PTR_ERR(data->base);

	data->id_det_gpio = devm_gpiod_get(dev, "usb0_id_det", GPIOD_IN);
	if (IS_ERR(data->id_det_gpio)) {
		if (PTR_ERR(data->id_det_gpio) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		data->id_det_gpio = NULL;
	}

	data->vbus_det_gpio = devm_gpiod_get(dev, "usb0_vbus_det", GPIOD_IN);
	if (IS_ERR(data->vbus_det_gpio)) {
		if (PTR_ERR(data->vbus_det_gpio) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		data->vbus_det_gpio = NULL;
	}

	/* We either want both gpio pins or neither (when in host mode) */
	if (!data->id_det_gpio != !data->vbus_det_gpio) {
		dev_err(dev, "failed to get id or vbus detect pin\n");
		return -ENODEV;
	}

	if (data->id_det_gpio) {
		data->extcon = devm_extcon_dev_allocate(dev,
							sun4i_usb_phy0_cable);
		if (IS_ERR(data->extcon))
			return PTR_ERR(data->extcon);

		ret = devm_extcon_dev_register(dev, data->extcon);
		if (ret) {
			dev_err(dev, "failed to register extcon: %d\n", ret);
			return ret;
		}
	}

	for (i = 0; i < data->num_phys; i++) {
		struct sun4i_usb_phy *phy = data->phys + i;
		char name[16];

		snprintf(name, sizeof(name), "usb%d_vbus", i);
		phy->vbus = devm_regulator_get_optional(dev, name);
		if (IS_ERR(phy->vbus)) {
			if (PTR_ERR(phy->vbus) == -EPROBE_DEFER)
				return -EPROBE_DEFER;
			phy->vbus = NULL;
		}

		if (dedicated_clocks)
			snprintf(name, sizeof(name), "usb%d_phy", i);
		else
			strlcpy(name, "usb_phy", sizeof(name));

		phy->clk = devm_clk_get(dev, name);
		if (IS_ERR(phy->clk)) {
			dev_err(dev, "failed to get clock %s\n", name);
			return PTR_ERR(phy->clk);
		}

		snprintf(name, sizeof(name), "usb%d_reset", i);
		phy->reset = devm_reset_control_get(dev, name);
		if (IS_ERR(phy->reset)) {
			dev_err(dev, "failed to get reset %s\n", name);
			return PTR_ERR(phy->reset);
		}

		if (i) { /* No pmu for usbc0 */
			snprintf(name, sizeof(name), "pmu%d", i);
			res = platform_get_resource_byname(pdev,
							IORESOURCE_MEM, name);
			phy->pmu = devm_ioremap_resource(dev, res);
			if (IS_ERR(phy->pmu))
				return PTR_ERR(phy->pmu);
		}

		phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops);
		if (IS_ERR(phy->phy)) {
			dev_err(dev, "failed to create PHY %d\n", i);
			return PTR_ERR(phy->phy);
		}

		phy->index = i;
		phy_set_drvdata(phy->phy, &data->phys[i]);
	}

	data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
	data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio);
	if (data->id_det_irq  < 0 || data->vbus_det_irq < 0)
		data->phy0_poll = true;

	if (data->id_det_irq >= 0) {
		ret = devm_request_irq(dev, data->id_det_irq,
				sun4i_usb_phy0_id_vbus_det_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"usb0-id-det", data);
		if (ret) {
			dev_err(dev, "Err requesting id-det-irq: %d\n", ret);
			return ret;
		}
	}

	if (data->vbus_det_irq >= 0) {
		ret = devm_request_irq(dev, data->vbus_det_irq,
				sun4i_usb_phy0_id_vbus_det_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"usb0-vbus-det", data);
		if (ret) {
			dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret);
			data->vbus_det_irq = -1;
			sun4i_usb_phy_remove(pdev); /* Stop detect work */
			return ret;
		}
	}

	phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
	if (IS_ERR(phy_provider)) {
		sun4i_usb_phy_remove(pdev); /* Stop detect work */
		return PTR_ERR(phy_provider);
	}

	return 0;
}

static const struct of_device_id sun4i_usb_phy_of_match[] = {
	{ .compatible = "allwinner,sun4i-a10-usb-phy" },
	{ .compatible = "allwinner,sun5i-a13-usb-phy" },
	{ .compatible = "allwinner,sun6i-a31-usb-phy" },
	{ .compatible = "allwinner,sun7i-a20-usb-phy" },
	{ },
};
MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);

static struct platform_driver sun4i_usb_phy_driver = {
	.probe	= sun4i_usb_phy_probe,
	.remove	= sun4i_usb_phy_remove,
	.driver = {
		.of_match_table	= sun4i_usb_phy_of_match,
		.name  = "sun4i-usb-phy",
	}
};
module_platform_driver(sun4i_usb_phy_driver);

MODULE_DESCRIPTION("Allwinner sun4i USB phy driver");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL v2");
