rockchip-saradc.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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/err.h>
  14. #define SARADC_CTRL_CHN_MASK GENMASK(2, 0)
  15. #define SARADC_CTRL_POWER_CTRL BIT(3)
  16. #define SARADC_CTRL_IRQ_ENABLE BIT(5)
  17. #define SARADC_CTRL_IRQ_STATUS BIT(6)
  18. #define SARADC_TIMEOUT (100 * 1000)
  19. struct rockchip_saradc_regs {
  20. unsigned int data;
  21. unsigned int stas;
  22. unsigned int ctrl;
  23. unsigned int dly_pu_soc;
  24. };
  25. struct rockchip_saradc_data {
  26. int num_bits;
  27. int num_channels;
  28. unsigned long clk_rate;
  29. };
  30. struct rockchip_saradc_priv {
  31. struct rockchip_saradc_regs *regs;
  32. int active_channel;
  33. const struct rockchip_saradc_data *data;
  34. };
  35. int rockchip_saradc_channel_data(struct udevice *dev, int channel,
  36. unsigned int *data)
  37. {
  38. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  39. struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
  40. if (channel != priv->active_channel) {
  41. pr_err("Requested channel is not active!");
  42. return -EINVAL;
  43. }
  44. if ((readl(&priv->regs->ctrl) & SARADC_CTRL_IRQ_STATUS) !=
  45. SARADC_CTRL_IRQ_STATUS)
  46. return -EBUSY;
  47. /* Read value */
  48. *data = readl(&priv->regs->data);
  49. *data &= uc_pdata->data_mask;
  50. /* Power down adc */
  51. writel(0, &priv->regs->ctrl);
  52. return 0;
  53. }
  54. int rockchip_saradc_start_channel(struct udevice *dev, int channel)
  55. {
  56. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  57. if (channel < 0 || channel >= priv->data->num_channels) {
  58. pr_err("Requested channel is invalid!");
  59. return -EINVAL;
  60. }
  61. /* 8 clock periods as delay between power up and start cmd */
  62. writel(8, &priv->regs->dly_pu_soc);
  63. /* Select the channel to be used and trigger conversion */
  64. writel(SARADC_CTRL_POWER_CTRL | (channel & SARADC_CTRL_CHN_MASK) |
  65. SARADC_CTRL_IRQ_ENABLE, &priv->regs->ctrl);
  66. priv->active_channel = channel;
  67. return 0;
  68. }
  69. int rockchip_saradc_stop(struct udevice *dev)
  70. {
  71. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  72. /* Power down adc */
  73. writel(0, &priv->regs->ctrl);
  74. priv->active_channel = -1;
  75. return 0;
  76. }
  77. int rockchip_saradc_probe(struct udevice *dev)
  78. {
  79. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  80. struct clk clk;
  81. int ret;
  82. ret = clk_get_by_index(dev, 0, &clk);
  83. if (ret)
  84. return ret;
  85. ret = clk_set_rate(&clk, priv->data->clk_rate);
  86. if (IS_ERR_VALUE(ret))
  87. return ret;
  88. priv->active_channel = -1;
  89. return 0;
  90. }
  91. int rockchip_saradc_ofdata_to_platdata(struct udevice *dev)
  92. {
  93. struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
  94. struct rockchip_saradc_priv *priv = dev_get_priv(dev);
  95. struct rockchip_saradc_data *data;
  96. data = (struct rockchip_saradc_data *)dev_get_driver_data(dev);
  97. priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev);
  98. if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) {
  99. pr_err("Dev: %s - can't get address!", dev->name);
  100. return -ENODATA;
  101. }
  102. priv->data = data;
  103. uc_pdata->data_mask = (1 << priv->data->num_bits) - 1;;
  104. uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
  105. uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5;
  106. uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1;
  107. return 0;
  108. }
  109. static const struct adc_ops rockchip_saradc_ops = {
  110. .start_channel = rockchip_saradc_start_channel,
  111. .channel_data = rockchip_saradc_channel_data,
  112. .stop = rockchip_saradc_stop,
  113. };
  114. static const struct rockchip_saradc_data saradc_data = {
  115. .num_bits = 10,
  116. .num_channels = 3,
  117. .clk_rate = 1000000,
  118. };
  119. static const struct rockchip_saradc_data rk3066_tsadc_data = {
  120. .num_bits = 12,
  121. .num_channels = 2,
  122. .clk_rate = 50000,
  123. };
  124. static const struct rockchip_saradc_data rk3399_saradc_data = {
  125. .num_bits = 10,
  126. .num_channels = 6,
  127. .clk_rate = 1000000,
  128. };
  129. static const struct udevice_id rockchip_saradc_ids[] = {
  130. { .compatible = "rockchip,saradc",
  131. .data = (ulong)&saradc_data },
  132. { .compatible = "rockchip,rk3066-tsadc",
  133. .data = (ulong)&rk3066_tsadc_data },
  134. { .compatible = "rockchip,rk3399-saradc",
  135. .data = (ulong)&rk3399_saradc_data },
  136. { }
  137. };
  138. U_BOOT_DRIVER(rockchip_saradc) = {
  139. .name = "rockchip_saradc",
  140. .id = UCLASS_ADC,
  141. .of_match = rockchip_saradc_ids,
  142. .ops = &rockchip_saradc_ops,
  143. .probe = rockchip_saradc_probe,
  144. .ofdata_to_platdata = rockchip_saradc_ofdata_to_platdata,
  145. .priv_auto_alloc_size = sizeof(struct rockchip_saradc_priv),
  146. };