Browse Source

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.
Greg Kroah-Hartman 10 years ago
parent
commit
8c5dfdbbeb

+ 2 - 0
drivers/iio/light/Kconfig

@@ -188,6 +188,7 @@ config SENSORS_LM3533
 config LTR501
 config LTR501
 	tristate "LTR-501ALS-01 light sensor"
 	tristate "LTR-501ALS-01 light sensor"
 	depends on I2C
 	depends on I2C
+	select REGMAP_I2C
 	select IIO_BUFFER
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
 	help
@@ -201,6 +202,7 @@ config LTR501
 config STK3310
 config STK3310
 	tristate "STK3310 ALS and proximity sensor"
 	tristate "STK3310 ALS and proximity sensor"
 	depends on I2C
 	depends on I2C
+	select REGMAP_I2C
 	help
 	help
 	 Say yes here to get support for the Sensortek STK3310 ambient light
 	 Say yes here to get support for the Sensortek STK3310 ambient light
 	 and proximity sensor. The STK3311 model is also supported by this
 	 and proximity sensor. The STK3311 model is also supported by this

+ 1 - 1
drivers/iio/light/ltr501.c

@@ -1302,7 +1302,7 @@ static int ltr501_init(struct ltr501_data *data)
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		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);
 	ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status);
 	if (ret < 0)
 	if (ret < 0)

+ 17 - 36
drivers/iio/light/stk3310.c

@@ -43,7 +43,6 @@
 #define STK3311_CHIP_ID_VAL			0x1D
 #define STK3311_CHIP_ID_VAL			0x1D
 #define STK3310_PSINT_EN			0x01
 #define STK3310_PSINT_EN			0x01
 #define STK3310_PS_MAX_VAL			0xFFFF
 #define STK3310_PS_MAX_VAL			0xFFFF
-#define STK3310_THRESH_MAX			0xFFFF
 
 
 #define STK3310_DRIVER_NAME			"stk3310"
 #define STK3310_DRIVER_NAME			"stk3310"
 #define STK3310_REGMAP_NAME			"stk3310_regmap"
 #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);
 				REG_FIELD(STK3310_REG_FLAG, 4, 4);
 static const struct reg_field stk3310_reg_field_flag_nf =
 static const struct reg_field stk3310_reg_field_flag_nf =
 				REG_FIELD(STK3310_REG_FLAG, 0, 0);
 				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] = {
 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] = {
 static const int stk3310_scale_table[][2] = {
@@ -128,14 +125,14 @@ static const struct iio_event_spec stk3310_events[] = {
 	/* Proximity event */
 	/* Proximity event */
 	{
 	{
 		.type = IIO_EV_TYPE_THRESH,
 		.type = IIO_EV_TYPE_THRESH,
-		.dir = IIO_EV_DIR_FALLING,
+		.dir = IIO_EV_DIR_RISING,
 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
 				 BIT(IIO_EV_INFO_ENABLE),
 				 BIT(IIO_EV_INFO_ENABLE),
 	},
 	},
 	/* Out-of-proximity event */
 	/* Out-of-proximity event */
 	{
 	{
 		.type = IIO_EV_TYPE_THRESH,
 		.type = IIO_EV_TYPE_THRESH,
-		.dir = IIO_EV_DIR_RISING,
+		.dir = IIO_EV_DIR_FALLING,
 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
 		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
 				 BIT(IIO_EV_INFO_ENABLE),
 				 BIT(IIO_EV_INFO_ENABLE),
 	},
 	},
@@ -205,23 +202,16 @@ static int stk3310_read_event(struct iio_dev *indio_dev,
 	u8 reg;
 	u8 reg;
 	u16 buf;
 	u16 buf;
 	int ret;
 	int ret;
-	unsigned int index;
 	struct stk3310_data *data = iio_priv(indio_dev);
 	struct stk3310_data *data = iio_priv(indio_dev);
 
 
 	if (info != IIO_EV_INFO_VALUE)
 	if (info != IIO_EV_INFO_VALUE)
 		return -EINVAL;
 		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)
 	if (dir == IIO_EV_DIR_RISING)
-		reg = STK3310_REG_THDL_PS;
-	else if (dir == IIO_EV_DIR_FALLING)
 		reg = STK3310_REG_THDH_PS;
 		reg = STK3310_REG_THDH_PS;
+	else if (dir == IIO_EV_DIR_FALLING)
+		reg = STK3310_REG_THDL_PS;
 	else
 	else
 		return -EINVAL;
 		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");
 		dev_err(&data->client->dev, "register read failed\n");
 		return ret;
 		return ret;
 	}
 	}
-	regmap_field_read(data->reg_ps_gain, &index);
-	*val = swab16(stk3310_ps_max[index] - buf);
+	*val = swab16(buf);
 
 
 	return IIO_VAL_INT;
 	return IIO_VAL_INT;
 }
 }
