1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2021, 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 <linux/iopoll.h> 13 #include <errno.h> 14 #include <asm/io.h> 15 #include <reset.h> 16 17 #define SARADC2_EN_END_INT BIT(0) 18 #define SARADC2_START BIT(4) 19 #define SARADC2_SINGLE_MODE BIT(5) 20 21 #define SARADC_TIMEOUT (100 * 1000) 22 23 struct rockchip_saradc_regs { 24 u32 conv_con; 25 u32 t_pd_soc; 26 u32 t_as_soc; 27 u32 t_das_soc; 28 u32 t_sel_soc; 29 u32 high_comp0; 30 u32 high_comp1; 31 u32 high_comp2; 32 u32 high_comp3; 33 u32 high_comp4; 34 u32 high_comp5; 35 u32 reserved0044; 36 u32 high_comp7; 37 u32 high_comp8; 38 u32 high_comp9; 39 u32 high_comp10; 40 u32 high_comp11; 41 u32 high_comp12; 42 u32 high_comp13; 43 u32 high_comp14; 44 u32 high_comp15; 45 u32 low_comp0; 46 u32 low_comp1; 47 u32 low_comp2; 48 u32 low_comp3; 49 u32 low_comp4; 50 u32 low_comp5; 51 u32 low_comp6; 52 u32 low_comp7; 53 u32 low_comp8; 54 u32 low_comp9; 55 u32 low_comp10; 56 u32 low_comp11; 57 u32 low_comp12; 58 u32 low_comp13; 59 u32 low_comp14; 60 u32 low_comp15; 61 u32 debounce; 62 u32 ht_int_en; 63 u32 lt_int_en; 64 u32 reserved0160[24]; 65 u32 mt_int_en; 66 u32 end_int_en; 67 u32 st_con; 68 u32 status; 69 u32 end_int_st; 70 u32 ht_int_st; 71 u32 lt_int_st; 72 u32 mt_int_st; 73 u32 data0; 74 u32 data1; 75 u32 data2; 76 u32 data3; 77 u32 data4; 78 u32 data5; 79 u32 data6; 80 u32 data7; 81 u32 data8; 82 u32 data9; 83 u32 data10; 84 u32 data11; 85 u32 data12; 86 u32 data13; 87 u32 data14; 88 u32 data15; 89 u32 auto_ch_en; 90 }; 91 92 struct rockchip_saradc_data { 93 int num_bits; 94 int num_channels; 95 unsigned long clk_rate; 96 }; 97 98 struct rockchip_saradc_priv { 99 struct rockchip_saradc_regs *regs; 100 int active_channel; 101 const struct rockchip_saradc_data *data; 102 struct reset_ctl rst; 103 }; 104 105 static int rockchip_saradc_channel_data(struct udevice *dev, int channel, 106 unsigned int *data) 107 { 108 struct rockchip_saradc_priv *priv = dev_get_priv(dev); 109 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 110 u32 status; 111 112 if (channel != priv->active_channel) { 113 pr_err("Requested channel is not active!"); 114 return -EINVAL; 115 } 116 117 /* Wait for end conversion interrupt status. */ 118 if (readl_poll_timeout(&priv->regs->end_int_st, status, 119 status & SARADC2_EN_END_INT, SARADC_TIMEOUT)) { 120 pr_err("Wait for end conversion interrupt status timeout!\n"); 121 return -ETIMEDOUT; 122 } 123 124 /* Clear irq. */ 125 writel(0x1, &priv->regs->end_int_st); 126 127 *data = readl(&priv->regs->data0 + priv->active_channel); 128 *data &= uc_pdata->data_mask; 129 130 return 0; 131 } 132 133 static int rockchip_saradc_start_channel(struct udevice *dev, int channel) 134 { 135 struct rockchip_saradc_priv *priv = dev_get_priv(dev); 136 int val; 137 138 if (channel < 0 || channel >= priv->data->num_channels) { 139 pr_err("Requested channel is invalid!"); 140 return -EINVAL; 141 } 142 143 #if CONFIG_IS_ENABLED(DM_RESET) 144 reset_assert(&priv->rst); 145 udelay(10); 146 reset_deassert(&priv->rst); 147 #endif 148 writel(0x20, &priv->regs->t_pd_soc); 149 writel(0xc, &priv->regs->t_das_soc); 150 val = SARADC2_EN_END_INT << 16 | SARADC2_EN_END_INT; 151 writel(val, &priv->regs->end_int_en); 152 val = SARADC2_START | SARADC2_SINGLE_MODE | channel; 153 writel(val << 16 | val, &priv->regs->conv_con); 154 155 udelay(100); 156 157 priv->active_channel = channel; 158 159 return 0; 160 } 161 162 static int rockchip_saradc_stop(struct udevice *dev) 163 { 164 struct rockchip_saradc_priv *priv = dev_get_priv(dev); 165 166 priv->active_channel = -1; 167 168 return 0; 169 } 170 171 static int rockchip_saradc_probe(struct udevice *dev) 172 { 173 struct rockchip_saradc_priv *priv = dev_get_priv(dev); 174 struct clk clk; 175 int ret; 176 177 #if CONFIG_IS_ENABLED(DM_RESET) 178 ret = reset_get_by_name(dev, "saradc-apb", &priv->rst); 179 if (ret) { 180 debug("reset_get_by_name() failed: %d\n", ret); 181 return ret; 182 } 183 #endif 184 185 ret = clk_get_by_index(dev, 0, &clk); 186 if (ret) 187 return ret; 188 189 ret = clk_set_rate(&clk, priv->data->clk_rate); 190 if (IS_ERR_VALUE(ret)) 191 return ret; 192 193 /* Wait until pll stable */ 194 mdelay(5); 195 196 priv->active_channel = -1; 197 198 return 0; 199 } 200 201 static int rockchip_saradc_ofdata_to_platdata(struct udevice *dev) 202 { 203 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 204 struct rockchip_saradc_priv *priv = dev_get_priv(dev); 205 struct rockchip_saradc_data *data; 206 207 data = (struct rockchip_saradc_data *)dev_get_driver_data(dev); 208 priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev); 209 if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) { 210 pr_err("Dev: %s - can't get address!", dev->name); 211 return -ENODATA; 212 } 213 214 priv->data = data; 215 uc_pdata->data_mask = (1 << priv->data->num_bits) - 1; 216 uc_pdata->data_format = ADC_DATA_FORMAT_BIN; 217 uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5; 218 uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1; 219 220 return 0; 221 } 222 223 static const struct adc_ops rockchip_saradc_ops = { 224 .start_channel = rockchip_saradc_start_channel, 225 .channel_data = rockchip_saradc_channel_data, 226 .stop = rockchip_saradc_stop, 227 }; 228 229 static const struct rockchip_saradc_data rk3588_saradc_data = { 230 .num_bits = 12, 231 .num_channels = 8, 232 .clk_rate = 1000000, 233 }; 234 235 static const struct rockchip_saradc_data rk3562_saradc_data = { 236 .num_bits = 10, 237 .num_channels = 8, 238 .clk_rate = 1000000, 239 }; 240 241 static const struct rockchip_saradc_data rv1106_saradc_data = { 242 .num_bits = 10, 243 .num_channels = 2, 244 .clk_rate = 1000000, 245 }; 246 247 static const struct rockchip_saradc_data rv1103b_saradc_data = { 248 .num_bits = 10, 249 .num_channels = 1, 250 .clk_rate = 1000000, 251 }; 252 253 static const struct udevice_id rockchip_saradc_ids[] = { 254 { 255 .compatible = "rockchip,rk3588-saradc", 256 .data = (ulong)&rk3588_saradc_data 257 }, 258 { 259 .compatible = "rockchip,rk3528-saradc", 260 .data = (ulong)&rk3588_saradc_data 261 }, 262 { 263 .compatible = "rockchip,rk3562-saradc", 264 .data = (ulong)&rk3562_saradc_data 265 }, 266 { 267 .compatible = "rockchip,rv1106-saradc", 268 .data = (ulong)&rv1106_saradc_data 269 }, 270 { 271 .compatible = "rockchip,rv1103b-saradc", 272 .data = (ulong)&rv1103b_saradc_data 273 }, 274 { } 275 }; 276 277 U_BOOT_DRIVER(rockchip_saradc_v2) = { 278 .name = "rockchip_saradc_v2", 279 .id = UCLASS_ADC, 280 .of_match = rockchip_saradc_ids, 281 .ops = &rockchip_saradc_ops, 282 .probe = rockchip_saradc_probe, 283 .ofdata_to_platdata = rockchip_saradc_ofdata_to_platdata, 284 .priv_auto_alloc_size = sizeof(struct rockchip_saradc_priv), 285 }; 286