Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v6.8.
  1/*
  2 * drivers/usb/otg/nop-usb-xceiv.c
  3 *
  4 * NOP USB transceiver for all USB transceiver which are either built-in
  5 * into USB IP or which are mostly autonomous.
  6 *
  7 * Copyright (C) 2009 Texas Instruments Inc
  8 * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, write to the Free Software
 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 23 *
 24 * Current status:
 25 *	This provides a "nop" transceiver for PHYs which are
 26 *	autonomous such as isp1504, isp1707, etc.
 27 */
 28
 29#include <linux/module.h>
 30#include <linux/platform_device.h>
 31#include <linux/dma-mapping.h>
 32#include <linux/usb/otg.h>
 33#include <linux/slab.h>
 34
 35struct nop_usb_xceiv {
 36	struct otg_transceiver	otg;
 37	struct device		*dev;
 38};
 39
 40static struct platform_device *pd;
 41
 42void usb_nop_xceiv_register(void)
 43{
 44	if (pd)
 45		return;
 46	pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0);
 47	if (!pd) {
 48		printk(KERN_ERR "Unable to register usb nop transceiver\n");
 49		return;
 50	}
 51}
 52EXPORT_SYMBOL(usb_nop_xceiv_register);
 53
 54void usb_nop_xceiv_unregister(void)
 55{
 56	platform_device_unregister(pd);
 57	pd = NULL;
 58}
 59EXPORT_SYMBOL(usb_nop_xceiv_unregister);
 60
 61static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x)
 62{
 63	return container_of(x, struct nop_usb_xceiv, otg);
 64}
 65
 66static int nop_set_suspend(struct otg_transceiver *x, int suspend)
 67{
 68	return 0;
 69}
 70
 71static int nop_set_peripheral(struct otg_transceiver *x,
 72		struct usb_gadget *gadget)
 73{
 74	struct nop_usb_xceiv *nop;
 75
 76	if (!x)
 77		return -ENODEV;
 78
 79	nop = xceiv_to_nop(x);
 80
 81	if (!gadget) {
 82		nop->otg.gadget = NULL;
 83		return -ENODEV;
 84	}
 85
 86	nop->otg.gadget = gadget;
 87	nop->otg.state = OTG_STATE_B_IDLE;
 88	return 0;
 89}
 90
 91static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host)
 92{
 93	struct nop_usb_xceiv *nop;
 94
 95	if (!x)
 96		return -ENODEV;
 97
 98	nop = xceiv_to_nop(x);
 99
100	if (!host) {
101		nop->otg.host = NULL;
102		return -ENODEV;
103	}
104
105	nop->otg.host = host;
106	return 0;
107}
108
109static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
110{
111	struct nop_usb_xceiv	*nop;
112	int err;
113
114	nop = kzalloc(sizeof *nop, GFP_KERNEL);
115	if (!nop)
116		return -ENOMEM;
117
118	nop->dev		= &pdev->dev;
119	nop->otg.dev		= nop->dev;
120	nop->otg.label		= "nop-xceiv";
121	nop->otg.state		= OTG_STATE_UNDEFINED;
122	nop->otg.set_host	= nop_set_host;
123	nop->otg.set_peripheral	= nop_set_peripheral;
124	nop->otg.set_suspend	= nop_set_suspend;
125
126	err = otg_set_transceiver(&nop->otg);
127	if (err) {
128		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
129			err);
130		goto exit;
131	}
132
133	platform_set_drvdata(pdev, nop);
134
135	ATOMIC_INIT_NOTIFIER_HEAD(&nop->otg.notifier);
136
137	return 0;
138exit:
139	kfree(nop);
140	return err;
141}
142
143static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
144{
145	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
146
147	otg_set_transceiver(NULL);
148
149	platform_set_drvdata(pdev, NULL);
150	kfree(nop);
151
152	return 0;
153}
154
155static struct platform_driver nop_usb_xceiv_driver = {
156	.probe		= nop_usb_xceiv_probe,
157	.remove		= __devexit_p(nop_usb_xceiv_remove),
158	.driver		= {
159		.name	= "nop_usb_xceiv",
160		.owner	= THIS_MODULE,
161	},
162};
163
164static int __init nop_usb_xceiv_init(void)
165{
166	return platform_driver_register(&nop_usb_xceiv_driver);
167}
168subsys_initcall(nop_usb_xceiv_init);
169
170static void __exit nop_usb_xceiv_exit(void)
171{
172	platform_driver_unregister(&nop_usb_xceiv_driver);
173}
174module_exit(nop_usb_xceiv_exit);
175
176MODULE_ALIAS("platform:nop_usb_xceiv");
177MODULE_AUTHOR("Texas Instruments Inc");
178MODULE_DESCRIPTION("NOP USB Transceiver driver");
179MODULE_LICENSE("GPL");