@@ -257,13 +246,13 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (dir == IIO_EV_DIR_RISING)
 	if (dir == IIO_EV_DIR_RISING)
-		reg = STK3310_REG_THDL_PS;
-	else if (dir == IIO_EV_DIR_FALLING)
 		reg = STK3310_REG_THDH_PS;
 		reg = STK3310_REG_THDH_PS;
+	else if (dir == IIO_EV_DIR_FALLING)
+		reg = STK3310_REG_THDL_PS;
 	else
 	else
 		return -EINVAL;
 		return -EINVAL;
 
 
-	buf = swab16(stk3310_ps_max[index] - val);
+	buf = swab16(val);
 	ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
 	ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
 	if (ret < 0)
 	if (ret < 0)
 		dev_err(&client->dev, "failed to set PS threshold!\n");
 		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;
 			return ret;
 		}
 		}
 		*val = swab16(buf);
 		*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);
 		mutex_unlock(&data->lock);
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 	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,
 	event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
 				     IIO_EV_TYPE_THRESH,
 				     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);
 	iio_push_event(indio_dev, event, data->timestamp);
 
 
 	/* Reset the interrupt flag */
 	/* Reset the interrupt flag */

+ 21 - 14
drivers/iio/magnetometer/mmc35240.c

@@ -84,10 +84,10 @@
 #define MMC35240_OTP_START_ADDR		0x1B
 #define MMC35240_OTP_START_ADDR		0x1B
 
 
 enum mmc35240_resolution {
 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 {
 enum mmc35240_axis {
@@ -100,22 +100,22 @@ static const struct {
 	int sens[3]; /* sensitivity per X, Y, Z axis */
 	int sens[3]; /* sensitivity per X, Y, Z axis */
 	int nfo; /* null field output */
 	int nfo; /* null field output */
 } mmc35240_props_table[] = {
 } mmc35240_props_table[] = {
-	/* 16 bits, 100Hz ODR */
+	/* 16 bits, 125Hz ODR */
 	{
 	{
 		{1024, 1024, 1024},
 		{1024, 1024, 1024},
 		32768,
 		32768,
 	},
 	},
-	/* 16 bits, 200Hz ODR */
+	/* 16 bits, 250Hz ODR */
 	{
 	{
 		{1024, 1024, 770},
 		{1024, 1024, 770},
 		32768,
 		32768,
 	},
 	},
-	/* 14 bits, 333Hz ODR */
+	/* 14 bits, 450Hz ODR */
 	{
 	{
 		{256, 256, 193},
 		{256, 256, 193},
 		8192,
 		8192,
 	},
 	},
-	/* 12 bits, 666Hz ODR */
+	/* 12 bits, 800Hz ODR */
 	{
 	{
 		{64, 64, 48},
 		{64, 64, 48},
 		2048,
 		2048,
@@ -133,9 +133,15 @@ struct mmc35240_data {
 	int axis_scale[3];
 	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) { \
 #define MMC35240_CHANNEL(_axis) { \
 	.type = IIO_MAGN, \
 	.type = IIO_MAGN, \
@@ -168,7 +174,8 @@ static int mmc35240_get_samp_freq_index(struct mmc35240_data *data,
 	int i;
 	int i;
 
 
 	for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); 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 i;
 	return -EINVAL;
 	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))
 		if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq))
 			return -EINVAL;
 			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:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 14 - 12
drivers/iio/proximity/sx9500.c

@@ -80,6 +80,7 @@
 #define SX9500_COMPSTAT_MASK		GENMASK(3, 0)
 #define SX9500_COMPSTAT_MASK		GENMASK(3, 0)
 
 
 #define SX9500_NUM_CHANNELS		4
 #define SX9500_NUM_CHANNELS		4
+#define SX9500_CHAN_MASK		GENMASK(SX9500_NUM_CHANNELS - 1, 0)
 
 
 struct sx9500_data {
 struct sx9500_data {
 	struct mutex mutex;
 	struct mutex mutex;
@@ -329,20 +330,20 @@ static int sx9500_read_proximity(struct sx9500_data *data,
 	else
 	else
 		ret = sx9500_wait_for_sample(data);
 		ret = sx9500_wait_for_sample(data);
 
 
-	if (ret < 0)
-		return ret;
-
 	mutex_lock(&data->mutex);
 	mutex_lock(&data->mutex);
 
 
-	ret = sx9500_read_prox_data(data, chan, val);
 	if (ret < 0)
 	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)
 	if (ret < 0)
-		goto out;
+		goto out_dec_data_rdy;
 
 
 	ret = sx9500_dec_data_rdy_users(data);
 	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)
 	if (ret < 0)
 		goto out;
 		goto out;
 
 
@@ -350,6 +351,8 @@ static int sx9500_read_proximity(struct sx9500_data *data,
 
 
 	goto out;
 	goto out;
 
 
+out_dec_data_rdy:
+	sx9500_dec_data_rdy_users(data);
 out_dec_chan:
 out_dec_chan:
 	sx9500_dec_chan_users(data, chan->channel);
 	sx9500_dec_chan_users(data, chan->channel);
 out:
 out:
@@ -679,7 +682,7 @@ out:
 static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
 static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
 {
 {
 	struct sx9500_data *data = iio_priv(indio_dev);
 	struct sx9500_data *data = iio_priv(indio_dev);
-	int ret, i;
+	int ret = 0, i;
 
 
 	mutex_lock(&data->mutex);
 	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)
 static int sx9500_buffer_predisable(struct iio_dev *indio_dev)
 {
 {
 	struct sx9500_data *data = iio_priv(indio_dev);
 	struct sx9500_data *data = iio_priv(indio_dev);
-	int ret, i;
+	int ret = 0, i;
 
 
 	iio_triggered_buffer_predisable(indio_dev);
 	iio_triggered_buffer_predisable(indio_dev);
 
 
@@ -800,8 +803,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev)
 	unsigned int val;
 	unsigned int val;
 
 
 	ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
 	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)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -821,7 +823,7 @@ static int sx9500_init_compensation(struct iio_dev *indio_dev)
 
 
 out:
 out:
 	regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
 	regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
-			   GENMASK(SX9500_NUM_CHANNELS, 0), 0);
+			   SX9500_CHAN_MASK, 0);
 	return ret;
 	return ret;
 }
 }
 
 

+ 3 - 0
drivers/iio/temperature/tmp006.c

@@ -132,6 +132,9 @@ static int tmp006_write_raw(struct iio_dev *indio_dev,
 	struct tmp006_data *data = iio_priv(indio_dev);
 	struct tmp006_data *data = iio_priv(indio_dev);
 	int i;
 	int i;
 
 
+	if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+		return -EINVAL;
+
 	for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
 	for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
 		if ((val == tmp006_freqs[i][0]) &&
 		if ((val == tmp006_freqs[i][0]) &&
 		    (val2 == tmp006_freqs[i][1])) {
 		    (val2 == tmp006_freqs[i][1])) {