0009-phy-sun4i-usb-Control-USB-supplies-via-regulator-ucl.patch 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. From e8fb34342dfb79cd2059431dd1a0f03202a244ca Mon Sep 17 00:00:00 2001
  2. From: Samuel Holland <[email protected]>
  3. Date: Thu, 26 Aug 2021 22:11:37 -0500
  4. Subject: [PATCH 09/90] phy: sun4i-usb: Control USB supplies via regulator
  5. uclass
  6. The device tree binding for the PHY provides VBUS supplies as regulator
  7. references. Now that all boards have the appropriate regulator uclass
  8. drivers enabled, the PHY driver can switch to using them. This replaces
  9. direct GPIO usage, which in some cases needed a special DM-incompatible
  10. "virtual" GPIO from the PMIC.
  11. The following boards provided a value for CONFIG_USB0_VBUS_PIN, but are
  12. missing the "usb0_vbus-supply" property in their device tree. None of
  13. them have the MUSB controller enabled in host or OTG mode, so they
  14. should see no impact:
  15. - Ainol_AW1_defconfig / sun7i-a20-ainol-aw1
  16. - Ampe_A76_defconfig / sun5i-a13-ampe-a76
  17. - CHIP_pro_defconfig / sun5i-gr8-chip-pro
  18. - Cubieboard4_defconfig / sun9i-a80-cubieboard4
  19. - Merrii_A80_Optimus_defconfig / sun9i-a80-optimus
  20. - Sunchip_CX-A99_defconfig / sun9i-a80-cx-a99
  21. - Yones_Toptech_BD1078_defconfig / sun7i-a20-yones-toptech-bd1078
  22. - Yones_Toptech_BS1078_V2_defconfig /
  23. sun6i-a31s-yones-toptech-bs1078-v2
  24. - iNet_3F_defconfig / sun4i-a10-inet-3f
  25. - iNet_3W_defconfig / sun4i-a10-inet-3w
  26. - iNet_86VS_defconfig / sun5i-a13-inet-86vs
  27. - iNet_D978_rev2_defconfig / sun8i-a33-inet-d978-rev2
  28. - icnova-a20-swac_defconfig / sun7i-a20-icnova-swac
  29. - sun8i_a23_evb_defconfig / sun8i-a23-evb
  30. Similarly, the following boards set CONFIG_USB1_VBUS_PIN, but do not
  31. have "usb1_vbus-supply" in their device tree. Neither of them have USB
  32. enabled at all, so again there should be no impact:
  33. - Cubieboard4_defconfig / sun9i-a80-cubieboard4 (also for USB3)
  34. - sun8i_a23_evb_defconfig / sun8i-a23-evb
  35. The following boards use a different pin for USB1 VBUS between their
  36. defconfig and their device tree. Depending on which is correct, they
  37. may be broken:
  38. - Linksprite_pcDuino3_Nano_defconfig (PH11) /
  39. sun7i-a20-pcduino3-nano (PD2)
  40. - icnova-a20-swac_defconfig (PG10) / sun7i-a20-icnova-swac (PH6)
  41. Finally, this board has conflicting pins given for its USB2 VBUS:
  42. - Lamobo_R1_defconfig (PH3) / sun7i-a20-lamobo-r1 (PH12)
  43. Signed-off-by: Samuel Holland <[email protected]>
  44. ---
  45. drivers/phy/allwinner/phy-sun4i-usb.c | 41 +++++++++++++--------------
  46. 1 file changed, 19 insertions(+), 22 deletions(-)
  47. --- a/drivers/phy/allwinner/phy-sun4i-usb.c
  48. +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
  49. @@ -97,27 +97,22 @@ struct sun4i_usb_phy_cfg {
  50. };
  51. struct sun4i_usb_phy_info {
  52. - const char *gpio_vbus;
  53. const char *gpio_vbus_det;
  54. const char *gpio_id_det;
  55. } phy_info[] = {
  56. {
  57. - .gpio_vbus = CONFIG_USB0_VBUS_PIN,
  58. .gpio_vbus_det = CONFIG_USB0_VBUS_DET,
  59. .gpio_id_det = CONFIG_USB0_ID_DET,
  60. },
  61. {
  62. - .gpio_vbus = CONFIG_USB1_VBUS_PIN,
  63. .gpio_vbus_det = NULL,
  64. .gpio_id_det = NULL,
  65. },
  66. {
  67. - .gpio_vbus = CONFIG_USB2_VBUS_PIN,
  68. .gpio_vbus_det = NULL,
  69. .gpio_id_det = NULL,
  70. },
  71. {
  72. - .gpio_vbus = CONFIG_USB3_VBUS_PIN,
  73. .gpio_vbus_det = NULL,
  74. .gpio_id_det = NULL,
  75. },
  76. @@ -125,11 +120,11 @@ struct sun4i_usb_phy_info {
  77. struct sun4i_usb_phy_plat {
  78. void __iomem *pmu;
  79. - struct gpio_desc gpio_vbus;
  80. struct gpio_desc gpio_vbus_det;
  81. struct gpio_desc gpio_id_det;
  82. struct clk clocks;
  83. struct reset_ctl resets;
  84. + struct udevice *vbus;
  85. int id;
  86. };
  87. @@ -218,14 +213,18 @@ static int sun4i_usb_phy_power_on(struct
  88. {
  89. struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
  90. struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
  91. + int ret;
  92. if (initial_usb_scan_delay) {
  93. mdelay(initial_usb_scan_delay);
  94. initial_usb_scan_delay = 0;
  95. }
  96. - if (dm_gpio_is_valid(&usb_phy->gpio_vbus))
  97. - dm_gpio_set_value(&usb_phy->gpio_vbus, 1);
  98. + if (usb_phy->vbus) {
  99. + ret = regulator_set_enable(usb_phy->vbus, true);
  100. + if (ret && ret != -ENOSYS)
  101. + return ret;
  102. + }
  103. return 0;
  104. }
  105. @@ -234,9 +233,13 @@ static int sun4i_usb_phy_power_off(struc
  106. {
  107. struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
  108. struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
  109. + int ret;
  110. - if (dm_gpio_is_valid(&usb_phy->gpio_vbus))
  111. - dm_gpio_set_value(&usb_phy->gpio_vbus, 0);
  112. + if (usb_phy->vbus) {
  113. + ret = regulator_set_enable(usb_phy->vbus, false);
  114. + if (ret && ret != -ENOSYS)
  115. + return ret;
  116. + }
  117. return 0;
  118. }
  119. @@ -450,22 +453,16 @@ static int sun4i_usb_phy_probe(struct ud
  120. for (i = 0; i < data->cfg->num_phys; i++) {
  121. struct sun4i_usb_phy_plat *phy = &plat[i];
  122. struct sun4i_usb_phy_info *info = &phy_info[i];
  123. - char name[16];
  124. + char name[20];
  125. if (data->cfg->missing_phys & BIT(i))
  126. continue;
  127. - ret = dm_gpio_lookup_name(info->gpio_vbus, &phy->gpio_vbus);
  128. - if (ret == 0) {
  129. - ret = dm_gpio_request(&phy->gpio_vbus, "usb_vbus");
  130. - if (ret)
  131. - return ret;
  132. - ret = dm_gpio_set_dir_flags(&phy->gpio_vbus,
  133. - GPIOD_IS_OUT);
  134. - if (ret)
  135. - return ret;
  136. - ret = dm_gpio_set_value(&phy->gpio_vbus, 0);
  137. - if (ret)
  138. + snprintf(name, sizeof(name), "usb%d_vbus-supply", i);
  139. + ret = device_get_supply_regulator(dev, name, &phy->vbus);
  140. + if (phy->vbus) {
  141. + ret = regulator_set_enable(phy->vbus, false);
  142. + if (ret && ret != -ENOSYS)
  143. return ret;
  144. }