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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJVpCJ3AAoJEFSFNJnE9BaIN3gP/0bAfaLmR8zdnnBlUCr3VG1I xiXjzpcnzg8sZR0883AeqgnGpu2W4LNAIrVumNLBWOCifvN2HVdlcmIH5iHjHR+n r9Mp6RM9bBYWbUCmOZuaTOKHBMifh59cc8y3UkRsGAjr/EvpT5jciX4d60EvSE4d nQ2Fcg/kEYmyVZQ1UjfUZvbOwUcNJP2WhHsz30HGDFSCeCYkbtrDz2lcZqaSZSDV P/nJ3ySQtLIJ3OzyCKz9b212WrLODWc50CDQlcIFzKxaMqYytGndE88Zsvs0a1nx JPcSDK7zaMItPJ75PA+I5h7L4mMTOgReTrnQlpLP3YnlAdS8/1o2gz9dLnI2Y7iC eBLOBFFwp/rgY6eHdcvjyiLmpGs1zl93tiZsVBvcQkJw74HG56xlemPzxN09tmLd gxlGztucdBhXh8/PAG9o5kSV7xcop2lftJP+jAV7rxpCbmi2use/2vejFi8qjFiE CekQxmEm32YakVnkNauz5iiUIgCUa5fZ++/G2nIg6F3iRlF8B6akUFdStCcwIc8b 6vyF4jkKU+hyAu0TiWnjLHa83brlJ44L4TOPhhS3QvDbGpr8ULHdCrSBdwifZoBC 0m6J0Tia6M/TmwQ+4Owd2MzNzX/YUbtd3b7nIje7QnEQu5UAe4F3Myio8uyWB8uR o/sfUmysDXQbKycJ0PEg =1kNg -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
8c5dfdbbeb
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
if (ret < 0)
|
||||
goto out_dec_data_rdy;
|
||||
|
||||
ret = sx9500_read_prox_data(data, chan, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = sx9500_dec_chan_users(data, chan->channel);
|
||||
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 @@ out:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,9 @@ static int tmp006_write_raw(struct iio_dev *indio_dev,
|
||||
struct tmp006_data *data = iio_priv(indio_dev);
|
||||
int i;
|
||||
|
||||
if (mask != IIO_CHAN_INFO_SAMP_FREQ)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
|
||||
if ((val == tmp006_freqs[i][0]) &&
|
||||
(val2 == tmp006_freqs[i][1])) {
|
||||
|
Loading…
Reference in New Issue
Block a user