aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-03 22:27:46 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-03 22:27:46 +0200
commit74eb9c06b1d722468db397595ac6834b9e4ac235 (patch)
treea201cde5eb2ce3f1785f4f4c2a650782e5c967b8 /drivers/staging
parentstaging: exfat: drop local TRUE/FALSE defines (diff)
parentiio: imu: st_lsm6dsx: rely on IIO_G_TO_M_S_2 for gain definition for LSM9DS1 (diff)
downloadlinux-dev-74eb9c06b1d722468db397595ac6834b9e4ac235.tar.xz
linux-dev-74eb9c06b1d722468db397595ac6834b9e4ac235.zip
Merge tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: Second set of new device support, cleanups and features for IIO in the 5.4 cycle Revised pull request to fix up a missing Signed-off-by and roll in a fix in the lsm9ds1 support after I broke it when applying. Revised again because the fix changed a hash meaning a fix that previously followed it now had the wrong fixes tag. A few fixes in here that could have gone a faster path but aren't quite worth the rush for 5.3. New device support * ad7606 - Support the ad7606b which adds a software controlled mode alongside the pin controlled only approach of the ad7606. Including dt-bindings. * lsm6dsx - Add support for the gyro and accelerometer part of the lsm9ds1 which is a compound device also including a magnetometer (st_sensors driver). Includes bindings and precursor rework of the driver. Features * ad7192 - Add support for low pass filter control. - DT binding docs. Cleanups and minor fixes * MAINTAINERS - Fix a typo in a path. - Add entry for ad7606 * ad5380 - Fix a failure to dereference a pointer before atempting to assign the value. * ad7192 - Drop platform data as not used in mainline and we now have full DT bindings. * ad7606 - YAML conversion for dt-bindings. * adis16240 - Rework write_raw to make it more readable using GENMASK. * adis16460 - Fix and issue with an unsigned variable holding potential negatives. * cros_ec - Fix missing default of calibration vector so that we get 'something' before calibration is complete on a given axis. * hid-sensors - Use int_pow instead of opencoding. * isl29501 - rename dt-binding docs to include renesas inline with other renesas parts and general current convention. * kxcjk1013 - Improve comments on the 'unusual' ACPI ids used to identify which sensor is which in certain laptops. * lsm6dsx - Add one bit to the fifo status masks for a number of parts. - Drop a reserved entry from the sensitivity values to tidy up interface. - Use core conversion macro from G to m/s^2 for lsm9ds1 to make it easier to relate to the datasheet and consistent with other parts supported. * max1027 - Use device managed APIs to avoid manual error handling and cleanup. * rfd77402 - Typo in Kconfig help. * sc27xx - Switch to polling mode from interrupts as interrupt handling typically to slow for very short sleeps. * st-sensors - Fix some missing selects for regmap. * tools - Add a .gitignore containing the binary outputs. * tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (27 commits) iio: imu: st_lsm6dsx: rely on IIO_G_TO_M_S_2 for gain definition for LSM9DS1 iio: imu: st_lsm6dsx: remove invalid gain value for LSM9DS1 iio: cros_ec: set calibscale for 3d MEMS to unit vector iio: dac: ad5380: fix incorrect assignment to val iio: imu: st_lsm6dsx: Fix FIFO diff mask for tagged fifo dt-bindings: iio: imu: st_lsm6dsx: add lsm9ds1 device bindings iio: imu: st_lsm6dsx: add support for accel/gyro unit of lsm9ds1 iio: imu: st_lsm6dsx: move register definitions to sensor_settings struct iio: imu: st_lsm6dsx: introduce update_fifo function pointer dt-bindings: iio: light: isl29501: Rename bindings documentation file Kconfig: Fix the reference to the RFD77402 ToF sensor in the 'help' section iio: st_sensors: Fix build error dt-bindings: iio: adc: Add AD7606B ADC documentation dt-bindings: iio: adc: Migrate AD7606 documentation to yaml MAINTAINERS: Add Beniamin Bia for AD7606 driver iio: adc: ad7606: Add support for AD7606B ADC tools: iio: add .gitignore iio: adc: sc27xx: Change to polling mode to read data iio: hid-sensor-attributes: Convert to use int_pow() iio: adc: max1027: Use device-managed APIs ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/iio/accel/adis16240.c5
-rw-r--r--drivers/staging/iio/adc/ad7192.c163
-rw-r--r--drivers/staging/iio/adc/ad7192.h37
3 files changed, 136 insertions, 69 deletions
diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c
index 62f4b3b1b457..82099db4bf0c 100644
--- a/drivers/staging/iio/accel/adis16240.c
+++ b/drivers/staging/iio/accel/adis16240.c
@@ -309,15 +309,12 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct adis *st = iio_priv(indio_dev);
- int bits = 10;
- s16 val16;
u8 addr;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
- val16 = val & ((1 << bits) - 1);
addr = adis16240_addresses[chan->scan_index][0];
- return adis_write_reg_16(st, addr, val16);
+ return adis_write_reg_16(st, addr, val & GENMASK(9, 0));
}
return -EINVAL;
}
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index df06e0570f9b..e6b660489165 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -25,8 +25,6 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/adc/ad_sigma_delta.h>
-#include "ad7192.h"
-
/* Registers */
#define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */
#define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */
@@ -145,6 +143,10 @@
#define AD7192_EXT_FREQ_MHZ_MAX 5120000
#define AD7192_INT_FREQ_MHZ 4915200
+#define AD7192_NO_SYNC_FILTER 1
+#define AD7192_SYNC3_FILTER 3
+#define AD7192_SYNC4_FILTER 4
+
/* NOTE:
* The AD7190/2/5 features a dual use data out ready DOUT/RDY output.
* In order to avoid contentions on the SPI bus, it's therefore necessary
@@ -252,7 +254,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st)
static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
{
struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi);
- bool rej60_en, sinc3_en, refin2_en, chop_en;
+ bool rej60_en, refin2_en;
bool buf_en, bipolar, burnout_curr_en;
unsigned long long scale_uv;
int i, ret, id;
@@ -284,24 +286,12 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
if (rej60_en)
st->mode |= AD7192_MODE_REJ60;
- sinc3_en = of_property_read_bool(np, "adi,sinc3-filter-enable");
- if (sinc3_en)
- st->mode |= AD7192_MODE_SINC3;
-
refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable");
if (refin2_en && st->devid != ID_AD7195)
st->conf |= AD7192_CONF_REFSEL;
- chop_en = of_property_read_bool(np, "adi,chop-enable");
- if (chop_en) {
- st->conf |= AD7192_CONF_CHOP;
- if (sinc3_en)
- st->f_order = 3; /* SINC 3rd order */
- else
- st->f_order = 4; /* SINC 4th order */
- } else {
- st->f_order = 1;
- }
+ st->conf &= ~AD7192_CONF_CHOP;
+ st->f_order = AD7192_NO_SYNC_FILTER;
buf_en = of_property_read_bool(np, "adi,buffer-enable");
if (buf_en)
@@ -313,7 +303,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
burnout_curr_en = of_property_read_bool(np,
"adi,burnout-currents-enable");
- if (burnout_curr_en && buf_en && !chop_en) {
+ if (burnout_curr_en && buf_en) {
st->conf |= AD7192_CONF_BURN;
} else if (burnout_curr_en) {
dev_warn(&st->sd.spi->dev,
@@ -411,6 +401,49 @@ static ssize_t ad7192_set(struct device *dev,
return ret ? ret : len;
}
+static void ad7192_get_available_filter_freq(struct ad7192_state *st,
+ int *freq)
+{
+ unsigned int fadc;
+
+ /* Formulas for filter at page 25 of the datasheet */
+ fadc = DIV_ROUND_CLOSEST(st->fclk,
+ AD7192_SYNC4_FILTER * AD7192_MODE_RATE(st->mode));
+ freq[0] = DIV_ROUND_CLOSEST(fadc * 240, 1024);
+
+ fadc = DIV_ROUND_CLOSEST(st->fclk,
+ AD7192_SYNC3_FILTER * AD7192_MODE_RATE(st->mode));
+ freq[1] = DIV_ROUND_CLOSEST(fadc * 240, 1024);
+
+ fadc = DIV_ROUND_CLOSEST(st->fclk, AD7192_MODE_RATE(st->mode));
+ freq[2] = DIV_ROUND_CLOSEST(fadc * 230, 1024);
+ freq[3] = DIV_ROUND_CLOSEST(fadc * 272, 1024);
+}
+
+static ssize_t ad7192_show_filter_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad7192_state *st = iio_priv(indio_dev);
+ unsigned int freq_avail[4], i;
+ size_t len = 0;
+
+ ad7192_get_available_filter_freq(st, freq_avail);
+
+ for (i = 0; i < ARRAY_SIZE(freq_avail); i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d.%d ", freq_avail[i] / 1000,
+ freq_avail[i] % 1000);
+
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(filter_low_pass_3db_frequency_available,
+ 0444, ad7192_show_filter_avail, NULL, 0);
+
static IIO_DEVICE_ATTR(bridge_switch_en, 0644,
ad7192_show_bridge_switch, ad7192_set,
AD7192_REG_GPOCON);
@@ -420,6 +453,7 @@ static IIO_DEVICE_ATTR(ac_excitation_en, 0644,
AD7192_REG_MODE);
static struct attribute *ad7192_attributes[] = {
+ &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr,
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
&iio_dev_attr_ac_excitation_en.dev_attr.attr,
NULL
@@ -430,6 +464,7 @@ static const struct attribute_group ad7192_attribute_group = {
};
static struct attribute *ad7195_attributes[] = {
+ &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr,
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
NULL
};
@@ -443,6 +478,75 @@ static unsigned int ad7192_get_temp_scale(bool unipolar)
return unipolar ? 2815 * 2 : 2815;
}
+static int ad7192_set_3db_filter_freq(struct ad7192_state *st,
+ int val, int val2)
+{
+ int freq_avail[4], i, ret, freq;
+ unsigned int diff_new, diff_old;
+ int idx = 0;
+
+ diff_old = U32_MAX;
+ freq = val * 1000 + val2;
+
+ ad7192_get_available_filter_freq(st, freq_avail);
+
+ for (i = 0; i < ARRAY_SIZE(freq_avail); i++) {
+ diff_new = abs(freq - freq_avail[i]);
+ if (diff_new < diff_old) {
+ diff_old = diff_new;
+ idx = i;
+ }
+ }
+
+ switch (idx) {
+ case 0:
+ st->f_order = AD7192_SYNC4_FILTER;
+ st->mode &= ~AD7192_MODE_SINC3;
+
+ st->conf |= AD7192_CONF_CHOP;
+ break;
+ case 1:
+ st->f_order = AD7192_SYNC3_FILTER;
+ st->mode |= AD7192_MODE_SINC3;
+
+ st->conf |= AD7192_CONF_CHOP;
+ break;
+ case 2:
+ st->f_order = AD7192_NO_SYNC_FILTER;
+ st->mode &= ~AD7192_MODE_SINC3;
+
+ st->conf &= ~AD7192_CONF_CHOP;
+ break;
+ case 3:
+ st->f_order = AD7192_NO_SYNC_FILTER;
+ st->mode |= AD7192_MODE_SINC3;
+
+ st->conf &= ~AD7192_CONF_CHOP;
+ break;
+ }
+
+ ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
+ if (ret < 0)
+ return ret;
+
+ return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf);
+}
+
+static int ad7192_get_3db_filter_freq(struct ad7192_state *st)
+{
+ unsigned int fadc;
+
+ fadc = DIV_ROUND_CLOSEST(st->fclk,
+ st->f_order * AD7192_MODE_RATE(st->mode));
+
+ if (st->conf & AD7192_CONF_CHOP)
+ return DIV_ROUND_CLOSEST(fadc * 240, 1024);
+ if (st->mode & AD7192_MODE_SINC3)
+ return DIV_ROUND_CLOSEST(fadc * 272, 1024);
+ else
+ return DIV_ROUND_CLOSEST(fadc * 230, 1024);
+}
+
static int ad7192_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@@ -483,6 +587,10 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
*val = st->fclk /
(st->f_order * 1024 * AD7192_MODE_RATE(st->mode));
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ *val = ad7192_get_3db_filter_freq(st);
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
}
return -EINVAL;
@@ -537,6 +645,9 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
st->mode |= AD7192_MODE_RATE(div);
ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
break;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ ret = ad7192_set_3db_filter_freq(st, val, val2 / 1000);
+ break;
default:
ret = -EINVAL;
}
@@ -555,6 +666,8 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_SAMP_FREQ:
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
@@ -655,6 +768,8 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
for (i = 0; i < indio_dev->num_channels; i++) {
*chan = channels[i];
+ chan->info_mask_shared_by_all |=
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY);
if (chan->type != IIO_TEMP)
chan->info_mask_shared_by_type_available |=
BIT(IIO_CHAN_INFO_SCALE);
@@ -666,16 +781,10 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
static int ad7192_probe(struct spi_device *spi)
{
- const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev);
struct ad7192_state *st;
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
- if (!pdata) {
- dev_err(&spi->dev, "no platform data?\n");
- return -ENODEV;
- }
-
if (!spi->irq) {
dev_err(&spi->dev, "no IRQ?\n");
return -ENODEV;
@@ -713,12 +822,10 @@ static int ad7192_probe(struct spi_device *spi)
voltage_uv = regulator_get_voltage(st->avdd);
- if (pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (voltage_uv)
+ if (voltage_uv)
st->int_vref_mv = voltage_uv / 1000;
else
- dev_warn(&spi->dev, "reference voltage undefined\n");
+ dev_err(&spi->dev, "Device tree error, reference voltage undefined\n");
spi_set_drvdata(spi, indio_dev);
st->devid = spi_get_device_id(spi)->driver_data;
diff --git a/drivers/staging/iio/adc/ad7192.h b/drivers/staging/iio/adc/ad7192.h
deleted file mode 100644
index f3669e1df084..000000000000
--- a/drivers/staging/iio/adc/ad7192.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * AD7190 AD7192 AD7195 SPI ADC driver
- *
- * Copyright 2011 Analog Devices Inc.
- */
-#ifndef IIO_ADC_AD7192_H_
-#define IIO_ADC_AD7192_H_
-
-/*
- * TODO: struct ad7192_platform_data needs to go into include/linux/iio
- */
-
-/**
- * struct ad7192_platform_data - platform/board specific information
- * @vref_mv: the external reference voltage in millivolt
- * @clock_source_sel: [0..3]
- * 0 External 4.92 MHz clock connected from MCLK1 to MCLK2
- * 1 External Clock applied to MCLK2
- * 2 Internal 4.92 MHz Clock not available at the MCLK2 pin
- * 3 Internal 4.92 MHz Clock available at the MCLK2 pin
- * @ext_clk_Hz: the external clock frequency in Hz, if not set
- * the driver uses the internal clock (16.776 MHz)
- * @refin2_en: REFIN1/REFIN2 Reference Select (AD7190/2 only)
- * @rej60_en: 50/60Hz notch filter enable
- * @sinc3_en: SINC3 filter enable (default SINC4)
- * @chop_en: CHOP mode enable
- * @buf_en: buffered input mode enable
- * @unipolar_en: unipolar mode enable
- * @burnout_curr_en: constant current generators on AIN(+|-) enable
- */
-
-struct ad7192_platform_data {
- u16 vref_mv;
-};
-
-#endif /* IIO_ADC_AD7192_H_ */