Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c5dfdbb authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'iio-fixes-for-4.2b' of...

Merge tag 'iio-fixes-for-4.2b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Jonathan writes:

Second set of IIO fixes for the 4.2 cycle. Note these depend (mostly) on
material in the recent merge window, hence their separation from set (a)
as the fixes-togreg branch predated the merge window.  I am running rather
later with these than I would have liked hence the large set.

* stk3310 fixes from Hartmut's review that came in post merge
  - fix direction of proximity inline with recent documentation
    clarification.
  - fix missing REGMAP_I2C dependency
  - rework the error handling for raw readings to fix an failure to power
    down in the event of a raw reading failing.
  - fix a bug in the compensation code which was toggling an extra bit in the
    register.
* mmc35240 - reported samplign frequencies were wrong.
* ltr501 fixes
  - fix a case of returning the return value of a regmap_read instead of
    the value read.
  - fix missing regmap dependency
* sx9500 - fix missing default values for ret in a couple of places to handle
  the case of no enabled channels.
* tmp006 - check that writes to info_mask elements are actually to writable
  ones.  Otherwise, writing to any of them will change the sampling frequency.
parents a732cd43 8d05abfa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ config SENSORS_LM3533
config LTR501
	tristate "LTR-501ALS-01 light sensor"
	depends on I2C
	select REGMAP_I2C
	select IIO_BUFFER
	select IIO_TRIGGERED_BUFFER
	help
@@ -201,6 +202,7 @@ config LTR501
config STK3310
	tristate "STK3310 ALS and proximity sensor"
	depends on I2C
	select REGMAP_I2C
	help
	 Say yes here to get support for the Sensortek STK3310 ambient light
	 and proximity sensor. The STK3311 model is also supported by this
+1 −1
Original line number Diff line number Diff line
@@ -1302,7 +1302,7 @@ static int ltr501_init(struct ltr501_data *data)
	if (ret < 0)
		return ret;

	data->als_contr = ret | data->chip_info->als_mode_active;
	data->als_contr = status | data->chip_info->als_mode_active;

	ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status);
	if (ret < 0)
+17 −36
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@
#define STK3311_CHIP_ID_VAL			0x1D
#define STK3310_PSINT_EN			0x01
#define STK3310_PS_MAX_VAL			0xFFFF
#define STK3310_THRESH_MAX			0xFFFF

#define STK3310_DRIVER_NAME			"stk3310"
#define STK3310_REGMAP_NAME			"stk3310_regmap"
@@ -84,15 +83,13 @@ static const struct reg_field stk3310_reg_field_flag_psint =
				REG_FIELD(STK3310_REG_FLAG, 4, 4);
static const struct reg_field stk3310_reg_field_flag_nf =
				REG_FIELD(STK3310_REG_FLAG, 0, 0);
/*
 * Maximum PS values with regard to scale. Used to export the 'inverse'
 * PS value (high values for far objects, low values for near objects).
 */

/* Estimate maximum proximity values with regard to measurement scale. */
static const int stk3310_ps_max[4] = {
	STK3310_PS_MAX_VAL / 64,
	STK3310_PS_MAX_VAL / 16,
	STK3310_PS_MAX_VAL /  4,
	STK3310_PS_MAX_VAL,
	STK3310_PS_MAX_VAL / 640,
	STK3310_PS_MAX_VAL / 160,
	STK3310_PS_MAX_VAL /  40,
	STK3310_PS_MAX_VAL /  10
};

static const int stk3310_scale_table[][2] = {
@@ -128,14 +125,14 @@ static const struct iio_event_spec stk3310_events[] = {
	/* Proximity event */
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_FALLING,
		.dir = IIO_EV_DIR_RISING,
		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
				 BIT(IIO_EV_INFO_ENABLE),
	},
	/* Out-of-proximity event */
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_RISING,
		.dir = IIO_EV_DIR_FALLING,
		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
				 BIT(IIO_EV_INFO_ENABLE),
	},
