pmic-uclass.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2014-2015 Samsung Electronics
  4. * Przemyslaw Marczak <p.marczak@samsung.com>
  5. */
  6. #include <common.h>
  7. #include <fdtdec.h>
  8. #include <errno.h>
  9. #include <dm.h>
  10. #include <vsprintf.h>
  11. #include <dm/lists.h>
  12. #include <dm/device-internal.h>
  13. #include <dm/uclass-internal.h>
  14. #include <power/pmic.h>
  15. #include <linux/ctype.h>
  16. #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
  17. int pmic_bind_children(struct udevice *pmic, ofnode parent,
  18. const struct pmic_child_info *child_info)
  19. {
  20. const struct pmic_child_info *info;
  21. struct driver *drv;
  22. struct udevice *child;
  23. const char *node_name;
  24. const char *reg_name;
  25. int bind_count = 0;
  26. ofnode node;
  27. int prefix_len;
  28. int ret;
  29. debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
  30. dev_of_offset(pmic));
  31. ofnode_for_each_subnode(node, parent) {
  32. node_name = ofnode_get_name(node);
  33. debug("* Found child node: '%s'\n", node_name);
  34. child = NULL;
  35. for (info = child_info; info->prefix && info->driver; info++) {
  36. debug(" - compatible prefix: '%s'\n", info->prefix);
  37. prefix_len = strlen(info->prefix);
  38. if (strncmp(info->prefix, node_name, prefix_len)) {
  39. reg_name = ofnode_read_string(node,
  40. "regulator-name");
  41. if (!reg_name)
  42. continue;
  43. if (strncmp(info->prefix, reg_name, prefix_len))
  44. continue;
  45. }
  46. drv = lists_driver_lookup_name(info->driver);
  47. if (!drv) {
  48. debug(" - driver: '%s' not found!\n",
  49. info->driver);
  50. continue;
  51. }
  52. debug(" - found child driver: '%s'\n", drv->name);
  53. ret = device_bind_with_driver_data(pmic, drv, node_name,
  54. 0, node, &child);
  55. if (ret) {
  56. debug(" - child binding error: %d\n", ret);
  57. continue;
  58. }
  59. debug(" - bound child device: '%s'\n", child->name);
  60. child->driver_data = trailing_strtol(node_name);
  61. debug(" - set 'child->driver_data': %lu\n",
  62. child->driver_data);
  63. break;
  64. }
  65. if (child)
  66. bind_count++;
  67. else
  68. debug(" - compatible prefix not found\n");
  69. }
  70. debug("Bound: %d children for PMIC: '%s'\n", bind_count, pmic->name);
  71. return bind_count;
  72. }
  73. #endif
  74. int pmic_get(const char *name, struct udevice **devp)
  75. {
  76. return uclass_get_device_by_name(UCLASS_PMIC, name, devp);
  77. }
  78. int pmic_reg_count(struct udevice *dev)
  79. {
  80. const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
  81. if (!ops || !ops->reg_count)
  82. return -ENOSYS;
  83. return ops->reg_count(dev);
  84. }
  85. int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len)
  86. {
  87. const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
  88. if (!buffer)
  89. return -EFAULT;
  90. if (!ops || !ops->read)
  91. return -ENOSYS;
  92. return ops->read(dev, reg, buffer, len);
  93. }
  94. int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len)
  95. {
  96. const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
  97. if (!buffer)
  98. return -EFAULT;
  99. if (!ops || !ops->write)
  100. return -ENOSYS;
  101. return ops->write(dev, reg, buffer, len);
  102. }
  103. int pmic_reg_read(struct udevice *dev, uint reg)
  104. {
  105. struct uc_pmic_priv *priv = dev_get_uclass_priv(dev);
  106. u32 val = 0;
  107. int ret;
  108. if (priv->trans_len < 1 || priv->trans_len > sizeof(val)) {
  109. debug("Wrong transmission size [%d]\n", priv->trans_len);
  110. return -EINVAL;
  111. }
  112. debug("%s: reg=%x priv->trans_len:%d", __func__, reg, priv->trans_len);
  113. ret = pmic_read(dev, reg, (uint8_t *)&val, priv->trans_len);
  114. debug(", value=%x, ret=%d\n", val, ret);
  115. return ret ? ret : val;
  116. }
  117. int pmic_reg_write(struct udevice *dev, uint reg, uint value)
  118. {
  119. struct uc_pmic_priv *priv = dev_get_uclass_priv(dev);
  120. int ret;
  121. if (priv->trans_len < 1 || priv->trans_len > sizeof(value)) {
  122. debug("Wrong transmission size [%d]\n", priv->trans_len);
  123. return -EINVAL;
  124. }
  125. debug("%s: reg=%x, value=%x priv->trans_len:%d", __func__, reg, value,
  126. priv->trans_len);
  127. ret = pmic_write(dev, reg, (uint8_t *)&value, priv->trans_len);
  128. debug(", ret=%d\n", ret);
  129. return ret;
  130. }
  131. int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
  132. {
  133. struct uc_pmic_priv *priv = dev_get_uclass_priv(dev);
  134. u32 val = 0;
  135. int ret;
  136. if (priv->trans_len < 1 || priv->trans_len > sizeof(val)) {
  137. debug("Wrong transmission size [%d]\n", priv->trans_len);
  138. return -EINVAL;
  139. }
  140. ret = pmic_read(dev, reg, (uint8_t *)&val, priv->trans_len);
  141. if (ret < 0)
  142. return ret;
  143. val = (val & ~clr) | set;
  144. return pmic_write(dev, reg, (uint8_t *)&val, priv->trans_len);
  145. }
  146. static int pmic_pre_probe(struct udevice *dev)
  147. {
  148. struct uc_pmic_priv *pmic_priv = dev_get_uclass_priv(dev);
  149. pmic_priv->trans_len = 1;
  150. return 0;
  151. }
  152. UCLASS_DRIVER(pmic) = {
  153. .id = UCLASS_PMIC,
  154. .name = "pmic",
  155. .pre_probe = pmic_pre_probe,
  156. .per_device_auto_alloc_size = sizeof(struct uc_pmic_priv),
  157. };