diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-05-22 00:36:56 -0600 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-05-22 00:36:56 -0600 |
commit | cf9b59e9d3e008591d1f54830f570982bb307a0d (patch) | |
tree | 113478ce8fd8c832ba726ffdf59b82cb46356476 /drivers/staging/iio/adc/max1363_ring.c | |
parent | 44504b2bebf8b5823c59484e73096a7d6574471d (diff) | |
parent | f4b87dee923342505e1ddba8d34ce9de33e75050 (diff) |
Merge remote branch 'origin' into secretlab/next-devicetree
Merging in current state of Linus' tree to deal with merge conflicts and
build failures in vio.c after merge.
Conflicts:
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-mpc.c
drivers/net/gianfar.c
Also fixed up one line in arch/powerpc/kernel/vio.c to use the
correct node pointer.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/staging/iio/adc/max1363_ring.c')
-rw-r--r-- | drivers/staging/iio/adc/max1363_ring.c | 82 |
1 files changed, 55 insertions, 27 deletions
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index f94fe2d38a97..56688dc9c92f 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -17,6 +17,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/i2c.h> +#include <linux/bitops.h> #include "../iio.h" #include "../ring_generic.h" @@ -26,32 +27,39 @@ #include "max1363.h" -ssize_t max1363_scan_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) +/* Todo: test this */ +int max1363_single_channel_from_ring(long mask, struct max1363_state *st) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *info = dev_info->dev_data; - int i, ret, len = 0; - char *ring_data; + unsigned long numvals; + int count = 0, ret; + u8 *ring_data; + if (!(st->current_mode->modemask & mask)) { + ret = -EBUSY; + goto error_ret; + } + numvals = hweight_long(st->current_mode->modemask); - ring_data = kmalloc(info->current_mode->numvals*2, GFP_KERNEL); + ring_data = kmalloc(numvals*2, GFP_KERNEL); if (ring_data == NULL) { ret = -ENOMEM; goto error_ret; } - ret = dev_info->ring->access.read_last(dev_info->ring, ring_data); + ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring, + ring_data); if (ret) goto error_free_ring_data; - len += sprintf(buf+len, "ring "); - for (i = 0; i < info->current_mode->numvals; i++) - len += sprintf(buf + len, "%d ", - ((int)(ring_data[i*2 + 0] & 0x0F) << 8) - + ((int)(ring_data[i*2 + 1]))); - len += sprintf(buf + len, "\n"); - kfree(ring_data); - - return len; + /* Need a count of channels prior to this one */ + mask >>= 1; + while (mask) { + if (mask & st->current_mode->modemask) + count++; + mask >>= 1; + } + if (st->chip_info->bits != 8) + ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + + (int)(ring_data[count*2 + 1]); + else + ret = ring_data[count]; error_free_ring_data: kfree(ring_data); @@ -70,9 +78,25 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) { struct max1363_state *st = indio_dev->dev_data; size_t d_size; + unsigned long numvals; + /* + * Need to figure out the current mode based upon the requested + * scan mask in iio_dev + */ + st->current_mode = max1363_match_mode(st->indio_dev->scan_mask, + st->chip_info); + if (!st->current_mode) + return -EINVAL; + + max1363_set_scan_mode(st); + + numvals = hweight_long(st->current_mode->modemask); if (indio_dev->ring->access.set_bpd) { - d_size = st->current_mode->numvals*2 + sizeof(s64); + if (st->chip_info->bits != 8) + d_size = numvals*2 + sizeof(s64); + else + d_size = numvals + sizeof(s64); if (d_size % 8) d_size += 8 - (d_size % 8); indio_dev->ring->access.set_bpd(indio_dev->ring, d_size); @@ -118,7 +142,7 @@ static int max1363_ring_predisable(struct iio_dev *indio_dev) * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ -void max1363_poll_func_th(struct iio_dev *indio_dev) +static void max1363_poll_func_th(struct iio_dev *indio_dev) { struct max1363_state *st = indio_dev->dev_data; @@ -145,9 +169,13 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) __u8 *rxbuf; int b_sent; size_t d_size; + unsigned long numvals = hweight_long(st->current_mode->modemask); /* Ensure the timestamp is 8 byte aligned */ - d_size = st->current_mode->numvals*2 + sizeof(s64); + if (st->chip_info->bits != 8) + d_size = numvals*2 + sizeof(s64); + else + d_size = numvals + sizeof(s64); if (d_size % sizeof(s64)) d_size += sizeof(s64) - (d_size % sizeof(s64)); @@ -159,16 +187,16 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) * might as well have this test in here in the meantime as it does * no harm. */ - if (st->current_mode->numvals == 0) + if (numvals == 0) return; rxbuf = kmalloc(d_size, GFP_KERNEL); if (rxbuf == NULL) return; - - b_sent = i2c_master_recv(st->client, - rxbuf, - st->current_mode->numvals*2); + if (st->chip_info->bits != 8) + b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); + else + b_sent = i2c_master_recv(st->client, rxbuf, numvals); if (b_sent < 0) goto done; @@ -238,5 +266,5 @@ void max1363_uninitialize_ring(struct iio_ring_buffer *ring) int max1363_initialize_ring(struct iio_ring_buffer *ring) { - return iio_ring_buffer_register(ring); + return iio_ring_buffer_register(ring, 0); }; |