Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.8-rc6 181 lines 4.1 kB view raw
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/usb/nop-usb-xceiv.h> 34#include <linux/slab.h> 35 36struct nop_usb_xceiv { 37 struct usb_phy phy; 38 struct device *dev; 39}; 40 41static struct platform_device *pd; 42 43void usb_nop_xceiv_register(void) 44{ 45 if (pd) 46 return; 47 pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); 48 if (!pd) { 49 printk(KERN_ERR "Unable to register usb nop transceiver\n"); 50 return; 51 } 52} 53EXPORT_SYMBOL(usb_nop_xceiv_register); 54 55void usb_nop_xceiv_unregister(void) 56{ 57 platform_device_unregister(pd); 58 pd = NULL; 59} 60EXPORT_SYMBOL(usb_nop_xceiv_unregister); 61 62static int nop_set_suspend(struct usb_phy *x, int suspend) 63{ 64 return 0; 65} 66 67static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) 68{ 69 if (!otg) 70 return -ENODEV; 71 72 if (!gadget) { 73 otg->gadget = NULL; 74 return -ENODEV; 75 } 76 77 otg->gadget = gadget; 78 otg->phy->state = OTG_STATE_B_IDLE; 79 return 0; 80} 81 82static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) 83{ 84 if (!otg) 85 return -ENODEV; 86 87 if (!host) { 88 otg->host = NULL; 89 return -ENODEV; 90 } 91 92 otg->host = host; 93 return 0; 94} 95 96static int nop_usb_xceiv_probe(struct platform_device *pdev) 97{ 98 struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; 99 struct nop_usb_xceiv *nop; 100 enum usb_phy_type type = USB_PHY_TYPE_USB2; 101 int err; 102 103 nop = kzalloc(sizeof *nop, GFP_KERNEL); 104 if (!nop) 105 return -ENOMEM; 106 107 nop->phy.otg = kzalloc(sizeof *nop->phy.otg, GFP_KERNEL); 108 if (!nop->phy.otg) { 109 kfree(nop); 110 return -ENOMEM; 111 } 112 113 if (pdata) 114 type = pdata->type; 115 116 nop->dev = &pdev->dev; 117 nop->phy.dev = nop->dev; 118 nop->phy.label = "nop-xceiv"; 119 nop->phy.set_suspend = nop_set_suspend; 120 nop->phy.state = OTG_STATE_UNDEFINED; 121 122 nop->phy.otg->phy = &nop->phy; 123 nop->phy.otg->set_host = nop_set_host; 124 nop->phy.otg->set_peripheral = nop_set_peripheral; 125 126 err = usb_add_phy(&nop->phy, type); 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->phy.notifier); 136 137 return 0; 138exit: 139 kfree(nop->phy.otg); 140 kfree(nop); 141 return err; 142} 143 144static int nop_usb_xceiv_remove(struct platform_device *pdev) 145{ 146 struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); 147 148 usb_remove_phy(&nop->phy); 149 150 platform_set_drvdata(pdev, NULL); 151 kfree(nop->phy.otg); 152 kfree(nop); 153 154 return 0; 155} 156 157static struct platform_driver nop_usb_xceiv_driver = { 158 .probe = nop_usb_xceiv_probe, 159 .remove = nop_usb_xceiv_remove, 160 .driver = { 161 .name = "nop_usb_xceiv", 162 .owner = THIS_MODULE, 163 }, 164}; 165 166static int __init nop_usb_xceiv_init(void) 167{ 168 return platform_driver_register(&nop_usb_xceiv_driver); 169} 170subsys_initcall(nop_usb_xceiv_init); 171 172static void __exit nop_usb_xceiv_exit(void) 173{ 174 platform_driver_unregister(&nop_usb_xceiv_driver); 175} 176module_exit(nop_usb_xceiv_exit); 177 178MODULE_ALIAS("platform:nop_usb_xceiv"); 179MODULE_AUTHOR("Texas Instruments Inc"); 180MODULE_DESCRIPTION("NOP USB Transceiver driver"); 181MODULE_LICENSE("GPL");