2009-02-06 17:32:35 +05:30
/*
* 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 0213 9 , USA .
*
* Current status :
2009-03-31 12:28:31 -07:00
* This provides a " nop " transceiver for PHYs which are
* autonomous such as isp1504 , isp1707 , etc .
2009-02-06 17:32:35 +05:30
*/
# 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 ;
} ;
2009-03-31 12:28:31 -07:00
static struct platform_device * pd ;
2009-02-06 17:32:35 +05:30
void usb_nop_xceiv_register ( void )
{
2009-03-31 12:28:31 -07:00
if ( pd )
return ;
pd = platform_device_register_simple ( " nop_usb_xceiv " , - 1 , NULL , 0 ) ;
if ( ! pd ) {
2009-02-06 17:32:35 +05:30
printk ( KERN_ERR " Unable to register usb nop transceiver \n " ) ;
return ;
}
}
2009-03-31 12:28:31 -07:00
EXPORT_SYMBOL ( usb_nop_xceiv_register ) ;
2009-02-06 17:32:35 +05:30
void usb_nop_xceiv_unregister ( void )
{
2009-03-31 12:28:31 -07:00
platform_device_unregister ( pd ) ;
2009-07-03 13:18:45 +05:30
pd = NULL ;
2009-02-06 17:32:35 +05:30
}
2009-03-31 12:28:31 -07:00
EXPORT_SYMBOL ( usb_nop_xceiv_unregister ) ;
2009-02-06 17:32:35 +05:30
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 " ) ;