hsdk-creg-gpio.c 4.4 KB

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