0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/irq.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/pm_runtime.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/ioport.h>
0020 #include <linux/io.h>
0021 #include <linux/of.h>
0022 #include <linux/of_platform.h>
0023 #include <linux/extcon.h>
0024 #include <linux/regulator/consumer.h>
0025
0026 #include <linux/usb/otg.h>
0027
0028
0029
0030
0031
0032
0033 #define USBOTGSS_REVISION 0x0000
0034 #define USBOTGSS_SYSCONFIG 0x0010
0035 #define USBOTGSS_IRQ_EOI 0x0020
0036 #define USBOTGSS_EOI_OFFSET 0x0008
0037 #define USBOTGSS_IRQSTATUS_RAW_0 0x0024
0038 #define USBOTGSS_IRQSTATUS_0 0x0028
0039 #define USBOTGSS_IRQENABLE_SET_0 0x002c
0040 #define USBOTGSS_IRQENABLE_CLR_0 0x0030
0041 #define USBOTGSS_IRQ0_OFFSET 0x0004
0042 #define USBOTGSS_IRQSTATUS_RAW_1 0x0030
0043 #define USBOTGSS_IRQSTATUS_1 0x0034
0044 #define USBOTGSS_IRQENABLE_SET_1 0x0038
0045 #define USBOTGSS_IRQENABLE_CLR_1 0x003c
0046 #define USBOTGSS_IRQSTATUS_RAW_2 0x0040
0047 #define USBOTGSS_IRQSTATUS_2 0x0044
0048 #define USBOTGSS_IRQENABLE_SET_2 0x0048
0049 #define USBOTGSS_IRQENABLE_CLR_2 0x004c
0050 #define USBOTGSS_IRQSTATUS_RAW_3 0x0050
0051 #define USBOTGSS_IRQSTATUS_3 0x0054
0052 #define USBOTGSS_IRQENABLE_SET_3 0x0058
0053 #define USBOTGSS_IRQENABLE_CLR_3 0x005c
0054 #define USBOTGSS_IRQSTATUS_EOI_MISC 0x0030
0055 #define USBOTGSS_IRQSTATUS_RAW_MISC 0x0034
0056 #define USBOTGSS_IRQSTATUS_MISC 0x0038
0057 #define USBOTGSS_IRQENABLE_SET_MISC 0x003c
0058 #define USBOTGSS_IRQENABLE_CLR_MISC 0x0040
0059 #define USBOTGSS_IRQMISC_OFFSET 0x03fc
0060 #define USBOTGSS_UTMI_OTG_STATUS 0x0080
0061 #define USBOTGSS_UTMI_OTG_CTRL 0x0084
0062 #define USBOTGSS_UTMI_OTG_OFFSET 0x0480
0063 #define USBOTGSS_TXFIFO_DEPTH 0x0508
0064 #define USBOTGSS_RXFIFO_DEPTH 0x050c
0065 #define USBOTGSS_MMRAM_OFFSET 0x0100
0066 #define USBOTGSS_FLADJ 0x0104
0067 #define USBOTGSS_DEBUG_CFG 0x0108
0068 #define USBOTGSS_DEBUG_DATA 0x010c
0069 #define USBOTGSS_DEV_EBC_EN 0x0110
0070 #define USBOTGSS_DEBUG_OFFSET 0x0600
0071
0072
0073 #define USBOTGSS_SYSCONFIG_DMADISABLE BIT(16)
0074
0075
0076 #define USBOTGSS_IRQ_EOI_LINE_NUMBER BIT(0)
0077
0078
0079 #define USBOTGSS_IRQO_COREIRQ_ST BIT(0)
0080
0081
0082 #define USBOTGSS_IRQMISC_DMADISABLECLR BIT(17)
0083 #define USBOTGSS_IRQMISC_OEVT BIT(16)
0084 #define USBOTGSS_IRQMISC_DRVVBUS_RISE BIT(13)
0085 #define USBOTGSS_IRQMISC_CHRGVBUS_RISE BIT(12)
0086 #define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE BIT(11)
0087 #define USBOTGSS_IRQMISC_IDPULLUP_RISE BIT(8)
0088 #define USBOTGSS_IRQMISC_DRVVBUS_FALL BIT(5)
0089 #define USBOTGSS_IRQMISC_CHRGVBUS_FALL BIT(4)
0090 #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL BIT(3)
0091 #define USBOTGSS_IRQMISC_IDPULLUP_FALL BIT(0)
0092
0093
0094 #define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS BIT(5)
0095 #define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS BIT(4)
0096 #define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS BIT(3)
0097 #define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP BIT(0)
0098
0099
0100 #define USBOTGSS_UTMI_OTG_CTRL_SW_MODE BIT(31)
0101 #define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT BIT(9)
0102 #define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE BIT(8)
0103 #define USBOTGSS_UTMI_OTG_CTRL_IDDIG BIT(4)
0104 #define USBOTGSS_UTMI_OTG_CTRL_SESSEND BIT(3)
0105 #define USBOTGSS_UTMI_OTG_CTRL_SESSVALID BIT(2)
0106 #define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID BIT(1)
0107
0108 enum dwc3_omap_utmi_mode {
0109 DWC3_OMAP_UTMI_MODE_UNKNOWN = 0,
0110 DWC3_OMAP_UTMI_MODE_HW,
0111 DWC3_OMAP_UTMI_MODE_SW,
0112 };
0113
0114 struct dwc3_omap {
0115 struct device *dev;
0116
0117 int irq;
0118 void __iomem *base;
0119
0120 u32 utmi_otg_ctrl;
0121 u32 utmi_otg_offset;
0122 u32 irqmisc_offset;
0123 u32 irq_eoi_offset;
0124 u32 debug_offset;
0125 u32 irq0_offset;
0126
0127 struct extcon_dev *edev;
0128 struct notifier_block vbus_nb;
0129 struct notifier_block id_nb;
0130
0131 struct regulator *vbus_reg;
0132 };
0133
0134 enum omap_dwc3_vbus_id_status {
0135 OMAP_DWC3_ID_FLOAT,
0136 OMAP_DWC3_ID_GROUND,
0137 OMAP_DWC3_VBUS_OFF,
0138 OMAP_DWC3_VBUS_VALID,
0139 };
0140
0141 static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
0142 {
0143 return readl(base + offset);
0144 }
0145
0146 static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
0147 {
0148 writel(value, base + offset);
0149 }
0150
0151 static u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap)
0152 {
0153 return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL +
0154 omap->utmi_otg_offset);
0155 }
0156
0157 static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
0158 {
0159 dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL +
0160 omap->utmi_otg_offset, value);
0161
0162 }
0163
0164 static u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap)
0165 {
0166 return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_0 -
0167 omap->irq0_offset);
0168 }
0169
0170 static void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value)
0171 {
0172 dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0 -
0173 omap->irq0_offset, value);
0174
0175 }
0176
0177 static u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap)
0178 {
0179 return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_MISC +
0180 omap->irqmisc_offset);
0181 }
0182
0183 static void dwc3_omap_write_irqmisc_status(struct dwc3_omap *omap, u32 value)
0184 {
0185 dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_MISC +
0186 omap->irqmisc_offset, value);
0187
0188 }
0189
0190 static void dwc3_omap_write_irqmisc_set(struct dwc3_omap *omap, u32 value)
0191 {
0192 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_MISC +
0193 omap->irqmisc_offset, value);
0194
0195 }
0196
0197 static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
0198 {
0199 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0 -
0200 omap->irq0_offset, value);
0201 }
0202
0203 static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
0204 {
0205 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
0206 omap->irqmisc_offset, value);
0207 }
0208
0209 static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
0210 {
0211 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
0212 omap->irq0_offset, value);
0213 }
0214
0215 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
0216 enum omap_dwc3_vbus_id_status status)
0217 {
0218 int ret;
0219 u32 val;
0220
0221 switch (status) {
0222 case OMAP_DWC3_ID_GROUND:
0223 if (omap->vbus_reg) {
0224 ret = regulator_enable(omap->vbus_reg);
0225 if (ret) {
0226 dev_err(omap->dev, "regulator enable failed\n");
0227 return;
0228 }
0229 }
0230
0231 val = dwc3_omap_read_utmi_ctrl(omap);
0232 val &= ~USBOTGSS_UTMI_OTG_CTRL_IDDIG;
0233 dwc3_omap_write_utmi_ctrl(omap, val);
0234 break;
0235
0236 case OMAP_DWC3_VBUS_VALID:
0237 val = dwc3_omap_read_utmi_ctrl(omap);
0238 val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND;
0239 val |= USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
0240 | USBOTGSS_UTMI_OTG_CTRL_SESSVALID;
0241 dwc3_omap_write_utmi_ctrl(omap, val);
0242 break;
0243
0244 case OMAP_DWC3_ID_FLOAT:
0245 if (omap->vbus_reg && regulator_is_enabled(omap->vbus_reg))
0246 regulator_disable(omap->vbus_reg);
0247 val = dwc3_omap_read_utmi_ctrl(omap);
0248 val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
0249 dwc3_omap_write_utmi_ctrl(omap, val);
0250 break;
0251
0252 case OMAP_DWC3_VBUS_OFF:
0253 val = dwc3_omap_read_utmi_ctrl(omap);
0254 val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID
0255 | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID);
0256 val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND;
0257 dwc3_omap_write_utmi_ctrl(omap, val);
0258 break;
0259
0260 default:
0261 dev_WARN(omap->dev, "invalid state\n");
0262 }
0263 }
0264
0265 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap);
0266 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap);
0267
0268 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
0269 {
0270 struct dwc3_omap *omap = _omap;
0271
0272 if (dwc3_omap_read_irqmisc_status(omap) ||
0273 dwc3_omap_read_irq0_status(omap)) {
0274
0275 dwc3_omap_disable_irqs(omap);
0276 return IRQ_WAKE_THREAD;
0277 }
0278
0279 return IRQ_NONE;
0280 }
0281
0282 static irqreturn_t dwc3_omap_interrupt_thread(int irq, void *_omap)
0283 {
0284 struct dwc3_omap *omap = _omap;
0285 u32 reg;
0286
0287
0288 reg = dwc3_omap_read_irqmisc_status(omap);
0289 dwc3_omap_write_irqmisc_status(omap, reg);
0290
0291 reg = dwc3_omap_read_irq0_status(omap);
0292 dwc3_omap_write_irq0_status(omap, reg);
0293
0294
0295 dwc3_omap_enable_irqs(omap);
0296
0297 return IRQ_HANDLED;
0298 }
0299
0300 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
0301 {
0302 u32 reg;
0303
0304
0305 reg = USBOTGSS_IRQO_COREIRQ_ST;
0306 dwc3_omap_write_irq0_set(omap, reg);
0307
0308 reg = (USBOTGSS_IRQMISC_OEVT |
0309 USBOTGSS_IRQMISC_DRVVBUS_RISE |
0310 USBOTGSS_IRQMISC_CHRGVBUS_RISE |
0311 USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
0312 USBOTGSS_IRQMISC_IDPULLUP_RISE |
0313 USBOTGSS_IRQMISC_DRVVBUS_FALL |
0314 USBOTGSS_IRQMISC_CHRGVBUS_FALL |
0315 USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
0316 USBOTGSS_IRQMISC_IDPULLUP_FALL);
0317
0318 dwc3_omap_write_irqmisc_set(omap, reg);
0319 }
0320
0321 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
0322 {
0323 u32 reg;
0324
0325
0326 reg = USBOTGSS_IRQO_COREIRQ_ST;
0327 dwc3_omap_write_irq0_clr(omap, reg);
0328
0329 reg = (USBOTGSS_IRQMISC_OEVT |
0330 USBOTGSS_IRQMISC_DRVVBUS_RISE |
0331 USBOTGSS_IRQMISC_CHRGVBUS_RISE |
0332 USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
0333 USBOTGSS_IRQMISC_IDPULLUP_RISE |
0334 USBOTGSS_IRQMISC_DRVVBUS_FALL |
0335 USBOTGSS_IRQMISC_CHRGVBUS_FALL |
0336 USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
0337 USBOTGSS_IRQMISC_IDPULLUP_FALL);
0338
0339 dwc3_omap_write_irqmisc_clr(omap, reg);
0340 }
0341
0342 static int dwc3_omap_id_notifier(struct notifier_block *nb,
0343 unsigned long event, void *ptr)
0344 {
0345 struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, id_nb);
0346
0347 if (event)
0348 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0349 else
0350 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0351
0352 return NOTIFY_DONE;
0353 }
0354
0355 static int dwc3_omap_vbus_notifier(struct notifier_block *nb,
0356 unsigned long event, void *ptr)
0357 {
0358 struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, vbus_nb);
0359
0360 if (event)
0361 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0362 else
0363 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0364
0365 return NOTIFY_DONE;
0366 }
0367
0368 static void dwc3_omap_map_offset(struct dwc3_omap *omap)
0369 {
0370 struct device_node *node = omap->dev->of_node;
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 if (of_device_is_compatible(node, "ti,am437x-dwc3")) {
0381 omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET;
0382 omap->irq0_offset = USBOTGSS_IRQ0_OFFSET;
0383 omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
0384 omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
0385 omap->debug_offset = USBOTGSS_DEBUG_OFFSET;
0386 }
0387 }
0388
0389 static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
0390 {
0391 u32 reg;
0392 struct device_node *node = omap->dev->of_node;
0393 u32 utmi_mode = 0;
0394
0395 reg = dwc3_omap_read_utmi_ctrl(omap);
0396
0397 of_property_read_u32(node, "utmi-mode", &utmi_mode);
0398
0399 switch (utmi_mode) {
0400 case DWC3_OMAP_UTMI_MODE_SW:
0401 reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
0402 break;
0403 case DWC3_OMAP_UTMI_MODE_HW:
0404 reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
0405 break;
0406 default:
0407 dev_WARN(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode);
0408 }
0409
0410 dwc3_omap_write_utmi_ctrl(omap, reg);
0411 }
0412
0413 static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
0414 {
0415 int ret;
0416 struct device_node *node = omap->dev->of_node;
0417 struct extcon_dev *edev;
0418
0419 if (of_property_read_bool(node, "extcon")) {
0420 edev = extcon_get_edev_by_phandle(omap->dev, 0);
0421 if (IS_ERR(edev)) {
0422 dev_vdbg(omap->dev, "couldn't get extcon device\n");
0423 return -EPROBE_DEFER;
0424 }
0425
0426 omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
0427 ret = devm_extcon_register_notifier(omap->dev, edev,
0428 EXTCON_USB, &omap->vbus_nb);
0429 if (ret < 0)
0430 dev_vdbg(omap->dev, "failed to register notifier for USB\n");
0431
0432 omap->id_nb.notifier_call = dwc3_omap_id_notifier;
0433 ret = devm_extcon_register_notifier(omap->dev, edev,
0434 EXTCON_USB_HOST, &omap->id_nb);
0435 if (ret < 0)
0436 dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n");
0437
0438 if (extcon_get_state(edev, EXTCON_USB) == true)
0439 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0440 else
0441 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0442
0443 if (extcon_get_state(edev, EXTCON_USB_HOST) == true)
0444 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0445 else
0446 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0447
0448 omap->edev = edev;
0449 }
0450
0451 return 0;
0452 }
0453
0454 static int dwc3_omap_probe(struct platform_device *pdev)
0455 {
0456 struct device_node *node = pdev->dev.of_node;
0457
0458 struct dwc3_omap *omap;
0459 struct device *dev = &pdev->dev;
0460 struct regulator *vbus_reg = NULL;
0461
0462 int ret;
0463 int irq;
0464
0465 void __iomem *base;
0466
0467 if (!node) {
0468 dev_err(dev, "device node not found\n");
0469 return -EINVAL;
0470 }
0471
0472 omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
0473 if (!omap)
0474 return -ENOMEM;
0475
0476 platform_set_drvdata(pdev, omap);
0477
0478 irq = platform_get_irq(pdev, 0);
0479 if (irq < 0)
0480 return irq;
0481
0482 base = devm_platform_ioremap_resource(pdev, 0);
0483 if (IS_ERR(base))
0484 return PTR_ERR(base);
0485
0486 if (of_property_read_bool(node, "vbus-supply")) {
0487 vbus_reg = devm_regulator_get(dev, "vbus");
0488 if (IS_ERR(vbus_reg)) {
0489 dev_err(dev, "vbus init failed\n");
0490 return PTR_ERR(vbus_reg);
0491 }
0492 }
0493
0494 omap->dev = dev;
0495 omap->irq = irq;
0496 omap->base = base;
0497 omap->vbus_reg = vbus_reg;
0498
0499 pm_runtime_enable(dev);
0500 ret = pm_runtime_get_sync(dev);
0501 if (ret < 0) {
0502 dev_err(dev, "get_sync failed with err %d\n", ret);
0503 goto err1;
0504 }
0505
0506 dwc3_omap_map_offset(omap);
0507 dwc3_omap_set_utmi_mode(omap);
0508
0509 ret = dwc3_omap_extcon_register(omap);
0510 if (ret < 0)
0511 goto err1;
0512
0513 ret = of_platform_populate(node, NULL, NULL, dev);
0514 if (ret) {
0515 dev_err(&pdev->dev, "failed to create dwc3 core\n");
0516 goto err1;
0517 }
0518
0519 ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
0520 dwc3_omap_interrupt_thread, IRQF_SHARED,
0521 "dwc3-omap", omap);
0522 if (ret) {
0523 dev_err(dev, "failed to request IRQ #%d --> %d\n",
0524 omap->irq, ret);
0525 goto err1;
0526 }
0527 dwc3_omap_enable_irqs(omap);
0528 return 0;
0529
0530 err1:
0531 pm_runtime_put_sync(dev);
0532 pm_runtime_disable(dev);
0533
0534 return ret;
0535 }
0536
0537 static int dwc3_omap_remove(struct platform_device *pdev)
0538 {
0539 struct dwc3_omap *omap = platform_get_drvdata(pdev);
0540
0541 dwc3_omap_disable_irqs(omap);
0542 disable_irq(omap->irq);
0543 of_platform_depopulate(omap->dev);
0544 pm_runtime_put_sync(&pdev->dev);
0545 pm_runtime_disable(&pdev->dev);
0546
0547 return 0;
0548 }
0549
0550 static const struct of_device_id of_dwc3_match[] = {
0551 {
0552 .compatible = "ti,dwc3"
0553 },
0554 {
0555 .compatible = "ti,am437x-dwc3"
0556 },
0557 { },
0558 };
0559 MODULE_DEVICE_TABLE(of, of_dwc3_match);
0560
0561 #ifdef CONFIG_PM_SLEEP
0562 static int dwc3_omap_suspend(struct device *dev)
0563 {
0564 struct dwc3_omap *omap = dev_get_drvdata(dev);
0565
0566 omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap);
0567 dwc3_omap_disable_irqs(omap);
0568
0569 return 0;
0570 }
0571
0572 static int dwc3_omap_resume(struct device *dev)
0573 {
0574 struct dwc3_omap *omap = dev_get_drvdata(dev);
0575
0576 dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl);
0577 dwc3_omap_enable_irqs(omap);
0578
0579 pm_runtime_disable(dev);
0580 pm_runtime_set_active(dev);
0581 pm_runtime_enable(dev);
0582
0583 return 0;
0584 }
0585
0586 static void dwc3_omap_complete(struct device *dev)
0587 {
0588 struct dwc3_omap *omap = dev_get_drvdata(dev);
0589
0590 if (extcon_get_state(omap->edev, EXTCON_USB))
0591 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0592 else
0593 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0594
0595 if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
0596 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0597 else
0598 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0599 }
0600
0601 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
0602
0603 SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
0604 .complete = dwc3_omap_complete,
0605 };
0606
0607 #define DEV_PM_OPS (&dwc3_omap_dev_pm_ops)
0608 #else
0609 #define DEV_PM_OPS NULL
0610 #endif
0611
0612 static struct platform_driver dwc3_omap_driver = {
0613 .probe = dwc3_omap_probe,
0614 .remove = dwc3_omap_remove,
0615 .driver = {
0616 .name = "omap-dwc3",
0617 .of_match_table = of_dwc3_match,
0618 .pm = DEV_PM_OPS,
0619 },
0620 };
0621
0622 module_platform_driver(dwc3_omap_driver);
0623
0624 MODULE_ALIAS("platform:omap-dwc3");
0625 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
0626 MODULE_LICENSE("GPL v2");
0627 MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");