diff options
author | Heiko Stübner <heiko@sntech.de> | 2011-08-21 08:32:14 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-22 19:03:15 -0400 |
commit | 938fbe54f33e97c2911d0665ec613d7f0c967d9a (patch) | |
tree | 24248499a682ab124a9c37e90e497e901c2bc0f6 /drivers/usb/gadget/s3c-hsudc.c | |
parent | da4fc14c9955bbcafb9cdcc34f9772f3e9481bb8 (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.c | 23 |
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"); |