.. | .. |
---|
108 | 108 | USB_IDLE = 0, |
---|
109 | 109 | USB_PERIPHERAL, |
---|
110 | 110 | USB_HOST, |
---|
111 | | - USB_DEDICATED_CHG |
---|
| 111 | + USB_DEDICATED_CHG, |
---|
| 112 | + USB_UART |
---|
112 | 113 | }; |
---|
113 | 114 | |
---|
114 | 115 | /* Register USB_LINK_STATUS interrupt */ |
---|
.. | .. |
---|
330 | 331 | switch (lsts) { |
---|
331 | 332 | case USB_LINK_ACA_RID_B_8505: |
---|
332 | 333 | event = UX500_MUSB_RIDB; |
---|
| 334 | + fallthrough; |
---|
333 | 335 | case USB_LINK_NOT_CONFIGURED_8505: |
---|
334 | 336 | case USB_LINK_RESERVED0_8505: |
---|
335 | 337 | case USB_LINK_RESERVED1_8505: |
---|
.. | .. |
---|
350 | 352 | |
---|
351 | 353 | case USB_LINK_ACA_RID_C_NM_8505: |
---|
352 | 354 | event = UX500_MUSB_RIDC; |
---|
| 355 | + fallthrough; |
---|
353 | 356 | case USB_LINK_STD_HOST_NC_8505: |
---|
354 | 357 | case USB_LINK_STD_HOST_C_NS_8505: |
---|
355 | 358 | case USB_LINK_STD_HOST_C_S_8505: |
---|
.. | .. |
---|
368 | 371 | case USB_LINK_ACA_RID_A_8505: |
---|
369 | 372 | case USB_LINK_ACA_DOCK_CHGR_8505: |
---|
370 | 373 | event = UX500_MUSB_RIDA; |
---|
| 374 | + fallthrough; |
---|
371 | 375 | case USB_LINK_HM_IDGND_8505: |
---|
372 | 376 | if (ab->mode == USB_IDLE) { |
---|
373 | 377 | ab->mode = USB_HOST; |
---|
.. | .. |
---|
388 | 392 | atomic_notifier_call_chain(&ab->phy.notifier, |
---|
389 | 393 | event, &ab->vbus_draw); |
---|
390 | 394 | usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); |
---|
| 395 | + break; |
---|
| 396 | + |
---|
| 397 | + /* |
---|
| 398 | + * FIXME: For now we rely on the boot firmware to set up the necessary |
---|
| 399 | + * PHY/pin configuration for UART mode. |
---|
| 400 | + * |
---|
| 401 | + * AB8505 does not seem to report any status change for UART cables, |
---|
| 402 | + * possibly because it cannot detect them autonomously. |
---|
| 403 | + * We may need to measure the ID resistance manually to reliably |
---|
| 404 | + * detect UART cables after bootup. |
---|
| 405 | + */ |
---|
| 406 | + case USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505: |
---|
| 407 | + case USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505: |
---|
| 408 | + if (ab->mode == USB_IDLE) { |
---|
| 409 | + ab->mode = USB_UART; |
---|
| 410 | + ab8500_usb_peri_phy_en(ab); |
---|
| 411 | + } |
---|
| 412 | + |
---|
391 | 413 | break; |
---|
392 | 414 | |
---|
393 | 415 | default: |
---|
.. | .. |
---|
422 | 444 | switch (lsts) { |
---|
423 | 445 | case USB_LINK_ACA_RID_B_8500: |
---|
424 | 446 | event = UX500_MUSB_RIDB; |
---|
| 447 | + fallthrough; |
---|
425 | 448 | case USB_LINK_NOT_CONFIGURED_8500: |
---|
426 | 449 | case USB_LINK_NOT_VALID_LINK_8500: |
---|
427 | 450 | ab->mode = USB_IDLE; |
---|
.. | .. |
---|
438 | 461 | case USB_LINK_ACA_RID_C_HS_8500: |
---|
439 | 462 | case USB_LINK_ACA_RID_C_HS_CHIRP_8500: |
---|
440 | 463 | event = UX500_MUSB_RIDC; |
---|
| 464 | + fallthrough; |
---|
441 | 465 | case USB_LINK_STD_HOST_NC_8500: |
---|
442 | 466 | case USB_LINK_STD_HOST_C_NS_8500: |
---|
443 | 467 | case USB_LINK_STD_HOST_C_S_8500: |
---|
.. | .. |
---|
457 | 481 | |
---|
458 | 482 | case USB_LINK_ACA_RID_A_8500: |
---|
459 | 483 | event = UX500_MUSB_RIDA; |
---|
| 484 | + fallthrough; |
---|
460 | 485 | case USB_LINK_HM_IDGND_8500: |
---|
461 | 486 | if (ab->mode == USB_IDLE) { |
---|
462 | 487 | ab->mode = USB_HOST; |
---|
.. | .. |
---|
493 | 518 | * 3. Enable AB regulators |
---|
494 | 519 | * 4. Enable USB phy |
---|
495 | 520 | * 5. Reset the musb controller |
---|
496 | | - * 6. Switch the ULPI GPIO pins to fucntion mode |
---|
| 521 | + * 6. Switch the ULPI GPIO pins to function mode |
---|
497 | 522 | * 7. Enable the musb Peripheral5 clock |
---|
498 | 523 | * 8. Restore MUSB context |
---|
499 | 524 | */ |
---|
.. | .. |
---|
505 | 530 | if (is_ab8500(ab->ab8500)) { |
---|
506 | 531 | enum ab8500_usb_link_status lsts; |
---|
507 | 532 | |
---|
508 | | - abx500_get_register_interruptible(ab->dev, |
---|
| 533 | + ret = abx500_get_register_interruptible(ab->dev, |
---|
509 | 534 | AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); |
---|
| 535 | + if (ret < 0) |
---|
| 536 | + return ret; |
---|
510 | 537 | lsts = (reg >> 3) & 0x0F; |
---|
511 | 538 | ret = ab8500_usb_link_status_update(ab, lsts); |
---|
512 | 539 | } else if (is_ab8505(ab->ab8500)) { |
---|
513 | 540 | enum ab8505_usb_link_status lsts; |
---|
514 | 541 | |
---|
515 | | - abx500_get_register_interruptible(ab->dev, |
---|
| 542 | + ret = abx500_get_register_interruptible(ab->dev, |
---|
516 | 543 | AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); |
---|
| 544 | + if (ret < 0) |
---|
| 545 | + return ret; |
---|
517 | 546 | lsts = (reg >> 3) & 0x1F; |
---|
518 | 547 | ret = ab8505_usb_link_status_update(ab, lsts); |
---|
519 | 548 | } |
---|
.. | .. |
---|
554 | 583 | ab->mode = USB_IDLE; |
---|
555 | 584 | ab->phy.otg->default_a = false; |
---|
556 | 585 | ab->vbus_draw = 0; |
---|
| 586 | + } |
---|
| 587 | + |
---|
| 588 | + if (ab->mode == USB_UART) { |
---|
| 589 | + ab8500_usb_peri_phy_dis(ab); |
---|
| 590 | + ab->mode = USB_IDLE; |
---|
557 | 591 | } |
---|
558 | 592 | |
---|
559 | 593 | if (is_ab8500_2p0(ab->ab8500)) { |
---|
.. | .. |
---|
708 | 742 | |
---|
709 | 743 | if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) { |
---|
710 | 744 | irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); |
---|
711 | | - if (irq < 0) { |
---|
712 | | - dev_err(&pdev->dev, "Link status irq not found\n"); |
---|
| 745 | + if (irq < 0) |
---|
713 | 746 | return irq; |
---|
714 | | - } |
---|
715 | 747 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
---|
716 | 748 | ab8500_usb_link_status_irq, |
---|
717 | 749 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
---|
.. | .. |
---|
724 | 756 | |
---|
725 | 757 | if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) { |
---|
726 | 758 | irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); |
---|
727 | | - if (irq < 0) { |
---|
728 | | - dev_err(&pdev->dev, "ID fall irq not found\n"); |
---|
| 759 | + if (irq < 0) |
---|
729 | 760 | return irq; |
---|
730 | | - } |
---|
731 | 761 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
---|
732 | 762 | ab8500_usb_disconnect_irq, |
---|
733 | 763 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
---|
.. | .. |
---|
740 | 770 | |
---|
741 | 771 | if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) { |
---|
742 | 772 | irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); |
---|
743 | | - if (irq < 0) { |
---|
744 | | - dev_err(&pdev->dev, "VBUS fall irq not found\n"); |
---|
| 773 | + if (irq < 0) |
---|
745 | 774 | return irq; |
---|
746 | | - } |
---|
747 | 775 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
---|
748 | 776 | ab8500_usb_disconnect_irq, |
---|
749 | 777 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
---|