// SPDX-License-Identifier: GPL-2.0-only /* * Analog devices AD5360, AD5361, AD5362, AD5363, AD5370, AD5371, AD5373 * multi-channel Digital to Analog Converters driver * * Copyright 2011 Analog Devices Inc.
*/
/** * struct ad5360_chip_info - chip specific information * @channel_template: channel specification template * @num_channels: number of channels * @channels_per_group: number of channels per group * @num_vrefs: number of vref supplies for the chip
*/
/** * struct ad5360_state - driver instance specific data * @spi: spi_device * @chip_info: chip model specific constants, available modes etc * @vref_reg: vref supply regulators * @ctrl: control register cache * @lock: lock to protect the data buffer during SPI ops * @data: spi transfer buffers
*/
/* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines.
*/ union {
__be32 d32;
u8 d8[4];
} data[2] __aligned(IIO_DMA_MINALIGN);
};
/* The first groups have their own vref, while the remaining groups
* share the last vref */
i = channel / st->chip_info->channels_per_group; if (i >= st->chip_info->num_vrefs)
i = st->chip_info->num_vrefs - 1;
case IIO_CHAN_INFO_OFFSET: if (val <= -max_val || val > 0) return -EINVAL;
val = -val;
/* offset is supposed to have the same scale as raw, but it * is always 14bits wide, so on a chip where the raw value has
* more bits, we need to shift offset. */
val >>= (chan->scan_type.realbits - 14);
/* There is one DAC offset register per vref. Changing one * channels offset will also change the offset for all other
* channels which share the same vref supply. */
ofs_index = ad5360_get_channel_vref_index(st, chan->channel); return ad5360_write(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
AD5360_REG_SF_OFS(ofs_index), val, 0); default: break;
}
return -EINVAL;
}
staticint ad5360_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long m)
{ struct ad5360_state *st = iio_priv(indio_dev); unsignedint ofs_index; int scale_uv; int ret;
switch (m) { case IIO_CHAN_INFO_RAW:
ret = ad5360_read(indio_dev, AD5360_READBACK_X1A,
chan->address); if (ret < 0) return ret;
*val = ret >> chan->scan_type.shift; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE:
scale_uv = ad5360_get_channel_vref(st, chan->channel); if (scale_uv < 0) return scale_uv;
/* vout = 4 * vref * dac_code */
*val = scale_uv * 4 / 1000;
*val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_CALIBBIAS:
ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
chan->address); if (ret < 0) return ret;
*val = ret; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBSCALE:
ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
chan->address); if (ret < 0) return ret;
*val = ret; return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET:
ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
ret = ad5360_read(indio_dev, AD5360_READBACK_SF,
AD5360_REG_SF_OFS(ofs_index)); if (ret < 0) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.