mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'char-misc-6.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc / IIO fixes from Greg KH: "Here are some much-delayed char/misc/iio driver fixes for 6.18-rc8. Fixes in here include: - lots of iio driver bugfixes for reported issues. - counter driver bugfix - slimbus driver bugfix - mei tiny bugfix - nvmem layout uevent bugfix All of these have been in linux-next for a while, but due to travel on my side, I haven't had a chance to get them to you" * tag 'char-misc-6.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (23 commits) nvmem: layouts: fix nvmem_layout_bus_uevent iio: accel: bmc150: Fix irq assumption regression most: usb: fix double free on late probe failure slimbus: ngd: Fix reference count leak in qcom_slim_ngd_notify_slaves firmware: stratix10-svc: fix bug in saving controller data mei: fix error flow in probe 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 ...
This commit is contained in:
@@ -451,7 +451,7 @@ static void mchp_tc_irq_remove(void *ptr)
|
||||
static int mchp_tc_irq_enable(struct counter_device *const counter, int irq)
|
||||
{
|
||||
struct mchp_tc_data *const priv = counter_priv(counter);
|
||||
int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, 0,
|
||||
int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, IRQF_SHARED,
|
||||
dev_name(counter->parent), counter);
|
||||
|
||||
if (ret < 0)
|
||||
|
||||
@@ -134,6 +134,7 @@ struct stratix10_svc_data {
|
||||
* @complete_status: state for completion
|
||||
* @svc_fifo_lock: protect access to service message data queue
|
||||
* @invoke_fn: function to issue secure monitor call or hypervisor call
|
||||
* @svc: manages the list of client svc drivers
|
||||
*
|
||||
* This struct is used to create communication channels for service clients, to
|
||||
* handle secure monitor or hypervisor call.
|
||||
@@ -150,6 +151,7 @@ struct stratix10_svc_controller {
|
||||
struct completion complete_status;
|
||||
spinlock_t svc_fifo_lock;
|
||||
svc_invoke_fn *invoke_fn;
|
||||
struct stratix10_svc *svc;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1206,6 +1208,7 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
|
||||
ret = -ENOMEM;
|
||||
goto err_free_kfifo;
|
||||
}
|
||||
controller->svc = svc;
|
||||
|
||||
svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0);
|
||||
if (!svc->stratix10_svc_rsu) {
|
||||
@@ -1237,8 +1240,6 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_unregister_fcs_dev;
|
||||
|
||||
dev_set_drvdata(dev, svc);
|
||||
|
||||
pr_info("Intel Service Layer Driver Initialized\n");
|
||||
|
||||
return 0;
|
||||
@@ -1256,8 +1257,8 @@ err_destroy_pool:
|
||||
|
||||
static void stratix10_svc_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev);
|
||||
struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev);
|
||||
struct stratix10_svc *svc = ctrl->svc;
|
||||
|
||||
of_platform_depopulate(ctrl->dev);
|
||||
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -223,6 +223,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
hw->mem_addr = pcim_iomap_table(pdev)[0];
|
||||
hw->read_fws = mei_me_read_fws;
|
||||
|
||||
err = mei_register(dev, &pdev->dev);
|
||||
if (err)
|
||||
goto end;
|
||||
|
||||
pci_enable_msi(pdev);
|
||||
|
||||
hw->irq = pdev->irq;
|
||||
@@ -237,13 +241,9 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
|
||||
pdev->irq);
|
||||
goto end;
|
||||
goto deregister;
|
||||
}
|
||||
|
||||
err = mei_register(dev, &pdev->dev);
|
||||
if (err)
|
||||
goto release_irq;
|
||||
|
||||
if (mei_start(dev)) {
|
||||
dev_err(&pdev->dev, "init hw failure.\n");
|
||||
err = -ENODEV;
|
||||
@@ -283,11 +283,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return 0;
|
||||
|
||||
deregister:
|
||||
mei_deregister(dev);
|
||||
release_irq:
|
||||
mei_cancel_work(dev);
|
||||
mei_disable_interrupts(dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
mei_deregister(dev);
|
||||
end:
|
||||
dev_err(&pdev->dev, "initialization failed.\n");
|
||||
return err;
|
||||
|
||||
@@ -87,6 +87,10 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
hw = to_txe_hw(dev);
|
||||
hw->mem_addr = pcim_iomap_table(pdev);
|
||||
|
||||
err = mei_register(dev, &pdev->dev);
|
||||
if (err)
|
||||
goto end;
|
||||
|
||||
pci_enable_msi(pdev);
|
||||
|
||||
/* clear spurious interrupts */
|
||||
@@ -106,13 +110,9 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq = %d\n",
|
||||
pdev->irq);
|
||||
goto end;
|
||||
goto deregister;
|
||||
}
|
||||
|
||||
err = mei_register(dev, &pdev->dev);
|
||||
if (err)
|
||||
goto release_irq;
|
||||
|
||||
if (mei_start(dev)) {
|
||||
dev_err(&pdev->dev, "init hw failure.\n");
|
||||
err = -ENODEV;
|
||||
@@ -145,11 +145,10 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return 0;
|
||||
|
||||
deregister:
|
||||
mei_deregister(dev);
|
||||
release_irq:
|
||||
mei_cancel_work(dev);
|
||||
mei_disable_interrupts(dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
mei_deregister(dev);
|
||||
end:
|
||||
dev_err(&pdev->dev, "initialization failed.\n");
|
||||
return err;
|
||||
|
||||
@@ -362,28 +362,27 @@ static int mei_vsc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = mei_register(mei_dev, dev);
|
||||
if (ret)
|
||||
goto err_dereg;
|
||||
goto err;
|
||||
|
||||
ret = mei_start(mei_dev);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "init hw failed\n");
|
||||
goto err_cancel;
|
||||
goto err;
|
||||
}
|
||||
|
||||
pm_runtime_enable(mei_dev->parent);
|
||||
|
||||
return 0;
|
||||
|
||||
err_dereg:
|
||||
mei_deregister(mei_dev);
|
||||
|
||||
err_cancel:
|
||||
err:
|
||||
mei_cancel_work(mei_dev);
|
||||
|
||||
vsc_tp_register_event_cb(tp, NULL, NULL);
|
||||
|
||||
mei_disable_interrupts(mei_dev);
|
||||
|
||||
mei_deregister(mei_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
|
||||
ret = most_register_interface(&mdev->iface);
|
||||
if (ret)
|
||||
goto err_free_busy_urbs;
|
||||
return ret;
|
||||
|
||||
mutex_lock(&mdev->io_mutex);
|
||||
if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
|
||||
@@ -1068,8 +1068,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
if (!mdev->dci) {
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
most_deregister_interface(&mdev->iface);
|
||||
ret = -ENOMEM;
|
||||
goto err_free_busy_urbs;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mdev->dci->dev.init_name = "dci";
|
||||
@@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
mdev->dci->dev.release = release_dci;
|
||||
if (device_register(&mdev->dci->dev)) {
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
put_device(&mdev->dci->dev);
|
||||
most_deregister_interface(&mdev->iface);
|
||||
ret = -ENOMEM;
|
||||
goto err_free_dci;
|
||||
return -ENOMEM;
|
||||
}
|
||||
mdev->dci->usb_device = mdev->usb_device;
|
||||
}
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
return 0;
|
||||
err_free_dci:
|
||||
put_device(&mdev->dci->dev);
|
||||
err_free_busy_urbs:
|
||||
kfree(mdev->busy_urbs);
|
||||
|
||||
err_free_ep_address:
|
||||
kfree(mdev->ep_address);
|
||||
err_free_cap:
|
||||
|
||||
@@ -51,7 +51,7 @@ static int nvmem_layout_bus_uevent(const struct device *dev,
|
||||
int ret;
|
||||
|
||||
ret = of_device_uevent_modalias(dev, env);
|
||||
if (ret != ENODEV)
|
||||
if (ret != -ENODEV)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1241,6 +1241,7 @@ static void qcom_slim_ngd_notify_slaves(struct qcom_slim_ngd_ctrl *ctrl)
|
||||
|
||||
if (slim_get_logical_addr(sbdev))
|
||||
dev_err(ctrl->dev, "Failed to get logical address\n");
|
||||
put_device(&sbdev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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