struct ad7476_chip_info { unsignedint int_vref_uv; struct iio_chan_spec channel[2]; /* channels used when convst gpio is defined */ struct iio_chan_spec convst_channel[2]; void (*reset)(struct ad7476_state *); bool has_vref; bool has_vdrive;
};
struct ad7476_state { struct spi_device *spi; conststruct ad7476_chip_info *chip_info; struct regulator *ref_reg; struct gpio_desc *convst_gpio; struct spi_transfer xfer; struct spi_message msg; /* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Make the buffer large enough for one 16 bit sample and one 64 bit * aligned 64 bit timestamp.
*/ unsignedchar data[ALIGN(2, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN);
};
staticvoid ad7091_reset(struct ad7476_state *st)
{ /* Any transfers with 8 scl cycles will reset the device */
spi_read(st->spi, st->data, 1);
}
staticint ad7476_scan_direct(struct ad7476_state *st)
{ int ret;
ad7091_convst(st);
ret = spi_sync(st->spi, &st->msg); if (ret) return ret;
return be16_to_cpup((__be16 *)st->data);
}
staticint ad7476_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long m)
{ int ret; struct ad7476_state *st = iio_priv(indio_dev); int scale_uv;
switch (m) { case IIO_CHAN_INFO_RAW: if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
ret = ad7476_scan_direct(st);
iio_device_release_direct(indio_dev);
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM;
st = iio_priv(indio_dev);
st->chip_info =
&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
reg = devm_regulator_get(&spi->dev, "vcc"); if (IS_ERR(reg)) return PTR_ERR(reg);
ret = regulator_enable(reg); if (ret) return ret;
ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable, reg); if (ret) return ret;
/* Either vcc or vref (below) as appropriate */ if (!st->chip_info->int_vref_uv)
st->ref_reg = reg;
if (st->chip_info->has_vref) {
/* If a device has an internal reference vref is optional */ if (st->chip_info->int_vref_uv) {
reg = devm_regulator_get_optional(&spi->dev, "vref"); if (IS_ERR(reg) && (PTR_ERR(reg) != -ENODEV)) return PTR_ERR(reg);
} else {
reg = devm_regulator_get(&spi->dev, "vref"); if (IS_ERR(reg)) return PTR_ERR(reg);
}
if (!IS_ERR(reg)) {
ret = regulator_enable(reg); if (ret) return ret;
ret = devm_add_action_or_reset(&spi->dev,
ad7476_reg_disable,
reg); if (ret) return ret;
st->ref_reg = reg;
} else { /* * Can only get here if device supports both internal * and external reference, but the regulator connected * to the external reference is not connected. * Set the reference regulator pointer to NULL to * indicate this.
*/
st->ref_reg = NULL;
}
}
if (st->chip_info->has_vdrive) {
ret = devm_regulator_get_enable(&spi->dev, "vdrive"); if (ret) return ret;
}
st->convst_gpio = devm_gpiod_get_optional(&spi->dev, "adi,conversion-start",
GPIOD_OUT_LOW); if (IS_ERR(st->convst_gpio)) return PTR_ERR(st->convst_gpio);
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.