ulpi.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2016 Linaro Ltd.
  4. */
  5. #include <linux/device.h>
  6. #include <linux/usb/chipidea.h>
  7. #include <linux/ulpi/interface.h>
  8. #include "ci.h"
  9. #define ULPI_WAKEUP BIT(31)
  10. #define ULPI_RUN BIT(30)
  11. #define ULPI_WRITE BIT(29)
  12. #define ULPI_SYNC_STATE BIT(27)
  13. #define ULPI_ADDR(n) ((n) << 16)
  14. #define ULPI_DATA(n) (n)
  15. static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
  16. {
  17. unsigned long usec = 10000;
  18. while (usec--) {
  19. if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
  20. return 0;
  21. udelay(1);
  22. }
  23. return -ETIMEDOUT;
  24. }
  25. static int ci_ulpi_read(struct device *dev, u8 addr)
  26. {
  27. struct ci_hdrc *ci = dev_get_drvdata(dev);
  28. int ret;
  29. hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
  30. ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
  31. if (ret)
  32. return ret;
  33. hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
  34. ret = ci_ulpi_wait(ci, ULPI_RUN);
  35. if (ret)
  36. return ret;
  37. return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
  38. }
  39. static int ci_ulpi_write(struct device *dev, u8 addr, u8 val)
  40. {
  41. struct ci_hdrc *ci = dev_get_drvdata(dev);
  42. int ret;
  43. hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
  44. ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
  45. if (ret)
  46. return ret;
  47. hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
  48. ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
  49. return ci_ulpi_wait(ci, ULPI_RUN);
  50. }
  51. int ci_ulpi_init(struct ci_hdrc *ci)
  52. {
  53. if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
  54. return 0;
  55. /*
  56. * Set PORTSC correctly so we can read/write ULPI registers for
  57. * identification purposes
  58. */
  59. hw_phymode_configure(ci);
  60. ci->ulpi_ops.read = ci_ulpi_read;
  61. ci->ulpi_ops.write = ci_ulpi_write;
  62. ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
  63. if (IS_ERR(ci->ulpi))
  64. dev_err(ci->dev, "failed to register ULPI interface");
  65. return PTR_ERR_OR_ZERO(ci->ulpi);
  66. }
  67. void ci_ulpi_exit(struct ci_hdrc *ci)
  68. {
  69. if (ci->ulpi) {
  70. ulpi_unregister_interface(ci->ulpi);
  71. ci->ulpi = NULL;
  72. }
  73. }
  74. int ci_ulpi_resume(struct ci_hdrc *ci)
  75. {
  76. int cnt = 100000;
  77. if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
  78. return 0;
  79. while (cnt-- > 0) {
  80. if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
  81. return 0;
  82. udelay(1);
  83. }
  84. return -ETIMEDOUT;
  85. }