rcar2.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // SPDX-License-Identifier: GPL-1.0+
  2. /*
  3. * Renesas USB driver R-Car Gen. 2 initialization and power control
  4. *
  5. * Copyright (C) 2014 Ulrich Hecht
  6. */
  7. #include <linux/gpio.h>
  8. #include <linux/of_gpio.h>
  9. #include <linux/phy/phy.h>
  10. #include <linux/usb/phy.h>
  11. #include "common.h"
  12. #include "rcar2.h"
  13. static int usbhs_rcar2_hardware_init(struct platform_device *pdev)
  14. {
  15. struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
  16. if (IS_ENABLED(CONFIG_GENERIC_PHY)) {
  17. struct phy *phy = phy_get(&pdev->dev, "usb");
  18. if (IS_ERR(phy))
  19. return PTR_ERR(phy);
  20. priv->phy = phy;
  21. return 0;
  22. }
  23. if (IS_ENABLED(CONFIG_USB_PHY)) {
  24. struct usb_phy *usb_phy = usb_get_phy_dev(&pdev->dev, 0);
  25. if (IS_ERR(usb_phy))
  26. return PTR_ERR(usb_phy);
  27. priv->usb_phy = usb_phy;
  28. return 0;
  29. }
  30. return -ENXIO;
  31. }
  32. static int usbhs_rcar2_hardware_exit(struct platform_device *pdev)
  33. {
  34. struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
  35. if (priv->phy) {
  36. phy_put(priv->phy);
  37. priv->phy = NULL;
  38. }
  39. if (priv->usb_phy) {
  40. usb_put_phy(priv->usb_phy);
  41. priv->usb_phy = NULL;
  42. }
  43. return 0;
  44. }
  45. static int usbhs_rcar2_power_ctrl(struct platform_device *pdev,
  46. void __iomem *base, int enable)
  47. {
  48. struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
  49. int retval = -ENODEV;
  50. if (priv->phy) {
  51. if (enable) {
  52. retval = phy_init(priv->phy);
  53. if (!retval)
  54. retval = phy_power_on(priv->phy);
  55. } else {
  56. phy_power_off(priv->phy);
  57. phy_exit(priv->phy);
  58. retval = 0;
  59. }
  60. }
  61. if (priv->usb_phy) {
  62. if (enable) {
  63. retval = usb_phy_init(priv->usb_phy);
  64. if (!retval)
  65. retval = usb_phy_set_suspend(priv->usb_phy, 0);
  66. } else {
  67. usb_phy_set_suspend(priv->usb_phy, 1);
  68. usb_phy_shutdown(priv->usb_phy);
  69. retval = 0;
  70. }
  71. }
  72. return retval;
  73. }
  74. static int usbhs_rcar2_get_id(struct platform_device *pdev)
  75. {
  76. return USBHS_GADGET;
  77. }
  78. const struct renesas_usbhs_platform_callback usbhs_rcar2_ops = {
  79. .hardware_init = usbhs_rcar2_hardware_init,
  80. .hardware_exit = usbhs_rcar2_hardware_exit,
  81. .power_ctrl = usbhs_rcar2_power_ctrl,
  82. .get_id = usbhs_rcar2_get_id,
  83. };