Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-4.1b' 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:

Second round of fixes for IIO in the 4.1 cycle.

* twl6030-gpadc - Drop a bonus space from the modalias.
* adis16400 - Report pressure channel scale (not much use without it)
            - Use different channel indices for the two voltage channels (ABI)
	    - Compute the san mask from the channel indices instead of using
	      ~0UL as we now care about extra bits being set.
	    - Fix burst mode due to rx buffer not being intialized and wrong
	      tx buffer type being set.  Also had the wrong transfer length.
	      All in all it didn't work, now it does ;)
	    - adis16448 has additional registers in burst mode so we skip
	      over them to make it work.
  • Loading branch information
gregkh committed May 24, 2015
2 parents e260818 + e5d7321 commit a8acb4d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 21 deletions.
2 changes: 1 addition & 1 deletion drivers/iio/adc/twl6030-gpadc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ static struct platform_driver twl6030_gpadc_driver = {

module_platform_driver(twl6030_gpadc_driver);

MODULE_ALIAS("platform: " DRIVER_NAME);
MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");
Expand Down
2 changes: 2 additions & 0 deletions drivers/iio/imu/adis16400.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
#define ADIS16400_NO_BURST BIT(1)
#define ADIS16400_HAS_SLOW_MODE BIT(2)
#define ADIS16400_HAS_SERIAL_NUMBER BIT(3)
#define ADIS16400_BURST_DIAG_STAT BIT(4)

struct adis16400_state;

Expand All @@ -165,6 +166,7 @@ struct adis16400_state {
int filt_int;

struct adis adis;
unsigned long avail_scan_mask[2];
};

/* At the moment triggers are only used for ring buffer
Expand Down
26 changes: 18 additions & 8 deletions drivers/iio/imu/adis16400_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,38 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev,
{
struct adis16400_state *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
uint16_t *tx;
unsigned int burst_length;
u8 *tx;

if (st->variant->flags & ADIS16400_NO_BURST)
return adis_update_scan_mode(indio_dev, scan_mask);

kfree(adis->xfer);
kfree(adis->buffer);

/* All but the timestamp channel */
burst_length = (indio_dev->num_channels - 1) * sizeof(u16);
if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
burst_length += sizeof(u16);

adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
if (!adis->xfer)
return -ENOMEM;

adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
GFP_KERNEL);
adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL);
if (!adis->buffer)
return -ENOMEM;

tx = adis->buffer + indio_dev->scan_bytes;

tx = adis->buffer + burst_length;
tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
tx[1] = 0;

adis->xfer[0].tx_buf = tx;
adis->xfer[0].bits_per_word = 8;
adis->xfer[0].len = 2;
adis->xfer[1].tx_buf = tx;
adis->xfer[1].rx_buf = adis->buffer;
adis->xfer[1].bits_per_word = 8;
adis->xfer[1].len = indio_dev->scan_bytes;
adis->xfer[1].len = burst_length;

spi_message_init(&adis->msg);
spi_message_add_tail(&adis->xfer[0], &adis->msg);
Expand All @@ -61,6 +65,7 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
struct adis16400_state *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
u32 old_speed_hz = st->adis.spi->max_speed_hz;
void *buffer;
int ret;

if (!adis->buffer)
Expand All @@ -81,7 +86,12 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
spi_setup(st->adis.spi);
}

iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
buffer = adis->buffer + sizeof(u16);
else
buffer = adis->buffer;

iio_push_to_buffers_with_timestamp(indio_dev, buffer,
pf->timestamp);

iio_trigger_notify_done(indio_dev->trig);
Expand Down
41 changes: 29 additions & 12 deletions drivers/iio/imu/adis16400_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
*val = st->variant->temp_scale_nano / 1000000;
*val2 = (st->variant->temp_scale_nano % 1000000);
return IIO_VAL_INT_PLUS_MICRO;
case IIO_PRESSURE:
/* 20 uBar = 0.002kPascal */
*val = 0;
*val2 = 2000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
Expand Down Expand Up @@ -454,10 +459,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
}
}

#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \
#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = 0, \
.channel = chn, \
.extend_name = name, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
Expand All @@ -474,10 +479,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
}

#define ADIS16400_SUPPLY_CHAN(addr, bits) \
ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY)
ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY, 0)

#define ADIS16400_AUX_ADC_CHAN(addr, bits) \
ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC)
ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC, 1)

#define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
.type = IIO_ANGL_VEL, \
Expand Down Expand Up @@ -773,7 +778,8 @@ static struct adis16400_chip_info adis16400_chips[] = {
.channels = adis16448_channels,
.num_channels = ARRAY_SIZE(adis16448_channels),
.flags = ADIS16400_HAS_PROD_ID |
ADIS16400_HAS_SERIAL_NUMBER,
ADIS16400_HAS_SERIAL_NUMBER |
ADIS16400_BURST_DIAG_STAT,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */
.temp_scale_nano = 73860000, /* 0.07386 C */
Expand All @@ -791,11 +797,6 @@ static const struct iio_info adis16400_info = {
.debugfs_reg_access = adis_debugfs_reg_access,
};

static const unsigned long adis16400_burst_scan_mask[] = {
~0UL,
0,
};

static const char * const adis16400_status_error_msgs[] = {
[ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
[ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
Expand Down Expand Up @@ -843,6 +844,20 @@ static const struct adis_data adis16400_data = {
BIT(ADIS16400_DIAG_STAT_POWER_LOW),
};

static void adis16400_setup_chan_mask(struct adis16400_state *st)
{
const struct adis16400_chip_info *chip_info = st->variant;
unsigned i;

for (i = 0; i < chip_info->num_channels; i++) {
const struct iio_chan_spec *ch = &chip_info->channels[i];

if (ch->scan_index >= 0 &&
ch->scan_index != ADIS16400_SCAN_TIMESTAMP)
st->avail_scan_mask[0] |= BIT(ch->scan_index);
}
}

static int adis16400_probe(struct spi_device *spi)
{
struct adis16400_state *st;
Expand All @@ -866,8 +881,10 @@ static int adis16400_probe(struct spi_device *spi)
indio_dev->info = &adis16400_info;
indio_dev->modes = INDIO_DIRECT_MODE;

if (!(st->variant->flags & ADIS16400_NO_BURST))
indio_dev->available_scan_masks = adis16400_burst_scan_mask;
if (!(st->variant->flags & ADIS16400_NO_BURST)) {
adis16400_setup_chan_mask(st);
indio_dev->available_scan_masks = st->avail_scan_mask;
}

ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
if (ret)
Expand Down

0 comments on commit a8acb4d

Please sign in to comment.