/*
 * drivers/usb/otg/nop-usb-xceiv.c
 *
 * NOP USB transceiver for all USB transceiver which are either built-in
 * into USB IP or which are mostly autonomous.
 *
 * Copyright (C) 2009 Texas Instruments Inc
 * Author: Ajay Kumar Gupta <ajay.gupta@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.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Current status:
 * 	this is to add "nop" transceiver for all those phy which is
 * 	autonomous such as isp1504 etc.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/usb/otg.h>

struct nop_usb_xceiv {
	struct otg_transceiver	otg;
	struct device		*dev;
};

static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;

static struct platform_device nop_xceiv_device = {
	.name           = "nop_usb_xceiv",
	.id             = -1,
	.dev = {
		.dma_mask               = &nop_xceiv_dmamask,
		.coherent_dma_mask      = DMA_32BIT_MASK,
		.platform_data          = NULL,
	},
};

void usb_nop_xceiv_register(void)
{
	if (platform_device_register(&nop_xceiv_device) < 0) {
		printk(KERN_ERR "Unable to register usb nop transceiver\n");
		return;
	}
}

void usb_nop_xceiv_unregister(void)
{
	platform_device_unregister(&nop_xceiv_device);
}

static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x)
{
	return container_of(x, struct nop_usb_xceiv, otg);
}

static int nop_set_suspend(struct otg_transceiver *x, int suspend)
{
	return 0;
}

static int nop_set_peripheral(struct otg_transceiver *x,
		struct usb_gadget *gadget)
{
	struct nop_usb_xceiv *nop;

	if (!x)
		return -ENODEV;

	nop = xceiv_to_nop(x);

	if (!gadget) {
		nop->otg.gadget = NULL;
		return -ENODEV;
	}

	nop->otg.gadget = gadget;
	nop->otg.state = OTG_STATE_B_IDLE;
	return 0;
}

static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host)
{
	struct nop_usb_xceiv *nop;

	if (!x)
		return -ENODEV;

	nop = xceiv_to_nop(x);

	if (!host) {
		nop->otg.host = NULL;
		return -ENODEV;
	}

	nop->otg.host = host;
	return 0;
}

static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
{
	struct nop_usb_xceiv	*nop;
	int err;

	nop = kzalloc(sizeof *nop, GFP_KERNEL);
	if (!nop)
		return -ENOMEM;

	nop->dev		= &pdev->dev;
	nop->otg.dev		= nop->dev;
	nop->otg.label		= "nop-xceiv";
	nop->otg.state		= OTG_STATE_UNDEFINED;
	nop->otg.set_host	= nop_set_host;
	nop->otg.set_peripheral	= nop_set_peripheral;
	nop->otg.set_suspend	= nop_set_suspend;

	err = otg_set_transceiver(&nop->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
			err);
		goto exit;
	}

	platform_set_drvdata(pdev, nop);

	return 0;
exit:
	kfree(nop);
	return err;
}

static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
{
	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);

	otg_set_transceiver(NULL);

	platform_set_drvdata(pdev, NULL);
	kfree(nop);

	return 0;
}

static struct platform_driver nop_usb_xceiv_driver = {
	.probe		= nop_usb_xceiv_probe,
	.remove		= __devexit_p(nop_usb_xceiv_remove),
	.driver		= {
		.name	= "nop_usb_xceiv",
		.owner	= THIS_MODULE,
	},
};

static int __init nop_usb_xceiv_init(void)
{
	return platform_driver_register(&nop_usb_xceiv_driver);
}
subsys_initcall(nop_usb_xceiv_init);

static void __exit nop_usb_xceiv_exit(void)
{
	platform_driver_unregister(&nop_usb_xceiv_driver);
}
module_exit(nop_usb_xceiv_exit);

MODULE_ALIAS("platform:nop_usb_xceiv");
MODULE_AUTHOR("Texas Instruments Inc");
MODULE_DESCRIPTION("NOP USB Transceiver driver");
MODULE_LICENSE("GPL");
