aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/s3c-hsudc.c
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2011-08-21 08:32:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-22 19:03:15 -0400
commit938fbe54f33e97c2911d0665ec613d7f0c967d9a (patch)
tree24248499a682ab124a9c37e90e497e901c2bc0f6 /drivers/usb/gadget/s3c-hsudc.c
parentda4fc14c9955bbcafb9cdcc34f9772f3e9481bb8 (diff)
s3c-hsudc: Add basic otg transceiver handling
Makes it possible to use i.e. gpio-vbus to handle vbus events. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/s3c-hsudc.c')
-rw-r--r--drivers/usb/gadget/s3c-hsudc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
index 00056c27a1c8..3e96cc5bb77f 100644
--- a/drivers/usb/gadget/s3c-hsudc.c
+++ b/drivers/usb/gadget/s3c-hsudc.c
@@ -26,6 +26,7 @@
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/usb/ch9.h> 27#include <linux/usb/ch9.h>
28#include <linux/usb/gadget.h> 28#include <linux/usb/gadget.h>
29#include <linux/usb/otg.h>
29#include <linux/prefetch.h> 30#include <linux/prefetch.h>
30 31
31#include <mach/regs-s3c2443-clock.h> 32#include <mach/regs-s3c2443-clock.h>
@@ -137,6 +138,7 @@ struct s3c_hsudc {
137 struct usb_gadget_driver *driver; 138 struct usb_gadget_driver *driver;
138 struct device *dev; 139 struct device *dev;
139 struct s3c24xx_hsudc_platdata *pd; 140 struct s3c24xx_hsudc_platdata *pd;
141 struct otg_transceiver *transceiver;
140 spinlock_t lock; 142 spinlock_t lock;
141 void __iomem *regs; 143 void __iomem *regs;
142 struct resource *mem_rsrc; 144 struct resource *mem_rsrc;
@@ -1171,6 +1173,22 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver,
1171 return ret; 1173 return ret;
1172 } 1174 }
1173 1175
1176 /* connect to bus through transceiver */
1177 if (hsudc->transceiver) {
1178 ret = otg_set_peripheral(hsudc->transceiver, &hsudc->gadget);
1179 if (ret) {
1180 dev_err(hsudc->dev, "%s: can't bind to transceiver\n",
1181 hsudc->gadget.name);
1182 driver->unbind(&hsudc->gadget);
1183
1184 device_del(&hsudc->gadget.dev);
1185
1186 hsudc->driver = NULL;
1187 hsudc->gadget.dev.driver = NULL;
1188 return ret;
1189 }
1190 }
1191
1174 enable_irq(hsudc->irq); 1192 enable_irq(hsudc->irq);
1175 dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); 1193 dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name);
1176 1194
@@ -1201,6 +1219,9 @@ static int s3c_hsudc_stop(struct usb_gadget_driver *driver)
1201 s3c_hsudc_stop_activity(hsudc, driver); 1219 s3c_hsudc_stop_activity(hsudc, driver);
1202 spin_unlock_irqrestore(&hsudc->lock, flags); 1220 spin_unlock_irqrestore(&hsudc->lock, flags);
1203 1221
1222 if (hsudc->transceiver)
1223 (void) otg_set_peripheral(hsudc->transceiver, NULL);
1224
1204 driver->unbind(&hsudc->gadget); 1225 driver->unbind(&hsudc->gadget);
1205 device_del(&hsudc->gadget.dev); 1226 device_del(&hsudc->gadget.dev);
1206 disable_irq(hsudc->irq); 1227 disable_irq(hsudc->irq);
@@ -1247,6 +1268,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev)
1247 hsudc->dev = dev; 1268 hsudc->dev = dev;
1248 hsudc->pd = pdev->dev.platform_data; 1269 hsudc->pd = pdev->dev.platform_data;
1249 1270
1271 hsudc->transceiver = otg_get_transceiver();
1272
1250 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1273 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1251 if (!res) { 1274 if (!res) {
1252 dev_err(dev, "unable to obtain driver resource data\n"); 1275 dev_err(dev, "unable to obtain driver resource data\n");