@@ -205,23 +202,16 @@ static int stk3310_read_event(struct iio_dev *indio_dev,
	u8 reg;
	u16 buf;
	int ret;
	unsigned int index;
	struct stk3310_data *data = iio_priv(indio_dev);

	if (info != IIO_EV_INFO_VALUE)
		return -EINVAL;

	/*
	 * Only proximity interrupts are implemented at the moment.
	 * Since we're inverting proximity values, the sensor's 'high'
	 * threshold will become our 'low' threshold, associated with
	 * 'near' events. Similarly, the sensor's 'low' threshold will
	 * be our 'high' threshold, associated with 'far' events.
	 */
	/* Only proximity interrupts are implemented at the moment. */
	if (dir == IIO_EV_DIR_RISING)
		reg = STK3310_REG_THDL_PS;
	else if (dir == IIO_EV_DIR_FALLING)
		reg = STK3310_REG_THDH_PS;
	else if (dir == IIO_EV_DIR_FALLING)
		reg = STK3310_REG_THDL_PS;
	else
		return -EINVAL;

@@ -232,8 +222,7 @@ static int stk3310_read_event(struct iio_dev *indio_dev,
		dev_err(&data->client->dev, "register read failed\n");
		return ret;
	}
	regmap_field_read(data->reg_ps_gain, &index);
	*val = swab16(stk3310_ps_max[index] - buf);
	*val = swab16(buf);

	return IIO_VAL_INT;
}
@@ -257,13 +246,13 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
		return -EINVAL;

	if (dir == IIO_EV_DIR_RISING)
		reg = STK3310_REG_THDL_PS;
	else if (dir == IIO_EV_DIR_FALLING)
		reg = STK3310_REG_THDH_PS;
	else if (dir == IIO_EV_DIR_FALLING)
		reg = STK3310_REG_THDL_PS;
	else
		return -EINVAL;

	buf = swab16(stk3310_ps_max[index] - val);
	buf = swab16(val);
	ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
	if (ret < 0)
		dev_err(&client->dev, "failed to set PS threshold!\n");
@@ -334,14 +323,6 @@ static int stk3310_read_raw(struct iio_dev *indio_dev,
			return ret;
		}
		*val = swab16(buf);
		if (chan->type == IIO_PROXIMITY) {
			/*
			 * Invert the proximity data so we return low values
			 * for close objects and high values for far ones.
			 */
			regmap_field_read(data->reg_ps_gain, &index);
			*val = stk3310_ps_max[index] - *val;
		}
		mutex_unlock(&data->lock);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_INT_TIME:
@@ -581,8 +562,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private)
	}
	event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
				     IIO_EV_TYPE_THRESH,
				     (dir ? IIO_EV_DIR_RISING :
					    IIO_EV_DIR_FALLING));
				     (dir ? IIO_EV_DIR_FALLING :
					    IIO_EV_DIR_RISING));
	iio_push_event(indio_dev, event, data->timestamp);

	/* Reset the interrupt flag */
+21 −14
Original line number Diff line number Diff line
@@ -84,10 +84,10 @@
#define MMC35240_OTP_START_ADDR		0x1B

enum mmc35240_resolution {
	MMC35240_16_BITS_SLOW = 0, /* 100 Hz */
	MMC35240_16_BITS_FAST,     /* 200 Hz */
	MMC35240_14_BITS,          /* 333 Hz */
	MMC35240_12_BITS,          /* 666 Hz */
	MMC35240_16_BITS_SLOW = 0, /* 7.92 ms */
	MMC35240_16_BITS_FAST,     /* 4.08 ms */
	MMC35240_14_BITS,          /* 2.16 ms */
	MMC35240_12_BITS,          /* 1.20 ms */
};

