Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-4.13a' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/jic23/iio into staging-linus

Jonathan writes:

First set of IIO fixes for the 4.13 cycle.

* ad2s1210
  - Fix negative angular velocity reads (identified by a gcc 7 warning)
* aspeed-adc
  - Wait for initialization sequence to finish before enabling channels.
  Without it no channels work.
* axp288
  - Revert a patch that dropped some bogus register mods.  No one is entirely
  sure why but it breaks charging on some devices.
  - Fix GPADC pin read returning 0. Turns out a small sleep is needed.
* bmc150
  - Make sure device is restored to normal state after suspend / resume
  cycle.  Otherwise, simple sysfs reads are broken.
* tsl2563
  - fix wrong event code.
* st-accel
  - add spi 3-wire support. Needed to fix the lsm303agr accelerometer
  which only had 3 wires in all cases.  Side effect is to enable optional
  3-wire support for other devices.
* st-pressure
  - disable multiread by default for LPS22HB (only effects SPI)
* sun4i-gpadc-iio
  - fix unbalanced irq enable / disable
* vf610
  - Fix VALT slection for REFSEL bits - ensures we are using the
  right reference pins.
  • Loading branch information
Greg Kroah-Hartman committed Jul 24, 2017
2 parents 520eccd + 737cc2a commit 055655a
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 15 deletions.
9 changes: 1 addition & 8 deletions drivers/iio/accel/bmc150-accel-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ struct bmc150_accel_data {
struct regmap *regmap;
int irq;
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
atomic_t active_intr;
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
struct mutex mutex;
u8 fifo_mode, watermark;
Expand Down Expand Up @@ -493,11 +492,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
goto out_fix_power_state;
}

if (state)
atomic_inc(&data->active_intr);
else
atomic_dec(&data->active_intr);

return 0;

out_fix_power_state:
Expand Down Expand Up @@ -1710,8 +1704,7 @@ static int bmc150_accel_resume(struct device *dev)
struct bmc150_accel_data *data = iio_priv(indio_dev);

mutex_lock(&data->mutex);
if (atomic_read(&data->active_intr))
bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
bmc150_accel_fifo_set_mode(data);
mutex_unlock(&data->mutex);

Expand Down
32 changes: 32 additions & 0 deletions drivers/iio/accel/st_accel_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x23,
.value = BIT(0),
},
.multi_read_bit = true,
.bootime = 2,
},
Expand Down Expand Up @@ -234,6 +238,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x23,
.value = BIT(0),
},
.multi_read_bit = true,
.bootime = 2,
},
Expand Down Expand Up @@ -316,6 +324,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.en_mask = 0x08,
},
},
.sim = {
.addr = 0x24,
.value = BIT(0),
},
.multi_read_bit = false,
.bootime = 2,
},
Expand Down Expand Up @@ -379,6 +391,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_int1 = 0x04,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x21,
.value = BIT(1),
},
.multi_read_bit = true,
.bootime = 2, /* guess */
},
Expand Down Expand Up @@ -437,6 +453,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x21,
.value = BIT(7),
},
.multi_read_bit = false,
.bootime = 2, /* guess */
},
Expand Down Expand Up @@ -499,6 +519,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.addr_ihl = 0x22,
.mask_ihl = 0x80,
},
.sim = {
.addr = 0x23,
.value = BIT(0),
},
.multi_read_bit = true,
.bootime = 2,
},
Expand Down Expand Up @@ -547,6 +571,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_int1 = 0x04,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x21,
.value = BIT(1),
},
.multi_read_bit = false,
.bootime = 2,
},
Expand Down Expand Up @@ -614,6 +642,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.sim = {
.addr = 0x23,
.value = BIT(0),
},
.multi_read_bit = true,
.bootime = 2,
},
Expand Down
26 changes: 26 additions & 0 deletions drivers/iio/adc/aspeed_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/iopoll.h>

