/* * Always assume 16 bits resolution as HW registers are aligned like that and * with enabled oversampling/averaging it actually corresponds to 16 bits.
*/ #define ADS7138_RES_BITS 16
ret = ads7138_i2c_read_block(client, reg, &value, sizeof(value)); if (ret) return ret; return value;
}
staticint ads7138_freq_to_bits(int freq)
{ int i;
for (i = 0; i < ARRAY_SIZE(ads7138_samp_freqs_bits[0]); i++) if (freq == ads7138_samp_freqs_bits[0][i]) return ads7138_samp_freqs_bits[1][i];
return -EINVAL;
}
staticint ads7138_bits_to_freq(int bits)
{ int i;
for (i = 0; i < ARRAY_SIZE(ads7138_samp_freqs_bits[1]); i++) if (bits == ads7138_samp_freqs_bits[1][i]) return ads7138_samp_freqs_bits[0][i];
return -EINVAL;
}
staticint ads7138_osr_to_bits(int osr)
{ int i;
for (i = 0; i < ARRAY_SIZE(ads7138_oversampling_ratios); i++) if (osr == ads7138_oversampling_ratios[i]) return i;
return -EINVAL;
}
staticint ads7138_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ struct ads7138_data *data = iio_priv(indio_dev); int ret, vref, bits;
u8 values[2];
switch (mask) { case IIO_CHAN_INFO_RAW:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_RECENT_LSB_CH(chan->channel),
values, ARRAY_SIZE(values)); if (ret) return ret;
*val = get_unaligned_le16(values); return IIO_VAL_INT; case IIO_CHAN_INFO_PEAK:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_MAX_LSB_CH(chan->channel),
values, ARRAY_SIZE(values)); if (ret) return ret;
*val = get_unaligned_le16(values); return IIO_VAL_INT; case IIO_CHAN_INFO_TROUGH:
ret = ads7138_i2c_read_block(data->client,
ADS7138_REG_MIN_LSB_CH(chan->channel),
values, ARRAY_SIZE(values)); if (ret) return ret;
*val = get_unaligned_le16(values); return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ:
ret = ads7138_i2c_read(data->client, ADS7138_REG_OPMODE_CFG); if (ret < 0) return ret;
bits = FIELD_GET(ADS7138_OPMODE_CFG_FREQ_MASK, ret);
*val = ads7138_bits_to_freq(bits); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE:
vref = regulator_get_voltage(data->vref_regu); if (vref < 0) return vref;
*val = vref / 1000;
*val2 = ADS7138_RES_BITS; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
ret = ads7138_i2c_read(data->client, ADS7138_REG_OSR_CFG); if (ret < 0) return ret;
staticint ads7138_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ struct ads7138_data *data = iio_priv(indio_dev); int bits, ret;
u8 value;
switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: {
bits = ads7138_freq_to_bits(val); if (bits < 0) return bits;
guard(mutex)(&data->lock);
ret = ads7138_i2c_read(data->client, ADS7138_REG_OPMODE_CFG); if (ret < 0) return ret;
value = ret & ~ADS7138_OPMODE_CFG_FREQ_MASK;
value |= FIELD_PREP(ADS7138_OPMODE_CFG_FREQ_MASK, bits); return ads7138_i2c_write(data->client, ADS7138_REG_OPMODE_CFG,
value);
} case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
bits = ads7138_osr_to_bits(val); if (bits < 0) return bits;
/* Check if interrupt was trigger by us */
ret = ads7138_i2c_read(data->client, ADS7138_REG_EVENT_FLAG); if (ret <= 0) return IRQ_NONE;
ret = ads7138_i2c_read(data->client, ADS7138_REG_EVENT_HIGH_FLAG); if (ret < 0) {
dev_warn(dev, "Failed to read event high flags: %d\n", ret); return IRQ_HANDLED;
}
events_high = ret;
ret = ads7138_i2c_read(data->client, ADS7138_REG_EVENT_LOW_FLAG); if (ret < 0) {
dev_warn(dev, "Failed to read event low flags: %d\n", ret); return IRQ_HANDLED;
}
events_low = ret;
for (i = 0; i < data->chip_data->channel_num; i++) { if (events_high & BIT(i)) {
code = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_RISING);
iio_push_event(indio_dev, code,
iio_get_time_ns(indio_dev));
} if (events_low & BIT(i)) {
code = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_FALLING);
iio_push_event(indio_dev, code,
iio_get_time_ns(indio_dev));
}
}
/* Try to clear all interrupt flags */
ret = ads7138_i2c_write(data->client, ADS7138_REG_EVENT_HIGH_FLAG, 0xFF); if (ret)
dev_warn(dev, "Failed to clear event high flags: %d\n", ret);
ret = ads7138_i2c_write(data->client, ADS7138_REG_EVENT_LOW_FLAG, 0xFF); if (ret)
dev_warn(dev, "Failed to clear event low flags: %d\n", ret);
data->vref_regu = devm_regulator_get(dev, "avdd"); if (IS_ERR(data->vref_regu)) return dev_err_probe(dev, PTR_ERR(data->vref_regu), "Failed to get avdd regulator\n");
ret = regulator_get_voltage(data->vref_regu); if (ret < 0) return dev_err_probe(dev, ret, "Failed to get avdd voltage\n");
/* Reset the chip to get a defined starting configuration */
ret = ads7138_i2c_set_bit(data->client, ADS7138_REG_GENERAL_CFG,
ADS7138_GENERAL_CFG_RST); if (ret) return ret;
ret = ads7138_set_conv_mode(data, ADS7138_MODE_AUTO); if (ret) return ret;
/* Enable statistics and digital window comparator */
ret = ads7138_i2c_set_bit(data->client, ADS7138_REG_GENERAL_CFG,
ADS7138_GENERAL_CFG_STATS_EN |
ADS7138_GENERAL_CFG_DWC_EN); if (ret) return ret;
/* Enable all channels for auto sequencing */
ret = ads7138_i2c_set_bit(data->client, ADS7138_REG_AUTO_SEQ_CH_SEL, 0xFF); if (ret) return ret;
/* Set auto sequence mode and start sequencing */ return ads7138_i2c_set_bit(data->client, ADS7138_REG_SEQUENCE_CFG,
ADS7138_SEQUENCE_CFG_SEQ_START |
ADS7138_SEQUENCE_CFG_SEQ_MODE);
}
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.