Commit 99440286 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-6.2a' of...

Merge tag 'iio-fixes-for-6.2a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:
  "1st set of IIO fixes for the 6.2 cycle.

   The usual mixed bag - with a bunch of issues found by Carlos Song
   in the fxos8700 IMU driver dominating.

   hid-accel,gyro
    - Fix wrong returned value when read succeeds.
   marvell,berlin-adc
    - Missing of_node_put() in an error path.
   nxp,fxos8700 (freescale)
    - Wrong channel type match.
    - Swapped channel read back.
    - Incomplete channel read back (not enough bytes).
    - Missing shift of acceleration data.
    - Range selection didn't work (datasheet bug)
    - Wrong ODR mode read back due to wrong field offset.
    - Drop unused, but wrong define.
    - Fix issue with magnetometer scale an units.
   nxp,imx8qxp
    - Fix an irq flood due to not reading data early enough.
   st,lsm6dsx
    - Add CONFIG_IIO_TRIGGERED_BUFFER select.
   st,stm32-adc
    - Fix missing MODULE_DEVICE_TABLE() needed for module aliases.
   ti,twl6030
    - Fix missing enable of some channels.
    - Fix a typo in previous patch that meant one channel still wasn't enabled.
   xilinx,xadc
    - Carrying on incorrectly after allocation error."

* tag 'iio-fixes-for-6.2a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: imu: fxos8700: fix MAGN sensor scale and unit
  iio: imu: fxos8700: remove definition FXOS8700_CTRL_ODR_MIN
  iio: imu: fxos8700: fix failed initialization ODR mode assignment
  iio: imu: fxos8700: fix incorrect ODR mode readback
  iio: light: cm32181: Fix PM support on system with 2 I2C resources
  iio: hid: fix the retval in gyro_3d_capture_sample
  iio: hid: fix the retval in accel_3d_capture_sample
  iio: imu: st_lsm6dsx: fix build when CONFIG_IIO_TRIGGERED_BUFFER=m
  iio:adc:twl6030: Enable measurement of VAC
  iio: imu: fxos8700: fix ACCEL measurement range selection
  iio: imu: fxos8700: fix IMU data bits returned to user space
  iio: imu: fxos8700: fix incomplete ACCEL and MAGN channels readback
  iio: imu: fxos8700: fix swapped ACCEL and MAGN channels readback
  iio: imu: fxos8700: fix map label of channel type to MAGN sensor
  iio:adc:twl6030: Enable measurements of VUSB, VBAT and others
  iio: imx8qxp-adc: fix irq flood when call imx8qxp_adc_read_raw()
  iio: adc: xilinx-ams: fix devm_krealloc() return value check
  iio: adc: berlin2-adc: Add missing of_node_put() in error path
  iio: adc: stm32-dfsdm: fill module aliases
