hsdk-creg-gpio.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Synopsys HSDK SDP Generic PLL clock driver
  3. *
  4. * Copyright (C) 2017 Synopsys
  5. * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
  6. *
  7. * This file is licensed under the terms of the GNU General Public
  8. * License version 2. This program is licensed "as is" without any
  9. * warranty of any kind, whether express or implied.
  10. */
  11. #include <log.h>
  12. #include <asm-generic/gpio.h>
  13. #include <asm/io.h>
  14. #include <common.h>
  15. #include <dm.h>
  16. #include <errno.h>
  17. #include <linux/bitops.h>
  18. #include <linux/printk.h>
  19. #define DRV_NAME "gpio_creg"
  20. struct hsdk_creg_gpio {
  21. u32 *regs;
  22. u8 shift;
  23. u8 activate;
  24. u8 deactivate;
  25. u8 bit_per_gpio;
  26. };
  27. static int hsdk_creg_gpio_set_value(struct udevice *dev, unsigned oft, int val)
  28. {
  29. struct hsdk_creg_gpio *hcg = dev_get_priv(dev);
  30. u8 reg_shift = oft * hcg->bit_per_gpio + hcg->shift;
  31. u32 reg = readl(hcg->regs);
  32. reg &= ~(GENMASK(hcg->bit_per_gpio - 1, 0) << reg_shift);
  33. reg |= ((val ? hcg->deactivate : hcg->activate) << reg_shift);
  34. writel(reg, hcg->regs);
  35. return 0;
  36. }
  37. static int hsdk_creg_gpio_direction_output(struct udevice *dev, unsigned oft,
  38. int val)
  39. {
  40. hsdk_creg_gpio_set_value(dev, oft, val);
  41. return 0;
  42. }
  43. static int hsdk_creg_gpio_direction_input(struct udevice *dev, unsigned oft)
  44. {
  45. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  46. pr_err("%s can't be used as input!\n", uc_priv->bank_name);
  47. return -ENOTSUPP;
  48. }
  49. static int hsdk_creg_gpio_get_value(struct udevice *dev, unsigned int oft)
  50. {
  51. struct hsdk_creg_gpio *hcg = dev_get_priv(dev);
  52. u32 val = readl(hcg->regs);
  53. val >>= oft * hcg->bit_per_gpio + hcg->shift;
  54. val &= GENMASK(hcg->bit_per_gpio - 1, 0);
  55. return (val == hcg->deactivate) ? 1 : 0;
  56. }
  57. static const struct dm_gpio_ops hsdk_creg_gpio_ops = {
  58. .direction_output = hsdk_creg_gpio_direction_output,
  59. .direction_input = hsdk_creg_gpio_direction_input,
  60. .set_value = hsdk_creg_gpio_set_value,
  61. .get_value = hsdk_creg_gpio_get_value,
  62. };
  63. static int hsdk_creg_gpio_probe(struct udevice *dev)
  64. {
  65. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  66. struct hsdk_creg_gpio *hcg = dev_get_priv(dev);
  67. u32 shift, bit_per_gpio, activate, deactivate, gpio_count;
  68. const u8 *defaults;
  69. hcg->regs = dev_read_addr_ptr(dev);
  70. gpio_count = dev_read_u32_default(dev, "gpio-count", 1);
  71. shift = dev_read_u32_default(dev, "gpio-first-shift", 0);
  72. bit_per_gpio = dev_read_u32_default(dev, "gpio-bit-per-line", 1);
  73. activate = dev_read_u32_default(dev, "gpio-activate-val", 1);
  74. deactivate = dev_read_u32_default(dev, "gpio-deactivate-val", 0);
  75. defaults = dev_read_u8_array_ptr(dev, "gpio-default-val", gpio_count);
  76. uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
  77. if (!uc_priv->bank_name)
  78. uc_priv->bank_name = dev_read_name(dev);
  79. if (!bit_per_gpio) {
  80. pr_err("%s: 'gpio-bit-per-line' can't be 0\n",
  81. uc_priv->bank_name);
  82. return -EINVAL;
  83. }
  84. if (!gpio_count) {
  85. pr_err("%s: 'gpio-count' can't be 0\n",
  86. uc_priv->bank_name);
  87. return -EINVAL;
  88. }
  89. if ((gpio_count * bit_per_gpio + shift) > 32) {
  90. pr_err("%s: u32 io register overflow: try to use %u bits\n",
  91. uc_priv->bank_name, gpio_count * bit_per_gpio + shift);
  92. return -EINVAL;
  93. }
  94. if (GENMASK(31, bit_per_gpio) & activate) {
  95. pr_err("%s: 'gpio-activate-val' can't be more than %lu\n",
  96. uc_priv->bank_name, GENMASK(bit_per_gpio - 1, 0));
  97. return -EINVAL;
  98. }
  99. if (GENMASK(31, bit_per_gpio) & deactivate) {
  100. pr_err("%s: 'gpio-deactivate-val' can't be more than %lu\n",
  101. uc_priv->bank_name, GENMASK(bit_per_gpio - 1, 0));
  102. return -EINVAL;
  103. }
  104. if (activate == deactivate) {
  105. pr_err("%s: 'gpio-deactivate-val' and 'gpio-activate-val' can't be equal\n",
  106. uc_priv->bank_name);
  107. return -EINVAL;
  108. }
  109. hcg->shift = (u8)shift;
  110. hcg->bit_per_gpio = (u8)bit_per_gpio;
  111. hcg->activate = (u8)activate;
  112. hcg->deactivate = (u8)deactivate;
  113. uc_priv->gpio_count = gpio_count;
  114. /* Setup default GPIO value if we have "gpio-default-val" array */
  115. if (defaults)
  116. for (u8 i = 0; i < gpio_count; i++)
  117. hsdk_creg_gpio_set_value(dev, i, defaults[i]);
  118. pr_debug("%s GPIO [0x%p] controller with %d gpios probed\n",
  119. uc_priv->bank_name, hcg->regs, uc_priv->gpio_count);
  120. return 0;
  121. }
  122. static const struct udevice_id hsdk_creg_gpio_ids[] = {
  123. { .compatible = "snps,creg-gpio" },
  124. { }
  125. };
  126. U_BOOT_DRIVER(gpio_hsdk_creg) = {
  127. .name = DRV_NAME,
  128. .id = UCLASS_GPIO,
  129. .ops = &hsdk_creg_gpio_ops,
  130. .probe = hsdk_creg_gpio_probe,
  131. .of_match = hsdk_creg_gpio_ids,
  132. .plat_auto = sizeof(struct hsdk_creg_gpio),
  133. };