905 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * AD5758 Digital to analog converters driver4 *5 * Copyright 2018 Analog Devices Inc.6 *7 * TODO: Currently CRC is not supported in this driver8 */9#include <linux/bsearch.h>10#include <linux/delay.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/mod_devicetable.h>14#include <linux/property.h>15#include <linux/spi/spi.h>16#include <linux/gpio/consumer.h>17 18#include <linux/iio/iio.h>19#include <linux/iio/sysfs.h>20 21/* AD5758 registers definition */22#define AD5758_NOP 0x0023#define AD5758_DAC_INPUT 0x0124#define AD5758_DAC_OUTPUT 0x0225#define AD5758_CLEAR_CODE 0x0326#define AD5758_USER_GAIN 0x0427#define AD5758_USER_OFFSET 0x0528#define AD5758_DAC_CONFIG 0x0629#define AD5758_SW_LDAC 0x0730#define AD5758_KEY 0x0831#define AD5758_GP_CONFIG1 0x0932#define AD5758_GP_CONFIG2 0x0A33#define AD5758_DCDC_CONFIG1 0x0B34#define AD5758_DCDC_CONFIG2 0x0C35#define AD5758_WDT_CONFIG 0x0F36#define AD5758_DIGITAL_DIAG_CONFIG 0x1037#define AD5758_ADC_CONFIG 0x1138#define AD5758_FAULT_PIN_CONFIG 0x1239#define AD5758_TWO_STAGE_READBACK_SELECT 0x1340#define AD5758_DIGITAL_DIAG_RESULTS 0x1441#define AD5758_ANALOG_DIAG_RESULTS 0x1542#define AD5758_STATUS 0x1643#define AD5758_CHIP_ID 0x1744#define AD5758_FREQ_MONITOR 0x1845#define AD5758_DEVICE_ID_0 0x1946#define AD5758_DEVICE_ID_1 0x1A47#define AD5758_DEVICE_ID_2 0x1B48#define AD5758_DEVICE_ID_3 0x1C49 50/* AD5758_DAC_CONFIG */51#define AD5758_DAC_CONFIG_RANGE_MSK GENMASK(3, 0)52#define AD5758_DAC_CONFIG_RANGE_MODE(x) (((x) & 0xF) << 0)53#define AD5758_DAC_CONFIG_INT_EN_MSK BIT(5)54#define AD5758_DAC_CONFIG_INT_EN_MODE(x) (((x) & 0x1) << 5)55#define AD5758_DAC_CONFIG_OUT_EN_MSK BIT(6)56#define AD5758_DAC_CONFIG_OUT_EN_MODE(x) (((x) & 0x1) << 6)57#define AD5758_DAC_CONFIG_SR_EN_MSK BIT(8)58#define AD5758_DAC_CONFIG_SR_EN_MODE(x) (((x) & 0x1) << 8)59#define AD5758_DAC_CONFIG_SR_CLOCK_MSK GENMASK(12, 9)60#define AD5758_DAC_CONFIG_SR_CLOCK_MODE(x) (((x) & 0xF) << 9)61#define AD5758_DAC_CONFIG_SR_STEP_MSK GENMASK(15, 13)62#define AD5758_DAC_CONFIG_SR_STEP_MODE(x) (((x) & 0x7) << 13)63 64/* AD5758_KEY */65#define AD5758_KEY_CODE_RESET_1 0x15FA66#define AD5758_KEY_CODE_RESET_2 0xAF5167#define AD5758_KEY_CODE_SINGLE_ADC_CONV 0x1ADC68#define AD5758_KEY_CODE_RESET_WDT 0x0D0669#define AD5758_KEY_CODE_CALIB_MEM_REFRESH 0xFCBA70 71/* AD5758_DCDC_CONFIG1 */72#define AD5758_DCDC_CONFIG1_DCDC_VPROG_MSK GENMASK(4, 0)73#define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x) (((x) & 0x1F) << 0)74#define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK GENMASK(6, 5)75#define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x) (((x) & 0x3) << 5)76 77/* AD5758_DCDC_CONFIG2 */78#define AD5758_DCDC_CONFIG2_ILIMIT_MSK GENMASK(3, 1)79#define AD5758_DCDC_CONFIG2_ILIMIT_MODE(x) (((x) & 0x7) << 1)80#define AD5758_DCDC_CONFIG2_INTR_SAT_3WI_MSK BIT(11)81#define AD5758_DCDC_CONFIG2_BUSY_3WI_MSK BIT(12)82 83/* AD5758_DIGITAL_DIAG_RESULTS */84#define AD5758_CAL_MEM_UNREFRESHED_MSK BIT(15)85 86/* AD5758_ADC_CONFIG */87#define AD5758_ADC_CONFIG_PPC_BUF_EN(x) (((x) & 0x1) << 11)88#define AD5758_ADC_CONFIG_PPC_BUF_MSK BIT(11)89 90#define AD5758_WR_FLAG_MSK(x) (0x80 | ((x) & 0x1F))91 92#define AD5758_FULL_SCALE_MICRO 65535000000ULL93 94struct ad5758_range {95 int reg;96 int min;97 int max;98};99 100/**101 * struct ad5758_state - driver instance specific data102 * @spi: spi_device103 * @lock: mutex lock104 * @gpio_reset: gpio descriptor for the reset line105 * @out_range: struct which stores the output range106 * @dc_dc_mode: variable which stores the mode of operation107 * @dc_dc_ilim: variable which stores the dc-to-dc converter current limit108 * @slew_time: variable which stores the target slew time109 * @pwr_down: variable which contains whether a channel is powered down or not110 * @d32: spi transfer buffers111 */112struct ad5758_state {113 struct spi_device *spi;114 struct mutex lock;115 struct gpio_desc *gpio_reset;116 struct ad5758_range out_range;117 unsigned int dc_dc_mode;118 unsigned int dc_dc_ilim;119 unsigned int slew_time;120 bool pwr_down;121 __be32 d32[3];122};123 124/*125 * Output ranges corresponding to bits [3:0] from DAC_CONFIG register126 * 0000: 0 V to 5 V voltage range127 * 0001: 0 V to 10 V voltage range128 * 0010: ±5 V voltage range129 * 0011: ±10 V voltage range130 * 1000: 0 mA to 20 mA current range131 * 1001: 0 mA to 24 mA current range132 * 1010: 4 mA to 20 mA current range133 * 1011: ±20 mA current range134 * 1100: ±24 mA current range135 * 1101: -1 mA to +22 mA current range136 */137enum ad5758_output_range {138 AD5758_RANGE_0V_5V,139 AD5758_RANGE_0V_10V,140 AD5758_RANGE_PLUSMINUS_5V,141 AD5758_RANGE_PLUSMINUS_10V,142 AD5758_RANGE_0mA_20mA = 8,143 AD5758_RANGE_0mA_24mA,144 AD5758_RANGE_4mA_24mA,145 AD5758_RANGE_PLUSMINUS_20mA,146 AD5758_RANGE_PLUSMINUS_24mA,147 AD5758_RANGE_MINUS_1mA_PLUS_22mA,148};149 150enum ad5758_dc_dc_mode {151 AD5758_DCDC_MODE_POWER_OFF,152 AD5758_DCDC_MODE_DPC_CURRENT,153 AD5758_DCDC_MODE_DPC_VOLTAGE,154 AD5758_DCDC_MODE_PPC_CURRENT,155};156 157static const struct ad5758_range ad5758_voltage_range[] = {158 { AD5758_RANGE_0V_5V, 0, 5000000 },159 { AD5758_RANGE_0V_10V, 0, 10000000 },160 { AD5758_RANGE_PLUSMINUS_5V, -5000000, 5000000 },161 { AD5758_RANGE_PLUSMINUS_10V, -10000000, 10000000 }162};163 164static const struct ad5758_range ad5758_current_range[] = {165 { AD5758_RANGE_0mA_20mA, 0, 20000},166 { AD5758_RANGE_0mA_24mA, 0, 24000 },167 { AD5758_RANGE_4mA_24mA, 4, 24000 },168 { AD5758_RANGE_PLUSMINUS_20mA, -20000, 20000 },169 { AD5758_RANGE_PLUSMINUS_24mA, -24000, 24000 },170 { AD5758_RANGE_MINUS_1mA_PLUS_22mA, -1000, 22000 },171};172 173static const int ad5758_sr_clk[16] = {174 240000, 200000, 150000, 128000, 64000, 32000, 16000, 8000, 4000, 2000,175 1000, 512, 256, 128, 64, 16176};177 178static const int ad5758_sr_step[8] = {179 4, 12, 64, 120, 256, 500, 1820, 2048180};181 182static const int ad5758_dc_dc_ilim[6] = {183 150000, 200000, 250000, 300000, 350000, 400000184};185 186static int ad5758_spi_reg_read(struct ad5758_state *st, unsigned int addr)187{188 struct spi_transfer t[] = {189 {190 .tx_buf = &st->d32[0],191 .len = 4,192 .cs_change = 1,193 }, {194 .tx_buf = &st->d32[1],195 .rx_buf = &st->d32[2],196 .len = 4,197 },198 };199 int ret;200 201 st->d32[0] = cpu_to_be32(202 (AD5758_WR_FLAG_MSK(AD5758_TWO_STAGE_READBACK_SELECT) << 24) |203 (addr << 8));204 st->d32[1] = cpu_to_be32(AD5758_WR_FLAG_MSK(AD5758_NOP) << 24);205 206 ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));207 if (ret < 0)208 return ret;209 210 return (be32_to_cpu(st->d32[2]) >> 8) & 0xFFFF;211}212 213static int ad5758_spi_reg_write(struct ad5758_state *st,214 unsigned int addr,215 unsigned int val)216{217 st->d32[0] = cpu_to_be32((AD5758_WR_FLAG_MSK(addr) << 24) |218 ((val & 0xFFFF) << 8));219 220 return spi_write(st->spi, &st->d32[0], sizeof(st->d32[0]));221}222 223static int ad5758_spi_write_mask(struct ad5758_state *st,224 unsigned int addr,225 unsigned long int mask,226 unsigned int val)227{228 int regval;229 230 regval = ad5758_spi_reg_read(st, addr);231 if (regval < 0)232 return regval;233 234 regval &= ~mask;235 regval |= val;236 237 return ad5758_spi_reg_write(st, addr, regval);238}239 240static int cmpfunc(const void *a, const void *b)241{242 return *(int *)a - *(int *)b;243}244 245static int ad5758_find_closest_match(const int *array,246 unsigned int size, int val)247{248 int i;249 250 for (i = 0; i < size; i++) {251 if (val <= array[i])252 return i;253 }254 255 return size - 1;256}257 258static int ad5758_wait_for_task_complete(struct ad5758_state *st,259 unsigned int reg,260 unsigned int mask)261{262 unsigned int timeout;263 int ret;264 265 timeout = 10;266 do {267 ret = ad5758_spi_reg_read(st, reg);268 if (ret < 0)269 return ret;270 271 if (!(ret & mask))272 return 0;273 274 usleep_range(100, 1000);275 } while (--timeout);276 277 dev_err(&st->spi->dev,278 "Error reading bit 0x%x in 0x%x register\n", mask, reg);279 280 return -EIO;281}282 283static int ad5758_calib_mem_refresh(struct ad5758_state *st)284{285 int ret;286 287 ret = ad5758_spi_reg_write(st, AD5758_KEY,288 AD5758_KEY_CODE_CALIB_MEM_REFRESH);289 if (ret < 0) {290 dev_err(&st->spi->dev,291 "Failed to initiate a calibration memory refresh\n");292 return ret;293 }294 295 /* Wait to allow time for the internal calibrations to complete */296 return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,297 AD5758_CAL_MEM_UNREFRESHED_MSK);298}299 300static int ad5758_soft_reset(struct ad5758_state *st)301{302 int ret;303 304 ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_1);305 if (ret < 0)306 return ret;307 308 ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_2);309 310 /* Perform a software reset and wait at least 100us */311 usleep_range(100, 1000);312 313 return ret;314}315 316static int ad5758_set_dc_dc_conv_mode(struct ad5758_state *st,317 enum ad5758_dc_dc_mode mode)318{319 int ret;320 321 /*322 * The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current323 * mode.324 */325 if (mode == AD5758_DCDC_MODE_PPC_CURRENT) {326 ret = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG,327 AD5758_ADC_CONFIG_PPC_BUF_MSK,328 AD5758_ADC_CONFIG_PPC_BUF_EN(1));329 if (ret < 0)330 return ret;331 }332 333 ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,334 AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,335 AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));336 if (ret < 0)337 return ret;338 339 /*340 * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.341 * This allows the 3-wire interface communication to complete.342 */343 ret = ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,344 AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);345 if (ret < 0)346 return ret;347 348 st->dc_dc_mode = mode;349 350 return ret;351}352 353static int ad5758_set_dc_dc_ilim(struct ad5758_state *st, unsigned int ilim)354{355 int ret;356 357 ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG2,358 AD5758_DCDC_CONFIG2_ILIMIT_MSK,359 AD5758_DCDC_CONFIG2_ILIMIT_MODE(ilim));360 if (ret < 0)361 return ret;362 /*363 * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.364 * This allows the 3-wire interface communication to complete.365 */366 return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,367 AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);368}369 370static int ad5758_slew_rate_set(struct ad5758_state *st,371 unsigned int sr_clk_idx,372 unsigned int sr_step_idx)373{374 unsigned int mode;375 unsigned long int mask;376 int ret;377 378 mask = AD5758_DAC_CONFIG_SR_EN_MSK |379 AD5758_DAC_CONFIG_SR_CLOCK_MSK |380 AD5758_DAC_CONFIG_SR_STEP_MSK;381 mode = AD5758_DAC_CONFIG_SR_EN_MODE(1) |382 AD5758_DAC_CONFIG_SR_STEP_MODE(sr_step_idx) |383 AD5758_DAC_CONFIG_SR_CLOCK_MODE(sr_clk_idx);384 385 ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG, mask, mode);386 if (ret < 0)387 return ret;388 389 /* Wait to allow time for the internal calibrations to complete */390 return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,391 AD5758_CAL_MEM_UNREFRESHED_MSK);392}393 394static int ad5758_slew_rate_config(struct ad5758_state *st)395{396 unsigned int sr_clk_idx, sr_step_idx;397 int i, res;398 s64 diff_new, diff_old;399 u64 sr_step, calc_slew_time;400 401 sr_clk_idx = 0;402 sr_step_idx = 0;403 diff_old = S64_MAX;404 /*405 * The slew time can be determined by using the formula:406 * Slew Time = (Full Scale Out / (Step Size x Update Clk Freq))407 * where Slew time is expressed in microseconds408 * Given the desired slew time, the following algorithm determines the409 * best match for the step size and the update clock frequency.410 */411 for (i = 0; i < ARRAY_SIZE(ad5758_sr_clk); i++) {412 /*413 * Go through each valid update clock freq and determine a raw414 * value for the step size by using the formula:415 * Step Size = Full Scale Out / (Update Clk Freq * Slew Time)416 */417 sr_step = AD5758_FULL_SCALE_MICRO;418 do_div(sr_step, ad5758_sr_clk[i]);419 do_div(sr_step, st->slew_time);420 /*421 * After a raw value for step size was determined, find the422 * closest valid match423 */424 res = ad5758_find_closest_match(ad5758_sr_step,425 ARRAY_SIZE(ad5758_sr_step),426 sr_step);427 /* Calculate the slew time */428 calc_slew_time = AD5758_FULL_SCALE_MICRO;429 do_div(calc_slew_time, ad5758_sr_step[res]);430 do_div(calc_slew_time, ad5758_sr_clk[i]);431 /*432 * Determine with how many microseconds the calculated slew time433 * is different from the desired slew time and store the diff434 * for the next iteration435 */436 diff_new = abs(st->slew_time - calc_slew_time);437 if (diff_new < diff_old) {438 diff_old = diff_new;439 sr_clk_idx = i;440 sr_step_idx = res;441 }442 }443 444 return ad5758_slew_rate_set(st, sr_clk_idx, sr_step_idx);445}446 447static int ad5758_set_out_range(struct ad5758_state *st, int range)448{449 int ret;450 451 ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,452 AD5758_DAC_CONFIG_RANGE_MSK,453 AD5758_DAC_CONFIG_RANGE_MODE(range));454 if (ret < 0)455 return ret;456 457 /* Wait to allow time for the internal calibrations to complete */458 return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,459 AD5758_CAL_MEM_UNREFRESHED_MSK);460}461 462static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)463{464 int ret;465 466 ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,467 AD5758_DAC_CONFIG_INT_EN_MSK,468 AD5758_DAC_CONFIG_INT_EN_MODE(enable));469 if (ret < 0)470 return ret;471 472 /* Wait to allow time for the internal calibrations to complete */473 return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,474 AD5758_CAL_MEM_UNREFRESHED_MSK);475}476 477static int ad5758_reset(struct ad5758_state *st)478{479 if (st->gpio_reset) {480 gpiod_set_value(st->gpio_reset, 0);481 usleep_range(100, 1000);482 gpiod_set_value(st->gpio_reset, 1);483 usleep_range(100, 1000);484 485 return 0;486 } else {487 /* Perform a software reset */488 return ad5758_soft_reset(st);489 }490}491 492static int ad5758_reg_access(struct iio_dev *indio_dev,493 unsigned int reg,494 unsigned int writeval,495 unsigned int *readval)496{497 struct ad5758_state *st = iio_priv(indio_dev);498 int ret;499 500 mutex_lock(&st->lock);501 if (readval) {502 ret = ad5758_spi_reg_read(st, reg);503 if (ret < 0) {504 mutex_unlock(&st->lock);505 return ret;506 }507 508 *readval = ret;509 ret = 0;510 } else {511 ret = ad5758_spi_reg_write(st, reg, writeval);512 }513 mutex_unlock(&st->lock);514 515 return ret;516}517 518static int ad5758_read_raw(struct iio_dev *indio_dev,519 struct iio_chan_spec const *chan,520 int *val, int *val2, long info)521{522 struct ad5758_state *st = iio_priv(indio_dev);523 int max, min, ret;524 525 switch (info) {526 case IIO_CHAN_INFO_RAW:527 mutex_lock(&st->lock);528 ret = ad5758_spi_reg_read(st, AD5758_DAC_INPUT);529 mutex_unlock(&st->lock);530 if (ret < 0)531 return ret;532 533 *val = ret;534 return IIO_VAL_INT;535 case IIO_CHAN_INFO_SCALE:536 min = st->out_range.min;537 max = st->out_range.max;538 *val = (max - min) / 1000;539 *val2 = 16;540 return IIO_VAL_FRACTIONAL_LOG2;541 case IIO_CHAN_INFO_OFFSET:542 min = st->out_range.min;543 max = st->out_range.max;544 *val = ((min * (1 << 16)) / (max - min)) / 1000;545 return IIO_VAL_INT;546 default:547 return -EINVAL;548 }549}550 551static int ad5758_write_raw(struct iio_dev *indio_dev,552 struct iio_chan_spec const *chan,553 int val, int val2, long info)554{555 struct ad5758_state *st = iio_priv(indio_dev);556 int ret;557 558 switch (info) {559 case IIO_CHAN_INFO_RAW:560 mutex_lock(&st->lock);561 ret = ad5758_spi_reg_write(st, AD5758_DAC_INPUT, val);562 mutex_unlock(&st->lock);563 return ret;564 default:565 return -EINVAL;566 }567}568 569static ssize_t ad5758_read_powerdown(struct iio_dev *indio_dev,570 uintptr_t priv,571 const struct iio_chan_spec *chan,572 char *buf)573{574 struct ad5758_state *st = iio_priv(indio_dev);575 576 return sysfs_emit(buf, "%d\n", st->pwr_down);577}578 579static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,580 uintptr_t priv,581 struct iio_chan_spec const *chan,582 const char *buf, size_t len)583{584 struct ad5758_state *st = iio_priv(indio_dev);585 bool pwr_down;586 unsigned int dac_config_mode, val;587 unsigned long int dac_config_msk;588 int ret;589 590 ret = kstrtobool(buf, &pwr_down);591 if (ret)592 return ret;593 594 mutex_lock(&st->lock);595 if (pwr_down)596 val = 0;597 else598 val = 1;599 600 dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) |601 AD5758_DAC_CONFIG_INT_EN_MODE(val);602 dac_config_msk = AD5758_DAC_CONFIG_OUT_EN_MSK |603 AD5758_DAC_CONFIG_INT_EN_MSK;604 605 ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,606 dac_config_msk,607 dac_config_mode);608 if (ret < 0)609 goto err_unlock;610 611 st->pwr_down = pwr_down;612 613err_unlock:614 mutex_unlock(&st->lock);615 616 return ret ? ret : len;617}618 619static const struct iio_info ad5758_info = {620 .read_raw = ad5758_read_raw,621 .write_raw = ad5758_write_raw,622 .debugfs_reg_access = &ad5758_reg_access,623};624 625static const struct iio_chan_spec_ext_info ad5758_ext_info[] = {626 {627 .name = "powerdown",628 .read = ad5758_read_powerdown,629 .write = ad5758_write_powerdown,630 .shared = IIO_SHARED_BY_TYPE,631 },632 { }633};634 635#define AD5758_DAC_CHAN(_chan_type) { \636 .type = (_chan_type), \637 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) | \638 BIT(IIO_CHAN_INFO_SCALE) | \639 BIT(IIO_CHAN_INFO_OFFSET), \640 .indexed = 1, \641 .output = 1, \642 .ext_info = ad5758_ext_info, \643}644 645static const struct iio_chan_spec ad5758_voltage_ch[] = {646 AD5758_DAC_CHAN(IIO_VOLTAGE)647};648 649static const struct iio_chan_spec ad5758_current_ch[] = {650 AD5758_DAC_CHAN(IIO_CURRENT)651};652 653static bool ad5758_is_valid_mode(enum ad5758_dc_dc_mode mode)654{655 switch (mode) {656 case AD5758_DCDC_MODE_DPC_CURRENT:657 case AD5758_DCDC_MODE_DPC_VOLTAGE:658 case AD5758_DCDC_MODE_PPC_CURRENT:659 return true;660 default:661 return false;662 }663}664 665static int ad5758_crc_disable(struct ad5758_state *st)666{667 unsigned int mask;668 669 mask = (AD5758_WR_FLAG_MSK(AD5758_DIGITAL_DIAG_CONFIG) << 24) | 0x5C3A;670 st->d32[0] = cpu_to_be32(mask);671 672 return spi_write(st->spi, &st->d32[0], 4);673}674 675static int ad5758_find_out_range(struct ad5758_state *st,676 const struct ad5758_range *range,677 unsigned int size,678 int min, int max)679{680 int i;681 682 for (i = 0; i < size; i++) {683 if ((min == range[i].min) && (max == range[i].max)) {684 st->out_range.reg = range[i].reg;685 st->out_range.min = range[i].min;686 st->out_range.max = range[i].max;687 688 return 0;689 }690 }691 692 return -EINVAL;693}694 695static int ad5758_parse_dt(struct ad5758_state *st)696{697 unsigned int tmp, tmparray[2], size;698 const struct ad5758_range *range;699 int *index, ret;700 701 st->dc_dc_ilim = 0;702 ret = device_property_read_u32(&st->spi->dev,703 "adi,dc-dc-ilim-microamp", &tmp);704 if (ret) {705 dev_dbg(&st->spi->dev,706 "Missing \"dc-dc-ilim-microamp\" property\n");707 } else {708 index = bsearch(&tmp, ad5758_dc_dc_ilim,709 ARRAY_SIZE(ad5758_dc_dc_ilim),710 sizeof(int), cmpfunc);711 if (!index)712 dev_dbg(&st->spi->dev, "dc-dc-ilim out of range\n");713 else714 st->dc_dc_ilim = index - ad5758_dc_dc_ilim;715 }716 717 ret = device_property_read_u32(&st->spi->dev, "adi,dc-dc-mode",718 &st->dc_dc_mode);719 if (ret) {720 dev_err(&st->spi->dev, "Missing \"dc-dc-mode\" property\n");721 return ret;722 }723 724 if (!ad5758_is_valid_mode(st->dc_dc_mode))725 return -EINVAL;726 727 if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE) {728 ret = device_property_read_u32_array(&st->spi->dev,729 "adi,range-microvolt",730 tmparray, 2);731 if (ret) {732 dev_err(&st->spi->dev,733 "Missing \"range-microvolt\" property\n");734 return ret;735 }736 range = ad5758_voltage_range;737 size = ARRAY_SIZE(ad5758_voltage_range);738 } else {739 ret = device_property_read_u32_array(&st->spi->dev,740 "adi,range-microamp",741 tmparray, 2);742 if (ret) {743 dev_err(&st->spi->dev,744 "Missing \"range-microamp\" property\n");745 return ret;746 }747 range = ad5758_current_range;748 size = ARRAY_SIZE(ad5758_current_range);749 }750 751 ret = ad5758_find_out_range(st, range, size, tmparray[0], tmparray[1]);752 if (ret) {753 dev_err(&st->spi->dev, "range invalid\n");754 return ret;755 }756 757 ret = device_property_read_u32(&st->spi->dev, "adi,slew-time-us", &tmp);758 if (ret) {759 dev_dbg(&st->spi->dev, "Missing \"slew-time-us\" property\n");760 st->slew_time = 0;761 } else {762 st->slew_time = tmp;763 }764 765 return 0;766}767 768static int ad5758_init(struct ad5758_state *st)769{770 int regval, ret;771 772 st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",773 GPIOD_OUT_HIGH);774 if (IS_ERR(st->gpio_reset))775 return PTR_ERR(st->gpio_reset);776 777 /* Disable CRC checks */778 ret = ad5758_crc_disable(st);779 if (ret < 0)780 return ret;781 782 /* Perform a reset */783 ret = ad5758_reset(st);784 if (ret < 0)785 return ret;786 787 /* Disable CRC checks */788 ret = ad5758_crc_disable(st);789 if (ret < 0)790 return ret;791 792 /* Perform a calibration memory refresh */793 ret = ad5758_calib_mem_refresh(st);794 if (ret < 0)795 return ret;796 797 regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);798 if (regval < 0)799 return regval;800 801 /* Clear all the error flags */802 ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);803 if (ret < 0)804 return ret;805 806 /* Set the dc-to-dc current limit */807 ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);808 if (ret < 0)809 return ret;810 811 /* Configure the dc-to-dc controller mode */812 ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);813 if (ret < 0)814 return ret;815 816 /* Configure the output range */817 ret = ad5758_set_out_range(st, st->out_range.reg);818 if (ret < 0)819 return ret;820 821 /* Enable Slew Rate Control, set the slew rate clock and step */822 if (st->slew_time) {823 ret = ad5758_slew_rate_config(st);824 if (ret < 0)825 return ret;826 }827 828 /* Power up the DAC and internal (INT) amplifiers */829 ret = ad5758_internal_buffers_en(st, 1);830 if (ret < 0)831 return ret;832 833 /* Enable VIOUT */834 return ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,835 AD5758_DAC_CONFIG_OUT_EN_MSK,836 AD5758_DAC_CONFIG_OUT_EN_MODE(1));837}838 839static int ad5758_probe(struct spi_device *spi)840{841 struct ad5758_state *st;842 struct iio_dev *indio_dev;843 int ret;844 845 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));846 if (!indio_dev)847 return -ENOMEM;848 849 st = iio_priv(indio_dev);850 spi_set_drvdata(spi, indio_dev);851 852 st->spi = spi;853 854 mutex_init(&st->lock);855 856 indio_dev->name = spi_get_device_id(spi)->name;857 indio_dev->info = &ad5758_info;858 indio_dev->modes = INDIO_DIRECT_MODE;859 indio_dev->num_channels = 1;860 861 ret = ad5758_parse_dt(st);862 if (ret < 0)863 return ret;864 865 if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE)866 indio_dev->channels = ad5758_voltage_ch;867 else868 indio_dev->channels = ad5758_current_ch;869 870 ret = ad5758_init(st);871 if (ret < 0) {872 dev_err(&spi->dev, "AD5758 init failed\n");873 return ret;874 }875 876 return devm_iio_device_register(&st->spi->dev, indio_dev);877}878 879static const struct spi_device_id ad5758_id[] = {880 { "ad5758", 0 },881 {}882};883MODULE_DEVICE_TABLE(spi, ad5758_id);884 885static const struct of_device_id ad5758_of_match[] = {886 { .compatible = "adi,ad5758" },887 { },888};889MODULE_DEVICE_TABLE(of, ad5758_of_match);890 891static struct spi_driver ad5758_driver = {892 .driver = {893 .name = KBUILD_MODNAME,894 .of_match_table = ad5758_of_match,895 },896 .probe = ad5758_probe,897 .id_table = ad5758_id,898};899 900module_spi_driver(ad5758_driver);901 902MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");903MODULE_DESCRIPTION("Analog Devices AD5758 DAC");904MODULE_LICENSE("GPL v2");905