Skip to content

Commit

Permalink
staging:iio: Switch the channel masks to bitmaps so as to allow for m…
Browse files Browse the repository at this point in the history
…ore channels.

This is as light as possible on changes to current drivers.
Some drivers make assumptions that their masks fit in a single
long.  Given they were previously working this is clearly valid if
not tidy.

The max1363 is an example where there should be no such assumptions.

V2: Add the new ad5933

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Acked-by: Michael Hennerich <Michael.Hennerich@analog.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Jonathan Cameron authored and Greg Kroah-Hartman committed Sep 6, 2011
1 parent bd94c6a commit 32b5eec
Show file tree
Hide file tree
Showing 20 changed files with 188 additions and 135 deletions.
5 changes: 3 additions & 2 deletions drivers/staging/iio/accel/lis3l02dq_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
ret = ring->access->read_last(ring, (u8 *)data);
if (ret)
goto error_free_data;
*val = data[bitmap_weight(&ring->scan_mask, index)];
*val = data[bitmap_weight(ring->scan_mask, index)];
error_free_data:

kfree(data);

return ret;
Expand Down Expand Up @@ -99,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
mutex_lock(&st->buf_lock);

for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
if (ring->scan_mask & (1 << i)) {
if (test_bit(i, ring->scan_mask)) {
/* lower byte */
xfers[j].tx_buf = st->tx + 2*j;
st->tx[2*j] = read_all_tx_array[i*4];
Expand Down
6 changes: 3 additions & 3 deletions drivers/staging/iio/adc/ad7192.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ struct ad7192_state {
u32 mode;
u32 conf;
u32 scale_avail[8][2];
u32 available_scan_masks[9];
long available_scan_masks[9];
u8 gpocon;
u8 devid;
/*
Expand Down Expand Up @@ -460,7 +460,7 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;

if (!(ring->scan_mask & (1 << ch)))
if (!(test_bit(ch, ring->scan_mask)))
return -EBUSY;

ret = ring->access->read_last(ring, (u8 *) &dat64);
Expand All @@ -482,7 +482,7 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev)
if (!ring->scan_count)
return -EINVAL;

channel = __ffs(ring->scan_mask);
channel = find_first_bit(ring->scan_mask, indio_dev->masklength);

d_size = ring->scan_count *
indio_dev->channels[0].scan_type.storagebits / 8;
Expand Down
4 changes: 2 additions & 2 deletions drivers/staging/iio/adc/ad7298_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch)
int ret;
u16 *ring_data;

if (!(ring->scan_mask & (1 << ch))) {
if (!(test_bit(ch, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
Expand Down Expand Up @@ -79,7 +79,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
command = AD7298_WRITE | st->ext_ref;

for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
if (ring->scan_mask & (1 << i))
if (test_bit(i, ring->scan_mask))
command |= m;

st->tx_buf[0] = cpu_to_be16(command);
Expand Down
18 changes: 11 additions & 7 deletions drivers/staging/iio/adc/ad7793.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ struct ad7793_state {
u16 mode;
u16 conf;
u32 scale_avail[8][2];
u32 available_scan_masks[7];
/* Note this uses fact that 8 the mask always fits in a long */
unsigned long available_scan_masks[7];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
Expand Down Expand Up @@ -321,7 +322,7 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;

if (!(ring->scan_mask & (1 << ch)))
if (!(test_bit(ch, ring->scan_mask)))
return -EBUSY;

ret = ring->access->read_last(ring, (u8 *) &dat64);
Expand All @@ -343,7 +344,8 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev)
if (!ring->scan_count)
return -EINVAL;

channel = __ffs(ring->scan_mask);
channel = find_first_bit(ring->scan_mask,
indio_dev->masklength);

d_size = ring->scan_count *
indio_dev->channels[0].scan_type.storagebits / 8;
Expand Down Expand Up @@ -875,10 +877,12 @@ static int __devinit ad7793_probe(struct spi_device *spi)
indio_dev->num_channels = 7;
indio_dev->info = &ad7793_info;

for (i = 0; i < indio_dev->num_channels; i++)
st->available_scan_masks[i] = (1 << i) | (1 <<
indio_dev->channels[indio_dev->num_channels - 1].
scan_index);
for (i = 0; i < indio_dev->num_channels; i++) {
set_bit(i, &st->available_scan_masks[i]);
set_bit(indio_dev->
channels[indio_dev->num_channels - 1].scan_index,
&st->available_scan_masks[i]);
}

init_waitqueue_head(&st->wq_data_avail);

Expand Down
4 changes: 2 additions & 2 deletions drivers/staging/iio/adc/ad7887.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ enum ad7887_supported_device_ids {
};

#ifdef CONFIG_IIO_RING_BUFFER
int ad7887_scan_from_ring(struct ad7887_state *st, long mask);
int ad7887_scan_from_ring(struct ad7887_state *st, int channum);
int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad7887_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_IIO_RING_BUFFER */
static inline int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
static inline int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
{
return 0;
}
Expand Down
10 changes: 6 additions & 4 deletions drivers/staging/iio/adc/ad7887_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@

#include "ad7887.h"

int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
{
struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
int count = 0, ret;
u16 *ring_data;

if (!(ring->scan_mask & mask)) {
if (!(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
Expand All @@ -41,7 +41,8 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
goto error_free_ring_data;

/* for single channel scan the result is stored with zero offset */
if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1)))
if ((test_bit(1, ring->scan_mask) || test_bit(0, ring->scan_mask)) &&
(channum == 1))
count = 1;

ret = be16_to_cpu(ring_data[count]);
Expand Down Expand Up @@ -78,7 +79,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
st->d_size);

switch (ring->scan_mask) {
/* We know this is a single long so can 'cheat' */
switch (*ring->scan_mask) {
case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0];
break;
Expand Down
4 changes: 2 additions & 2 deletions drivers/staging/iio/adc/ad799x.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ struct ad799x_platform_data {
int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask);

#ifdef CONFIG_AD799X_RING_BUFFER
int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask);
int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum);
int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad799x_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_AD799X_RING_BUFFER */
int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum)
{
return -EINVAL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/iio/adc/ad799x_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info,
mutex_lock(&dev_info->mlock);
if (iio_ring_enabled(dev_info))
ret = ad799x_single_channel_from_ring(st,
1 << chan->address);
chan->address);
else
ret = ad799x_scan_direct(st, chan->address);
mutex_unlock(&dev_info->mlock);
Expand Down
18 changes: 6 additions & 12 deletions drivers/staging/iio/adc/ad799x_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@

