/*
 * PHY driver for NXP LPC18xx/43xx internal USB OTG PHY
 *
 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.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/clk.h>
#include <linux/err.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

/* USB OTG PHY register offset and bit in CREG */
#define LPC18XX_CREG_CREG0		0x004
#define LPC18XX_CREG_CREG0_USB0PHY	BIT(5)

struct lpc18xx_usb_otg_phy {
	struct phy *phy;
	struct clk *clk;
	struct regmap *reg;
};

static int lpc18xx_usb_otg_phy_init(struct phy *phy)
{
	struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy);
	int ret;

	/* The PHY must be clocked at 480 MHz */
	ret = clk_set_rate(lpc->clk, 480000000);
	if (ret)
		return ret;

	return clk_prepare(lpc->clk);
}

static int lpc18xx_usb_otg_phy_exit(struct phy *phy)
{
	struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy);

	clk_unprepare(lpc->clk);

	return 0;
}

static int lpc18xx_usb_otg_phy_power_on(struct phy *phy)
{
	struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy);
	int ret;

	ret = clk_enable(lpc->clk);
	if (ret)
		return ret;

	/* The bit in CREG is cleared to enable the PHY */
	return regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
				  LPC18XX_CREG_CREG0_USB0PHY, 0);
}

static int lpc18xx_usb_otg_phy_power_off(struct phy *phy)
{
	struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy);
	int ret;

	ret = regmap_update_bits(lpc->reg, LPC18XX_CREG_CREG0,
				 LPC18XX_CREG_CREG0_USB0PHY,
				 LPC18XX_CREG_CREG0_USB0PHY);
	if (ret)
		return ret;

	clk_disable(lpc->clk);

	return 0;
}

static const struct phy_ops lpc18xx_usb_otg_phy_ops = {
	.init		= lpc18xx_usb_otg_phy_init,
	.exit		= lpc18xx_usb_otg_phy_exit,
	.power_on	= lpc18xx_usb_otg_phy_power_on,
	.power_off	= lpc18xx_usb_otg_phy_power_off,
	.owner		= THIS_MODULE,
};

static int lpc18xx_usb_otg_phy_probe(struct platform_device *pdev)
{
	struct phy_provider *phy_provider;
	struct lpc18xx_usb_otg_phy *lpc;

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

	lpc->reg = syscon_node_to_regmap(pdev->dev.of_node->parent);
	if (IS_ERR(lpc->reg)) {
		dev_err(&pdev->dev, "failed to get syscon\n");
		return PTR_ERR(lpc->reg);
	}

	lpc->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(lpc->clk)) {
		dev_err(&pdev->dev, "failed to get clock\n");
		return PTR_ERR(lpc->clk);
	}

	lpc->phy = devm_phy_create(&pdev->dev, NULL, &lpc18xx_usb_otg_phy_ops);
	if (IS_ERR(lpc->phy)) {
		dev_err(&pdev->dev, "failed to create PHY\n");
		return PTR_ERR(lpc->phy);
	}

	phy_set_drvdata(lpc->phy, lpc);

	phy_provider = devm_of_phy_provider_register(&pdev->dev,
						     of_phy_simple_xlate);

	return PTR_ERR_OR_ZERO(phy_provider);
}

static const struct of_device_id lpc18xx_usb_otg_phy_match[] = {
	{ .compatible = "nxp,lpc1850-usb-otg-phy" },
	{ }
};
MODULE_DEVICE_TABLE(of, lpc18xx_usb_otg_phy_match);

static struct platform_driver lpc18xx_usb_otg_phy_driver = {
	.probe		= lpc18xx_usb_otg_phy_probe,
	.driver		= {
		.name	= "lpc18xx-usb-otg-phy",
		.of_match_table = lpc18xx_usb_otg_phy_match,
	},
};
module_platform_driver(lpc18xx_usb_otg_phy_driver);

MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("NXP LPC18xx/43xx USB OTG PHY driver");
MODULE_LICENSE("GPL v2");
