ret = i2c_smbus_read_i2c_block_data(client, cmd, sizeof(values), values); if (ret < 0) return ret; if (ret != sizeof(values)) return -EIO; return get_unaligned_be24(&values[0]) & GENMASK(19, 0);
}
/* Spin for max 160ms until DEV_RDY is 1, or return error. */ staticint hp206c_wait_dev_rdy(struct iio_dev *indio_dev)
{ int ret; int count = 0; struct hp206c_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client;
while (++count <= HP206C_MAX_DEV_RDY_WAIT_COUNT) {
ret = hp206c_read_reg(client, HP206C_REG_INT_SRC); if (ret < 0) {
dev_err(&indio_dev->dev, "Failed READ_REG INT_SRC: %d\n", ret); return ret;
} if (ret & HP206C_FLAG_DEV_RDY) return0;
usleep_range(HP206C_DEV_RDY_WAIT_US, HP206C_DEV_RDY_WAIT_US * 3 / 2);
} return -ETIMEDOUT;
}
staticint hp206c_set_compensation(struct i2c_client *client, bool enabled)
{ int val;
val = hp206c_read_reg(client, HP206C_REG_PARA); if (val < 0) return val; if (enabled)
val |= HP206C_FLAG_CMPS_EN; else
val &= ~HP206C_FLAG_CMPS_EN;
ret = hp206c_wait_dev_rdy(indio_dev); if (ret < 0) {
dev_err(&indio_dev->dev, "Device not ready: %d\n", ret); return ret;
}
ret = i2c_smbus_write_byte(client, conv_cmd); if (ret < 0) {
dev_err(&indio_dev->dev, "Failed convert: %d\n", ret); return ret;
}
usleep_range(sleep_us, sleep_us * 3 / 2);
ret = hp206c_wait_dev_rdy(indio_dev); if (ret < 0) {
dev_err(&indio_dev->dev, "Device not ready: %d\n", ret); return ret;
}
ret = hp206c_read_20bit(client, read_cmd); if (ret < 0)
dev_err(&indio_dev->dev, "Failed read: %d\n", ret);
return ret;
}
staticint hp206c_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ int ret; struct hp206c_data *data = iio_priv(indio_dev); conststruct hp206c_osr_setting *osr_setting;
u8 conv_cmd;
mutex_lock(&data->mutex);
switch (mask) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: switch (chan->type) { case IIO_TEMP:
*val = hp206c_osr_rates[data->temp_osr_index];
ret = IIO_VAL_INT; break;
case IIO_PRESSURE:
*val = hp206c_osr_rates[data->pres_osr_index];
ret = IIO_VAL_INT; break; default:
ret = -EINVAL;
} break;
case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_TEMP:
osr_setting = &hp206c_osr_settings[data->temp_osr_index];
conv_cmd = HP206C_CMD_ADC_CVT |
osr_setting->osr_mask |
HP206C_CMD_ADC_CVT_CHNL_T;
ret = hp206c_conv_and_read(indio_dev,
conv_cmd,
HP206C_CMD_READ_T,
osr_setting->temp_conv_time_us); if (ret >= 0) { /* 20 significant bits are provided. *Extendsignovertherest.
*/
*val = sign_extend32(ret, 19);
ret = IIO_VAL_INT;
} break;
case IIO_PRESSURE:
osr_setting = &hp206c_osr_settings[data->pres_osr_index];
conv_cmd = HP206C_CMD_ADC_CVT |
osr_setting->osr_mask |
HP206C_CMD_ADC_CVT_CHNL_PT;
ret = hp206c_conv_and_read(indio_dev,
conv_cmd,
HP206C_CMD_READ_P,
osr_setting->pres_conv_time_us); if (ret >= 0) {
*val = ret;
ret = IIO_VAL_INT;
} break; default:
ret = -EINVAL;
} break;
case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_TEMP:
*val = 0;
*val2 = 10000;
ret = IIO_VAL_INT_PLUS_MICRO; break;
case IIO_PRESSURE:
*val = 0;
*val2 = 1000;
ret = IIO_VAL_INT_PLUS_MICRO; break; default:
ret = -EINVAL;
} break;
default:
ret = -EINVAL;
}
mutex_unlock(&data->mutex); return ret;
}
staticint hp206c_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ int ret = 0; struct hp206c_data *data = iio_priv(indio_dev);
if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO) return -EINVAL;
mutex_lock(&data->mutex); switch (chan->type) { case IIO_TEMP:
data->temp_osr_index = find_closest_descending(val,
hp206c_osr_rates, ARRAY_SIZE(hp206c_osr_rates)); break; case IIO_PRESSURE:
data->pres_osr_index = find_closest_descending(val,
hp206c_osr_rates, ARRAY_SIZE(hp206c_osr_rates)); break; default:
ret = -EINVAL;
}
mutex_unlock(&data->mutex); return ret;
}
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
dev_err(&client->dev, "Adapter does not support " "all required i2c functionality\n"); return -ENODEV;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM;
data = iio_priv(indio_dev);
data->client = client;
mutex_init(&data->mutex);
/* Do a soft reset on probe */
ret = hp206c_soft_reset(indio_dev); if (ret) {
dev_err(&client->dev, "Failed to reset on startup: %d\n", ret); return -ENODEV;
}
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.