enum mmc35240_axis {
@@ -100,22 +100,22 @@ static const struct {
	int sens[3]; /* sensitivity per X, Y, Z axis */
	int nfo; /* null field output */
} mmc35240_props_table[] = {
	/* 16 bits, 100Hz ODR */
	/* 16 bits, 125Hz ODR */
	{
		{1024, 1024, 1024},
		32768,
	},
	/* 16 bits, 200Hz ODR */
	/* 16 bits, 250Hz ODR */
	{
		{1024, 1024, 770},
		32768,
	},
	/* 14 bits, 333Hz ODR */
	/* 14 bits, 450Hz ODR */
	{
		{256, 256, 193},
		8192,
	},
	/* 12 bits, 666Hz ODR */
	/* 12 bits, 800Hz ODR */
	{
		{64, 64, 48},
		2048,
@@ -133,9 +133,15 @@ struct mmc35240_data {
	int axis_scale[3];
};

static const int mmc35240_samp_freq[] = {100, 200, 333, 666};
static const struct {
	int val;
	int val2;
} mmc35240_samp_freq[] = { {1, 500000},
			   {13, 0},
			   {25, 0},
			   {50, 0} };

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100 200 333 666");
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1.5 13 25 50");

#define MMC35240_CHANNEL(_axis) { \
	.type = IIO_MAGN, \
@@ -168,7 +174,8 @@ static int mmc35240_get_samp_freq_index(struct mmc35240_data *data,
	int i;

	for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); i++)
		if (mmc35240_samp_freq[i] == val)
		if (mmc35240_samp_freq[i].val == val &&
		    mmc35240_samp_freq[i].val2 == val2)
			return i;
	return -EINVAL;
}
@@ -378,9 +385,9 @@ static int mmc35240_read_raw(struct iio_dev *indio_dev,
		if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq))
			return -EINVAL;

		*val = mmc35240_samp_freq[i];
		*val2 = 0;
		return IIO_VAL_INT;
		*val = mmc35240_samp_freq[i].val;
		*val2 = mmc35240_samp_freq[i].val2;
		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
+14 −12
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@
#define SX9500_COMPSTAT_MASK		GENMASK(3, 0)

#define SX9500_NUM_CHANNELS		4
#define SX9500_CHAN_MASK		GENMASK(SX9500_NUM_CHANNELS - 1, 0)

struct sx9500_data {
	struct mutex mutex;
@@ -329,20 +330,20 @@ static int sx9500_read_proximity(struct sx9500_data *data,
	else
		ret = sx9500_wait_for_sample(data);

	if (ret < 0)
		return ret;

	mutex_lock(&data->mutex);

	ret = sx9500_read_prox_data(data, chan, val);
	if (ret < 0)
		goto out;
		goto out_dec_data_rdy;

	ret = sx9500_dec_chan_users(data, chan->channel);
	ret = sx9500_read_prox_data(data, chan, val);
	if (ret < 0)
		goto out;
		goto out_dec_data_rdy;

	ret = sx9500_dec_data_rdy_users(data);
	if (ret < 0)
		goto out_dec_chan;

	ret = sx9500_dec_chan_users(data, chan->channel);
	if (ret < 0)
		goto out;

@@ -350,6 +351,8 @@ static int sx9500_read_proximity(struct sx9500_data *data,

	goto out;

out_dec_data_rdy:
	sx9500_dec_data_rdy_users(data);
out_dec_chan:
	sx9500_dec_chan_users(data, chan->channel);
out:
@@ -679,7 +682,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private)
static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
{
	struct sx9500_data *data = iio_priv(indio_dev);
	int ret, i;
	int ret = 0, i;

	mutex_lock(&data->mutex);

@@ -703,7 +706,7 @@ static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
static int sx9500_buffer_predisable(struct iio_dev *indio_dev)
{
	struct sx9500_data *data = iio_priv(indio_dev);
	int ret, i;
	int ret = 0, i;

	iio_triggered_buffer_predisable(indio_dev);

@@ -800,8 +803,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev)
	unsigned int val;

	ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
				 GENMASK(SX9500_NUM_CHANNELS, 0),
				 GENMASK(SX9500_NUM_CHANNELS, 0));
				 SX9500_CHAN_MASK, SX9500_CHAN_MASK);
	if (ret < 0)
		return ret;

@@ -821,7 +823,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev)

out:
	regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
			   GENMASK(SX9500_NUM_CHANNELS, 0), 0);
			   SX9500_CHAN_MASK, 0);
	return ret;
}

Loading