aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/otg
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2012-09-06 10:57:07 -0400
committerFelipe Balbi <balbi@ti.com>2012-09-06 13:15:59 -0400
commit0e98de67bacba812b1b465b90a3f940d24401c27 (patch)
treec30e6cd16ac5f3d33a696f50304c6538cc20e121 /drivers/usb/otg
parent657b306a7bdfca4ae1514b533a0e7c3c6d26dbc6 (diff)
usb: otg: make twl6030_usb as a comparator driver to omap_usb2
All the PHY configuration other than VBUS, ID GND and OTG SRP are removed from twl6030. The phy configurations are taken care by the dedicated usb2 phy driver. So twl6030 is made as comparator driver for VBUS and ID detection. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/otg')
-rw-r--r--drivers/usb/otg/Kconfig2
-rw-r--r--drivers/usb/otg/twl6030-usb.c118
2 files changed, 19 insertions, 101 deletions
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 13fd1ddf742f..d8c8a42bff3e 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -68,7 +68,7 @@ config TWL4030_USB
68 68
69config TWL6030_USB 69config TWL6030_USB
70 tristate "TWL6030 USB Transceiver Driver" 70 tristate "TWL6030 USB Transceiver Driver"
71 depends on TWL4030_CORE 71 depends on TWL4030_CORE && OMAP_USB2
72 select USB_OTG_UTILS 72 select USB_OTG_UTILS
73 help 73 help
74 Enable this to support the USB OTG transceiver on TWL6030 74 Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c
index 6907d8df7a27..32525bb667ee 100644
--- a/drivers/usb/otg/twl6030-usb.c
+++ b/drivers/usb/otg/twl6030-usb.c
@@ -25,8 +25,9 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/usb/otg.h>
29#include <linux/usb/musb-omap.h> 28#include <linux/usb/musb-omap.h>
29#include <linux/usb/phy_companion.h>
30#include <linux/usb/omap_usb.h>
30#include <linux/i2c/twl.h> 31#include <linux/i2c/twl.h>
31#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
32#include <linux/err.h> 33#include <linux/err.h>
@@ -87,7 +88,7 @@
87#define VBUS_DET BIT(2) 88#define VBUS_DET BIT(2)
88 89
89struct twl6030_usb { 90struct twl6030_usb {
90 struct usb_phy phy; 91 struct phy_companion comparator;
91 struct device *dev; 92 struct device *dev;
92 93
93 /* for vbus reporting with irqs disabled */ 94 /* for vbus reporting with irqs disabled */
@@ -107,7 +108,7 @@ struct twl6030_usb {
107 unsigned long features; 108 unsigned long features;
108}; 109};
109 110
110#define phy_to_twl(x) container_of((x), struct twl6030_usb, phy) 111#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator)
111 112
112/*-------------------------------------------------------------------------*/ 113/*-------------------------------------------------------------------------*/
113 114
@@ -137,50 +138,9 @@ static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address)
137 return ret; 138 return ret;
138} 139}
139 140
140static int twl6030_phy_init(struct usb_phy *x) 141static int twl6030_start_srp(struct phy_companion *comparator)
141{ 142{
142 struct twl6030_usb *twl; 143 struct twl6030_usb *twl = comparator_to_twl(comparator);
143 struct device *dev;
144 struct twl4030_usb_data *pdata;
145
146 twl = phy_to_twl(x);
147 dev = twl->dev;
148 pdata = dev->platform_data;
149
150 if (twl->linkstat == OMAP_MUSB_ID_GROUND)
151 pdata->phy_power(twl->dev, 1, 1);
152 else
153 pdata->phy_power(twl->dev, 0, 1);
154
155 return 0;
156}
157
158static void twl6030_phy_shutdown(struct usb_phy *x)
159{
160 struct twl6030_usb *twl;
161 struct device *dev;
162 struct twl4030_usb_data *pdata;
163
164 twl = phy_to_twl(x);
165 dev = twl->dev;
166 pdata = dev->platform_data;
167 pdata->phy_power(twl->dev, 0, 0);
168}
169
170static int twl6030_phy_suspend(struct usb_phy *x, int suspend)
171{
172 struct twl6030_usb *twl = phy_to_twl(x);
173 struct device *dev = twl->dev;
174 struct twl4030_usb_data *pdata = dev->platform_data;
175
176 pdata->phy_suspend(dev, suspend);
177
178 return 0;
179}
180
181static int twl6030_start_srp(struct usb_otg *otg)
182{
183 struct twl6030_usb *twl = phy_to_twl(otg->phy);
184 144
185 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); 145 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET);
186 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); 146 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET);
@@ -313,23 +273,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
313 return IRQ_HANDLED; 273 return IRQ_HANDLED;
314} 274}
315 275
316static int twl6030_set_peripheral(struct usb_otg *otg, 276static int twl6030_enable_irq(struct twl6030_usb *twl)
317 struct usb_gadget *gadget)
318{ 277{
319 if (!otg)
320 return -ENODEV;
321
322 otg->gadget = gadget;
323 if (!gadget)
324 otg->phy->state = OTG_STATE_UNDEFINED;
325
326 return 0;
327}
328
329static int twl6030_enable_irq(struct usb_phy *x)
330{
331 struct twl6030_usb *twl = phy_to_twl(x);
332
333 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); 278 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
334 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); 279 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C);
335 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); 280 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C);
@@ -362,9 +307,9 @@ static void otg_set_vbus_work(struct work_struct *data)
362 CHARGERUSB_CTRL1); 307 CHARGERUSB_CTRL1);
363} 308}
364 309
365static int twl6030_set_vbus(struct usb_otg *otg, bool enabled) 310static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
366{ 311{
367 struct twl6030_usb *twl = phy_to_twl(otg->phy); 312 struct twl6030_usb *twl = comparator_to_twl(comparator);
368 313
369 twl->vbus_enable = enabled; 314 twl->vbus_enable = enabled;
370 schedule_work(&twl->set_vbus_work); 315 schedule_work(&twl->set_vbus_work);
@@ -372,23 +317,12 @@ static int twl6030_set_vbus(struct usb_otg *otg, bool enabled)
372 return 0; 317 return 0;
373} 318}
374 319
375static int twl6030_set_host(struct usb_otg *otg, struct usb_bus *host)
376{
377 if (!otg)
378 return -ENODEV;
379
380 otg->host = host;
381 if (!host)
382 otg->phy->state = OTG_STATE_UNDEFINED;
383 return 0;
384}
385
386static int __devinit twl6030_usb_probe(struct platform_device *pdev) 320static int __devinit twl6030_usb_probe(struct platform_device *pdev)
387{ 321{
322 u32 ret;
388 struct twl6030_usb *twl; 323 struct twl6030_usb *twl;
389 int status, err; 324 int status, err;
390 struct twl4030_usb_data *pdata; 325 struct twl4030_usb_data *pdata;
391 struct usb_otg *otg;
392 struct device *dev = &pdev->dev; 326 struct device *dev = &pdev->dev;
393 pdata = dev->platform_data; 327 pdata = dev->platform_data;
394 328
@@ -396,28 +330,20 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
396 if (!twl) 330 if (!twl)
397 return -ENOMEM; 331 return -ENOMEM;
398 332
399 otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL);
400 if (!otg)
401 return -ENOMEM;
402
403 twl->dev = &pdev->dev; 333 twl->dev = &pdev->dev;
404 twl->irq1 = platform_get_irq(pdev, 0); 334 twl->irq1 = platform_get_irq(pdev, 0);
405 twl->irq2 = platform_get_irq(pdev, 1); 335 twl->irq2 = platform_get_irq(pdev, 1);
406 twl->features = pdata->features; 336 twl->features = pdata->features;
407 twl->linkstat = OMAP_MUSB_UNKNOWN; 337 twl->linkstat = OMAP_MUSB_UNKNOWN;
408 338
409 twl->phy.dev = twl->dev; 339 twl->comparator.set_vbus = twl6030_set_vbus;
410 twl->phy.label = "twl6030"; 340 twl->comparator.start_srp = twl6030_start_srp;
411 twl->phy.otg = otg;
412 twl->phy.init = twl6030_phy_init;
413 twl->phy.shutdown = twl6030_phy_shutdown;
414 twl->phy.set_suspend = twl6030_phy_suspend;
415 341
416 otg->phy = &twl->phy; 342 ret = omap_usb2_set_comparator(&twl->comparator);
417 otg->set_host = twl6030_set_host; 343 if (ret == -ENODEV) {
418 otg->set_peripheral = twl6030_set_peripheral; 344 dev_info(&pdev->dev, "phy not ready, deferring probe");
419 otg->set_vbus = twl6030_set_vbus; 345 return -EPROBE_DEFER;
420 otg->start_srp = twl6030_start_srp; 346 }
421 347
422 /* init spinlock for workqueue */ 348 /* init spinlock for workqueue */
423 spin_lock_init(&twl->lock); 349 spin_lock_init(&twl->lock);
@@ -427,7 +353,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
427 dev_err(&pdev->dev, "ldo init failed\n"); 353 dev_err(&pdev->dev, "ldo init failed\n");
428 return err; 354 return err;
429 } 355 }
430 usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);
431 356
432 platform_set_drvdata(pdev, twl); 357 platform_set_drvdata(pdev, twl);
433 if (device_create_file(&pdev->dev, &dev_attr_vbus)) 358 if (device_create_file(&pdev->dev, &dev_attr_vbus))
@@ -458,9 +383,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
458 } 383 }
459 384
460 twl->asleep = 0; 385 twl->asleep = 0;
461 pdata->phy_init(dev); 386 twl6030_enable_irq(twl);
462 twl6030_phy_suspend(&twl->phy, 0);
463 twl6030_enable_irq(&twl->phy);
464 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); 387 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
465 388
466 return 0; 389 return 0;
@@ -470,10 +393,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
470{ 393{
471 struct twl6030_usb *twl = platform_get_drvdata(pdev); 394 struct twl6030_usb *twl = platform_get_drvdata(pdev);
472 395
473 struct twl4030_usb_data *pdata;
474 struct device *dev = &pdev->dev;
475 pdata = dev->platform_data;
476
477 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 396 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
478 REG_INT_MSK_LINE_C); 397 REG_INT_MSK_LINE_C);
479 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 398 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
@@ -481,7 +400,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
481 free_irq(twl->irq1, twl); 400 free_irq(twl->irq1, twl);
482 free_irq(twl->irq2, twl); 401 free_irq(twl->irq2, twl);
483 regulator_put(twl->usb3v3); 402 regulator_put(twl->usb3v3);
484 pdata->phy_exit(twl->dev);
485 device_remove_file(twl->dev, &dev_attr_vbus); 403 device_remove_file(twl->dev, &dev_attr_vbus);
486 cancel_work_sync(&twl->set_vbus_work); 404 cancel_work_sync(&twl->set_vbus_work);
487 405