/*
 * Samsung EXYNOS SoC series MIPI DISPLAYPORT PHY driver
 *
 * Copyright (C) 2016 Samsung Electronics Co., Ltd.
 * Author: Kwangje Kim <kj1.kim@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>

#define EXYNOS_DISPLAYPORT_PHY_ISO_BYPASS  BIT(0)

struct exynos_displayport_phy {
	struct device *dev;
	spinlock_t slock;
	void __iomem *regs;
	struct regmap *reg_pmu;
	struct displayport_phy_desc {
		struct phy *phy;
		unsigned int iso_offset;
	} phys;
};

/* 1: Isolation bypass, 0: Isolation enable */
static int __set_phy_isolation(struct regmap *reg_pmu,
		unsigned int offset, unsigned int on)
{
	unsigned int val;
	int ret;

	val = on ? EXYNOS_DISPLAYPORT_PHY_ISO_BYPASS : 0;

	ret = regmap_update_bits(reg_pmu, offset,
			EXYNOS_DISPLAYPORT_PHY_ISO_BYPASS, val);

	pr_debug("%s off=0x%x, val=0x%x\n", __func__, offset, val);
	return ret;
}

static const struct of_device_id exynos_displayport_phy_of_table[] = {
	{ .compatible = "samsung,displayport-phy" },
};
MODULE_DEVICE_TABLE(of, exynos_displayport_phy_of_table);

#define to_displayport_phy(desc) \
	container_of((desc), struct exynos_displayport_phy, phys)

static int exynos_displayport_phy_power_on(struct phy *phy)
{
	struct displayport_phy_desc *phy_desc = phy_get_drvdata(phy);
	struct exynos_displayport_phy *state = to_displayport_phy(phy_desc);

	return __set_phy_isolation(state->reg_pmu, phy_desc->iso_offset, 1);
}

static int exynos_displayport_phy_power_off(struct phy *phy)
{
	struct displayport_phy_desc *phy_desc = phy_get_drvdata(phy);
	struct exynos_displayport_phy *state = to_displayport_phy(phy_desc);

	return __set_phy_isolation(state->reg_pmu, phy_desc->iso_offset, 0);
}

static struct phy *exynos_displayport_phy_of_xlate(struct device *dev,
					struct of_phandle_args *args)
{
	struct exynos_displayport_phy *state = dev_get_drvdata(dev);

	return state->phys.phy;
}

static struct phy_ops exynos_displayport_phy_ops = {
	.power_on	= exynos_displayport_phy_power_on,
	.power_off	= exynos_displayport_phy_power_off,
	.owner		= THIS_MODULE,
};

static int exynos_displayport_phy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct exynos_displayport_phy *state;
	struct phy_provider *phy_provider;
	const struct of_device_id *of_id;
	struct phy *generic_phy;
	unsigned int iso[1];
	unsigned int elements;
	int ret = 0;

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

	state->dev = &pdev->dev;

	of_id = of_match_device(of_match_ptr(exynos_displayport_phy_of_table), dev);
	if (!of_id)
		return -EINVAL;

	dev_set_drvdata(dev, state);
	spin_lock_init(&state->slock);

	state->reg_pmu = syscon_regmap_lookup_by_phandle(node,
						"samsung,pmu-syscon");
	if (IS_ERR(state->reg_pmu)) {
		dev_err(dev, "Failed to lookup PMU regmap\n");
		return PTR_ERR(state->reg_pmu);
	}

	elements = of_property_count_u32_elems(node, "isolation");
	ret = of_property_read_u32_array(node, "isolation", iso, elements);
	if (ret) {
		dev_err(dev, "cannot get displayport-phy isolation!!!\n");
		return ret;
	}

	state->phys.iso_offset = iso[0];
	dev_dbg(dev, "%s: iso 0x%x\n", __func__, state->phys.iso_offset);

	generic_phy = devm_phy_create(dev, NULL,
				&exynos_displayport_phy_ops);
	if (IS_ERR(generic_phy)) {
		dev_err(dev, "failed to create PHY\n");
		return PTR_ERR(generic_phy);
	}

	state->phys.phy = generic_phy;

	phy_set_drvdata(generic_phy, &state->phys);

	phy_provider = devm_of_phy_provider_register(dev,
			exynos_displayport_phy_of_xlate);

	if (IS_ERR(phy_provider))
		dev_err(dev, "failed to create exynos displayport-phy\n");
	else
		dev_err(dev, "Creating exynos-displayport-phy\n");

	return PTR_ERR_OR_ZERO(phy_provider);
}

static struct platform_driver exynos_displayport_phy_driver = {
	.probe	= exynos_displayport_phy_probe,
	.driver = {
		.name  = "exynos-displayport-phy",
		.of_match_table = of_match_ptr(exynos_displayport_phy_of_table),
	}
};
module_platform_driver(exynos_displayport_phy_driver);

MODULE_DESCRIPTION("Samsung EXYNOS SoC DISPLAYPORT PHY driver");
MODULE_LICENSE("GPL v2");
