Commit 79fd571b authored by David Frey's avatar David Frey Committed by Jonathan Cameron

iio: chemical: bme680: simplify oversampling handling

Temperature, pressure and humidity all expose and oversampling setting
that works in the same way.  Provide common handling for the
oversampling sysfs attributes.
Signed-off-by: default avatarDavid Frey <dpfrey@gmail.com>
Reviewed-by: default avatarHimanshu Jha <himanshujha199640@gmail.com>
Tested-by: default avatarHimanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 3dcb60cd
...@@ -91,8 +91,6 @@ static const struct iio_chan_spec bme680_channels[] = { ...@@ -91,8 +91,6 @@ static const struct iio_chan_spec bme680_channels[] = {
}, },
}; };
static const int bme680_oversampling_avail[] = { 1, 2, 4, 8, 16 };
static int bme680_read_calib(struct bme680_data *data, static int bme680_read_calib(struct bme680_data *data,
struct bme680_calib *calib) struct bme680_calib *calib)
{ {
...@@ -503,12 +501,20 @@ static int bme680_set_mode(struct bme680_data *data, bool mode) ...@@ -503,12 +501,20 @@ static int bme680_set_mode(struct bme680_data *data, bool mode)
return ret; return ret;
} }
static u8 bme680_oversampling_to_reg(u8 val)
{
return ilog2(val) + 1;
}
static int bme680_chip_config(struct bme680_data *data) static int bme680_chip_config(struct bme680_data *data)
{ {
struct device *dev = regmap_get_device(data->regmap); struct device *dev = regmap_get_device(data->regmap);
int ret; int ret;
u8 osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK, u8 osrs;
data->oversampling_humid + 1);
osrs = FIELD_PREP(
BME680_OSRS_HUMIDITY_MASK,
bme680_oversampling_to_reg(data->oversampling_humid));
/* /*
* Highly recommended to set oversampling of humidity before * Highly recommended to set oversampling of humidity before
* temperature/pressure oversampling. * temperature/pressure oversampling.
...@@ -529,12 +535,12 @@ static int bme680_chip_config(struct bme680_data *data) ...@@ -529,12 +535,12 @@ static int bme680_chip_config(struct bme680_data *data)
return ret; return ret;
} }
osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK, data->oversampling_temp + 1) | osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK,
FIELD_PREP(BME680_OSRS_PRESS_MASK, data->oversampling_press + 1); bme680_oversampling_to_reg(data->oversampling_temp)) |
FIELD_PREP(BME680_OSRS_PRESS_MASK,
bme680_oversampling_to_reg(data->oversampling_press));
ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS, ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
BME680_OSRS_TEMP_MASK | BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK,
BME680_OSRS_PRESS_MASK,
osrs); osrs);
if (ret < 0) if (ret < 0)
dev_err(dev, "failed to write ctrl_meas register\n"); dev_err(dev, "failed to write ctrl_meas register\n");
...@@ -767,13 +773,13 @@ static int bme680_read_raw(struct iio_dev *indio_dev, ...@@ -767,13 +773,13 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_OVERSAMPLING_RATIO: case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
switch (chan->type) { switch (chan->type) {
case IIO_TEMP: case IIO_TEMP:
*val = 1 << data->oversampling_temp; *val = data->oversampling_temp;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_PRESSURE: case IIO_PRESSURE:
*val = 1 << data->oversampling_press; *val = data->oversampling_press;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_HUMIDITYRELATIVE: case IIO_HUMIDITYRELATIVE:
*val = 1 << data->oversampling_humid; *val = data->oversampling_humid;
return IIO_VAL_INT; return IIO_VAL_INT;
default: default:
return -EINVAL; return -EINVAL;
...@@ -783,52 +789,9 @@ static int bme680_read_raw(struct iio_dev *indio_dev, ...@@ -783,52 +789,9 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
} }
} }
static int bme680_write_oversampling_ratio_temp(struct bme680_data *data, static bool bme680_is_valid_oversampling(int rate)
int val)
{ {
int i; return (rate > 0 && rate <= 16 && is_power_of_2(rate));
for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
if (bme680_oversampling_avail[i] == val) {
data->oversampling_temp = ilog2(val);
return bme680_chip_config(data);
}
}
return -EINVAL;
}
static int bme680_write_oversampling_ratio_press(struct bme680_data *data,
int val)
{
int i;
for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
if (bme680_oversampling_avail[i] == val) {
data->oversampling_press = ilog2(val);
return bme680_chip_config(data);
}
}
return -EINVAL;
}
static int bme680_write_oversampling_ratio_humid(struct bme680_data *data,
int val)
{
int i;
for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
if (bme680_oversampling_avail[i] == val) {
data->oversampling_humid = ilog2(val);
return bme680_chip_config(data);
}
}
return -EINVAL;
} }
static int bme680_write_raw(struct iio_dev *indio_dev, static int bme680_write_raw(struct iio_dev *indio_dev,
...@@ -839,16 +802,26 @@ static int bme680_write_raw(struct iio_dev *indio_dev, ...@@ -839,16 +802,26 @@ static int bme680_write_raw(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_OVERSAMPLING_RATIO: case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
{
if (!bme680_is_valid_oversampling(val))
return -EINVAL;
switch (chan->type) { switch (chan->type) {
case IIO_TEMP: case IIO_TEMP:
return bme680_write_oversampling_ratio_temp(data, val); data->oversampling_temp = val;
break;
case IIO_PRESSURE: case IIO_PRESSURE:
return bme680_write_oversampling_ratio_press(data, val); data->oversampling_press = val;
break;
case IIO_HUMIDITYRELATIVE: case IIO_HUMIDITYRELATIVE:
return bme680_write_oversampling_ratio_humid(data, val); data->oversampling_humid = val;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
return bme680_chip_config(data);
}
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -910,9 +883,9 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap, ...@@ -910,9 +883,9 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
/* default values for the sensor */ /* default values for the sensor */
data->oversampling_humid = ilog2(2); /* 2X oversampling rate */ data->oversampling_humid = 2; /* 2X oversampling rate */
data->oversampling_press = ilog2(4); /* 4X oversampling rate */ data->oversampling_press = 4; /* 4X oversampling rate */
data->oversampling_temp = ilog2(8); /* 8X oversampling rate */ data->oversampling_temp = 8; /* 8X oversampling rate */
data->heater_temp = 320; /* degree Celsius */ data->heater_temp = 320; /* degree Celsius */
data->heater_dur = 150; /* milliseconds */ data->heater_dur = 150; /* milliseconds */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment