Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.11 473 lines 12 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog 4 * Converter 5 * 6 * Copyright 2011 Analog Devices Inc. 7 */ 8 9#include <linux/interrupt.h> 10#include <linux/fs.h> 11#include <linux/device.h> 12#include <linux/kernel.h> 13#include <linux/spi/spi.h> 14#include <linux/slab.h> 15#include <linux/sysfs.h> 16#include <linux/regulator/consumer.h> 17#include <linux/module.h> 18#include <linux/bitops.h> 19 20#include <linux/iio/iio.h> 21#include <linux/iio/sysfs.h> 22#include <linux/iio/dac/ad5791.h> 23 24#define AD5791_DAC_MASK GENMASK(19, 0) 25 26#define AD5791_CMD_READ BIT(23) 27#define AD5791_CMD_WRITE 0 28#define AD5791_ADDR(addr) ((addr) << 20) 29 30/* Registers */ 31#define AD5791_ADDR_NOOP 0 32#define AD5791_ADDR_DAC0 1 33#define AD5791_ADDR_CTRL 2 34#define AD5791_ADDR_CLRCODE 3 35#define AD5791_ADDR_SW_CTRL 4 36 37/* Control Register */ 38#define AD5791_CTRL_RBUF BIT(1) 39#define AD5791_CTRL_OPGND BIT(2) 40#define AD5791_CTRL_DACTRI BIT(3) 41#define AD5791_CTRL_BIN2SC BIT(4) 42#define AD5791_CTRL_SDODIS BIT(5) 43#define AD5761_CTRL_LINCOMP(x) ((x) << 6) 44 45#define AD5791_LINCOMP_0_10 0 46#define AD5791_LINCOMP_10_12 1 47#define AD5791_LINCOMP_12_16 2 48#define AD5791_LINCOMP_16_19 3 49#define AD5791_LINCOMP_19_20 12 50 51#define AD5780_LINCOMP_0_10 0 52#define AD5780_LINCOMP_10_20 12 53 54/* Software Control Register */ 55#define AD5791_SWCTRL_LDAC BIT(0) 56#define AD5791_SWCTRL_CLR BIT(1) 57#define AD5791_SWCTRL_RESET BIT(2) 58 59#define AD5791_DAC_PWRDN_6K 0 60#define AD5791_DAC_PWRDN_3STATE 1 61 62/** 63 * struct ad5791_chip_info - chip specific information 64 * @get_lin_comp: function pointer to the device specific function 65 */ 66 67struct ad5791_chip_info { 68 int (*get_lin_comp) (unsigned int span); 69}; 70 71/** 72 * struct ad5791_state - driver instance specific data 73 * @spi: spi_device 74 * @reg_vdd: positive supply regulator 75 * @reg_vss: negative supply regulator 76 * @chip_info: chip model specific constants 77 * @vref_mv: actual reference voltage used 78 * @vref_neg_mv: voltage of the negative supply 79 * @ctrl: control register cache 80 * @pwr_down_mode: current power down mode 81 * @pwr_down: true if device is powered down 82 * @data: spi transfer buffers 83 */ 84struct ad5791_state { 85 struct spi_device *spi; 86 struct regulator *reg_vdd; 87 struct regulator *reg_vss; 88 const struct ad5791_chip_info *chip_info; 89 unsigned short vref_mv; 90 unsigned int vref_neg_mv; 91 unsigned ctrl; 92 unsigned pwr_down_mode; 93 bool pwr_down; 94 95 union { 96 __be32 d32; 97 u8 d8[4]; 98 } data[3] __aligned(IIO_DMA_MINALIGN); 99}; 100 101enum ad5791_supported_device_ids { 102 ID_AD5760, 103 ID_AD5780, 104 ID_AD5781, 105 ID_AD5791, 106}; 107 108static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val) 109{ 110 st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE | 111 AD5791_ADDR(addr) | 112 (val & AD5791_DAC_MASK)); 113 114 return spi_write(st->spi, &st->data[0].d8[1], 3); 115} 116 117static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val) 118{ 119 int ret; 120 struct spi_transfer xfers[] = { 121 { 122 .tx_buf = &st->data[0].d8[1], 123 .bits_per_word = 8, 124 .len = 3, 125 .cs_change = 1, 126 }, { 127 .tx_buf = &st->data[1].d8[1], 128 .rx_buf = &st->data[2].d8[1], 129 .bits_per_word = 8, 130 .len = 3, 131 }, 132 }; 133 134 st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ | 135 AD5791_ADDR(addr)); 136 st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP)); 137 138 ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); 139 140 *val = be32_to_cpu(st->data[2].d32); 141 142 return ret; 143} 144 145static const char * const ad5791_powerdown_modes[] = { 146 "6kohm_to_gnd", 147 "three_state", 148}; 149 150static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev, 151 const struct iio_chan_spec *chan) 152{ 153 struct ad5791_state *st = iio_priv(indio_dev); 154 155 return st->pwr_down_mode; 156} 157 158static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev, 159 const struct iio_chan_spec *chan, unsigned int mode) 160{ 161 struct ad5791_state *st = iio_priv(indio_dev); 162 163 st->pwr_down_mode = mode; 164 165 return 0; 166} 167 168static const struct iio_enum ad5791_powerdown_mode_enum = { 169 .items = ad5791_powerdown_modes, 170 .num_items = ARRAY_SIZE(ad5791_powerdown_modes), 171 .get = ad5791_get_powerdown_mode, 172 .set = ad5791_set_powerdown_mode, 173}; 174 175static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev, 176 uintptr_t private, const struct iio_chan_spec *chan, char *buf) 177{ 178 struct ad5791_state *st = iio_priv(indio_dev); 179 180 return sysfs_emit(buf, "%d\n", st->pwr_down); 181} 182 183static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, 184 uintptr_t private, const struct iio_chan_spec *chan, const char *buf, 185 size_t len) 186{ 187 bool pwr_down; 188 int ret; 189 struct ad5791_state *st = iio_priv(indio_dev); 190 191 ret = kstrtobool(buf, &pwr_down); 192 if (ret) 193 return ret; 194 195 if (!pwr_down) { 196 st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); 197 } else { 198 if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K) 199 st->ctrl |= AD5791_CTRL_OPGND; 200 else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE) 201 st->ctrl |= AD5791_CTRL_DACTRI; 202 } 203 st->pwr_down = pwr_down; 204 205 ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl); 206 207 return ret ? ret : len; 208} 209 210static int ad5791_get_lin_comp(unsigned int span) 211{ 212 if (span <= 10000) 213 return AD5791_LINCOMP_0_10; 214 else if (span <= 12000) 215 return AD5791_LINCOMP_10_12; 216 else if (span <= 16000) 217 return AD5791_LINCOMP_12_16; 218 else if (span <= 19000) 219 return AD5791_LINCOMP_16_19; 220 else 221 return AD5791_LINCOMP_19_20; 222} 223 224static int ad5780_get_lin_comp(unsigned int span) 225{ 226 if (span <= 10000) 227 return AD5780_LINCOMP_0_10; 228 else 229 return AD5780_LINCOMP_10_20; 230} 231static const struct ad5791_chip_info ad5791_chip_info_tbl[] = { 232 [ID_AD5760] = { 233 .get_lin_comp = ad5780_get_lin_comp, 234 }, 235 [ID_AD5780] = { 236 .get_lin_comp = ad5780_get_lin_comp, 237 }, 238 [ID_AD5781] = { 239 .get_lin_comp = ad5791_get_lin_comp, 240 }, 241 [ID_AD5791] = { 242 .get_lin_comp = ad5791_get_lin_comp, 243 }, 244}; 245 246static int ad5791_read_raw(struct iio_dev *indio_dev, 247 struct iio_chan_spec const *chan, 248 int *val, 249 int *val2, 250 long m) 251{ 252 struct ad5791_state *st = iio_priv(indio_dev); 253 u64 val64; 254 int ret; 255 256 switch (m) { 257 case IIO_CHAN_INFO_RAW: 258 ret = ad5791_spi_read(st, chan->address, val); 259 if (ret) 260 return ret; 261 *val &= AD5791_DAC_MASK; 262 *val >>= chan->scan_type.shift; 263 return IIO_VAL_INT; 264 case IIO_CHAN_INFO_SCALE: 265 *val = st->vref_mv; 266 *val2 = (1 << chan->scan_type.realbits) - 1; 267 return IIO_VAL_FRACTIONAL; 268 case IIO_CHAN_INFO_OFFSET: 269 val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits); 270 do_div(val64, st->vref_mv); 271 *val = -val64; 272 return IIO_VAL_INT; 273 default: 274 return -EINVAL; 275 } 276 277}; 278 279static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { 280 { 281 .name = "powerdown", 282 .shared = IIO_SHARED_BY_TYPE, 283 .read = ad5791_read_dac_powerdown, 284 .write = ad5791_write_dac_powerdown, 285 }, 286 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, 287 &ad5791_powerdown_mode_enum), 288 IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ad5791_powerdown_mode_enum), 289 { }, 290}; 291 292#define AD5791_CHAN(bits, _shift) { \ 293 .type = IIO_VOLTAGE, \ 294 .output = 1, \ 295 .indexed = 1, \ 296 .address = AD5791_ADDR_DAC0, \ 297 .channel = 0, \ 298 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 299 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 300 BIT(IIO_CHAN_INFO_OFFSET), \ 301 .scan_type = { \ 302 .sign = 'u', \ 303 .realbits = (bits), \ 304 .storagebits = 24, \ 305 .shift = (_shift), \ 306 }, \ 307 .ext_info = ad5791_ext_info, \ 308} 309 310static const struct iio_chan_spec ad5791_channels[] = { 311 [ID_AD5760] = AD5791_CHAN(16, 4), 312 [ID_AD5780] = AD5791_CHAN(18, 2), 313 [ID_AD5781] = AD5791_CHAN(18, 2), 314 [ID_AD5791] = AD5791_CHAN(20, 0) 315}; 316 317static int ad5791_write_raw(struct iio_dev *indio_dev, 318 struct iio_chan_spec const *chan, 319 int val, 320 int val2, 321 long mask) 322{ 323 struct ad5791_state *st = iio_priv(indio_dev); 324 325 switch (mask) { 326 case IIO_CHAN_INFO_RAW: 327 val &= GENMASK(chan->scan_type.realbits - 1, 0); 328 val <<= chan->scan_type.shift; 329 330 return ad5791_spi_write(st, chan->address, val); 331 332 default: 333 return -EINVAL; 334 } 335} 336 337static const struct iio_info ad5791_info = { 338 .read_raw = &ad5791_read_raw, 339 .write_raw = &ad5791_write_raw, 340}; 341 342static int ad5791_probe(struct spi_device *spi) 343{ 344 struct ad5791_platform_data *pdata = spi->dev.platform_data; 345 struct iio_dev *indio_dev; 346 struct ad5791_state *st; 347 int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; 348 bool use_rbuf_gain2; 349 350 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 351 if (!indio_dev) 352 return -ENOMEM; 353 st = iio_priv(indio_dev); 354 st->reg_vdd = devm_regulator_get(&spi->dev, "vdd"); 355 if (!IS_ERR(st->reg_vdd)) { 356 ret = regulator_enable(st->reg_vdd); 357 if (ret) 358 return ret; 359 360 ret = regulator_get_voltage(st->reg_vdd); 361 if (ret < 0) 362 goto error_disable_reg_pos; 363 364 pos_voltage_uv = ret; 365 } 366 367 st->reg_vss = devm_regulator_get(&spi->dev, "vss"); 368 if (!IS_ERR(st->reg_vss)) { 369 ret = regulator_enable(st->reg_vss); 370 if (ret) 371 goto error_disable_reg_pos; 372 373 ret = regulator_get_voltage(st->reg_vss); 374 if (ret < 0) 375 goto error_disable_reg_neg; 376 377 neg_voltage_uv = ret; 378 } 379 380 st->pwr_down = true; 381 st->spi = spi; 382 383 if (pdata) 384 use_rbuf_gain2 = pdata->use_rbuf_gain2; 385 else 386 use_rbuf_gain2 = device_property_read_bool(&spi->dev, 387 "adi,rbuf-gain2-en"); 388 389 if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) { 390 st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000; 391 st->vref_neg_mv = neg_voltage_uv / 1000; 392 } else if (pdata) { 393 st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv; 394 st->vref_neg_mv = pdata->vref_neg_mv; 395 } else { 396 dev_warn(&spi->dev, "reference voltage unspecified\n"); 397 } 398 399 ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); 400 if (ret) 401 goto error_disable_reg_neg; 402 403 st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi) 404 ->driver_data]; 405 406 407 st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv)) 408 | (use_rbuf_gain2 ? 0 : AD5791_CTRL_RBUF) | 409 AD5791_CTRL_BIN2SC; 410 411 ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl | 412 AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); 413 if (ret) 414 goto error_disable_reg_neg; 415 416 spi_set_drvdata(spi, indio_dev); 417 indio_dev->info = &ad5791_info; 418 indio_dev->modes = INDIO_DIRECT_MODE; 419 indio_dev->channels 420 = &ad5791_channels[spi_get_device_id(spi)->driver_data]; 421 indio_dev->num_channels = 1; 422 indio_dev->name = spi_get_device_id(st->spi)->name; 423 ret = iio_device_register(indio_dev); 424 if (ret) 425 goto error_disable_reg_neg; 426 427 return 0; 428 429error_disable_reg_neg: 430 if (!IS_ERR(st->reg_vss)) 431 regulator_disable(st->reg_vss); 432error_disable_reg_pos: 433 if (!IS_ERR(st->reg_vdd)) 434 regulator_disable(st->reg_vdd); 435 return ret; 436} 437 438static void ad5791_remove(struct spi_device *spi) 439{ 440 struct iio_dev *indio_dev = spi_get_drvdata(spi); 441 struct ad5791_state *st = iio_priv(indio_dev); 442 443 iio_device_unregister(indio_dev); 444 if (!IS_ERR(st->reg_vdd)) 445 regulator_disable(st->reg_vdd); 446 447 if (!IS_ERR(st->reg_vss)) 448 regulator_disable(st->reg_vss); 449} 450 451static const struct spi_device_id ad5791_id[] = { 452 {"ad5760", ID_AD5760}, 453 {"ad5780", ID_AD5780}, 454 {"ad5781", ID_AD5781}, 455 {"ad5790", ID_AD5791}, 456 {"ad5791", ID_AD5791}, 457 {} 458}; 459MODULE_DEVICE_TABLE(spi, ad5791_id); 460 461static struct spi_driver ad5791_driver = { 462 .driver = { 463 .name = "ad5791", 464 }, 465 .probe = ad5791_probe, 466 .remove = ad5791_remove, 467 .id_table = ad5791_id, 468}; 469module_spi_driver(ad5791_driver); 470 471MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); 472MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC"); 473MODULE_LICENSE("GPL v2");