hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/usb/phy/phy-ab8500-usb.c
....@@ -108,7 +108,8 @@
108108 USB_IDLE = 0,
109109 USB_PERIPHERAL,
110110 USB_HOST,
111
- USB_DEDICATED_CHG
111
+ USB_DEDICATED_CHG,
112
+ USB_UART
112113 };
113114
114115 /* Register USB_LINK_STATUS interrupt */
....@@ -330,6 +331,7 @@
330331 switch (lsts) {
331332 case USB_LINK_ACA_RID_B_8505:
332333 event = UX500_MUSB_RIDB;
334
+ fallthrough;
333335 case USB_LINK_NOT_CONFIGURED_8505:
334336 case USB_LINK_RESERVED0_8505:
335337 case USB_LINK_RESERVED1_8505:
....@@ -350,6 +352,7 @@
350352
351353 case USB_LINK_ACA_RID_C_NM_8505:
352354 event = UX500_MUSB_RIDC;
355
+ fallthrough;
353356 case USB_LINK_STD_HOST_NC_8505:
354357 case USB_LINK_STD_HOST_C_NS_8505:
355358 case USB_LINK_STD_HOST_C_S_8505:
....@@ -368,6 +371,7 @@
368371 case USB_LINK_ACA_RID_A_8505:
369372 case USB_LINK_ACA_DOCK_CHGR_8505:
370373 event = UX500_MUSB_RIDA;
374
+ fallthrough;
371375 case USB_LINK_HM_IDGND_8505:
372376 if (ab->mode == USB_IDLE) {
373377 ab->mode = USB_HOST;
....@@ -388,6 +392,24 @@
388392 atomic_notifier_call_chain(&ab->phy.notifier,
389393 event, &ab->vbus_draw);
390394 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
+
391413 break;
392414
393415 default:
....@@ -422,6 +444,7 @@
422444 switch (lsts) {
423445 case USB_LINK_ACA_RID_B_8500:
424446 event = UX500_MUSB_RIDB;
447
+ fallthrough;
425448 case USB_LINK_NOT_CONFIGURED_8500:
426449 case USB_LINK_NOT_VALID_LINK_8500:
427450 ab->mode = USB_IDLE;
....@@ -438,6 +461,7 @@
438461 case USB_LINK_ACA_RID_C_HS_8500:
439462 case USB_LINK_ACA_RID_C_HS_CHIRP_8500:
440463 event = UX500_MUSB_RIDC;
464
+ fallthrough;
441465 case USB_LINK_STD_HOST_NC_8500:
442466 case USB_LINK_STD_HOST_C_NS_8500:
443467 case USB_LINK_STD_HOST_C_S_8500:
....@@ -457,6 +481,7 @@
457481
458482 case USB_LINK_ACA_RID_A_8500:
459483 event = UX500_MUSB_RIDA;
484
+ fallthrough;
460485 case USB_LINK_HM_IDGND_8500:
461486 if (ab->mode == USB_IDLE) {
462487 ab->mode = USB_HOST;
....@@ -493,7 +518,7 @@
493518 * 3. Enable AB regulators
494519 * 4. Enable USB phy
495520 * 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
497522 * 7. Enable the musb Peripheral5 clock
498523 * 8. Restore MUSB context
499524 */
....@@ -505,15 +530,19 @@
505530 if (is_ab8500(ab->ab8500)) {
506531 enum ab8500_usb_link_status lsts;
507532
508
- abx500_get_register_interruptible(ab->dev,
533
+ ret = abx500_get_register_interruptible(ab->dev,
509534 AB8500_USB, AB8500_USB_LINE_STAT_REG, &reg);
535
+ if (ret < 0)
536
+ return ret;
510537 lsts = (reg >> 3) & 0x0F;
511538 ret = ab8500_usb_link_status_update(ab, lsts);
512539 } else if (is_ab8505(ab->ab8500)) {
513540 enum ab8505_usb_link_status lsts;
514541
515
- abx500_get_register_interruptible(ab->dev,
542
+ ret = abx500_get_register_interruptible(ab->dev,
516543 AB8500_USB, AB8505_USB_LINE_STAT_REG, &reg);
544
+ if (ret < 0)
545
+ return ret;
517546 lsts = (reg >> 3) & 0x1F;
518547 ret = ab8505_usb_link_status_update(ab, lsts);
519548 }
....@@ -554,6 +583,11 @@
554583 ab->mode = USB_IDLE;
555584 ab->phy.otg->default_a = false;
556585 ab->vbus_draw = 0;
586
+ }
587
+
588
+ if (ab->mode == USB_UART) {
589
+ ab8500_usb_peri_phy_dis(ab);
590
+ ab->mode = USB_IDLE;
557591 }
558592
559593 if (is_ab8500_2p0(ab->ab8500)) {
....@@ -708,10 +742,8 @@
708742
709743 if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) {
710744 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)
713746 return irq;
714
- }
715747 err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
716748 ab8500_usb_link_status_irq,
717749 IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
....@@ -724,10 +756,8 @@
724756
725757 if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) {
726758 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)
729760 return irq;
730
- }
731761 err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
732762 ab8500_usb_disconnect_irq,
733763 IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
....@@ -740,10 +770,8 @@
740770
741771 if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) {
742772 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)
745774 return irq;
746
- }
747775 err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
748776 ab8500_usb_disconnect_irq,
749777 IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,