diff options
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/accel/bma180.c | 16 | ||||
-rw-r--r-- | drivers/iio/adc/max1363.c | 2 | ||||
-rw-r--r-- | drivers/iio/adc/ti_am335x_adc.c | 68 | ||||
-rw-r--r-- | drivers/iio/adc/twl6030-gpadc.c | 2 | ||||
-rw-r--r-- | drivers/iio/imu/adis16400.h | 1 | ||||
-rw-r--r-- | drivers/iio/imu/adis16400_core.c | 10 | ||||
-rw-r--r-- | drivers/iio/light/tsl2563.c | 16 | ||||
-rw-r--r-- | drivers/iio/magnetometer/ak8975.c | 16 | ||||
-rw-r--r-- | drivers/iio/magnetometer/mag3110.c | 8 |
9 files changed, 91 insertions, 48 deletions
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 3bec9220df04..bfec313492b3 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -447,14 +447,14 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = { { }, }; -#define BMA180_CHANNEL(_index) { \ +#define BMA180_CHANNEL(_axis) { \ .type = IIO_ACCEL, \ - .indexed = 1, \ - .channel = (_index), \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_index = (_index), \ + .scan_index = AXIS_##_axis, \ .scan_type = { \ .sign = 's', \ .realbits = 14, \ @@ -465,10 +465,10 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = { } static const struct iio_chan_spec bma180_channels[] = { - BMA180_CHANNEL(AXIS_X), - BMA180_CHANNEL(AXIS_Y), - BMA180_CHANNEL(AXIS_Z), - IIO_CHAN_SOFT_TIMESTAMP(4), + BMA180_CHANNEL(X), + BMA180_CHANNEL(Y), + BMA180_CHANNEL(Z), + IIO_CHAN_SOFT_TIMESTAMP(3), }; static irqreturn_t bma180_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 122827266796..ce84b012f7df 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1554,7 +1554,7 @@ static int max1363_probe(struct i2c_client *client, st->client = client; st->vref_uv = st->chip_info->int_vref_mv * 1000; - vref = devm_regulator_get(&client->dev, "vref"); + vref = devm_regulator_get_optional(&client->dev, "vref"); if (!IS_ERR(vref)) { int vref_uv; diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 30261a9bd3d4..a4db3026bec6 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -59,6 +59,24 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev) return step_en; } +static u32 get_adc_chan_step_mask(struct tiadc_device *adc_dev, + struct iio_chan_spec const *chan) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) { + if (chan->channel == adc_dev->channel_line[i]) { + u32 step; + + step = adc_dev->channel_step[i]; + /* +1 for the charger */ + return 1 << (step + 1); + } + } + WARN_ON(1); + return 0; +} + static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan) { return 1 << adc_dev->channel_step[chan]; @@ -180,7 +198,7 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev) enb |= (get_adc_step_bit(adc_dev, bit) << 1); adc_dev->buffer_en_ch_steps = enb; - am335x_tsc_se_set(adc_dev->mfd_tscadc, enb); + am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb); tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW); @@ -198,6 +216,7 @@ static int tiadc_buffer_predisable(struct iio_dev *indio_dev) tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW)); am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps); + adc_dev->buffer_en_ch_steps = 0; /* Flush FIFO of leftover data in the time it takes to disable adc */ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); @@ -327,34 +346,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, unsigned int fifo1count, read, stepid; bool found = false; u32 step_en; - unsigned long timeout = jiffies + usecs_to_jiffies - (IDLE_TIMEOUT * adc_dev->channels); + unsigned long timeout; if (iio_buffer_enabled(indio_dev)) return -EBUSY; - step_en = get_adc_step_mask(adc_dev); - am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); + step_en = get_adc_chan_step_mask(adc_dev, chan); + if (!step_en) + return -EINVAL; + + fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); + while (fifo1count--) + tiadc_readl(adc_dev, REG_FIFO1); + + am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); - /* Wait for ADC sequencer to complete sampling */ - while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) { - if (time_after(jiffies, timeout)) + timeout = jiffies + usecs_to_jiffies + (IDLE_TIMEOUT * adc_dev->channels); + /* Wait for Fifo threshold interrupt */ + while (1) { + fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); + if (fifo1count) + break; + + if (time_after(jiffies, timeout)) { + am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); return -EAGAIN; } + } map_val = chan->channel + TOTAL_CHANNELS; /* - * When the sub-system is first enabled, - * the sequencer will always start with the - * lowest step (1) and continue until step (16). - * For ex: If we have enabled 4 ADC channels and - * currently use only 1 out of them, the - * sequencer still configures all the 4 steps, - * leading to 3 unwanted data. - * Hence we need to flush out this data. + * We check the complete FIFO. We programmed just one entry but in case + * something went wrong we left empty handed (-EAGAIN previously) and + * then the value apeared somehow in the FIFO we would have two entries. + * Therefore we read every item and keep only the latest version of the + * requested channel. */ - - fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); for (i = 0; i < fifo1count; i++) { read = tiadc_readl(adc_dev, REG_FIFO1); stepid = read & FIFOREAD_CHNLID_MASK; @@ -366,6 +394,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, *val = (u16) read; } } + am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); if (found == false) return -EBUSY; @@ -493,7 +522,8 @@ static int tiadc_resume(struct device *dev) tiadc_writel(adc_dev, REG_CTRL, restore); tiadc_step_config(indio_dev); - + am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, + adc_dev->buffer_en_ch_steps); return 0; } diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index c40ca3aac108..15282f148b3b 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -968,7 +968,7 @@ static int twl6030_gpadc_suspend(struct device *pdev) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR, TWL6030_REG_TOGGLE1); if (ret) - dev_err(pdev, "error reseting GPADC (%d)!\n", ret); + dev_err(pdev, "error resetting GPADC (%d)!\n", ret); return 0; }; diff --git a/drivers/iio/imu/adis16400.h b/drivers/iio/imu/adis16400.h index 2f8f9d632386..0916bf6b6c31 100644 --- a/drivers/iio/imu/adis16400.h +++ b/drivers/iio/imu/adis16400.h @@ -189,6 +189,7 @@ enum { ADIS16300_SCAN_INCLI_X, ADIS16300_SCAN_INCLI_Y, ADIS16400_SCAN_ADC, + ADIS16400_SCAN_TIMESTAMP, }; #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 411586f49dae..433583b6f800 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -632,7 +632,7 @@ static const struct iio_chan_spec adis16400_channels[] = { ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14), ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12), ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12), - IIO_CHAN_SOFT_TIMESTAMP(12) + IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), }; static const struct iio_chan_spec adis16448_channels[] = { @@ -659,7 +659,7 @@ static const struct iio_chan_spec adis16448_channels[] = { }, }, ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12), - IIO_CHAN_SOFT_TIMESTAMP(11) + IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), }; static const struct iio_chan_spec adis16350_channels[] = { @@ -677,7 +677,7 @@ static const struct iio_chan_spec adis16350_channels[] = { ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12), ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12), ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12), - IIO_CHAN_SOFT_TIMESTAMP(11) + IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), }; static const struct iio_chan_spec adis16300_channels[] = { @@ -690,7 +690,7 @@ static const struct iio_chan_spec adis16300_channels[] = { ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12), ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13), ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13), - IIO_CHAN_SOFT_TIMESTAMP(14) + IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), }; static const struct iio_chan_spec adis16334_channels[] = { @@ -701,7 +701,7 @@ static const struct iio_chan_spec adis16334_channels[] = { ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14), ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14), ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12), - IIO_CHAN_SOFT_TIMESTAMP(8) + IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), }; static struct attribute *adis16400_attributes[] = { diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 3d8110157f2d..94daa9fc1247 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -460,10 +460,14 @@ static int tsl2563_write_raw(struct iio_dev *indio_dev, { struct tsl2563_chip *chip = iio_priv(indio_dev); - if (chan->channel == IIO_MOD_LIGHT_BOTH) + if (mask != IIO_CHAN_INFO_CALIBSCALE) + return -EINVAL; + if (chan->channel2 == IIO_MOD_LIGHT_BOTH) chip->calib0 = calib_from_sysfs(val); - else + else if (chan->channel2 == IIO_MOD_LIGHT_IR) chip->calib1 = calib_from_sysfs(val); + else + return -EINVAL; return 0; } @@ -472,14 +476,14 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, - long m) + long mask) { int ret = -EINVAL; u32 calib0, calib1; struct tsl2563_chip *chip = iio_priv(indio_dev); mutex_lock(&chip->lock); - switch (m) { + switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { @@ -498,7 +502,7 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, ret = tsl2563_get_adc(chip); if (ret) goto error_ret; - if (chan->channel == 0) + if (chan->channel2 == IIO_MOD_LIGHT_BOTH) *val = chip->data0; else *val = chip->data1; @@ -510,7 +514,7 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_CALIBSCALE: - if (chan->channel == 0) + if (chan->channel2 == IIO_MOD_LIGHT_BOTH) *val = calib_to_sysfs(chip->calib0); else *val = calib_to_sysfs(chip->calib1); diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 039c3e85caf4..74866d1efd1b 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -85,6 +85,7 @@ #define AK8975_MAX_CONVERSION_TIMEOUT 500 #define AK8975_CONVERSION_DONE_POLL_TIME 10 #define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000) +#define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256) /* * Per-instance context data for the device. @@ -265,15 +266,15 @@ static int ak8975_setup(struct i2c_client *client) * * Since 1uT = 0.01 gauss, our final scale factor becomes: * - * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100 - * Hadj = H * ((ASA + 128) * 30 / 256 + * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100 + * Hadj = H * ((ASA + 128) * 0.003) / 256 * * Since ASA doesn't change, we cache the resultant scale factor into the * device context in ak8975_setup(). */ - data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8; - data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8; - data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8; + data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]); + data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]); + data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]); return 0; } @@ -428,8 +429,9 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: return ak8975_read_axis(indio_dev, chan->address, val); case IIO_CHAN_INFO_SCALE: - *val = data->raw_to_gauss[chan->address]; - return IIO_VAL_INT; + *val = 0; + *val2 = data->raw_to_gauss[chan->address]; + return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; } diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index 4b65b6d3bdb1..f66955fb3509 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -106,7 +106,7 @@ static ssize_t mag3110_show_int_plus_micros(char *buf, while (n-- > 0) len += scnprintf(buf + len, PAGE_SIZE - len, - "%d.%d ", vals[n][0], vals[n][1]); + "%d.%06d ", vals[n][0], vals[n][1]); /* replace trailing space by newline */ buf[len - 1] = '\n'; @@ -154,6 +154,9 @@ static int mag3110_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + switch (chan->type) { case IIO_MAGN: /* in 0.1 uT / LSB */ ret = mag3110_read(data, buffer); @@ -199,6 +202,9 @@ static int mag3110_write_raw(struct iio_dev *indio_dev, struct mag3110_data *data = iio_priv(indio_dev); int rate; + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: rate = mag3110_get_samp_freq_index(data, val, val2); |