1 /* 2 * Copyright (C) 2015 Samsung Electronics 3 * Przemyslaw Marczak <p.marczak@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <errno.h> 10 #include <dm.h> 11 #include <dm/lists.h> 12 #include <dm/device-internal.h> 13 #include <dm/uclass-internal.h> 14 #include <adc.h> 15 #include <power/regulator.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define ADC_UCLASS_PLATDATA_SIZE sizeof(struct adc_uclass_platdata) 20 #define CHECK_NUMBER true 21 #define CHECK_MASK (!CHECK_NUMBER) 22 23 /* TODO: add support for timer uclass (for early calls) */ 24 #ifdef CONFIG_SANDBOX_ARCH 25 #define sdelay(x) udelay(x) 26 #else 27 extern void sdelay(unsigned long loops); 28 #endif 29 30 static int check_channel(struct udevice *dev, int value, bool number_or_mask, 31 const char *caller_function) 32 { 33 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 34 unsigned mask = number_or_mask ? (1 << value) : value; 35 36 /* For the real ADC hardware, some ADC channels can be inactive. 37 * For example if device has 4 analog channels, and only channels 38 * 1-st and 3-rd are valid, then channel mask is: 0b1010, so request 39 * with mask 0b1110 should return an error. 40 */ 41 if ((uc_pdata->channel_mask >= mask) && (uc_pdata->channel_mask & mask)) 42 return 0; 43 44 printf("Error in %s/%s().\nWrong channel selection for device: %s\n", 45 __FILE__, caller_function, dev->name); 46 47 return -EINVAL; 48 } 49 50 #ifdef CONFIG_ADC_REQ_REGULATOR 51 static int adc_supply_enable(struct udevice *dev) 52 { 53 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 54 const char *supply_type; 55 int ret = 0; 56 57 if (uc_pdata->vdd_supply) { 58 supply_type = "vdd"; 59 ret = regulator_set_enable(uc_pdata->vdd_supply, true); 60 } 61 62 if (!ret && uc_pdata->vss_supply) { 63 supply_type = "vss"; 64 ret = regulator_set_enable(uc_pdata->vss_supply, true); 65 } 66 67 if (ret) 68 pr_err("%s: can't enable %s-supply!", dev->name, supply_type); 69 70 return ret; 71 } 72 #else 73 static inline int adc_supply_enable(struct udevice *dev) { return 0; } 74 #endif 75 76 int adc_data_mask(struct udevice *dev, unsigned int *data_mask) 77 { 78 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 79 80 if (!uc_pdata) 81 return -ENOSYS; 82 83 *data_mask = uc_pdata->data_mask; 84 return 0; 85 } 86 87 int adc_stop(struct udevice *dev) 88 { 89 const struct adc_ops *ops = dev_get_driver_ops(dev); 90 91 if (!ops->stop) 92 return -ENOSYS; 93 94 return ops->stop(dev); 95 } 96 97 int adc_start_channel(struct udevice *dev, int channel) 98 { 99 const struct adc_ops *ops = dev_get_driver_ops(dev); 100 int ret; 101 102 if (!ops->start_channel) 103 return -ENOSYS; 104 105 ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 106 if (ret) 107 return ret; 108 109 ret = adc_supply_enable(dev); 110 if (ret) 111 return ret; 112 113 return ops->start_channel(dev, channel); 114 } 115 116 int adc_start_channels(struct udevice *dev, unsigned int channel_mask) 117 { 118 const struct adc_ops *ops = dev_get_driver_ops(dev); 119 int ret; 120 121 if (!ops->start_channels) 122 return -ENOSYS; 123 124 ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 125 if (ret) 126 return ret; 127 128 ret = adc_supply_enable(dev); 129 if (ret) 130 return ret; 131 132 return ops->start_channels(dev, channel_mask); 133 } 134 135 int adc_channel_data(struct udevice *dev, int channel, unsigned int *data) 136 { 137 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 138 const struct adc_ops *ops = dev_get_driver_ops(dev); 139 unsigned int timeout_us = uc_pdata->data_timeout_us; 140 int ret; 141 142 if (!ops->channel_data) 143 return -ENOSYS; 144 145 ret = check_channel(dev, channel, CHECK_NUMBER, __func__); 146 if (ret) 147 return ret; 148 149 do { 150 ret = ops->channel_data(dev, channel, data); 151 if (!ret || ret != -EBUSY) 152 break; 153 154 /* TODO: use timer uclass (for early calls). */ 155 sdelay(5); 156 } while (timeout_us--); 157 158 return ret; 159 } 160 161 int adc_channels_data(struct udevice *dev, unsigned int channel_mask, 162 struct adc_channel *channels) 163 { 164 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 165 unsigned int timeout_us = uc_pdata->multidata_timeout_us; 166 const struct adc_ops *ops = dev_get_driver_ops(dev); 167 int ret; 168 169 if (!ops->channels_data) 170 return -ENOSYS; 171 172 ret = check_channel(dev, channel_mask, CHECK_MASK, __func__); 173 if (ret) 174 return ret; 175 176 do { 177 ret = ops->channels_data(dev, channel_mask, channels); 178 if (!ret || ret != -EBUSY) 179 break; 180 181 /* TODO: use timer uclass (for early calls). */ 182 sdelay(5); 183 } while (timeout_us--); 184 185 return ret; 186 } 187 188 int adc_channel_single_shot(const char *name, int channel, unsigned int *data) 189 { 190 struct udevice *dev; 191 int ret; 192 193 ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 194 if (ret) 195 return ret; 196 197 ret = adc_start_channel(dev, channel); 198 if (ret) 199 return ret; 200 201 ret = adc_channel_data(dev, channel, data); 202 if (ret) 203 return ret; 204 205 return 0; 206 } 207 208 static int _adc_channels_single_shot(struct udevice *dev, 209 unsigned int channel_mask, 210 struct adc_channel *channels) 211 { 212 unsigned int data; 213 int channel, ret; 214 215 for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) { 216 /* Check channel bit. */ 217 if (!((channel_mask >> channel) & 0x1)) 218 continue; 219 220 ret = adc_start_channel(dev, channel); 221 if (ret) 222 return ret; 223 224 ret = adc_channel_data(dev, channel, &data); 225 if (ret) 226 return ret; 227 228 channels->id = channel; 229 channels->data = data; 230 channels++; 231 } 232 233 return 0; 234 } 235 236 int adc_channels_single_shot(const char *name, unsigned int channel_mask, 237 struct adc_channel *channels) 238 { 239 struct udevice *dev; 240 int ret; 241 242 ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); 243 if (ret) 244 return ret; 245 246 ret = adc_start_channels(dev, channel_mask); 247 if (ret) 248 goto try_manual; 249 250 ret = adc_channels_data(dev, channel_mask, channels); 251 if (ret) 252 return ret; 253 254 return 0; 255 256 try_manual: 257 if (ret != -ENOSYS) 258 return ret; 259 260 return _adc_channels_single_shot(dev, channel_mask, channels); 261 } 262 263 #ifdef CONFIG_ADC_REQ_REGULATOR 264 static int adc_vdd_platdata_update(struct udevice *dev) 265 { 266 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 267 int ret; 268 269 /* Warning! 270 * This function can't return supply device before its bind. 271 * Please pay attention to proper fdt scan sequence. If ADC device 272 * will bind before its supply regulator device, then the below 'get' 273 * will return an error. 274 */ 275 ret = device_get_supply_regulator(dev, "vdd-supply", 276 &uc_pdata->vdd_supply); 277 if (ret) 278 return ret; 279 280 ret = regulator_get_value(uc_pdata->vdd_supply); 281 if (ret < 0) 282 return ret; 283 284 uc_pdata->vdd_microvolts = ret; 285 286 return 0; 287 } 288 #else 289 static inline int adc_vdd_platdata_update(struct udevice *dev) { return 0; } 290 #endif 291 292 #ifdef CONFIG_ADC_REQ_REGULATOR 293 static int adc_vss_platdata_update(struct udevice *dev) 294 { 295 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 296 int ret; 297 298 ret = device_get_supply_regulator(dev, "vss-supply", 299 &uc_pdata->vss_supply); 300 if (ret) 301 return ret; 302 303 ret = regulator_get_value(uc_pdata->vss_supply); 304 if (ret < 0) 305 return ret; 306 307 uc_pdata->vss_microvolts = ret; 308 309 return 0; 310 } 311 #else 312 static inline int adc_vss_platdata_update(struct udevice *dev) { return 0; } 313 #endif 314 315 int adc_vdd_value(struct udevice *dev, int *uV) 316 { 317 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 318 int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1; 319 320 if (!uc_pdata->vdd_supply) 321 goto nodev; 322 323 /* Update the regulator Value. */ 324 ret = adc_vdd_platdata_update(dev); 325 if (ret) 326 return ret; 327 nodev: 328 if (uc_pdata->vdd_microvolts == -ENODATA) 329 return -ENODATA; 330 331 *uV = uc_pdata->vdd_microvolts * value_sign; 332 333 return 0; 334 } 335 336 int adc_vss_value(struct udevice *dev, int *uV) 337 { 338 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 339 int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1; 340 341 if (!uc_pdata->vss_supply) 342 goto nodev; 343 344 /* Update the regulator Value. */ 345 ret = adc_vss_platdata_update(dev); 346 if (ret) 347 return ret; 348 nodev: 349 if (uc_pdata->vss_microvolts == -ENODATA) 350 return -ENODATA; 351 352 *uV = uc_pdata->vss_microvolts * value_sign; 353 354 return 0; 355 } 356 357 static int adc_vdd_platdata_set(struct udevice *dev) 358 { 359 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 360 int ret; 361 char *prop; 362 363 prop = "vdd-polarity-negative"; 364 uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop); 365 366 ret = adc_vdd_platdata_update(dev); 367 if (ret != -ENOENT) 368 return ret; 369 370 /* No vdd-supply phandle. */ 371 prop = "vdd-microvolts"; 372 uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 373 374 return 0; 375 } 376 377 static int adc_vss_platdata_set(struct udevice *dev) 378 { 379 struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); 380 int ret; 381 char *prop; 382 383 prop = "vss-polarity-negative"; 384 uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop); 385 386 ret = adc_vss_platdata_update(dev); 387 if (ret != -ENOENT) 388 return ret; 389 390 /* No vss-supply phandle. */ 391 prop = "vss-microvolts"; 392 uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA); 393 394 return 0; 395 } 396 397 static int adc_pre_probe(struct udevice *dev) 398 { 399 int ret; 400 401 /* Set ADC VDD platdata: polarity, uV, regulator (phandle). */ 402 ret = adc_vdd_platdata_set(dev); 403 if (ret) 404 pr_err("%s: Can't update Vdd. Error: %d", dev->name, ret); 405 406 /* Set ADC VSS platdata: polarity, uV, regulator (phandle). */ 407 ret = adc_vss_platdata_set(dev); 408 if (ret) 409 pr_err("%s: Can't update Vss. Error: %d", dev->name, ret); 410 411 return 0; 412 } 413 414 UCLASS_DRIVER(adc) = { 415 .id = UCLASS_ADC, 416 .name = "adc", 417 .pre_probe = adc_pre_probe, 418 .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE, 419 }; 420