/*
 * phy-keystone - USB PHY, talking to dwc3 controller in Keystone.
 *
 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
 *
 * Author: WingMan Kwok <w-kwok2@ti.com>
 *
 * 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/module.h>
#include <linux/platform_device.h>
#include <linux/usb/usb_phy_gen_xceiv.h>
#include <linux/io.h>
#include <linux/of.h>

#include "phy-generic.h"

/* USB PHY control register offsets */
#define USB_PHY_CTL_UTMI		0x0000
#define USB_PHY_CTL_PIPE		0x0004
#define USB_PHY_CTL_PARAM_1		0x0008
#define USB_PHY_CTL_PARAM_2		0x000c
#define USB_PHY_CTL_CLOCK		0x0010
#define USB_PHY_CTL_PLL			0x0014

#define PHY_REF_SSP_EN			BIT(29)

struct keystone_usbphy {
	struct usb_phy_gen_xceiv	usb_phy_gen;
	void __iomem			*phy_ctrl;
};

static inline u32 keystone_usbphy_readl(void __iomem *base, u32 offset)
{
	return readl(base + offset);
}

static inline void keystone_usbphy_writel(void __iomem *base,
					  u32 offset, u32 value)
{
	writel(value, base + offset);
}

static int keystone_usbphy_init(struct usb_phy *phy)
{
	struct keystone_usbphy *k_phy = dev_get_drvdata(phy->dev);
	u32 val;

	val  = keystone_usbphy_readl(k_phy->phy_ctrl, USB_PHY_CTL_CLOCK);
	keystone_usbphy_writel(k_phy->phy_ctrl, USB_PHY_CTL_CLOCK,
				val | PHY_REF_SSP_EN);
	return 0;
}

static void keystone_usbphy_shutdown(struct usb_phy *phy)
{
	struct keystone_usbphy *k_phy = dev_get_drvdata(phy->dev);
	u32 val;

	val  = keystone_usbphy_readl(k_phy->phy_ctrl, USB_PHY_CTL_CLOCK);
	keystone_usbphy_writel(k_phy->phy_ctrl, USB_PHY_CTL_CLOCK,
				val &= ~PHY_REF_SSP_EN);
}

static int keystone_usbphy_probe(struct platform_device *pdev)
{
	struct device		*dev = &pdev->dev;
	struct keystone_usbphy	*k_phy;
	struct resource		*res;
	int ret;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	k_phy->phy_ctrl = devm_ioremap_resource(dev, res);
	if (IS_ERR(k_phy->phy_ctrl))
		return PTR_ERR(k_phy->phy_ctrl);

	ret = usb_phy_gen_create_phy(dev, &k_phy->usb_phy_gen, NULL);
	if (ret)
		return ret;

	k_phy->usb_phy_gen.phy.init = keystone_usbphy_init;
	k_phy->usb_phy_gen.phy.shutdown = keystone_usbphy_shutdown;

	platform_set_drvdata(pdev, k_phy);

	ret = usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
	if (ret)
		return ret;

	return 0;
}

static int keystone_usbphy_remove(struct platform_device *pdev)
{
	struct keystone_usbphy *k_phy = platform_get_drvdata(pdev);

	usb_remove_phy(&k_phy->usb_phy_gen.phy);

	return 0;
}

static const struct of_device_id keystone_usbphy_ids[] = {
	{ .compatible = "ti,keystone-usbphy" },
	{ }
};
MODULE_DEVICE_TABLE(of, keystone_usbphy_ids);

static struct platform_driver keystone_usbphy_driver = {
	.probe          = keystone_usbphy_probe,
	.remove         = keystone_usbphy_remove,
	.driver         = {
		.name   = "keystone-usbphy",
		.owner  = THIS_MODULE,
		.of_match_table = keystone_usbphy_ids,
	},
};

module_platform_driver(keystone_usbphy_driver);

MODULE_ALIAS("platform:keystone-usbphy");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_DESCRIPTION("Keystone USB phy driver");
MODULE_LICENSE("GPL v2");