#define ASPEED_RESOLUTION_BITS 10
#define ASPEED_CLOCKS_PER_SAMPLE 12
Expand All @@ -38,11 +39,17 @@

#define ASPEED_ENGINE_ENABLE BIT(0)

#define ASPEED_ADC_CTRL_INIT_RDY BIT(8)

#define ASPEED_ADC_INIT_POLLING_TIME 500
#define ASPEED_ADC_INIT_TIMEOUT 500000

struct aspeed_adc_model_data {
const char *model_name;
unsigned int min_sampling_rate; // Hz
unsigned int max_sampling_rate; // Hz
unsigned int vref_voltage; // mV
bool wait_init_sequence;
};

struct aspeed_adc_data {
Expand Down Expand Up @@ -211,6 +218,24 @@ static int aspeed_adc_probe(struct platform_device *pdev)
goto scaler_error;
}

model_data = of_device_get_match_data(&pdev->dev);

if (model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
data->base + ASPEED_REG_ENGINE_CONTROL);

/* Wait for initial sequence complete. */
ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL,
adc_engine_control_reg_val,
adc_engine_control_reg_val &
ASPEED_ADC_CTRL_INIT_RDY,
ASPEED_ADC_INIT_POLLING_TIME,
ASPEED_ADC_INIT_TIMEOUT);
if (ret)
goto scaler_error;
}

/* Start all channels in normal mode. */
ret = clk_prepare_enable(data->clk_scaler->clk);
if (ret)
Expand Down Expand Up @@ -274,6 +299,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
.vref_voltage = 1800, // mV
.min_sampling_rate = 1,
.max_sampling_rate = 1000000,
.wait_init_sequence = true,
};

static const struct of_device_id aspeed_adc_matches[] = {
Expand Down
42 changes: 41 additions & 1 deletion drivers/iio/adc/axp288_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <linux/iio/driver.h>

#define AXP288_ADC_EN_MASK 0xF1
#define AXP288_ADC_TS_PIN_GPADC 0xF2
#define AXP288_ADC_TS_PIN_ON 0xF3

enum axp288_adc_id {
AXP288_ADC_TS,
Expand Down Expand Up @@ -121,6 +123,26 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
return IIO_VAL_INT;
}

static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
unsigned long address)
{
int ret;

/* channels other than GPADC do not need to switch TS pin */
if (address != AXP288_GP_ADC_H)
return 0;

ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
if (ret)
return ret;

/* When switching to the GPADC pin give things some time to settle */
if (mode == AXP288_ADC_TS_PIN_GPADC)
usleep_range(6000, 10000);

return 0;
}

static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
Expand All @@ -131,7 +153,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
chan->address)) {
dev_err(&indio_dev->dev, "GPADC mode\n");
ret = -EINVAL;
break;
}
ret = axp288_adc_read_channel(val, chan->address, info->regmap);
if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
chan->address))
dev_err(&indio_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
Expand All @@ -141,6 +172,15 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
}

static int axp288_adc_set_state(struct regmap *regmap)
{
/* ADC should be always enabled for internal FG to function */
if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
return -EIO;

return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
}

static const struct iio_info axp288_adc_iio_info = {
.read_raw = &axp288_adc_read_raw,
.driver_module = THIS_MODULE,
Expand Down Expand Up @@ -169,7 +209,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected.
*/
ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
ret = axp288_adc_set_state(axp20x->regmap);
if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret;
Expand Down
3 changes: 1 addition & 2 deletions drivers/iio/adc/sun4i-gpadc-iio.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,

err:
pm_runtime_put_autosuspend(indio_dev->dev.parent);
disable_irq(irq);
mutex_unlock(&info->mutex);

return ret;
Expand Down Expand Up @@ -365,7 +366,6 @@ static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
complete(&info->completion);

out:
disable_irq_nosync(info->temp_data_irq);
return IRQ_HANDLED;
}