parents bf29ce87 2acd0313
......@@ -280,6 +280,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
hid_sensor_convert_timestamp(
&accel_state->common_attributes,
*(int64_t *)raw_data);
ret = 0;
break;
default:
break;
......
......@@ -298,8 +298,10 @@ static int berlin2_adc_probe(struct platform_device *pdev)
int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
if (!indio_dev)
if (!indio_dev) {
of_node_put(parent_np);
return -ENOMEM;
}
priv = iio_priv(indio_dev);
......
......@@ -86,6 +86,8 @@
#define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100)
#define IMX8QXP_ADC_MAX_FIFO_SIZE 16
struct imx8qxp_adc {
struct device *dev;
void __iomem *regs;
......@@ -95,6 +97,7 @@ struct imx8qxp_adc {
/* Serialise ADC channel reads */
struct mutex lock;
struct completion completion;
u32 fifo[IMX8QXP_ADC_MAX_FIFO_SIZE];
};
#define IMX8QXP_ADC_CHAN(_idx) { \
......@@ -238,8 +241,7 @@ static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev,
return ret;
}
*val = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK,
readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
*val = adc->fifo[0];
mutex_unlock(&adc->lock);
return IIO_VAL_INT;
......@@ -265,10 +267,15 @@ static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id)
{
struct imx8qxp_adc *adc = dev_id;
u32 fifo_count;
int i;
fifo_count = FIELD_GET(IMX8QXP_ADC_FCTRL_FCOUNT_MASK,
readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL));
for (i = 0; i < fifo_count; i++)
adc->fifo[i] = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK,
readl_relaxed(adc->regs + IMX8QXP_ADR_ADC_RESFIFO));
if (fifo_count)
complete(&adc->completion);
......
......@@ -1520,6 +1520,7 @@ static const struct of_device_id stm32_dfsdm_adc_match[] = {
},
{}
};
MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match);
static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
{
......
......@@ -57,6 +57,18 @@
#define TWL6030_GPADCS BIT(1)
#define TWL6030_GPADCR BIT(0)
#define USB_VBUS_CTRL_SET 0x04
#define USB_ID_CTRL_SET 0x06
#define TWL6030_MISC1 0xE4
#define VBUS_MEAS 0x01
#define ID_MEAS 0x01
#define VAC_MEAS 0x04
#define VBAT_MEAS 0x02
#define BB_MEAS 0x01
/**
* struct twl6030_chnl_calib - channel calibration
* @gain: slope coefficient for ideal curve
......@@ -927,6 +939,26 @@ static int twl6030_gpadc_probe(struct platform_device *pdev)
return ret;
}
ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
ret = twl_i2c_write_u8(TWL6030_MODULE_ID0,
VBAT_MEAS | BB_MEAS | VAC_MEAS,
TWL6030_MISC1);
if (ret < 0) {
dev_err(dev, "failed to wire up inputs\n");
return ret;
}
indio_dev->name = DRIVER_NAME;
indio_dev->info = &twl6030_gpadc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
......
......@@ -1329,7 +1329,7 @@ static int ams_parse_firmware(struct iio_dev *indio_dev)
dev_channels = devm_krealloc(dev, ams_channels, dev_size, GFP_KERNEL);
if (!dev_channels)
ret = -ENOMEM;
return -ENOMEM;
indio_dev->channels = dev_channels;
indio_dev->num_channels = num_channels;
......
......@@ -231,6 +231,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
gyro_state->timestamp =
hid_sensor_convert_timestamp(&gyro_state->common_attributes,
*(s64 *)raw_data);
ret = 0;
break;
default:
break;
......
......@@ -10,6 +10,7 @@
#include <linux/regmap.h>
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
......@@ -144,9 +145,8 @@
#define FXOS8700_NVM_DATA_BNK0 0xa7
/* Bit definitions for FXOS8700_CTRL_REG1 */
#define FXOS8700_CTRL_ODR_MSK 0x38
#define FXOS8700_CTRL_ODR_MAX 0x00
#define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3)
#define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3)
/* Bit definitions for FXOS8700_M_CTRL_REG1 */
#define FXOS8700_HMS_MASK GENMASK(1, 0)
......@@ -320,7 +320,7 @@ static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type)
switch (iio_type) {
case IIO_ACCEL:
return FXOS8700_ACCEL;
case IIO_ANGL_VEL:
case IIO_MAGN:
return FXOS8700_MAGN;
default:
return -EINVAL;
......@@ -345,15 +345,35 @@ static int fxos8700_set_active_mode(struct fxos8700_data *data,
static int fxos8700_set_scale(struct fxos8700_data *data,
enum fxos8700_sensor t, int uscale)
{
int i;
int i, ret, val;
bool active_mode;
static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
struct device *dev = regmap_get_device(data->regmap);
if (t == FXOS8700_MAGN) {
dev_err(dev, "Magnetometer scale is locked at 1200uT\n");
dev_err(dev, "Magnetometer scale is locked at 0.001Gs\n");
return -EINVAL;
}
/*
* When device is in active mode, it failed to set an ACCEL
* full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG.
* This is not align with the datasheet, but it is a fxos8700
* chip behavier. Set the device in standby mode before setting
* an ACCEL full-scale range.
*/
ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
if (ret)
return ret;
active_mode = val & FXOS8700_ACTIVE;
if (active_mode) {
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
val & ~FXOS8700_ACTIVE);
if (ret)
return ret;
}
for (i = 0; i < scale_num; i++)
if (fxos8700_accel_scale[i].uscale == uscale)
break;
......@@ -361,8 +381,12 @@ static int fxos8700_set_scale(struct fxos8700_data *data,
if (i == scale_num)
return -EINVAL;
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
fxos8700_accel_scale[i].bits);
if (ret)
return ret;
return regmap_write(data->regmap, FXOS8700_CTRL_REG1,
active_mode);
}
static int fxos8700_get_scale(struct fxos8700_data *data,
......@@ -372,7 +396,7 @@ static int fxos8700_get_scale(struct fxos8700_data *data,
static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
if (t == FXOS8700_MAGN) {
*uscale = 1200; /* Magnetometer is locked at 1200uT */
*uscale = 1000; /* Magnetometer is locked at 0.001Gs */
return 0;
}
......@@ -394,22 +418,61 @@ static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
int axis, int *val)
{
u8 base, reg;
s16 tmp;
int ret;
enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB;
/*
* Different register base addresses varies with channel types.
* This bug hasn't been noticed before because using an enum is
* really hard to read. Use an a switch statement to take over that.
*/
switch (chan_type) {
case IIO_ACCEL:
base = FXOS8700_OUT_X_MSB;
break;
case IIO_MAGN:
base = FXOS8700_M_OUT_X_MSB;
break;
default:
return -EINVAL;
}
/* Block read 6 bytes of device output registers to avoid data loss */
ret = regmap_bulk_read(data->regmap, base, data->buf,
FXOS8700_DATA_BUF_SIZE);
sizeof(data->buf));
if (ret)
return ret;
/* Convert axis to buffer index */
reg = axis - IIO_MOD_X;
/*
* Convert to native endianness. The accel data and magn data
* are signed, so a forced type conversion is needed.
*/
tmp = be16_to_cpu(data->buf[reg]);
/*
* ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
* 14-bit left-justified sample data and MAGN output data registers
* contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply
* a signed 2 bits right shift to the readback raw data from ACCEL
* output data register and keep that from MAGN sensor as the origin.
* Value should be extended to 32 bit.
*/
switch (chan_type) {
case IIO_ACCEL:
tmp = tmp >> 2;
break;
case IIO_MAGN:
/* Nothing to do */
break;
default:
return -EINVAL;
}
/* Convert to native endianness */
*val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
*val = sign_extend32(tmp, 15);
return 0;
}
......@@ -445,10 +508,9 @@ static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
if (i >= odr_num)
return -EINVAL;
return regmap_update_bits(data->regmap,
FXOS8700_CTRL_REG1,
FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE,
fxos8700_odr[i].bits << 3 | active_mode);
val &= ~FXOS8700_CTRL_ODR_MSK;
val |= FIELD_PREP(FXOS8700_CTRL_ODR_MSK, fxos8700_odr[i].bits) | FXOS8700_ACTIVE;
return regmap_write(data->regmap, FXOS8700_CTRL_REG1, val);
}
static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
......@@ -461,7 +523,7 @@ static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
if (ret)
return ret;
val &= FXOS8700_CTRL_ODR_MSK;
val = FIELD_GET(FXOS8700_CTRL_ODR_MSK, val);
for (i = 0; i < odr_num; i++)
if (val == fxos8700_odr[i].bits)
......@@ -526,7 +588,7 @@ static IIO_CONST_ATTR(in_accel_sampling_frequency_available,
static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
"1.5625 6.25 12.5 50 100 200 400 800");
static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200");
static IIO_CONST_ATTR(in_magn_scale_available, "0.001000");
static struct attribute *fxos8700_attrs[] = {
&iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
......@@ -592,14 +654,19 @@ static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
if (ret)
return ret;
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
/*
* Set max full-scale range (+/-8G) for ACCEL sensor in chip
* initialization then activate the device.
*/
ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
if (ret)
return ret;
/* Set for max full-scale range (+/-8G) */
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
return regmap_update_bits(data->regmap, FXOS8700_CTRL_REG1,
FXOS8700_CTRL_ODR_MSK | FXOS8700_ACTIVE,
FIELD_PREP(FXOS8700_CTRL_ODR_MSK, FXOS8700_CTRL_ODR_MAX) |
FXOS8700_ACTIVE);
}
static void fxos8700_chip_uninit(void *data)
......
......@@ -4,6 +4,7 @@ config IIO_ST_LSM6DSX
tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors"
depends on (I2C || SPI || I3C)
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IIO_KFIFO_BUF
select IIO_ST_LSM6DSX_I2C if (I2C)
select IIO_ST_LSM6DSX_SPI if (SPI_MASTER)
......
......@@ -440,6 +440,8 @@ static int cm32181_probe(struct i2c_client *client)
if (!indio_dev)
return -ENOMEM;
i2c_set_clientdata(client, indio_dev);
/*
* Some ACPI systems list 2 I2C resources for the CM3218 sensor, the
* SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address.
......@@ -460,8 +462,6 @@ static int cm32181_probe(struct i2c_client *client)
return PTR_ERR(client);
}
i2c_set_clientdata(client, indio_dev);
cm32181 = iio_priv(indio_dev);
cm32181->client = client;
cm32181->dev = dev;
......@@ -490,7 +490,8 @@ static int cm32181_probe(struct i2c_client *client)
static int cm32181_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev));
struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
CM32181_CMD_ALS_DISABLE);
......@@ -498,8 +499,8 @@ static int cm32181_suspend(struct device *dev)
static int cm32181_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev));
struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
......
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