rockchip-saradc.c 4.3 KB

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