Expand All @@ -380,7 +380,6 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
complete(&info->completion);

out:
disable_irq_nosync(info->fifo_data_irq);
return IRQ_HANDLED;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/adc/vf610_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
#define VF610_ADC_ADSTS_MASK 0x300
#define VF610_ADC_ADLPC_EN 0x80
#define VF610_ADC_ADHSC_EN 0x400
#define VF610_ADC_REFSEL_VALT 0x100
#define VF610_ADC_REFSEL_VALT 0x800
#define VF610_ADC_REFSEL_VBG 0x1000
#define VF610_ADC_ADTRG_HARD 0x2000
#define VF610_ADC_AVGS_8 0x4000
Expand Down
29 changes: 29 additions & 0 deletions drivers/iio/common/st_sensors/st_sensors_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,31 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
}
EXPORT_SYMBOL(st_sensors_read_info_raw);

static int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
const struct st_sensor_settings *sensor_settings)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
struct device_node *np = sdata->dev->of_node;
struct st_sensors_platform_data *pdata;

pdata = (struct st_sensors_platform_data *)sdata->dev->platform_data;
if (((np && of_property_read_bool(np, "spi-3wire")) ||
(pdata && pdata->spi_3wire)) && sensor_settings->sim.addr) {
int err;

err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
sensor_settings->sim.addr,
sensor_settings->sim.value);
if (err < 0) {
dev_err(&indio_dev->dev,
"failed to init interface mode\n");
return err;
}
}

return 0;
}

int st_sensors_check_device_support(struct iio_dev *indio_dev,
int num_sensors_list,
const struct st_sensor_settings *sensor_settings)
Expand All @@ -574,6 +599,10 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
return -ENODEV;
}

err = st_sensors_init_interface_mode(indio_dev, &sensor_settings[i]);
if (err < 0)
return err;

if (sensor_settings[i].wai_addr) {
err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
sensor_settings[i].wai_addr, &wai);
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/light/tsl2563.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
struct tsl2563_chip *chip = iio_priv(dev_info);

iio_push_event(dev_info,
IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_EITHER),
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/pressure/st_pressure_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
.multi_read_bit = true,
.multi_read_bit = false,
.bootime = 2,
},
};
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/iio/resolver/ad2s1210.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad2s1210_state *st = iio_priv(indio_dev);
bool negative;
u16 negative;
int ret = 0;
u16 pos;
s16 vel;
Expand Down
7 changes: 7 additions & 0 deletions include/linux/iio/common/st_sensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ struct st_sensor_fullscale {
struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
};

struct st_sensor_sim {
u8 addr;
u8 value;
};

/**
* struct st_sensor_bdu - ST sensor device block data update
* @addr: address of the register.
Expand Down Expand Up @@ -197,6 +202,7 @@ struct st_sensor_transfer_function {
* @bdu: Block data update register.
* @das: Data Alignment Selection register.
* @drdy_irq: Data ready register of the sensor.
* @sim: SPI serial interface mode register of the sensor.
* @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
* @bootime: samples to discard when sensor passing from power-down to power-up.
*/
Expand All @@ -213,6 +219,7 @@ struct st_sensor_settings {
struct st_sensor_bdu bdu;
struct st_sensor_das das;
struct st_sensor_data_ready_irq drdy_irq;
struct st_sensor_sim sim;
bool multi_read_bit;
unsigned int bootime;
};
Expand Down
2 changes: 2 additions & 0 deletions include/linux/platform_data/st_sensors_pdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
* Available only for accelerometer and pressure sensors.
* Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet).
* @open_drain: set the interrupt line to be open drain if possible.
* @spi_3wire: enable spi-3wire mode.
*/
struct st_sensors_platform_data {
u8 drdy_int_pin;
bool open_drain;
bool spi_3wire;
};

#endif /* ST_SENSORS_PDATA_H */

0 comments on commit 055655a

Please sign in to comment.