pmic-uclass.c 3.5 KB

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