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