pinctrl-bcm6838.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <common.h>
  3. #include <dm.h>
  4. #include <regmap.h>
  5. #include <syscon.h>
  6. #include <dm/device_compat.h>
  7. #include <dm/pinctrl.h>
  8. #define BCM6838_CMD_LOAD_MUX 0x21
  9. #define BCM6838_FUNC_OFFS 12
  10. #define BCM6838_FUNC_MASK (0x37 << BCM6838_FUNC_OFFS)
  11. #define BCM6838_PIN_OFFS 0
  12. #define BCM6838_PIN_MASK (0xfff << BCM6838_PIN_OFFS)
  13. #define BCM6838_MAX_PIN_NAME_LEN 8
  14. static char bcm6838_pin_name[BCM6838_MAX_PIN_NAME_LEN];
  15. #define BCM6838_MAX_FUNC_NAME_LEN 8
  16. static char bcm6838_func_name[BCM6838_MAX_FUNC_NAME_LEN];
  17. struct bcm6838_test_port_hw {
  18. unsigned long port_blk_data1;
  19. unsigned long port_blk_data2;
  20. unsigned long port_command;
  21. };
  22. static const struct bcm6838_test_port_hw bcm6838_hw = {
  23. .port_blk_data1 = 0x10,
  24. .port_blk_data2 = 0x14,
  25. .port_command = 0x18
  26. };
  27. struct bcm6838_pinctrl_priv {
  28. const struct bcm6838_test_port_hw *hw;
  29. struct regmap *regmap;
  30. u32 pins_count;
  31. u32 functions_count;
  32. };
  33. int bcm6838_pinctrl_get_pins_count(struct udevice *dev)
  34. {
  35. struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  36. return priv->pins_count;
  37. }
  38. const char *bcm6838_pinctrl_get_pin_name(struct udevice *dev,
  39. unsigned int selector)
  40. {
  41. snprintf(bcm6838_pin_name, BCM6838_MAX_PIN_NAME_LEN, "%u", selector);
  42. return bcm6838_pin_name;
  43. }
  44. int bcm6838_pinctrl_get_functions_count(struct udevice *dev)
  45. {
  46. struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  47. return priv->functions_count;
  48. }
  49. const char *bcm6838_pinctrl_get_function_name(struct udevice *dev,
  50. unsigned int selector)
  51. {
  52. snprintf(bcm6838_func_name, BCM6838_MAX_FUNC_NAME_LEN, "%u", selector);
  53. return bcm6838_func_name;
  54. }
  55. int bcm6838_pinctrl_pinmux_set(struct udevice *dev,
  56. unsigned int pin_selector,
  57. unsigned int func_selector)
  58. {
  59. struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  60. const struct bcm6838_test_port_hw *hw = priv->hw;
  61. unsigned int data;
  62. regmap_write(priv->regmap, hw->port_blk_data1, 0);
  63. data = (func_selector << BCM6838_FUNC_OFFS) & BCM6838_FUNC_MASK;
  64. data |= (pin_selector << BCM6838_PIN_OFFS) & BCM6838_PIN_MASK;
  65. regmap_write(priv->regmap, hw->port_blk_data2, data);
  66. regmap_write(priv->regmap, hw->port_command, BCM6838_CMD_LOAD_MUX);
  67. return 0;
  68. }
  69. int bcm6838_pinctrl_probe(struct udevice *dev)
  70. {
  71. struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev);
  72. const struct bcm6838_test_port_hw *hw =
  73. (const struct bcm6838_test_port_hw *)dev_get_driver_data(dev);
  74. int err;
  75. u32 phandle;
  76. ofnode node;
  77. err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle);
  78. if (err) {
  79. dev_err(dev, "%s: unable to read regmap\n", __func__);
  80. goto out;
  81. }
  82. node = ofnode_get_by_phandle(phandle);
  83. if (!ofnode_valid(node)) {
  84. dev_err(dev, "%s: unable to find node\n", __func__);
  85. err = -EINVAL;
  86. goto out;
  87. }
  88. priv->regmap = syscon_node_to_regmap(node);
  89. if (!priv->regmap) {
  90. dev_err(dev, "%s: unable to find regmap\n", __func__);
  91. err = -ENODEV;
  92. goto out;
  93. }
  94. err = ofnode_read_u32(dev_ofnode(dev), "brcm,pins-count",
  95. &priv->pins_count);
  96. if (err) {
  97. dev_err(dev, "%s: unable to read brcm,pins-count\n",
  98. __func__);
  99. goto out;
  100. }
  101. err = ofnode_read_u32(dev_ofnode(dev), "brcm,functions-count",
  102. &priv->functions_count);
  103. if (err) {
  104. dev_err(dev, "%s: unable to read brcm,functions-count\n",
  105. __func__);
  106. goto out;
  107. }
  108. priv->hw = hw;
  109. out:
  110. return err;
  111. }
  112. const struct pinctrl_ops bcm6838_pinctrl_ops = {
  113. .set_state = pinctrl_generic_set_state,
  114. .get_pins_count = bcm6838_pinctrl_get_pins_count,
  115. .get_pin_name = bcm6838_pinctrl_get_pin_name,
  116. .get_functions_count = bcm6838_pinctrl_get_functions_count,
  117. .get_function_name = bcm6838_pinctrl_get_function_name,
  118. .pinmux_set = bcm6838_pinctrl_pinmux_set,
  119. };
  120. static const struct udevice_id bcm6838_pinctrl_match[] = {
  121. {
  122. .compatible = "brcm,bcm6838-pinctrl",
  123. .data = (ulong)&bcm6838_hw,
  124. },
  125. { /* sentinel */ }
  126. };
  127. U_BOOT_DRIVER(bcm6838_pinctrl) = {
  128. .name = "bcm6838_pinctrl",
  129. .id = UCLASS_PINCTRL,
  130. .of_match = bcm6838_pinctrl_match,
  131. .ops = &bcm6838_pinctrl_ops,
  132. .priv_auto_alloc_size = sizeof(struct bcm6838_pinctrl_priv),
  133. .probe = bcm6838_pinctrl_probe,
  134. };