rockchip-saradc.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2017, Fuzhou Rockchip Electronics Co., Ltd
  4. *
  5. * Rockchip SARADC driver for U-Boot
  6. */
  7. #include <common.h>
  8. #include <adc.h>
  9. #include <clk.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <asm/io.h>
  13. #include <linux/bitops.h>
  14. #include <linux/err.h>
  15. #include <power/regulator.h>
  16. #define SARADC_CTRL_CHN_MASK GENMASK(2, 0)
  17. #define SARADC_CTRL_POWER_CTRL BIT(3)
  18. #define SARADC_CTRL_IRQ_ENABLE BIT(5)
  19. #define SARADC_CTRL_IRQ_STATUS BIT(6)
  20. #define SARADC_TIMEOUT (100 * 1000)
  21. struct rockchip_saradc_regs {
  22. unsigned int data;
  23. unsigned int stas;
  24. unsigned int ctrl;
  25. unsigned int dly_pu_soc;
  26. };
  27. struct rockchip_saradc_data {
  28. int num_bits;
  29. int num_channels;
  30. unsigned long clk_rate;
  31. };
  32. struct rockchip_saradc_priv {
  33. struct rockchip_saradc_regs *regs;
  34. int active_channel;
  35. const struct rockchip_saradc_data *data;
  36. };
  37. int rockchip_saradc_channel_data(struct udevice *dev, int channel,
  38. unsigned int *data)
  39. {
  40. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  41. struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
  42. if (channel != priv->active_channel) {
  43. pr_err("Requested channel is not active!");
  44. return -EINVAL;
  45. }
  46. if ((readl(&priv->regs->ctrl) & SARADC_CTRL_IRQ_STATUS) !=
  47. SARADC_CTRL_IRQ_STATUS)
  48. return -EBUSY;
  49. /* Read value */
  50. *data = readl(&priv->regs->data);
  51. *data &= uc_pdata->data_mask;
  52. /* Power down adc */
  53. writel(0, &priv->regs->ctrl);
  54. return 0;
  55. }
  56. int rockchip_saradc_start_channel(struct udevice *dev, int channel)
  57. {
  58. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  59. if (channel < 0 || channel >= priv->data->num_channels) {
  60. pr_err("Requested channel is invalid!");
  61. return -EINVAL;
  62. }
  63. /* 8 clock periods as delay between power up and start cmd */
  64. writel(8, &priv->regs->dly_pu_soc);
  65. /* Select the channel to be used and trigger conversion */
  66. writel(SARADC_CTRL_POWER_CTRL | (channel & SARADC_CTRL_CHN_MASK) |
  67. SARADC_CTRL_IRQ_ENABLE, &priv->regs->ctrl);
  68. priv->active_channel = channel;
  69. return 0;
  70. }
  71. int rockchip_saradc_stop(struct udevice *dev)
  72. {
  73. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  74. /* Power down adc */
  75. writel(0, &priv->regs->ctrl);
  76. priv->active_channel = -1;
  77. return 0;
  78. }
  79. int rockchip_saradc_probe(struct udevice *dev)
  80. {
  81. struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
  82. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  83. struct udevice *vref;
  84. struct clk clk;
  85. int vref_uv;
  86. int ret;
  87. ret = clk_get_by_index(dev, 0, &clk);
  88. if (ret)
  89. return ret;
  90. ret = clk_set_rate(&clk, priv->data->clk_rate);
  91. if (IS_ERR_VALUE(ret))
  92. return ret;
  93. priv->active_channel = -1;
  94. ret = device_get_supply_regulator(dev, "vref-supply", &vref);
  95. if (ret) {
  96. printf("can't get vref-supply: %d\n", ret);
  97. return ret;
  98. }
  99. vref_uv = regulator_get_value(vref);
  100. if (vref_uv < 0) {
  101. printf("can't get vref-supply value: %d\n", vref_uv);
  102. return vref_uv;
  103. }
  104. /* VDD supplied by common vref pin */
  105. uc_pdata->vdd_supply = vref;
  106. uc_pdata->vdd_microvolts = vref_uv;
  107. uc_pdata->vss_microvolts = 0;
  108. return 0;
  109. }
  110. int rockchip_saradc_of_to_plat(struct udevice *dev)
  111. {
  112. struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
  113. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  114. struct rockchip_saradc_data *data;
  115. data = (struct rockchip_saradc_data *)dev_get_driver_data(dev);
  116. priv->regs = dev_read_addr_ptr(dev);
  117. if (!priv->regs) {
  118. pr_err("Dev: %s - can't get address!", dev->name);
  119. return -EINVAL;
  120. }
  121. priv->data = data;
  122. uc_pdata->data_mask = (1 << priv->data->num_bits) - 1;
  123. uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
  124. uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5;
  125. uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1;
  126. return 0;
  127. }
  128. static const struct adc_ops rockchip_saradc_ops = {
  129. .start_channel = rockchip_saradc_start_channel,
  130. .channel_data = rockchip_saradc_channel_data,
  131. .stop = rockchip_saradc_stop,
  132. };
  133. static const struct rockchip_saradc_data saradc_data = {
  134. .num_bits = 10,
  135. .num_channels = 3,
  136. .clk_rate = 1000000,
  137. };
  138. static const struct rockchip_saradc_data rk3066_tsadc_data = {
  139. .num_bits = 12,
  140. .num_channels = 2,
  141. .clk_rate = 50000,
  142. };
  143. static const struct rockchip_saradc_data rk3399_saradc_data = {
  144. .num_bits = 10,
  145. .num_channels = 6,
  146. .clk_rate = 1000000,
  147. };
  148. static const struct udevice_id rockchip_saradc_ids[] = {
  149. { .compatible = "rockchip,saradc",
  150. .data = (ulong)&saradc_data },
  151. { .compatible = "rockchip,rk3066-tsadc",
  152. .data = (ulong)&rk3066_tsadc_data },
  153. { .compatible = "rockchip,rk3399-saradc",
  154. .data = (ulong)&rk3399_saradc_data },
  155. { }
  156. };
  157. U_BOOT_DRIVER(rockchip_saradc) = {
  158. .name = "rockchip_saradc",
  159. .id = UCLASS_ADC,
  160. .of_match = rockchip_saradc_ids,
  161. .ops = &rockchip_saradc_ops,
  162. .probe = rockchip_saradc_probe,
  163. .of_to_plat = rockchip_saradc_of_to_plat,
  164. .priv_auto = sizeof(struct rockchip_saradc_priv),
  165. };