mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
Merge tag 'iio-fixes-for-6.18a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus
Jonathan writes: IIO: Fixes for 6.18 (set 1) The usual mixed back of brand new and ancient bugs. dmaengine buffer / core - Add new callback to allow fetching the providing device for a DMA channel. Use this to get the right device for the dmaengine buffer implementation. adi,ad4030 - Fix incorrect _scale value for common-mode channels. adi,ad7124 - Fix gain and offset for temperature channel. adi,ad7280a - Fix a factor of 10 error when setting the balance timer. adi,ad7380 - Fix sampling frequency to account for need to trigger twice per scan for some supported chips. adi,adxl355 - Ensure a long enough wait after SW reset. bosch,bmc150 - Fix wrong assumption that interrupts are always available. bosch,bmp280 - Fix the measurement time calculation. richtek,rtq6056 - Fix wrong sign bit when sign extending. samsung,ssp - Fix cleanup of registered mfd devices on error. st,lsm6dsx - Fix wrong sized array for register information. - Fix a wrong time stamp calculation for some devices. st,stm32-dfsdm - Update handling of st,adc-alt-channel to reflect binding change as part of moving to iio-backend framework. ti,hdc3020 - Fix wrong units for temperature and humidity. Also the thresholds and hysteresis. * tag 'iio-fixes-for-6.18a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: iio: accel: bmc150: Fix irq assumption regression iio: st_lsm6dsx: Fixed calibrated timestamp calculation iio: humditiy: hdc3020: fix units for thresholds and hysteresis iio: humditiy: hdc3020: fix units for temperature and humidity measurement iio: imu: st_lsm6dsx: fix array size for st_lsm6dsx_settings fields iio: accel: fix ADXL355 startup race condition iio: adc: ad7124: fix temperature channel iio:common:ssp_sensors: Fix an error handling path ssp_probe() iio: adc: ad7280a: fix ad7280_store_balance_timer() iio: buffer-dmaengine: enable .get_dma_dev() iio: buffer-dma: support getting the DMA channel iio: buffer: support getting dma channel from the buffer iio: pressure: bmp280: correct meas_time_us calculation iio: adc: stm32-dfsdm: fix st,adc-alt-channel property handling iio: adc: ad7380: fix SPI offload trigger rate iio: adc: rtq6056: Correct the sign bit index iio: adc: ad4030: Fix _scale value for common-mode channels
This commit is contained in:
@@ -56,6 +56,8 @@
|
||||
#define ADXL355_POWER_CTL_DRDY_MSK BIT(2)
|
||||
#define ADXL355_SELF_TEST_REG 0x2E
|
||||
#define ADXL355_RESET_REG 0x2F
|
||||
#define ADXL355_BASE_ADDR_SHADOW_REG 0x50
|
||||
#define ADXL355_SHADOW_REG_COUNT 5
|
||||
|
||||
#define ADXL355_DEVID_AD_VAL 0xAD
|
||||
#define ADXL355_DEVID_MST_VAL 0x1D
|
||||
@@ -294,7 +296,12 @@ static void adxl355_fill_3db_frequency_table(struct adxl355_data *data)
|
||||
static int adxl355_setup(struct adxl355_data *data)
|
||||
{
|
||||
unsigned int regval;
|
||||
int retries = 5; /* the number is chosen based on empirical reasons */
|
||||
int ret;
|
||||
u8 *shadow_regs __free(kfree) = kzalloc(ADXL355_SHADOW_REG_COUNT, GFP_KERNEL);
|
||||
|
||||
if (!shadow_regs)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, ®val);
|
||||
if (ret)
|
||||
@@ -321,14 +328,41 @@ static int adxl355_setup(struct adxl355_data *data)
|
||||
if (regval != ADXL355_PARTID_VAL)
|
||||
dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval);
|
||||
|
||||
/*
|
||||
* Perform a software reset to make sure the device is in a consistent
|
||||
* state after start-up.
|
||||
*/
|
||||
ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE);
|
||||
/* Read shadow registers to be compared after reset */
|
||||
ret = regmap_bulk_read(data->regmap,
|
||||
ADXL355_BASE_ADDR_SHADOW_REG,
|
||||
shadow_regs, ADXL355_SHADOW_REG_COUNT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
do {
|
||||
if (--retries == 0) {
|
||||
dev_err(data->dev, "Shadow registers mismatch\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a software reset to make sure the device is in a consistent
|
||||
* state after start-up.
|
||||
*/
|
||||
ret = regmap_write(data->regmap, ADXL355_RESET_REG,
|
||||
ADXL355_RESET_CODE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait at least 5ms after software reset */
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
/* Read shadow registers for comparison */
|
||||
ret = regmap_bulk_read(data->regmap,
|
||||
ADXL355_BASE_ADDR_SHADOW_REG,
|
||||
data->buffer.buf,
|
||||
ADXL355_SHADOW_REG_COUNT);
|
||||
if (ret)
|
||||
return ret;
|
||||
} while (memcmp(shadow_regs, data->buffer.buf,
|
||||
ADXL355_SHADOW_REG_COUNT));
|
||||
|
||||
ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
|
||||
ADXL355_POWER_CTL_DRDY_MSK,
|
||||
FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1));
|
||||
|
||||
@@ -523,6 +523,10 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
|
||||
const struct bmc150_accel_interrupt_info *info = intr->info;
|
||||
int ret;
|
||||
|
||||
/* We do not always have an IRQ */
|
||||
if (data->irq <= 0)
|
||||
return 0;
|
||||
|
||||
if (state) {
|
||||
if (atomic_inc_return(&intr->users) > 1)
|
||||
return 0;
|
||||
@@ -1696,6 +1700,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
|
||||
}
|
||||
|
||||
if (irq > 0) {
|
||||
data->irq = irq;
|
||||
ret = devm_request_threaded_irq(dev, irq,
|
||||
bmc150_accel_irq_handler,
|
||||
bmc150_accel_irq_thread_handler,
|
||||
|
||||
@@ -58,6 +58,7 @@ enum bmc150_accel_trigger_id {
|
||||
|
||||
struct bmc150_accel_data {
|
||||
struct regmap *regmap;
|
||||
int irq;
|
||||
struct regulator_bulk_data regulators[2];
|
||||
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
|
||||
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
|
||||
|
||||
@@ -385,7 +385,7 @@ static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
|
||||
struct ad4030_state *st = iio_priv(indio_dev);
|
||||
const struct iio_scan_type *scan_type;
|
||||
|
||||
scan_type = iio_get_current_scan_type(indio_dev, st->chip->channels);
|
||||
scan_type = iio_get_current_scan_type(indio_dev, chan);
|
||||
if (IS_ERR(scan_type))
|
||||
return PTR_ERR(scan_type);
|
||||
|
||||
|
||||
@@ -1525,10 +1525,6 @@ static int __ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < st->num_channels; i++) {
|
||||
|
||||
if (indio_dev->channels[i].type != IIO_VOLTAGE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* For calibration the OFFSET register should hold its reset default
|
||||
* value. For the GAIN register there is no such requirement but
|
||||
@@ -1538,6 +1534,14 @@ static int __ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio
|
||||
st->channels[i].cfg.calibration_offset = 0x800000;
|
||||
st->channels[i].cfg.calibration_gain = st->gain_default;
|
||||
|
||||
/*
|
||||
* Only the main voltage input channels are important enough
|
||||
* to be automatically calibrated here. For everything else,
|
||||
* just use the default values set above.
|
||||
*/
|
||||
if (indio_dev->channels[i].type != IIO_VOLTAGE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Full-scale calibration isn't supported at gain 1, so skip in
|
||||
* that case. Note that untypically full-scale calibration has
|
||||
|
||||
@@ -541,7 +541,7 @@ static ssize_t ad7280_store_balance_timer(struct iio_dev *indio_dev,
|
||||
int val, val2;
|
||||
int ret;
|
||||
|
||||
ret = iio_str_to_fixpoint(buf, 1000, &val, &val2);
|
||||
ret = iio_str_to_fixpoint(buf, 100, &val, &val2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -1227,6 +1227,14 @@ static int ad7380_offload_buffer_postenable(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* When the sequencer is required to read all channels, we need to
|
||||
* trigger twice per sample period in order to read one complete set
|
||||
* of samples.
|
||||
*/
|
||||
if (st->seq)
|
||||
config.periodic.frequency_hz *= 2;
|
||||
|
||||
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, &config);
|
||||
if (ret)
|
||||
spi_unoptimize_message(&st->offload_msg);
|
||||
|
||||
@@ -300,7 +300,7 @@ static int rtq6056_adc_read_channel(struct rtq6056_priv *priv,
|
||||
return IIO_VAL_INT;
|
||||
case RTQ6056_REG_SHUNTVOLT:
|
||||
case RTQ6056_REG_CURRENT:
|
||||
*val = sign_extend32(regval, 16);
|
||||
*val = sign_extend32(regval, 15);
|
||||
return IIO_VAL_INT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
||||
@@ -725,9 +725,8 @@ static int stm32_dfsdm_generic_channel_parse_of(struct stm32_dfsdm *dfsdm,
|
||||
}
|
||||
df_ch->src = val;
|
||||
|
||||
ret = fwnode_property_read_u32(node, "st,adc-alt-channel", &df_ch->alt_si);
|
||||
if (ret != -EINVAL)
|
||||
df_ch->alt_si = 0;
|
||||
if (fwnode_property_present(node, "st,adc-alt-channel"))
|
||||
df_ch->alt_si = 1;
|
||||
|
||||
if (adc->dev_data->type == DFSDM_IIO) {
|
||||
backend = devm_iio_backend_fwnode_get(&indio_dev->dev, NULL, node);
|
||||
|
||||
@@ -786,6 +786,12 @@ out_end_signalling:
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enqueue_dmabuf, "IIO_DMA_BUFFER");
|
||||
|
||||
struct device *iio_dma_buffer_get_dma_dev(struct iio_buffer *buffer)
|
||||
{
|
||||
return iio_buffer_to_queue(buffer)->dev;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_get_dma_dev, "IIO_DMA_BUFFER");
|
||||
|
||||
void iio_dma_buffer_lock_queue(struct iio_buffer *buffer)
|
||||
{
|
||||
struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer);
|
||||
|
||||
@@ -177,6 +177,8 @@ static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = {
|
||||
.lock_queue = iio_dma_buffer_lock_queue,
|
||||
.unlock_queue = iio_dma_buffer_unlock_queue,
|
||||
|
||||
.get_dma_dev = iio_dma_buffer_get_dma_dev,
|
||||
|
||||
.modes = INDIO_BUFFER_HARDWARE,
|
||||
.flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK,
|
||||
};
|
||||
|
||||
@@ -503,7 +503,7 @@ static int ssp_probe(struct spi_device *spi)
|
||||
ret = spi_setup(spi);
|
||||
if (ret < 0) {
|
||||
dev_err(&spi->dev, "Failed to setup spi\n");
|
||||
return ret;
|
||||
goto err_setup_spi;
|
||||
}
|
||||
|
||||
data->fw_dl_state = SSP_FW_DL_STATE_NONE;
|
||||
@@ -568,6 +568,8 @@ err_read_reg:
|
||||
err_setup_irq:
|
||||
mutex_destroy(&data->pending_lock);
|
||||
mutex_destroy(&data->comm_lock);
|
||||
err_setup_spi:
|
||||
mfd_remove_devices(&spi->dev);
|
||||
|
||||
dev_err(&spi->dev, "Probe failed!\n");
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@
|
||||
#define HDC3020_MAX_TEMP_HYST_MICRO 164748607
|
||||
#define HDC3020_MAX_HUM_MICRO 99220264
|
||||
|
||||
/* Divide 65535 from the datasheet by 5 to avoid overflows */
|
||||
#define HDC3020_THRESH_FRACTION (65535 / 5)
|
||||
|
||||
struct hdc3020_data {
|
||||
struct i2c_client *client;
|
||||
struct gpio_desc *reset_gpio;
|
||||
@@ -301,9 +304,9 @@ static int hdc3020_read_raw(struct iio_dev *indio_dev,
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val2 = 65536;
|
||||
if (chan->type == IIO_TEMP)
|
||||
*val = 175;
|
||||
*val = 175 * MILLI;
|
||||
else
|
||||
*val = 100;
|
||||
*val = 100 * MILLI;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
@@ -376,15 +379,18 @@ static int hdc3020_thresh_get_temp(u16 thresh)
|
||||
int temp;
|
||||
|
||||
/*
|
||||
* Get the temperature threshold from 9 LSBs, shift them to get
|
||||
* the truncated temperature threshold representation and
|
||||
* calculate the threshold according to the formula in the
|
||||
* datasheet. Result is degree celsius scaled by 65535.
|
||||
* Get the temperature threshold from 9 LSBs, shift them to get the
|
||||
* truncated temperature threshold representation and calculate the
|
||||
* threshold according to the explicit formula in the datasheet:
|
||||
* T(C) = -45 + (175 * temp) / 65535.
|
||||
* Additionally scale by HDC3020_THRESH_FRACTION to avoid precision loss
|
||||
* when calculating threshold and hysteresis values. Result is degree
|
||||
* celsius scaled by HDC3020_THRESH_FRACTION.
|
||||
*/
|
||||
temp = FIELD_GET(HDC3020_THRESH_TEMP_MASK, thresh) <<
|
||||
HDC3020_THRESH_TEMP_TRUNC_SHIFT;
|
||||
|
||||
return -2949075 + (175 * temp);
|
||||
return -2949075 / 5 + (175 / 5 * temp);
|
||||
}
|
||||
|
||||
static int hdc3020_thresh_get_hum(u16 thresh)
|
||||
@@ -394,13 +400,16 @@ static int hdc3020_thresh_get_hum(u16 thresh)
|
||||
/*
|
||||
* Get the humidity threshold from 7 MSBs, shift them to get the
|
||||
* truncated humidity threshold representation and calculate the
|
||||
* threshold according to the formula in the datasheet. Result is
|
||||
* percent scaled by 65535.
|
||||
* threshold according to the explicit formula in the datasheet:
|
||||
* RH(%) = 100 * hum / 65535.
|
||||
* Additionally scale by HDC3020_THRESH_FRACTION to avoid precision loss
|
||||
* when calculating threshold and hysteresis values. Result is percent
|
||||
* scaled by HDC3020_THRESH_FRACTION.
|
||||
*/
|
||||
hum = FIELD_GET(HDC3020_THRESH_HUM_MASK, thresh) <<
|
||||
HDC3020_THRESH_HUM_TRUNC_SHIFT;
|
||||
|
||||
return hum * 100;
|
||||
return hum * 100 / 5;
|
||||
}
|
||||
|
||||
static u16 hdc3020_thresh_set_temp(int s_temp, u16 curr_thresh)
|
||||
@@ -455,8 +464,8 @@ int hdc3020_thresh_clr(s64 s_thresh, s64 s_hyst, enum iio_event_direction dir)
|
||||
else
|
||||
s_clr = s_thresh + s_hyst;
|
||||
|
||||
/* Divide by 65535 to get units of micro */
|
||||
return div_s64(s_clr, 65535);
|
||||
/* Divide by HDC3020_THRESH_FRACTION to get units of micro */
|
||||
return div_s64(s_clr, HDC3020_THRESH_FRACTION);
|
||||
}
|
||||
|
||||
static int _hdc3020_write_thresh(struct hdc3020_data *data, u16 reg, u16 val)
|
||||
@@ -507,7 +516,7 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
|
||||
|
||||
clr = ret;
|
||||
/* Scale value to include decimal part into calculations */
|
||||
s_val = (val < 0) ? (val * 1000000 - val2) : (val * 1000000 + val2);
|
||||
s_val = (val < 0) ? (val * 1000 - val2) : (val * 1000 + val2);
|
||||
switch (chan->type) {
|
||||
case IIO_TEMP:
|
||||
switch (info) {
|
||||
@@ -523,7 +532,8 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
|
||||
/* Calculate old hysteresis */
|
||||
s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000;
|
||||
s_clr = (s64)hdc3020_thresh_get_temp(clr) * 1000000;
|
||||
s_hyst = div_s64(abs(s_thresh - s_clr), 65535);
|
||||
s_hyst = div_s64(abs(s_thresh - s_clr),
|
||||
HDC3020_THRESH_FRACTION);
|
||||
/* Set new threshold */
|
||||
thresh = reg_val;
|
||||
/* Set old hysteresis */
|
||||
@@ -532,16 +542,17 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
/*
|
||||
* Function hdc3020_thresh_get_temp returns temperature
|
||||
* in degree celsius scaled by 65535. Scale by 1000000
|
||||
* to be able to subtract scaled hysteresis value.
|
||||
* in degree celsius scaled by HDC3020_THRESH_FRACTION.
|
||||
* Scale by 1000000 to be able to subtract scaled
|
||||
* hysteresis value.
|
||||
*/
|
||||
s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000;
|
||||
/*
|
||||
* Units of s_val are in micro degree celsius, scale by
|
||||
* 65535 to get same units as s_thresh.
|
||||
* HDC3020_THRESH_FRACTION to get same units as s_thresh.
|
||||
*/
|
||||
s_val = min(abs(s_val), HDC3020_MAX_TEMP_HYST_MICRO);
|
||||
s_hyst = (s64)s_val * 65535;
|
||||
s_hyst = (s64)s_val * HDC3020_THRESH_FRACTION;
|
||||
s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir);
|
||||
s_clr = max(s_clr, HDC3020_MIN_TEMP_MICRO);
|
||||
s_clr = min(s_clr, HDC3020_MAX_TEMP_MICRO);
|
||||
@@ -565,7 +576,8 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
|
||||
/* Calculate old hysteresis */
|
||||
s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000;
|
||||
s_clr = (s64)hdc3020_thresh_get_hum(clr) * 1000000;
|
||||
s_hyst = div_s64(abs(s_thresh - s_clr), 65535);
|
||||
s_hyst = div_s64(abs(s_thresh - s_clr),
|
||||
HDC3020_THRESH_FRACTION);
|
||||
/* Set new threshold */
|
||||
thresh = reg_val;
|
||||
/* Try to set old hysteresis */
|
||||
@@ -574,15 +586,16 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
/*
|
||||
* Function hdc3020_thresh_get_hum returns relative
|
||||
* humidity in percent scaled by 65535. Scale by 1000000
|
||||
* to be able to subtract scaled hysteresis value.
|
||||
* humidity in percent scaled by HDC3020_THRESH_FRACTION.
|
||||
* Scale by 1000000 to be able to subtract scaled
|
||||
* hysteresis value.
|
||||
*/
|
||||
s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000;
|
||||
/*
|
||||
* Units of s_val are in micro percent, scale by 65535
|
||||
* to get same units as s_thresh.
|
||||
* Units of s_val are in micro percent, scale by
|
||||
* HDC3020_THRESH_FRACTION to get same units as s_thresh.
|
||||
*/
|
||||
s_hyst = (s64)s_val * 65535;
|
||||
s_hyst = (s64)s_val * HDC3020_THRESH_FRACTION;
|
||||
s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir);
|
||||
s_clr = max(s_clr, 0);
|
||||
s_clr = min(s_clr, HDC3020_MAX_HUM_MICRO);
|
||||
@@ -630,7 +643,7 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
|
||||
thresh = hdc3020_thresh_get_temp(ret);
|
||||
switch (info) {
|
||||
case IIO_EV_INFO_VALUE:
|
||||
*val = thresh;
|
||||
*val = thresh * MILLI;
|
||||
break;
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
ret = hdc3020_read_be16(data, reg_clr);
|
||||
@@ -638,18 +651,18 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
|
||||
return ret;
|
||||
|
||||
clr = hdc3020_thresh_get_temp(ret);
|
||||
*val = abs(thresh - clr);
|
||||
*val = abs(thresh - clr) * MILLI;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
*val2 = 65535;
|
||||
*val2 = HDC3020_THRESH_FRACTION;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
case IIO_HUMIDITYRELATIVE:
|
||||
thresh = hdc3020_thresh_get_hum(ret);
|
||||
switch (info) {
|
||||
case IIO_EV_INFO_VALUE:
|
||||
*val = thresh;
|
||||
*val = thresh * MILLI;
|
||||
break;
|
||||
case IIO_EV_INFO_HYSTERESIS:
|
||||
ret = hdc3020_read_be16(data, reg_clr);
|
||||
@@ -657,12 +670,12 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
|
||||
return ret;
|
||||
|
||||
clr = hdc3020_thresh_get_hum(ret);
|
||||
*val = abs(thresh - clr);
|
||||
*val = abs(thresh - clr) * MILLI;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
*val2 = 65535;
|
||||
*val2 = HDC3020_THRESH_FRACTION;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -192,6 +192,22 @@ struct st_lsm6dsx_fifo_ops {
|
||||
* @fifo_en: Hw timer FIFO enable register info (addr + mask).
|
||||
* @decimator: Hw timer FIFO decimator register info (addr + mask).
|
||||
* @freq_fine: Difference in % of ODR with respect to the typical.
|
||||
* @ts_sensitivity: Nominal timestamp sensitivity.
|
||||
* @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
|
||||
* This coefficient comes into play when linearizing the formula
|
||||
* used to calculate the calibrated timestamp (please see the
|
||||
* relevant formula in the AN for the specific IMU).
|
||||
* For example, in the case of LSM6DSO we have:
|
||||
*
|
||||
* 1 / (1 + x) ~= 1 - x (Taylor’s Series)
|
||||
* ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
|
||||
* ttrim[ns] ~= 25000 - 37.5 * val
|
||||
* ttrim[ns] ~= 25000 - (37500 * val) / 1000
|
||||
*
|
||||
* so, replacing ts_sensitivity = 25000 and
|
||||
* ts_trim_coeff = 37500
|
||||
*
|
||||
* ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
|
||||
*/
|
||||
struct st_lsm6dsx_hw_ts_settings {
|
||||
struct st_lsm6dsx_reg timer_en;
|
||||
@@ -199,6 +215,8 @@ struct st_lsm6dsx_hw_ts_settings {
|
||||
struct st_lsm6dsx_reg fifo_en;
|
||||
struct st_lsm6dsx_reg decimator;
|
||||
u8 freq_fine;
|
||||
u16 ts_sensitivity;
|
||||
u16 ts_trim_coeff;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -252,6 +270,15 @@ struct st_lsm6dsx_event_settings {
|
||||
u8 wakeup_src_x_mask;
|
||||
};
|
||||
|
||||
enum st_lsm6dsx_sensor_id {
|
||||
ST_LSM6DSX_ID_GYRO,
|
||||
ST_LSM6DSX_ID_ACC,
|
||||
ST_LSM6DSX_ID_EXT0,
|
||||
ST_LSM6DSX_ID_EXT1,
|
||||
ST_LSM6DSX_ID_EXT2,
|
||||
ST_LSM6DSX_ID_MAX
|
||||
};
|
||||
|
||||
enum st_lsm6dsx_ext_sensor_id {
|
||||
ST_LSM6DSX_ID_MAGN,
|
||||
};
|
||||
@@ -337,23 +364,14 @@ struct st_lsm6dsx_settings {
|
||||
struct st_lsm6dsx_odr_table_entry odr_table[2];
|
||||
struct st_lsm6dsx_samples_to_discard samples_to_discard[2];
|
||||
struct st_lsm6dsx_fs_table_entry fs_table[2];
|
||||
struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
|
||||
struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
|
||||
struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX];
|
||||
struct st_lsm6dsx_reg batch[2];
|
||||
struct st_lsm6dsx_fifo_ops fifo_ops;
|
||||
struct st_lsm6dsx_hw_ts_settings ts_settings;
|
||||
struct st_lsm6dsx_shub_settings shub_settings;
|
||||
struct st_lsm6dsx_event_settings event_settings;
|
||||
};
|
||||
|
||||
enum st_lsm6dsx_sensor_id {
|
||||
ST_LSM6DSX_ID_GYRO,
|
||||
ST_LSM6DSX_ID_ACC,
|
||||
ST_LSM6DSX_ID_EXT0,
|
||||
ST_LSM6DSX_ID_EXT1,
|
||||
ST_LSM6DSX_ID_EXT2,
|
||||
ST_LSM6DSX_ID_MAX,
|
||||
};
|
||||
|
||||
enum st_lsm6dsx_fifo_mode {
|
||||
ST_LSM6DSX_FIFO_BYPASS = 0x0,
|
||||
ST_LSM6DSX_FIFO_CONT = 0x6,
|
||||
|
||||
@@ -94,8 +94,6 @@
|
||||
|
||||
#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
|
||||
|
||||
#define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */
|
||||
|
||||
static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
|
||||
ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
|
||||
ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
|
||||
@@ -983,6 +981,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
||||
.mask = GENMASK(7, 6),
|
||||
},
|
||||
.freq_fine = 0x63,
|
||||
.ts_sensitivity = 25000,
|
||||
.ts_trim_coeff = 37500,
|
||||
},
|
||||
.shub_settings = {
|
||||
.page_mux = {
|
||||
@@ -1196,6 +1196,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
||||
.mask = GENMASK(7, 6),
|
||||
},
|
||||
.freq_fine = 0x63,
|
||||
.ts_sensitivity = 25000,
|
||||
.ts_trim_coeff = 37500,
|
||||
},
|
||||
.event_settings = {
|
||||
.enable_reg = {
|
||||
@@ -1371,6 +1373,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
||||
.mask = GENMASK(7, 6),
|
||||
},
|
||||
.freq_fine = 0x4f,
|
||||
.ts_sensitivity = 21701,
|
||||
.ts_trim_coeff = 28212,
|
||||
},
|
||||
.shub_settings = {
|
||||
.page_mux = {
|
||||
@@ -2248,20 +2252,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
|
||||
}
|
||||
|
||||
/* calibrate timestamp sensitivity */
|
||||
hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
|
||||
hw->ts_gain = ts_settings->ts_sensitivity;
|
||||
if (ts_settings->freq_fine) {
|
||||
err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* linearize the AN5192 formula:
|
||||
* 1 / (1 + x) ~= 1 - x (Taylor’s Series)
|
||||
* ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
|
||||
* ttrim[ns] ~= 25000 - 37.5 * val
|
||||
* ttrim[ns] ~= 25000 - (37500 * val) / 1000
|
||||
*/
|
||||
hw->ts_gain -= ((s8)val * 37500) / 1000;
|
||||
hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1623,19 +1623,28 @@ static int iio_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device *iio_buffer_get_dma_dev(const struct iio_dev *indio_dev,
|
||||
struct iio_buffer *buffer)
|
||||
{
|
||||
if (buffer->access->get_dma_dev)
|
||||
return buffer->access->get_dma_dev(buffer);
|
||||
|
||||
return indio_dev->dev.parent;
|
||||
}
|
||||
|
||||
static struct dma_buf_attachment *
|
||||
iio_buffer_find_attachment(struct iio_dev_buffer_pair *ib,
|
||||
struct dma_buf *dmabuf, bool nonblock)
|
||||
{
|
||||
struct device *dev = ib->indio_dev->dev.parent;
|
||||
struct iio_buffer *buffer = ib->buffer;
|
||||
struct device *dma_dev = iio_buffer_get_dma_dev(ib->indio_dev, buffer);
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct iio_dmabuf_priv *priv;
|
||||
|
||||
guard(mutex)(&buffer->dmabufs_mutex);
|
||||
|
||||
list_for_each_entry(priv, &buffer->dmabufs, entry) {
|
||||
if (priv->attach->dev == dev
|
||||
if (priv->attach->dev == dma_dev
|
||||
&& priv->attach->dmabuf == dmabuf) {
|
||||
attach = priv->attach;
|
||||
break;
|
||||
@@ -1653,6 +1662,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
|
||||
{
|
||||
struct iio_dev *indio_dev = ib->indio_dev;
|
||||
struct iio_buffer *buffer = ib->buffer;
|
||||
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
|
||||
struct dma_buf_attachment *attach;
|
||||
struct iio_dmabuf_priv *priv, *each;
|
||||
struct dma_buf *dmabuf;
|
||||
@@ -1679,7 +1689,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
|
||||
goto err_free_priv;
|
||||
}
|
||||
|
||||
attach = dma_buf_attach(dmabuf, indio_dev->dev.parent);
|
||||
attach = dma_buf_attach(dmabuf, dma_dev);
|
||||
if (IS_ERR(attach)) {
|
||||
err = PTR_ERR(attach);
|
||||
goto err_dmabuf_put;
|
||||
@@ -1719,7 +1729,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
|
||||
* combo. If we do, refuse to attach.
|
||||
*/
|
||||
list_for_each_entry(each, &buffer->dmabufs, entry) {
|
||||
if (each->attach->dev == indio_dev->dev.parent
|
||||
if (each->attach->dev == dma_dev
|
||||
&& each->attach->dmabuf == dmabuf) {
|
||||
/*
|
||||
* We unlocked the reservation object, so going through
|
||||
@@ -1758,6 +1768,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
|
||||
{
|
||||
struct iio_buffer *buffer = ib->buffer;
|
||||
struct iio_dev *indio_dev = ib->indio_dev;
|
||||
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
|
||||
struct iio_dmabuf_priv *priv;
|
||||
struct dma_buf *dmabuf;
|
||||
int dmabuf_fd, ret = -EPERM;
|
||||
@@ -1772,7 +1783,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
|
||||
guard(mutex)(&buffer->dmabufs_mutex);
|
||||
|
||||
list_for_each_entry(priv, &buffer->dmabufs, entry) {
|
||||
if (priv->attach->dev == indio_dev->dev.parent
|
||||
if (priv->attach->dev == dma_dev
|
||||
&& priv->attach->dmabuf == dmabuf) {
|
||||
list_del(&priv->entry);
|
||||
|
||||
|
||||
@@ -1040,13 +1040,16 @@ static int bmp280_wait_conv(struct bmp280_data *data)
|
||||
unsigned int reg, meas_time_us;
|
||||
int ret;
|
||||
|
||||
/* Check if we are using a BME280 device */
|
||||
if (data->oversampling_humid)
|
||||
meas_time_us = BMP280_PRESS_HUMID_MEAS_OFFSET +
|
||||
BIT(data->oversampling_humid) * BMP280_MEAS_DUR;
|
||||
/* Constant part of the measurement time */
|
||||
meas_time_us = BMP280_MEAS_OFFSET;
|
||||
|
||||
else
|
||||
meas_time_us = 0;
|
||||
/*
|
||||
* Check if we are using a BME280 device,
|
||||
* Humidity measurement time
|
||||
*/
|
||||
if (data->chip_info->oversampling_humid_avail)
|
||||
meas_time_us += BMP280_PRESS_HUMID_MEAS_OFFSET +
|
||||
BIT(data->oversampling_humid) * BMP280_MEAS_DUR;
|
||||
|
||||
/* Pressure measurement time */
|
||||
meas_time_us += BMP280_PRESS_HUMID_MEAS_OFFSET +
|
||||
|
||||
@@ -174,5 +174,6 @@ int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer,
|
||||
size_t size, bool cyclic);
|
||||
void iio_dma_buffer_lock_queue(struct iio_buffer *buffer);
|
||||
void iio_dma_buffer_unlock_queue(struct iio_buffer *buffer);
|
||||
struct device *iio_dma_buffer_get_dma_dev(struct iio_buffer *buffer);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,7 @@ struct sg_table;
|
||||
* @enqueue_dmabuf: called from userspace via ioctl to queue this DMABUF
|
||||
* object to this buffer. Requires a valid DMABUF fd, that
|
||||
* was previouly attached to this buffer.
|
||||
* @get_dma_dev: called to get the DMA channel associated with this buffer.
|
||||
* @lock_queue: called when the core needs to lock the buffer queue;
|
||||
* it is used when enqueueing DMABUF objects.
|
||||
* @unlock_queue: used to unlock a previously locked buffer queue
|
||||
@@ -90,6 +91,7 @@ struct iio_buffer_access_funcs {
|
||||
struct iio_dma_buffer_block *block,
|
||||
struct dma_fence *fence, struct sg_table *sgt,
|
||||
size_t size, bool cyclic);
|
||||
struct device * (*get_dma_dev)(struct iio_buffer *buffer);
|
||||
void (*lock_queue)(struct iio_buffer *buffer);
|
||||
void (*unlock_queue)(struct iio_buffer *buffer);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user