#include "ad799x.h"

int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum)
{
struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
int count = 0, ret;
u16 *ring_data;

if (!(ring->scan_mask & mask)) {
if (!(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
Expand All @@ -44,13 +44,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
if (ret)
goto error_free_ring_data;
/* Need a count of channels prior to this one */
mask >>= 1;
while (mask) {
if (mask & ring->scan_mask)
count++;
mask >>= 1;
}

count = bitmap_weight(ring->scan_mask, channum);
ret = be16_to_cpu(ring_data[count]);

error_free_ring_data:
Expand All @@ -77,7 +71,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
*/

if (st->id == ad7997 || st->id == ad7998)
ad7997_8_set_scan_mode(st, ring->scan_mask);
ad7997_8_set_scan_mode(st, *ring->scan_mask);

st->d_size = ring->scan_count * 2;

Expand Down Expand Up @@ -121,12 +115,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
case ad7991:
case ad7995:
case ad7999:
cmd = st->config | (ring->scan_mask << AD799X_CHANNEL_SHIFT);
cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT);
break;
case ad7992:
case ad7993:
case ad7994:
cmd = (ring->scan_mask << AD799X_CHANNEL_SHIFT) |
cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) |
AD7998_CONV_RES_REG;
break;
case ad7997:
Expand Down
8 changes: 5 additions & 3 deletions drivers/staging/iio/adc/max1363.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@
#define MAX1363_SCAN_MASK 0x60
#define MAX1363_SE_DE_MASK 0x01

#define MAX1363_MAX_CHANNELS 25
/**
* struct max1363_mode - scan mode information
* @conf: The corresponding value of the configuration register
* @modemask: Bit mask corresponding to channels enabled in this mode
*/
struct max1363_mode {
int8_t conf;
long modemask;
DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
};

/* This must be maintained along side the max1363_mode_table in max1363_core */
Expand Down Expand Up @@ -145,13 +146,14 @@ struct max1363_state {
};

const struct max1363_mode
*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci);
*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci);

int max1363_set_scan_mode(struct max1363_state *st);

#ifdef CONFIG_MAX1363_RING_BUFFER

int max1363_single_channel_from_ring(long mask, struct max1363_state *st);
int max1363_single_channel_from_ring(const long *mask,
struct max1363_state *st);
int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void max1363_ring_cleanup(struct iio_dev *indio_dev);

Expand Down
Loading

0 comments on commit 32b5eec

Please sign in to comment.