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