staticint ad4851_scale_fill(struct iio_dev *indio_dev)
{ struct ad4851_state *st = iio_priv(indio_dev); unsignedint i, val1, val2; int ret;
for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_unipolar); i++) {
ret = __ad4851_get_scale(indio_dev,
ad4851_scale_avail_unipolar[i],
&val1, &val2); if (ret) return ret;
for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_bipolar); i++) {
ret = __ad4851_get_scale(indio_dev,
ad4851_scale_avail_bipolar[i],
&val1, &val2); if (ret) return ret;
if (osr == 1) {
ret = regmap_clear_bits(st->regmap, AD4851_REG_OVERSAMPLE,
AD4851_OS_EN_MSK); if (ret) return ret;
} else {
val = ad4851_osr_to_regval(osr); if (val < 0) return -EINVAL;
ret = regmap_update_bits(st->regmap, AD4851_REG_OVERSAMPLE,
AD4851_OS_EN_MSK |
AD4851_OS_RATIO_MSK,
FIELD_PREP(AD4851_OS_EN_MSK, 1) |
FIELD_PREP(AD4851_OS_RATIO_MSK, val)); if (ret) return ret;
}
/* Channel is ignored by the backend being used here */
ret = iio_backend_oversampling_ratio_set(st->back, 0, osr); if (ret) return ret;
switch (st->info->resolution) { case 20: switch (osr) { case 0: return -EINVAL; case 1:
val = 20; break; default:
val = 24; break;
} break; case 16:
val = 16; break; default: return -EINVAL;
}
ret = iio_backend_data_size_set(st->back, val); if (ret) return ret;
if (osr == 1 || st->info->resolution == 16) {
ret = regmap_clear_bits(st->regmap, AD4851_REG_PACKET,
AD4851_PACKET_FORMAT_MASK); if (ret) return ret;
st->resolution_boost_enabled = false;
} else {
ret = regmap_update_bits(st->regmap, AD4851_REG_PACKET,
AD4851_PACKET_FORMAT_MASK,
FIELD_PREP(AD4851_PACKET_FORMAT_MASK, 1)); if (ret) return ret;
st->resolution_boost_enabled = true;
}
if (st->osr != osr) {
ret = ad4851_scale_fill(indio_dev); if (ret) return ret;
ret = iio_backend_interface_type_get(st->back, &interface_type); if (ret) return ret;
switch (interface_type) { case IIO_BACKEND_INTERFACE_SERIAL_CMOS:
num_lanes = indio_dev->num_channels; break; case IIO_BACKEND_INTERFACE_SERIAL_LVDS:
num_lanes = 1; break; default: return -EINVAL;
}
if (st->info->resolution == 16) {
ret = iio_backend_data_size_set(st->back, 24); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_PACKET,
AD4851_TEST_PAT | AD4857_PACKET_SIZE_24); if (ret) return ret;
} else {
ret = iio_backend_data_size_set(st->back, 32); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_PACKET,
AD4851_TEST_PAT | AD4858_PACKET_SIZE_32); if (ret) return ret;
}
for (i = 0; i < indio_dev->num_channels; i++) {
ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_0(i),
AD4851_TESTPAT_0_DEFAULT); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_1(i),
AD4851_TESTPAT_1_DEFAULT); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_2(i),
AD4851_TESTPAT_2_DEFAULT); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_3(i),
AD4851_TESTPAT_3_DEFAULT(i)); if (ret) return ret;
ret = iio_backend_chan_enable(st->back,
indio_dev->channels[i].channel); if (ret) return ret;
}
for (i = 0; i < num_lanes; i++) { for (delay = 0; delay < AD4851_MAX_IODELAY; delay++) {
ret = iio_backend_iodelay_set(st->back, i, delay); if (ret) return ret;
ret = iio_backend_chan_status(st->back, i, &status); if (ret) return ret;
staticint ad4851_get_calibbias(struct ad4851_state *st, int ch, int *val)
{ unsignedint lsb, mid, msb; int ret;
guard(mutex)(&st->lock); /* * After testing, the bulk_write operations doesn't work as expected * here since the cs needs to be raised after each byte transaction.
*/
ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MSB(ch), &msb); if (ret) return ret;
ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), &mid); if (ret) return ret;
ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), &lsb); if (ret) return ret;
guard(mutex)(&st->lock); /* * After testing, the bulk_write operations doesn't work as expected * here since the cs needs to be raised after each byte transaction.
*/
ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), buf[2]); if (ret) return ret;
ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), buf[1]); if (ret) return ret;
for (c = 0; c < indio_dev->num_channels; c++) { if (test_bit(c, scan_mask))
ret = iio_backend_chan_enable(st->back, c); else
ret = iio_backend_chan_disable(st->back, c); if (ret) return ret;
}
return 0;
}
staticint ad4851_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, constint **vals, int *type, int *length, long mask)
{ struct ad4851_state *st = iio_priv(indio_dev);
switch (mask) { case IIO_CHAN_INFO_SCALE: if (st->bipolar_ch[chan->channel]) {
*vals = (constint *)st->scales_bipolar;
*type = IIO_VAL_INT_PLUS_MICRO; /* Values are stored in a 2D matrix */
*length = ARRAY_SIZE(ad4851_scale_avail_bipolar) * 2;
} else {
*vals = (constint *)st->scales_unipolar;
*type = IIO_VAL_INT_PLUS_MICRO; /* Values are stored in a 2D matrix */
*length = ARRAY_SIZE(ad4851_scale_avail_unipolar) * 2;
} return IIO_AVAIL_LIST; case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*vals = ad4851_oversampling_ratios;
*length = ARRAY_SIZE(ad4851_oversampling_ratios);
*type = IIO_VAL_INT; return IIO_AVAIL_LIST; default: return -EINVAL;
}
}
/* * In case of AD4858_IIO_CHANNEL the scan_type is handled dynamically during the * parse_channels function.
*/ #define AD4858_IIO_CHANNEL \
{ \
AD4851_IIO_CHANNEL \
}
/* * parse_channels() function handles the rest of the channel related attributes * that are usually are stored in the chip info structure.
*/ staticconststruct ad4851_chip_info ad4851_info = {
.name = "ad4851",
.product_id = 0x67,
.max_sample_rate_hz = 250 * KILO,
.resolution = 16,
.max_channels = AD4851_MAX_CH_NR,
.parse_channels = ad4857_parse_channels,
};
indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM;
st = iio_priv(indio_dev);
st->spi = spi;
ret = devm_mutex_init(dev, &st->lock); if (ret) return ret;
ret = devm_regulator_bulk_get_enable(dev,
ARRAY_SIZE(ad4851_power_supplies),
ad4851_power_supplies); if (ret) return dev_err_probe(dev, ret, "failed to get and enable supplies\n");
ret = devm_regulator_get_enable_optional(dev, "vddh"); if (ret < 0 && ret != -ENODEV) return dev_err_probe(dev, ret, "failed to enable vddh voltage\n");
ret = devm_regulator_get_enable_optional(dev, "vddl"); if (ret < 0 && ret != -ENODEV) return dev_err_probe(dev, ret, "failed to enable vddl voltage\n");
ret = devm_regulator_get_enable_optional(dev, "vrefbuf"); if (ret < 0 && ret != -ENODEV) return dev_err_probe(dev, ret, "failed to enable vrefbuf voltage\n");
st->vrefbuf_en = ret != -ENODEV;
ret = devm_regulator_get_enable_optional(dev, "vrefio"); if (ret < 0 && ret != -ENODEV) return dev_err_probe(dev, ret, "failed to enable vrefio voltage\n");
st->vrefio_en = ret != -ENODEV;
st->pd_gpio = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_LOW); if (IS_ERR(st->pd_gpio)) return dev_err_probe(dev, PTR_ERR(st->pd_gpio), "Error on requesting pd GPIO\n");
st->cnv = devm_pwm_get(dev, NULL); if (IS_ERR(st->cnv)) return dev_err_probe(dev, PTR_ERR(st->cnv), "Error on requesting pwm\n");
st->info = spi_get_device_match_data(spi); if (!st->info) return -ENODEV;
st->regmap = devm_regmap_init_spi(spi, ®map_config); if (IS_ERR(st->regmap)) return PTR_ERR(st->regmap);
ret = ad4851_set_sampling_freq(st, HZ_PER_MHZ); if (ret) return ret;
ret = devm_add_action_or_reset(&st->spi->dev, ad4851_pwm_disable,
st->cnv); if (ret) 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.