Commit 32b5eeca authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Greg Kroah-Hartman

staging:iio: Switch the channel masks to bitmaps so as to allow for more 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: default avatarJonathan Cameron <jic23@cam.ac.uk>
Acked-by: default avatarMichael Hennerich <Michael.Hennerich@analog.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent bd94c6a8
...@@ -61,8 +61,9 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring, ...@@ -61,8 +61,9 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
ret = ring->access->read_last(ring, (u8 *)data); ret = ring->access->read_last(ring, (u8 *)data);
if (ret) if (ret)
goto error_free_data; goto error_free_data;
*val = data[bitmap_weight(&ring->scan_mask, index)]; *val = data[bitmap_weight(ring->scan_mask, index)];
error_free_data: error_free_data:
kfree(data); kfree(data);
return ret; return ret;
...@@ -99,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array) ...@@ -99,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) 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 */ /* lower byte */
xfers[j].tx_buf = st->tx + 2*j; xfers[j].tx_buf = st->tx + 2*j;
st->tx[2*j] = read_all_tx_array[i*4]; st->tx[2*j] = read_all_tx_array[i*4];
......
...@@ -146,7 +146,7 @@ struct ad7192_state { ...@@ -146,7 +146,7 @@ struct ad7192_state {
u32 mode; u32 mode;
u32 conf; u32 conf;
u32 scale_avail[8][2]; u32 scale_avail[8][2];
u32 available_scan_masks[9]; long available_scan_masks[9];
u8 gpocon; u8 gpocon;
u8 devid; u8 devid;
/* /*
...@@ -460,7 +460,7 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val) ...@@ -460,7 +460,7 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
s64 dat64[2]; s64 dat64[2];
u32 *dat32 = (u32 *)dat64; u32 *dat32 = (u32 *)dat64;
if (!(ring->scan_mask & (1 << ch))) if (!(test_bit(ch, ring->scan_mask)))
return -EBUSY; return -EBUSY;
ret = ring->access->read_last(ring, (u8 *) &dat64); ret = ring->access->read_last(ring, (u8 *) &dat64);
...@@ -482,7 +482,7 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev) ...@@ -482,7 +482,7 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev)
if (!ring->scan_count) if (!ring->scan_count)
return -EINVAL; return -EINVAL;
channel = __ffs(ring->scan_mask); channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
d_size = ring->scan_count * d_size = ring->scan_count *
indio_dev->channels[0].scan_type.storagebits / 8; indio_dev->channels[0].scan_type.storagebits / 8;
......
...@@ -24,7 +24,7 @@ int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch) ...@@ -24,7 +24,7 @@ int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch)
int ret; int ret;
u16 *ring_data; u16 *ring_data;
if (!(ring->scan_mask & (1 << ch))) { if (!(test_bit(ch, ring->scan_mask))) {
ret = -EBUSY; ret = -EBUSY;
goto error_ret; goto error_ret;
} }
...@@ -79,7 +79,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) ...@@ -79,7 +79,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
command = AD7298_WRITE | st->ext_ref; command = AD7298_WRITE | st->ext_ref;
for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) 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; command |= m;
st->tx_buf[0] = cpu_to_be16(command); st->tx_buf[0] = cpu_to_be16(command);
......
...@@ -51,7 +51,8 @@ struct ad7793_state { ...@@ -51,7 +51,8 @@ struct ad7793_state {
u16 mode; u16 mode;
u16 conf; u16 conf;
u32 scale_avail[8][2]; 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 * DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines. * transfer buffers to live in their own cache lines.
...@@ -321,7 +322,7 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) ...@@ -321,7 +322,7 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
s64 dat64[2]; s64 dat64[2];
u32 *dat32 = (u32 *)dat64; u32 *dat32 = (u32 *)dat64;
if (!(ring->scan_mask & (1 << ch))) if (!(test_bit(ch, ring->scan_mask)))
return -EBUSY; return -EBUSY;
ret = ring->access->read_last(ring, (u8 *) &dat64); ret = ring->access->read_last(ring, (u8 *) &dat64);
...@@ -343,7 +344,8 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev) ...@@ -343,7 +344,8 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev)
if (!ring->scan_count) if (!ring->scan_count)
return -EINVAL; return -EINVAL;
channel = __ffs(ring->scan_mask); channel = find_first_bit(ring->scan_mask,
indio_dev->masklength);
d_size = ring->scan_count * d_size = ring->scan_count *
indio_dev->channels[0].scan_type.storagebits / 8; indio_dev->channels[0].scan_type.storagebits / 8;
...@@ -875,10 +877,12 @@ static int __devinit ad7793_probe(struct spi_device *spi) ...@@ -875,10 +877,12 @@ static int __devinit ad7793_probe(struct spi_device *spi)
indio_dev->num_channels = 7; indio_dev->num_channels = 7;
indio_dev->info = &ad7793_info; indio_dev->info = &ad7793_info;
for (i = 0; i < indio_dev->num_channels; i++) for (i = 0; i < indio_dev->num_channels; i++) {
st->available_scan_masks[i] = (1 << i) | (1 << set_bit(i, &st->available_scan_masks[i]);
indio_dev->channels[indio_dev->num_channels - 1]. set_bit(indio_dev->
scan_index); channels[indio_dev->num_channels - 1].scan_index,
&st->available_scan_masks[i]);
}
init_waitqueue_head(&st->wq_data_avail); init_waitqueue_head(&st->wq_data_avail);
......
...@@ -83,11 +83,11 @@ enum ad7887_supported_device_ids { ...@@ -83,11 +83,11 @@ enum ad7887_supported_device_ids {
}; };
#ifdef CONFIG_IIO_RING_BUFFER #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); int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad7887_ring_cleanup(struct iio_dev *indio_dev); void ad7887_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_IIO_RING_BUFFER */ #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; return 0;
} }
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
#include "ad7887.h" #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; struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
int count = 0, ret; int count = 0, ret;
u16 *ring_data; u16 *ring_data;
if (!(ring->scan_mask & mask)) { if (!(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY; ret = -EBUSY;
goto error_ret; goto error_ret;
} }
...@@ -41,7 +41,8 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask) ...@@ -41,7 +41,8 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
goto error_free_ring_data; goto error_free_ring_data;
/* for single channel scan the result is stored with zero offset */ /* 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; count = 1;
ret = be16_to_cpu(ring_data[count]); ret = be16_to_cpu(ring_data[count]);
...@@ -78,7 +79,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) ...@@ -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, indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
st->d_size); st->d_size);
switch (ring->scan_mask) { /* We know this is a single long so can 'cheat' */
switch (*ring->scan_mask) {
case (1 << 0): case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0]; st->ring_msg = &st->msg[AD7887_CH0];
break; break;
......
...@@ -124,11 +124,11 @@ struct ad799x_platform_data { ...@@ -124,11 +124,11 @@ struct ad799x_platform_data {
int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask); int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask);
#ifdef CONFIG_AD799X_RING_BUFFER #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); int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad799x_ring_cleanup(struct iio_dev *indio_dev); void ad799x_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_AD799X_RING_BUFFER */ #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; return -EINVAL;
} }
......
...@@ -151,7 +151,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info, ...@@ -151,7 +151,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info,
mutex_lock(&dev_info->mlock); mutex_lock(&dev_info->mlock);
if (iio_ring_enabled(dev_info)) if (iio_ring_enabled(dev_info))
ret = ad799x_single_channel_from_ring(st, ret = ad799x_single_channel_from_ring(st,
1 << chan->address); chan->address);
else else
ret = ad799x_scan_direct(st, chan->address); ret = ad799x_scan_direct(st, chan->address);
mutex_unlock(&dev_info->mlock); mutex_unlock(&dev_info->mlock);
......
...@@ -23,13 +23,13 @@ ...@@ -23,13 +23,13 @@
#include "ad799x.h" #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; struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
int count = 0, ret; int count = 0, ret;
u16 *ring_data; u16 *ring_data;
if (!(ring->scan_mask & mask)) { if (!(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY; ret = -EBUSY;
goto error_ret; goto error_ret;
} }
...@@ -44,13 +44,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask) ...@@ -44,13 +44,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
if (ret) if (ret)
goto error_free_ring_data; goto error_free_ring_data;
/* Need a count of channels prior to this one */ /* Need a count of channels prior to this one */
mask >>= 1; count = bitmap_weight(ring->scan_mask, channum);
while (mask) {
if (mask & ring->scan_mask)
count++;
mask >>= 1;
}
ret = be16_to_cpu(ring_data[count]); ret = be16_to_cpu(ring_data[count]);
error_free_ring_data: error_free_ring_data:
...@@ -77,7 +71,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) ...@@ -77,7 +71,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
*/ */
if (st->id == ad7997 || st->id == ad7998) 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; st->d_size = ring->scan_count * 2;
...@@ -121,12 +115,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) ...@@ -121,12 +115,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
case ad7991: case ad7991:
case ad7995: case ad7995:
case ad7999: case ad7999:
cmd = st->config | (ring->scan_mask << AD799X_CHANNEL_SHIFT); cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT);
break; break;
case ad7992: case ad7992:
case ad7993: case ad7993:
case ad7994: case ad7994:
cmd = (ring->scan_mask << AD799X_CHANNEL_SHIFT) | cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) |
AD7998_CONV_RES_REG; AD7998_CONV_RES_REG;
break; break;
case ad7997: case ad7997:
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#define MAX1363_SCAN_MASK 0x60 #define MAX1363_SCAN_MASK 0x60
#define MAX1363_SE_DE_MASK 0x01 #define MAX1363_SE_DE_MASK 0x01
#define MAX1363_MAX_CHANNELS 25
/** /**
* struct max1363_mode - scan mode information * struct max1363_mode - scan mode information
* @conf: The corresponding value of the configuration register * @conf: The corresponding value of the configuration register
...@@ -64,7 +65,7 @@ ...@@ -64,7 +65,7 @@
*/ */
struct max1363_mode { struct max1363_mode {
int8_t conf; int8_t conf;
long modemask; DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
}; };
/* This must be maintained along side the max1363_mode_table in max1363_core */ /* This must be maintained along side the max1363_mode_table in max1363_core */
...@@ -145,13 +146,14 @@ struct max1363_state { ...@@ -145,13 +146,14 @@ struct max1363_state {
}; };
const struct max1363_mode 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); int max1363_set_scan_mode(struct max1363_state *st);
#ifdef CONFIG_MAX1363_RING_BUFFER #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); int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void max1363_ring_cleanup(struct iio_dev *indio_dev); void max1363_ring_cleanup(struct iio_dev *indio_dev);
......
...@@ -42,14 +42,14 @@ ...@@ -42,14 +42,14 @@
.conf = MAX1363_CHANNEL_SEL(_num) \ .conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_SCAN_SINGLE_1 \
| MAX1363_CONFIG_SE, \ | MAX1363_CONFIG_SE, \
.modemask = _mask, \ .modemask[0] = _mask, \
} }
#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ #define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \ .conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_SCAN_TO_CS \
| MAX1363_CONFIG_SE, \ | MAX1363_CONFIG_SE, \
.modemask = _mask, \ .modemask[0] = _mask, \
} }
/* note not available for max1363 hence naming */ /* note not available for max1363 hence naming */
...@@ -57,14 +57,14 @@ ...@@ -57,14 +57,14 @@
.conf = MAX1363_CHANNEL_SEL(_num) \ .conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1236_SCAN_MID_TO_CHANNEL \
| MAX1363_CONFIG_SE, \ | MAX1363_CONFIG_SE, \
.modemask = _mask \ .modemask[0] = _mask \
} }
#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ #define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_nump) \ .conf = MAX1363_CHANNEL_SEL(_nump) \
| MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_SCAN_SINGLE_1 \
| MAX1363_CONFIG_DE, \ | MAX1363_CONFIG_DE, \
.modemask = _mask \ .modemask[0] = _mask \
} }
/* Can't think how to automate naming so specify for now */ /* Can't think how to automate naming so specify for now */
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
.conf = MAX1363_CHANNEL_SEL(_num) \ .conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_SCAN_TO_CS \
| MAX1363_CONFIG_DE, \ | MAX1363_CONFIG_DE, \
.modemask = _mask \ .modemask[0] = _mask \
} }
/* note only available for max1363 hence naming */ /* note only available for max1363 hence naming */
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
.conf = MAX1363_CHANNEL_SEL(_num) \ .conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1236_SCAN_MID_TO_CHANNEL \
| MAX1363_CONFIG_SE, \ | MAX1363_CONFIG_SE, \
.modemask = _mask \ .modemask[0] = _mask \
} }
static const struct max1363_mode max1363_mode_table[] = { static const struct max1363_mode max1363_mode_table[] = {
...@@ -147,13 +147,15 @@ static const struct max1363_mode max1363_mode_table[] = { ...@@ -147,13 +147,15 @@ static const struct max1363_mode max1363_mode_table[] = {
}; };
const struct max1363_mode 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 i; int i;
if (mask) if (mask)
for (i = 0; i < ci->num_modes; i++) for (i = 0; i < ci->num_modes; i++)
if (!((~max1363_mode_table[ci->mode_list[i]].modemask) & if (bitmap_subset(mask,
mask)) max1363_mode_table[ci->mode_list[i]].
modemask,
MAX1363_MAX_CHANNELS))
return &max1363_mode_table[ci->mode_list[i]]; return &max1363_mode_table[ci->mode_list[i]];
return NULL; return NULL;
} }
...@@ -187,7 +189,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev, ...@@ -187,7 +189,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
int ret = 0; int ret = 0;
s32 data; s32 data;
char rxbuf[2]; char rxbuf[2];
long mask; const unsigned long *mask;
struct max1363_state *st = iio_priv(indio_dev); struct max1363_state *st = iio_priv(indio_dev);
struct i2c_client *client = st->client; struct i2c_client *client = st->client;
...@@ -644,7 +646,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) ...@@ -644,7 +646,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
int ret, i = 3, j; int ret, i = 3, j;
unsigned long numelements; unsigned long numelements;
int len; int len;
long modemask; const long *modemask;
if (!enabled) { if (!enabled) {
/* transition to ring capture is not currently supported */ /* transition to ring capture is not currently supported */
...@@ -672,7 +674,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) ...@@ -672,7 +674,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
st->configbyte |= max1363_mode_table[d1m0to3m2].conf; st->configbyte |= max1363_mode_table[d1m0to3m2].conf;
modemask = max1363_mode_table[d1m0to3m2].modemask; modemask = max1363_mode_table[d1m0to3m2].modemask;
} }
numelements = hweight_long(modemask); numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS);
len = 3 * numelements + 3; len = 3 * numelements + 3;
tx_buf = kmalloc(len, GFP_KERNEL); tx_buf = kmalloc(len, GFP_KERNEL);
if (!tx_buf) { if (!tx_buf) {
...@@ -688,7 +690,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) ...@@ -688,7 +690,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
* setup to match what we need. * setup to match what we need.
*/ */
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
if (modemask & (1 << j)) { if (test_bit(j, modemask)) {
/* Establish the mode is in the scan */ /* Establish the mode is in the scan */
if (st->mask_low & (1 << j)) { if (st->mask_low & (1 << j)) {
tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF;
...@@ -1281,7 +1283,7 @@ static int __devinit max1363_probe(struct i2c_client *client, ...@@ -1281,7 +1283,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
st->client = client; st->client = client;
indio_dev->available_scan_masks indio_dev->available_scan_masks
= kzalloc(sizeof(*indio_dev->available_scan_masks)* = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*
(st->chip_info->num_modes + 1), GFP_KERNEL); (st->chip_info->num_modes + 1), GFP_KERNEL);
if (!indio_dev->available_scan_masks) { if (!indio_dev->available_scan_masks) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1289,9 +1291,10 @@ static int __devinit max1363_probe(struct i2c_client *client, ...@@ -1289,9 +1291,10 @@ static int __devinit max1363_probe(struct i2c_client *client,
} }
for (i = 0; i < st->chip_info->num_modes; i++) for (i = 0; i < st->chip_info->num_modes; i++)
indio_dev->available_scan_masks[i] = bitmap_copy(indio_dev->available_scan_masks +
BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i,
max1363_mode_table[st->chip_info->mode_list[i]] max1363_mode_table[st->chip_info->mode_list[i]]
.modemask; .modemask, MAX1363_MAX_CHANNELS);
/* Estabilish that the iio_dev is a child of the i2c device */ /* Estabilish that the iio_dev is a child of the i2c device */
indio_dev->dev.parent = &client->dev; indio_dev->dev.parent = &client->dev;
indio_dev->name = id->name; indio_dev->name = id->name;
......
...@@ -21,12 +21,14 @@ ...@@ -21,12 +21,14 @@
#include "max1363.h" #include "max1363.h"
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)
{ {
struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
int count = 0, ret; int count = 0, ret, index;
u8 *ring_data; u8 *ring_data;
if (!(st->current_mode->modemask & mask)) { index = find_first_bit(mask, MAX1363_MAX_CHANNELS);
if (!(test_bit(index, st->current_mode->modemask))) {
ret = -EBUSY; ret = -EBUSY;
goto error_ret; goto error_ret;
} }
...@@ -41,12 +43,8 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st) ...@@ -41,12 +43,8 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
if (ret) if (ret)
goto error_free_ring_data; goto error_free_ring_data;
/* Need a count of channels prior to this one */ /* Need a count of channels prior to this one */
mask >>= 1;
while (mask) { count = bitmap_weight(mask, index - 1);
if (mask & st->current_mode->modemask)
count++;
mask >>= 1;
}
if (st->chip_info->bits != 8) if (st->chip_info->bits != 8)
ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8)
+ (int)(ring_data[count*2 + 1]); + (int)(ring_data[count*2 + 1]);
...@@ -85,7 +83,8 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) ...@@ -85,7 +83,8 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
max1363_set_scan_mode(st); max1363_set_scan_mode(st);
numvals = hweight_long(st->current_mode->modemask); numvals = bitmap_weight(st->current_mode->modemask,
indio_dev->masklength);
if (ring->access->set_bytes_per_datum) { if (ring->access->set_bytes_per_datum) {
if (ring->scan_timestamp) if (ring->scan_timestamp)
d_size += sizeof(s64); d_size += sizeof(s64);
...@@ -110,7 +109,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) ...@@ -110,7 +109,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
__u8 *rxbuf; __u8 *rxbuf;
int b_sent; int b_sent;
size_t d_size; size_t d_size;
unsigned long numvals = hweight_long(st->current_mode->modemask); unsigned long numvals = bitmap_weight(st->current_mode->modemask,
MAX1363_MAX_CHANNELS);
/* Ensure the timestamp is 8 byte aligned */ /* Ensure the timestamp is 8 byte aligned */
if (st->chip_info->bits != 8) if (st->chip_info->bits != 8)
......
...@@ -272,6 +272,8 @@ struct iio_info { ...@@ -272,6 +272,8 @@ struct iio_info {
* @mlock: [INTERN] lock used to prevent simultaneous device state * @mlock: [INTERN] lock used to prevent simultaneous device state
* changes * changes
* @available_scan_masks: [DRIVER] optional array of allowed bitmasks * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
* @masklength: [INTERN] the length of the mask established from
* channels
* @trig: [INTERN] current device trigger (ring buffer modes) * @trig: [INTERN] current device trigger (ring buffer modes)
* @pollfunc: [DRIVER] function run on trigger being received * @pollfunc: [DRIVER] function run on trigger being received
* @channels: [DRIVER] channel specification structure table * @channels: [DRIVER] channel specification structure table
...@@ -294,7 +296,8 @@ struct iio_dev { ...@@ -294,7 +296,8 @@ struct iio_dev {
struct iio_ring_buffer *ring; struct iio_ring_buffer *ring;
struct mutex mlock; struct mutex mlock;
u32 *available_scan_masks; unsigned long *available_scan_masks;
unsigned masklength;
struct iio_trigger *trig; struct iio_trigger *trig;
struct iio_poll_func *pollfunc; struct iio_poll_func *pollfunc;
......
...@@ -640,7 +640,7 @@ static void ad5933_work(struct work_struct *work) ...@@ -640,7 +640,7 @@ static void ad5933_work(struct work_struct *work)
if (status & AD5933_STAT_DATA_VALID) { if (status & AD5933_STAT_DATA_VALID) {
ad5933_i2c_read(st->client, ad5933_i2c_read(st->client,
(ring->scan_mask & (1 << 0)) ? test_bit(1, ring->scan_mask) ?
AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
ring->scan_count * 2, (u8 *)buf); ring->scan_count * 2, (u8 *)buf);
......
...@@ -85,7 +85,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx) ...@@ -85,7 +85,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++) for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
if (indio_dev->ring->scan_mask & (1 << i)) { if (test_bit(i, indio_dev->ring->scan_mask)) {
xfers[j].tx_buf = &read_all_tx_array[i]; xfers[j].tx_buf = &read_all_tx_array[i];
xfers[j].bits_per_word = 16; xfers[j].bits_per_word = 16;
xfers[j].len = 2; xfers[j].len = 2;
...@@ -117,7 +117,8 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) ...@@ -117,7 +117,8 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
int i = 0, j, ret = 0; int i = 0, j, ret = 0;
s16 *data; s16 *data;
size_t datasize = ring->access->get_bytes_per_datum(ring); size_t datasize = ring->access->get_bytes_per_datum(ring);
unsigned long mask = ring->scan_mask; /* Asumption that long is enough for maximum channels */
unsigned long mask = *ring->scan_mask;
data = kmalloc(datasize , GFP_KERNEL); data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) { if (data == NULL) {
......
...@@ -132,9 +132,7 @@ static ssize_t iio_scan_el_show(struct device *dev, ...@@ -132,9 +132,7 @@ static ssize_t iio_scan_el_show(struct device *dev,
static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit) static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
{ {
if (bit > IIO_MAX_SCAN_LENGTH) clear_bit(bit, ring->scan_mask);
return -EINVAL;
ring->scan_mask &= ~(1 << bit);
ring->scan_count--; ring->scan_count--;
return 0; return 0;
} }
...@@ -323,11 +321,27 @@ int iio_ring_buffer_register(struct iio_dev *indio_dev, ...@@ -323,11 +321,27 @@ int iio_ring_buffer_register(struct iio_dev *indio_dev,
if (channels) { if (channels) {
/* new magic */ /* new magic */
for (i = 0; i < num_channels; i++) { for (i = 0; i < num_channels; i++) {
/* Establish necessary mask length */
if (channels[i].scan_index >
(int)indio_dev->masklength - 1)
indio_dev->masklength
= indio_dev->channels[i].scan_index + 1;
ret = iio_ring_add_channel_sysfs(indio_dev, ret = iio_ring_add_channel_sysfs(indio_dev,
&channels[i]); &channels[i]);
if (ret < 0) if (ret < 0)
goto error_cleanup_group; goto error_cleanup_group;
} }
if (indio_dev->masklength && ring->scan_mask == NULL) {
ring->scan_mask
= kzalloc(sizeof(*ring->scan_mask)*
BITS_TO_LONGS(indio_dev->masklength),
GFP_KERNEL);
if (ring->scan_mask == NULL) {
ret = -ENOMEM;
goto error_cleanup_group;
}
}
} }
return 0; return 0;
...@@ -343,6 +357,7 @@ EXPORT_SYMBOL(iio_ring_buffer_register); ...@@ -343,6 +357,7 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
void iio_ring_buffer_unregister(struct iio_dev *indio_dev) void iio_ring_buffer_unregister(struct iio_dev *indio_dev)
{ {
kfree(indio_dev->ring->scan_mask);
if (indio_dev->ring->attrs) if (indio_dev->ring->attrs)
sysfs_remove_group(&indio_dev->dev.kobj, sysfs_remove_group(&indio_dev->dev.kobj,
indio_dev->ring->attrs); indio_dev->ring->attrs);
...@@ -539,3 +554,85 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev) ...@@ -539,3 +554,85 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev)
return 0; return 0;
} }
EXPORT_SYMBOL(iio_sw_ring_preenable); EXPORT_SYMBOL(iio_sw_ring_preenable);
/* note NULL used as error indicator as it doesn't make sense. */
static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
unsigned int masklength,
unsigned long *mask)
{
if (bitmap_empty(mask, masklength))
return NULL;
while (*av_masks) {
if (bitmap_subset(mask, av_masks, masklength))
return av_masks;
av_masks += BITS_TO_LONGS(masklength);
}
return NULL;
}
/**
* iio_scan_mask_set() - set particular bit in the scan mask
* @ring: the ring buffer whose scan mask we are interested in
* @bit: the bit to be set.
**/
int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
{
struct iio_dev *dev_info = ring->indio_dev;
unsigned long *mask;
unsigned long *trialmask;
trialmask = kmalloc(sizeof(*trialmask)*
BITS_TO_LONGS(dev_info->masklength),
GFP_KERNEL);
if (trialmask == NULL)
return -ENOMEM;
if (!dev_info->masklength) {
WARN_ON("trying to set scan mask prior to registering ring\n");
kfree(trialmask);
return -EINVAL;
}
bitmap_copy(trialmask, ring->scan_mask, dev_info->masklength);
set_bit(bit, trialmask);
if (dev_info->available_scan_masks) {
mask = iio_scan_mask_match(dev_info->available_scan_masks,
dev_info->masklength,
trialmask);
if (!mask) {
kfree(trialmask);
return -EINVAL;
}
}
bitmap_copy(ring->scan_mask, trialmask, dev_info->masklength);
ring->scan_count++;
kfree(trialmask);
return 0;
};
EXPORT_SYMBOL_GPL(iio_scan_mask_set);
int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
{
struct iio_dev *dev_info = ring->indio_dev;
long *mask;
if (bit > dev_info->masklength)
return -EINVAL;
if (!ring->scan_mask)
return 0;
if (dev_info->available_scan_masks)
mask = iio_scan_mask_match(dev_info->available_scan_masks,
dev_info->masklength,
ring->scan_mask);
else
mask = ring->scan_mask;
if (!mask)
return 0;
return test_bit(bit, mask);
};
EXPORT_SYMBOL_GPL(iio_scan_mask_query);
...@@ -122,7 +122,7 @@ struct ade7758_state { ...@@ -122,7 +122,7 @@ struct ade7758_state {
u8 *tx; u8 *tx;
u8 *rx; u8 *rx;
struct mutex buf_lock; struct mutex buf_lock;
u32 available_scan_masks[AD7758_NUM_WAVESRC]; unsigned long available_scan_masks[AD7758_NUM_WAVESRC];
struct iio_chan_spec *ade7758_ring_channels; struct iio_chan_spec *ade7758_ring_channels;
struct spi_transfer ring_xfer[4]; struct spi_transfer ring_xfer[4];
struct spi_message ring_msg; struct spi_message ring_msg;
......
...@@ -767,7 +767,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) ...@@ -767,7 +767,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
for (i = 0; i < AD7758_NUM_WAVESRC; i++) for (i = 0; i < AD7758_NUM_WAVESRC; i++)
st->available_scan_masks[i] = 1 << i; set_bit(i, &st->available_scan_masks[i]);
indio_dev->available_scan_masks = st->available_scan_masks; indio_dev->available_scan_masks = st->available_scan_masks;
......
...@@ -98,7 +98,7 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev) ...@@ -98,7 +98,7 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
if (!ring->scan_count) if (!ring->scan_count)
return -EINVAL; return -EINVAL;
channel = __ffs(ring->scan_mask); channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8; d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
......
...@@ -104,7 +104,7 @@ struct iio_ring_buffer { ...@@ -104,7 +104,7 @@ struct iio_ring_buffer {
int bpe; int bpe;
struct attribute_group *scan_el_attrs; struct attribute_group *scan_el_attrs;
int scan_count; int scan_count;
unsigned long scan_mask; long *scan_mask;
bool scan_timestamp; bool scan_timestamp;
const struct iio_ring_access_funcs *access; const struct iio_ring_access_funcs *access;
const struct iio_ring_setup_ops *setup_ops; const struct iio_ring_setup_ops *setup_ops;
...@@ -124,6 +124,8 @@ struct iio_ring_buffer { ...@@ -124,6 +124,8 @@ struct iio_ring_buffer {
void iio_ring_buffer_init(struct iio_ring_buffer *ring, void iio_ring_buffer_init(struct iio_ring_buffer *ring,
struct iio_dev *dev_info); struct iio_dev *dev_info);
void iio_ring_buffer_deinit(struct iio_ring_buffer *ring);
/** /**
* __iio_update_ring_buffer() - update common elements of ring buffers * __iio_update_ring_buffer() - update common elements of ring buffers
* @ring: ring buffer that is the event source * @ring: ring buffer that is the event source
...@@ -137,70 +139,14 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring, ...@@ -137,70 +139,14 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
ring->length = length; ring->length = length;
} }
/* int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit);
* These are mainly provided to allow for a change of implementation if a device
* has a large number of scan elements
*/
#define IIO_MAX_SCAN_LENGTH 31
/* note 0 used as error indicator as it doesn't make sense. */
static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
{
while (*av_masks) {
if (!(~*av_masks & mask))
return *av_masks;
av_masks++;
}
return 0;
}
static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
{
struct iio_dev *dev_info = ring->indio_dev;
u32 mask;
if (bit > IIO_MAX_SCAN_LENGTH)
return -EINVAL;
if (!ring->scan_mask)
return 0;
if (dev_info->available_scan_masks)
mask = iio_scan_mask_match(dev_info->available_scan_masks,
ring->scan_mask);
else
mask = ring->scan_mask;
if (!mask)
return -EINVAL;
return !!(mask & (1 << bit));
};
/** /**
* iio_scan_mask_set() - set particular bit in the scan mask * iio_scan_mask_set() - set particular bit in the scan mask
* @ring: the ring buffer whose scan mask we are interested in * @ring: the ring buffer whose scan mask we are interested in
* @bit: the bit to be set. * @bit: the bit to be set.
**/ **/
static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit) int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit);
{
struct iio_dev *dev_info = ring->indio_dev;
u32 mask;
u32 trialmask = ring->scan_mask | (1 << bit);
if (bit > IIO_MAX_SCAN_LENGTH)
return -EINVAL;
if (dev_info->available_scan_masks) {
mask = iio_scan_mask_match(dev_info->available_scan_masks,
trialmask);
if (!mask)
return -EINVAL;
}
ring->scan_mask = trialmask;
ring->scan_count++;
return 0;
};
#define to_iio_ring_buffer(d) \ #define to_iio_ring_buffer(d) \
container_of(d, struct iio_ring_buffer, dev) container_of(d, struct iio_ring_buffer, dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment