430 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * AD5721, AD5721R, AD5761, AD5761R, Voltage Output Digital to Analog Converter4 *5 * Copyright 2016 Qtechnology A/S6 * 2016 Ricardo Ribalda <ribalda@kernel.org>7 */8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/spi/spi.h>11#include <linux/bitops.h>12#include <linux/iio/iio.h>13#include <linux/iio/sysfs.h>14#include <linux/regulator/consumer.h>15#include <linux/platform_data/ad5761.h>16 17#define AD5761_ADDR(addr) ((addr & 0xf) << 16)18#define AD5761_ADDR_NOOP 0x019#define AD5761_ADDR_DAC_WRITE 0x320#define AD5761_ADDR_CTRL_WRITE_REG 0x421#define AD5761_ADDR_SW_DATA_RESET 0x722#define AD5761_ADDR_DAC_READ 0xb23#define AD5761_ADDR_CTRL_READ_REG 0xc24#define AD5761_ADDR_SW_FULL_RESET 0xf25 26#define AD5761_CTRL_USE_INTVREF BIT(5)27#define AD5761_CTRL_ETS BIT(6)28 29/**30 * struct ad5761_chip_info - chip specific information31 * @int_vref: Value of the internal reference voltage in mV - 0 if external32 * reference voltage is used33 * @channel: channel specification34*/35 36struct ad5761_chip_info {37 unsigned long int_vref;38 const struct iio_chan_spec channel;39};40 41struct ad5761_range_params {42 int m;43 int c;44};45 46enum ad5761_supported_device_ids {47 ID_AD5721,48 ID_AD5721R,49 ID_AD5761,50 ID_AD5761R,51};52 53/**54 * struct ad5761_state - driver instance specific data55 * @spi: spi_device56 * @vref_reg: reference voltage regulator57 * @use_intref: true when the internal voltage reference is used58 * @vref: actual voltage reference in mVolts59 * @range: output range mode used60 * @lock: lock to protect the data buffer during SPI ops61 * @data: cache aligned spi buffer62 */63struct ad5761_state {64 struct spi_device *spi;65 struct regulator *vref_reg;66 struct mutex lock;67 68 bool use_intref;69 int vref;70 enum ad5761_voltage_range range;71 72 /*73 * DMA (thus cache coherency maintenance) may require the74 * transfer buffers to live in their own cache lines.75 */76 union {77 __be32 d32;78 u8 d8[4];79 } data[3] __aligned(IIO_DMA_MINALIGN);80};81 82static const struct ad5761_range_params ad5761_range_params[] = {83 [AD5761_VOLTAGE_RANGE_M10V_10V] = {84 .m = 80,85 .c = 40,86 },87 [AD5761_VOLTAGE_RANGE_0V_10V] = {88 .m = 40,89 .c = 0,90 },91 [AD5761_VOLTAGE_RANGE_M5V_5V] = {92 .m = 40,93 .c = 20,94 },95 [AD5761_VOLTAGE_RANGE_0V_5V] = {96 .m = 20,97 .c = 0,98 },99 [AD5761_VOLTAGE_RANGE_M2V5_7V5] = {100 .m = 40,101 .c = 10,102 },103 [AD5761_VOLTAGE_RANGE_M3V_3V] = {104 .m = 24,105 .c = 12,106 },107 [AD5761_VOLTAGE_RANGE_0V_16V] = {108 .m = 64,109 .c = 0,110 },111 [AD5761_VOLTAGE_RANGE_0V_20V] = {112 .m = 80,113 .c = 0,114 },115};116 117static int _ad5761_spi_write(struct ad5761_state *st, u8 addr, u16 val)118{119 st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr) | val);120 121 return spi_write(st->spi, &st->data[0].d8[1], 3);122}123 124static int ad5761_spi_write(struct iio_dev *indio_dev, u8 addr, u16 val)125{126 struct ad5761_state *st = iio_priv(indio_dev);127 int ret;128 129 mutex_lock(&st->lock);130 ret = _ad5761_spi_write(st, addr, val);131 mutex_unlock(&st->lock);132 133 return ret;134}135 136static int _ad5761_spi_read(struct ad5761_state *st, u8 addr, u16 *val)137{138 int ret;139 struct spi_transfer xfers[] = {140 {141 .tx_buf = &st->data[0].d8[1],142 .bits_per_word = 8,143 .len = 3,144 .cs_change = true,145 }, {146 .tx_buf = &st->data[1].d8[1],147 .rx_buf = &st->data[2].d8[1],148 .bits_per_word = 8,149 .len = 3,150 },151 };152 153 st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr));154 st->data[1].d32 = cpu_to_be32(AD5761_ADDR(AD5761_ADDR_NOOP));155 156 ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));157 158 *val = be32_to_cpu(st->data[2].d32);159 160 return ret;161}162 163static int ad5761_spi_read(struct iio_dev *indio_dev, u8 addr, u16 *val)164{165 struct ad5761_state *st = iio_priv(indio_dev);166 int ret;167 168 mutex_lock(&st->lock);169 ret = _ad5761_spi_read(st, addr, val);170 mutex_unlock(&st->lock);171 172 return ret;173}174 175static int ad5761_spi_set_range(struct ad5761_state *st,176 enum ad5761_voltage_range range)177{178 u16 aux;179 int ret;180 181 aux = (range & 0x7) | AD5761_CTRL_ETS;182 183 if (st->use_intref)184 aux |= AD5761_CTRL_USE_INTVREF;185 186 ret = _ad5761_spi_write(st, AD5761_ADDR_SW_FULL_RESET, 0);187 if (ret)188 return ret;189 190 ret = _ad5761_spi_write(st, AD5761_ADDR_CTRL_WRITE_REG, aux);191 if (ret)192 return ret;193 194 st->range = range;195 196 return 0;197}198 199static int ad5761_read_raw(struct iio_dev *indio_dev,200 struct iio_chan_spec const *chan,201 int *val,202 int *val2,203 long mask)204{205 struct ad5761_state *st;206 int ret;207 u16 aux;208 209 switch (mask) {210 case IIO_CHAN_INFO_RAW:211 ret = ad5761_spi_read(indio_dev, AD5761_ADDR_DAC_READ, &aux);212 if (ret)213 return ret;214 *val = aux >> chan->scan_type.shift;215 return IIO_VAL_INT;216 case IIO_CHAN_INFO_SCALE:217 st = iio_priv(indio_dev);218 *val = st->vref * ad5761_range_params[st->range].m;219 *val /= 10;220 *val2 = chan->scan_type.realbits;221 return IIO_VAL_FRACTIONAL_LOG2;222 case IIO_CHAN_INFO_OFFSET:223 st = iio_priv(indio_dev);224 *val = -(1 << chan->scan_type.realbits);225 *val *= ad5761_range_params[st->range].c;226 *val /= ad5761_range_params[st->range].m;227 return IIO_VAL_INT;228 default:229 return -EINVAL;230 }231}232 233static int ad5761_write_raw(struct iio_dev *indio_dev,234 struct iio_chan_spec const *chan,235 int val,236 int val2,237 long mask)238{239 u16 aux;240 241 if (mask != IIO_CHAN_INFO_RAW)242 return -EINVAL;243 244 if (val2 || (val << chan->scan_type.shift) > 0xffff || val < 0)245 return -EINVAL;246 247 aux = val << chan->scan_type.shift;248 249 return ad5761_spi_write(indio_dev, AD5761_ADDR_DAC_WRITE, aux);250}251 252static const struct iio_info ad5761_info = {253 .read_raw = &ad5761_read_raw,254 .write_raw = &ad5761_write_raw,255};256 257#define AD5761_CHAN(_bits) { \258 .type = IIO_VOLTAGE, \259 .output = 1, \260 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \261 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \262 BIT(IIO_CHAN_INFO_OFFSET), \263 .scan_type = { \264 .sign = 'u', \265 .realbits = (_bits), \266 .storagebits = 16, \267 .shift = 16 - (_bits), \268 }, \269}270 271static const struct ad5761_chip_info ad5761_chip_infos[] = {272 [ID_AD5721] = {273 .int_vref = 0,274 .channel = AD5761_CHAN(12),275 },276 [ID_AD5721R] = {277 .int_vref = 2500,278 .channel = AD5761_CHAN(12),279 },280 [ID_AD5761] = {281 .int_vref = 0,282 .channel = AD5761_CHAN(16),283 },284 [ID_AD5761R] = {285 .int_vref = 2500,286 .channel = AD5761_CHAN(16),287 },288};289 290static int ad5761_get_vref(struct ad5761_state *st,291 const struct ad5761_chip_info *chip_info)292{293 int ret;294 295 st->vref_reg = devm_regulator_get_optional(&st->spi->dev, "vref");296 if (PTR_ERR(st->vref_reg) == -ENODEV) {297 /* Use Internal regulator */298 if (!chip_info->int_vref) {299 dev_err(&st->spi->dev,300 "Voltage reference not found\n");301 return -EIO;302 }303 304 st->use_intref = true;305 st->vref = chip_info->int_vref;306 return 0;307 }308 309 if (IS_ERR(st->vref_reg)) {310 dev_err(&st->spi->dev,311 "Error getting voltage reference regulator\n");312 return PTR_ERR(st->vref_reg);313 }314 315 ret = regulator_enable(st->vref_reg);316 if (ret) {317 dev_err(&st->spi->dev,318 "Failed to enable voltage reference\n");319 return ret;320 }321 322 ret = regulator_get_voltage(st->vref_reg);323 if (ret < 0) {324 dev_err(&st->spi->dev,325 "Failed to get voltage reference value\n");326 goto disable_regulator_vref;327 }328 329 if (ret < 2000000 || ret > 3000000) {330 dev_warn(&st->spi->dev,331 "Invalid external voltage ref. value %d uV\n", ret);332 ret = -EIO;333 goto disable_regulator_vref;334 }335 336 st->vref = ret / 1000;337 st->use_intref = false;338 339 return 0;340 341disable_regulator_vref:342 regulator_disable(st->vref_reg);343 st->vref_reg = NULL;344 return ret;345}346 347static int ad5761_probe(struct spi_device *spi)348{349 struct iio_dev *iio_dev;350 struct ad5761_state *st;351 int ret;352 const struct ad5761_chip_info *chip_info =353 &ad5761_chip_infos[spi_get_device_id(spi)->driver_data];354 enum ad5761_voltage_range voltage_range = AD5761_VOLTAGE_RANGE_0V_5V;355 struct ad5761_platform_data *pdata = dev_get_platdata(&spi->dev);356 357 iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));358 if (!iio_dev)359 return -ENOMEM;360 361 st = iio_priv(iio_dev);362 363 st->spi = spi;364 spi_set_drvdata(spi, iio_dev);365 366 ret = ad5761_get_vref(st, chip_info);367 if (ret)368 return ret;369 370 if (pdata)371 voltage_range = pdata->voltage_range;372 373 mutex_init(&st->lock);374 375 ret = ad5761_spi_set_range(st, voltage_range);376 if (ret)377 goto disable_regulator_err;378 379 iio_dev->info = &ad5761_info;380 iio_dev->modes = INDIO_DIRECT_MODE;381 iio_dev->channels = &chip_info->channel;382 iio_dev->num_channels = 1;383 iio_dev->name = spi_get_device_id(st->spi)->name;384 ret = iio_device_register(iio_dev);385 if (ret)386 goto disable_regulator_err;387 388 return 0;389 390disable_regulator_err:391 if (!IS_ERR_OR_NULL(st->vref_reg))392 regulator_disable(st->vref_reg);393 394 return ret;395}396 397static void ad5761_remove(struct spi_device *spi)398{399 struct iio_dev *iio_dev = spi_get_drvdata(spi);400 struct ad5761_state *st = iio_priv(iio_dev);401 402 iio_device_unregister(iio_dev);403 404 if (!IS_ERR_OR_NULL(st->vref_reg))405 regulator_disable(st->vref_reg);406}407 408static const struct spi_device_id ad5761_id[] = {409 {"ad5721", ID_AD5721},410 {"ad5721r", ID_AD5721R},411 {"ad5761", ID_AD5761},412 {"ad5761r", ID_AD5761R},413 {}414};415MODULE_DEVICE_TABLE(spi, ad5761_id);416 417static struct spi_driver ad5761_driver = {418 .driver = {419 .name = "ad5761",420 },421 .probe = ad5761_probe,422 .remove = ad5761_remove,423 .id_table = ad5761_id,424};425module_spi_driver(ad5761_driver);426 427MODULE_AUTHOR("Ricardo Ribalda <ribalda@kernel.org>");428MODULE_DESCRIPTION("Analog Devices AD5721, AD5721R, AD5761, AD5761R driver");429MODULE_LICENSE("GPL v2");430