All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
@ 2011-05-18 13:40 Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 001/111] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
                   ` (111 more replies)
  0 siblings, 112 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Dear Greg,

Here is the set I mentioned was coming.

Thomas Gleixner just pushed the required irq patches to the tip tree
(though they aren't visible yet).

[tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
fe12bc2c996d3e492b2920e32ac79f7bbae3e15d

and

[tip:irq/core] irq: Export functions to allow modular irq drivers
edf76f8307c350bcb81f0c760118a991b3e62956

There are two other dependencies. One is a trivial missing header
in arm (patch on it's way through the arm tree). Doesn't break building
except on arm anyway.

The other is the strtobool that you added to driver-core
Add a strtobool function matching semantics of existing in kernel equivalents
ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e

First some thanks are due:

Arnd Bergmann for a very useful 'review'.  We haven't yet done
everything Arnd suggested, but a lot of it is here.

Thomas Gleixner for suggesting how to handle the triggers without
reinventing the wheel.

Michael Hennerich as ever for trying everything out, killing bugs
and converting a whole host of Analog's devices over to the new
API.

Anyhow, now for a quick summary of what we have here:

1) iio_chan_spec structure introduction.  This moves responsibliity
for creation of most sysfs attributes into the core.  The same
structure is used to create all the relevant entries for buffers
as well as direct access attributes.  Note this only comes into
it's own after various other cleanups later in the series.
To evalutate this people should look at the end result, not all
the mashups that were required to let us introduce it slowly.

2) irq_chip based handling of triggers.  The kernel already has
a clean way of passing 'trigger' events around: irqs.  Thomas
pointed this out and gave some guidance on how to do this.  It
is far cleaner (and shorter) than our previous version and
also allows us to take everything into threaded interrupts.

3) Buffer interface rework.  This was based on Arnd's review.
 * event escalation is removed - there was no usecase for it,
   even when devices can provide the hardware suppport.  This
   greatly complicated our event system for little gain.
 * without escallation there is only one 'event' possible from
   a buffer at a time.  Thus Arnd pointed out we could just use
   poll to handle it and scrap the chrdev.
 * Now we only have one chrdev, we can drop most device tree we'd
   built up to handle them.
 * Event system is now only used for 'threshold events' and similar.
   Reworking that is probably next.

More minor stuff hiding in here:

* scrap the ring_helper stuff.  Seemed like a useful bit of
  helper code.  Now many things are simpler, it's not worth
  bothering.
* move name handling into the core - everyone has to do it, so why
  leave it to the drivers.
* move various allocation jobs into the core - again, they occur
  every time so why have them in drivers
* pull out const static elements of iio_dev into a new iio_info
  structure. (another Arnd suggestion).
* merge all the IMU drivers - this has been floating around for a
  long time.  We finally hammered it in as it made the other conversions
  easier.
* Lots of other cleanup.
* Couple of new parts for the max1363 driver.
* Michael found a few other old bugs whilst hammering various parts.

Anyhow, thanks Greg and sorry for sending you quite such
a big series in one go!  Its had a fair bit of testing on arm
and blackfin (build tested only on x86), but with this much code,
I wouldn't be entirely suprised if we broke a few devices...

Sorry to anyone with an out of tree driver - this will cause breakage.

Jonathan

Jonathan Cameron (92):
  staging:iio: allow channels to be set up using a table of
    iio_channel_spec structures.
  staging:iio:lis3l02dq - move to new channel_spec approach.
  staging:iio:max1363 - move to channel_spec registration.
  staging:iio: remove ability to escalate events.
  staging:iio: Add polling of events on the ring access chrdev.
  staging:iio: remove legacy event chrdev for the buffers
  staging:iio: Buffer device flattening.
  staging:iio:lis3l02dq: General cleanup
  staging:iio: Push interrupt setup down into the drivers for event
    lines.
  staging:iio: lis3l02dq - separate entirely interrupt handling for
    thesholds from that for the datardy signal.
  staging:iio:sca3000 extract old event handling and move to poll for
    events from buffer
  staging:iio:buffering remove unused parameter dead_offset from
    read_last_n in all buffer implementations.
  staging:iio:light:tsl2563 remove old style event registration.
  staging:iio:dac:ad5504 move from old to new event handling.
  staging:iio:adt7316 get rid of legacy event handling code.
  staging:iio:adc:ad7745 move from old to current event handling.
  staging:iio:adc:ad7816 move from old to current event handling.
  staging:iio:adc:ad7150 move from deprecated event handling plus
    remove irq as gpio requirement.
  staging:iio:adc:ad7152 remove unregister of interrupt line.
  staging:iio:adc:adt75 old to new event handling conversion
  staging:iio:ad7291 move from old event system to current.
  staging:iio:adc:adt7410 move to current event handling
  staging:iio:adt7310 move to current event handling
  staging:iio:adc:ad7314 remove unmatched unregister of event line.
  staging:iio:adc:ad799x move to new event handling
  staging:iio: Remove legacy event handling.
  staging:iio:accel:lis3l02dq make threshold interrupt threaded.
  staging:iio: Add infrastructure for irq_chip based triggers
  staging:iio:Documentation generic_buffer.c update to new abi for
    buffers + misc fixes
  staging:iio:ring_sw add function needed for threaded irq.
  staging:iio: add generic data ready poll function.
  staging:iio:accel:lis3l02dq move to threaded trigger handling.
  staging:iio:adc:max1363 move to irqchip based threaded irq triggering
  staging:iio:adc:ad7476 use channel_spec
  staging:iio:adc:ad7476 move to irqchip based triggering
  staging:iio:meter:ade7758 move to irqchip based trigger handling.
  staging:iio:imu:adis16400 move to irq based triggers and channel spec
    channel registration.
  staging:iio:imu:adis16350 etc support into adis16400 driver.
  staging:iio:imu remove old adis16350. Support now in adis16400
    driver.
  staging:iio:imu:adis16400 add support for adis16300
  staging:iio:imu remove adis16300 driver.
  staging:iio:accel:adis16201 move to irqchip based trigger handling.
  staging:iio:accel:adis16203 move to irqchip based trigger handling.
  staging:iio:accel:adis16204 move to irqchip based trigger handling.
  staging:iio:accel:adis16209 move to irqchip based trigger handling.
  staging:iio:accel:adis16240 move to irqchip based trigger handling.
  staging:iio:adc:ad7298 move to irqchip based trigger handling.
  staging:iio:adc:ad7606 conversion to irq_chip based polling.
  staging:iio:adc:ad7887 move to irqchip based trigger handling.
  staging:iio:adc:ad799x move to irqchip based trigger handling.
  staging:iio:gyro:adis16260 move to irqchip based trigger handling.
  staging:iio:trigger remove legacy pollfunc elements.
  staging:iio: Add core attribute handling for name of device.
  staging:iio: use the new central name attribute creation code
  staging:iio:light:tsl2563: chan_spec based channel setup.
  staging:iio:accel:adis16201 move to chan_spec based setup.
  staging:iio:accel:adis16203 move to chan_spec based setup.
  staging:iio:accel:adis16204 move to chan_spec based setup.
  staging:iio:accel:adis16209 move to chan_spec based setup.
  staging:iio:adc:ad799x removed unused headers.
  staging:iio:accel: lis3l02dq add writing for calibscale and
    calibbias.
  staging:iio: Add chan info support for 'peak_raw' attributes.
  staging:iio:accel:adis16240 move to chan_spec based setup.
  staging:iio:gyro:adis16260 move to chan_spec based setup.
  staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs
    like everything else.
  staging:iio:max1363 trivial removal of unused trig pointer.
  staging:iio:max1363 add new 2 channels parts form maxim, 11644-7
  staging:iio:trigger sysfs userspace trigger rework.
  staging:iio:core clean out unused elements.
  staging:iio:adc:ad7150 fix event codes.
  staging:iio:adc:ad7816 and adt75 change to meaningful event code.
  staging:iio:adc:ad7291 remove abuse of buffer events and replace with
    something almost sane
  staging:iio:adc:adt7310 replace abuse of buffer events.
  staging:iio:adc:adt7410 replace abuse of buffer events.
  staging:iio:addac:adt7316 replace abuse of buffer events.
  staging:iio:buffer - remove unused event code for buffer events.
  staging:iio:lis3l02dq remerge the two interrupt handlers.
  staging:iio: iio_event_interfaces - clean out unused elements
  staging:iio:trigger handle name attr in core, remove old alloc and
    register any control_attrs via struct device
  drivers:staging:iio:imu:adis16400 avoid allocating rx, tx, and state
    separately from iio_dev.
  staging:iio: rationalization of different buffer implementation
    hooks.
  staging:iio: Rip out helper for software rings.
  staging:iio:ad7780 trivial unused header cleanup.
  staging:iio: poll func allocation clean up.
  staging:iio:core cleanup: squash tiny wrappers and use dev_set_name
    to handle creation of event interface name.
  staging:iio: ring core cleanups + check if read_last available in
    lis3l02dq
  staging:iio:accel:lis3l02dq make write_reg_8 take value not a pointer
    to value.
  staging:iio: implement an iio_info structure to take some of the
    constant elements out of iio_dev.
  staging:iio:max1363 misc cleanups and use of for_each_bit_set to    
    simplify event code spitting out.
  staging:iio: use pollfunc allocation helpers in remaining drivers.
  staging:iio:documenation partial update.
  staging:iio: Trivial kconfig reorganization and uniformity
    improvements.

Michael Hennerich (19):
  staging:iio:adc:ad7887: Convert to new channel registration method.
  staging:iio:adc:ad7887: Use private data space from
    iio_allocate_device
  staging:iio:adc:ad799x: Convert to new channel registration method.
  staging:iio:adc:ad799x: Use private data space from
    iio_allocate_device
  staging:iio:adc:ad7298: Convert to new channel registration method
  staging:iio:adc:ad7606 Convert to new channel registration method
    Update Add missing call to iio_trigger_notify_done() Set pollfunc
    top and bottom half handler
  staging:iio:adc:ad7606: Use private data space from
    iio_allocate_device
  staging:iio: Add channel types IIO_CURRENT and IIO_POWER.
  staging:iio:meter:ade7758: Update trigger to the new API
  staging:iio:meter:ade7758: Fix timing on SPI read accessor functions.
  iio:staging:meter:ade7758: Fix return value of ade7758_write_reset
  staging:iio:meter:ade7758: Fix list and set of available sample
    frequencies.
  staging:iio:meter:ade7758: Use iio channel spec and miscellaneous
    other changes.
  staging:iio:adc:AD7298: Use private data space from
    iio_allocate_device
  staging:iio:adc: AD7606: Consitently use indio_dev
  staging:iio:adc: AD7606: Drop dev_data in favour of iio_priv()
  staging:iio:adc:AD7780: Convert to new channel registration method
  staging:iio:adc: AD7780: Use private data space from
    iio_allocate_device + trivial fixes
  staging:iio:meter:ade7758: Use private data space from
    iio_allocate_device

 drivers/staging/iio/Documentation/device.txt       |   78 +-
 drivers/staging/iio/Documentation/generic_buffer.c |   93 +-
 drivers/staging/iio/Documentation/iio_utils.h      |   20 +-
 drivers/staging/iio/Documentation/overview.txt     |   19 +-
 drivers/staging/iio/Documentation/ring.txt         |   44 +-
 drivers/staging/iio/Documentation/trigger.txt      |   16 +-
 drivers/staging/iio/Documentation/userspace.txt    |   12 -
 drivers/staging/iio/Kconfig                        |   15 +-
 drivers/staging/iio/accel/adis16201.h              |    9 +-
 drivers/staging/iio/accel/adis16201_core.c         |  467 +++---
 drivers/staging/iio/accel/adis16201_ring.c         |  146 +--
 drivers/staging/iio/accel/adis16201_trigger.c      |   53 +-
 drivers/staging/iio/accel/adis16203.h              |   18 +-
 drivers/staging/iio/accel/adis16203_core.c         |  389 +++--
 drivers/staging/iio/accel/adis16203_ring.c         |  123 +-
 drivers/staging/iio/accel/adis16203_trigger.c      |   53 +-
 drivers/staging/iio/accel/adis16204.h              |   18 +-
 drivers/staging/iio/accel/adis16204_core.c         |  412 +++---
 drivers/staging/iio/accel/adis16204_ring.c         |  126 +-
 drivers/staging/iio/accel/adis16204_trigger.c      |   53 +-
 drivers/staging/iio/accel/adis16209.h              |    6 +-
 drivers/staging/iio/accel/adis16209_core.c         |  446 +++---
 drivers/staging/iio/accel/adis16209_ring.c         |  143 +--
 drivers/staging/iio/accel/adis16209_trigger.c      |   42 +-
 drivers/staging/iio/accel/adis16220_core.c         |   11 +-
 drivers/staging/iio/accel/adis16240.h              |    7 +-
 drivers/staging/iio/accel/adis16240_core.c         |  370 +++--
 drivers/staging/iio/accel/adis16240_ring.c         |  131 +-
 drivers/staging/iio/accel/adis16240_trigger.c      |   42 +-
 drivers/staging/iio/accel/kxsd9.c                  |   12 +-
 drivers/staging/iio/accel/lis3l02dq.h              |   46 +-
 drivers/staging/iio/accel/lis3l02dq_core.c         |  842 ++++------
 drivers/staging/iio/accel/lis3l02dq_ring.c         |  504 +++---
 drivers/staging/iio/accel/sca3000.h                |   76 +-
 drivers/staging/iio/accel/sca3000_core.c           |  953 ++++-------
 drivers/staging/iio/accel/sca3000_ring.c           |  265 ++-
 drivers/staging/iio/adc/Kconfig                    |   48 +-
 drivers/staging/iio/adc/ad7150.c                   |  176 +--
 drivers/staging/iio/adc/ad7152.c                   |   31 +-
 drivers/staging/iio/adc/ad7291.c                   |  500 ++----
 drivers/staging/iio/adc/ad7298.h                   |   12 +-
 drivers/staging/iio/adc/ad7298_core.c              |  242 ++--
 drivers/staging/iio/adc/ad7298_ring.c              |  134 +-
 drivers/staging/iio/adc/ad7314.c                   |   33 +-
 drivers/staging/iio/adc/ad7476.h                   |    7 +-
 drivers/staging/iio/adc/ad7476_core.c              |  171 +-
 drivers/staging/iio/adc/ad7476_ring.c              |  127 +-
 drivers/staging/iio/adc/ad7606.h                   |   20 +-
 drivers/staging/iio/adc/ad7606_core.c              |  300 ++--
 drivers/staging/iio/adc/ad7606_par.c               |   30 +-
 drivers/staging/iio/adc/ad7606_ring.c              |  152 +--
 drivers/staging/iio/adc/ad7606_spi.c               |   24 +-
 drivers/staging/iio/adc/ad7745.c                   |  119 +-
 drivers/staging/iio/adc/ad7780.c                   |  186 +--
 drivers/staging/iio/adc/ad7816.c                   |  109 +-
 drivers/staging/iio/adc/ad7887.h                   |   17 +-
 drivers/staging/iio/adc/ad7887_core.c              |  200 +--
 drivers/staging/iio/adc/ad7887_ring.c              |  156 +--
 drivers/staging/iio/adc/ad799x.h                   |   33 +-
 drivers/staging/iio/adc/ad799x_core.c              |  859 ++++------
 drivers/staging/iio/adc/ad799x_ring.c              |   93 +-
 drivers/staging/iio/adc/adt7310.c                  |  204 +--
 drivers/staging/iio/adc/adt7410.c                  |  199 +--
 drivers/staging/iio/adc/adt75.c                    |  178 +--
 drivers/staging/iio/adc/max1363.h                  |   91 +-
 drivers/staging/iio/adc/max1363_core.c             | 1844 ++++++++------------
 drivers/staging/iio/adc/max1363_ring.c             |   90 +-
 drivers/staging/iio/addac/adt7316.c                |  494 ++----
 drivers/staging/iio/chrdev.h                       |   44 +-
 drivers/staging/iio/dac/ad5446.c                   |   21 +-
 drivers/staging/iio/dac/ad5504.c                   |   88 +-
 drivers/staging/iio/dac/ad5504.h                   |    4 -
 drivers/staging/iio/dac/ad5624r_spi.c              |   21 +-
 drivers/staging/iio/dac/ad5791.c                   |    8 +-
 drivers/staging/iio/dac/max517.c                   |   15 +-
 drivers/staging/iio/dds/ad5930.c                   |   12 +-
 drivers/staging/iio/dds/ad9832.c                   |   21 +-
 drivers/staging/iio/dds/ad9834.c                   |   21 +-
 drivers/staging/iio/dds/ad9850.c                   |   10 +-
 drivers/staging/iio/dds/ad9852.c                   |   10 +-
 drivers/staging/iio/dds/ad9910.c                   |   10 +-
 drivers/staging/iio/dds/ad9951.c                   |   10 +-
 drivers/staging/iio/gyro/adis16060_core.c          |    8 +-
 drivers/staging/iio/gyro/adis16080_core.c          |   11 +-
 drivers/staging/iio/gyro/adis16130_core.c          |   12 +-
 drivers/staging/iio/gyro/adis16260.h               |    7 +-
 drivers/staging/iio/gyro/adis16260_core.c          |  460 +++---
 drivers/staging/iio/gyro/adis16260_ring.c          |  124 +-
 drivers/staging/iio/gyro/adis16260_trigger.c       |   55 +-
 drivers/staging/iio/gyro/adxrs450_core.c           |    8 +-
 drivers/staging/iio/iio.h                          |  339 +++--
 drivers/staging/iio/imu/Kconfig                    |   26 +-
 drivers/staging/iio/imu/Makefile                   |    8 -
 drivers/staging/iio/imu/adis16300.h                |  184 --
 drivers/staging/iio/imu/adis16300_core.c           |  732 --------
 drivers/staging/iio/imu/adis16300_ring.c           |  238 ---
 drivers/staging/iio/imu/adis16300_trigger.c        |  119 --
 drivers/staging/iio/imu/adis16350.h                |  177 --
 drivers/staging/iio/imu/adis16350_core.c           |  733 --------
 drivers/staging/iio/imu/adis16350_ring.c           |  236 ---
 drivers/staging/iio/imu/adis16350_trigger.c        |  119 --
 drivers/staging/iio/imu/adis16400.h                |   38 +-
 drivers/staging/iio/imu/adis16400_core.c           |  715 +++++---
 drivers/staging/iio/imu/adis16400_ring.c           |  235 ++--
 drivers/staging/iio/imu/adis16400_trigger.c        |   71 +-
 drivers/staging/iio/industrialio-core.c            |  928 +++++++---
 drivers/staging/iio/industrialio-ring.c            |  579 ++++---
 drivers/staging/iio/industrialio-trigger.c         |  272 ++-
 drivers/staging/iio/kfifo_buf.c                    |   61 +-
 drivers/staging/iio/kfifo_buf.h                    |   40 +-
 drivers/staging/iio/light/Kconfig                  |   26 +-
 drivers/staging/iio/light/isl29018.c               |   21 +-
 drivers/staging/iio/light/tsl2563.c                |  387 ++---
 drivers/staging/iio/light/tsl2583.c                |    8 +-
 drivers/staging/iio/magnetometer/ak8975.c          |    8 +-
 drivers/staging/iio/magnetometer/hmc5843.c         |    8 +-
 drivers/staging/iio/meter/ade7753.c                |   12 +-
 drivers/staging/iio/meter/ade7754.c                |   12 +-
 drivers/staging/iio/meter/ade7758.h                |   71 +-
 drivers/staging/iio/meter/ade7758_core.c           |  342 ++--
 drivers/staging/iio/meter/ade7758_ring.c           |  281 ++--
 drivers/staging/iio/meter/ade7758_trigger.c        |   61 +-
 drivers/staging/iio/meter/ade7759.c                |   13 +-
 drivers/staging/iio/meter/ade7854.c                |    8 +-
 drivers/staging/iio/resolver/ad2s120x.c            |   11 +-
 drivers/staging/iio/resolver/ad2s1210.c            |   10 +-
 drivers/staging/iio/resolver/ad2s90.c              |   10 +-
 drivers/staging/iio/ring_generic.h                 |  287 +---
 drivers/staging/iio/ring_sw.c                      |  198 +--
 drivers/staging/iio/ring_sw.h                      |  196 +--
 drivers/staging/iio/sysfs.h                        |  185 +--
 drivers/staging/iio/trigger.h                      |  109 +-
 drivers/staging/iio/trigger/iio-trig-bfin-timer.c  |   22 +-
 drivers/staging/iio/trigger/iio-trig-gpio.c        |   25 +-
 .../staging/iio/trigger/iio-trig-periodic-rtc.c    |   24 +-
 drivers/staging/iio/trigger/iio-trig-sysfs.c       |  169 ++-
 136 files changed, 8665 insertions(+), 13608 deletions(-)
 delete mode 100644 drivers/staging/iio/Documentation/userspace.txt
 delete mode 100644 drivers/staging/iio/imu/adis16300.h
 delete mode 100644 drivers/staging/iio/imu/adis16300_core.c
 delete mode 100644 drivers/staging/iio/imu/adis16300_ring.c
 delete mode 100644 drivers/staging/iio/imu/adis16300_trigger.c
 delete mode 100644 drivers/staging/iio/imu/adis16350.h
 delete mode 100644 drivers/staging/iio/imu/adis16350_core.c
 delete mode 100644 drivers/staging/iio/imu/adis16350_ring.c
 delete mode 100644 drivers/staging/iio/imu/adis16350_trigger.c

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 001/111] staging:iio: allow channels to be set up using a table of iio_channel_spec structures.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 002/111] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
                   ` (110 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V8: Add missing address in IIO_CHAN macro. Spotted by Michael Hennerich.
V7: Document additions to iio_dev structure.
V6: Fixup the docs for iio_chan_spec structure.
V5: Actually have the macro handle the _input type channels (oops)
V4: Add ability to do, _input and modified channel naming in a coherent fashion.
    Scrap all the messy IIO_CHAN_* macros and move to only one.

V3: Added more types - intensity and light.

V2: Various fixes - some thanks to Arnd.
    Bug fix for unregistering of event attr group
    Changed iio_read_channel_info to have two part value - use for
    raw value read as well.
    constify the channelspec structures
    raw write support for calibbias and similar
    Additional strings for buidling attribute names.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/chrdev.h            |    3 +
 drivers/staging/iio/iio.h               |  208 +++++++++-
 drivers/staging/iio/industrialio-core.c |  738 +++++++++++++++++++++++++++++--
 drivers/staging/iio/industrialio-ring.c |  188 ++++++++-
 drivers/staging/iio/ring_generic.h      |   20 +
 drivers/staging/iio/sysfs.h             |   58 ++-
 6 files changed, 1161 insertions(+), 54 deletions(-)

diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 4fcb99c..62c4285 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -91,6 +91,9 @@ struct iio_event_interface {
 	void					*private;
 	char					_name[35];
 	char					_attrname[20];
+
+	struct list_head event_attr_list;
+	struct list_head dev_attr_list;
 };
 
 /**
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 80ef2cf..440704c 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -26,6 +26,161 @@
 
 struct iio_dev;
 
+/* naughty temporary hack to match these against the event version
+   - need to flattern these together */
+enum iio_chan_type {
+	/* Need this here for now to support buffer events
+	 * set to 0  to avoid changes to ring_generic.c */
+	IIO_BUFFER = 0,
+
+	/* real channel types */
+	IIO_IN,
+	IIO_ACCEL,
+	IIO_IN_DIFF,
+	IIO_GYRO,
+	IIO_MAGN,
+	IIO_LIGHT,
+	IIO_INTENSITY,
+	IIO_PROXIMITY,
+	IIO_TEMP,
+	IIO_INCLI,
+	IIO_ROT,
+	IIO_ANGL,
+	IIO_TIMESTAMP,
+};
+
+#define IIO_MOD_X			0
+#define IIO_MOD_LIGHT_BOTH		0
+#define IIO_MOD_Y			1
+#define IIO_MOD_LIGHT_IR		1
+#define IIO_MOD_Z			2
+#define IIO_MOD_X_AND_Y			3
+#define IIO_MOD_X_ANX_Z			4
+#define IIO_MOD_Y_AND_Z			5
+#define IIO_MOD_X_AND_Y_AND_Z		6
+#define IIO_MOD_X_OR_Y			7
+#define IIO_MOD_X_OR_Z			8
+#define IIO_MOD_Y_OR_Z			9
+#define IIO_MOD_X_OR_Y_OR_Z		10
+
+/* Could add the raw attributes as well - allowing buffer only devices */
+enum iio_chan_info_enum {
+	IIO_CHAN_INFO_SCALE_SHARED,
+	IIO_CHAN_INFO_SCALE_SEPARATE,
+	IIO_CHAN_INFO_OFFSET_SHARED,
+	IIO_CHAN_INFO_OFFSET_SEPARATE,
+	IIO_CHAN_INFO_CALIBSCALE_SHARED,
+	IIO_CHAN_INFO_CALIBSCALE_SEPARATE,
+	IIO_CHAN_INFO_CALIBBIAS_SHARED,
+	IIO_CHAN_INFO_CALIBBIAS_SEPARATE
+};
+
+/**
+ * struct iio_chan_spec - specification of a single channel
+ * @type:		What type of measurement is the channel making.
+ * @channel:		What number or name do we wish to asign the channel.
+ * @channel2:		If there is a second number for a differential
+ *			channel then this is it. If modified is set then the
+ *			value here specifies the modifier.
+ * @address:		Driver specific identifier.
+ * @scan_index:	Monotonic index to give ordering in scans when read
+ *			from a buffer.
+ * @scan_type:		Sign:		's' or 'u' to specify signed or unsigned
+ *			realbits:	Number of valid bits of data
+ *			storage_bits:	Realbits + padding
+ *			shift:		Shift right by this before masking out
+ *					realbits.
+ * @info_mask:		What information is to be exported about this channel.
+ *			This includes calibbias, scale etc.
+ * @event_mask:	What events can this channel produce.
+ * @extend_name:	Allows labeling of channel attributes with an
+ *			informative name. Note this has no effect codes etc,
+ *			unlike modifiers.
+ * @processed_val:	Flag to specify the data access attribute should be
+ *			*_input rather than *_raw.
+ * @modified:		Does a modifier apply to this channel. What these are
+ *			depends on the channel type.  Modifier is set in
+ *			channel2. Examples are IIO_MOD_X for axial sensors about
+ *			the 'x' axis.
+ * @indexed:		Specify the channel has a numerical index. If not,
+ *			the value in channel will be suppressed for attribute
+ *			but not for event codes. Typically set it to 0 when
+ *			the index is false.
+ * @shared_handler:	Single handler for the events registered.
+ */
+struct iio_chan_spec {
+	enum iio_chan_type	type;
+	int			channel;
+	int			channel2;
+	unsigned long		address;
+	int			scan_index;
+	struct {
+		char	sign;
+		u8	realbits;
+		u8	storagebits;
+		u8	shift;
+	} scan_type;
+	const long		info_mask;
+	const long		event_mask;
+	const char		*extend_name;
+	unsigned		processed_val:1;
+	unsigned		modified:1;
+	unsigned		indexed:1;
+	/* TODO: investigate pushing shared event handling out to
+	 * the drivers */
+	struct iio_event_handler_list *shared_handler;
+};
+/* Meant for internal use only */
+void __iio_device_attr_deinit(struct device_attribute *dev_attr);
+int __iio_device_attr_init(struct device_attribute *dev_attr,
+			   const char *postfix,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   bool generic);
+#define IIO_ST(si, rb, sb, sh)						\
+	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
+
+#define IIO_CHAN(_type, _mod, _indexed, _proc, _name, _chan, _chan2,	\
+		 _inf_mask, _address, _si, _stype, _event_mask,		\
+		 _handler)						\
+	{ .type = _type,						\
+	  .modified = _mod,						\
+	  .indexed = _indexed,						\
+	  .processed_val = _proc,					\
+	  .extend_name = _name,						\
+	  .channel = _chan,						\
+	  .channel2 = _chan2,						\
+	  .info_mask = _inf_mask,					\
+	  .address = _address,						\
+	  .scan_index = _si,						\
+	  .scan_type = _stype,						\
+	  .event_mask = _event_mask,					\
+	  .shared_handler = _handler }
+
+#define IIO_CHAN_SOFT_TIMESTAMP(_si)					\
+	{ .type = IIO_TIMESTAMP, .channel = -1,				\
+			.scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) }
+
+int __iio_add_chan_devattr(const char *postfix,
+			   const char *group,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*func)(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   int mask,
+			   bool generic,
+			   struct device *dev,
+			   struct list_head *attr_list);
 /**
  * iio_get_time_ns() - utility function to get a time stamp for events etc
  **/
@@ -70,7 +225,8 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
 
 /* Vast majority of this is set by the industrialio subsystem on a
  * call to iio_device_register. */
-
+#define IIO_VAL_INT 1
+#define IIO_VAL_INT_PLUS_MICRO 2
 /**
  * struct iio_dev - industrial I/O device
  * @id:			[INTERN] used to identify device internally
@@ -93,6 +249,24 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @trig:		[INTERN] current device trigger (ring buffer modes)
  * @pollfunc:		[DRIVER] function run on trigger being received
+ * @channels:		[DRIVER] channel specification structure table
+ * @num_channels:	[DRIVER] number of chanels specified in @channels.
+ * @channel_attr_list:	[INTERN] keep track of automatically created channel
+ *			attributes.
+ * @name:		[DRIVER] name of the device.
+ * @read_raw:		[DRIVER] function to request a value from the device.
+ *			mask specifies which value. Note 0 means a reading of
+ *			the channel in question.  Return value will specify the
+ *			type of value returned by the device. val and val2 will
+ *			contain the elements making up the returned value.
+ * @write_raw:		[DRIVER] function to write a value to the device.
+ *			Parameters are the same as for read_raw.
+ * @read_event_config:	[DRIVER] find out if the event is enabled.
+ * @write_event_config:	[DRIVER] set if the event is enabled.
+ * @read_event_value:	[DRIVER] read a value associated with the event. Meaning
+ *			is event dependant. event_code specifies which event.
+ * @write_event_value:	[DRIVER] write the value associate with the event.
+ *			Meaning is event dependent.
  **/
 struct iio_dev {
 	int				id;
@@ -116,6 +290,38 @@ struct iio_dev {
 	u32				*available_scan_masks;
 	struct iio_trigger		*trig;
 	struct iio_poll_func		*pollfunc;
+
+	struct iio_chan_spec const *channels;
+	int num_channels;
+	struct list_head channel_attr_list;
+
+	char *name; /*device name - IMPLEMENT */
+	int (*read_raw)(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val,
+			int *val2,
+			long mask);
+
+	int (*write_raw)(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan,
+			 int val,
+			 int val2,
+			 long mask);
+
+	int (*read_event_config)(struct iio_dev *indio_dev,
+				 int event_code);
+
+	int (*write_event_config)(struct iio_dev *indio_dev,
+				  int event_code,
+				  struct iio_event_handler_list *listel,
+				  int state);
+
+	int (*read_event_value)(struct iio_dev *indio_dev,
+				int event_code,
+				int *val);
+	int (*write_event_value)(struct iio_dev *indio_dev,
+				 int event_code,
+				 int val);
 };
 
 /**
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 3a82414..b67394c 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -44,6 +44,44 @@ struct bus_type iio_bus_type = {
 };
 EXPORT_SYMBOL(iio_bus_type);
 
+static const char * const iio_chan_type_name_spec_shared[] = {
+	[IIO_TIMESTAMP] = "timestamp",
+	[IIO_ACCEL] = "accel",
+	[IIO_IN] = "in",
+	[IIO_IN_DIFF] = "in-in",
+	[IIO_GYRO] = "gyro",
+	[IIO_TEMP] = "temp",
+	[IIO_MAGN] = "magn",
+	[IIO_INCLI] = "incli",
+	[IIO_ROT] = "rot",
+	[IIO_INTENSITY] = "intensity",
+	[IIO_LIGHT] = "illuminance",
+	[IIO_ANGL] = "angl",
+};
+
+static const char * const iio_chan_type_name_spec_complex[] = {
+	[IIO_IN_DIFF] = "in%d-in%d",
+};
+
+static const char * const iio_modifier_names_light[] = {
+	[IIO_MOD_LIGHT_BOTH] = "both",
+	[IIO_MOD_LIGHT_IR] = "ir",
+};
+
+static const char * const iio_modifier_names_axial[] = {
+	[IIO_MOD_X] = "x",
+	[IIO_MOD_Y] = "y",
+	[IIO_MOD_Z] = "z",
+};
+
+/* relies on pairs of these shared then separate */
+static const char * const iio_chan_info_postfix[] = {
+	[IIO_CHAN_INFO_SCALE_SHARED/2] = "scale",
+	[IIO_CHAN_INFO_OFFSET_SHARED/2] = "offset",
+	[IIO_CHAN_INFO_CALIBSCALE_SHARED/2] = "calibscale",
+	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
+};
+
 void __iio_change_event(struct iio_detected_event_list *ev,
 			int ev_code,
 			s64 timestamp)
@@ -488,24 +526,375 @@ static void __exit iio_exit(void)
 	bus_unregister(&iio_bus_type);
 }
 
-static int iio_device_register_sysfs(struct iio_dev *dev_info)
+static ssize_t iio_read_channel_info(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
 {
-	int ret = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val, val2;
+	int ret = indio_dev->read_raw(indio_dev, this_attr->c,
+				      &val, &val2, this_attr->address);
 
-	ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
-	if (ret) {
-		dev_err(dev_info->dev.parent,
-			"Failed to register sysfs hooks\n");
+	if (ret < 0)
+		return ret;
+
+	if (ret == IIO_VAL_INT)
+		return sprintf(buf, "%d\n", val);
+	else if (ret == IIO_VAL_INT_PLUS_MICRO) {
+		if (val2 < 0)
+			return sprintf(buf, "-%d.%06u\n", val, -val2);
+		else
+			return sprintf(buf, "%d.%06u\n", val, val2);
+	} else
+		return 0;
+}
+
+static ssize_t iio_write_channel_info(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret, integer = 0, micro = 0, micro_mult = 100000;
+	bool integer_part = true, negative = false;
+
+	/* Assumes decimal - precision based on number of digits */
+	if (!indio_dev->write_raw)
+		return -EINVAL;
+	if (buf[0] == '-') {
+		negative = true;
+		buf++;
+	}
+	while (*buf) {
+		if ('0' <= *buf && *buf <= '9') {
+			if (integer_part)
+				integer = integer*10 + *buf - '0';
+			else {
+				micro += micro_mult*(*buf - '0');
+				if (micro_mult == 1)
+					break;
+				micro_mult /= 10;
+			}
+		} else if (*buf == '\n') {
+			if (*(buf + 1) == '\0')
+				break;
+			else
+				return -EINVAL;
+		} else if (*buf == '.') {
+			integer_part = false;
+		} else {
+			return -EINVAL;
+		}
+		buf++;
+	}
+	if (negative) {
+		if (integer)
+			integer = -integer;
+		else
+			micro = -micro;
+	}
+
+	ret = indio_dev->write_raw(indio_dev, this_attr->c,
+				       integer, micro, this_attr->address);
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+static int __iio_build_postfix(struct iio_chan_spec const *chan,
+			       bool generic,
+			       const char *postfix,
+			       char **result)
+{
+	char *all_post;
+	/* 3 options - generic, extend_name, modified - if generic, extend_name
+	* and modified cannot apply.*/
+
+	if (generic || (!chan->modified && !chan->extend_name)) {
+		all_post = kasprintf(GFP_KERNEL, "%s", postfix);
+	} else if (chan->modified) {
+		const char *intermediate;
+		switch (chan->type) {
+		case IIO_INTENSITY:
+			intermediate
+				= iio_modifier_names_light[chan->channel2];
+			break;
+		case IIO_ACCEL:
+		case IIO_GYRO:
+		case IIO_MAGN:
+		case IIO_INCLI:
+		case IIO_ROT:
+		case IIO_ANGL:
+			intermediate
+				= iio_modifier_names_axial[chan->channel2];
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (chan->extend_name)
+			all_post = kasprintf(GFP_KERNEL, "%s_%s_%s",
+					     intermediate,
+					     chan->extend_name,
+					     postfix);
+		else
+			all_post = kasprintf(GFP_KERNEL, "%s_%s",
+					     intermediate,
+					     postfix);
+	} else
+		all_post = kasprintf(GFP_KERNEL, "%s_%s", chan->extend_name,
+				     postfix);
+	if (all_post == NULL)
+		return -ENOMEM;
+	*result = all_post;
+	return 0;
+}
+
+int __iio_device_attr_init(struct device_attribute *dev_attr,
+			   const char *postfix,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   bool generic)
+{
+	int ret;
+	char *name_format, *full_postfix;
+	sysfs_attr_init(&dev_attr->attr);
+	ret = __iio_build_postfix(chan, generic, postfix, &full_postfix);
+	if (ret)
+		goto error_ret;
+
+	/* Special case for types that uses both channel numbers in naming */
+	if (chan->type == IIO_IN_DIFF && !generic)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_complex[chan->type],
+				    full_postfix);
+	else if (generic || !chan->indexed)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    full_postfix);
+	else
+		name_format
+			= kasprintf(GFP_KERNEL, "%s%d_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    chan->channel,
+				    full_postfix);
+
+	if (name_format == NULL) {
+		ret = -ENOMEM;
+		goto error_free_full_postfix;
+	}
+	dev_attr->attr.name = kasprintf(GFP_KERNEL,
+					name_format,
+					chan->channel,
+					chan->channel2);
+	if (dev_attr->attr.name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name_format;
+	}
+
+	if (readfunc) {
+		dev_attr->attr.mode |= S_IRUGO;
+		dev_attr->show = readfunc;
+	}
+
+	if (writefunc) {
+		dev_attr->attr.mode |= S_IWUSR;
+		dev_attr->store = writefunc;
+	}
+	kfree(name_format);
+	kfree(full_postfix);
+
+	return 0;
+
+error_free_name_format:
+	kfree(name_format);
+error_free_full_postfix:
+	kfree(full_postfix);
+error_ret:
+	return ret;
+}
+
+void __iio_device_attr_deinit(struct device_attribute *dev_attr)
+{
+	kfree(dev_attr->attr.name);
+}
+
+int __iio_add_chan_devattr(const char *postfix,
+			   const char *group,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   int mask,
+			   bool generic,
+			   struct device *dev,
+			   struct list_head *attr_list)
+{
+	int ret;
+	struct iio_dev_attr *iio_attr, *t;
+
+	iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL);
+	if (iio_attr == NULL) {
+		ret = -ENOMEM;
 		goto error_ret;
 	}
+	ret = __iio_device_attr_init(&iio_attr->dev_attr,
+				     postfix, chan,
+				     readfunc, writefunc, generic);
+	if (ret)
+		goto error_iio_dev_attr_free;
+	iio_attr->c = chan;
+	iio_attr->address = mask;
+	list_for_each_entry(t, attr_list, l)
+		if (strcmp(t->dev_attr.attr.name,
+			   iio_attr->dev_attr.attr.name) == 0) {
+			if (!generic)
+				dev_err(dev, "tried to double register : %s\n",
+					t->dev_attr.attr.name);
+			ret = -EBUSY;
+			goto error_device_attr_deinit;
+		}
+
+	ret = sysfs_add_file_to_group(&dev->kobj,
+				      &iio_attr->dev_attr.attr, group);
+	if (ret < 0)
+		goto error_device_attr_deinit;
+
+	list_add(&iio_attr->l, attr_list);
+
+	return 0;
+
+error_device_attr_deinit:
+	__iio_device_attr_deinit(&iio_attr->dev_attr);
+error_iio_dev_attr_free:
+	kfree(iio_attr);
+error_ret:
+	return ret;
+}
+
+static int iio_device_add_channel_sysfs(struct iio_dev *dev_info,
+					struct iio_chan_spec const *chan)
+{
+	int ret, i;
+
+
+	if (chan->channel < 0)
+		return 0;
+	if (chan->processed_val)
+		ret = __iio_add_chan_devattr("input", NULL, chan,
+					     &iio_read_channel_info,
+					     NULL,
+					     0,
+					     0,
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+	else
+		ret = __iio_add_chan_devattr("raw", NULL, chan,
+					     &iio_read_channel_info,
+					     NULL,
+					     0,
+					     0,
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+	if (ret)
+		goto error_ret;
+
+	for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
+		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
+					     NULL, chan,
+					     &iio_read_channel_info,
+					     &iio_write_channel_info,
+					     (1 << i),
+					     !(i%2),
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+		if (ret == -EBUSY && (i%2 == 0)) {
+			ret = 0;
+			continue;
+		}
+		if (ret < 0)
+			goto error_ret;
+	}
+error_ret:
+	return ret;
+}
+
+static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
+						 struct iio_dev_attr *p)
+{
+	sysfs_remove_file_from_group(&dev_info->dev.kobj,
+				     &p->dev_attr.attr, NULL);
+	kfree(p->dev_attr.attr.name);
+	kfree(p);
+}
+
+static int iio_device_register_sysfs(struct iio_dev *dev_info)
+{
+	int i, ret = 0;
+	struct iio_dev_attr *p, *n;
+
+	if (dev_info->attrs) {
+		ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
+		if (ret) {
+			dev_err(dev_info->dev.parent,
+				"Failed to register sysfs hooks\n");
+			goto error_ret;
+		}
+	}
 
+	/*
+	 * New channel registration method - relies on the fact a group does
+	 *  not need to be initialized if it is name is NULL.
+	 */
+	INIT_LIST_HEAD(&dev_info->channel_attr_list);
+	if (dev_info->channels)
+		for (i = 0; i < dev_info->num_channels; i++) {
+			ret = iio_device_add_channel_sysfs(dev_info,
+							   &dev_info
+							   ->channels[i]);
+			if (ret < 0)
+				goto error_clear_attrs;
+		}
+
+	return 0;
+error_clear_attrs:
+	list_for_each_entry_safe(p, n,
+				 &dev_info->channel_attr_list, l) {
+		list_del(&p->l);
+		iio_device_remove_and_free_read_attr(dev_info, p);
+	}
+	if (dev_info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 error_ret:
 	return ret;
+
 }
 
 static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
-	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
+
+	struct iio_dev_attr *p, *n;
+	list_for_each_entry_safe(p, n, &dev_info->channel_attr_list, l) {
+		list_del(&p->l);
+		iio_device_remove_and_free_read_attr(dev_info, p);
+	}
+
+	if (dev_info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
 /* Return a negative errno on failure */
@@ -552,8 +941,277 @@ static void iio_device_unregister_id(struct iio_dev *dev_info)
 	iio_free_ida_val(&iio_ida, dev_info->id);
 }
 
+static const char * const iio_ev_type_text[] = {
+	[IIO_EV_TYPE_THRESH] = "thresh",
+	[IIO_EV_TYPE_MAG] = "mag",
+	[IIO_EV_TYPE_ROC] = "roc"
+};
+
+static const char * const iio_ev_dir_text[] = {
+	[IIO_EV_DIR_EITHER] = "either",
+	[IIO_EV_DIR_RISING] = "rising",
+	[IIO_EV_DIR_FALLING] = "falling"
+};
+
+static ssize_t iio_ev_state_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	int ret;
+	unsigned long val;
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret || val < 0 || val > 1)
+		return -EINVAL;
+
+	ret = indio_dev->write_event_config(indio_dev, this_attr->mask,
+					    this_attr->listel,
+					    val);
+	return (ret < 0) ? ret : len;
+}
+
+static ssize_t iio_ev_state_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	int val = indio_dev->read_event_config(indio_dev, this_attr->mask);
+
+	if (val < 0)
+		return val;
+	else
+		return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t iio_ev_value_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val, ret;
+
+	ret = indio_dev->read_event_value(indio_dev,
+					  this_attr->address, &val);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t iio_ev_value_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = indio_dev->write_event_value(indio_dev, this_attr->address,
+					   val);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
+static int __iio_add_chan_event_attr(const char *postfix,
+				     const char *group,
+				     struct iio_chan_spec const *chan,
+				     unsigned int mask,
+				     struct device *dev,
+				     struct list_head *attr_list)
+{
+	char *name_format, *full_postfix;
+	int ret;
+	struct iio_event_attr *iio_ev_attr;
+
+	iio_ev_attr = kzalloc(sizeof *iio_ev_attr, GFP_KERNEL);
+	if (iio_ev_attr == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	sysfs_attr_init(&iio_ev_attr->dev_attr.attr);
+	ret = __iio_build_postfix(chan, 0, postfix, &full_postfix);
+	if (ret)
+		goto error_ret;
+	/* Special case for types that uses both channel numbers in naming */
+	if (chan->type == IIO_IN_DIFF)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_complex[chan->type],
+				    full_postfix);
+	else if (!chan->indexed)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    full_postfix);
+	else
+		name_format
+			= kasprintf(GFP_KERNEL, "%s%d_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    chan->channel,
+				    full_postfix);
+	if (name_format == NULL) {
+		ret = -ENOMEM;
+		goto error_free_attr;
+	}
+
+	iio_ev_attr->dev_attr.attr.name = kasprintf(GFP_KERNEL,
+						    name_format,
+						    chan->channel,
+						    chan->channel2);
+	if (iio_ev_attr->dev_attr.attr.name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name_format;
+	}
+
+	iio_ev_attr->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
+	iio_ev_attr->dev_attr.show = &iio_ev_state_show;
+	iio_ev_attr->dev_attr.store = &iio_ev_state_store;
+	iio_ev_attr->mask = mask;
+	iio_ev_attr->listel = chan->shared_handler;
+	ret = sysfs_add_file_to_group(&dev->kobj,
+				      &iio_ev_attr->dev_attr.attr,
+				      group);
+	if (ret < 0)
+		goto error_free_name;
+	list_add(&iio_ev_attr->l, attr_list);
+	kfree(name_format);
+	return 0;
+
+error_free_name:
+	kfree(iio_ev_attr->dev_attr.attr.name);
+error_free_name_format:
+	kfree(name_format);
+error_free_attr:
+	kfree(iio_ev_attr);
+error_ret:
+	return ret;
+}
+
+
+static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
+				      struct iio_chan_spec const *chan)
+{
+
+	int ret = 0, i, mask;
+	char *postfix;
+	if (!chan->event_mask)
+		return 0;
+
+	for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
+				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
+				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		switch (chan->type) {
+			/* Switch this to a table at some point */
+		case IIO_IN:
+			mask = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
+						    i/IIO_EV_TYPE_MAX,
+						    i%IIO_EV_TYPE_MAX);
+			break;
+		case IIO_ACCEL:
+			mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
+						  i/IIO_EV_TYPE_MAX,
+						  i%IIO_EV_TYPE_MAX);
+			break;
+		case IIO_IN_DIFF:
+			mask = IIO_MOD_EVENT_CODE(chan->type, chan->channel,
+						  chan->channel2,
+						  i/IIO_EV_TYPE_MAX,
+						  i%IIO_EV_TYPE_MAX);
+			break;
+		default:
+			printk(KERN_INFO "currently unhandled type of event\n");
+		}
+		ret = __iio_add_chan_event_attr(postfix,
+						NULL,
+						chan,
+						mask,
+						/*HACK. - limits us to one
+						  event interface - fix by
+						  extending the bitmask - but
+						  how far*/
+						&dev_info->event_interfaces[0]
+						.dev,
+						&dev_info->event_interfaces[0].
+						event_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
+
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
+				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
+				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		ret = __iio_add_chan_devattr(postfix, NULL, chan,
+					     iio_ev_value_show,
+					     iio_ev_value_store,
+					     mask,
+					     0,
+					     &dev_info->event_interfaces[0]
+					     .dev,
+					     &dev_info->event_interfaces[0]
+					     .dev_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
+
+	}
+
+error_ret:
+	return ret;
+}
+
+static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info,
+						const char *groupname,
+						int num)
+{
+	struct iio_dev_attr *p, *n;
+	struct iio_event_attr *q, *m;
+	list_for_each_entry_safe(p, n,
+				 &dev_info->event_interfaces[num].
+				 dev_attr_list, l) {
+		sysfs_remove_file_from_group(&dev_info
+					     ->event_interfaces[num].dev.kobj,
+					     &p->dev_attr.attr,
+					     groupname);
+		kfree(p->dev_attr.attr.name);
+		kfree(p);
+	}
+	list_for_each_entry_safe(q, m,
+				 &dev_info->event_interfaces[num].
+				 event_attr_list, l) {
+		sysfs_remove_file_from_group(&dev_info
+					     ->event_interfaces[num].dev.kobj,
+					     &q->dev_attr.attr,
+					     groupname);
+		kfree(q->dev_attr.attr.name);
+		kfree(q);
+	}
+}
+
 static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 {
+	int j;
 	int ret;
 	/*p for adding, q for removing */
 	struct attribute **attrp, **attrq;
@@ -561,23 +1219,42 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 	if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
 		attrp = dev_info->event_conf_attrs[i].attrs;
 		while (*attrp) {
-			ret =  sysfs_add_file_to_group(&dev_info->dev.kobj,
+			ret =  sysfs_add_file_to_group(&dev_info
+						       ->event_interfaces[0]
+						       .dev.kobj,
 						       *attrp,
-						       dev_info
-						       ->event_attrs[i].name);
+						       NULL);
 			if (ret)
 				goto error_ret;
 			attrp++;
 		}
 	}
+	INIT_LIST_HEAD(&dev_info->event_interfaces[0].event_attr_list);
+	INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list);
+	/* Dynically created from the channels array */
+	if (dev_info->channels) {
+		for (j = 0; j < dev_info->num_channels; j++) {
+			ret = iio_device_add_event_sysfs(dev_info,
+							 &dev_info
+							 ->channels[j]);
+			if (ret)
+				goto error_clear_attrs;
+		}
+	}
 	return 0;
 
+error_clear_attrs:
+	__iio_remove_all_event_sysfs(dev_info,
+				     NULL,
+				     i);
 error_ret:
 	attrq = dev_info->event_conf_attrs[i].attrs;
 	while (attrq != attrp) {
-			sysfs_remove_file_from_group(&dev_info->dev.kobj,
-					     *attrq,
-					     dev_info->event_attrs[i].name);
+			sysfs_remove_file_from_group(&dev_info
+						     ->event_interfaces[0]
+						     .dev.kobj,
+						     *attrq,
+						     NULL);
 		attrq++;
 	}
 
@@ -588,15 +1265,18 @@ static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
 						  int i)
 {
 	struct attribute **attrq;
-
+	__iio_remove_all_event_sysfs(dev_info,
+				     NULL,
+				     i);
 	if (dev_info->event_conf_attrs
 		&& dev_info->event_conf_attrs[i].attrs) {
 		attrq = dev_info->event_conf_attrs[i].attrs;
 		while (*attrq) {
-			sysfs_remove_file_from_group(&dev_info->dev.kobj,
+			sysfs_remove_file_from_group(&dev_info
+						     ->event_interfaces[0]
+						     .dev.kobj,
 						     *attrq,
-						     dev_info
-						     ->event_attrs[i].name);
+						     NULL);
 			attrq++;
 		}
 	}
@@ -650,10 +1330,12 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 
 		dev_set_drvdata(&dev_info->event_interfaces[i].dev,
 				(void *)dev_info);
-		ret = sysfs_create_group(&dev_info
-					->event_interfaces[i]
-					.dev.kobj,
-					&dev_info->event_attrs[i]);
+
+		if (dev_info->event_attrs != NULL)
+			ret = sysfs_create_group(&dev_info
+						 ->event_interfaces[i]
+						 .dev.kobj,
+						 &dev_info->event_attrs[i]);
 
 		if (ret) {
 			dev_err(&dev_info->dev,
@@ -676,7 +1358,8 @@ error_unregister_config_attrs:
 	i = dev_info->num_interrupt_lines - 1;
 error_remove_sysfs_interfaces:
 	for (j = 0; j < i; j++)
-		sysfs_remove_group(&dev_info
+		if (dev_info->event_attrs != NULL)
+			sysfs_remove_group(&dev_info
 				   ->event_interfaces[j].dev.kobj,
 				   &dev_info->event_attrs[j]);
 error_free_setup_ev_ints:
@@ -696,10 +1379,13 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 
 	if (dev_info->num_interrupt_lines == 0)
 		return;
-	for (i = 0; i < dev_info->num_interrupt_lines; i++)
-		sysfs_remove_group(&dev_info
-				   ->event_interfaces[i].dev.kobj,
-				   &dev_info->event_attrs[i]);
+	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+		__iio_remove_event_config_attrs(dev_info, i);
+		if (dev_info->event_attrs != NULL)
+			sysfs_remove_group(&dev_info
+					   ->event_interfaces[i].dev.kobj,
+					   &dev_info->event_attrs[i]);
+	}
 
 	for (i = 0; i < dev_info->num_interrupt_lines; i++)
 		iio_free_ev_int(&dev_info->event_interfaces[i]);
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 3f6bee0..d6b4bb7 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -233,9 +233,162 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 }
 EXPORT_SYMBOL(iio_ring_buffer_init);
 
-int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
+static ssize_t iio_show_scan_index(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	return sprintf(buf, "%u\n", this_attr->c->scan_index);
+}
+
+static ssize_t iio_show_fixed_type(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	return sprintf(buf, "%c%d/%d>>%u\n",
+		       this_attr->c->scan_type.sign,
+		       this_attr->c->scan_type.realbits,
+		       this_attr->c->scan_type.storagebits,
+		       this_attr->c->scan_type.shift);
+}
+
+static int __iio_add_chan_scan_elattr(const char *postfix,
+				      const char *group,
+				      const struct iio_chan_spec *chan,
+				      struct device *dev,
+				      struct list_head *attr_list)
 {
 	int ret;
+	struct iio_scan_el *scan_el;
+
+	scan_el = kzalloc(sizeof *scan_el, GFP_KERNEL);
+	if (scan_el == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	if (chan->type != IIO_TIMESTAMP)
+		ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
+					     iio_scan_el_show,
+					     iio_scan_el_store, 0);
+	else /*
+	      * Timestamp handled separately because it simplifies a lot of
+	      * drivers by ensuring they don't have to know its magic index
+	      */
+		ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
+					     iio_scan_el_ts_show,
+					     iio_scan_el_ts_store, 0);
+	if (ret)
+		goto error_free_scan_el;
+
+	scan_el->number = chan->scan_index;
+
+	ret = sysfs_add_file_to_group(&dev->kobj,
+				      &scan_el->dev_attr.attr,
+				      group);
+	if (ret < 0)
+		goto error_device_attr_deinit;
+
+	list_add(&scan_el->l, attr_list);
+
+	return 0;
+error_device_attr_deinit:
+	__iio_device_attr_deinit(&scan_el->dev_attr);
+error_free_scan_el:
+	kfree(scan_el);
+error_ret:
+	return ret;
+}
+
+static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
+				      const struct iio_chan_spec *chan)
+{
+	int ret;
+
+	ret = __iio_add_chan_devattr("index", "scan_elements",
+				     chan,
+				     &iio_show_scan_index,
+				     NULL,
+				     0,
+				     0,
+				     &ring->dev,
+				     &ring->scan_el_dev_attr_list);
+	if (ret)
+		goto error_ret;
+
+	ret = __iio_add_chan_devattr("type", "scan_elements",
+				     chan,
+				     &iio_show_fixed_type,
+				     NULL,
+				     0,
+				     0,
+				     &ring->dev,
+				     &ring->scan_el_dev_attr_list);
+
+	if (ret)
+		goto error_ret;
+
+	ret = __iio_add_chan_scan_elattr("en", "scan_elements",
+					 chan, &ring->dev,
+					 &ring->scan_el_en_attr_list);
+
+error_ret:
+	return ret;
+}
+
+static void iio_ring_remove_and_free_scan_el_attr(struct iio_ring_buffer *ring,
+						  struct iio_scan_el *p)
+{
+	sysfs_remove_file_from_group(&ring->dev.kobj,
+				     &p->dev_attr.attr, "scan_elements");
+	kfree(p->dev_attr.attr.name);
+	kfree(p);
+}
+
+static void iio_ring_remove_and_free_scan_dev_attr(struct iio_ring_buffer *ring,
+						   struct iio_dev_attr *p)
+{
+	sysfs_remove_file_from_group(&ring->dev.kobj,
+				     &p->dev_attr.attr, "scan_elements");
+	kfree(p->dev_attr.attr.name);
+	kfree(p);
+}
+
+static struct attribute *iio_scan_el_dummy_attrs[] = {
+	NULL
+};
+
+static struct attribute_group iio_scan_el_dummy_group = {
+	.name = "scan_elements",
+	.attrs = iio_scan_el_dummy_attrs
+};
+
+static void __iio_ring_attr_cleanup(struct iio_ring_buffer *ring)
+{
+	struct iio_dev_attr *p, *n;
+	struct iio_scan_el *q, *m;
+	int anydynamic = !(list_empty(&ring->scan_el_dev_attr_list) &&
+			   list_empty(&ring->scan_el_en_attr_list));
+	list_for_each_entry_safe(p, n,
+				 &ring->scan_el_dev_attr_list, l)
+		iio_ring_remove_and_free_scan_dev_attr(ring, p);
+	list_for_each_entry_safe(q, m,
+				 &ring->scan_el_en_attr_list, l)
+		iio_ring_remove_and_free_scan_el_attr(ring, q);
+
+	if (ring->scan_el_attrs)
+		sysfs_remove_group(&ring->dev.kobj,
+				   ring->scan_el_attrs);
+	else if (anydynamic)
+		sysfs_remove_group(&ring->dev.kobj,
+				   &iio_scan_el_dummy_group);
+}
+
+int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+				const struct iio_chan_spec *channels,
+				int num_channels)
+{
+	int ret, i;
 
 	ring->id = id;
 
@@ -268,9 +421,28 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
 				"Failed to add sysfs scan elements\n");
 			goto error_free_ring_buffer_event_chrdev;
 		}
+	} else if (channels) {
+		ret = sysfs_create_group(&ring->dev.kobj,
+					 &iio_scan_el_dummy_group);
+		if (ret)
+			goto error_free_ring_buffer_event_chrdev;
 	}
 
-	return ret;
+
+	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
+	INIT_LIST_HEAD(&ring->scan_el_en_attr_list);
+	if (channels) {
+		/* new magic */
+		for (i = 0; i < num_channels; i++) {
+			ret = iio_ring_add_channel_sysfs(ring, &channels[i]);
+			if (ret < 0)
+				goto error_cleanup_dynamic;
+		}
+	}
+
+	return 0;
+error_cleanup_dynamic:
+	__iio_ring_attr_cleanup(ring);
 error_free_ring_buffer_event_chrdev:
 	__iio_free_ring_buffer_event_chrdev(ring);
 error_remove_device:
@@ -278,14 +450,17 @@ error_remove_device:
 error_ret:
 	return ret;
 }
+EXPORT_SYMBOL(iio_ring_buffer_register_ex);
+
+int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
+{
+	return iio_ring_buffer_register_ex(ring, id, NULL, 0);
+}
 EXPORT_SYMBOL(iio_ring_buffer_register);
 
 void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
-	if (ring->scan_el_attrs)
-		sysfs_remove_group(&ring->dev.kobj,
-				   ring->scan_el_attrs);
-
+	__iio_ring_attr_cleanup(ring);
 	__iio_free_ring_buffer_access_chrdev(ring);
 	__iio_free_ring_buffer_event_chrdev(ring);
 	device_del(&ring->dev);
@@ -540,4 +715,3 @@ error_ret:
 	return ret ? ret : len;
 }
 EXPORT_SYMBOL(iio_scan_el_ts_store);
-
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 780c6aa..ada51c2 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -140,6 +140,8 @@ struct iio_ring_buffer {
 	int				(*predisable)(struct iio_dev *);
 	int				(*postdisable)(struct iio_dev *);
 
+	struct list_head scan_el_dev_attr_list;
+	struct list_head scan_el_en_attr_list;
 };
 
 /**
@@ -177,6 +179,7 @@ struct iio_scan_el {
 	struct device_attribute		dev_attr;
 	unsigned int			number;
 	unsigned int			label;
+	struct list_head l;
 
 	int (*set_state)(struct iio_scan_el *scanel,
 			 struct iio_dev *dev_info,
@@ -430,6 +433,14 @@ static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
  **/
 int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id);
 
+/** iio_ring_buffer_register_ex() - register the buffer with IIO core
+ * @ring: the buffer to be registered
+ * @id: the id of the buffer (typically 0)
+ **/
+int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+				const struct iio_chan_spec *channels,
+				int num_channels);
+
 /**
  * iio_ring_buffer_unregister() - unregister the buffer from IIO core
  * @ring: the buffer to be unregistered
@@ -481,6 +492,15 @@ static inline int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
 {
 	return 0;
 };
+
+static inline int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring,
+					      int id,
+					      struct iio_chan_spec *channels,
+					      int num_channels)
+{
+	return 0;
+}
+
 static inline void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {};
 
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 8f4d547..44bd575 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -24,6 +24,7 @@ struct iio_event_attr {
 	struct device_attribute dev_attr;
 	int mask;
 	struct iio_event_handler_list *listel;
+	struct list_head l;
 };
 
 #define to_iio_event_attr(_dev_attr) \
@@ -34,11 +35,14 @@ struct iio_event_attr {
  * @dev_attr:	underlying device attribute
  * @address:	associated register address
  * @val2:	secondary attribute value
+ * @l:		list head for maintaining list of dynamically created attrs.
  */
 struct iio_dev_attr {
 	struct device_attribute dev_attr;
 	int address;
 	int val2;
+	struct list_head l;
+	struct iio_chan_spec const *c;
 };
 
 #define to_iio_dev_attr(_dev_attr)				\
@@ -259,26 +263,28 @@ struct iio_const_attr {
 #define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \
 	IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler)
 
-#define IIO_EV_CLASS_BUFFER		0
-#define IIO_EV_CLASS_IN			1
-#define IIO_EV_CLASS_ACCEL		2
-#define IIO_EV_CLASS_GYRO		3
-#define IIO_EV_CLASS_MAGN		4
-#define IIO_EV_CLASS_LIGHT		5
-#define IIO_EV_CLASS_PROXIMITY		6
-#define IIO_EV_CLASS_TEMP		7
-
-#define IIO_EV_MOD_X			0
-#define IIO_EV_MOD_Y			1
-#define IIO_EV_MOD_Z			2
-#define IIO_EV_MOD_X_AND_Y		3
-#define IIO_EV_MOD_X_ANX_Z		4
-#define IIO_EV_MOD_Y_AND_Z		5
-#define IIO_EV_MOD_X_AND_Y_AND_Z	6
-#define IIO_EV_MOD_X_OR_Y		7
-#define IIO_EV_MOD_X_OR_Z		8
-#define IIO_EV_MOD_Y_OR_Z		9
-#define IIO_EV_MOD_X_OR_Y_OR_Z		10
+/* must match our channel defs */
+#define IIO_EV_CLASS_IN			IIO_IN
+#define IIO_EV_CLASS_IN_DIFF		IIO_IN_DIFF
+#define IIO_EV_CLASS_ACCEL		IIO_ACCEL
+#define IIO_EV_CLASS_GYRO		IIO_GYRO
+#define IIO_EV_CLASS_MAGN		IIO_MAGN
+#define IIO_EV_CLASS_LIGHT		IIO_LIGHT
+#define IIO_EV_CLASS_PROXIMITY		IIO_PROXIMITY
+#define IIO_EV_CLASS_TEMP		IIO_TEMP
+#define IIO_EV_CLASS_BUFFER		IIO_BUFFER
+
+#define IIO_EV_MOD_X			IIO_MOD_X
+#define IIO_EV_MOD_Y			IIO_MOD_Y
+#define IIO_EV_MOD_Z			IIO_MOD_Z
+#define IIO_EV_MOD_X_AND_Y		IIO_MOD_X_AND_Y
+#define IIO_EV_MOD_X_ANX_Z		IIO_MOD_X_AND_Z
+#define IIO_EV_MOD_Y_AND_Z		IIO_MOD_Y_AND_Z
+#define IIO_EV_MOD_X_AND_Y_AND_Z	IIO_MOD_X_AND_Y_AND_Z
+#define IIO_EV_MOD_X_OR_Y		IIO_MOD_X_OR_Y
+#define IIO_EV_MOD_X_OR_Z		IIO_MOD_X_OR_Z
+#define IIO_EV_MOD_Y_OR_Z		IIO_MOD_Y_OR_Z
+#define IIO_EV_MOD_X_OR_Y_OR_Z		IIO_MOD_X_OR_Y_OR_Z
 
 #define IIO_EV_TYPE_THRESH		0
 #define IIO_EV_TYPE_MAG			1
@@ -288,6 +294,10 @@ struct iio_const_attr {
 #define IIO_EV_DIR_RISING		1
 #define IIO_EV_DIR_FALLING		2
 
+#define IIO_EV_TYPE_MAX 8
+#define IIO_EV_BIT(type, direction)			\
+	(1 << (type*IIO_EV_TYPE_MAX + direction))
+
 #define IIO_EVENT_CODE(channelclass, orient_bit, number,		\
 		       modifier, type, direction)			\
 	(channelclass | (orient_bit << 8) | ((number) << 9) |		\
@@ -304,6 +314,14 @@ struct iio_const_attr {
 #define IIO_BUFFER_EVENT_CODE(code)		\
 	(IIO_EV_CLASS_BUFFER | (code << 8))
 
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 24) & 0xf)
+
+/* Event code number extraction depends on which type of event we have.
+ * Perhaps review this function in the future*/
+#define IIO_EVENT_CODE_EXTRACT_NUM(mask) ((mask >> 9) & 0x0f)
+
+#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 13) & 0x7)
+
 /**
  * IIO_EVENT_ATTR_RING_50_FULL - ring buffer event to indicate 50% full
  * @_show: output method for the attribute
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 002/111] staging:iio:lis3l02dq - move to new channel_spec approach.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 001/111] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 003/111] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
                   ` (109 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V3: Move to single IIO_CHAN macro.
V2: Update to two part read_raw value.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |   13 +-
 drivers/staging/iio/accel/lis3l02dq_core.c |  554 +++++++++++-----------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |  227 +++++-------
 3 files changed, 313 insertions(+), 481 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 1140218..88b5598 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -188,9 +188,9 @@ int lis3l02dq_spi_write_reg_8(struct device *dev,
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
 
-ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf);
+ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
+				       int index,
+				       int *val);
 
 
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev);
@@ -215,11 +215,10 @@ static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 {
 	return 0;
 }
-
 static inline ssize_t
-lis3l02dq_read_accel_from_ring(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf)
+lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
+			       int index,
+			       int *val)
 {
 	return 0;
 }
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index e11388a..0368d51 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -39,20 +39,11 @@
  * This means that use cannot be made of spi_write etc.
  */
 
-/**
- * lis3l02dq_spi_read_reg_8() - read single byte from a single register
- * @dev: device asosciated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be read
- * @val: pass back the resulting value
- **/
-int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
+static int __lis3l02dq_spi_read_reg_8(struct lis3l02dq_state *st,
+				      u8 reg_address, u8 *val)
 {
-	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
+	int ret;
 	struct spi_transfer xfer = {
 		.tx_buf = st->tx,
 		.rx_buf = st->rx,
@@ -73,6 +64,19 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
 
 	return ret;
 }
+/**
+ * lis3l02dq_spi_read_reg_8() - read single byte from a single register
+ * @dev: device asosciated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be read
+ * @val: pass back the resulting value
+ **/
+int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	return __lis3l02dq_spi_read_reg_8(st, reg_address, val);
+}
 
 /**
  * lis3l02dq_spi_write_reg_8() - write single byte to a register
@@ -154,23 +158,13 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev,
 	return ret;
 }
 
-/**
- * lisl302dq_spi_read_reg_s16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int lis3l02dq_spi_read_reg_s16(struct device *dev,
-				      u8 lower_reg_address,
-				      s16 *val)
+static int lis3l02dq_read_16bit_s(struct lis3l02dq_state *st,
+				  u8 lower_reg_address,
+				  int *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	int ret;
+	s16 tempval;
 	struct spi_transfer xfers[] = { {
 			.tx_buf = st->tx,
 			.rx_buf = st->rx,
@@ -182,15 +176,14 @@ static int lis3l02dq_spi_read_reg_s16(struct device *dev,
 			.rx_buf = st->rx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
-
+			.cs_change = 0,
 		},
 	};
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
 	st->tx[1] = 0;
-	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address+1);
+	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
 	st->tx[3] = 0;
 
 	spi_message_init(&msg);
@@ -201,135 +194,103 @@ static int lis3l02dq_spi_read_reg_s16(struct device *dev,
 		dev_err(&st->us->dev, "problem when reading 16 bit register");
 		goto error_ret;
 	}
-	*val = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
+	tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
 
+	*val = tempval;
 error_ret:
 	mutex_unlock(&st->buf_lock);
 	return ret;
 }
 
-/**
- * lis3l02dq_read_signed() - attribute function used for 8 bit signed values
- * @dev: the child device associated with the iio_dev or iio_trigger
- * @attr: the attribute being processed
- * @buf: buffer into which put the output string
- **/
-static ssize_t lis3l02dq_read_signed(struct device *dev,
-				     struct device_attribute *attr,
-				     char *buf)
-{
-	int ret;
-	s8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, (u8 *)&val);
-
-	return ret ? ret : sprintf(buf, "%d\n", val);
-}
-
-static ssize_t lis3l02dq_read_unsigned(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf)
-{
-	int ret;
-	u8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, &val);
-
-	return ret ? ret : sprintf(buf, "%d\n", val);
-}
-
-static ssize_t lis3l02dq_write_signed(struct device *dev,
-				      struct device_attribute *attr,
-				      const char *buf,
-				      size_t len)
-{
-	long valin;
-	s8 val;
-	int ret;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = strict_strtol(buf, 10, &valin);
-	if (ret)
-		goto error_ret;
-	val = valin;
-	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, (u8 *)&val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t lis3l02dq_write_unsigned(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
-{
-	int ret;
-	ulong valin;
-	u8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = strict_strtoul(buf, 10, &valin);
-	if (ret)
-		goto err_ret;
-	val = valin;
-	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, &val);
+enum lis3l02dq_rm_ind {
+	LIS3L02DQ_ACCEL,
+	LIS3L02DQ_GAIN,
+	LIS3L02DQ_BIAS,
+};
 
-err_ret:
-	return ret ? ret : len;
-}
+static u8 lis3l02dq_axis_map[3][3] = {
+	[LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
+			      LIS3L02DQ_REG_OUT_Y_L_ADDR,
+			      LIS3L02DQ_REG_OUT_Z_L_ADDR },
+	[LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
+			     LIS3L02DQ_REG_GAIN_Y_ADDR,
+			     LIS3L02DQ_REG_GAIN_Z_ADDR },
+	[LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
+			     LIS3L02DQ_REG_OFFSET_Y_ADDR,
+			     LIS3L02DQ_REG_OFFSET_Z_ADDR }
+};
 
-static ssize_t lis3l02dq_read_16bit_signed(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
+static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
+				 int e,
+				 int *val)
 {
-	int ret;
-	s16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_s16(dev, this_attr->address, &val);
-
-	if (ret)
-		return ret;
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	return sprintf(buf, "%d\n", val);
+	return lis3l02dq_read_16bit_s(st, LIS3L02DQ_REG_THS_L_ADDR, val);
 }
 
-static ssize_t lis3l02dq_read_accel(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
+static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
+				  int event_code,
+				  int val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
-		ret = lis3l02dq_read_accel_from_ring(dev, attr, buf);
-	else
-		ret =  lis3l02dq_read_16bit_signed(dev, attr, buf);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
+	u16 value = val;
+	return lis3l02dq_spi_write_reg_s16(&indio_dev->dev,
+					   LIS3L02DQ_REG_THS_L_ADDR,
+					   value);
 }
 
-static ssize_t lis3l02dq_write_16bit_signed(struct device *dev,
-					    struct device_attribute *attr,
-					    const char *buf,
-					    size_t len)
+static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val,
+			      int *val2,
+			      long mask)
 {
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = lis3l02dq_spi_write_reg_s16(dev, this_attr->address, val);
-
+	u8 utemp;
+	s8 stemp;
+	ssize_t ret = 0;
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	u8 reg;
+	switch (mask) {
+	case 0:
+		/* Take the iio_dev status lock */
+		mutex_lock(&indio_dev->mlock);
+		if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
+			ret = lis3l02dq_read_accel_from_ring(indio_dev->ring,
+							     chan->scan_index,
+							     val);
+		else {
+			reg = lis3l02dq_axis_map
+				[LIS3L02DQ_ACCEL][chan->address];
+			ret = lis3l02dq_read_16bit_s(st, reg, val);
+		}
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		*val = 0;
+		*val2 = 9580;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
+		ret = __lis3l02dq_spi_read_reg_8(st, reg, &utemp);
+		if (ret)
+			goto error_ret;
+		/* to match with what previous code does */
+		*val = utemp;
+		return IIO_VAL_INT;
+
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
+		ret = __lis3l02dq_spi_read_reg_8(st, reg, (u8 *)&stemp);
+		/* to match with what previous code does */
+		*val = stemp;
+		return IIO_VAL_INT;
+	}
 error_ret:
-	return ret ? ret : len;
+	return ret;
 }
 
 static ssize_t lis3l02dq_read_frequency(struct device *dev,
@@ -469,168 +430,139 @@ err_ret:
 	return ret;
 }
 
-#define LIS3L02DQ_SIGNED_ATTR(name, reg)	\
-	IIO_DEVICE_ATTR(name,			\
-			S_IWUSR | S_IRUGO,	\
-			lis3l02dq_read_signed,	\
-			lis3l02dq_write_signed, \
-			reg);
-
-#define LIS3L02DQ_UNSIGNED_ATTR(name, reg)		\
-	IIO_DEVICE_ATTR(name,				\
-			S_IWUSR | S_IRUGO,		\
-			lis3l02dq_read_unsigned,	\
-			lis3l02dq_write_unsigned,	\
-			reg);
-
-static LIS3L02DQ_SIGNED_ATTR(accel_x_calibbias,
-			     LIS3L02DQ_REG_OFFSET_X_ADDR);
-static LIS3L02DQ_SIGNED_ATTR(accel_y_calibbias,
-			     LIS3L02DQ_REG_OFFSET_Y_ADDR);
-static LIS3L02DQ_SIGNED_ATTR(accel_z_calibbias,
-			     LIS3L02DQ_REG_OFFSET_Z_ADDR);
-
-static LIS3L02DQ_UNSIGNED_ATTR(accel_x_calibscale,
-			       LIS3L02DQ_REG_GAIN_X_ADDR);
-static LIS3L02DQ_UNSIGNED_ATTR(accel_y_calibscale,
-			       LIS3L02DQ_REG_GAIN_Y_ADDR);
-static LIS3L02DQ_UNSIGNED_ATTR(accel_z_calibscale,
-			       LIS3L02DQ_REG_GAIN_Z_ADDR);
-
-static IIO_DEVICE_ATTR(accel_raw_mag_value,
-		       S_IWUSR | S_IRUGO,
-		       lis3l02dq_read_16bit_signed,
-		       lis3l02dq_write_16bit_signed,
-		       LIS3L02DQ_REG_THS_L_ADDR);
-/* RFC The reading method for these will change depending on whether
- * ring buffer capture is in use. Is it worth making these take two
- * functions and let the core handle which to call, or leave as in this
- * driver where it is the drivers problem to manage this?
- */
-
-static IIO_DEV_ATTR_ACCEL_X(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_X_L_ADDR);
-
-static IIO_DEV_ATTR_ACCEL_Y(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_Y_L_ADDR);
-
-static IIO_DEV_ATTR_ACCEL_Z(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_Z_L_ADDR);
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 			      lis3l02dq_read_frequency,
 			      lis3l02dq_write_frequency);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 
-static ssize_t lis3l02dq_read_interrupt_config(struct device *dev,
-					       struct device_attribute *attr,
-					       char *buf)
+static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
 {
-	int ret;
-	s8 val;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	ret = lis3l02dq_spi_read_reg_8(dev->parent,
-				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-				       (u8 *)&val);
+	/* Stash the timestamp somewhere convenient for the bh */
+	st->thresh_timestamp = timestamp;
+	schedule_work(&st->work_thresh);
 
-	return ret ? ret : sprintf(buf, "%d\n", !!(val & this_attr->mask));
+	return 0;
 }
 
-static ssize_t lis3l02dq_write_interrupt_config(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	int ret, currentlyset, changed = 0;
-	u8 valold, controlold;
-	bool val;
+/* A shared handler for a number of threshold types */
+IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
 
-	val = !(buf[0] == '0');
 
-	mutex_lock(&indio_dev->mlock);
-	/* read current value */
-	ret = lis3l02dq_spi_read_reg_8(dev->parent,
+#define LIS3L02DQ_INFO_MASK				\
+	((1 << IIO_CHAN_INFO_SCALE_SHARED) |		\
+	 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
+	 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE))
+
+#define LIS3L02DQ_EVENT_MASK					\
+	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |	\
+	 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+
+static struct iio_chan_spec lis3l02dq_channels[] = {
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK,
+		 0, 0, IIO_ST('s', 12, 16, 0),
+		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK,
+		 1, 1, IIO_ST('s', 12, 16, 0),
+		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK,
+		 2, 2, IIO_ST('s', 12, 16, 0),
+		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+	IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
+
+static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
+					   int event_code)
+{
+
+	u8 val;
+	int ret;
+	u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+			 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			  IIO_EV_DIR_RISING)));
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
 				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-				       &valold);
-	if (ret)
-		goto error_mutex_unlock;
+				       &val);
+	if (ret < 0)
+		return ret;
+
+	return !!(val & mask);
+}
 
+static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
+					int event_code,
+					struct iio_event_handler_list *list_el,
+					int state)
+{
+	int ret = 0;
+	u8 val, control;
+	u8 currentlyset;
+	bool changed = false;
+	u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+			 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			  IIO_EV_DIR_RISING)));
+
+	mutex_lock(&indio_dev->mlock);
 	/* read current control */
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
 				       LIS3L02DQ_REG_CTRL_2_ADDR,
-				       &controlold);
+				       &control);
 	if (ret)
-		goto error_mutex_unlock;
-	currentlyset = !!(valold & this_attr->mask);
-	if (val == false && currentlyset) {
-		valold &= ~this_attr->mask;
-		changed = 1;
-		iio_remove_event_from_list(this_attr->listel,
-						 &indio_dev->interrupts[0]
-						 ->ev_list);
-	} else if (val == true && !currentlyset) {
-		changed = 1;
-		valold |= this_attr->mask;
-		iio_add_event_to_list(this_attr->listel,
-					    &indio_dev->interrupts[0]->ev_list);
+		goto error_ret;
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &val);
+	if (ret < 0)
+		goto error_ret;
+	currentlyset = val & mask;
+
+	if (!currentlyset && state) {
+		changed = true;
+		val |= mask;
+		iio_add_event_to_list(list_el,
+				      &indio_dev->interrupts[0]->ev_list);
+
+	} else if (currentlyset && !state) {
+		changed = true;
+		val &= ~mask;
+		iio_remove_event_from_list(list_el,
+					   &indio_dev->interrupts[0]->ev_list);
 	}
-
 	if (changed) {
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
 						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-						&valold);
+						&val);
 		if (ret)
-			goto error_mutex_unlock;
-		/* This always enables the interrupt, even if we've remove the
-		 * last thing using it. For this device we can use the reference
-		 * count on the handler to tell us if anyone wants the interrupt
-		 */
-		controlold = this_attr->listel->refcount ?
-			(controlold | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
-			(controlold & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
-		ret = lis3l02dq_spi_write_reg_8(dev,
-						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&controlold);
-		if (ret)
-			goto error_mutex_unlock;
+			goto error_ret;
+		control = list_el->refcount ?
+			(control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
+			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
+		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+					       LIS3L02DQ_REG_CTRL_2_ADDR,
+					       &control);
 	}
-error_mutex_unlock:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-
-static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	/* Stash the timestamp somewhere convenient for the bh */
-	st->thresh_timestamp = timestamp;
-	schedule_work(&st->work_thresh);
-
-	return 0;
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
 }
 
-
 /* Unforunately it appears the interrupt won't clear unless you read from the
  * src register.
  */
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
-       struct lis3l02dq_state *st
-	       = container_of(work_s,
-		       struct lis3l02dq_state, work_thresh);
-
+	struct lis3l02dq_state *st
+		= container_of(work_s,
+			       struct lis3l02dq_state, work_thresh);
 	u8 t;
 
 	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
@@ -700,75 +632,9 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 	return;
 }
 
-/* A shared handler for a number of threshold types */
-IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
-
-IIO_EVENT_ATTR_SH(accel_x_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH);
-
-IIO_EVENT_ATTR_SH(accel_y_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH);
-
-IIO_EVENT_ATTR_SH(accel_z_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH);
-
-IIO_EVENT_ATTR_SH(accel_x_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW);
-
-IIO_EVENT_ATTR_SH(accel_y_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW);
-
-IIO_EVENT_ATTR_SH(accel_z_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW);
-
-
-static struct attribute *lis3l02dq_event_attributes[] = {
-	&iio_event_attr_accel_x_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_y_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_z_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_x_thresh_falling_en.dev_attr.attr,
-	&iio_event_attr_accel_y_thresh_falling_en.dev_attr.attr,
-	&iio_event_attr_accel_z_thresh_falling_en.dev_attr.attr,
-	&iio_dev_attr_accel_raw_mag_value.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group lis3l02dq_event_attribute_group = {
-	.attrs = lis3l02dq_event_attributes,
-};
-
 static IIO_CONST_ATTR_NAME("lis3l02dq");
-static IIO_CONST_ATTR(accel_scale, "0.00958");
 
 static struct attribute *lis3l02dq_attributes[] = {
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibscale.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibscale.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibscale.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_const_attr_name.dev_attr.attr,
@@ -813,7 +679,13 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 
 	st->help.indio_dev->dev.parent = &spi->dev;
 	st->help.indio_dev->num_interrupt_lines = 1;
-	st->help.indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
+	st->help.indio_dev->channels = lis3l02dq_channels;
+	st->help.indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
+	st->help.indio_dev->read_raw = &lis3l02dq_read_raw;
+	st->help.indio_dev->read_event_value = &lis3l02dq_read_thresh;
+	st->help.indio_dev->write_event_value = &lis3l02dq_write_thresh;
+	st->help.indio_dev->write_event_config = &lis3l02dq_write_event_config;
+	st->help.indio_dev->read_event_config = &lis3l02dq_read_event_config;
 	st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
 	st->help.indio_dev->dev_data = (void *)(&st->help);
 	st->help.indio_dev->driver_module = THIS_MODULE;
@@ -828,7 +700,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->help.indio_dev->ring, 0,
+					  lis3l02dq_channels,
+					  ARRAY_SIZE(lis3l02dq_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 529a3cc..a710832 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -29,86 +29,6 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
 }
 
 /**
- * lis3l02dq_scan_el_set_state() set whether a scan contains a given channel
- * @scan_el:	associtate iio scan element attribute
- * @indio_dev:	the device structure
- * @bool:	desired state
- *
- * mlock already held when this is called.
- **/
-static int lis3l02dq_scan_el_set_state(struct iio_scan_el *scan_el,
-				       struct iio_dev *indio_dev,
-				       bool state)
-{
-	u8 t, mask;
-	int ret;
-
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
-				       LIS3L02DQ_REG_CTRL_1_ADDR,
-				       &t);
-	if (ret)
-		goto error_ret;
-	switch (scan_el->label) {
-	case LIS3L02DQ_REG_OUT_X_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
-		break;
-	case LIS3L02DQ_REG_OUT_Y_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
-		break;
-	case LIS3L02DQ_REG_OUT_Z_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
-		break;
-	default:
-		ret = -EINVAL;
-		goto error_ret;
-	}
-
-	if (!(mask & t) == state) {
-		if (state)
-			t |= mask;
-		else
-			t &= ~mask;
-		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
-						LIS3L02DQ_REG_CTRL_1_ADDR,
-						&t);
-	}
-error_ret:
-	return ret;
-
-}
-static IIO_SCAN_EL_C(accel_x, 0,
-		     LIS3L02DQ_REG_OUT_X_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_SCAN_EL_C(accel_y, 1,
-		     LIS3L02DQ_REG_OUT_Y_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_SCAN_EL_C(accel_z, 2,
-		     LIS3L02DQ_REG_OUT_Z_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 12, 16);
-static IIO_SCAN_EL_TIMESTAMP(3);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *lis3l02dq_scan_el_attrs[] = {
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group lis3l02dq_scan_el_group = {
-	.attrs = lis3l02dq_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
  * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
  * @private_data:	iio_dev
  **/
@@ -151,58 +71,27 @@ IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll);
 /**
  * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
  **/
-ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf)
+ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
+				       int index,
+				       int *val)
 {
-	struct iio_scan_el *el = NULL;
-	int ret, len = 0, i = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct iio_ring_buffer *ring = dev_info->ring;
-	struct attribute_group *scan_el_attrs = ring->scan_el_attrs;
+	int ret;
 	s16 *data;
+	if (!iio_scan_mask_query(ring, index))
+		return -EINVAL;
 
-	while (scan_el_attrs->attrs[i]) {
-		el = to_iio_scan_el((struct device_attribute *)
-				    (scan_el_attrs->attrs[i]));
-		/* label is in fact the address */
-		if (el->label == this_attr->address)
-			break;
-		i++;
-	}
-	if (!scan_el_attrs->attrs[i]) {
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	/* If this element is in the scan mask */
-	ret = iio_scan_mask_query(ring, el->number);
-	if (ret < 0)
-		goto error_ret;
-	if (ret) {
-		data = kmalloc(ring->access.get_bytes_per_datum(ring),
-			       GFP_KERNEL);
-		if (data == NULL)
-			return -ENOMEM;
-		ret = ring->access.read_last(ring,
-					(u8 *)data);
-		if (ret)
-			goto error_free_data;
-	} else {
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	len = iio_scan_mask_count_to_right(ring, el->number);
-	if (len < 0) {
-		ret = len;
+	data = kmalloc(ring->access.get_bytes_per_datum(ring),
+		       GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = ring->access.read_last(ring, (u8 *)data);
+	if (ret)
 		goto error_free_data;
-	}
-	len = sprintf(buf, "ring %d\n", data[len]);
+	*val = data[iio_scan_mask_count_to_right(ring, index)];
 error_free_data:
 	kfree(data);
-error_ret:
-	return ret ? ret : len;
-
+	return ret;
 }
 
 static const u8 read_all_tx_array[] = {
@@ -234,7 +123,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 
 	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)) {
 			/* lower byte */
 			xfers[j].tx_buf = st->tx + 2*j;
@@ -258,7 +147,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 			xfers[j].cs_change = 1;
 			j++;
 		}
-	}
+
 	/* After these are transmitted, the rx_buff should have
 	 * values in alternate bytes
 	 */
@@ -488,6 +377,76 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
 	lis3l02dq_free_buf(indio_dev->ring);
 }
 
+static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
+{
+	/* Disable unwanted channels otherwise the interrupt will not clear */
+	u8 t;
+	int ret;
+	bool oneenabled = false;
+
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret;
+
+	if (iio_scan_mask_query(indio_dev->ring, 0)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
+	if (iio_scan_mask_query(indio_dev->ring, 1)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
+	if (iio_scan_mask_query(indio_dev->ring, 2)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+
+	if (!oneenabled) /* what happens in this case is unknown */
+		return -EINVAL;
+	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&t);
+	if (ret)
+		goto error_ret;
+
+	return iio_triggered_ring_postenable(indio_dev);
+error_ret:
+	return ret;
+}
+
+/* Turn all channels on again */
+static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
+{
+	u8 t;
+	int ret;
+
+	ret = iio_triggered_ring_predisable(indio_dev);
+	if (ret)
+		goto error_ret;
+
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret;
+	t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE |
+		LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE |
+		LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+
+	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&t);
+
+error_ret:
+	return ret;
+}
+
+
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret;
@@ -504,17 +463,17 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	lis3l02dq_register_buf_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &lis3l02dq_scan_el_group;
+
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->postenable = &lis3l02dq_ring_postenable;
+	ring->predisable = &lis3l02dq_ring_predisable;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+	iio_scan_mask_set(ring, 0);
+	iio_scan_mask_set(ring, 1);
+	iio_scan_mask_set(ring, 2);
 
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
 	if (ret)
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 003/111] staging:iio:max1363 - move to channel_spec registration.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 001/111] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 002/111] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 004/111] staging:iio: remove ability to escalate events Jonathan Cameron
                   ` (108 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V3: move to single chan registration macro. Also introduce some
local macros to greatly reduce code length when setting up the
chan_spec arrays for all the different devices.

V2: update read_raw for two value approach.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/max1363.h      |    8 +-
 drivers/staging/iio/adc/max1363_core.c | 1143 +++++++++-----------------------
 drivers/staging/iio/adc/max1363_ring.c |    1 -
 3 files changed, 333 insertions(+), 819 deletions(-)

diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 6a8687f..b5a3dcd 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -152,24 +152,24 @@ enum max1363_modes {
 /**
  * struct max1363_chip_info - chip specifc information
  * @name:		indentification string for chip
- * @num_inputs:		number of physical inputs on chip
  * @bits:		accuracy of the adc in bits
  * @int_vref_mv:	the internal reference voltage
  * @monitor_mode:	whether the chip supports monitor interrupts
  * @mode_list:		array of available scan modes
  * @num_modes:		the number of scan modes available
  * @default_mode:	the scan mode in which the chip starts up
+ * @channel:		channel specification
+ * @num_channels:	number of channels
  */
 struct max1363_chip_info {
-	u8				num_inputs;
 	u8				bits;
 	u16				int_vref_mv;
 	bool				monitor_mode;
 	const enum max1363_modes	*mode_list;
 	int				num_modes;
 	enum max1363_modes		default_mode;
-	struct attribute_group		*dev_attrs;
-	struct attribute_group		*scan_attrs;
+	struct iio_chan_spec *channels;
+	int num_channels;
 };
 
 /**
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 1037087..66bdc87 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -42,39 +42,6 @@
 /* Here we claim all are 16 bits. This currently does no harm and saves
  * us a lot of scan element listings */
 
-#define MAX1363_SCAN_EL(number)				\
-	IIO_SCAN_EL_C(in##number, number, 0, NULL);
-#define MAX1363_SCAN_EL_D(p, n, number)					\
-	IIO_SCAN_NAMED_EL_C(in##p##m##in##n, in##p-in##n, number, 0, NULL);
-
-static MAX1363_SCAN_EL(0);
-static MAX1363_SCAN_EL(1);
-static MAX1363_SCAN_EL(2);
-static MAX1363_SCAN_EL(3);
-static MAX1363_SCAN_EL(4);
-static MAX1363_SCAN_EL(5);
-static MAX1363_SCAN_EL(6);
-static MAX1363_SCAN_EL(7);
-static MAX1363_SCAN_EL(8);
-static MAX1363_SCAN_EL(9);
-static MAX1363_SCAN_EL(10);
-static MAX1363_SCAN_EL(11);
-static MAX1363_SCAN_EL_D(0, 1, 12);
-static MAX1363_SCAN_EL_D(2, 3, 13);
-static MAX1363_SCAN_EL_D(4, 5, 14);
-static MAX1363_SCAN_EL_D(6, 7, 15);
-static MAX1363_SCAN_EL_D(8, 9, 16);
-static MAX1363_SCAN_EL_D(10, 11, 17);
-static MAX1363_SCAN_EL_D(1, 0, 18);
-static MAX1363_SCAN_EL_D(3, 2, 19);
-static MAX1363_SCAN_EL_D(5, 4, 20);
-static MAX1363_SCAN_EL_D(7, 6, 21);
-static MAX1363_SCAN_EL_D(9, 8, 22);
-static MAX1363_SCAN_EL_D(11, 10, 23);
-
-static IIO_SCAN_EL_TIMESTAMP(24);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
 static const struct max1363_mode max1363_mode_table[] = {
 	/* All of the single channel options first */
 	MAX1363_MODE_SINGLE(0, 1 << 0),
@@ -150,58 +117,6 @@ const struct max1363_mode
 	return NULL;
 }
 
-static ssize_t max1363_show_precision_u(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_priv(ring->indio_dev);
-	return sprintf(buf, "u%d/16\n", st->chip_info->bits);
-}
-
-static ssize_t max1363_show_precision_s(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_priv(ring->indio_dev);
-	return sprintf(buf, "s%d/16\n", st->chip_info->bits);
-}
-
-#define MAX1363_SCAN_TYPE(n)						\
-	DEVICE_ATTR(in##n##_type, S_IRUGO,				\
-		    max1363_show_precision_u, NULL);
-#define MAX1363_SCAN_TYPE_D(p, n)					\
-	struct device_attribute dev_attr_in##p##m##in##n##_type =	\
-		__ATTR(in##p-in##n##_type, S_IRUGO,			\
-		       max1363_show_precision_s, NULL);
-
-static MAX1363_SCAN_TYPE(0);
-static MAX1363_SCAN_TYPE(1);
-static MAX1363_SCAN_TYPE(2);
-static MAX1363_SCAN_TYPE(3);
-static MAX1363_SCAN_TYPE(4);
-static MAX1363_SCAN_TYPE(5);
-static MAX1363_SCAN_TYPE(6);
-static MAX1363_SCAN_TYPE(7);
-static MAX1363_SCAN_TYPE(8);
-static MAX1363_SCAN_TYPE(9);
-static MAX1363_SCAN_TYPE(10);
-static MAX1363_SCAN_TYPE(11);
-
-static MAX1363_SCAN_TYPE_D(0, 1);
-static MAX1363_SCAN_TYPE_D(2, 3);
-static MAX1363_SCAN_TYPE_D(4, 5);
-static MAX1363_SCAN_TYPE_D(6, 7);
-static MAX1363_SCAN_TYPE_D(8, 9);
-static MAX1363_SCAN_TYPE_D(10, 11);
-static MAX1363_SCAN_TYPE_D(1, 0);
-static MAX1363_SCAN_TYPE_D(3, 2);
-static MAX1363_SCAN_TYPE_D(5, 4);
-static MAX1363_SCAN_TYPE_D(7, 6);
-static MAX1363_SCAN_TYPE_D(9, 8);
-static MAX1363_SCAN_TYPE_D(11, 10);
-
 static int max1363_write_basic_config(struct i2c_client *client,
 				      unsigned char d1,
 				      unsigned char d2)
@@ -232,18 +147,17 @@ int max1363_set_scan_mode(struct max1363_state *st)
 					  st->configbyte);
 }
 
-static ssize_t max1363_read_single_channel(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int max1363_read_single_chan(struct iio_dev *indio_dev,
+				    struct iio_chan_spec const *chan,
+				    int *val,
+				    long m)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	struct i2c_client *client = st->client;
-	int ret = 0, len = 0;
-	s32 data ;
+	int ret = 0;
+	s32 data;
 	char rxbuf[2];
 	long mask;
+	struct max1363_state *st = iio_priv(indio_dev);
+	struct i2c_client *client = st->client;
 
 	mutex_lock(&indio_dev->mlock);
 	/*
@@ -258,7 +172,7 @@ static ssize_t max1363_read_single_channel(struct device *dev,
 
 	/* If ring buffer capture is occurring, query the buffer */
 	if (iio_ring_enabled(indio_dev)) {
-		mask = max1363_mode_table[this_attr->address].modemask;
+		mask = max1363_mode_table[chan->address].modemask;
 		data = max1363_single_channel_from_ring(mask, st);
 		if (data < 0) {
 			ret = data;
@@ -267,10 +181,10 @@ static ssize_t max1363_read_single_channel(struct device *dev,
 	} else {
 		/* Check to see if current scan mode is correct */
 		if (st->current_mode !=
-		    &max1363_mode_table[this_attr->address]) {
+		    &max1363_mode_table[chan->address]) {
 			/* Update scan mode if needed */
 			st->current_mode
-				= &max1363_mode_table[this_attr->address];
+				= &max1363_mode_table[chan->address];
 			ret = max1363_set_scan_mode(st);
 			if (ret)
 				goto error_ret;
@@ -282,7 +196,6 @@ static ssize_t max1363_read_single_channel(struct device *dev,
 				ret = data;
 				goto error_ret;
 			}
-
 			data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8;
 		} else {
 			/* Get reading */
@@ -294,60 +207,44 @@ static ssize_t max1363_read_single_channel(struct device *dev,
 			data = rxbuf[0];
 		}
 	}
-	/* Pretty print the result */
-	len = sprintf(buf, "%u\n", data);
-
+	*val = data;
 error_ret:
 	mutex_unlock(&indio_dev->mlock);
-	return ret ? ret : len;
+	return ret;
+
 }
 
-/* Direct read attribtues */
-static IIO_DEV_ATTR_IN_RAW(0, max1363_read_single_channel, _s0);
-static IIO_DEV_ATTR_IN_RAW(1, max1363_read_single_channel, _s1);
-static IIO_DEV_ATTR_IN_RAW(2, max1363_read_single_channel, _s2);
-static IIO_DEV_ATTR_IN_RAW(3, max1363_read_single_channel, _s3);
-static IIO_DEV_ATTR_IN_RAW(4, max1363_read_single_channel, _s4);
-static IIO_DEV_ATTR_IN_RAW(5, max1363_read_single_channel, _s5);
-static IIO_DEV_ATTR_IN_RAW(6, max1363_read_single_channel, _s6);
-static IIO_DEV_ATTR_IN_RAW(7, max1363_read_single_channel, _s7);
-static IIO_DEV_ATTR_IN_RAW(8, max1363_read_single_channel, _s8);
-static IIO_DEV_ATTR_IN_RAW(9, max1363_read_single_channel, _s9);
-static IIO_DEV_ATTR_IN_RAW(10, max1363_read_single_channel, _s10);
-static IIO_DEV_ATTR_IN_RAW(11, max1363_read_single_channel, _s11);
-
-static IIO_DEV_ATTR_IN_DIFF_RAW(0, 1, max1363_read_single_channel, d0m1);
-static IIO_DEV_ATTR_IN_DIFF_RAW(2, 3, max1363_read_single_channel, d2m3);
-static IIO_DEV_ATTR_IN_DIFF_RAW(4, 5, max1363_read_single_channel, d4m5);
-static IIO_DEV_ATTR_IN_DIFF_RAW(6, 7, max1363_read_single_channel, d6m7);
-static IIO_DEV_ATTR_IN_DIFF_RAW(8, 9, max1363_read_single_channel, d8m9);
-static IIO_DEV_ATTR_IN_DIFF_RAW(10, 11, max1363_read_single_channel, d10m11);
-static IIO_DEV_ATTR_IN_DIFF_RAW(1, 0, max1363_read_single_channel, d1m0);
-static IIO_DEV_ATTR_IN_DIFF_RAW(3, 2, max1363_read_single_channel, d3m2);
-static IIO_DEV_ATTR_IN_DIFF_RAW(5, 4, max1363_read_single_channel, d5m4);
-static IIO_DEV_ATTR_IN_DIFF_RAW(7, 6, max1363_read_single_channel, d7m6);
-static IIO_DEV_ATTR_IN_DIFF_RAW(9, 8, max1363_read_single_channel, d9m8);
-static IIO_DEV_ATTR_IN_DIFF_RAW(11, 10, max1363_read_single_channel, d11m10);
-
-
-static ssize_t max1363_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
+static int max1363_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long m)
 {
-	/* Driver currently only support internal vref */
-	struct max1363_state *st = iio_priv(dev_get_drvdata(dev));
-	/* Corresponds to Vref / 2^(bits) */
-
-	if ((1 << (st->chip_info->bits + 1))
-	    > st->chip_info->int_vref_mv)
-		return sprintf(buf, "0.5\n");
-	else
-		return sprintf(buf, "%d\n",
-			st->chip_info->int_vref_mv >> st->chip_info->bits);
+	struct max1363_state *st = iio_priv(indio_dev);
+	int ret;
+	switch (m) {
+	case 0:
+		ret = max1363_read_single_chan(indio_dev, chan, val, m);
+		if (ret)
+			return ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		if ((1 << (st->chip_info->bits + 1)) >
+		    st->chip_info->int_vref_mv) {
+			*val = 0;
+			*val2 = 500000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		} else {
+			*val = (st->chip_info->int_vref_mv)
+				>> st->chip_info->bits;
+			return IIO_VAL_INT;
+		}
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, max1363_show_scale, NULL, 0);
-
 static ssize_t max1363_show_name(struct device *dev,
 				 struct device_attribute *attr,
 				 char *buf)
@@ -366,17 +263,111 @@ static const enum max1363_modes max1363_mode_list[] = {
 	d0m1to2m3, d1m0to3m2,
 };
 
+static int max1363_int_th(struct iio_dev *indio_dev,
+			int index,
+			s64 timestamp,
+			int not_test)
+{
+	struct max1363_state *st = iio_priv(indio_dev);
+
+	st->last_timestamp = timestamp;
+	schedule_work(&st->thresh_work);
+	return 0;
+}
+
+IIO_EVENT_SH(max1363_thresh, max1363_int_th);
+
+#define MAX1363_EV_M						\
+	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)	\
+	 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+#define MAX1363_INFO_MASK (1 << IIO_CHAN_INFO_SCALE_SHARED)
+
+static struct iio_chan_spec max1363_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
+		 _s0, 0, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 _s1, 1, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
+		 _s2, 2, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
+		 _s3, 3, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
+		 d0m1, 4, IIO_ST('s', 12, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
+		 d2m3, 5, IIO_ST('s', 12, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 d1m0, 6, IIO_ST('s', 12, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
+		 d3m2, 7, IIO_ST('s', 12, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
+static struct iio_chan_spec max1361_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
+		 _s0, 0, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 _s1, 1, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
+		 _s2, 2, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
+		 _s3, 3, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
+		 &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
+		 d0m1, 4, IIO_ST('s', 10, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
+		 d2m3, 5, IIO_ST('s', 10, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 d1m0, 6, IIO_ST('s', 10, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
+		 d3m2, 7, IIO_ST('s', 10, 16, 0),
+		 MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
+#define MAX1363_CHAN_U(num, address, scan_index, bits)		\
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, num, 0, MAX1363_INFO_MASK,	\
+		 address, scan_index, IIO_ST('u', bits,		\
+					     (bits == 8) ? 8 : 16, 0),	\
+		 0, NULL)
+/* bipolar channel */
+#define MAX1363_CHAN_B(num, num2, address, scan_index, bits)		\
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, num, num2, MAX1363_INFO_MASK,\
+		 address, scan_index, IIO_ST('s', bits,		\
+					     (bits == 8) ? 8 : 16, 0),	\
+		 0, NULL)
+
+#define MAX1363_4X_CHANS(bits) {		\
+	MAX1363_CHAN_U(0, _s0, 0, bits),	\
+	MAX1363_CHAN_U(1, _s1, 1, bits),	\
+	MAX1363_CHAN_U(2, _s2, 2, bits),	\
+	MAX1363_CHAN_U(3, _s3, 3, bits),	\
+	MAX1363_CHAN_B(0, 1, d0m1, 4, bits),	\
+	MAX1363_CHAN_B(2, 3, d2m3, 5, bits),	\
+	MAX1363_CHAN_B(1, 0, d1m0, 6, bits),	\
+	MAX1363_CHAN_B(3, 2, d3m2, 7, bits),	\
+	IIO_CHAN_SOFT_TIMESTAMP(8)		\
+	}
+
+static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8);
+static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10);
+static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12);
+
 static struct attribute *max1363_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
 	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
 	NULL
 };
 
@@ -384,34 +375,6 @@ static struct attribute_group max1363_dev_attr_group = {
 	.attrs = max1363_device_attrs,
 };
 
-static struct attribute *max1363_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group max1363_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max1363_scan_el_attrs,
-};
-
 /* Appies to max1236, max1237 */
 static const enum max1363_modes max1236_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -434,100 +397,36 @@ static const enum max1363_modes max1238_mode_list[] = {
 	d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
 };
 
-static struct attribute *max1238_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in8_raw.dev_attr.attr,
-	&iio_dev_attr_in9_raw.dev_attr.attr,
-	&iio_dev_attr_in10_raw.dev_attr.attr,
-	&iio_dev_attr_in11_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in4min5_raw.dev_attr.attr,
-	&iio_dev_attr_in6min7_raw.dev_attr.attr,
-	&iio_dev_attr_in8min9_raw.dev_attr.attr,
-	&iio_dev_attr_in10min11_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
-	&iio_dev_attr_in5min4_raw.dev_attr.attr,
-	&iio_dev_attr_in7min6_raw.dev_attr.attr,
-	&iio_dev_attr_in9min8_raw.dev_attr.attr,
-	&iio_dev_attr_in11min10_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group max1238_dev_attr_group = {
-	.attrs = max1238_device_attrs,
-};
-
-static struct attribute *max1238_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,	&dev_attr_in4_type.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,	&dev_attr_in5_type.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,	&dev_attr_in6_type.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,	&dev_attr_in7_type.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_scan_el_in8.dev_attr.attr,	&dev_attr_in8_type.attr,
-	&iio_const_attr_in8_index.dev_attr.attr,
-	&iio_scan_el_in9.dev_attr.attr,	&dev_attr_in9_type.attr,
-	&iio_const_attr_in9_index.dev_attr.attr,
-	&iio_scan_el_in10.dev_attr.attr,	&dev_attr_in10_type.attr,
-	&iio_const_attr_in10_index.dev_attr.attr,
-	&iio_scan_el_in11.dev_attr.attr,	&dev_attr_in11_type.attr,
-	&iio_const_attr_in11_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in4min5.dev_attr.attr,	&dev_attr_in4min5_type.attr,
-	&iio_const_attr_in4min5_index.dev_attr.attr,
-	&iio_scan_el_in6min7.dev_attr.attr,	&dev_attr_in6min7_type.attr,
-	&iio_const_attr_in6min7_index.dev_attr.attr,
-	&iio_scan_el_in8min9.dev_attr.attr,	&dev_attr_in8min9_type.attr,
-	&iio_const_attr_in8min9_index.dev_attr.attr,
-	&iio_scan_el_in10min11.dev_attr.attr,	&dev_attr_in10min11_type.attr,
-	&iio_const_attr_in10min11_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	&iio_scan_el_in5min4.dev_attr.attr,	&dev_attr_in5min4_type.attr,
-	&iio_const_attr_in5min4_index.dev_attr.attr,
-	&iio_scan_el_in7min6.dev_attr.attr,	&dev_attr_in7min6_type.attr,
-	&iio_const_attr_in7min6_index.dev_attr.attr,
-	&iio_scan_el_in9min8.dev_attr.attr,	&dev_attr_in9min8_type.attr,
-	&iio_const_attr_in9min8_index.dev_attr.attr,
-	&iio_scan_el_in11min10.dev_attr.attr,	&dev_attr_in11min10_type.attr,
-	&iio_const_attr_in11min10_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group max1238_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max1238_scan_el_attrs,
-};
-
+#define MAX1363_12X_CHANS(bits) {			\
+	MAX1363_CHAN_U(0, _s0, 0, bits),		\
+	MAX1363_CHAN_U(1, _s1, 1, bits),		\
+	MAX1363_CHAN_U(2, _s2, 2, bits),		\
+	MAX1363_CHAN_U(3, _s3, 3, bits),		\
+	MAX1363_CHAN_U(4, _s4, 4, bits),		\
+	MAX1363_CHAN_U(5, _s5, 5, bits),		\
+	MAX1363_CHAN_U(6, _s6, 6, bits),		\
+	MAX1363_CHAN_U(7, _s7, 7, bits),		\
+	MAX1363_CHAN_U(8, _s8, 8, bits),		\
+	MAX1363_CHAN_U(9, _s9, 9, bits),		\
+	MAX1363_CHAN_U(10, _s10, 10, bits),		\
+	MAX1363_CHAN_U(11, _s11, 11, bits),		\
+	MAX1363_CHAN_B(0, 1, d0m1, 12, bits),		\
+	MAX1363_CHAN_B(2, 3, d2m3, 13, bits),		\
+	MAX1363_CHAN_B(4, 5, d4m5, 14, bits),		\
+	MAX1363_CHAN_B(6, 7, d6m7, 15, bits),		\
+	MAX1363_CHAN_B(8, 9, d8m9, 16, bits),		\
+	MAX1363_CHAN_B(10, 11, d10m11, 17, bits),	\
+	MAX1363_CHAN_B(1, 0, d1m0, 18, bits),		\
+	MAX1363_CHAN_B(3, 2, d3m2, 19, bits),		\
+	MAX1363_CHAN_B(5, 4, d5m4, 20, bits),		\
+	MAX1363_CHAN_B(7, 6, d7m6, 21, bits),		\
+	MAX1363_CHAN_B(9, 8, d9m8, 22, bits),		\
+	MAX1363_CHAN_B(11, 10, d11m10, 23, bits),	\
+	IIO_CHAN_SOFT_TIMESTAMP(24)			\
+	}
+static struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
+static struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
+static struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
 
 static const enum max1363_modes max11607_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -547,75 +446,28 @@ static const enum max1363_modes max11608_mode_list[] = {
 	d1m0to3m2, d1m0to5m4, d1m0to7m6,
 };
 
-static struct attribute *max11608_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in4min5_raw.dev_attr.attr,
-	&iio_dev_attr_in6min7_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
-	&iio_dev_attr_in5min4_raw.dev_attr.attr,
-	&iio_dev_attr_in7min6_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group max11608_dev_attr_group = {
-	.attrs = max11608_device_attrs,
-};
-
-static struct attribute *max11608_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,	&dev_attr_in4_type.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,	&dev_attr_in5_type.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,	&dev_attr_in6_type.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,	&dev_attr_in7_type.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in4min5.dev_attr.attr,	&dev_attr_in4min5_type.attr,
-	&iio_const_attr_in4min5_index.dev_attr.attr,
-	&iio_scan_el_in6min7.dev_attr.attr,	&dev_attr_in6min7_type.attr,
-	&iio_const_attr_in6min7_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	&iio_scan_el_in5min4.dev_attr.attr,	&dev_attr_in5min4_type.attr,
-	&iio_const_attr_in5min4_index.dev_attr.attr,
-	&iio_scan_el_in7min6.dev_attr.attr,	&dev_attr_in7min6_type.attr,
-	&iio_const_attr_in7min6_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group max11608_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max11608_scan_el_attrs,
-};
+#define MAX1363_8X_CHANS(bits) {				\
+		MAX1363_CHAN_U(0, _s0, 0, bits),		\
+			MAX1363_CHAN_U(1, _s1, 1, bits),	\
+			MAX1363_CHAN_U(2, _s2, 2, bits),	\
+			MAX1363_CHAN_U(3, _s3, 3, bits),	\
+			MAX1363_CHAN_U(4, _s4, 4, bits),	\
+			MAX1363_CHAN_U(5, _s5, 5, bits),	\
+			MAX1363_CHAN_U(6, _s6, 6, bits),	\
+			MAX1363_CHAN_U(7, _s7, 7, bits),	\
+			MAX1363_CHAN_B(0, 1, d0m1, 8, bits),	\
+			MAX1363_CHAN_B(2, 3, d2m3, 9, bits),	\
+			MAX1363_CHAN_B(4, 5, d4m5, 10, bits),	\
+			MAX1363_CHAN_B(6, 7, d6m7, 11, bits),	\
+			MAX1363_CHAN_B(1, 0, d1m0, 12, bits),	\
+			MAX1363_CHAN_B(3, 2, d3m2, 13, bits),	\
+			MAX1363_CHAN_B(5, 4, d5m4, 14, bits),	\
+			MAX1363_CHAN_B(7, 6, d7m6, 15, bits),	\
+			IIO_CHAN_SOFT_TIMESTAMP(16)		\
+		}
+static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
+static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
+static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
 
 enum { max1361,
        max1362,
@@ -656,348 +508,314 @@ enum { max1361,
 /* max1363 and max1368 tested - rest from data sheet */
 static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 	[max1361] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.monitor_mode = 1,
 		.mode_list = max1363_mode_list,
 		.num_modes = ARRAY_SIZE(max1363_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
 	},
 	[max1362] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 4096,
 		.monitor_mode = 1,
 		.mode_list = max1363_mode_list,
 		.num_modes = ARRAY_SIZE(max1363_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
 	},
 	[max1363] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.monitor_mode = 1,
 		.mode_list = max1363_mode_list,
 		.num_modes = ARRAY_SIZE(max1363_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
 	},
 	[max1364] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 4096,
 		.monitor_mode = 1,
 		.mode_list = max1363_mode_list,
 		.num_modes = ARRAY_SIZE(max1363_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
 	},
 	[max1036] = {
-		.num_inputs = 4,
 		.bits = 8,
 		.int_vref_mv = 4096,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
 	},
 	[max1037] = {
-		.num_inputs = 4,
 		.bits = 8,
 		.int_vref_mv = 2048,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
 	},
 	[max1038] = {
-		.num_inputs = 12,
 		.bits = 8,
 		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
 	},
 	[max1039] = {
-		.num_inputs = 12,
 		.bits = 8,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
 	},
 	[max1136] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 4096,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
 	},
 	[max1137] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
 	},
 	[max1138] = {
-		.num_inputs = 12,
 		.bits = 10,
 		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
 	},
 	[max1139] = {
-		.num_inputs = 12,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
 	},
 	[max1236] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 4096,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
 	},
 	[max1237] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.mode_list = max1236_mode_list,
 		.num_modes = ARRAY_SIZE(max1236_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
 	},
 	[max1238] = {
-		.num_inputs = 12,
 		.bits = 12,
 		.int_vref_mv = 4096,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max1239] = {
-		.num_inputs = 12,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11600] = {
-		.num_inputs = 4,
 		.bits = 8,
 		.int_vref_mv = 4096,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
 	},
 	[max11601] = {
-		.num_inputs = 4,
 		.bits = 8,
 		.int_vref_mv = 2048,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
 	},
 	[max11602] = {
-		.num_inputs = 8,
 		.bits = 8,
 		.int_vref_mv = 4096,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
 	},
 	[max11603] = {
-		.num_inputs = 8,
 		.bits = 8,
 		.int_vref_mv = 2048,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
 	},
 	[max11604] = {
-		.num_inputs = 12,
 		.bits = 8,
 		.int_vref_mv = 4098,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11605] = {
-		.num_inputs = 12,
 		.bits = 8,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11606] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 4096,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
 	},
 	[max11607] = {
-		.num_inputs = 4,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
 	},
 	[max11608] = {
-		.num_inputs = 8,
 		.bits = 10,
 		.int_vref_mv = 4096,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
 	},
 	[max11609] = {
-		.num_inputs = 8,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
 	},
 	[max11610] = {
-		.num_inputs = 12,
 		.bits = 10,
 		.int_vref_mv = 4098,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11611] = {
-		.num_inputs = 12,
 		.bits = 10,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11612] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 4096,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
 	},
 	[max11613] = {
-		.num_inputs = 4,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.mode_list = max11607_mode_list,
 		.num_modes = ARRAY_SIZE(max11607_mode_list),
 		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
 	},
 	[max11614] = {
-		.num_inputs = 8,
 		.bits = 12,
 		.int_vref_mv = 4096,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
 	},
 	[max11615] = {
-		.num_inputs = 8,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.mode_list = max11608_mode_list,
 		.num_modes = ARRAY_SIZE(max11608_mode_list),
 		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
 	},
 	[max11616] = {
-		.num_inputs = 12,
 		.bits = 12,
 		.int_vref_mv = 4098,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	},
 	[max11617] = {
-		.num_inputs = 12,
 		.bits = 12,
 		.int_vref_mv = 2048,
 		.mode_list = max1238_mode_list,
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
 	}
 };
 
@@ -1048,51 +866,24 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
 static IIO_CONST_ATTR(sampling_frequency_available,
 		"133000 665000 33300 16600 8300 4200 2000 1000");
 
-static ssize_t max1363_show_thresh(struct device *dev,
-				struct device_attribute *attr,
-				char *buf,
-				bool high)
+static int max1363_read_thresh(struct iio_dev *indio_dev,
+			       int event_code,
+			       int *val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	if (high)
-		return sprintf(buf, "%d\n",
-			st->thresh_high[this_attr->address]);
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+		*val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
 	else
-		return sprintf(buf, "%d\n",
-			st->thresh_low[this_attr->address & 0x7]);
-}
-
-static ssize_t max1363_show_thresh_low(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	return max1363_show_thresh(dev, attr, buf, false);
-}
-
-static ssize_t max1363_show_thresh_high(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	return max1363_show_thresh(dev, attr, buf, true);
+		*val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
+	return 0;
 }
 
-static ssize_t max1363_store_thresh_unsigned(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len,
-					bool high)
+static int max1363_write_thresh(struct iio_dev *indio_dev,
+				int event_code,
+				int val)
 {
-	struct max1363_state *st = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	unsigned long val;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
+	struct max1363_state *st = iio_priv(indio_dev);
+	/* make it handle signed correctly as well */
 	switch (st->chip_info->bits) {
 	case 10:
 		if (val > 0x3FF)
@@ -1104,154 +895,15 @@ static ssize_t max1363_store_thresh_unsigned(struct device *dev,
 		break;
 	}
 
-	switch (high) {
-	case 1:
-		st->thresh_high[this_attr->address] = val;
-		break;
-	case 0:
-		st->thresh_low[this_attr->address & 0x7] = val;
-		break;
-	}
-
-	return len;
-}
-
-static ssize_t max1363_store_thresh_high_unsigned(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_unsigned(dev, attr, buf, len, true);
-}
-
-static ssize_t max1363_store_thresh_low_unsigned(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_unsigned(dev, attr, buf, len, false);
-}
-
-static ssize_t max1363_store_thresh_signed(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len,
-					bool high)
-{
-	struct max1363_state *st = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long val;
-	int ret;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
-	switch (st->chip_info->bits) {
-	case 10:
-		if (val < -512 || val > 511)
-			return -EINVAL;
-		break;
-	case 12:
-		if (val < -2048 || val > 2047)
-			return -EINVAL;
-		break;
-	}
-
-	switch (high) {
-	case 1:
-		st->thresh_high[this_attr->address] = val;
+	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+	case IIO_EV_DIR_FALLING:
+		st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
 		break;
-	case 0:
-		st->thresh_low[this_attr->address & 0x7] = val;
+	case IIO_EV_DIR_RISING:
+		st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
 		break;
 	}
 
-	return len;
-}
-
-static ssize_t max1363_store_thresh_high_signed(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_signed(dev, attr, buf, len, true);
-}
-
-static ssize_t max1363_store_thresh_low_signed(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_signed(dev, attr, buf, len, false);
-}
-
-static IIO_DEVICE_ATTR(in0_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 0);
-static IIO_DEVICE_ATTR(in0_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 0);
-static IIO_DEVICE_ATTR(in1_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 1);
-static IIO_DEVICE_ATTR(in1_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 1);
-static IIO_DEVICE_ATTR(in2_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 2);
-static IIO_DEVICE_ATTR(in2_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 2);
-static IIO_DEVICE_ATTR(in3_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 3);
-static IIO_DEVICE_ATTR(in3_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 3);
-
-static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_high_value,
-			in0-in1_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 4);
-static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_low_value,
-			in0-in1_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 4);
-static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_high_value,
-			in2-in3_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 5);
-static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_low_value,
-			in2-in3_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 5);
-static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_high_value,
-			in1-in0_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 6);
-static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_low_value,
-			in1-in0_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 6);
-static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_high_value,
-			in3-in2_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 7);
-static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_low_value,
-			in3-in2_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 7);
-
-static int max1363_int_th(struct iio_dev *indio_dev,
-			int index,
-			s64 timestamp,
-			int not_test)
-{
-	struct max1363_state *st = iio_priv(indio_dev);
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->thresh_work);
 	return 0;
 }
 
@@ -1265,6 +917,7 @@ static void max1363_thresh_handler_bh(struct work_struct *work_s)
 		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
 
 	i2c_master_recv(st->client, &rx, 1);
+	/* todo - begging for use of for_each_set_bit */
 	if (rx & (1 << 0))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_LOW_THRESH(3),
@@ -1301,23 +954,21 @@ static void max1363_thresh_handler_bh(struct work_struct *work_s)
 	i2c_master_send(st->client, tx, 2);
 }
 
-static ssize_t max1363_read_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+static int max1363_read_event_config(struct iio_dev *indio_dev,
+				     int event_code)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int val;
 
+	int val;
+	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
 	mutex_lock(&indio_dev->mlock);
-	if (this_attr->mask & 0x8)
-		val = (1 << (this_attr->mask & 0x7)) & st->mask_low;
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+		val = (1 << number) & st->mask_low;
 	else
-		val = (1 << this_attr->mask) & st->mask_high;
+		val = (1 << number) & st->mask_high;
 	mutex_unlock(&indio_dev->mlock);
 
-	return sprintf(buf, "%d\n", !!val);
+	return val;
 }
 
 static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
@@ -1434,6 +1085,7 @@ error_ret:
  * To keep this manageable we always use one of 3 scan modes.
  * Scan 0...3, 0-1,2-3 and 1-0,3-2
  */
+
 static inline int __max1363_check_event_mask(int thismask, int checkmask)
 {
 	int ret = 0;
@@ -1454,206 +1106,61 @@ error_ret:
 	return ret;
 }
 
-static ssize_t max1363_write_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
+static int max1363_write_event_config(struct iio_dev *indio_dev,
+				      int event_code,
+				      struct iio_event_handler_list *listel,
+				      int state)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	int ret = 0;
 	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	unsigned long val;
-	int ret;
 	u16 unifiedmask;
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
+	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+
 	mutex_lock(&indio_dev->mlock);
 	unifiedmask = st->mask_low | st->mask_high;
-	if (this_attr->mask & 0x08) {
-		/* If we are disabling no need to test */
-		if (val == 0)
-			st->mask_low &= ~(1 << (this_attr->mask & 0x7));
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) {
+
+		if (state == 0)
+			st->mask_low &= ~(1 << number);
 		else {
-			ret = __max1363_check_event_mask(this_attr->mask & 0x7,
-							unifiedmask);
+			ret = __max1363_check_event_mask((1 << number),
+							 unifiedmask);
 			if (ret)
 				goto error_ret;
-			st->mask_low |= (1 << (this_attr->mask & 0x7));
+			st->mask_low |= (1 << number);
 		}
 	} else {
-		if (val == 0)
-			st->mask_high &= ~(1 << (this_attr->mask));
+		if (state == 0)
+			st->mask_high &= ~(1 << number);
 		else {
-			ret = __max1363_check_event_mask(this_attr->mask,
-							unifiedmask);
+			ret = __max1363_check_event_mask((1 << number),
+							 unifiedmask);
 			if (ret)
 				goto error_ret;
-			st->mask_high |= (1 << this_attr->mask);
+			st->mask_high |= (1 << number);
 		}
 	}
 	if (st->monitor_on && !st->mask_high && !st->mask_low)
-		iio_remove_event_from_list(this_attr->listel,
-					&indio_dev->interrupts[0]->ev_list);
-	if (!st->monitor_on && val)
-		iio_add_event_to_list(this_attr->listel,
-				&indio_dev->interrupts[0]->ev_list);
+		iio_remove_event_from_list(listel,
+					   &indio_dev->interrupts[0]->ev_list);
+	if (!st->monitor_on && state)
+		iio_add_event_to_list(listel,
+				      &indio_dev->interrupts[0]->ev_list);
 
 	max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
 error_ret:
 	mutex_unlock(&indio_dev->mlock);
 
-	return len;
+	return ret;
 }
 
-IIO_EVENT_SH(max1363_thresh, max1363_int_th);
-
-#define MAX1363_HIGH_THRESH(a) a
-#define MAX1363_LOW_THRESH(a) (a | 0x8)
-
-IIO_EVENT_ATTR_SH(in0_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(0));
-
-IIO_EVENT_ATTR_SH(in0_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(0));
-
-IIO_EVENT_ATTR_SH(in1_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(1));
-
-IIO_EVENT_ATTR_SH(in1_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(1));
-
-IIO_EVENT_ATTR_SH(in2_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(2));
-
-IIO_EVENT_ATTR_SH(in2_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(2));
-
-IIO_EVENT_ATTR_SH(in3_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(3));
-
-IIO_EVENT_ATTR_SH(in3_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(3));
-
-IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_high_en,
-			in0-in1_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(4));
-
-IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_low_en,
-			in0-in1_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(4));
-
-IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_high_en,
-			in3-in2_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(5));
-
-IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_low_en,
-			in3-in2_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(5));
-
-IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_high_en,
-			in1-in0_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(6));
-
-IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_low_en,
-			in1-in0_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(6));
-
-IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_high_en,
-			in2-in3_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(7));
-
-IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_low_en,
-			in2-in3_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(7));
-
 /*
  * As with scan_elements, only certain sets of these can
  * be combined.
  */
 static struct attribute *max1363_event_attributes[] = {
-	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in2_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in2_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in3_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in3_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in0min1_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in0min1_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in2min3_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in2min3_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in1min0_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in1min0_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in3min2_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in3min2_thresh_low_value.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in0_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in2_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in2_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in3_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in3_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in0min1_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in0min1_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in3min2_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in3min2_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in1min0_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in1min0_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in2min3_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in2min3_thresh_low_en.dev_attr.attr,
 	NULL,
 };
 
@@ -1721,8 +1228,14 @@ static int __devinit max1363_probe(struct i2c_client *client,
 			.modemask;
 	/* Estabilish that the iio_dev is a child of the i2c device */
 	indio_dev->dev.parent = &client->dev;
-	indio_dev->attrs = st->chip_info->dev_attrs;
-
+	indio_dev->attrs = &max1363_dev_attr_group;
+	indio_dev->read_event_value = &max1363_read_thresh;
+	indio_dev->write_event_value = &max1363_write_thresh;
+	indio_dev->read_event_config = &max1363_read_event_config;
+	indio_dev->write_event_config = &max1363_write_event_config;
+	indio_dev->channels = st->chip_info->channels;
+	indio_dev->num_channels = st->chip_info->num_channels;
+	indio_dev->read_raw = &max1363_read_raw;
 	/* Todo: this shouldn't be here. */
 	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
@@ -1744,7 +1257,9 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	if (ret)
 		goto error_cleanup_ring;
 	regdone = 1;
-	ret = iio_ring_buffer_register(indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  st->chip_info->channels,
+					  st->chip_info->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
@@ -1754,9 +1269,9 @@ static int __devinit max1363_probe(struct i2c_client *client,
 						0,
 						IRQF_TRIGGER_RISING,
 						client->name);
+
 		if (ret)
 			goto error_uninit_ring;
-
 		INIT_WORK(&st->thresh_work, max1363_thresh_handler_bh);
 	}
 
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index dbe8c9f..405f729 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -199,7 +199,6 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_deallocate_sw_rb;
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->preenable = &max1363_ring_preenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 004/111] staging:iio: remove ability to escalate events.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (2 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 003/111] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 005/111] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
                   ` (107 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Whilst it is possible to output events to say buffers have passed
a particular level there are no obvious reasons to actually do so.

The upshot of this patch is that buffers will only ever have
one threshold turned on at a time.

For now sca3000 has it's ring buffer effectively disabled.
Fixed later in series.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/sca3000_ring.c |   13 +++++++++----
 drivers/staging/iio/chrdev.h             |   13 -------------
 drivers/staging/iio/iio.h                |   16 ++--------------
 drivers/staging/iio/industrialio-core.c  |   30 ++----------------------------
 drivers/staging/iio/industrialio-ring.c  |   23 ++---------------------
 drivers/staging/iio/ring_generic.h       |    3 ---
 drivers/staging/iio/ring_sw.c            |   14 +-------------
 7 files changed, 16 insertions(+), 96 deletions(-)

diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index b505e70..c20bfe0 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -45,9 +45,12 @@
  * Currently does not provide timestamps.  As the hardware doesn't add them they
  * can only be inferred approximately from ring buffer events such as 50% full
  * and knowledge of when buffer was last emptied.  This is left to userspace.
+ *
+ * Temporarily deliberately broken.
  **/
 static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
-				      size_t count, u8 **data, int *dead_offset)
+				      size_t count, char __user *buf,
+				      int *dead_offset)
 {
 	struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r);
 	struct iio_dev *indio_dev = hw_ring->private;
@@ -56,6 +59,8 @@ static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
 	s16 *samples;
 	int ret, i, num_available, num_read = 0;
 	int bytes_per_sample = 1;
+	u8 *datas;
+	u8 **data = &datas;
 
 	if (st->bpse == 11)
 		bytes_per_sample = 2;
@@ -353,9 +358,9 @@ void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
 void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
 {
 	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
-		iio_push_or_escallate_ring_event(ring,
-						 IIO_EVENT_CODE_RING_75_FULL,
-						 0);
+		iio_push_ring_event(ring,
+				    IIO_EVENT_CODE_RING_75_FULL,
+				    0);
 	else if (val & SCA3000_INT_STATUS_HALF)
 		iio_push_ring_event(ring,
 				    IIO_EVENT_CODE_RING_50_FULL, 0);
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 62c4285..d72049c 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -45,23 +45,10 @@ struct iio_event_data {
  * struct iio_detected_event_list - list element for events that have occurred
  * @list:		linked list header
  * @ev:			the event itself
- * @shared_pointer:	used when the event is shared - i.e. can be escallated
- *			on demand (eg ring buffer 50%->100% full)
  */
 struct iio_detected_event_list {
 	struct list_head		list;
 	struct iio_event_data		ev;
-	struct iio_shared_ev_pointer	*shared_pointer;
-};
-/**
- * struct iio_shared_ev_pointer - allows shared events to identify if currently
- *				in the detected event list
- * @ev_p:	pointer to detected event list element (null if not in list)
- * @lock:	protect this element to prevent simultaneous edit and remove
- */
-struct iio_shared_ev_pointer {
-	struct iio_detected_event_list	*ev_p;
-	spinlock_t			lock;
 };
 
 /**
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 440704c..1663220 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -394,22 +394,10 @@ int iio_push_event(struct iio_dev *dev_info,
  * @ev_int:		the event interface to which we are pushing the event
  * @ev_code:		the outgoing event code
  * @timestamp:		timestamp of the event
- * @shared_pointer_p:	the shared event pointer
  **/
 int __iio_push_event(struct iio_event_interface *ev_int,
-		    int ev_code,
-		    s64 timestamp,
-		    struct iio_shared_ev_pointer*
-		    shared_pointer_p);
-/**
- * __iio_change_event() - change an event code in case of event escalation
- * @ev:			the event to be changed
- * @ev_code:		new event code
- * @timestamp:		new timestamp
- **/
-void __iio_change_event(struct iio_detected_event_list *ev,
-			int ev_code,
-			s64 timestamp);
+		     int ev_code,
+		     s64 timestamp);
 
 /**
  * iio_setup_ev_int() - configure an event interface (chrdev)
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index b67394c..24ce216 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -82,15 +82,6 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
 };
 
-void __iio_change_event(struct iio_detected_event_list *ev,
-			int ev_code,
-			s64 timestamp)
-{
-	ev->ev.id = ev_code;
-	ev->ev.timestamp = timestamp;
-}
-EXPORT_SYMBOL(__iio_change_event);
-
 /* Used both in the interrupt line put events and the ring buffer ones */
 
 /* Note that in it's current form someone has to be listening before events
@@ -99,9 +90,7 @@ EXPORT_SYMBOL(__iio_change_event);
  */
 int __iio_push_event(struct iio_event_interface *ev_int,
 		     int ev_code,
-		     s64 timestamp,
-		     struct iio_shared_ev_pointer *
-		     shared_pointer_p)
+		     s64 timestamp)
 {
 	struct iio_detected_event_list *ev;
 	int ret = 0;
@@ -121,9 +110,6 @@ int __iio_push_event(struct iio_event_interface *ev_int,
 		}
 		ev->ev.id = ev_code;
 		ev->ev.timestamp = timestamp;
-		ev->shared_pointer = shared_pointer_p;
-		if (ev->shared_pointer)
-			shared_pointer_p->ev_p = ev;
 
 		list_add_tail(&ev->list, &ev_int->det_events.list);
 		ev_int->current_events++;
@@ -143,7 +129,7 @@ int iio_push_event(struct iio_dev *dev_info,
 		   s64 timestamp)
 {
 	return __iio_push_event(&dev_info->event_interfaces[ev_line],
-				ev_code, timestamp, NULL);
+				ev_code, timestamp);
 }
 EXPORT_SYMBOL(iio_push_event);
 
@@ -311,18 +297,6 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
 	list_del(&el->list);
 	ev_int->current_events--;
 	mutex_unlock(&ev_int->event_list_lock);
-	/*
-	 * Possible concurency issue if an update of this event is on its way
-	 * through. May lead to new event being removed whilst the reported
-	 * event was the unescalated event. In typical use case this is not a
-	 * problem as userspace will say read half the buffer due to a 50%
-	 * full event which would make the correct 100% full incorrect anyway.
-	 */
-	if (el->shared_pointer) {
-		spin_lock(&el->shared_pointer->lock);
-		(el->shared_pointer->ev_p) = NULL;
-		spin_unlock(&el->shared_pointer->lock);
-	}
 	kfree(el);
 
 	return len;
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index d6b4bb7..5d7cd0e 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -27,28 +27,11 @@ int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
 		       s64 timestamp)
 {
 	return __iio_push_event(&ring_buf->ev_int,
-			       event_code,
-			       timestamp,
-			       &ring_buf->shared_ev_pointer);
+				event_code,
+				timestamp);
 }
 EXPORT_SYMBOL(iio_push_ring_event);
 
-int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
-				    int event_code,
-				    s64 timestamp)
-{
-	if (ring_buf->shared_ev_pointer.ev_p)
-		__iio_change_event(ring_buf->shared_ev_pointer.ev_p,
-				   event_code,
-				   timestamp);
-	else
-		return iio_push_ring_event(ring_buf,
-					  event_code,
-					  timestamp);
-	return 0;
-}
-EXPORT_SYMBOL(iio_push_or_escallate_ring_event);
-
 /**
  * iio_ring_open() - chrdev file open for ring buffer access
  *
@@ -228,8 +211,6 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 	ring->indio_dev = dev_info;
 	ring->ev_int.private = ring;
 	ring->access_handler.private = ring;
-	ring->shared_ev_pointer.ev_p = NULL;
-	spin_lock_init(&ring->shared_ev_pointer.lock);
 }
 EXPORT_SYMBOL(iio_ring_buffer_init);
 
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index ada51c2..d51c21c 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -107,8 +107,6 @@ struct iio_ring_access_funcs {
  * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
  * @access_handler:	[INTERN] chrdev access handling
  * @ev_int:		[INTERN] chrdev interface for the event chrdev
- * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
- *			events
  * @access:		[DRIVER] ring access functions associated with the
  *			implementation.
  * @preenable:		[DRIVER] function to run prior to marking ring enabled
@@ -133,7 +131,6 @@ struct iio_ring_buffer {
 	bool				scan_timestamp;
 	struct iio_handler		access_handler;
 	struct iio_event_interface	ev_int;
-	struct iio_shared_ev_pointer	shared_ev_pointer;
 	struct iio_ring_access_funcs	access;
 	int				(*preenable)(struct iio_dev *);
 	int				(*postenable)(struct iio_dev *);
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index ea0015e..0004814 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -123,14 +123,6 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 		 */
 		if (change_test_ptr == ring->read_p)
 			ring->read_p = temp_ptr;
-
-		spin_lock(&ring->buf.shared_ev_pointer.lock);
-
-		ret = iio_push_or_escallate_ring_event(&ring->buf,
-			       IIO_EVENT_CODE_RING_100_FULL, timestamp);
-		spin_unlock(&ring->buf.shared_ev_pointer.lock);
-		if (ret)
-			goto error_ret;
 	}
 	/* investigate if our event barrier has been passed */
 	/* There are definite 'issues' with this and chances of
@@ -140,15 +132,11 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
 		ring->half_p = ring->data;
 	if (ring->half_p == ring->read_p) {
-		spin_lock(&ring->buf.shared_ev_pointer.lock);
 		code = IIO_EVENT_CODE_RING_50_FULL;
 		ret = __iio_push_event(&ring->buf.ev_int,
 				       code,
-				       timestamp,
-				       &ring->buf.shared_ev_pointer);
-		spin_unlock(&ring->buf.shared_ev_pointer.lock);
+				       timestamp);
 	}
-error_ret:
 	return ret;
 }
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 005/111] staging:iio: Add polling of events on the ring access chrdev.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (3 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 004/111] staging:iio: remove ability to escalate events Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 006/111] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
                   ` (106 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Staging one of combining the ring chrdevs.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-ring.c |   29 ++++++++++++++++++++++++-----
 drivers/staging/iio/ring_generic.h      |    3 +++
 drivers/staging/iio/ring_sw.c           |    8 ++++++++
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 5d7cd0e..5c3f466 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/slab.h>
+#include <linux/poll.h>
 
 #include "iio.h"
 #include "ring_generic.h"
@@ -90,10 +91,27 @@ static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
 	return ret;
 }
 
+/**
+ * iio_ring_poll() - poll the ring to find out if it has data
+ */
+static unsigned int iio_ring_poll(struct file *filp,
+				  struct poll_table_struct *wait)
+{
+	struct iio_ring_buffer *rb = filp->private_data;
+	int ret = 0;
+
+	poll_wait(filp, &rb->pollq, wait);
+	if (rb->stufftoread)
+		return POLLIN | POLLRDNORM;
+	/* need a way of knowing if there may be enough data... */
+	return ret;
+}
+
 static const struct file_operations iio_ring_fileops = {
 	.read = iio_ring_read_first_n_outer,
 	.release = iio_ring_release,
 	.open = iio_ring_open,
+	.poll = iio_ring_poll,
 	.owner = THIS_MODULE,
 	.llseek = noop_llseek,
 };
@@ -211,6 +229,7 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 	ring->indio_dev = dev_info;
 	ring->ev_int.private = ring;
 	ring->access_handler.private = ring;
+	init_waitqueue_head(&ring->pollq);
 }
 EXPORT_SYMBOL(iio_ring_buffer_init);
 
@@ -392,7 +411,7 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 						      ring->owner);
 
 	if (ret)
-		goto error_free_ring_buffer_event_chrdev;
+		goto error_ret;
 
 	if (ring->scan_el_attrs) {
 		ret = sysfs_create_group(&ring->dev.kobj,
@@ -400,13 +419,13 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 		if (ret) {
 			dev_err(&ring->dev,
 				"Failed to add sysfs scan elements\n");
-			goto error_free_ring_buffer_event_chrdev;
+			goto error_free_ring_buffer_access_chrdev;
 		}
 	} else if (channels) {
 		ret = sysfs_create_group(&ring->dev.kobj,
 					 &iio_scan_el_dummy_group);
 		if (ret)
-			goto error_free_ring_buffer_event_chrdev;
+			goto error_free_ring_buffer_access_chrdev;
 	}
 
 
@@ -424,8 +443,8 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 	return 0;
 error_cleanup_dynamic:
 	__iio_ring_attr_cleanup(ring);
-error_free_ring_buffer_event_chrdev:
-	__iio_free_ring_buffer_event_chrdev(ring);
+error_free_ring_buffer_access_chrdev:
+	__iio_free_ring_buffer_access_chrdev(ring);
 error_remove_device:
 	device_del(&ring->dev);
 error_ret:
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index d51c21c..0640a8a 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -139,6 +139,9 @@ struct iio_ring_buffer {
 
 	struct list_head scan_el_dev_attr_list;
 	struct list_head scan_el_en_attr_list;
+
+	wait_queue_head_t pollq;
+	bool stufftoread;
 };
 
 /**
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 0004814..53c6774 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
 #include <linux/poll.h>
 #include "ring_sw.h"
 #include "trigger.h"
@@ -136,6 +137,8 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 		ret = __iio_push_event(&ring->buf.ev_int,
 				       code,
 				       timestamp);
+		ring->buf.stufftoread = true;
+		wake_up_interruptible(&ring->buf.pollq);
 	}
 	return ret;
 }
@@ -261,6 +264,10 @@ int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
 		ret =  -EFAULT;
 		goto error_free_data_cpy;
 	}
+
+	if (bytes_to_rip >= ring->buf.length*ring->buf.bytes_per_datum/2)
+		ring->buf.stufftoread = 0;
+
 error_free_data_cpy:
 	kfree(data);
 error_ret:
@@ -310,6 +317,7 @@ int iio_request_update_sw_rb(struct iio_ring_buffer *r)
 	int ret = 0;
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
+	r->stufftoread = false;
 	spin_lock(&ring->use_lock);
 	if (!ring->update_needed)
 		goto error_ret;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 006/111] staging:iio: remove legacy event chrdev for the buffers
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (4 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 005/111] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 007/111] staging:iio: Buffer device flattening Jonathan Cameron
                   ` (105 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

part of sca3000 driver temporarily disabled (buffer won't run
anyway).  This section is replaced later in this patch set.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/sca3000_ring.c |    2 +
 drivers/staging/iio/iio.h                |   14 -------
 drivers/staging/iio/industrialio-core.c  |    4 +-
 drivers/staging/iio/industrialio-ring.c  |   58 +-----------------------------
 drivers/staging/iio/ring_generic.h       |   25 -------------
 drivers/staging/iio/ring_sw.c            |    5 ---
 6 files changed, 5 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index c20bfe0..44f9a56 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -357,6 +357,7 @@ void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
  **/
 void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
 {
+	/*
 	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
 		iio_push_ring_event(ring,
 				    IIO_EVENT_CODE_RING_75_FULL,
@@ -364,4 +365,5 @@ void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
 	else if (val & SCA3000_INT_STATUS_HALF)
 		iio_push_ring_event(ring,
 				    IIO_EVENT_CODE_RING_50_FULL, 0);
+	*/
 }
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 1663220..7e44639 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -400,20 +400,6 @@ int __iio_push_event(struct iio_event_interface *ev_int,
 		     s64 timestamp);
 
 /**
- * iio_setup_ev_int() - configure an event interface (chrdev)
- * @name:		name used for resulting sysfs directory etc.
- * @ev_int:		interface we are configuring
- * @owner:		module that is responsible for registering this ev_int
- * @dev:		device whose ev_int this is
- **/
-int iio_setup_ev_int(struct iio_event_interface *ev_int,
-		     const char *name,
-		     struct module *owner,
-		     struct device *dev);
-
-void iio_free_ev_int(struct iio_event_interface *ev_int);
-
-/**
  * iio_allocate_chrdev() - Allocate a chrdev
  * @handler:	struct that contains relevant file handling for chrdev
  * @dev_info:	iio_dev for which chrdev is being created
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 24ce216..9ddd6a6 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -393,7 +393,7 @@ void iio_device_free_chrdev_minor(int val)
 	spin_unlock(&iio_ida_lock);
 }
 
-int iio_setup_ev_int(struct iio_event_interface *ev_int,
+static int iio_setup_ev_int(struct iio_event_interface *ev_int,
 		     const char *name,
 		     struct module *owner,
 		     struct device *dev)
@@ -445,7 +445,7 @@ error_device_put:
 	return ret;
 }
 
-void iio_free_ev_int(struct iio_event_interface *ev_int)
+static void iio_free_ev_int(struct iio_event_interface *ev_int)
 {
 	device_unregister(&ev_int->dev);
 	put_device(&ev_int->dev);
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 5c3f466..559d613 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -23,16 +23,6 @@
 #include "iio.h"
 #include "ring_generic.h"
 
-int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
-		       int event_code,
-		       s64 timestamp)
-{
-	return __iio_push_event(&ring_buf->ev_int,
-				event_code,
-				timestamp);
-}
-EXPORT_SYMBOL(iio_push_ring_event);
-
 /**
  * iio_ring_open() - chrdev file open for ring buffer access
  *
@@ -116,43 +106,6 @@ static const struct file_operations iio_ring_fileops = {
 	.llseek = noop_llseek,
 };
 
-/**
- * __iio_request_ring_buffer_event_chrdev() - allocate ring event chrdev
- * @buf:	ring buffer whose event chrdev we are allocating
- * @id:		id of this ring buffer (typically 0)
- * @owner:	the module who owns the ring buffer (for ref counting)
- * @dev:	device with which the chrdev is associated
- **/
-static inline int
-__iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf,
-				       int id,
-				       struct module *owner,
-				       struct device *dev)
-{
-	int ret;
-
-	snprintf(buf->ev_int._name, sizeof(buf->ev_int._name),
-		 "%s:event%d",
-		 dev_name(&buf->dev),
-		 id);
-	ret = iio_setup_ev_int(&(buf->ev_int),
-			       buf->ev_int._name,
-			       owner,
-			       dev);
-	if (ret)
-		goto error_ret;
-	return 0;
-
-error_ret:
-	return ret;
-}
-
-static inline void
-__iio_free_ring_buffer_event_chrdev(struct iio_ring_buffer *buf)
-{
-	iio_free_ev_int(&(buf->ev_int));
-}
-
 static void iio_ring_access_release(struct device *dev)
 {
 	struct iio_ring_buffer *buf
@@ -227,7 +180,6 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 	if (ring->access.mark_param_change)
 		ring->access.mark_param_change(ring);
 	ring->indio_dev = dev_info;
-	ring->ev_int.private = ring;
 	ring->access_handler.private = ring;
 	init_waitqueue_head(&ring->pollq);
 }
@@ -399,19 +351,12 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 	if (ret)
 		goto error_ret;
 
-	ret = __iio_request_ring_buffer_event_chrdev(ring,
-						     0,
-						     ring->owner,
-						     &ring->dev);
-	if (ret)
-		goto error_remove_device;
-
 	ret = __iio_request_ring_buffer_access_chrdev(ring,
 						      0,
 						      ring->owner);
 
 	if (ret)
-		goto error_ret;
+		goto error_remove_device;
 
 	if (ring->scan_el_attrs) {
 		ret = sysfs_create_group(&ring->dev.kobj,
@@ -462,7 +407,6 @@ void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
 	__iio_ring_attr_cleanup(ring);
 	__iio_free_ring_buffer_access_chrdev(ring);
-	__iio_free_ring_buffer_event_chrdev(ring);
 	device_del(&ring->dev);
 }
 EXPORT_SYMBOL(iio_ring_buffer_unregister);
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 0640a8a..3a1a872 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -16,29 +16,6 @@
 struct iio_ring_buffer;
 
 /**
- * iio_push_ring_event() - ring buffer specific push to event chrdev
- * @ring_buf:		ring buffer that is the event source
- * @event_code:		event indentification code
- * @timestamp:		time of event
- **/
-int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
-			int event_code,
-			s64 timestamp);
-/**
- * iio_push_or_escallate_ring_event() -	escalate or add as appropriate
- * @ring_buf:		ring buffer that is the event source
- * @event_code:		event indentification code
- * @timestamp:		time of event
- *
- * Typical usecase is to escalate a 50% ring full to 75% full if no one has yet
- * read the first event. Clearly the 50% full is no longer of interest in
- * typical use case.
- **/
-int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
-				     int event_code,
-				     s64 timestamp);
-
-/**
  * struct iio_ring_access_funcs - access functions for ring buffers.
  * @mark_in_use:	reference counting, typically to prevent module removal
  * @unmark_in_use:	reduce reference count when no longer using ring buffer
@@ -106,7 +83,6 @@ struct iio_ring_access_funcs {
  * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
  * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
  * @access_handler:	[INTERN] chrdev access handling
- * @ev_int:		[INTERN] chrdev interface for the event chrdev
  * @access:		[DRIVER] ring access functions associated with the
  *			implementation.
  * @preenable:		[DRIVER] function to run prior to marking ring enabled
@@ -130,7 +106,6 @@ struct iio_ring_buffer {
 	u32				scan_mask;
 	bool				scan_timestamp;
 	struct iio_handler		access_handler;
-	struct iio_event_interface	ev_int;
 	struct iio_ring_access_funcs	access;
 	int				(*preenable)(struct iio_dev *);
 	int				(*postenable)(struct iio_dev *);
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 53c6774..a429a3d 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -69,7 +69,6 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 				unsigned char *data, s64 timestamp)
 {
 	int ret = 0;
-	int code;
 	unsigned char *temp_ptr, *change_test_ptr;
 
 	/* initial store */
@@ -133,10 +132,6 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
 		ring->half_p = ring->data;
 	if (ring->half_p == ring->read_p) {
-		code = IIO_EVENT_CODE_RING_50_FULL;
-		ret = __iio_push_event(&ring->buf.ev_int,
-				       code,
-				       timestamp);
 		ring->buf.stufftoread = true;
 		wake_up_interruptible(&ring->buf.pollq);
 	}
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 007/111] staging:iio: Buffer device flattening.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (5 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 006/111] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 008/111] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
                   ` (104 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Given we now only have one device we don't need the extra layer any more.
Hence this patch removes it.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-ring.c |   76 ++++++++++---------------------
 drivers/staging/iio/ring_generic.h      |    8 +---
 drivers/staging/iio/ring_sw.c           |    3 +-
 3 files changed, 28 insertions(+), 59 deletions(-)

diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 559d613..625263e 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -106,72 +106,60 @@ static const struct file_operations iio_ring_fileops = {
 	.llseek = noop_llseek,
 };
 
-static void iio_ring_access_release(struct device *dev)
+void iio_ring_access_release(struct device *dev)
 {
 	struct iio_ring_buffer *buf
-		= access_dev_to_iio_ring_buffer(dev);
+		= container_of(dev, struct iio_ring_buffer, dev);
 	cdev_del(&buf->access_handler.chrdev);
 	iio_device_free_chrdev_minor(MINOR(dev->devt));
 }
-
-static struct device_type iio_ring_access_type = {
-	.release = iio_ring_access_release,
-};
+EXPORT_SYMBOL(iio_ring_access_release);
 
 static inline int
-__iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf,
-					int id,
+__iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
 					struct module *owner)
 {
 	int ret, minor;
 
 	buf->access_handler.flags = 0;
 
-	buf->access_dev.parent = &buf->dev;
-	buf->access_dev.bus = &iio_bus_type;
-	buf->access_dev.type = &iio_ring_access_type;
-	device_initialize(&buf->access_dev);
+	buf->dev.bus = &iio_bus_type;
+	device_initialize(&buf->dev);
 
 	minor = iio_device_get_chrdev_minor();
 	if (minor < 0) {
 		ret = minor;
 		goto error_device_put;
 	}
-	buf->access_dev.devt = MKDEV(MAJOR(iio_devt), minor);
-
-
-	buf->access_id = id;
-
-	dev_set_name(&buf->access_dev, "%s:access%d",
-		     dev_name(&buf->dev),
-		     buf->access_id);
-	ret = device_add(&buf->access_dev);
+	buf->dev.devt = MKDEV(MAJOR(iio_devt), minor);
+	dev_set_name(&buf->dev, "%s:buffer%d",
+		     dev_name(buf->dev.parent),
+		     buf->id);
+	ret = device_add(&buf->dev);
 	if (ret < 0) {
-		printk(KERN_ERR "failed to add the ring access dev\n");
+		printk(KERN_ERR "failed to add the ring dev\n");
 		goto error_device_put;
 	}
-
 	cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops);
 	buf->access_handler.chrdev.owner = owner;
-
-	ret = cdev_add(&buf->access_handler.chrdev, buf->access_dev.devt, 1);
+	ret = cdev_add(&buf->access_handler.chrdev, buf->dev.devt, 1);
 	if (ret) {
-		printk(KERN_ERR "failed to allocate ring access chrdev\n");
+		printk(KERN_ERR "failed to allocate ring chrdev\n");
 		goto error_device_unregister;
 	}
 	return 0;
 
 error_device_unregister:
-	device_unregister(&buf->access_dev);
+	device_unregister(&buf->dev);
 error_device_put:
-	put_device(&buf->access_dev);
+	put_device(&buf->dev);
 
 	return ret;
 }
 
-static void __iio_free_ring_buffer_access_chrdev(struct iio_ring_buffer *buf)
+static void __iio_free_ring_buffer_chrdev(struct iio_ring_buffer *buf)
 {
-	device_unregister(&buf->access_dev);
+	device_unregister(&buf->dev);
 }
 
 void iio_ring_buffer_init(struct iio_ring_buffer *ring,
@@ -344,36 +332,25 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 
 	ring->id = id;
 
-	dev_set_name(&ring->dev, "%s:buffer%d",
-		     dev_name(ring->dev.parent),
-		     ring->id);
-	ret = device_add(&ring->dev);
-	if (ret)
-		goto error_ret;
-
-	ret = __iio_request_ring_buffer_access_chrdev(ring,
-						      0,
-						      ring->owner);
+	ret = __iio_request_ring_buffer_chrdev(ring, ring->owner);
 
 	if (ret)
-		goto error_remove_device;
-
+		goto error_ret;
 	if (ring->scan_el_attrs) {
 		ret = sysfs_create_group(&ring->dev.kobj,
 					 ring->scan_el_attrs);
 		if (ret) {
 			dev_err(&ring->dev,
 				"Failed to add sysfs scan elements\n");
-			goto error_free_ring_buffer_access_chrdev;
+			goto error_free_ring_buffer_chrdev;
 		}
 	} else if (channels) {
 		ret = sysfs_create_group(&ring->dev.kobj,
 					 &iio_scan_el_dummy_group);
 		if (ret)
-			goto error_free_ring_buffer_access_chrdev;
+			goto error_free_ring_buffer_chrdev;
 	}
 
-
 	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
 	INIT_LIST_HEAD(&ring->scan_el_en_attr_list);
 	if (channels) {
@@ -388,10 +365,8 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 	return 0;
 error_cleanup_dynamic:
 	__iio_ring_attr_cleanup(ring);
-error_free_ring_buffer_access_chrdev:
-	__iio_free_ring_buffer_access_chrdev(ring);
-error_remove_device:
-	device_del(&ring->dev);
+error_free_ring_buffer_chrdev:
+	__iio_free_ring_buffer_chrdev(ring);
 error_ret:
 	return ret;
 }
@@ -406,8 +381,7 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
 void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
 	__iio_ring_attr_cleanup(ring);
-	__iio_free_ring_buffer_access_chrdev(ring);
-	device_del(&ring->dev);
+	__iio_free_ring_buffer_chrdev(ring);
 }
 EXPORT_SYMBOL(iio_ring_buffer_unregister);
 
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 3a1a872..91f1037 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -68,11 +68,9 @@ struct iio_ring_access_funcs {
 /**
  * struct iio_ring_buffer - general ring buffer structure
  * @dev:		ring buffer device struct
- * @access_dev:		system device struct for the chrdev
  * @indio_dev:		industrial I/O device structure
  * @owner:		module that owns the ring buffer (for ref counting)
  * @id:			unique id number
- * @access_id:		device id number
  * @length:		[DEVICE] number of datums in ring
  * @bytes_per_datum:	[DEVICE] size of individual datum including timestamp
  * @bpe:		[DEVICE] size of individual channel value
@@ -92,11 +90,9 @@ struct iio_ring_access_funcs {
   **/
 struct iio_ring_buffer {
 	struct device dev;
-	struct device access_dev;
 	struct iio_dev *indio_dev;
 	struct module *owner;
 	int				id;
-	int				access_id;
 	int				length;
 	int				bytes_per_datum;
 	int				bpe;
@@ -398,8 +394,6 @@ static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
 
 #define to_iio_ring_buffer(d)			\
 	container_of(d, struct iio_ring_buffer, dev)
-#define access_dev_to_iio_ring_buffer(d)			\
-	container_of(d, struct iio_ring_buffer, access_dev)
 
 /**
  * iio_ring_buffer_register() - register the buffer with IIO core
@@ -416,6 +410,8 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 				const struct iio_chan_spec *channels,
 				int num_channels);
 
+void iio_ring_access_release(struct device *dev);
+
 /**
  * iio_ring_buffer_unregister() - unregister the buffer from IIO core
  * @ring: the buffer to be unregistered
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index a429a3d..5fbf5ff 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -375,6 +375,7 @@ EXPORT_SYMBOL(iio_mark_update_needed_sw_rb);
 static void iio_sw_rb_release(struct device *dev)
 {
 	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
+	iio_ring_access_release(&r->dev);
 	kfree(iio_to_sw_ring(r));
 }
 
@@ -416,9 +417,7 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
 	iio_ring_buffer_init(buf, indio_dev);
 	__iio_init_sw_ring_buffer(ring);
 	buf->dev.type = &iio_sw_ring_type;
-	device_initialize(&buf->dev);
 	buf->dev.parent = &indio_dev->dev;
-	buf->dev.bus = &iio_bus_type;
 	dev_set_drvdata(&buf->dev, (void *)buf);
 
 	return buf;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 008/111] staging:iio:lis3l02dq: General cleanup
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (6 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 007/111] staging:iio: Buffer device flattening Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:40 ` [PATCH 009/111] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
                   ` (103 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

As Arnd observed, things are clearner if we pass iio_dev into read and write fucntions.

Now uses st for lis3l02dq_state everywhere.

Other bits of trivial tidying.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    4 +-
 drivers/staging/iio/accel/lis3l02dq_core.c |  118 ++++++++++++----------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   62 ++++++++-------
 3 files changed, 84 insertions(+), 100 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 88b5598..76f592b 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -173,11 +173,11 @@ struct lis3l02dq_state {
 #define lis3l02dq_h_to_s(_h)				\
 	container_of(_h, struct lis3l02dq_state, help)
 
-int lis3l02dq_spi_read_reg_8(struct device *dev,
+int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
 			     u8 reg_address,
 			     u8 *val);
 
-int lis3l02dq_spi_write_reg_8(struct device *dev,
+int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
 			      u8 *val);
 
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 0368d51..a812e3e 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -39,9 +39,17 @@
  * This means that use cannot be made of spi_write etc.
  */
 
-static int __lis3l02dq_spi_read_reg_8(struct lis3l02dq_state *st,
-				      u8 reg_address, u8 *val)
+/**
+ * lis3l02dq_spi_read_reg_8() - read single byte from a single register
+ * @indio_dev: iio_dev for this actual device
+ * @reg_address: the address of the register to be read
+ * @val: pass back the resulting value
+ **/
+int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
+			     u8 reg_address, u8 *val)
 {
+	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	struct spi_message msg;
 	int ret;
 	struct spi_transfer xfer = {
@@ -49,7 +57,6 @@ static int __lis3l02dq_spi_read_reg_8(struct lis3l02dq_state *st,
 		.rx_buf = st->rx,
 		.bits_per_word = 8,
 		.len = 2,
-		.cs_change = 1,
 	};
 
 	mutex_lock(&st->buf_lock);
@@ -64,50 +71,26 @@ static int __lis3l02dq_spi_read_reg_8(struct lis3l02dq_state *st,
 
 	return ret;
 }
-/**
- * lis3l02dq_spi_read_reg_8() - read single byte from a single register
- * @dev: device asosciated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be read
- * @val: pass back the resulting value
- **/
-int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	return __lis3l02dq_spi_read_reg_8(st, reg_address, val);
-}
 
 /**
  * lis3l02dq_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-int lis3l02dq_spi_write_reg_8(struct device *dev,
+int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
 			      u8 *val)
 {
 	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	struct spi_transfer xfer = {
-		.tx_buf = st->tx,
-		.bits_per_word = 8,
-		.len = 2,
-		.cs_change = 1,
-	};
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
 	st->tx[1] = *val;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-	ret = spi_sync(st->us, &msg);
+	ret = spi_write(st->us, st->tx, 2);
 	mutex_unlock(&st->buf_lock);
 
 	return ret;
@@ -115,18 +98,17 @@ int lis3l02dq_spi_write_reg_8(struct device *dev,
 
 /**
  * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
+ * @indio_dev: iio_dev for this device
+ * @lower_reg_address: the address of the lower of the two registers.
+ *               Second register is assumed to have address one greater.
+ * @value: value to be written
  **/
-static int lis3l02dq_spi_write_reg_s16(struct device *dev,
+static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
 				       u8 lower_reg_address,
 				       s16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
@@ -139,7 +121,6 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -158,10 +139,14 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev,
 	return ret;
 }
 
-static int lis3l02dq_read_16bit_s(struct lis3l02dq_state *st,
+static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
 				  u8 lower_reg_address,
 				  int *val)
 {
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+
 	struct spi_message msg;
 	int ret;
 	s16 tempval;
@@ -176,7 +161,6 @@ static int lis3l02dq_read_16bit_s(struct lis3l02dq_state *st,
 			.rx_buf = st->rx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 0,
 		},
 	};
 
@@ -224,11 +208,7 @@ static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
 				 int e,
 				 int *val)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
-	return lis3l02dq_read_16bit_s(st, LIS3L02DQ_REG_THS_L_ADDR, val);
+	return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
 }
 
 static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
@@ -236,7 +216,7 @@ static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
 				  int val)
 {
 	u16 value = val;
-	return lis3l02dq_spi_write_reg_s16(&indio_dev->dev,
+	return lis3l02dq_spi_write_reg_s16(indio_dev,
 					   LIS3L02DQ_REG_THS_L_ADDR,
 					   value);
 }
@@ -250,10 +230,8 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 	u8 utemp;
 	s8 stemp;
 	ssize_t ret = 0;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	u8 reg;
+
 	switch (mask) {
 	case 0:
 		/* Take the iio_dev status lock */
@@ -265,7 +243,7 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 		else {
 			reg = lis3l02dq_axis_map
 				[LIS3L02DQ_ACCEL][chan->address];
-			ret = lis3l02dq_read_16bit_s(st, reg, val);
+			ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
 		}
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
@@ -275,7 +253,7 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT_PLUS_MICRO;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
-		ret = __lis3l02dq_spi_read_reg_8(st, reg, &utemp);
+		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
 		if (ret)
 			goto error_ret;
 		/* to match with what previous code does */
@@ -284,7 +262,7 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
-		ret = __lis3l02dq_spi_read_reg_8(st, reg, (u8 *)&stemp);
+		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
 		/* to match with what previous code does */
 		*val = stemp;
 		return IIO_VAL_INT;
@@ -297,9 +275,10 @@ static ssize_t lis3l02dq_read_frequency(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret, len = 0;
 	s8 t;
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       (u8 *)&t);
 	if (ret)
@@ -337,7 +316,7 @@ static ssize_t lis3l02dq_write_frequency(struct device *dev,
 		return ret;
 
 	mutex_lock(&indio_dev->mlock);
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &t);
 	if (ret)
@@ -362,7 +341,7 @@ static ssize_t lis3l02dq_write_frequency(struct device *dev,
 		goto error_ret_mutex;
 	}
 
-	ret = lis3l02dq_spi_write_reg_8(dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&t);
 
@@ -383,7 +362,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
 	val = LIS3L02DQ_DEFAULT_CTRL1;
 	/* Write suitable defaults to ctrl1 */
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&val);
 	if (ret) {
@@ -391,7 +370,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 		goto err_ret;
 	}
 	/* Repeat as sometimes doesn't work first time?*/
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&val);
 	if (ret) {
@@ -401,17 +380,18 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
 	/* Read back to check this has worked acts as loose test of correct
 	 * chip */
-	ret = lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(st->help.indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &valtest);
 	if (ret || (valtest != val)) {
-		dev_err(&st->help.indio_dev->dev, "device not playing ball");
+		dev_err(&st->help.indio_dev->dev,
+			"device not playing ball %d %d\n", valtest, val);
 		ret = -EINVAL;
 		goto err_ret;
 	}
 
 	val = LIS3L02DQ_DEFAULT_CTRL2;
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
 					&val);
 	if (ret) {
@@ -420,7 +400,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 	}
 
 	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
 					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 					&val);
 	if (ret)
@@ -488,7 +468,7 @@ static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
 	u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
 			 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			  IIO_EV_DIR_RISING)));
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 				       &val);
 	if (ret < 0)
@@ -512,12 +492,12 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 
 	mutex_lock(&indio_dev->mlock);
 	/* read current control */
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_2_ADDR,
 				       &control);
 	if (ret)
 		goto error_ret;
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 				       &val);
 	if (ret < 0)
@@ -537,7 +517,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					   &indio_dev->interrupts[0]->ev_list);
 	}
 	if (changed) {
-		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 						&val);
 		if (ret)
@@ -545,7 +525,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 		control = list_el->refcount ?
 			(control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
 			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
-		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					       LIS3L02DQ_REG_CTRL_2_ADDR,
 					       &control);
 	}
@@ -565,7 +545,7 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 			       struct lis3l02dq_state, work_thresh);
 	u8 t;
 
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 
@@ -625,7 +605,7 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 	/* reenable the irq */
 	enable_irq(st->us->irq);
 	/* Ack and allow for new interrupts */
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
 				 &t);
 
@@ -764,7 +744,7 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 	u8 val = 0;
 
 	mutex_lock(&indio_dev->mlock);
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&val);
 	if (ret) {
@@ -772,7 +752,7 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 		goto err_ret;
 	}
 
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
 					&val);
 	if (ret)
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index a710832..2c666f2 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -206,7 +206,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
 /* Get the current event mask register */
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_2_ADDR,
 				       &valold);
 	if (ret)
@@ -220,12 +220,12 @@ __lis3l02dq_write_data_ready_config(struct device *dev,
 
 		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
 		/* The double write is to overcome a hardware bug?*/
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
 						&valold);
 		if (ret)
 			goto error_ret;
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
 						&valold);
 		if (ret)
@@ -240,7 +240,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev,
 		/* if not set, enable requested */
 		valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
 		iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
 						&valold);
 		if (ret)
@@ -275,7 +275,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 		/* Clear any outstanding ready events */
 		ret = lis3l02dq_read_all(st, NULL);
 	}
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 	return ret;
@@ -328,47 +328,51 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct lis3l02dq_state *state = indio_dev->dev_data;
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	state->trig = iio_allocate_trigger();
-	if (!state->trig)
+	st->trig = iio_allocate_trigger();
+	if (!st->trig)
 		return -ENOMEM;
 
-	state->trig->name = kasprintf(GFP_KERNEL,
-				      "lis3l02dq-dev%d",
-				      indio_dev->id);
-	if (!state->trig->name) {
+	st->trig->name = kasprintf(GFP_KERNEL,
+				   "lis3l02dq-dev%d",
+				   indio_dev->id);
+	if (!st->trig->name) {
 		ret = -ENOMEM;
 		goto error_free_trig;
 	}
 
-	state->trig->dev.parent = &state->us->dev;
-	state->trig->owner = THIS_MODULE;
-	state->trig->private_data = state;
-	state->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
-	state->trig->try_reenable = &lis3l02dq_trig_try_reen;
-	state->trig->control_attrs = &lis3l02dq_trigger_attr_group;
-	ret = iio_trigger_register(state->trig);
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = st;
+	st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &lis3l02dq_trig_try_reen;
+	st->trig->control_attrs = &lis3l02dq_trigger_attr_group;
+	ret = iio_trigger_register(st->trig);
 	if (ret)
 		goto error_free_trig_name;
 
 	return 0;
 
 error_free_trig_name:
-	kfree(state->trig->name);
+	kfree(st->trig->name);
 error_free_trig:
-	iio_free_trigger(state->trig);
+	iio_free_trigger(st->trig);
 
 	return ret;
 }
 
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct lis3l02dq_state *state = indio_dev->dev_data;
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	kfree(st->trig->name);
+	iio_free_trigger(st->trig);
 }
 
 void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
@@ -384,7 +388,7 @@ static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
 	int ret;
 	bool oneenabled = false;
 
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &t);
 	if (ret)
@@ -408,7 +412,7 @@ static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
 
 	if (!oneenabled) /* what happens in this case is unknown */
 		return -EINVAL;
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&t);
 	if (ret)
@@ -429,7 +433,7 @@ static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
 	if (ret)
 		goto error_ret;
 
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &t);
 	if (ret)
@@ -438,7 +442,7 @@ static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
 		LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE |
 		LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
 
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&t);
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 009/111] staging:iio: Push interrupt setup down into the drivers for event lines.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (7 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 008/111] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
@ 2011-05-18 13:40 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 010/111] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
                   ` (102 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:40 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

It is much easier to do in driver, and the core does not add much.
Note all drivers will have to be updated with this patch.
None currently are.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    3 +++
 drivers/staging/iio/industrialio-core.c |   17 +++--------------
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 7e44639..cd5ac59 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -12,6 +12,7 @@
 
 #include <linux/device.h>
 #include <linux/cdev.h>
+#include <linux/irq.h>
 #include "sysfs.h"
 #include "chrdev.h"
 
@@ -376,6 +377,8 @@ void iio_unregister_interrupt_line(struct iio_dev *dev_info,
 				   int line_number);
 
 
+/* temporarily exported to allow moving of interrupt requesting into drivers */
+irqreturn_t iio_interrupt_handler(int irq, void *_int_info);
 
 /**
  * iio_push_event() - try to add event to the list for userspace reading
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 9ddd6a6..136ff04 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -134,7 +134,7 @@ int iio_push_event(struct iio_dev *dev_info,
 EXPORT_SYMBOL(iio_push_event);
 
 /* Generic interrupt line interrupt handler */
-static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
+irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
 {
 	struct iio_interrupt *int_info = _int_info;
 	struct iio_dev *dev_info = int_info->dev_info;
@@ -157,6 +157,7 @@ static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
 
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL(iio_interrupt_handler);
 
 static struct iio_interrupt *iio_allocate_interrupt(void)
 {
@@ -175,7 +176,7 @@ int iio_register_interrupt_line(unsigned int irq,
 				unsigned long type,
 				const char *name)
 {
-	int ret;
+	int ret = 0;
 
 	dev_info->interrupts[line_number] = iio_allocate_interrupt();
 	if (dev_info->interrupts[line_number] == NULL) {
@@ -186,16 +187,6 @@ int iio_register_interrupt_line(unsigned int irq,
 	dev_info->interrupts[line_number]->irq = irq;
 	dev_info->interrupts[line_number]->dev_info = dev_info;
 
-	/* Possibly only request on demand?
-	 * Can see this may complicate the handling of interrupts.
-	 * However, with this approach we might end up handling lots of
-	 * events no-one cares about.*/
-	ret = request_irq(irq,
-			  &iio_interrupt_handler,
-			  type,
-			  name,
-			  dev_info->interrupts[line_number]);
-
 error_ret:
 	return ret;
 }
@@ -215,8 +206,6 @@ void iio_unregister_interrupt_line(struct iio_dev *dev_info, int line_number)
 {
 	/* make sure the interrupt handlers are all done */
 	flush_scheduled_work();
-	free_irq(dev_info->interrupts[line_number]->irq,
-		 dev_info->interrupts[line_number]);
 	kfree(dev_info->interrupts[line_number]);
 }
 EXPORT_SYMBOL(iio_unregister_interrupt_line);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 010/111] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (8 preceding siblings ...)
  2011-05-18 13:40 ` [PATCH 009/111] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 011/111] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
                   ` (101 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This removes the one and only real user of the rather complex event list management.
V3: More trivial rebase fixups.
V2: Trivial rebase fixup.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    2 +
 drivers/staging/iio/accel/lis3l02dq_core.c |   97 ++++++++++++++++++++++------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   55 ++++++++--------
 3 files changed, 107 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 76f592b..d366a97 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -181,6 +181,8 @@ int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
 			      u8 *val);
 
+int lis3l02dq_disable_all_events(struct iio_dev *indio_dev);
+
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index a812e3e..c764fc9 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -416,26 +416,21 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 
-static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
+static irqreturn_t lis3l02dq_event_handler(int irq, void *_int_info)
 {
+	struct iio_interrupt *int_info = _int_info;
+	struct iio_dev *indio_dev = int_info->dev_info;
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
-	/* Stash the timestamp somewhere convenient for the bh */
-	st->thresh_timestamp = timestamp;
+	disable_irq_nosync(irq);
+	st->thresh_timestamp = iio_get_time_ns();
 	schedule_work(&st->work_thresh);
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-/* A shared handler for a number of threshold types */
-IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
-
-
 #define LIS3L02DQ_INFO_MASK				\
 	((1 << IIO_CHAN_INFO_SCALE_SHARED) |		\
 	 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
@@ -448,13 +443,13 @@ IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
 static struct iio_chan_spec lis3l02dq_channels[] = {
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK,
 		 0, 0, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+		 LIS3L02DQ_EVENT_MASK, NULL),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK,
 		 1, 1, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+		 LIS3L02DQ_EVENT_MASK, NULL),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK,
 		 2, 2, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+		 LIS3L02DQ_EVENT_MASK, NULL),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -477,11 +472,57 @@ static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
 	return !!(val & mask);
 }
 
+int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
+{
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	int ret;
+	u8 control, val;
+	bool irqtofree;
+
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_CTRL_2_ADDR,
+				       &control);
+
+	irqtofree = !!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
+
+	control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_CTRL_2_ADDR,
+					&control);
+	if (ret)
+		goto error_ret;
+	/* Also for consistency clear the mask */
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &val);
+	if (ret)
+		goto error_ret;
+	val &= ~0x3f;
+
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+					&val);
+	if (ret)
+		goto error_ret;
+
+	if (irqtofree)
+		free_irq(st->us->irq, indio_dev->interrupts[0]);
+
+	ret = control;
+error_ret:
+	return ret;
+}
+
 static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					int event_code,
 					struct iio_event_handler_list *list_el,
 					int state)
 {
+	struct iio_sw_ring_helper_state *h
+		= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	int ret = 0;
 	u8 val, control;
 	u8 currentlyset;
@@ -507,27 +548,39 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 	if (!currentlyset && state) {
 		changed = true;
 		val |= mask;
-		iio_add_event_to_list(list_el,
-				      &indio_dev->interrupts[0]->ev_list);
-
 	} else if (currentlyset && !state) {
 		changed = true;
 		val &= ~mask;
-		iio_remove_event_from_list(list_el,
-					   &indio_dev->interrupts[0]->ev_list);
 	}
+
 	if (changed) {
+		if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
+			ret = request_irq(st->us->irq,
+					  &lis3l02dq_event_handler,
+					  IRQF_TRIGGER_RISING,
+					  "lis3l02dq_event",
+					  indio_dev->interrupts[0]);
+			if (ret)
+				goto error_ret;
+		}
+
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 						&val);
 		if (ret)
 			goto error_ret;
-		control = list_el->refcount ?
+		control = val & 0x3f ?
 			(control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
 			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					       LIS3L02DQ_REG_CTRL_2_ADDR,
 					       &control);
+		if (ret)
+			goto error_ret;
+
+		/* remove interrupt handler if nothing is still on */
+		if (!(val & 0x3f))
+			free_irq(st->us->irq, indio_dev->interrupts[0]);
 	}
 
 error_ret:
@@ -697,7 +750,6 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 						  "lis3l02dq");
 		if (ret)
 			goto error_uninitialize_ring;
-
 		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
 		if (ret)
 			goto error_unregister_line;
@@ -768,6 +820,9 @@ static int lis3l02dq_remove(struct spi_device *spi)
 	int ret;
 	struct lis3l02dq_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->help.indio_dev;
+	ret = lis3l02dq_disable_all_events(indio_dev);
+	if (ret)
+		goto err_ret;
 
 	ret = lis3l02dq_stop_device(indio_dev);
 	if (ret)
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 2c666f2..9bc2e5f 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -51,23 +51,14 @@ static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
 /**
  * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
+static irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
-	iio_trigger_poll(st->trig, timestamp);
+	disable_irq_nosync(irq);
+	iio_trigger_poll(private, iio_get_time_ns());
 
 	return IRQ_HANDLED;
 }
 
-/* This is an event as it is a response to a physical interrupt */
-IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll);
-
 /**
  * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
  **/
@@ -196,14 +187,15 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
 
 /* Caller responsible for locking as necessary. */
 static int
-__lis3l02dq_write_data_ready_config(struct device *dev,
-				    struct iio_event_handler_list *list,
-				    bool state)
+__lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 {
 	int ret;
 	u8 valold;
 	bool currentlyset;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_sw_ring_helper_state *h
+				= iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
 /* Get the current event mask register */
 	ret = lis3l02dq_spi_read_reg_8(indio_dev,
@@ -217,8 +209,9 @@ __lis3l02dq_write_data_ready_config(struct device *dev,
 
 /* Disable requested */
 	if (!state && currentlyset) {
-
+		/* disable the data ready signal */
 		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+
 		/* The double write is to overcome a hardware bug?*/
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
@@ -231,20 +224,31 @@ __lis3l02dq_write_data_ready_config(struct device *dev,
 		if (ret)
 			goto error_ret;
 
-		iio_remove_event_from_list(list,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-
+		free_irq(st->us->irq, st->trig);
 /* Enable requested */
 	} else if (state && !currentlyset) {
 		/* if not set, enable requested */
-		valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
-		iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
+		/* first disable all events */
+		ret = lis3l02dq_disable_all_events(indio_dev);
+		if (ret < 0)
+			goto error_ret;
+
+		valold = ret |
+			LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+		ret = request_irq(st->us->irq,
+				  lis3l02dq_data_rdy_trig_poll,
+				  IRQF_TRIGGER_RISING, "lis3l02dq_datardy",
+				  st->trig);
+		if (ret)
+			goto error_ret;
+
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
 						&valold);
-		if (ret)
+		if (ret) {
+			free_irq(st->us->irq, st->trig);
 			goto error_ret;
+		}
 	}
 
 	return 0;
@@ -265,9 +269,8 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct lis3l02dq_state *st = trig->private_data;
 	int ret = 0;
 	u8 t;
-	__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev,
-					    &iio_event_data_rdy_trig,
-					    state);
+
+	__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, state);
 	if (state == false) {
 		/* possible quirk with handler currently worked around
 		   by ensuring the work queue is empty */
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 011/111] staging:iio:sca3000 extract old event handling and move to poll for events from buffer
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (9 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 010/111] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 012/111] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
                   ` (100 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Fairly substantial rewrite as the code had bitrotted.
A rethink is needed for how to handle variable types in the new chan_spec world.

This patch restores sca3000 buffer usage to a working state.
V3: Rebase fixups.
V2: Move to new version of IIO_CHAN macro

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/sca3000.h      |   76 +--
 drivers/staging/iio/accel/sca3000_core.c |  891 +++++++++++-------------------
 drivers/staging/iio/accel/sca3000_ring.c |  252 ++++++---
 3 files changed, 510 insertions(+), 709 deletions(-)

diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index db71033..f77eb74 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -158,17 +158,17 @@
 
 /**
  * struct sca3000_state - device instance state information
- * @us: 	 		the associated spi device
- * @info: 	  		chip variant information
- * @indio_dev: 	 		device information used by the IIO core
- * @interrupt_handler_ws: 	event interrupt handler for all events
- * @last_timestamp: 		the timestamp of the last event
- * @mo_det_use_count: 		reference counter for the motion detection unit
- * @lock: 		 	lock used to protect elements of sca3000_state
- * 	 			and the underlying device state.
- * @bpse: 		 	number of bits per scan element
- * @tx: 		 	dma-able transmit buffer
- * @rx: 		 	dma-able receive buffer
+ * @us:			the associated spi device
+ * @info:			chip variant information
+ * @indio_dev:			device information used by the IIO core
+ * @interrupt_handler_ws:	event interrupt handler for all events
+ * @last_timestamp:		the timestamp of the last event
+ * @mo_det_use_count:		reference counter for the motion detection unit
+ * @lock:			lock used to protect elements of sca3000_state
+ *				and the underlying device state.
+ * @bpse:			number of bits per scan element
+ * @tx:			dma-able transmit buffer
+ * @rx:			dma-able receive buffer
  **/
 struct sca3000_state {
 	struct spi_device		*us;
@@ -179,15 +179,15 @@ struct sca3000_state {
 	int				mo_det_use_count;
 	struct mutex			lock;
 	int				bpse;
-	u8				*tx;
-	/* not used during a ring buffer read */
-	u8				*rx;
+	/* Can these share a cacheline ? */
+	u8				rx[2] ____cacheline_aligned;
+	u8				tx[6] ____cacheline_aligned;
 };
 
 /**
  * struct sca3000_chip_info - model dependent parameters
- * @name: 			model identification
- * @scale:			string containing floating point scale factor
+ * @name:			model identification
+ * @scale:			scale * 10^-6
  * @temp_output:		some devices have temperature sensors.
  * @measurement_mode_freq:	normal mode sampling frequency
  * @option_mode_1:		first optional mode. Not all models have one
@@ -200,29 +200,20 @@ struct sca3000_state {
  **/
 struct sca3000_chip_info {
 	const char		*name;
-	const char		*scale;
+	unsigned int		scale;
 	bool			temp_output;
 	int			measurement_mode_freq;
 	int			option_mode_1;
 	int			option_mode_1_freq;
 	int			option_mode_2;
 	int			option_mode_2_freq;
+	int			mot_det_mult_xz[6];
+	int			mot_det_mult_y[7];
 };
 
-/**
- * sca3000_read_data() read a series of values from the device
- * @dev:		device
- * @reg_address_high:	start address (decremented read)
- * @rx:			pointer where received data is placed. Callee
- *			responsible for freeing this.
- * @len:		number of bytes to read
- *
- * The main lock must be held.
- **/
-int sca3000_read_data(struct sca3000_state *st,
-		      u8 reg_address_high,
-		      u8 **rx_p,
-		      int len);
+int sca3000_read_data_short(struct sca3000_state *st,
+			    u8 reg_address_high,
+			    int len);
 
 /**
  * sca3000_write_reg() write a single register
@@ -233,29 +224,6 @@ int sca3000_read_data(struct sca3000_state *st,
  **/
 int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val);
 
-/* Conversion function for use with the ring buffer when in 11bit mode */
-static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb)
-{
-	int16_t val;
-
-	val = ((lsb >> 3) & 0x1C) | (msb << 5);
-	val |= (val & (1 << 12)) ? 0xE000 : 0;
-
-	return val;
-}
-
-static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
-{
-	s16 val;
-
-	val = ((lsb >> 3) & 0x1F) | (msb << 5);
-	/* sign fill */
-	val |= (val & (1 << 12)) ? 0xE000 : 0;
-
-	return val;
-}
-
-
 #ifdef CONFIG_IIO_RING_BUFFER
 /**
  * sca3000_register_ring_funcs() setup the ring state change functions
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 6abf2b7..00704a5 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -42,93 +42,73 @@ enum sca3000_variant {
 static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
 	{
 		.name = "sca3000-d01",
-		.scale = " 0.0073575",
+		.scale = 7357,
 		.temp_output = true,
 		.measurement_mode_freq = 250,
 		.option_mode_1 = SCA3000_OP_MODE_BYPASS,
 		.option_mode_1_freq = 250,
+		.mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
+		.mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
 	}, {
 		.name = "sca3000-e02",
-		.scale = "0.00981",
+		.scale = 9810,
 		.measurement_mode_freq = 125,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 63,
+		.mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
+		.mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
 	}, {
 		.name = "sca3000-e04",
-		.scale = "0.01962",
+		.scale = 19620,
 		.measurement_mode_freq = 100,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 50,
 		.option_mode_2 = SCA3000_OP_MODE_WIDE,
 		.option_mode_2_freq = 400,
+		.mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
+		.mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
 	}, {
 		.name = "sca3000-e05",
-		.scale = "0.0613125",
+		.scale = 61313,
 		.measurement_mode_freq = 200,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 50,
 		.option_mode_2 = SCA3000_OP_MODE_WIDE,
 		.option_mode_2_freq = 400,
+		.mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900},
+		.mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600},
 	},
 };
 
-
 int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
 {
-	struct spi_transfer xfer = {
-		.bits_per_word = 8,
-		.len = 2,
-		.cs_change = 1,
-		.tx_buf = st->tx,
-	};
-	struct spi_message msg;
-
 	st->tx[0] = SCA3000_WRITE_REG(address);
 	st->tx[1] = val;
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	return spi_sync(st->us, &msg);
+	return spi_write(st->us, st->tx, 2);
 }
 
-int sca3000_read_data(struct sca3000_state *st,
-		      uint8_t reg_address_high,
-		      u8 **rx_p,
-		      int len)
+int sca3000_read_data_short(struct sca3000_state *st,
+			    uint8_t reg_address_high,
+			    int len)
 {
-	int ret;
 	struct spi_message msg;
-	struct spi_transfer xfer = {
-		.bits_per_word = 8,
-		.len = len + 1,
-		.cs_change = 1,
-		.tx_buf = st->tx,
+	struct spi_transfer xfer[2] = {
+		{
+			.len = 1,
+			.tx_buf = st->tx,
+		}, {
+			.len = len,
+			.rx_buf = st->rx,
+		}
 	};
-
-	*rx_p = kmalloc(len + 1, GFP_KERNEL);
-	if (*rx_p == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	xfer.rx_buf = *rx_p;
 	st->tx[0] = SCA3000_READ_REG(reg_address_high);
 	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	ret = spi_sync(st->us, &msg);
-
-	if (ret) {
-		dev_err(get_device(&st->us->dev), "problem reading register");
-		goto error_free_rx;
-	}
-
-	return 0;
-error_free_rx:
-	kfree(*rx_p);
-error_ret:
-	return ret;
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
 
+	return spi_sync(st->us, &msg);
 }
+
 /**
  * sca3000_reg_lock_on() test if the ctrl register lock is on
  *
@@ -136,17 +116,13 @@ error_ret:
  **/
 static int sca3000_reg_lock_on(struct sca3000_state *st)
 {
-	u8 *rx;
 	int ret;
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
-
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
 	if (ret < 0)
 		return ret;
-	ret = !(rx[1] & SCA3000_LOCKED);
-	kfree(rx);
 
-	return ret;
+	return !(st->rx[0] & SCA3000_LOCKED);
 }
 
 /**
@@ -161,19 +137,15 @@ static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
 	struct spi_message msg;
 	struct spi_transfer xfer[3] = {
 		{
-			.bits_per_word = 8,
 			.len = 2,
 			.cs_change = 1,
 			.tx_buf = st->tx,
 		}, {
-			.bits_per_word = 8,
 			.len = 2,
 			.cs_change = 1,
 			.tx_buf = st->tx + 2,
 		}, {
-			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.tx_buf = st->tx + 4,
 		},
 	};
@@ -236,8 +208,7 @@ error_ret:
  * Lock must be held.
  **/
 static int sca3000_read_ctrl_reg(struct sca3000_state *st,
-				 u8 ctrl_reg,
-				 u8 **rx_p)
+				 u8 ctrl_reg)
 {
 	int ret;
 
@@ -253,8 +224,11 @@ static int sca3000_read_ctrl_reg(struct sca3000_state *st,
 	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_CTRL_DATA, rx_p, 1);
-
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1);
+	if (ret)
+		goto error_ret;
+	else
+		return st->rx[0];
 error_ret:
 	return ret;
 }
@@ -267,20 +241,18 @@ error_ret:
  **/
 static int sca3000_check_status(struct device *dev)
 {
-	u8 *rx;
 	int ret;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
 	if (ret < 0)
 		goto error_ret;
-	if (rx[1] & SCA3000_EEPROM_CS_ERROR)
+	if (st->rx[0] & SCA3000_EEPROM_CS_ERROR)
 		dev_err(dev, "eeprom error\n");
-	if (rx[1] & SCA3000_SPI_FRAME_ERROR)
+	if (st->rx[0] & SCA3000_SPI_FRAME_ERROR)
 		dev_err(dev, "Previous SPI Frame was corrupt\n");
-	kfree(rx);
 
 error_ret:
 	mutex_unlock(&st->lock);
@@ -288,45 +260,6 @@ error_ret:
 }
 #endif /* SCA3000_DEBUG */
 
-/**
- * sca3000_read_13bit_signed() sysfs interface to read 13 bit signed registers
- *
- * These are described as signed 12 bit on the data sheet, which appears
- * to be a conventional 2's complement 13 bit.
- **/
-static ssize_t sca3000_read_13bit_signed(struct device *dev,
-					 struct device_attribute *attr,
-					 char *buf)
-{
-	int len = 0, ret;
-	int val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	u8 *rx;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct sca3000_state *st = indio_dev->dev_data;
-
-	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, this_attr->address, &rx, 2);
-	if (ret < 0)
-		goto error_ret;
-	val = sca3000_13bit_convert(rx[1], rx[2]);
-	len += sprintf(buf + len, "%d\n", val);
-	kfree(rx);
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret ? ret : len;
-}
-
-static ssize_t sca3000_show_scale(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct sca3000_state *st = dev_info->dev_data;
-	return sprintf(buf, "%s\n", st->info->scale);
-}
-
 static ssize_t sca3000_show_name(struct device *dev,
 				 struct device_attribute *attr,
 				 char *buf)
@@ -346,18 +279,14 @@ static ssize_t sca3000_show_rev(struct device *dev,
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 
-	u8 *rx;
-
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_REVID, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1);
 	if (ret < 0)
 		goto error_ret;
 	len += sprintf(buf + len,
 		       "major=%d, minor=%d\n",
-		       rx[1] & SCA3000_REVID_MAJOR_MASK,
-		       rx[1] & SCA3000_REVID_MINOR_MASK);
-	kfree(rx);
-
+		       st->rx[0] & SCA3000_REVID_MAJOR_MASK,
+		       st->rx[0] & SCA3000_REVID_MINOR_MASK);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -410,15 +339,14 @@ sca3000_show_measurement_mode(struct device *dev,
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 	int len = 0, ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 	/* mask bottom 2 bits - only ones that are relevant */
-	rx[1] &= 0x03;
-	switch (rx[1]) {
+	st->rx[0] &= 0x03;
+	switch (st->rx[0]) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		len += sprintf(buf + len, "0 - normal mode\n");
 		break;
@@ -462,7 +390,6 @@ sca3000_store_measurement_mode(struct device *dev,
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 	int ret;
-	u8 *rx;
 	int mask = 0x03;
 	long val;
 
@@ -470,20 +397,18 @@ sca3000_store_measurement_mode(struct device *dev,
 	ret = strict_strtol(buf, 10, &val);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	rx[1] &= ~mask;
-	rx[1] |= (val & mask);
-	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, rx[1]);
+	st->rx[0] &= ~mask;
+	st->rx[0] |= (val & mask);
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, st->rx[0]);
 	if (ret)
-		goto error_free_rx;
+		goto error_ret;
 	mutex_unlock(&st->lock);
 
 	return len;
 
-error_free_rx:
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -507,16 +432,72 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
 
 static IIO_DEV_ATTR_NAME(sca3000_show_name);
 static IIO_DEV_ATTR_REV(sca3000_show_rev);
-static IIO_DEVICE_ATTR(accel_scale, S_IRUGO, sca3000_show_scale,
-		       NULL, 0);
 
-static IIO_DEV_ATTR_ACCEL_X(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_X_MSB);
-static IIO_DEV_ATTR_ACCEL_Y(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_Y_MSB);
-static IIO_DEV_ATTR_ACCEL_Z(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_Z_MSB);
+#define SCA3000_INFO_MASK			\
+	(1 << IIO_CHAN_INFO_SCALE_SHARED)
+#define SCA3000_EVENT_MASK					\
+	(IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
+
+static struct iio_chan_spec sca3000_channels[] = {
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK,
+		 0, 0, IIO_ST('s', 11, 16, 5),
+		 SCA3000_EVENT_MASK, NULL),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK,
+		 1, 1, IIO_ST('s', 11, 16, 5),
+		 SCA3000_EVENT_MASK, NULL),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK,
+		 2, 2, IIO_ST('s', 11, 16, 5),
+		 SCA3000_EVENT_MASK, NULL),
+};
 
+static u8 sca3000_addresses[3][3] = {
+	[0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH,
+	       SCA3000_MD_CTRL_OR_X},
+	[1] = {SCA3000_REG_ADDR_Y_MSB, SCA3000_REG_CTRL_SEL_MD_Y_TH,
+	       SCA3000_MD_CTRL_OR_Y},
+	[2] = {SCA3000_REG_ADDR_Z_MSB, SCA3000_REG_CTRL_SEL_MD_Z_TH,
+	       SCA3000_MD_CTRL_OR_Z},
+};
+
+static int sca3000_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long mask)
+{
+	struct sca3000_state *st = indio_dev->dev_data;
+	int ret;
+	u8 address;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&st->lock);
+		if (st->mo_det_use_count) {
+			mutex_unlock(&st->lock);
+			return -EBUSY;
+		}
+		address = sca3000_addresses[chan->address][0];
+		ret = sca3000_read_data_short(st, address, 2);
+		if (ret < 0) {
+			mutex_unlock(&st->lock);
+			return ret;
+		}
+		*val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
+		*val = ((*val) << (sizeof(*val)*8 - 13)) >>
+			(sizeof(*val)*8 - 13);
+		mutex_unlock(&st->lock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		*val = 0;
+		if (chan->type == IIO_ACCEL)
+			*val2 = st->info->scale;
+		else /* temperature */
+			*val2 = 555556;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
 
 /**
  * sca3000_read_av_freq() sysfs function to get available frequencies
@@ -532,15 +513,16 @@ static ssize_t sca3000_read_av_freq(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int len = 0, ret;
-	u8 *rx;
+	int len = 0, ret, val;
+
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto error_ret;
-	rx[1] &= 0x03;
-	switch (rx[1]) {
+
+	switch (val & 0x03) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		len += sprintf(buf + len, "%d %d %d\n",
 			       st->info->measurement_mode_freq,
@@ -560,7 +542,6 @@ static ssize_t sca3000_read_av_freq(struct device *dev,
 			       st->info->option_mode_2_freq/4);
 		break;
 	}
-	kfree(rx);
 	return len;
 error_ret:
 	return ret;
@@ -575,12 +556,11 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st,
 					  int *base_freq)
 {
 	int ret;
-	u8 *rx;
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	switch (0x03 & rx[1]) {
+	switch (0x03 & st->rx[0]) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		*base_freq = info->measurement_mode_freq;
 		break;
@@ -591,7 +571,6 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st,
 		*base_freq = info->option_mode_2_freq;
 		break;
 	}
-	kfree(rx);
 error_ret:
 	return ret;
 }
@@ -605,18 +584,19 @@ static ssize_t sca3000_read_frequency(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int ret, len = 0, base_freq = 0;
-	u8 *rx;
+	int ret, len = 0, base_freq = 0, val;
+
 	mutex_lock(&st->lock);
 	ret = __sca3000_get_base_freq(st, st->info, &base_freq);
 	if (ret)
 		goto error_ret_mut;
-	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto error_ret;
+	val = ret;
 	if (base_freq > 0)
-		switch (rx[1]&0x03) {
+		switch (val & 0x03) {
 		case 0x00:
 		case 0x03:
 			len = sprintf(buf, "%d\n", base_freq);
@@ -628,7 +608,7 @@ static ssize_t sca3000_read_frequency(struct device *dev,
 			len = sprintf(buf, "%d\n", base_freq/4);
 			break;
 	}
-	kfree(rx);
+
 	return len;
 error_ret_mut:
 	mutex_unlock(&st->lock);
@@ -647,7 +627,7 @@ static ssize_t sca3000_set_frequency(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret, base_freq = 0;
-	u8 *rx;
+	int ctrlval;
 	long val;
 
 	ret = strict_strtol(buf, 10, &val);
@@ -660,21 +640,23 @@ static ssize_t sca3000_set_frequency(struct device *dev,
 	if (ret)
 		goto error_free_lock;
 
-	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+	if (ret < 0)
 		goto error_free_lock;
+	ctrlval = ret;
 	/* clear the bits */
-	rx[1] &= ~0x03;
+	ctrlval &= ~0x03;
 
 	if (val == base_freq/2) {
-		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_2;
+		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
 	} else if (val == base_freq/4) {
-		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_4;
+		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
 	} else if (val != base_freq) {
 		ret = -EINVAL;
 		goto error_free_lock;
 	}
-	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, rx[1]);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
+				     ctrlval);
 error_free_lock:
 	mutex_unlock(&st->lock);
 
@@ -704,17 +686,14 @@ static ssize_t sca3000_read_temp(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int len = 0, ret;
+	int ret;
 	int val;
-	u8 *rx;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_TEMP_MSB, &rx, 2);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_TEMP_MSB, 2);
 	if (ret < 0)
 		goto error_ret;
-	val = ((rx[1]&0x3F) << 3) | ((rx[2] & 0xE0) >> 5);
-	len += sprintf(buf + len, "%d\n", val);
-	kfree(rx);
+	val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5);
 
-	return len;
+	return sprintf(buf, "%d\n", val);
 
 error_ret:
 	return ret;
@@ -725,80 +704,72 @@ static IIO_CONST_ATTR_TEMP_SCALE("0.555556");
 static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
 
 /**
- * sca3000_show_thresh() sysfs query of a threshold
+ * sca3000_read_thresh() - query of a threshold
  **/
-static ssize_t sca3000_show_thresh(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int sca3000_read_thresh(struct iio_dev *indio_dev,
+			       int e,
+			       int *val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	int ret, i;
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int len = 0, ret;
-	u8 *rx;
-
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 	mutex_lock(&st->lock);
-	ret = sca3000_read_ctrl_reg(st,
-				    this_attr->address,
-				    &rx);
+	ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
 	mutex_unlock(&st->lock);
-	if (ret)
+	if (ret < 0)
 		return ret;
-	len += sprintf(buf + len, "%d\n", rx[1]);
-	kfree(rx);
+	*val = 0;
+	if (num == 1)
+		for_each_set_bit(i, (unsigned long *)&ret,
+				 ARRAY_SIZE(st->info->mot_det_mult_y))
+			*val += st->info->mot_det_mult_y[i];
+	else
+		for_each_set_bit(i, (unsigned long *)&ret,
+				 ARRAY_SIZE(st->info->mot_det_mult_xz))
+			*val += st->info->mot_det_mult_xz[i];
 
-	return len;
+	return 0;
 }
 
 /**
- * sca3000_write_thresh() sysfs control of threshold
+ * sca3000_write_thresh() control of threshold
  **/
-static ssize_t sca3000_write_thresh(struct device *dev,
-				    struct device_attribute *attr,
-				    const char *buf,
-				    size_t len)
+static int sca3000_write_thresh(struct iio_dev *indio_dev,
+				    int e,
+				    int val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 	int ret;
-	long val;
+	int i;
+	u8 nonlinear = 0;
+
+	if (num == 1) {
+		i = ARRAY_SIZE(st->info->mot_det_mult_y);
+		while (i > 0)
+			if (val >= st->info->mot_det_mult_y[--i]) {
+				nonlinear |= (1 << i);
+				val -= st->info->mot_det_mult_y[i];
+			}
+	} else {
+		i = ARRAY_SIZE(st->info->mot_det_mult_xz);
+		while (i > 0)
+			if (val >= st->info->mot_det_mult_xz[--i]) {
+				nonlinear |= (1 << i);
+				val -= st->info->mot_det_mult_xz[i];
+			}
+	}
 
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
 	mutex_lock(&st->lock);
-	ret = sca3000_write_ctrl_reg(st, this_attr->address, val);
+	ret = sca3000_write_ctrl_reg(st, sca3000_addresses[num][1], nonlinear);
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 
-static IIO_DEVICE_ATTR(accel_x_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_X_TH);
-
-static IIO_DEVICE_ATTR(accel_y_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_Y_TH);
-
-static IIO_DEVICE_ATTR(accel_z_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_Z_TH);
-
 static struct attribute *sca3000_attributes[] = {
 	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
-	&iio_dev_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
@@ -809,10 +780,6 @@ static struct attribute *sca3000_attributes[] = {
 static struct attribute *sca3000_attributes_with_temp[] = {
 	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
-	&iio_dev_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
@@ -836,134 +803,102 @@ static const struct attribute_group sca3000_attribute_group_with_temp = {
 /* depending on event, push to the ring buffer event chrdev or the event one */
 
 /**
- * sca3000_interrupt_handler_bh() - handling ring and non ring events
+ * sca3000_event_handler() - handling ring and non ring events
  *
  * This function is complicated by the fact that the devices can signify ring
  * and non ring events via the same interrupt line and they can only
  * be distinguished via a read of the relevant status register.
  **/
-static void sca3000_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t sca3000_event_handler(int irq, void *private)
 {
-	struct sca3000_state *st
-		= container_of(work_s, struct sca3000_state,
-			       interrupt_handler_ws);
-	u8 *rx;
-	int ret;
+	struct iio_dev *indio_dev = private;
+	struct sca3000_state *st;
+	int ret, val;
+	s64 last_timestamp = iio_get_time_ns();
 
+	st = indio_dev->dev_data;
 	/* Could lead if badly timed to an extra read of status reg,
 	 * but ensures no interrupt is missed.
 	 */
-	enable_irq(st->us->irq);
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS,
-				&rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto done;
 
-	sca3000_ring_int_process(rx[1], st->indio_dev->ring);
+	sca3000_ring_int_process(val, st->indio_dev->ring);
 
-	if (rx[1] & SCA3000_INT_STATUS_FREE_FALL)
+	if (val & SCA3000_INT_STATUS_FREE_FALL)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X_AND_Y_AND_Z,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_FALLING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_Y_TRIGGER)
+	if (val & SCA3000_INT_STATUS_Y_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_X_TRIGGER)
+	if (val & SCA3000_INT_STATUS_X_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_Z_TRIGGER)
+	if (val & SCA3000_INT_STATUS_Z_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
 done:
-	kfree(rx);
-	return;
+	return IRQ_HANDLED;
 }
 
 /**
- * sca3000_handler_th() handles all interrupt events from device
- *
- * These devices deploy unified interrupt status registers meaning
- * all interrupts must be handled together
+ * sca3000_read_event_config() what events are enabled
  **/
-static int sca3000_handler_th(struct iio_dev *dev_info,
-			      int index,
-			      s64 timestamp,
-			      int no_test)
+static int sca3000_read_event_config(struct iio_dev *indio_dev,
+				     int e)
 {
-	struct sca3000_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->interrupt_handler_ws);
-
-	return 0;
-}
-
-/**
- * sca3000_query_mo_det() is motion detection enabled for this axis
- *
- * First queries if motion detection is enabled and then if this axis is
- * on.
- **/
-static ssize_t sca3000_query_mo_det(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int ret, len = 0;
-	u8 *rx;
+	int ret;
 	u8 protect_mask = 0x03;
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 
 	/* read current value of mode register */
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 
-	if ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET)
-		len += sprintf(buf + len, "0\n");
+	if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET)
+		ret = 0;
 	else {
-		kfree(rx);
-		ret = sca3000_read_ctrl_reg(st,
-					    SCA3000_REG_CTRL_SEL_MD_CTRL,
-					    &rx);
-		if (ret)
+		ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+		if (ret < 0)
 			goto error_ret;
 		/* only supporting logical or's for now */
-		len += sprintf(buf + len, "%d\n",
-			       (rx[1] & this_attr->mask) ? 1 : 0);
+		ret = !!(ret & sca3000_addresses[num][2]);
 	}
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 /**
  * sca3000_query_free_fall_mode() is free fall mode enabled
@@ -973,80 +908,20 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev,
 					    char *buf)
 {
 	int ret, len;
-	u8 *rx;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
+	int val;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
-	if (ret)
+	if (ret < 0)
 		return ret;
 	len = sprintf(buf, "%d\n",
-		      !!(rx[1] & SCA3000_FREE_FALL_DETECT));
-	kfree(rx);
-
+		      !!(val & SCA3000_FREE_FALL_DETECT));
 	return len;
 }
-/**
- * sca3000_query_ring_int() is the hardware ring status interrupt enabled
- **/
-static ssize_t sca3000_query_ring_int(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int ret, len;
-	u8 *rx;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
-	struct sca3000_state *st = indio_dev->dev_data;
-	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
-	mutex_unlock(&st->lock);
-	if (ret)
-		return ret;
-	len = sprintf(buf, "%d\n", (rx[1] & this_attr->mask) ? 1 : 0);
-	kfree(rx);
-
-	return len;
-}
-/**
- * sca3000_set_ring_int() set state of ring status interrupt
- **/
-static ssize_t sca3000_set_ring_int(struct device *dev,
-				      struct device_attribute *attr,
-				      const char *buf,
-				      size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
-	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-
-	long val;
-	int ret;
-	u8 *rx;
-
-	mutex_lock(&st->lock);
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
-	if (ret)
-		goto error_ret;
-	if (val)
-		ret = sca3000_write_reg(st,
-					SCA3000_REG_ADDR_INT_MASK,
-					rx[1] | this_attr->mask);
-	else
-		ret = sca3000_write_reg(st,
-					SCA3000_REG_ADDR_INT_MASK,
-					rx[1] & ~this_attr->mask);
-	kfree(rx);
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret ? ret : len;
-}
 
 /**
  * sca3000_set_free_fall_mode() simple on off control for free fall int
@@ -1065,7 +940,6 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
 	struct sca3000_state *st = indio_dev->dev_data;
 	long val;
 	int ret;
-	u8 *rx;
 	u8 protect_mask = SCA3000_FREE_FALL_DETECT;
 
 	mutex_lock(&st->lock);
@@ -1074,20 +948,18 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
 		goto error_ret;
 
 	/* read current value of mode register */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 
 	/*if off and should be on*/
-	if (val && !(rx[1] & protect_mask))
+	if (val && !(st->rx[0] & protect_mask))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] | SCA3000_FREE_FALL_DETECT));
+					(st->rx[0] | SCA3000_FREE_FALL_DETECT));
 	/* if on and should be off */
-	else if (!val && (rx[1]&protect_mask))
+	else if (!val && (st->rx[0] & protect_mask))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask));
-
-	kfree(rx);
+					(st->rx[0] & ~protect_mask));
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -1103,73 +975,65 @@ error_ret:
  * There is a complexity in knowing which mode to return to when
  * this mode is disabled.  Currently normal mode is assumed.
  **/
-static ssize_t sca3000_set_mo_det(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
+static int sca3000_write_event_config(struct iio_dev *indio_dev,
+				      int e,
+				      struct iio_event_handler_list *list_el,
+				      int state)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	long val;
-	int ret;
-	u8 *rx;
+	int ret, ctrlval;
 	u8 protect_mask = 0x03;
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 
 	mutex_lock(&st->lock);
 	/* First read the motion detector config to find out if
 	 * this axis is on*/
-	ret = sca3000_read_ctrl_reg(st,
-				    SCA3000_REG_CTRL_SEL_MD_CTRL,
-				    &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+	if (ret < 0)
 		goto exit_point;
+	ctrlval = ret;
 	/* Off and should be on */
-	if (val && !(rx[1] & this_attr->mask)) {
+	if (state && !(ctrlval & sca3000_addresses[num][2])) {
 		ret = sca3000_write_ctrl_reg(st,
 					     SCA3000_REG_CTRL_SEL_MD_CTRL,
-					     rx[1] | this_attr->mask);
+					     ctrlval |
+					     sca3000_addresses[num][2]);
 		if (ret)
-			goto exit_point_free_rx;
+			goto exit_point;
 		st->mo_det_use_count++;
-	} else if (!val && (rx[1]&this_attr->mask)) {
+	} else if (!state && (ctrlval & sca3000_addresses[num][2])) {
 		ret = sca3000_write_ctrl_reg(st,
 					     SCA3000_REG_CTRL_SEL_MD_CTRL,
-					     rx[1] & ~(this_attr->mask));
+					     ctrlval &
+					     ~(sca3000_addresses[num][2]));
 		if (ret)
-			goto exit_point_free_rx;
+			goto exit_point;
 		st->mo_det_use_count--;
-	} else /* relies on clean state for device on boot */
-		goto exit_point_free_rx;
-	kfree(rx);
+	}
+
 	/* read current value of mode register */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto exit_point;
 	/*if off and should be on*/
 	if ((st->mo_det_use_count)
-	    && ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
+	    && ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask)
+					(st->rx[0] & ~protect_mask)
 					| SCA3000_MEAS_MODE_MOT_DET);
 	/* if on and should be off */
 	else if (!(st->mo_det_use_count)
-		 && ((rx[1]&protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
+		 && ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask));
-exit_point_free_rx:
-	kfree(rx);
+					(st->rx[0] & ~protect_mask));
 exit_point:
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 
 /* Shared event handler for all events as single event status register */
-IIO_EVENT_SH(all, &sca3000_handler_th);
+IIO_EVENT_SH(all, NULL);
 
 /* Free fall detector related event attribute */
 IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en,
@@ -1179,51 +1043,13 @@ IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en,
 			sca3000_set_free_fall_mode,
 			0);
 
-IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
-		     accel_x&y&z_mag_falling_period,
-		     "0.226");
-
-/* Motion detector related event attributes */
-IIO_EVENT_ATTR_SH(accel_x_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_X);
-
-IIO_EVENT_ATTR_SH(accel_y_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_Y);
-
-IIO_EVENT_ATTR_SH(accel_z_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_Z);
-
-/* Hardware ring buffer related event attributes */
-IIO_EVENT_ATTR_RING_50_FULL_SH(iio_event_all,
-			       sca3000_query_ring_int,
-			       sca3000_set_ring_int,
-			       SCA3000_INT_MASK_RING_HALF);
-
-IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all,
-			       sca3000_query_ring_int,
-			       sca3000_set_ring_int,
-			       SCA3000_INT_MASK_RING_THREE_QUARTER);
+static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
+			    accel_x&y&z_mag_falling_period,
+			    "0.226");
 
 static struct attribute *sca3000_event_attributes[] = {
 	&iio_event_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
 	&iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
-	&iio_event_attr_accel_x_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_accel_y_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_accel_z_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_ring_50_full.dev_attr.attr,
-	&iio_event_attr_ring_75_full.dev_attr.attr,
 	NULL,
 };
 
@@ -1241,70 +1067,50 @@ static struct attribute_group sca3000_event_attribute_group = {
 static int sca3000_clean_setup(struct sca3000_state *st)
 {
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
 	/* Ensure all interrupts have been acknowledged */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
 	if (ret)
 		goto error_ret;
-	kfree(rx);
 
 	/* Turn off all motion detection channels */
-	ret = sca3000_read_ctrl_reg(st,
-				    SCA3000_REG_CTRL_SEL_MD_CTRL,
-				    &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+	if (ret < 0)
 		goto error_ret;
-	ret = sca3000_write_ctrl_reg(st,
-				     SCA3000_REG_CTRL_SEL_MD_CTRL,
-				     rx[1] & SCA3000_MD_CTRL_PROT_MASK);
-	kfree(rx);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL,
+				     ret & SCA3000_MD_CTRL_PROT_MASK);
 	if (ret)
 		goto error_ret;
 
 	/* Disable ring buffer */
-	sca3000_read_ctrl_reg(st,
-			      SCA3000_REG_CTRL_SEL_OUT_CTRL,
-			      &rx);
-	/* Frequency of ring buffer sampling deliberately restricted to make
-	 * debugging easier - add control of this later */
-	ret = sca3000_write_ctrl_reg(st,
-				     SCA3000_REG_CTRL_SEL_OUT_CTRL,
-				     (rx[1] & SCA3000_OUT_CTRL_PROT_MASK)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
+				     (ret & SCA3000_OUT_CTRL_PROT_MASK)
 				     | SCA3000_OUT_CTRL_BUF_X_EN
 				     | SCA3000_OUT_CTRL_BUF_Y_EN
 				     | SCA3000_OUT_CTRL_BUF_Z_EN
 				     | SCA3000_OUT_CTRL_BUF_DIV_4);
-	kfree(rx);
-
 	if (ret)
 		goto error_ret;
 	/* Enable interrupts, relevant to mode and set up as active low */
-	ret = sca3000_read_data(st,
-			  SCA3000_REG_ADDR_INT_MASK,
-			  &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
 	if (ret)
 		goto error_ret;
 	ret = sca3000_write_reg(st,
 				SCA3000_REG_ADDR_INT_MASK,
-				(rx[1] & SCA3000_INT_MASK_PROT_MASK)
+				(ret & SCA3000_INT_MASK_PROT_MASK)
 				| SCA3000_INT_MASK_ACTIVE_LOW);
-	kfree(rx);
 	if (ret)
 		goto error_ret;
 	/* Select normal measurement mode, free fall off, ring off */
 	/* Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
 	 * as that occurs in one of the example on the datasheet */
-	ret = sca3000_read_data(st,
-			  SCA3000_REG_ADDR_MODE,
-			  &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_write_reg(st,
-				SCA3000_REG_ADDR_MODE,
-				(rx[1] & SCA3000_MODE_PROT_MASK));
-	kfree(rx);
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+				(st->rx[0] & SCA3000_MODE_PROT_MASK));
 	st->bpse = 11;
 
 error_ret:
@@ -1312,8 +1118,7 @@ error_ret:
 	return ret;
 }
 
-static int __devinit __sca3000_probe(struct spi_device *spi,
-				     enum sca3000_variant variant)
+static int __devinit sca3000_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
 	struct sca3000_state *st;
@@ -1325,75 +1130,63 @@ static int __devinit __sca3000_probe(struct spi_device *spi,
 	}
 	spi_set_drvdata(spi, st);
 
-	st->tx = kmalloc(sizeof(*st->tx)*6, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_clear_st;
-	}
-	st->rx = kmalloc(sizeof(*st->rx)*3, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 	st->us = spi;
 	mutex_init(&st->lock);
-	st->info = &sca3000_spi_chip_info_tbl[variant];
+	st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi)
+					      ->driver_data];
 
 	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
-		goto error_free_rx;
+		goto error_clear_st;
 	}
-
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->num_interrupt_lines = 1;
 	st->indio_dev->event_attrs = &sca3000_event_attribute_group;
 	if (st->info->temp_output)
 		st->indio_dev->attrs = &sca3000_attribute_group_with_temp;
-	else
+	else {
 		st->indio_dev->attrs = &sca3000_attribute_group;
+		st->indio_dev->channels = sca3000_channels;
+		st->indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
+	}
+	st->indio_dev->read_raw = &sca3000_read_raw;
+	st->indio_dev->read_event_value = &sca3000_read_thresh;
+	st->indio_dev->write_event_value = &sca3000_write_thresh;
+	st->indio_dev->read_event_config = &sca3000_read_event_config;
+	st->indio_dev->write_event_config = &sca3000_write_event_config;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	sca3000_configure_ring(st->indio_dev);
-
 	ret = iio_device_register(st->indio_dev);
 	if (ret < 0)
 		goto error_free_dev;
 	regdone = 1;
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  sca3000_channels,
+					  ARRAY_SIZE(sca3000_channels));
 	if (ret < 0)
 		goto error_unregister_dev;
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		INIT_WORK(&st->interrupt_handler_ws,
-			  sca3000_interrupt_handler_bh);
-		ret = iio_register_interrupt_line(spi->irq,
-						  st->indio_dev,
-						  0,
-						  IRQF_TRIGGER_FALLING,
-						  "sca3000");
+		ret = request_threaded_irq(spi->irq,
+					   NULL,
+					   &sca3000_event_handler,
+					   IRQF_TRIGGER_FALLING,
+					   "sca3000",
+					   st->indio_dev);
 		if (ret)
 			goto error_unregister_ring;
-		/* RFC
-		 * Probably a common situation.  All interrupts need an ack
-		 * and there is only one handler so the complicated list system
-		 * is overkill.  At very least a simpler registration method
-		 * might be worthwhile.
-		 */
-		iio_add_event_to_list(
-			iio_event_attr_accel_z_mag_rising_en.listel,
-			&st->indio_dev
-			->interrupts[0]->ev_list);
 	}
 	sca3000_register_ring_funcs(st->indio_dev);
 	ret = sca3000_clean_setup(st);
 	if (ret)
-		goto error_unregister_interrupt_line;
+		goto error_free_irq;
 	return 0;
 
-error_unregister_interrupt_line:
+error_free_irq:
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+		free_irq(spi->irq, st->indio_dev);
 error_unregister_ring:
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unregister_dev:
@@ -1402,10 +1195,6 @@ error_free_dev:
 		iio_device_unregister(st->indio_dev);
 	else
 		iio_free_device(st->indio_dev);
-error_free_rx:
-	kfree(st->rx);
-error_free_tx:
-	kfree(st->tx);
 error_clear_st:
 	kfree(st);
 error_ret:
@@ -1415,20 +1204,19 @@ error_ret:
 static int sca3000_stop_all_interrupts(struct sca3000_state *st)
 {
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
 	if (ret)
 		goto error_ret;
 	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK,
-				(rx[1] & ~(SCA3000_INT_MASK_RING_THREE_QUARTER
-					   | SCA3000_INT_MASK_RING_HALF
-					   | SCA3000_INT_MASK_ALL_INTS)));
+				(st->rx[0] &
+				 ~(SCA3000_INT_MASK_RING_THREE_QUARTER |
+				   SCA3000_INT_MASK_RING_HALF |
+				   SCA3000_INT_MASK_ALL_INTS)));
 error_ret:
-	kfree(rx);
+	mutex_unlock(&st->lock);
 	return ret;
-
 }
 
 static int sca3000_remove(struct spi_device *spi)
@@ -1441,87 +1229,44 @@ static int sca3000_remove(struct spi_device *spi)
 	if (ret)
 		return ret;
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi->irq, indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	sca3000_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
 
-	kfree(st->tx);
-	kfree(st->rx);
 	kfree(st);
 
 	return 0;
 }
 
-/* These macros save on an awful lot of repeated code */
-#define SCA3000_VARIANT_PROBE(_name)				\
-	static int __devinit					\
-	sca3000_##_name##_probe(struct spi_device *spi)		\
-	{							\
-		return __sca3000_probe(spi, _name);		\
-	}
-
-#define SCA3000_VARIANT_SPI_DRIVER(_name)			\
-	struct spi_driver sca3000_##_name##_driver = {		\
-		.driver = {					\
-			.name = "sca3000_" #_name,		\
-			.owner = THIS_MODULE,			\
-		},						\
-		.probe = sca3000_##_name##_probe,		\
-		.remove = __devexit_p(sca3000_remove),		\
-	}
-
-SCA3000_VARIANT_PROBE(d01);
-static SCA3000_VARIANT_SPI_DRIVER(d01);
-
-SCA3000_VARIANT_PROBE(e02);
-static SCA3000_VARIANT_SPI_DRIVER(e02);
-
-SCA3000_VARIANT_PROBE(e04);
-static SCA3000_VARIANT_SPI_DRIVER(e04);
+static const struct spi_device_id sca3000_id[] = {
+	{"sca3000_d01", d01},
+	{"sca3000_e02", e02},
+	{"sca3000_e04", e04},
+	{"sca3000_e05", e05},
+	{}
+};
 
-SCA3000_VARIANT_PROBE(e05);
-static SCA3000_VARIANT_SPI_DRIVER(e05);
+static struct spi_driver sca3000_driver = {
+	.driver = {
+		.name = "sca3000",
+		.owner = THIS_MODULE,
+	},
+	.probe = sca3000_probe,
+	.remove = __devexit_p(sca3000_remove),
+	.id_table = sca3000_id,
+};
 
 static __init int sca3000_init(void)
 {
-	int ret;
-
-	ret = spi_register_driver(&sca3000_d01_driver);
-	if (ret)
-		goto error_ret;
-	ret = spi_register_driver(&sca3000_e02_driver);
-	if (ret)
-		goto error_unreg_d01;
-	ret = spi_register_driver(&sca3000_e04_driver);
-	if (ret)
-		goto error_unreg_e02;
-	ret = spi_register_driver(&sca3000_e05_driver);
-	if (ret)
-		goto error_unreg_e04;
-
-	return 0;
-
-error_unreg_e04:
-	spi_unregister_driver(&sca3000_e04_driver);
-error_unreg_e02:
-	spi_unregister_driver(&sca3000_e02_driver);
-error_unreg_d01:
-	spi_unregister_driver(&sca3000_d01_driver);
-error_ret:
-
-	return ret;
+	return spi_register_driver(&sca3000_driver);
 }
+module_init(sca3000_init);
 
 static __exit void sca3000_exit(void)
 {
-	spi_unregister_driver(&sca3000_e05_driver);
-	spi_unregister_driver(&sca3000_e04_driver);
-	spi_unregister_driver(&sca3000_e02_driver);
-	spi_unregister_driver(&sca3000_d01_driver);
+	spi_unregister_driver(&sca3000_driver);
 }
-
-module_init(sca3000_init);
 module_exit(sca3000_exit);
 
 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 44f9a56..8efd4f0 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -17,6 +17,8 @@
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -34,6 +36,44 @@
  * Currently scan elements aren't configured so it doesn't matter.
  */
 
+static int sca3000_read_data(struct sca3000_state *st,
+			    uint8_t reg_address_high,
+			    u8 **rx_p,
+			    int len)
+{
+	int ret;
+	struct spi_message msg;
+	struct spi_transfer xfer[2] = {
+		{
+			.len = 1,
+			.tx_buf = st->tx,
+		}, {
+			.len = len,
+		}
+	};
+	*rx_p = kmalloc(len, GFP_KERNEL);
+	if (*rx_p == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	xfer[1].rx_buf = *rx_p;
+	st->tx[0] = SCA3000_READ_REG(reg_address_high);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(get_device(&st->us->dev), "problem reading register");
+		goto error_free_rx;
+	}
+
+	return 0;
+error_free_rx:
+	kfree(*rx_p);
+error_ret:
+	return ret;
+}
+
 /**
  * sca3000_read_first_n_hw_rb() - main ring access, pulls data from ring
  * @r:			the ring
@@ -45,8 +85,6 @@
  * Currently does not provide timestamps.  As the hardware doesn't add them they
  * can only be inferred approximately from ring buffer events such as 50% full
  * and knowledge of when buffer was last emptied.  This is left to userspace.
- *
- * Temporarily deliberately broken.
  **/
 static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
 				      size_t count, char __user *buf,
@@ -56,54 +94,45 @@ static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
 	struct iio_dev *indio_dev = hw_ring->private;
 	struct sca3000_state *st = indio_dev->dev_data;
 	u8 *rx;
-	s16 *samples;
 	int ret, i, num_available, num_read = 0;
 	int bytes_per_sample = 1;
-	u8 *datas;
-	u8 **data = &datas;
 
 	if (st->bpse == 11)
 		bytes_per_sample = 2;
 
 	mutex_lock(&st->lock);
-	/* Check how much data is available:
-	 * RFC: Implement an ioctl to not bother checking whether there
-	 * is enough data in the ring?  Afterall, if we are responding
-	 * to an interrupt we have a minimum content guaranteed so it
-	 * seems slight silly to waste time checking it is there.
-	 */
-	ret = sca3000_read_data(st,
-				SCA3000_REG_ADDR_BUF_COUNT,
-				&rx, 1);
+	if (count % bytes_per_sample) {
+		ret = -EINVAL;
+		goto error_ret;
+	}
+
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_BUF_COUNT, 1);
 	if (ret)
 		goto error_ret;
 	else
-		num_available = rx[1];
-	/* num_available is the total number of samples available
+		num_available = st->rx[0];
+	/*
+	 * num_available is the total number of samples available
 	 * i.e. number of time points * number of channels.
 	 */
-	kfree(rx);
 	if (count > num_available * bytes_per_sample)
 		num_read = num_available*bytes_per_sample;
 	else
-		num_read = count - (count % (bytes_per_sample));
+		num_read = count;
 
-	/* Avoid the read request byte */
-	*dead_offset = 1;
 	ret = sca3000_read_data(st,
 				SCA3000_REG_ADDR_RING_OUT,
-				data, num_read);
-
-	/* Convert byte order and shift to default resolution */
-	if (st->bpse == 11) {
-		samples = (s16*)(*data+1);
-		for (i = 0; i < (num_read/2); i++) {
-			samples[i] = be16_to_cpup(
-					(__be16 *)&(samples[i]));
-			samples[i] >>= 3;
-		}
-	}
+				&rx, num_read);
+	if (ret)
+		goto error_ret;
+
+	for (i = 0; i < num_read; i++)
+		*(((u16 *)rx) + i) = be16_to_cpup((u16 *)rx + i);
 
+	if (copy_to_user(buf, rx, num_read))
+		ret = -EFAULT;
+	kfree(rx);
+	r->stufftoread = 0;
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -132,6 +161,76 @@ static IIO_RING_BYTES_PER_DATUM_ATTR;
 static IIO_RING_LENGTH_ATTR;
 
 /**
+ * sca3000_query_ring_int() is the hardware ring status interrupt enabled
+ **/
+static ssize_t sca3000_query_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret, val;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
+	val = st->rx[0];
+	mutex_unlock(&st->lock);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", !!(val & this_attr->address));
+}
+
+/**
+ * sca3000_set_ring_int() set state of ring status interrupt
+ **/
+static ssize_t sca3000_set_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	long val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
+	if (ret)
+		goto error_ret;
+	if (val)
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					st->rx[0] | this_attr->address);
+	else
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					st->rx[0] & ~this_attr->address);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(50_percent, S_IRUGO | S_IWUSR,
+		       sca3000_query_ring_int,
+		       sca3000_set_ring_int,
+		       SCA3000_INT_MASK_RING_HALF);
+
+static IIO_DEVICE_ATTR(75_percent, S_IRUGO | S_IWUSR,
+		       sca3000_query_ring_int,
+		       sca3000_set_ring_int,
+		       SCA3000_INT_MASK_RING_THREE_QUARTER);
+
+
+/**
  * sca3000_show_ring_bpse() -sysfs function to query bits per sample from ring
  * @dev: ring buffer device
  * @attr: this device attribute
@@ -142,20 +241,18 @@ static ssize_t sca3000_show_ring_bpse(struct device *dev,
 				      char *buf)
 {
 	int len = 0, ret;
-	u8 *rx;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 	struct iio_dev *indio_dev = ring->indio_dev;
 	struct sca3000_state *st = indio_dev->dev_data;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	if (rx[1] & SCA3000_RING_BUF_8BIT)
+	if (st->rx[0] & SCA3000_RING_BUF_8BIT)
 		len = sprintf(buf, "s8/8\n");
 	else
 		len = sprintf(buf, "s11/16\n");
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -178,20 +275,19 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev,
 	struct iio_dev *indio_dev = ring->indio_dev;
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	if (strncmp(buf, "s8/8", 4) == 0) {
+	if (sysfs_streq(buf, "s8/8")) {
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					rx[1] | SCA3000_RING_BUF_8BIT);
+					st->rx[0] | SCA3000_RING_BUF_8BIT);
 		st->bpse = 8;
-	} else if (strncmp(buf, "s11/16", 5) == 0) {
+	} else if (sysfs_streq(buf, "s11/16")) {
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					rx[1] & ~SCA3000_RING_BUF_8BIT);
+					st->rx[0] & ~SCA3000_RING_BUF_8BIT);
 		st->bpse = 11;
 	} else
 		ret = -EINVAL;
@@ -201,32 +297,22 @@ error_ret:
 	return ret ? ret : len;
 }
 
-static IIO_SCAN_EL_C(accel_x, 0, 0, NULL);
-static IIO_SCAN_EL_C(accel_y, 1, 0, NULL);
-static IIO_SCAN_EL_C(accel_z, 2, 0, NULL);
-static IIO_CONST_ATTR(accel_type_available, "s8/8 s11/16");
-static IIO_DEVICE_ATTR(accel_type,
-		       S_IRUGO | S_IWUSR,
-		       sca3000_show_ring_bpse,
-		       sca3000_store_ring_bpse,
-		       0);
+static ssize_t sca3000_show_buffer_scale(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
 
-static struct attribute *sca3000_scan_el_attrs[] = {
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type_available.dev_attr.attr,
-	&iio_dev_attr_accel_type.dev_attr.attr,
-	NULL
-};
+	return sprintf(buf, "0.%06d\n", 4*st->info->scale);
+}
 
-static struct attribute_group sca3000_scan_el_group = {
-	.attrs = sca3000_scan_el_attrs,
-	.name = "scan_elements",
-};
+static IIO_DEVICE_ATTR(accel_scale,
+		       S_IRUGO,
+		       sca3000_show_buffer_scale,
+		       NULL,
+		       0);
 
 /*
  * Ring buffer attributes
@@ -238,6 +324,9 @@ static struct attribute *sca3000_ring_attributes[] = {
 	&dev_attr_length.attr,
 	&dev_attr_bytes_per_datum.attr,
 	&dev_attr_enable.attr,
+	&iio_dev_attr_50_percent.dev_attr.attr,
+	&iio_dev_attr_75_percent.dev_attr.attr,
+	&iio_dev_attr_accel_scale.dev_attr.attr,
 	NULL,
 };
 
@@ -263,11 +352,12 @@ static struct iio_ring_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
 	ring = kzalloc(sizeof *ring, GFP_KERNEL);
 	if (!ring)
 		return NULL;
+
 	ring->private = indio_dev;
 	buf = &ring->buf;
+	buf->stufftoread = 0;
 	iio_ring_buffer_init(buf, indio_dev);
 	buf->dev.type = &sca3000_ring_type;
-	device_initialize(&buf->dev);
 	buf->dev.parent = &indio_dev->dev;
 	dev_set_drvdata(&buf->dev, (void *)buf);
 
@@ -287,10 +377,14 @@ int sca3000_configure_ring(struct iio_dev *indio_dev)
 		return -ENOMEM;
 	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
 
-	indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
 	indio_dev->ring->access.read_first_n = &sca3000_read_first_n_hw_rb;
 	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
-	indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
+	indio_dev->ring->access.get_bytes_per_datum =
+		&sca3000_ring_get_bytes_per_datum;
+
+	iio_scan_mask_set(indio_dev->ring, 0);
+	iio_scan_mask_set(indio_dev->ring, 1);
+	iio_scan_mask_set(indio_dev->ring, 2);
 
 	return 0;
 }
@@ -305,22 +399,20 @@ int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state)
 {
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 	if (state) {
 		printk(KERN_INFO "supposedly enabling ring buffer\n");
 		ret = sca3000_write_reg(st,
 					SCA3000_REG_ADDR_MODE,
-					(rx[1] | SCA3000_RING_BUF_ENABLE));
+					(st->rx[0] | SCA3000_RING_BUF_ENABLE));
 	} else
 		ret = sca3000_write_reg(st,
 					SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~SCA3000_RING_BUF_ENABLE));
-	kfree(rx);
+					(st->rx[0] & ~SCA3000_RING_BUF_ENABLE));
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -357,13 +449,9 @@ void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
  **/
 void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
 {
-	/*
-	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
-		iio_push_ring_event(ring,
-				    IIO_EVENT_CODE_RING_75_FULL,
-				    0);
-	else if (val & SCA3000_INT_STATUS_HALF)
-		iio_push_ring_event(ring,
-				    IIO_EVENT_CODE_RING_50_FULL, 0);
-	*/
+	if (val & (SCA3000_INT_STATUS_THREE_QUARTERS |
+		   SCA3000_INT_STATUS_HALF)) {
+		ring->stufftoread = true;
+		wake_up_interruptible(&ring->pollq);
+	}
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 012/111] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (10 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 011/111] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 013/111] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
                   ` (99 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This element has been usused by the core for quite some time.  sca3000 set it none the less
until the rewrite in the previous patch (and hence didn't work).

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/sca3000_ring.c |    5 +----
 drivers/staging/iio/industrialio-ring.c  |    4 ++--
 drivers/staging/iio/kfifo_buf.c          |    3 +--
 drivers/staging/iio/kfifo_buf.h          |    3 +--
 drivers/staging/iio/ring_generic.h       |    3 +--
 drivers/staging/iio/ring_sw.c            |   15 +++++++--------
 drivers/staging/iio/ring_sw.h            |    4 +---
 7 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 8efd4f0..d3c3789 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -79,16 +79,13 @@ error_ret:
  * @r:			the ring
  * @count:		number of samples to try and pull
  * @data:		output the actual samples pulled from the hw ring
- * @dead_offset:	cheating a bit here: Set to 1 so as to allow for the
- *			leading byte used in bus comms.
  *
  * Currently does not provide timestamps.  As the hardware doesn't add them they
  * can only be inferred approximately from ring buffer events such as 50% full
  * and knowledge of when buffer was last emptied.  This is left to userspace.
  **/
 static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
-				      size_t count, char __user *buf,
-				      int *dead_offset)
+				      size_t count, char __user *buf)
 {
 	struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r);
 	struct iio_dev *indio_dev = hw_ring->private;
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 625263e..4497a50 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -71,12 +71,12 @@ static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
 				  size_t n, loff_t *f_ps)
 {
 	struct iio_ring_buffer *rb = filp->private_data;
-	int ret, dead_offset;
+	int ret;
 
 	/* rip lots must exist. */
 	if (!rb->access.read_first_n)
 		return -EINVAL;
-	ret = rb->access.read_first_n(rb, n, buf, &dead_offset);
+	ret = rb->access.read_first_n(rb, n, buf);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index 74c93f7..fdd5d9e 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -182,12 +182,11 @@ int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
 EXPORT_SYMBOL(iio_store_to_kfifo);
 
 int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
-			   size_t n, char __user *buf, int *deadoffset)
+			   size_t n, char __user *buf)
 {
 	int ret, copied;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
 
-	*deadoffset = 0;
 	ret = kfifo_to_user(&kf->kf, buf, r->bytes_per_datum*n, &copied);
 
 	return copied;
diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h
index 457010d..eb337a4 100644
--- a/drivers/staging/iio/kfifo_buf.h
+++ b/drivers/staging/iio/kfifo_buf.h
@@ -23,8 +23,7 @@ void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r);
 int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
 int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
 			   size_t n,
-			   char __user *buf,
-			   int *dead_offset);
+			   char __user *buf);
 
 int iio_request_update_kfifo(struct iio_ring_buffer *r);
 int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r);
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 91f1037..671e9fd 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -50,8 +50,7 @@ struct iio_ring_access_funcs {
 	int (*read_last)(struct iio_ring_buffer *ring, u8 *data);
 	int (*read_first_n)(struct iio_ring_buffer *ring,
 			    size_t n,
-			    char __user *buf,
-			    int *dead_offset);
+			    char __user *buf);
 
 	int (*mark_param_change)(struct iio_ring_buffer *ring);
 	int (*request_update)(struct iio_ring_buffer *ring);
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 5fbf5ff..40beadd 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -139,14 +139,13 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 }
 
 int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
-			   size_t n, char __user *buf, int *dead_offset)
+			   size_t n, char __user *buf)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
 	u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
 	u8 *data;
-	int ret, max_copied;
-	int bytes_to_rip;
+	int ret, max_copied, bytes_to_rip, dead_offset;
 
 	/* A userspace program has probably made an error if it tries to
 	 *  read something that is not a whole number of bpds.
@@ -227,9 +226,9 @@ int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
 	current_read_p = ring->read_p;
 
 	if (initial_read_p <= current_read_p)
-		*dead_offset = current_read_p - initial_read_p;
+		dead_offset = current_read_p - initial_read_p;
 	else
-		*dead_offset = ring->buf.length*ring->buf.bytes_per_datum
+		dead_offset = ring->buf.length*ring->buf.bytes_per_datum
 			- (initial_read_p - current_read_p);
 
 	/* possible issue if the initial write has been lapped or indeed
@@ -237,7 +236,7 @@ int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
 	/* No valid data read.
 	 * In this case the read pointer is already correct having been
 	 * pushed further than we would look. */
-	if (max_copied - *dead_offset < 0) {
+	if (max_copied - dead_offset < 0) {
 		ret = 0;
 		goto error_free_data_cpy;
 	}
@@ -253,9 +252,9 @@ int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
 	while (ring->read_p != end_read_p)
 		ring->read_p = end_read_p;
 
-	ret = max_copied - *dead_offset;
+	ret = max_copied - dead_offset;
 
-	if (copy_to_user(buf, data + *dead_offset, ret))  {
+	if (copy_to_user(buf, data + dead_offset, ret))  {
 		ret =  -EFAULT;
 		goto error_free_data_cpy;
 	}
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index ee86020..7d56524 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -97,13 +97,11 @@ int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
  * @r:			ring buffer instance
  * @n:			number of datum's to try and read
  * @buf:		userspace buffer into which data is copied
- * @dead_offset:	how much of the stored data was possibly invalidated by
  *			the end of the copy.
  **/
 int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
 			   size_t n,
-			   char __user *buf,
-			   int *dead_offset);
+			   char __user *buf);
 
 /**
  * iio_request_update_sw_rb() - update params if update needed
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 013/111] staging:iio:light:tsl2563 remove old style event registration.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (11 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 012/111] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 014/111] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
                   ` (98 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/light/tsl2563.c |   62 +++++++++++------------------------
 1 files changed, 19 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 19b7215..d613086 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -117,8 +117,6 @@ struct tsl2563_chip {
 	struct i2c_client	*client;
 	struct delayed_work	poweroff_work;
 
-	struct work_struct	work_thresh;
-	s64			event_timestamp;
 	/* Remember state for suspend and resume functions */
 	pm_message_t		state;
 
@@ -677,38 +675,22 @@ static IIO_DEVICE_ATTR(intensity0_both_raw_thresh_falling_value,
 		tsl2563_write_thresh,
 		TSL2563_REG_LOWLOW);
 
-static int tsl2563_int_th(struct iio_dev *dev_info,
-			int index,
-			s64 timestamp,
-			int not_test)
+static irqreturn_t tsl2563_event_handler(int irq, void *private)
 {
+	struct iio_dev *dev_info = private;
 	struct tsl2563_chip *chip = iio_priv(dev_info);
-
-	chip->event_timestamp = timestamp;
-	schedule_work(&chip->work_thresh);
-
-	return 0;
-}
-
-static void tsl2563_int_bh(struct work_struct *work_s)
-{
-	struct tsl2563_chip *chip
-		= container_of(work_s,
-			struct tsl2563_chip, work_thresh);
 	u8 cmd = TSL2563_CMD | TSL2563_CLEARINT;
 
-	iio_push_event(iio_priv_to_dev(chip), 0,
+	iio_push_event(dev_info, 0,
 		       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_LIGHT,
 					    0,
 					    IIO_EV_TYPE_THRESH,
 					    IIO_EV_DIR_EITHER),
-		       chip->event_timestamp);
+		       iio_get_time_ns());
 
-	/* reenable_irq */
-	enable_irq(chip->client->irq);
 	/* clear the interrupt and push the event */
 	i2c_master_send(chip->client, &cmd, sizeof(cmd));
-
+	return IRQ_HANDLED;
 }
 
 static ssize_t tsl2563_write_interrupt_config(struct device *dev,
@@ -718,7 +700,6 @@ static ssize_t tsl2563_write_interrupt_config(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct tsl2563_chip *chip = iio_priv(indio_dev);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
 	int input, ret = 0;
 
 	ret = sscanf(buf, "%d", &input);
@@ -726,8 +707,6 @@ static ssize_t tsl2563_write_interrupt_config(struct device *dev,
 		return -EINVAL;
 	mutex_lock(&chip->lock);
 	if (input && !(chip->intr & 0x30)) {
-		iio_add_event_to_list(this_attr->listel,
-				&indio_dev->interrupts[0]->ev_list);
 		chip->intr &= ~0x30;
 		chip->intr |= 0x10;
 		/* ensure the chip is actually on */
@@ -747,8 +726,6 @@ static ssize_t tsl2563_write_interrupt_config(struct device *dev,
 	if (!input && (chip->intr & 0x30)) {
 		chip->intr |= ~0x30;
 		ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
-		iio_remove_event_from_list(this_attr->listel,
-					&indio_dev->interrupts[0]->ev_list);
 		chip->int_enabled = false;
 		/* now the interrupt is not enabled, we can go to sleep */
 		schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
@@ -781,15 +758,14 @@ error_ret:
 
 	return (ret < 0) ? ret : len;
 }
-
-IIO_EVENT_ATTR(intensity0_both_thresh_en,
-	tsl2563_read_interrupt_config,
-	tsl2563_write_interrupt_config,
-	0,
-	tsl2563_int_th);
+static IIO_DEVICE_ATTR(intensity0_both_thresh_en,
+		       S_IRUGO | S_IWUSR,
+		       tsl2563_read_interrupt_config,
+		       tsl2563_write_interrupt_config,
+		       0);
 
 static struct attribute *tsl2563_event_attributes[] = {
-	&iio_event_attr_intensity0_both_thresh_en.dev_attr.attr,
+	&iio_dev_attr_intensity0_both_thresh_en.dev_attr.attr,
 	&iio_dev_attr_intensity0_both_raw_thresh_rising_value.dev_attr.attr,
 	&iio_dev_attr_intensity0_both_raw_thresh_falling_value.dev_attr.attr,
 	NULL,
@@ -820,7 +796,6 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 
 	chip = iio_priv(indio_dev);
 
-	INIT_WORK(&chip->work_thresh, tsl2563_int_bh);
 	i2c_set_clientdata(client, chip);
 	chip->client = client;
 
@@ -865,11 +840,12 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 		goto fail1;
 
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-						indio_dev,
-						0,
-						IRQF_TRIGGER_RISING,
-						client->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &tsl2563_event_handler,
+					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					   "tsl2563_event",
+					   indio_dev);
 		if (ret)
 			goto fail2;
 	}
@@ -884,7 +860,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 	return 0;
 fail3:
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 fail2:
 	iio_device_unregister(indio_dev);
 fail1:
@@ -904,7 +880,7 @@ static int tsl2563_remove(struct i2c_client *client)
 	flush_scheduled_work();
 	tsl2563_set_power(chip, 0);
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 
 	return 0;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 014/111] staging:iio:dac:ad5504 move from old to new event handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (12 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 013/111] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 015/111] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
                   ` (97 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested, but fairly trivial change here.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/dac/ad5504.c |   53 +++++++++++--------------------------
 drivers/staging/iio/dac/ad5504.h |    4 ---
 2 files changed, 16 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
index 28ace30..5534c41 100644
--- a/drivers/staging/iio/dac/ad5504.c
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -261,35 +261,18 @@ static struct attribute_group ad5504_ev_attribute_group = {
 	.attrs = ad5504_ev_attributes,
 };
 
-static void ad5504_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad5504_event_handler(int irq, void *private)
 {
-	struct ad5504_state *st = container_of(work_s,
-		struct ad5504_state, work_alarm);
-
-	iio_push_event(st->indio_dev, 0,
-			IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP,
-			0,
-			IIO_EV_TYPE_THRESH,
-			IIO_EV_DIR_RISING),
-			st->last_timestamp);
-
-	enable_irq(st->spi->irq);
-}
-
-static int ad5504_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad5504_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_alarm);
-	return 0;
+	iio_push_event(private, 0,
+		       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP,
+					    0,
+					    IIO_EV_TYPE_THRESH,
+					    IIO_EV_DIR_RISING),
+		       iio_get_time_ns());
+
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad5504, &ad5504_interrupt);
-
 static int __devinit ad5504_probe(struct spi_device *spi)
 {
 	struct ad5504_platform_data *pdata = spi->dev.platform_data;
@@ -342,18 +325,14 @@ static int __devinit ad5504_probe(struct spi_device *spi)
 		goto error_free_dev;
 
 	if (spi->irq) {
-		INIT_WORK(&st->work_alarm, ad5504_interrupt_bh);
-
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				spi_get_device_id(st->spi)->name);
+		ret = request_threaded_irq(spi->irq,
+					   NULL,
+					   &ad5504_event_handler,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   spi_get_device_id(st->spi)->name,
+					   st->indio_dev);
 		if (ret)
 			goto error_unreg_iio_device;
-
-		iio_add_event_to_list(&iio_event_ad5504,
-				&st->indio_dev->interrupts[0]->ev_list);
 	}
 
 	return 0;
@@ -379,7 +358,7 @@ static int __devexit ad5504_remove(struct spi_device *spi)
 	struct ad5504_state *st = spi_get_drvdata(spi);
 
 	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+		free_irq(spi->irq, st->indio_dev);
 
 	iio_device_unregister(st->indio_dev);
 
diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h
index d2fac63..13ef353 100644
--- a/drivers/staging/iio/dac/ad5504.h
+++ b/drivers/staging/iio/dac/ad5504.h
@@ -45,8 +45,6 @@ struct ad5504_platform_data {
  * @us:			spi_device
  * @reg:		supply regulator
  * @vref_mv:		actual reference voltage used
- * @work_alarm:		bh work structure for event handling
- * @last_timestamp:	timestamp of last event interrupt
  * @pwr_down_mask	power down mask
  * @pwr_down_mode	current power down mode
  */
@@ -56,8 +54,6 @@ struct ad5504_state {
 	struct spi_device		*spi;
 	struct regulator		*reg;
 	unsigned short			vref_mv;
-	struct work_struct		work_alarm;
-	s64				last_timestamp;
 	unsigned			pwr_down_mask;
 	unsigned			pwr_down_mode;
 };
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 015/111] staging:iio:adt7316 get rid of legacy event handling code.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (13 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 014/111] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 016/111] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
                   ` (96 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Note this driver is still a long way from being abi compliant.
What I have done here cleans up a few corners, but primarily gets
it away from using the infrastructure that is going away.

Untested

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/addac/adt7316.c |  366 +++++++++-------------------------
 1 files changed, 97 insertions(+), 269 deletions(-)

diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index d01cb4c..7174e7b 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -176,8 +176,6 @@
 struct adt7316_chip_info {
 	const char		*name;
 	struct iio_dev		*indio_dev;
-	struct work_struct	thresh_work;
-	s64			last_timestamp;
 	struct adt7316_bus	bus;
 	u16			ldac_pin;
 	u16			int_mask;	/* 0x2f */
@@ -1795,10 +1793,10 @@ static const struct attribute_group adt7516_attribute_group = {
 #define IIO_EVENT_CODE_ADT7516_AIN4           IIO_BUFFER_EVENT_CODE(8)
 #define IIO_EVENT_CODE_ADT7316_VDD            IIO_BUFFER_EVENT_CODE(9)
 
-static void adt7316_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7316_event_handler(int irq, void *private)
 {
-	struct adt7316_chip_info *chip =
-		container_of(work_s, struct adt7316_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7316_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 stat1, stat2;
 	int i, ret, count;
 
@@ -1813,7 +1811,7 @@ static void adt7316_interrupt_bh(struct work_struct *work_s)
 			if (stat1 & (1 << i))
 				iio_push_event(chip->indio_dev, 0,
 					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
-					chip->last_timestamp);
+					iio_get_time_ns());
 		}
 	}
 
@@ -1822,27 +1820,12 @@ static void adt7316_interrupt_bh(struct work_struct *work_s)
 		if (stat2 & ADT7316_INT_MASK2_VDD)
 			iio_push_event(chip->indio_dev, 0,
 				IIO_EVENT_CODE_ADT7316_VDD,
-				chip->last_timestamp);
+				       iio_get_time_ns());
 	}
 
-	enable_irq(chip->bus.irq);
+	return IRQ_HANDLED;
 }
 
-static int adt7316_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7316_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
-}
-
-IIO_EVENT_SH(adt7316, &adt7316_interrupt);
-
 /*
  * Show mask of enabled interrupts in Hex.
  */
@@ -1901,9 +1884,9 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
 }
 static inline ssize_t adt7316_show_ad_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 	u8 val;
@@ -1911,10 +1894,10 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev,
 	int ret;
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
-		bound_reg > ADT7316_EX_TEMP_LOW)
+		this_attr->address > ADT7316_EX_TEMP_LOW)
 		return -EPERM;
 
-	ret = chip->bus.read(chip->bus.client, bound_reg, &val);
+	ret = chip->bus.read(chip->bus.client, this_attr->address, &val);
 	if (ret)
 		return -EIO;
 
@@ -1931,10 +1914,10 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev,
 
 static inline ssize_t adt7316_set_ad_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 	long data;
@@ -1942,7 +1925,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
 	int ret;
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
-		bound_reg > ADT7316_EX_TEMP_LOW)
+		this_attr->address > ADT7316_EX_TEMP_LOW)
 		return -EPERM;
 
 	ret = strict_strtol(buf, 10, &data);
@@ -1963,183 +1946,13 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
 
 	val = (u8)data;
 
-	ret = chip->bus.write(chip->bus.client, bound_reg, val);
+	ret = chip->bus.write(chip->bus.client, this_attr->address, val);
 	if (ret)
 		return -EIO;
 
 	return len;
 }
 
-static ssize_t adt7316_show_in_temp_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_in_temp_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_in_temp_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_in_temp_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain2_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN2_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain2_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN2_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain2_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN2_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain2_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN2_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain3_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN3_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain3_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN3_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain3_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN3_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain3_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN3_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain4_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN4_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain4_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN4_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain4_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN4_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain4_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN4_LOW, buf, len);
-}
-
 static ssize_t adt7316_show_int_enabled(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -2173,47 +1986,72 @@ static ssize_t adt7316_set_int_enabled(struct device *dev,
 	return len;
 }
 
-
-IIO_EVENT_ATTR_SH(int_mask, iio_event_adt7316,
-		adt7316_show_int_mask, adt7316_set_int_mask, 0);
-IIO_EVENT_ATTR_SH(in_temp_high, iio_event_adt7316,
-		adt7316_show_in_temp_high, adt7316_set_in_temp_high, 0);
-IIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316,
-		adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0);
-IIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_high,
-		adt7316_set_ex_temp_ain1_high, 0);
-IIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_low,
-		adt7316_set_ex_temp_ain1_low, 0);
-IIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_high,
-		adt7316_set_ex_temp_ain1_high, 0);
-IIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_low,
-		adt7316_set_ex_temp_ain1_low, 0);
-IIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316,
-		adt7316_show_ain2_high, adt7316_set_ain2_high, 0);
-IIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316,
-		adt7316_show_ain2_low, adt7316_set_ain2_low, 0);
-IIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316,
-		adt7316_show_ain3_high, adt7316_set_ain3_high, 0);
-IIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316,
-		adt7316_show_ain3_low, adt7316_set_ain3_low, 0);
-IIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316,
-		adt7316_show_ain4_high, adt7316_set_ain4_high, 0);
-IIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316,
-		adt7316_show_ain4_low, adt7316_set_ain4_low, 0);
-IIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316,
-		adt7316_show_int_enabled, adt7316_set_int_enabled, 0);
+static IIO_DEVICE_ATTR(int_mask,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_int_mask, adt7316_set_int_mask,
+		       0);
+static IIO_DEVICE_ATTR(in_temp_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_IN_TEMP_HIGH);
+static IIO_DEVICE_ATTR(in_temp_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_IN_TEMP_LOW);
+static IIO_DEVICE_ATTR(ex_temp_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_HIGH);
+static IIO_DEVICE_ATTR(ex_temp_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_LOW);
+
+/* NASTY duplication to be fixed */
+static IIO_DEVICE_ATTR(ex_temp_ain1_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_HIGH);
+static IIO_DEVICE_ATTR(ex_temp_ain1_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_LOW);
+static IIO_DEVICE_ATTR(ain2_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN2_HIGH);
+static IIO_DEVICE_ATTR(ain2_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN2_LOW);
+static IIO_DEVICE_ATTR(ain3_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN3_HIGH);
+static IIO_DEVICE_ATTR(ain3_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN3_LOW);
+static IIO_DEVICE_ATTR(ain4_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN4_HIGH);
+static IIO_DEVICE_ATTR(ain4_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN4_LOW);
+static IIO_DEVICE_ATTR(int_enabled,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_int_enabled,
+		       adt7316_set_int_enabled, 0);
 
 static struct attribute *adt7316_event_attributes[] = {
-	&iio_event_attr_int_mask.dev_attr.attr,
-	&iio_event_attr_in_temp_high.dev_attr.attr,
-	&iio_event_attr_in_temp_low.dev_attr.attr,
-	&iio_event_attr_ex_temp_high.dev_attr.attr,
-	&iio_event_attr_ex_temp_low.dev_attr.attr,
-	&iio_event_attr_int_enabled.dev_attr.attr,
+	&iio_dev_attr_int_mask.dev_attr.attr,
+	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_int_enabled.dev_attr.attr,
 	NULL,
 };
 
@@ -2222,18 +2060,18 @@ static struct attribute_group adt7316_event_attribute_group = {
 };
 
 static struct attribute *adt7516_event_attributes[] = {
-	&iio_event_attr_int_mask.dev_attr.attr,
-	&iio_event_attr_in_temp_high.dev_attr.attr,
-	&iio_event_attr_in_temp_low.dev_attr.attr,
-	&iio_event_attr_ex_temp_ain1_high.dev_attr.attr,
-	&iio_event_attr_ex_temp_ain1_low.dev_attr.attr,
-	&iio_event_attr_ain2_high.dev_attr.attr,
-	&iio_event_attr_ain2_low.dev_attr.attr,
-	&iio_event_attr_ain3_high.dev_attr.attr,
-	&iio_event_attr_ain3_low.dev_attr.attr,
-	&iio_event_attr_ain4_high.dev_attr.attr,
-	&iio_event_attr_ain4_low.dev_attr.attr,
-	&iio_event_attr_int_enabled.dev_attr.attr,
+	&iio_dev_attr_int_mask.dev_attr.attr,
+	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_ain1_high_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_ain1_low_value.dev_attr.attr,
+	&iio_dev_attr_ain2_high_value.dev_attr.attr,
+	&iio_dev_attr_ain2_low_value.dev_attr.attr,
+	&iio_dev_attr_ain3_high_value.dev_attr.attr,
+	&iio_dev_attr_ain3_low_value.dev_attr.attr,
+	&iio_dev_attr_ain4_high_value.dev_attr.attr,
+	&iio_dev_attr_ain4_low_value.dev_attr.attr,
+	&iio_dev_attr_int_enabled.dev_attr.attr,
 	NULL,
 };
 
@@ -2326,24 +2164,15 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 		if (adt7316_platform_data[0])
 			chip->bus.irq_flags = adt7316_platform_data[0];
 
-		ret = iio_register_interrupt_line(chip->bus.irq,
-				chip->indio_dev,
-				0,
-				chip->bus.irq_flags,
-				chip->name);
+		ret = request_threaded_irq(chip->bus.irq,
+					   NULL,
+					   &adt7316_event_handler,
+					   chip->bus.irq_flags | IRQF_ONESHOT,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_adt7316.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_adt7316,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, adt7316_interrupt_bh);
-
 		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
 			chip->config1 |= ADT7316_INT_POLARITY;
 	}
@@ -2366,7 +2195,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 	return 0;
 
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(chip->bus.irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -2383,12 +2212,11 @@ int __devexit adt7316_remove(struct device *dev)
 
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
-	struct iio_dev *indio_dev = chip->indio_dev;
 
 	dev_set_drvdata(dev, NULL);
 	if (chip->bus.irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-	iio_device_unregister(indio_dev);
+		free_irq(chip->bus.irq, chip->indio_dev);
+	iio_device_unregister(chip->indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 016/111] staging:iio:adc:ad7745 move from old to current event handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (14 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 015/111] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 017/111] staging:iio:adc:ad7816 " Jonathan Cameron
                   ` (95 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Nice simple one.  Not sure we actually want devices outputting
datardy signals like that, but I'll leave it for now.
Cleaned up some unneeded functions whilst here.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7745.c |   89 ++++++++++---------------------------
 1 files changed, 24 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
index 1373d23..cb1fc61 100644
--- a/drivers/staging/iio/adc/ad7745.c
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -58,9 +56,7 @@ struct ad774x_chip_info {
 	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
 	bool inter;
-	s64 last_timestamp;
 	u16 cap_offs;                   /* Capacitive offset */
 	u16 cap_gain;                   /* Capacitive gain calibration */
 	u16 volt_gain;                  /* Voltage gain calibration */
@@ -76,7 +72,8 @@ struct ad774x_conversion_mode {
 	u8 reg_cfg;
 };
 
-struct ad774x_conversion_mode ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = {
+static struct ad774x_conversion_mode
+ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -547,67 +544,33 @@ static const struct attribute_group ad774x_attribute_group = {
 #define IIO_EVENT_ATTR_VT_RDY_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(vt_rdy, _evlist, _show, _store, _mask)
 
-static void ad774x_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t ad774x_event_handler(int irq, void *private)
 {
-	struct ad774x_chip_info *chip =
-		container_of(work_s, struct ad774x_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad774x_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 int_status;
 
-	enable_irq(chip->client->irq);
-
 	ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1);
 
 	if (int_status & AD774X_STATUS_RDYCAP)
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CAP_RDY,
-				chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_EVENT_CODE_CAP_RDY,
+			       iio_get_time_ns());
 
 	if (int_status & AD774X_STATUS_RDYVT)
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_VT_RDY,
-				chip->last_timestamp);
-}
-
-static int ad774x_interrupt_handler_th(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad774x_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
-}
-
-IIO_EVENT_SH(data_rdy, &ad774x_interrupt_handler_th);
-
-static ssize_t ad774x_query_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	/*
-	 * AD774X provides one /RDY pin, which can be used as interrupt
-	 * but the pin is not configurable
-	 */
-	return sprintf(buf, "1\n");
-}
+		iio_push_event(indio_dev, 0,
+			       IIO_EVENT_CODE_VT_RDY,
+			       iio_get_time_ns());
 
-static ssize_t ad774x_set_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return len;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_ATTR_CAP_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
-IIO_EVENT_ATTR_VT_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
+static IIO_CONST_ATTR(cap_rdy_en, "1");
+static IIO_CONST_ATTR(vt_rdy_en, "1");
 
 static struct attribute *ad774x_event_attributes[] = {
-	&iio_event_attr_cap_rdy.dev_attr.attr,
-	&iio_event_attr_vt_rdy.dev_attr.attr,
+	&iio_const_attr_cap_rdy_en.dev_attr.attr,
+	&iio_const_attr_vt_rdy_en.dev_attr.attr,
 	NULL,
 };
 
@@ -656,18 +619,14 @@ static int __devinit ad774x_probe(struct i2c_client *client,
 	regdone = 1;
 
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				"ad774x");
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad774x_event_handler,
+					   IRQF_TRIGGER_FALLING,
+					   "ad774x",
+					   chip->indio_dev);
 		if (ret)
 			goto error_free_dev;
-
-		iio_add_event_to_list(iio_event_attr_cap_rdy.listel,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad774x_interrupt_handler_bh);
 	}
 
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
@@ -676,7 +635,7 @@ static int __devinit ad774x_probe(struct i2c_client *client,
 
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(chip->indio_dev);
+		free_irq(client->irq, chip->indio_dev);
 	else
 		iio_free_device(chip->indio_dev);
 error_free_chip:
@@ -691,7 +650,7 @@ static int __devexit ad774x_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 017/111] staging:iio:adc:ad7816 move from old to current event handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (15 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 016/111] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 018/111] staging:iio:adc:ad7150 move from deprecated event handling plus remove irq as gpio requirement Jonathan Cameron
                   ` (94 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

I'm not sure what the event is and am very much against the dodgy
hack to give it a code. However for now, lets just stop it using
the deprecated core handling so we can move on.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7816.c |   62 +++++++++----------------------------
 1 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 9e30d35..a062ec3 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -47,8 +45,6 @@ struct ad7816_chip_info {
 	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u16 rdwr_pin;
 	u16 convert_pin;
 	u16 busy_pin;
@@ -266,33 +262,14 @@ static const struct attribute_group ad7816_attribute_group = {
 
 #define IIO_EVENT_CODE_AD7816_OTI    IIO_BUFFER_EVENT_CODE(0)
 
-static void ad7816_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad7816_event_handler(int irq, void *private)
 {
-	struct ad7816_chip_info *chip =
-		container_of(work_s, struct ad7816_chip_info, thresh_work);
-
-	enable_irq(chip->spi_dev->irq);
-
-	iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_AD7816_OTI,
-			chip->last_timestamp);
-}
-
-static int ad7816_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad7816_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	iio_push_event(private, 0,
+		       IIO_EVENT_CODE_AD7816_OTI,
+		       iio_get_time_ns());
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad7816, &ad7816_interrupt);
-
 static ssize_t ad7816_show_oti(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -352,11 +329,11 @@ static inline ssize_t ad7816_set_oti(struct device *dev,
 	return len;
 }
 
-IIO_EVENT_ATTR_SH(oti, iio_event_ad7816,
-		ad7816_show_oti, ad7816_set_oti, 0);
+static IIO_DEVICE_ATTR(oti, S_IRUGO | S_IWUSR,
+		       ad7816_show_oti, ad7816_set_oti, 0);
 
 static struct attribute *ad7816_event_attributes[] = {
-	&iio_event_attr_oti.dev_attr.attr,
+	&iio_dev_attr_oti.dev_attr.attr,
 	NULL,
 };
 
@@ -438,23 +415,14 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev)
 
 	if (spi_dev->irq) {
 		/* Only low trigger is supported in ad7816/7/8 */
-		ret = iio_register_interrupt_line(spi_dev->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(spi_dev->irq,
+					   NULL,
+					   &ad7816_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_ad7816.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad7816,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7816_interrupt_bh);
 	}
 
 	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
@@ -485,7 +453,7 @@ static int __devexit ad7816_remove(struct spi_device *spi_dev)
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
 	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi_dev->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	gpio_free(chip->busy_pin);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 018/111] staging:iio:adc:ad7150 move from deprecated event handling plus remove irq as gpio requirement.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (16 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 017/111] staging:iio:adc:ad7816 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 019/111] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
                   ` (93 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Another driver with some very 'non standard' magic event codes.
Again I've left it be for now and merely moved it to the new
api.

There is no reason why the irq in this driver ever had to be a gpio.
Scrap that test and clean out unecessary headers.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7150.c |  121 ++++++++++---------------------------
 1 files changed, 33 insertions(+), 88 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 5a2991a..6a9f326 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -7,15 +7,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -66,9 +61,7 @@ struct ad7150_chip_info {
 	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
 	bool inter;
-	s64 last_timestamp;
 	u16 ch1_threshold;     /* Ch1 Threshold (in fixed threshold mode) */
 	u8  ch1_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
 	u8  ch1_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
@@ -88,7 +81,8 @@ struct ad7150_conversion_mode {
 	u8 reg_cfg;
 };
 
-struct ad7150_conversion_mode ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
+static struct ad7150_conversion_mode
+ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -666,91 +660,45 @@ static const struct attribute_group ad7150_attribute_group = {
 #define IIO_EVENT_CODE_CH2_HIGH    IIO_BUFFER_EVENT_CODE(2)
 #define IIO_EVENT_CODE_CH2_LOW     IIO_BUFFER_EVENT_CODE(3)
 
-#define IIO_EVENT_ATTR_CH1_HIGH_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch1_high, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH2_HIGH_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch2_high, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH1_LOW_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch1_low, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH2_LOW_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch2_low, _evlist, _show, _store, _mask)
-
-static void ad7150_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t ad7150_event_handler(int irq, void *private)
 {
-	struct ad7150_chip_info *chip =
-		container_of(work_s, struct ad7150_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad7150_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 int_status;
-
-	enable_irq(chip->client->irq);
+	s64 timestamp = iio_get_time_ns();
 
 	ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1);
 
 	if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1))
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_CH1_HIGH,
-				chip->last_timestamp);
+				timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1))
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_CH1_LOW,
-				chip->last_timestamp);
+				timestamp);
 
 	if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2))
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_CH2_HIGH,
-				chip->last_timestamp);
+				timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2))
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_CH2_LOW,
-				chip->last_timestamp);
-}
-
-static int ad7150_interrupt_handler_th(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad7150_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+				timestamp);
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(threshold, &ad7150_interrupt_handler_th);
-
-static ssize_t ad7150_query_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	/*
-	 * AD7150 provides two logic output channels, which can be used as interrupt
-	 * but the pins are not configurable
-	 */
-	return sprintf(buf, "1\n");
-}
-
-static ssize_t ad7150_set_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return len;
-}
-
-IIO_EVENT_ATTR_CH1_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH2_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH1_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH2_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+static IIO_CONST_ATTR(ch1_high_en, "1");
+static IIO_CONST_ATTR(ch2_high_en, "1");
+static IIO_CONST_ATTR(ch1_low_en, "1");
+static IIO_CONST_ATTR(ch2_low_en, "1");
 
 static struct attribute *ad7150_event_attributes[] = {
-	&iio_event_attr_ch1_high.dev_attr.attr,
-	&iio_event_attr_ch2_high.dev_attr.attr,
-	&iio_event_attr_ch1_low.dev_attr.attr,
-	&iio_event_attr_ch2_low.dev_attr.attr,
+	&iio_const_attr_ch1_high_en.dev_attr.attr,
+	&iio_const_attr_ch2_high_en.dev_attr.attr,
+	&iio_const_attr_ch1_low_en.dev_attr.attr,
+	&iio_const_attr_ch2_low_en.dev_attr.attr,
 	NULL,
 };
 
@@ -798,19 +746,16 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 		goto error_free_dev;
 	regdone = 1;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				"ad7150");
+	if (client->irq) {
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad7150_event_handler,
+					   IRQF_TRIGGER_RISING |
+					   IRQF_TRIGGER_FALLING,
+					   "ad7150",
+					   chip->indio_dev);
 		if (ret)
 			goto error_free_dev;
-
-		iio_add_event_to_list(iio_event_attr_ch2_low.listel,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7150_interrupt_handler_bh);
 	}
 
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
@@ -833,8 +778,8 @@ static int __devexit ad7150_remove(struct i2c_client *client)
 	struct ad7150_chip_info *chip = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = chip->indio_dev;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 019/111] staging:iio:adc:ad7152 remove unregister of interrupt line.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (17 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 018/111] staging:iio:adc:ad7150 move from deprecated event handling plus remove irq as gpio requirement Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 020/111] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
                   ` (92 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

a) This interface is going away
b) There is no matching register call so looks like a cut and paste
error

Trivial sparse warning fix.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |    9 ++-------
 1 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 163c307..25715f0 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -7,15 +7,11 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -72,7 +68,8 @@ struct ad7152_conversion_mode {
 	u8 reg_cfg;
 };
 
-struct ad7152_conversion_mode ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
+static struct ad7152_conversion_mode
+ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -567,8 +564,6 @@ static int __devexit ad7152_remove(struct i2c_client *client)
 	struct ad7152_chip_info *chip = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = chip->indio_dev;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 020/111] staging:iio:adc:adt75 old to new event handling conversion
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (18 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 019/111] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 021/111] staging:iio:ad7291 move from old event system to current Jonathan Cameron
                   ` (91 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Another one where the events are 'unusual'.  Still left sorting
that out for another day.

Untested changes

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/adt75.c |  144 ++++++++++++---------------------------
 1 files changed, 43 insertions(+), 101 deletions(-)

diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index f247c4c..0d1cc75 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -7,15 +7,11 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -57,8 +53,6 @@ struct adt75_chip_info {
 	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -279,33 +273,15 @@ static const struct attribute_group adt75_attribute_group = {
 
 #define IIO_EVENT_CODE_ADT75_OTI    IIO_BUFFER_EVENT_CODE(0)
 
-static void adt75_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt75_event_handler(int irq, void *private)
 {
-	struct adt75_chip_info *chip =
-		container_of(work_s, struct adt75_chip_info, thresh_work);
+	iio_push_event(private, 0,
+		       IIO_EVENT_CODE_ADT75_OTI,
+		       iio_get_time_ns());
 
-	enable_irq(chip->client->irq);
-
-	iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT75_OTI,
-			chip->last_timestamp);
-}
-
-static int adt75_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt75_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt75, &adt75_interrupt);
-
 static ssize_t adt75_show_oti_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -458,16 +434,16 @@ static ssize_t adt75_set_fault_queue(struct device *dev,
 }
 static inline ssize_t adt75_show_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt75_chip_info *chip = dev_info->dev_data;
 	u16 data;
 	char sign = ' ';
 	int ret;
 
-	ret = adt75_i2c_read(chip, bound_reg, (u8 *)&data);
+	ret = adt75_i2c_read(chip, this_attr->address, (u8 *)&data);
 	if (ret)
 		return -EIO;
 
@@ -485,10 +461,10 @@ static inline ssize_t adt75_show_t_bound(struct device *dev,
 
 static inline ssize_t adt75_set_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt75_chip_info *chip = dev_info->dev_data;
 	long tmp1, tmp2;
@@ -525,67 +501,42 @@ static inline ssize_t adt75_set_t_bound(struct device *dev,
 	data <<= ADT75_VALUE_OFFSET;
 	data = swab16(data);
 
-	ret = adt75_i2c_write(chip, bound_reg, (u8)data);
+	ret = adt75_i2c_write(chip, this_attr->address, (u8)data);
 	if (ret)
 		return -EIO;
 
 	return ret;
 }
 
-static ssize_t adt75_show_t_os(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt75_show_t_bound(dev, attr,
-			ADT75_T_OS, buf);
-}
-
-static inline ssize_t adt75_set_t_os(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt75_set_t_bound(dev, attr,
-			ADT75_T_OS, buf, len);
-}
-
-static ssize_t adt75_show_t_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt75_show_t_bound(dev, attr,
-			ADT75_T_HYST, buf);
-}
-
-static inline ssize_t adt75_set_t_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt75_set_t_bound(dev, attr,
-			ADT75_T_HYST, buf, len);
-}
 
-IIO_EVENT_ATTR_SH(oti_mode, iio_event_adt75,
-		adt75_show_oti_mode, adt75_set_oti_mode, 0);
-IIO_EVENT_ATTR_SH(available_oti_modes, iio_event_adt75,
-		adt75_show_available_oti_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(smbus_alart, iio_event_adt75,
-		adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt75,
-		adt75_show_fault_queue, adt75_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_os, iio_event_adt75,
-		adt75_show_t_os, adt75_set_t_os, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt75,
-		adt75_show_t_hyst, adt75_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(oti_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_oti_mode, adt75_set_oti_mode, 0);
+static IIO_DEVICE_ATTR(available_oti_modes,
+		       S_IRUGO,
+		       adt75_show_available_oti_modes, NULL, 0);
+static IIO_DEVICE_ATTR(smbus_alart,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_fault_queue, adt75_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_os_value,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_t_bound, adt75_set_t_bound,
+		       ADT75_T_OS);
+static IIO_DEVICE_ATTR(t_hyst_value,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_t_bound, adt75_set_t_bound,
+		       ADT75_T_HYST);
 
 static struct attribute *adt75_event_attributes[] = {
-	&iio_event_attr_oti_mode.dev_attr.attr,
-	&iio_event_attr_available_oti_modes.dev_attr.attr,
-	&iio_event_attr_smbus_alart.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_os.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_oti_mode.dev_attr.attr,
+	&iio_dev_attr_available_oti_modes.dev_attr.attr,
+	&iio_dev_attr_smbus_alart.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_os_value.dev_attr.attr,
+	&iio_dev_attr_t_hyst_value.dev_attr.attr,
 	NULL,
 };
 
@@ -633,24 +584,15 @@ static int __devinit adt75_probe(struct i2c_client *client,
 		goto error_free_dev;
 
 	if (client->irq > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &adt75_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_adt75.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_adt75,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, adt75_interrupt_bh);
-
 		ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
 		if (ret) {
 			ret = -EIO;
@@ -672,7 +614,7 @@ static int __devinit adt75_probe(struct i2c_client *client,
 
 	return 0;
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -689,7 +631,7 @@ static int __devexit adt75_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 021/111] staging:iio:ad7291 move from old event system to current.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (19 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 020/111] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 022/111] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
                   ` (90 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This driver needed some tender loving care. It still does.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7291.c |  422 ++++++++++++-------------------------
 1 files changed, 137 insertions(+), 285 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 976ae7f..23ad18e 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -65,8 +63,6 @@ struct ad7291_chip_info {
 	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u16 command;
 	u8  channels;	/* Active voltage channels */
 };
@@ -477,22 +473,23 @@ static const struct attribute_group ad7291_attribute_group = {
 #define IIO_EVENT_CODE_AD7291_T_AVG_LOW     IIO_BUFFER_EVENT_CODE(3)
 #define IIO_EVENT_CODE_AD7291_VOLTAGE_BASE  IIO_BUFFER_EVENT_CODE(4)
 
-static void ad7291_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad7291_event_handler(int irq, void *private)
 {
-	struct ad7291_chip_info *chip =
-		container_of(work_s, struct ad7291_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad7291_chip_info *chip = iio_dev_get_devdata(private);
 	u16 t_status, v_status;
 	u16 command;
 	int i;
+	s64 timestamp = iio_get_time_ns();
 
 	if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
-		return;
+		return IRQ_HANDLED;
 
 	if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
-		return;
+		return IRQ_HANDLED;
 
 	if (!(t_status || v_status))
-		return;
+		return IRQ_HANDLED;
 
 	command = chip->command | AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
@@ -500,50 +497,35 @@ static void ad7291_interrupt_bh(struct work_struct *work_s)
 	command = chip->command & ~AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
 
-	enable_irq(chip->client->irq);
-
 	for (i = 0; i < 4; i++) {
 		if (t_status & (1 << i))
-			iio_push_event(chip->indio_dev, 0,
+			iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_AD7291_T_SENSE_HIGH + i,
-				chip->last_timestamp);
+				timestamp);
 	}
 
 	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i++) {
 		if (v_status & (1 << i))
-			iio_push_event(chip->indio_dev, 0,
+			iio_push_event(indio_dev, 0,
 				IIO_EVENT_CODE_AD7291_VOLTAGE_BASE + i,
-				chip->last_timestamp);
+				timestamp);
 	}
-}
 
-static int ad7291_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad7291_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad7291, &ad7291_interrupt);
-
 static inline ssize_t ad7291_show_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	u16 data;
 	char sign = ' ';
 	int ret;
 
-	ret = ad7291_i2c_read(chip, bound_reg, &data);
+	ret = ad7291_i2c_read(chip, this_attr->address, &data);
 	if (ret)
 		return -EIO;
 
@@ -561,12 +543,12 @@ static inline ssize_t ad7291_show_t_bound(struct device *dev,
 
 static inline ssize_t ad7291_set_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	long tmp1, tmp2;
 	u16 data;
 	char *pos;
@@ -600,64 +582,13 @@ static inline ssize_t ad7291_set_t_bound(struct device *dev,
 		/* convert positive value to supplyment */
 		data = (AD7291_T_VALUE_SIGN << 1) - data;
 
-	ret = ad7291_i2c_write(chip, bound_reg, data);
+	ret = ad7291_i2c_write(chip, this_attr->address, data);
 	if (ret)
 		return -EIO;
 
 	return ret;
 }
 
-static ssize_t ad7291_show_t_sense_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_HIGH, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_HIGH, buf, len);
-}
-
-static ssize_t ad7291_show_t_sense_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_LOW, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_LOW, buf, len);
-}
-
-static ssize_t ad7291_show_t_sense_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_HYST, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_HYST, buf, len);
-}
-
 static inline ssize_t ad7291_show_v_bound(struct device *dev,
 		struct device_attribute *attr,
 		u8 bound_reg,
@@ -712,191 +643,121 @@ static inline ssize_t ad7291_set_v_bound(struct device *dev,
 	return ret;
 }
 
-static int ad7291_get_voltage_limit_regs(const char *channel)
-{
-	int index;
-
-	if (strlen(channel) < 3 && channel[0] != 'v')
-		return -EINVAL;
-
-	index = channel[1] - '0';
-	if (index >= AD7291_VOLTAGE_LIMIT_COUNT)
-		return -EINVAL;
-
-	return index;
-}
-
-static ssize_t ad7291_show_voltage_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs, buf, len);
-}
-
-static ssize_t ad7291_show_voltage_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs+1, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs+1, buf, len);
-}
-
-static ssize_t ad7291_show_voltage_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs+2, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs+2, buf, len);
-}
-
-IIO_EVENT_ATTR_SH(t_sense_high, iio_event_ad7291,
-		ad7291_show_t_sense_high, ad7291_set_t_sense_high, 0);
-IIO_EVENT_ATTR_SH(t_sense_low, iio_event_ad7291,
-		ad7291_show_t_sense_low, ad7291_set_t_sense_low, 0);
-IIO_EVENT_ATTR_SH(t_sense_hyst, iio_event_ad7291,
-		ad7291_show_t_sense_hyst, ad7291_set_t_sense_hyst, 0);
-
-IIO_EVENT_ATTR_SH(v0_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v0_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v0_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v1_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v1_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v1_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v2_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v2_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v2_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v3_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v3_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v3_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v4_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v4_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v4_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v5_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v5_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v5_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v6_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v6_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v6_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v7_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v7_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v7_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+static IIO_DEVICE_ATTR(t_sense_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_HIGH);
+static IIO_DEVICE_ATTR(t_sense_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_LOW);
+static IIO_DEVICE_ATTR(t_sense_hyst_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_HYST);
+static IIO_DEVICE_ATTR(v0_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x04);
+static IIO_DEVICE_ATTR(v0_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x05);
+static IIO_DEVICE_ATTR(v0_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x06);
+static IIO_DEVICE_ATTR(v1_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x07);
+static IIO_DEVICE_ATTR(v1_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x08);
+static IIO_DEVICE_ATTR(v1_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x09);
+static IIO_DEVICE_ATTR(v2_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0A);
+static IIO_DEVICE_ATTR(v2_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0B);
+static IIO_DEVICE_ATTR(v2_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0C);
+static IIO_DEVICE_ATTR(v3_high,
+		       S_IRUGO | S_IWUSR,
+		       /* Datasheet suggests this one and this one only
+			  has the registers in different order */
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0E);
+static IIO_DEVICE_ATTR(v3_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0D);
+static IIO_DEVICE_ATTR(v3_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0F);
+static IIO_DEVICE_ATTR(v4_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x10);
+static IIO_DEVICE_ATTR(v4_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x11);
+static IIO_DEVICE_ATTR(v4_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x12);
+static IIO_DEVICE_ATTR(v5_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x13);
+static IIO_DEVICE_ATTR(v5_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x14);
+static IIO_DEVICE_ATTR(v5_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x15);
+static IIO_DEVICE_ATTR(v6_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x16);
+static IIO_DEVICE_ATTR(v6_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x17);
+static IIO_DEVICE_ATTR(v6_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x18);
+static IIO_DEVICE_ATTR(v7_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x19);
+static IIO_DEVICE_ATTR(v7_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1A);
+static IIO_DEVICE_ATTR(v7_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1B);
 
 static struct attribute *ad7291_event_attributes[] = {
-	&iio_event_attr_t_sense_high.dev_attr.attr,
-	&iio_event_attr_t_sense_low.dev_attr.attr,
-	&iio_event_attr_t_sense_hyst.dev_attr.attr,
-	&iio_event_attr_v0_high.dev_attr.attr,
-	&iio_event_attr_v0_low.dev_attr.attr,
-	&iio_event_attr_v0_hyst.dev_attr.attr,
-	&iio_event_attr_v1_high.dev_attr.attr,
-	&iio_event_attr_v1_low.dev_attr.attr,
-	&iio_event_attr_v1_hyst.dev_attr.attr,
-	&iio_event_attr_v2_high.dev_attr.attr,
-	&iio_event_attr_v2_low.dev_attr.attr,
-	&iio_event_attr_v2_hyst.dev_attr.attr,
-	&iio_event_attr_v3_high.dev_attr.attr,
-	&iio_event_attr_v3_low.dev_attr.attr,
-	&iio_event_attr_v3_hyst.dev_attr.attr,
-	&iio_event_attr_v4_high.dev_attr.attr,
-	&iio_event_attr_v4_low.dev_attr.attr,
-	&iio_event_attr_v4_hyst.dev_attr.attr,
-	&iio_event_attr_v5_high.dev_attr.attr,
-	&iio_event_attr_v5_low.dev_attr.attr,
-	&iio_event_attr_v5_hyst.dev_attr.attr,
-	&iio_event_attr_v6_high.dev_attr.attr,
-	&iio_event_attr_v6_low.dev_attr.attr,
-	&iio_event_attr_v6_hyst.dev_attr.attr,
-	&iio_event_attr_v7_high.dev_attr.attr,
-	&iio_event_attr_v7_low.dev_attr.attr,
-	&iio_event_attr_v7_hyst.dev_attr.attr,
+	&iio_dev_attr_t_sense_high_value.dev_attr.attr,
+	&iio_dev_attr_t_sense_low_value.dev_attr.attr,
+	&iio_dev_attr_t_sense_hyst_value.dev_attr.attr,
+	&iio_dev_attr_v0_high.dev_attr.attr,
+	&iio_dev_attr_v0_low.dev_attr.attr,
+	&iio_dev_attr_v0_hyst.dev_attr.attr,
+	&iio_dev_attr_v1_high.dev_attr.attr,
+	&iio_dev_attr_v1_low.dev_attr.attr,
+	&iio_dev_attr_v1_hyst.dev_attr.attr,
+	&iio_dev_attr_v2_high.dev_attr.attr,
+	&iio_dev_attr_v2_low.dev_attr.attr,
+	&iio_dev_attr_v2_hyst.dev_attr.attr,
+	&iio_dev_attr_v3_high.dev_attr.attr,
+	&iio_dev_attr_v3_low.dev_attr.attr,
+	&iio_dev_attr_v3_hyst.dev_attr.attr,
+	&iio_dev_attr_v4_high.dev_attr.attr,
+	&iio_dev_attr_v4_low.dev_attr.attr,
+	&iio_dev_attr_v4_hyst.dev_attr.attr,
+	&iio_dev_attr_v5_high.dev_attr.attr,
+	&iio_dev_attr_v5_low.dev_attr.attr,
+	&iio_dev_attr_v5_hyst.dev_attr.attr,
+	&iio_dev_attr_v6_high.dev_attr.attr,
+	&iio_dev_attr_v6_low.dev_attr.attr,
+	&iio_dev_attr_v6_hyst.dev_attr.attr,
+	&iio_dev_attr_v7_high.dev_attr.attr,
+	&iio_dev_attr_v7_low.dev_attr.attr,
+	&iio_dev_attr_v7_hyst.dev_attr.attr,
 	NULL,
 };
 
@@ -945,24 +806,15 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 		goto error_free_dev;
 
 	if (client->irq > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad7291_event_handler,
+					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_ad7291.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad7291,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7291_interrupt_bh);
-
 		/* set irq polarity low level */
 		chip->command |= AD7291_ALART_POLARITY;
 	}
@@ -979,7 +831,7 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 	return 0;
 
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -996,7 +848,7 @@ static int __devexit ad7291_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 022/111] staging:iio:adc:adt7410 move to current event handling
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (20 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 021/111] staging:iio:ad7291 move from old event system to current Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 023/111] staging:iio:adt7310 " Jonathan Cameron
                   ` (89 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This device actually has a pair of interrupts. The code basically ignores
that and feeds them both to the same handlers.  I'm not sure if that is
the right thing to do, but the updated code should do exactly the same.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/adt7410.c |  151 +++++++++++++++----------------------
 1 files changed, 61 insertions(+), 90 deletions(-)

diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index 7cc3feb..dc59130 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -7,15 +7,12 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -80,8 +77,6 @@ struct adt7410_chip_info {
 	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -381,47 +376,32 @@ static const struct attribute_group adt7410_attribute_group = {
 #define IIO_EVENT_CODE_ADT7410_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
 #define IIO_EVENT_CODE_ADT7410_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
 
-static void adt7410_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7410_event_handler(int irq, void *private)
 {
-	struct adt7410_chip_info *chip =
-		container_of(work_s, struct adt7410_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7410_chip_info *chip = iio_dev_get_devdata(indio_dev);
+	s64 timestamp = iio_get_time_ns();
 	u8 status;
 
 	if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
-		return;
-
-	enable_irq(chip->client->irq);
+		return IRQ_HANDLED;
 
 	if (status & ADT7410_STAT_T_HIGH)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7410_ABOVE_ALARM,
-			chip->last_timestamp);
+			timestamp);
 	if (status & ADT7410_STAT_T_LOW)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7410_BELLOW_ALARM,
-			chip->last_timestamp);
+			timestamp);
 	if (status & ADT7410_STAT_T_CRIT)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7410_ABOVE_CRIT,
-			chip->last_timestamp);
-}
-
-static int adt7410_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7410_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
+			timestamp);
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt7410, &adt7410_interrupt);
-IIO_EVENT_SH(adt7410_ct, &adt7410_interrupt);
-
 static ssize_t adt7410_show_event_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -699,45 +679,51 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev,
 	return ret;
 }
 
-IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7410,
-		adt7410_show_event_mode, adt7410_set_event_mode, 0);
-IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7410,
-		adt7410_show_available_event_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7410,
-		adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7410,
-		adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
-IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7410,
-		adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
-IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7410_ct,
-		adt7410_show_t_crit, adt7410_set_t_crit, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7410,
-		adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(event_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_event_mode, adt7410_set_event_mode, 0);
+static IIO_DEVICE_ATTR(available_event_modes,
+		       S_IRUGO,
+		       adt7410_show_available_event_modes, NULL, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_alarm_high,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
+static IIO_DEVICE_ATTR(t_alarm_low,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
+static IIO_DEVICE_ATTR(t_crit,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_crit, adt7410_set_t_crit, 0);
+static IIO_DEVICE_ATTR(t_hyst,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
 
 static struct attribute *adt7410_event_int_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_alarm_high.dev_attr.attr,
-	&iio_event_attr_t_alarm_low.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_alarm_high.dev_attr.attr,
+	&iio_dev_attr_t_alarm_low.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute *adt7410_event_ct_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_crit.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_crit.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
 	{
 		.attrs = adt7410_event_int_attributes,
-	},
-	{
+	}, {
 		.attrs = adt7410_event_ct_attributes,
 	}
 };
@@ -784,44 +770,29 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 
 	/* CT critcal temperature event. line 0 */
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &adt7410_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7410.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7410,
-				&chip->indio_dev->interrupts[0]->ev_list);
 	}
 
 	/* INT bound temperature alarm event. line 1 */
 	if (adt7410_platform_data[0]) {
-		ret = iio_register_interrupt_line(adt7410_platform_data[0],
-				chip->indio_dev,
-				1,
-				adt7410_platform_data[1],
-				chip->name);
+		ret = request_threaded_irq(adt7410_platform_data[0],
+					   NULL,
+					   &adt7410_event_handler,
+					   adt7410_platform_data[1],
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7410.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7410_ct,
-				&chip->indio_dev->interrupts[1]->ev_list);
 	}
 
 	if (client->irq && adt7410_platform_data[0]) {
-		INIT_WORK(&chip->thresh_work, adt7410_interrupt_bh);
 
 		ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
 		if (ret) {
@@ -850,9 +821,9 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 	return 0;
 
 error_unreg_int_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 1);
+	free_irq(adt7410_platform_data[0], chip->indio_dev);
 error_unreg_ct_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -870,9 +841,9 @@ static int __devexit adt7410_remove(struct i2c_client *client)
 	unsigned long *adt7410_platform_data = client->dev.platform_data;
 
 	if (adt7410_platform_data[0])
-		iio_unregister_interrupt_line(indio_dev, 1);
+		free_irq(adt7410_platform_data[0], chip->indio_dev);
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 023/111] staging:iio:adt7310 move to current event handling
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (21 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 022/111] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 024/111] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
                   ` (88 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Another driver that has two event lines, but pushes all events out
the same chrdev. Probably needs a rethink.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/adt7310.c |  155 +++++++++++++++----------------------
 1 files changed, 64 insertions(+), 91 deletions(-)

diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index 7e66c42..9b2a8ec 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -7,15 +7,12 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -85,8 +82,6 @@ struct adt7310_chip_info {
 	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -413,45 +408,33 @@ static const struct attribute_group adt7310_attribute_group = {
 #define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
 #define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
 
-static void adt7310_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7310_event_handler(int irq, void *private)
 {
-	struct adt7310_chip_info *chip =
-		container_of(work_s, struct adt7310_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7310_chip_info *chip = iio_dev_get_devdata(indio_dev);
+	s64 timestamp = iio_get_time_ns();
 	u8 status;
+	int ret;
 
-	if (adt7310_spi_read_byte(chip, ADT7310_STATUS, &status))
-		return;
+	ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
+	if (ret)
+		return ret;
 
 	if (status & ADT7310_STAT_T_HIGH)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7310_ABOVE_ALARM,
-			chip->last_timestamp);
+			timestamp);
 	if (status & ADT7310_STAT_T_LOW)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7310_BELLOW_ALARM,
-			chip->last_timestamp);
+			timestamp);
 	if (status & ADT7310_STAT_T_CRIT)
-		iio_push_event(chip->indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_ADT7310_ABOVE_CRIT,
-			chip->last_timestamp);
-}
-
-static int adt7310_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7310_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+			timestamp);
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt7310, &adt7310_interrupt);
-IIO_EVENT_SH(adt7310_ct, &adt7310_interrupt);
-
 static ssize_t adt7310_show_event_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -729,45 +712,51 @@ static inline ssize_t adt7310_set_t_hyst(struct device *dev,
 	return len;
 }
 
-IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7310,
-		adt7310_show_event_mode, adt7310_set_event_mode, 0);
-IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7310,
-		adt7310_show_available_event_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7310,
-		adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7310,
-		adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
-IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7310,
-		adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
-IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7310_ct,
-		adt7310_show_t_crit, adt7310_set_t_crit, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7310,
-		adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(event_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_event_mode, adt7310_set_event_mode, 0);
+static IIO_DEVICE_ATTR(available_event_modes,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_available_event_modes, NULL, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_alarm_high,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
+static IIO_DEVICE_ATTR(t_alarm_low,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
+static IIO_DEVICE_ATTR(t_crit,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_crit, adt7310_set_t_crit, 0);
+static IIO_DEVICE_ATTR(t_hyst,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
 
 static struct attribute *adt7310_event_int_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_alarm_high.dev_attr.attr,
-	&iio_event_attr_t_alarm_low.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_alarm_high.dev_attr.attr,
+	&iio_dev_attr_t_alarm_low.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute *adt7310_event_ct_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_crit.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_crit.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
 	{
 		.attrs = adt7310_event_int_attributes,
-	},
-	{
+	}, {
 		.attrs = adt7310_event_ct_attributes,
 	}
 };
@@ -818,45 +807,29 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 			irq_flags = adt7310_platform_data[2];
 		else
 			irq_flags = IRQF_TRIGGER_LOW;
-		ret = iio_register_interrupt_line(spi_dev->irq,
-				chip->indio_dev,
-				0,
-				irq_flags,
-				chip->name);
+		ret = request_threaded_irq(spi_dev->irq,
+					   NULL,
+					   &adt7310_event_handler,
+					   irq_flags,
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7310.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7310,
-				&chip->indio_dev->interrupts[0]->ev_list);
 	}
 
 	/* INT bound temperature alarm event. line 1 */
 	if (adt7310_platform_data[0]) {
-		ret = iio_register_interrupt_line(adt7310_platform_data[0],
-				chip->indio_dev,
-				1,
-				adt7310_platform_data[1],
-				chip->name);
+		ret = request_threaded_irq(adt7310_platform_data[0],
+					   NULL,
+					   &adt7310_event_handler,
+					   adt7310_platform_data[1],
+					   chip->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7310.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7310_ct,
-				&chip->indio_dev->interrupts[1]->ev_list);
 	}
 
 	if (spi_dev->irq && adt7310_platform_data[0]) {
-		INIT_WORK(&chip->thresh_work, adt7310_interrupt_bh);
-
 		ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
 		if (ret) {
 			ret = -EIO;
@@ -884,9 +857,9 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 	return 0;
 
 error_unreg_int_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 1);
+	free_irq(adt7310_platform_data[0], chip->indio_dev);
 error_unreg_ct_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(spi_dev->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -905,9 +878,9 @@ static int __devexit adt7310_remove(struct spi_device *spi_dev)
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
 	if (adt7310_platform_data[0])
-		iio_unregister_interrupt_line(indio_dev, 1);
+		free_irq(adt7310_platform_data[0], chip->indio_dev);
 	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi_dev->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 024/111] staging:iio:adc:ad7314 remove unmatched unregister of event line.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (22 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 023/111] staging:iio:adt7310 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 025/111] staging:iio:adc:ad799x move to new event handling Jonathan Cameron
                   ` (87 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7314.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
index dffbec1..bc34e29 100644
--- a/drivers/staging/iio/adc/ad7314.c
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -6,16 +6,11 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -262,8 +257,6 @@ static int __devexit ad7314_remove(struct spi_device *spi_dev)
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
-	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 025/111] staging:iio:adc:ad799x move to new event handling
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (23 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 024/111] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 026/111] staging:iio: Remove legacy " Jonathan Cameron
                   ` (86 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad799x.h      |    1 -
 drivers/staging/iio/adc/ad799x_core.c |  252 +++++++++++++++------------------
 2 files changed, 115 insertions(+), 138 deletions(-)

diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index a421362..503fa61 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -114,7 +114,6 @@ struct ad799x_state {
 	struct i2c_client		*client;
 	const struct ad799x_chip_info	*chip_info;
 	struct work_struct		poll_work;
-	struct work_struct		work_thresh;
 	atomic_t			protect_ring;
 	size_t				d_size;
 	struct iio_trigger		*trig;
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 09d109f..34fc85c 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -338,11 +338,11 @@ static ssize_t ad799x_read_channel_config(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	int ret;
 	u16 val;
-	ret = ad799x_i2c_read16(st, this_attr->mask, &val);
+	ret = ad799x_i2c_read16(st, this_attr->address, &val);
 	if (ret)
 		return ret;
 
@@ -356,7 +356,7 @@ static ssize_t ad799x_write_channel_config(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	long val;
 	int ret;
@@ -366,54 +366,40 @@ static ssize_t ad799x_write_channel_config(struct device *dev,
 		return ret;
 
 	mutex_lock(&dev_info->mlock);
-	ret = ad799x_i2c_write16(st, this_attr->mask, val);
+	ret = ad799x_i2c_write16(st, this_attr->address, val);
 	mutex_unlock(&dev_info->mlock);
 
 	return ret ? ret : len;
 }
 
-static void ad799x_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad799x_event_handler(int irq, void *private)
 {
-	struct ad799x_state *st = container_of(work_s,
-		struct ad799x_state, work_thresh);
+	struct iio_dev *indio_dev = private;
+	struct ad799x_state *st = iio_dev_get_devdata(private);
 	u8 status;
-	int i;
+	int i, ret;
 
-	if (ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status))
-		goto err_out;
+	ret = ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status);
+	if (ret)
+		return ret;
 
 	if (!status)
-		goto err_out;
+		return -EIO;
 
 	ad799x_i2c_write8(st, AD7998_ALERT_STAT_REG, AD7998_ALERT_STAT_CLEAR);
 
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i))
-			iio_push_event(st->indio_dev, 0,
-				i & 0x1 ?
-				IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) :
-				IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1),
-				st->last_timestamp);
+			iio_push_event(indio_dev, 0,
+				       i & 0x1 ?
+				       IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) :
+				       IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1),
+				       iio_get_time_ns());
 	}
 
-err_out:
-	enable_irq(st->client->irq);
-}
-
-static int ad799x_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad799x_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_thresh);
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad799x, &ad799x_interrupt);
-
 /* Direct read attribtues */
 static IIO_DEV_ATTR_IN_RAW(0, ad799x_read_single_channel, 0);
 static IIO_DEV_ATTR_IN_RAW(1, ad799x_read_single_channel, 1);
@@ -562,77 +548,77 @@ static struct attribute_group ad7997_8_scan_el_group = {
 	.attrs = ad7997_8_scan_el_attrs,
 };
 
-IIO_EVENT_ATTR_SH(in0_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH1_REG);
-
-IIO_EVENT_ATTR_SH(in0_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH1_REG);
-
-IIO_EVENT_ATTR_SH(in0_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH1_REG);
-
-IIO_EVENT_ATTR_SH(in1_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH2_REG);
-
-IIO_EVENT_ATTR_SH(in1_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH2_REG);
-
-IIO_EVENT_ATTR_SH(in1_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH2_REG);
-
-IIO_EVENT_ATTR_SH(in2_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH3_REG);
-
-IIO_EVENT_ATTR_SH(in2_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH3_REG);
-
-IIO_EVENT_ATTR_SH(in2_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH3_REG);
-
-IIO_EVENT_ATTR_SH(in3_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH4_REG);
-
-IIO_EVENT_ATTR_SH(in3_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH4_REG);
-
-IIO_EVENT_ATTR_SH(in3_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH4_REG);
+static IIO_DEVICE_ATTR(in0_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH1_REG);
+
+static IIO_DEVICE_ATTR(in0_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH1_REG);
+
+static IIO_DEVICE_ATTR(in0_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH1_REG);
+
+static IIO_DEVICE_ATTR(in1_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH2_REG);
+
+static IIO_DEVICE_ATTR(in1_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH2_REG);
+
+static IIO_DEVICE_ATTR(in1_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH2_REG);
+
+static IIO_DEVICE_ATTR(in2_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH3_REG);
+
+static IIO_DEVICE_ATTR(in2_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH3_REG);
+
+static IIO_DEVICE_ATTR(in2_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH3_REG);
+
+static IIO_DEVICE_ATTR(in3_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH4_REG);
+
+static IIO_DEVICE_ATTR(in3_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH4_REG);
+
+static IIO_DEVICE_ATTR(in3_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH4_REG);
 
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 			      ad799x_read_frequency,
@@ -640,18 +626,18 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
 
 static struct attribute *ad7993_4_7_8_event_attributes[] = {
-	&iio_event_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in2_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in2_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in2_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in3_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in3_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in3_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_both_hyst_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
@@ -662,12 +648,12 @@ static struct attribute_group ad7993_4_7_8_event_attrs_group = {
 };
 
 static struct attribute *ad7992_event_attributes[] = {
-	&iio_event_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
@@ -835,23 +821,15 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 		goto error_cleanup_ring;
 
 	if (client->irq > 0 && st->chip_info->monitor_mode) {
-		INIT_WORK(&st->work_thresh, ad799x_interrupt_bh);
-
-		ret = iio_register_interrupt_line(client->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				client->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   ad799x_event_handler,
+					   IRQF_TRIGGER_FALLING |
+					   IRQF_ONESHOT,
+					   client->name,
+					   st->indio_dev);
 		if (ret)
 			goto error_cleanup_ring;
-
-		/*
-		 * The event handler list element refer to iio_event_ad799x.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad799x,
-				&st->indio_dev->interrupts[0]->ev_list);
 	}
 
 	return 0;
@@ -879,7 +857,7 @@ static __devexit int ad799x_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	if (client->irq > 0 && st->chip_info->monitor_mode)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad799x_ring_cleanup(indio_dev);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 026/111] staging:iio: Remove legacy event handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (24 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 025/111] staging:iio:adc:ad799x move to new event handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 027/111] staging:iio:accel:lis3l02dq make threshold interrupt threaded Jonathan Cameron
                   ` (85 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This requires all drivers using the channel registration code and
events to change in one go.

V3: remove unwanted irq enable from event handler.
V2: rebase related fixes to move to new IIO_CHAN macro. All trivial.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq_core.c |   36 +---
 drivers/staging/iio/accel/sca3000_core.c   |   27 +--
 drivers/staging/iio/adc/max1363.h          |    4 -
 drivers/staging/iio/adc/max1363_core.c     |  116 ++++--------
 drivers/staging/iio/chrdev.h               |   21 ---
 drivers/staging/iio/iio.h                  |   86 +---------
 drivers/staging/iio/industrialio-core.c    |  266 +++-------------------------
 drivers/staging/iio/sysfs.h                |  129 --------------
 8 files changed, 85 insertions(+), 600 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index c764fc9..2b70a67 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -416,10 +416,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 
-static irqreturn_t lis3l02dq_event_handler(int irq, void *_int_info)
+static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 {
-	struct iio_interrupt *int_info = _int_info;
-	struct iio_dev *indio_dev = int_info->dev_info;
+	struct iio_dev *indio_dev = private;
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
@@ -442,14 +441,11 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *_int_info)
 
 static struct iio_chan_spec lis3l02dq_channels[] = {
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK,
-		 0, 0, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, NULL),
+		 0, 0, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK,
-		 1, 1, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, NULL),
+		 1, 1, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK,
-		 2, 2, IIO_ST('s', 12, 16, 0),
-		 LIS3L02DQ_EVENT_MASK, NULL),
+		 2, 2, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -508,7 +504,7 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 		goto error_ret;
 
 	if (irqtofree)
-		free_irq(st->us->irq, indio_dev->interrupts[0]);
+		free_irq(st->us->irq, indio_dev);
 
 	ret = control;
 error_ret:
@@ -517,7 +513,6 @@ error_ret:
 
 static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					int event_code,
-					struct iio_event_handler_list *list_el,
 					int state)
 {
 	struct iio_sw_ring_helper_state *h
@@ -559,7 +554,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					  &lis3l02dq_event_handler,
 					  IRQF_TRIGGER_RISING,
 					  "lis3l02dq_event",
-					  indio_dev->interrupts[0]);
+					  indio_dev);
 			if (ret)
 				goto error_ret;
 		}
@@ -580,7 +575,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 
 		/* remove interrupt handler if nothing is still on */
 		if (!(val & 0x3f))
-			free_irq(st->us->irq, indio_dev->interrupts[0]);
+			free_irq(st->us->irq, indio_dev);
 	}
 
 error_ret:
@@ -743,16 +738,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
 		st->inter = 0;
-		ret = iio_register_interrupt_line(spi->irq,
-						  st->help.indio_dev,
-						  0,
-						  IRQF_TRIGGER_RISING,
-						  "lis3l02dq");
-		if (ret)
-			goto error_uninitialize_ring;
 		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
@@ -764,9 +752,6 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 error_remove_trigger:
 	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
 		lis3l02dq_remove_trigger(st->help.indio_dev);
-error_unregister_line:
-	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
-		iio_unregister_interrupt_line(st->help.indio_dev, 0);
 error_uninitialize_ring:
 	iio_ring_buffer_unregister(st->help.indio_dev->ring);
 error_unreg_ring_funcs:
@@ -831,9 +816,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
 	flush_scheduled_work();
 
 	lis3l02dq_remove_trigger(indio_dev);
-	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
 	iio_ring_buffer_unregister(indio_dev->ring);
 	lis3l02dq_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 00704a5..d11fc94 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -440,14 +440,11 @@ static IIO_DEV_ATTR_REV(sca3000_show_rev);
 
 static struct iio_chan_spec sca3000_channels[] = {
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK,
-		 0, 0, IIO_ST('s', 11, 16, 5),
-		 SCA3000_EVENT_MASK, NULL),
+		 0, 0, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK,
-		 1, 1, IIO_ST('s', 11, 16, 5),
-		 SCA3000_EVENT_MASK, NULL),
+		 1, 1, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK,
-		 2, 2, IIO_ST('s', 11, 16, 5),
-		 SCA3000_EVENT_MASK, NULL),
+		 2, 2, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
 };
 
 static u8 sca3000_addresses[3][3] = {
@@ -977,7 +974,6 @@ error_ret:
  **/
 static int sca3000_write_event_config(struct iio_dev *indio_dev,
 				      int e,
-				      struct iio_event_handler_list *list_el,
 				      int state)
 {
 	struct sca3000_state *st = indio_dev->dev_data;
@@ -1032,23 +1028,20 @@ exit_point:
 	return ret;
 }
 
-/* Shared event handler for all events as single event status register */
-IIO_EVENT_SH(all, NULL);
-
 /* Free fall detector related event attribute */
-IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en,
-			accel_x&y&z_mag_falling_en,
-			iio_event_all,
-			sca3000_query_free_fall_mode,
-			sca3000_set_free_fall_mode,
-			0);
+static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en,
+			     accel_x&y&z_mag_falling_en,
+			     S_IRUGO | S_IWUSR,
+			     sca3000_query_free_fall_mode,
+			     sca3000_set_free_fall_mode,
+			     0);
 
 static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
 			    accel_x&y&z_mag_falling_period,
 			    "0.226");
 
 static struct attribute *sca3000_event_attributes[] = {
-	&iio_event_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
+	&iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
 	&iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
 	NULL,
 };
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index b5a3dcd..76635a0 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -189,8 +189,6 @@ struct max1363_chip_info {
  * @mask_low:		bitmask for enabled low thresholds
  * @thresh_high:	high threshold values
  * @thresh_low:		low threshold values
- * @last_timestamp:	timestamp of last event interrupt
- * @thresh_work:	bh work structure for event handling
  */
 struct max1363_state {
 	struct i2c_client		*client;
@@ -213,8 +211,6 @@ struct max1363_state {
 	/* 4x unipolar first then the fours bipolar ones */
 	s16				thresh_high[8];
 	s16				thresh_low[8];
-	s64				last_timestamp;
-	struct work_struct		thresh_work;
 };
 
 const struct max1363_mode
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 66bdc87..892bb41 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -263,20 +263,6 @@ static const enum max1363_modes max1363_mode_list[] = {
 	d0m1to2m3, d1m0to3m2,
 };
 
-static int max1363_int_th(struct iio_dev *indio_dev,
-			int index,
-			s64 timestamp,
-			int not_test)
-{
-	struct max1363_state *st = iio_priv(indio_dev);
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->thresh_work);
-	return 0;
-}
-
-IIO_EVENT_SH(max1363_thresh, max1363_int_th);
-
 #define MAX1363_EV_M						\
 	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)	\
 	 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
@@ -284,71 +270,53 @@ IIO_EVENT_SH(max1363_thresh, max1363_int_th);
 
 static struct iio_chan_spec max1363_channels[] = {
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
-		 _s0, 0, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s0, 0, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
-		 _s1, 1, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s1, 1, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
-		 _s2, 2, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s2, 2, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
-		 _s3, 3, IIO_ST('u', 12, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s3, 3, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
-		 d0m1, 4, IIO_ST('s', 12, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d0m1, 4, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
-		 d2m3, 5, IIO_ST('s', 12, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d2m3, 5, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
-		 d1m0, 6, IIO_ST('s', 12, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d1m0, 6, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
-		 d3m2, 7, IIO_ST('s', 12, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d3m2, 7, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
 	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
 static struct iio_chan_spec max1361_channels[] = {
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
-		 _s0, 0, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s0, 0, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
-		 _s1, 1, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s1, 1, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
-		 _s2, 2, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s2, 2, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
-		 _s3, 3, IIO_ST('u', 10, 16, 0), MAX1363_EV_M,
-		 &iio_event_max1363_thresh),
+		 _s3, 3, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
-		 d0m1, 4, IIO_ST('s', 10, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d0m1, 4, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
-		 d2m3, 5, IIO_ST('s', 10, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d2m3, 5, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
-		 d1m0, 6, IIO_ST('s', 10, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d1m0, 6, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
-		 d3m2, 7, IIO_ST('s', 10, 16, 0),
-		 MAX1363_EV_M, &iio_event_max1363_thresh),
+		 d3m2, 7, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
 	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
 #define MAX1363_CHAN_U(num, address, scan_index, bits)		\
 	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, num, 0, MAX1363_INFO_MASK,	\
 		 address, scan_index, IIO_ST('u', bits,		\
-					     (bits == 8) ? 8 : 16, 0),	\
-		 0, NULL)
+					     (bits == 8) ? 8 : 16, 0), 0)
 /* bipolar channel */
 #define MAX1363_CHAN_B(num, num2, address, scan_index, bits)		\
 	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, num, num2, MAX1363_INFO_MASK,\
 		 address, scan_index, IIO_ST('s', bits,		\
-					     (bits == 8) ? 8 : 16, 0),	\
-		 0, NULL)
+					     (bits == 8) ? 8 : 16, 0), 0)
 
 #define MAX1363_4X_CHANS(bits) {		\
 	MAX1363_CHAN_U(0, _s0, 0, bits),	\
@@ -907,11 +875,11 @@ static int max1363_write_thresh(struct iio_dev *indio_dev,
 	return 0;
 }
 
-static void max1363_thresh_handler_bh(struct work_struct *work_s)
+static irqreturn_t max1363_event_handler(int irq, void *private)
 {
-	struct max1363_state *st = container_of(work_s, struct max1363_state,
-						thresh_work);
-	struct iio_dev *indio_dev = iio_priv_to_dev(st);
+	struct iio_dev *indio_dev = private;
+	struct max1363_state *st = iio_priv(indio_dev);
+	s64 timestamp = iio_get_time_ns();
 	u8 rx;
 	u8 tx[2] = { st->setupbyte,
 		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
@@ -921,37 +889,38 @@ static void max1363_thresh_handler_bh(struct work_struct *work_s)
 	if (rx & (1 << 0))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_LOW_THRESH(3),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 1))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_HIGH_THRESH(3),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 2))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_LOW_THRESH(2),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 3))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_HIGH_THRESH(2),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 4))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_LOW_THRESH(1),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 5))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_HIGH_THRESH(1),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 6))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_LOW_THRESH(0),
-			st->last_timestamp);
+			timestamp);
 	if (rx & (1 << 7))
 		iio_push_event(indio_dev, 0,
 			IIO_EVENT_CODE_IN_HIGH_THRESH(0),
-			st->last_timestamp);
-	enable_irq(st->client->irq);
+			timestamp);
 	i2c_master_send(st->client, tx, 2);
+
+	return IRQ_HANDLED;
 }
 
 static int max1363_read_event_config(struct iio_dev *indio_dev,
@@ -1108,7 +1077,6 @@ error_ret:
 
 static int max1363_write_event_config(struct iio_dev *indio_dev,
 				      int event_code,
-				      struct iio_event_handler_list *listel,
 				      int state)
 {
 	int ret = 0;
@@ -1140,12 +1108,6 @@ static int max1363_write_event_config(struct iio_dev *indio_dev,
 			st->mask_high |= (1 << number);
 		}
 	}
-	if (st->monitor_on && !st->mask_high && !st->mask_low)
-		iio_remove_event_from_list(listel,
-					   &indio_dev->interrupts[0]->ev_list);
-	if (!st->monitor_on && state)
-		iio_add_event_to_list(listel,
-				      &indio_dev->interrupts[0]->ev_list);
 
 	max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
 error_ret:
@@ -1264,15 +1226,15 @@ static int __devinit max1363_probe(struct i2c_client *client,
 		goto error_cleanup_ring;
 
 	if (st->chip_info->monitor_mode && client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-						indio_dev,
-						0,
-						IRQF_TRIGGER_RISING,
-						client->name);
+		ret = request_threaded_irq(st->client->irq,
+					   NULL,
+					   &max1363_event_handler,
+					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					   "max1363_event",
+					   indio_dev);
 
 		if (ret)
 			goto error_uninit_ring;
-		INIT_WORK(&st->thresh_work, max1363_thresh_handler_bh);
 	}
 
 	return 0;
@@ -1304,7 +1266,7 @@ static int max1363_remove(struct i2c_client *client)
 	struct regulator *reg = st->reg;
 
 	if (st->chip_info->monitor_mode && client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(st->client->irq, indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	max1363_ring_cleanup(indio_dev);
 	kfree(indio_dev->available_scan_masks);
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index d72049c..10491f0 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -78,28 +78,7 @@ struct iio_event_interface {
 	void					*private;
 	char					_name[35];
 	char					_attrname[20];
-
-	struct list_head event_attr_list;
 	struct list_head dev_attr_list;
 };
 
-/**
- * struct iio_event_handler_list - element in list of handlers for events
- * @list:		list header
- * @refcount:		as the handler may be shared between multiple device
- *			side events, reference counting ensures clean removal
- * @exist_lock:		prevents race conditions related to refcount usage.
- * @handler:		event handler function - called on event if this
- *			event_handler is enabled.
- *
- * Each device has one list of these per interrupt line.
- **/
-struct iio_event_handler_list {
-	struct list_head	list;
-	int			refcount;
-	struct mutex		exist_lock;
-	int (*handler)(struct iio_dev *dev_info, int index, s64 timestamp,
-		       int no_test);
-};
-
 #endif
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index cd5ac59..1c5e975 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -107,7 +107,6 @@ enum iio_chan_info_enum {
  *			the value in channel will be suppressed for attribute
  *			but not for event codes. Typically set it to 0 when
  *			the index is false.
- * @shared_handler:	Single handler for the events registered.
  */
 struct iio_chan_spec {
 	enum iio_chan_type	type;
@@ -127,9 +126,6 @@ struct iio_chan_spec {
 	unsigned		processed_val:1;
 	unsigned		modified:1;
 	unsigned		indexed:1;
-	/* TODO: investigate pushing shared event handling out to
-	 * the drivers */
-	struct iio_event_handler_list *shared_handler;
 };
 /* Meant for internal use only */
 void __iio_device_attr_deinit(struct device_attribute *dev_attr);
@@ -148,8 +144,7 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
 	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
 
 #define IIO_CHAN(_type, _mod, _indexed, _proc, _name, _chan, _chan2,	\
-		 _inf_mask, _address, _si, _stype, _event_mask,		\
-		 _handler)						\
+		 _inf_mask, _address, _si, _stype, _event_mask)		\
 	{ .type = _type,						\
 	  .modified = _mod,						\
 	  .indexed = _indexed,						\
@@ -161,8 +156,7 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
 	  .address = _address,						\
 	  .scan_index = _si,						\
 	  .scan_type = _stype,						\
-	  .event_mask = _event_mask,					\
-	  .shared_handler = _handler }
+	  .event_mask = _event_mask }
 
 #define IIO_CHAN_SOFT_TIMESTAMP(_si)					\
 	{ .type = IIO_TIMESTAMP, .channel = -1,				\
@@ -197,26 +191,6 @@ static inline s64 iio_get_time_ns(void)
 	return timespec_to_ns(&ts);
 }
 
-/**
- * iio_add_event_to_list() - Wraps adding to event lists
- * @el:		the list element of the event to be handled.
- * @head:	the list associated with the event handler being used.
- *
- * Does reference counting to allow shared handlers.
- **/
-void iio_add_event_to_list(struct iio_event_handler_list *el,
-			   struct list_head *head);
-
-/**
- * iio_remove_event_from_list() - Wraps removing from event list
- * @el:		element to be removed
- * @head:	associate list head for the interrupt handler.
- *
- * Does reference counting to allow shared handlers.
- **/
-void iio_remove_event_from_list(struct iio_event_handler_list *el,
-				struct list_head *head);
-
 /* Device operating modes */
 #define INDIO_DIRECT_MODE		0x01
 #define INDIO_RING_TRIGGERED		0x02
@@ -240,7 +214,6 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
  * @driver_module:	[DRIVER] module structure used to ensure correct
  *			ownership of chrdevs etc
  * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device
- * @interrupts:		[INTERN] interrupt line specific event lists etc
  * @event_attrs:	[DRIVER] event control attributes
  * @event_conf_attrs:	[DRIVER] event configuration attributes
  * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
@@ -279,7 +252,6 @@ struct iio_dev {
 	struct module			*driver_module;
 
 	int				num_interrupt_lines;
-	struct iio_interrupt		**interrupts;
 	struct attribute_group		*event_attrs;
 	struct attribute_group		*event_conf_attrs;
 
@@ -314,7 +286,6 @@ struct iio_dev {
 
 	int (*write_event_config)(struct iio_dev *indio_dev,
 				  int event_code,
-				  struct iio_event_handler_list *listel,
 				  int state);
 
 	int (*read_event_value)(struct iio_dev *indio_dev,
@@ -338,49 +309,6 @@ int iio_device_register(struct iio_dev *dev_info);
 void iio_device_unregister(struct iio_dev *dev_info);
 
 /**
- * struct iio_interrupt - wrapper used to allow easy handling of multiple
- *			physical interrupt lines
- * @dev_info:		the iio device for which the is an interrupt line
- * @line_number:	associated line number
- * @id:			ida allocated unique id number
- * @irq:		associate interrupt number
- * @ev_list:		event handler list for associated events
- * @ev_list_lock:	ensure only one access to list at a time
- **/
-struct iio_interrupt {
-	struct iio_dev			*dev_info;
-	int				line_number;
-	int				id;
-	int				irq;
-	struct list_head		ev_list;
-	spinlock_t			ev_list_lock;
-};
-
-#define to_iio_interrupt(i) container_of(i, struct iio_interrupt, ev_list)
-
-/**
- * iio_register_interrupt_line() - Tell IIO about interrupt lines
- *
- * @irq:		Typically provided via platform data
- * @dev_info:		IIO device info structure for device
- * @line_number:	Which interrupt line of the device is this?
- * @type:		Interrupt type (e.g. edge triggered etc)
- * @name:		Identifying name.
- **/
-int iio_register_interrupt_line(unsigned int			irq,
-				struct iio_dev			*dev_info,
-				int				line_number,
-				unsigned long			type,
-				const char			*name);
-
-void iio_unregister_interrupt_line(struct iio_dev *dev_info,
-				   int line_number);
-
-
-/* temporarily exported to allow moving of interrupt requesting into drivers */
-irqreturn_t iio_interrupt_handler(int irq, void *_int_info);
-
-/**
  * iio_push_event() - try to add event to the list for userspace reading
  * @dev_info:		IIO device structure
  * @ev_line:		Which event line (hardware interrupt)
@@ -393,16 +321,6 @@ int iio_push_event(struct iio_dev *dev_info,
 		  s64 timestamp);
 
 /**
- * __iio_push_event() - tries to add an event to the list associated with a chrdev
- * @ev_int:		the event interface to which we are pushing the event
- * @ev_code:		the outgoing event code
- * @timestamp:		timestamp of the event
- **/
-int __iio_push_event(struct iio_event_interface *ev_int,
-		     int ev_code,
-		     s64 timestamp);
-
-/**
  * iio_allocate_chrdev() - Allocate a chrdev
  * @handler:	struct that contains relevant file handling for chrdev
  * @dev_info:	iio_dev for which chrdev is being created
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 136ff04..52188f9 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -82,16 +82,13 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
 };
 
-/* Used both in the interrupt line put events and the ring buffer ones */
-
-/* Note that in it's current form someone has to be listening before events
- * are queued. Hence a client MUST open the chrdev before the ring buffer is
- * switched on.
- */
-int __iio_push_event(struct iio_event_interface *ev_int,
-		     int ev_code,
-		     s64 timestamp)
+int iio_push_event(struct iio_dev *dev_info,
+		   int ev_line,
+		   int ev_code,
+		   s64 timestamp)
 {
+	struct iio_event_interface *ev_int
+		= &dev_info->event_interfaces[ev_line];
 	struct iio_detected_event_list *ev;
 	int ret = 0;
 
@@ -121,76 +118,8 @@ int __iio_push_event(struct iio_event_interface *ev_int,
 error_ret:
 	return ret;
 }
-EXPORT_SYMBOL(__iio_push_event);
-
-int iio_push_event(struct iio_dev *dev_info,
-		   int ev_line,
-		   int ev_code,
-		   s64 timestamp)
-{
-	return __iio_push_event(&dev_info->event_interfaces[ev_line],
-				ev_code, timestamp);
-}
 EXPORT_SYMBOL(iio_push_event);
 
-/* Generic interrupt line interrupt handler */
-irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
-{
-	struct iio_interrupt *int_info = _int_info;
-	struct iio_dev *dev_info = int_info->dev_info;
-	struct iio_event_handler_list *p;
-	s64 time_ns;
-	unsigned long flags;
-
-	spin_lock_irqsave(&int_info->ev_list_lock, flags);
-	if (list_empty(&int_info->ev_list)) {
-		spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
-		return IRQ_NONE;
-	}
-
-	time_ns = iio_get_time_ns();
-	list_for_each_entry(p, &int_info->ev_list, list) {
-		disable_irq_nosync(irq);
-		p->handler(dev_info, 1, time_ns, !(p->refcount > 1));
-	}
-	spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
-
-	return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(iio_interrupt_handler);
-
-static struct iio_interrupt *iio_allocate_interrupt(void)
-{
-	struct iio_interrupt *i = kmalloc(sizeof *i, GFP_KERNEL);
-	if (i) {
-		spin_lock_init(&i->ev_list_lock);
-		INIT_LIST_HEAD(&i->ev_list);
-	}
-	return i;
-}
-
-/* Confirming the validity of supplied irq is left to drivers.*/
-int iio_register_interrupt_line(unsigned int irq,
-				struct iio_dev *dev_info,
-				int line_number,
-				unsigned long type,
-				const char *name)
-{
-	int ret = 0;
-
-	dev_info->interrupts[line_number] = iio_allocate_interrupt();
-	if (dev_info->interrupts[line_number] == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	dev_info->interrupts[line_number]->line_number = line_number;
-	dev_info->interrupts[line_number]->irq = irq;
-	dev_info->interrupts[line_number]->dev_info = dev_info;
-
-error_ret:
-	return ret;
-}
-EXPORT_SYMBOL(iio_register_interrupt_line);
 
 /* This turns up an awful lot */
 ssize_t iio_read_const_attr(struct device *dev,
@@ -201,52 +130,6 @@ ssize_t iio_read_const_attr(struct device *dev,
 }
 EXPORT_SYMBOL(iio_read_const_attr);
 
-/* Before this runs the interrupt generator must have been disabled */
-void iio_unregister_interrupt_line(struct iio_dev *dev_info, int line_number)
-{
-	/* make sure the interrupt handlers are all done */
-	flush_scheduled_work();
-	kfree(dev_info->interrupts[line_number]);
-}
-EXPORT_SYMBOL(iio_unregister_interrupt_line);
-
-/* Reference counted add and remove */
-void iio_add_event_to_list(struct iio_event_handler_list *el,
-			  struct list_head *head)
-{
-	unsigned long flags;
-	struct iio_interrupt *inter = to_iio_interrupt(head);
-
-	/* take mutex to protect this element */
-	mutex_lock(&el->exist_lock);
-	if (el->refcount == 0) {
-		/* Take the event list spin lock */
-		spin_lock_irqsave(&inter->ev_list_lock, flags);
-		list_add(&el->list, head);
-		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
-	}
-	el->refcount++;
-	mutex_unlock(&el->exist_lock);
-}
-EXPORT_SYMBOL(iio_add_event_to_list);
-
-void iio_remove_event_from_list(struct iio_event_handler_list *el,
-			       struct list_head *head)
-{
-	unsigned long flags;
-	struct iio_interrupt *inter = to_iio_interrupt(head);
-
-	mutex_lock(&el->exist_lock);
-	el->refcount--;
-	if (el->refcount == 0) {
-		/* Take the event list spin lock */
-		spin_lock_irqsave(&inter->ev_list_lock, flags);
-		list_del_init(&el->list);
-		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
-	}
-	mutex_unlock(&el->exist_lock);
-}
-EXPORT_SYMBOL(iio_remove_event_from_list);
 
 static ssize_t iio_event_chrdev_read(struct file *filep,
 				     char __user *buf,
@@ -922,15 +805,14 @@ static ssize_t iio_ev_state_store(struct device *dev,
 				  size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
 	unsigned long val;
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret || val < 0 || val > 1)
 		return -EINVAL;
 
-	ret = indio_dev->write_event_config(indio_dev, this_attr->mask,
-					    this_attr->listel,
+	ret = indio_dev->write_event_config(indio_dev, this_attr->address,
 					    val);
 	return (ret < 0) ? ret : len;
 }
@@ -940,8 +822,8 @@ static ssize_t iio_ev_state_show(struct device *dev,
 				 char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int val = indio_dev->read_event_config(indio_dev, this_attr->mask);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val = indio_dev->read_event_config(indio_dev, this_attr->address);
 
 	if (val < 0)
 		return val;
@@ -987,83 +869,6 @@ static ssize_t iio_ev_value_store(struct device *dev,
 	return len;
 }
 
-static int __iio_add_chan_event_attr(const char *postfix,
-				     const char *group,
-				     struct iio_chan_spec const *chan,
-				     unsigned int mask,
-				     struct device *dev,
-				     struct list_head *attr_list)
-{
-	char *name_format, *full_postfix;
-	int ret;
-	struct iio_event_attr *iio_ev_attr;
-
-	iio_ev_attr = kzalloc(sizeof *iio_ev_attr, GFP_KERNEL);
-	if (iio_ev_attr == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	sysfs_attr_init(&iio_ev_attr->dev_attr.attr);
-	ret = __iio_build_postfix(chan, 0, postfix, &full_postfix);
-	if (ret)
-		goto error_ret;
-	/* Special case for types that uses both channel numbers in naming */
-	if (chan->type == IIO_IN_DIFF)
-		name_format
-			= kasprintf(GFP_KERNEL, "%s_%s",
-				    iio_chan_type_name_spec_complex[chan->type],
-				    full_postfix);
-	else if (!chan->indexed)
-		name_format
-			= kasprintf(GFP_KERNEL, "%s_%s",
-				    iio_chan_type_name_spec_shared[chan->type],
-				    full_postfix);
-	else
-		name_format
-			= kasprintf(GFP_KERNEL, "%s%d_%s",
-				    iio_chan_type_name_spec_shared[chan->type],
-				    chan->channel,
-				    full_postfix);
-	if (name_format == NULL) {
-		ret = -ENOMEM;
-		goto error_free_attr;
-	}
-
-	iio_ev_attr->dev_attr.attr.name = kasprintf(GFP_KERNEL,
-						    name_format,
-						    chan->channel,
-						    chan->channel2);
-	if (iio_ev_attr->dev_attr.attr.name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_name_format;
-	}
-
-	iio_ev_attr->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
-	iio_ev_attr->dev_attr.show = &iio_ev_state_show;
-	iio_ev_attr->dev_attr.store = &iio_ev_state_store;
-	iio_ev_attr->mask = mask;
-	iio_ev_attr->listel = chan->shared_handler;
-	ret = sysfs_add_file_to_group(&dev->kobj,
-				      &iio_ev_attr->dev_attr.attr,
-				      group);
-	if (ret < 0)
-		goto error_free_name;
-	list_add(&iio_ev_attr->l, attr_list);
-	kfree(name_format);
-	return 0;
-
-error_free_name:
-	kfree(iio_ev_attr->dev_attr.attr.name);
-error_free_name_format:
-	kfree(name_format);
-error_free_attr:
-	kfree(iio_ev_attr);
-error_ret:
-	return ret;
-}
-
-
 static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 				      struct iio_chan_spec const *chan)
 {
@@ -1102,18 +907,21 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 		default:
 			printk(KERN_INFO "currently unhandled type of event\n");
 		}
-		ret = __iio_add_chan_event_attr(postfix,
-						NULL,
-						chan,
-						mask,
-						/*HACK. - limits us to one
-						  event interface - fix by
-						  extending the bitmask - but
-						  how far*/
-						&dev_info->event_interfaces[0]
-						.dev,
-						&dev_info->event_interfaces[0].
-						event_attr_list);
+		ret = __iio_add_chan_devattr(postfix,
+					     NULL,
+					     chan,
+					     &iio_ev_state_show,
+					     iio_ev_state_store,
+					     mask,
+					     /*HACK. - limits us to one
+					       event interface - fix by
+					       extending the bitmask - but
+					       how far*/
+					     0,
+					     &dev_info->event_interfaces[0]
+					     .dev,
+					     &dev_info->event_interfaces[0].
+					     dev_attr_list);
 		kfree(postfix);
 		if (ret)
 			goto error_ret;
@@ -1149,7 +957,6 @@ static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info,
 						int num)
 {
 	struct iio_dev_attr *p, *n;
-	struct iio_event_attr *q, *m;
 	list_for_each_entry_safe(p, n,
 				 &dev_info->event_interfaces[num].
 				 dev_attr_list, l) {
@@ -1160,23 +967,12 @@ static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info,
 		kfree(p->dev_attr.attr.name);
 		kfree(p);
 	}
-	list_for_each_entry_safe(q, m,
-				 &dev_info->event_interfaces[num].
-				 event_attr_list, l) {
-		sysfs_remove_file_from_group(&dev_info
-					     ->event_interfaces[num].dev.kobj,
-					     &q->dev_attr.attr,
-					     groupname);
-		kfree(q->dev_attr.attr.name);
-		kfree(q);
-	}
 }
 
 static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 {
 	int j;
 	int ret;
-	/*p for adding, q for removing */
 	struct attribute **attrp, **attrq;
 
 	if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
@@ -1192,7 +988,6 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 			attrp++;
 		}
 	}
-	INIT_LIST_HEAD(&dev_info->event_interfaces[0].event_attr_list);
 	INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list);
 	/* Dynically created from the channels array */
 	if (dev_info->channels) {
@@ -1263,14 +1058,6 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 		goto error_ret;
 	}
 
-	dev_info->interrupts = kzalloc(sizeof(struct iio_interrupt *)
-				       *dev_info->num_interrupt_lines,
-				       GFP_KERNEL);
-	if (dev_info->interrupts == NULL) {
-		ret = -ENOMEM;
-		goto error_free_event_interfaces;
-	}
-
 	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
 		dev_info->event_interfaces[i].owner = dev_info->driver_module;
 
@@ -1328,8 +1115,6 @@ error_remove_sysfs_interfaces:
 error_free_setup_ev_ints:
 	for (j = 0; j < i; j++)
 		iio_free_ev_int(&dev_info->event_interfaces[j]);
-	kfree(dev_info->interrupts);
-error_free_event_interfaces:
 	kfree(dev_info->event_interfaces);
 error_ret:
 
@@ -1352,7 +1137,6 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 
 	for (i = 0; i < dev_info->num_interrupt_lines; i++)
 		iio_free_ev_int(&dev_info->event_interfaces[i]);
-	kfree(dev_info->interrupts);
 	kfree(dev_info->event_interfaces);
 }
 
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 44bd575..6a7642e 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -15,22 +15,6 @@
 #include "iio.h"
 
 /**
- * struct iio_event_attr - event control attribute
- * @dev_attr:	underlying device attribute
- * @mask:	mask for the event when detecting
- * @listel:	list header to allow addition to list of event handlers
-*/
-struct iio_event_attr {
-	struct device_attribute dev_attr;
-	int mask;
-	struct iio_event_handler_list *listel;
-	struct list_head l;
-};
-
-#define to_iio_event_attr(_dev_attr) \
-	container_of(_dev_attr, struct iio_event_attr, dev_attr)
-
-/**
  * struct iio_dev_attr - iio specific device attribute
  * @dev_attr:	underlying device attribute
  * @address:	associated register address
@@ -184,85 +168,6 @@ struct iio_const_attr {
 #define IIO_CONST_ATTR_TEMP_SCALE(_string)		\
 	IIO_CONST_ATTR(temp_scale, _string)
 
-/**
- * IIO_EVENT_SH - generic shared event handler
- * @_name: event name
- * @_handler: handler function to be called
- *
- * This is used in cases where more than one event may result from a single
- * handler.  Often the case that some alarm register must be read and multiple
- * alarms may have been triggered.
- **/
-#define IIO_EVENT_SH(_name, _handler)					\
-	static struct iio_event_handler_list				\
-	iio_event_##_name = {						\
-		.handler = _handler,					\
-		.refcount = 0,						\
-		.exist_lock = __MUTEX_INITIALIZER(iio_event_##_name	\
-						  .exist_lock),		\
-		.list = {						\
-			.next = &iio_event_##_name.list,		\
-			.prev = &iio_event_##_name.list,		\
-		},							\
-	};
-
-/**
- * IIO_EVENT_ATTR_SH - generic shared event attribute
- * @_name: event name
- * @_ev_list: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- *
- * An attribute with an associated IIO_EVENT_SH
- **/
-#define IIO_EVENT_ATTR_SH(_name, _ev_list, _show, _store, _mask)	\
-	static struct iio_event_attr					\
-	iio_event_attr_##_name						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &_ev_list };
-
-#define IIO_EVENT_ATTR_NAMED_SH(_vname, _name, _ev_list, _show, _store, _mask) \
-	static struct iio_event_attr					\
-	iio_event_attr_##_vname						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &_ev_list };
-
-/**
- * IIO_EVENT_ATTR - non-shared event attribute
- * @_name: event name
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- **/
-#define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler)		\
-	IIO_EVENT_SH(_name, _handler);					\
-	static struct							\
-	iio_event_attr							\
-	iio_event_attr_##_name						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &iio_event_##_name };				\
-
-/**
- * IIO_EVENT_ATTR_DATA_RDY - event driven by data ready signal
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- *
- * Not typically implemented in devices where full triggering support
- * has been implemented.
- **/
-#define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \
-	IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler)
-
 /* must match our channel defs */
 #define IIO_EV_CLASS_IN			IIO_IN
 #define IIO_EV_CLASS_IN_DIFF		IIO_IN_DIFF
@@ -322,38 +227,4 @@ struct iio_const_attr {
 
 #define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 13) & 0x7)
 
-/**
- * IIO_EVENT_ATTR_RING_50_FULL - ring buffer event to indicate 50% full
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- **/
-#define IIO_EVENT_ATTR_RING_50_FULL(_show, _store, _mask, _handler)	\
-	IIO_EVENT_ATTR(ring_50_full, _show, _store, _mask, _handler)
-
-/**
- * IIO_EVENT_ATTR_RING_50_FULL_SH - shared ring event to indicate 50% full
- * @_evlist: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- **/
-#define IIO_EVENT_ATTR_RING_50_FULL_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ring_50_full, _evlist, _show, _store, _mask)
-
-/**
- * IIO_EVENT_ATTR_RING_75_FULL_SH - shared ring event to indicate 75% full
- * @_evlist: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- **/
-#define IIO_EVENT_ATTR_RING_75_FULL_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ring_75_full, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_CODE_RING_50_FULL	IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_RING_75_FULL	IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_RING_100_FULL	IIO_BUFFER_EVENT_CODE(2)
-
 #endif /* _INDUSTRIAL_IO_SYSFS_H_ */
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 027/111] staging:iio:accel:lis3l02dq make threshold interrupt threaded.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (25 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 026/111] staging:iio: Remove legacy " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 028/111] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
                   ` (84 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

We have moved the timestamp acquisition into the bottom half. It may
technically be less accurate but for this device I very much doubt
anyone cares!

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    4 -
 drivers/staging/iio/accel/lis3l02dq_core.c |  159 +++++++++++++---------------
 2 files changed, 73 insertions(+), 90 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index d366a97..67f312d 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -150,8 +150,6 @@ Form of high byte dependent on justification set in ctrl reg */
  * struct lis3l02dq_state - device instance specific data
  * @helper:		data and func pointer allowing generic functions
  * @us:			actual spi_device
- * @work_thresh:	bh for threshold events
- * @thresh_timestamp:	timestamp for threshold interrupts.
  * @inter:		used to check if new interrupt has been triggered
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -161,8 +159,6 @@ Form of high byte dependent on justification set in ctrl reg */
 struct lis3l02dq_state {
 	struct iio_sw_ring_helper_state	help;
 	struct spi_device		*us;
-	struct work_struct		work_thresh;
-	s64				thresh_timestamp;
 	bool				inter;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 2b70a67..6c5f8a6 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -422,10 +422,72 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	u8 t;
+
+	s64 timestamp = iio_get_time_ns();
+
+	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
+				 &t);
 
-	disable_irq_nosync(irq);
-	st->thresh_timestamp = iio_get_time_ns();
-	schedule_work(&st->work_thresh);
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_Z,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_RISING),
+			       timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_Z,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_FALLING),
+			       timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_Y,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_RISING),
+			       timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_Y,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_FALLING),
+			       timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_X,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_RISING),
+			       timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
+		iio_push_event(st->help.indio_dev, 0,
+			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
+						  0,
+						  IIO_EV_MOD_X,
+						  IIO_EV_TYPE_THRESH,
+						  IIO_EV_DIR_FALLING),
+			       timestamp);
+
+	/* Ack and allow for new interrupts */
+	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
+				 &t);
 
 	return IRQ_HANDLED;
 }
@@ -550,11 +612,13 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 
 	if (changed) {
 		if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
-			ret = request_irq(st->us->irq,
-					  &lis3l02dq_event_handler,
-					  IRQF_TRIGGER_RISING,
-					  "lis3l02dq_event",
-					  indio_dev);
+			ret = request_threaded_irq(st->us->irq,
+						   NULL,
+						   &lis3l02dq_event_handler,
+						   IRQF_TRIGGER_RISING |
+						   IRQF_ONESHOT,
+						   "lis3l02dq_event",
+						   indio_dev);
 			if (ret)
 				goto error_ret;
 		}
@@ -583,83 +647,6 @@ error_ret:
 	return ret;
 }
 
-/* Unforunately it appears the interrupt won't clear unless you read from the
- * src register.
- */
-static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
-{
-	struct lis3l02dq_state *st
-		= container_of(work_s,
-			       struct lis3l02dq_state, work_thresh);
-	u8 t;
-
-	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
-				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
-				 &t);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_Z,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_Z,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_Y,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_Y,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_X,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
-
-	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
-		iio_push_event(st->help.indio_dev, 0,
-			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
-						  0,
-						  IIO_EV_MOD_X,
-						  IIO_EV_TYPE_THRESH,
-						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
-	/* reenable the irq */
-	enable_irq(st->us->irq);
-	/* Ack and allow for new interrupts */
-	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
-				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
-				 &t);
-
-	return;
-}
-
 static IIO_CONST_ATTR_NAME("lis3l02dq");
 
 static struct attribute *lis3l02dq_attributes[] = {
@@ -681,7 +668,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 		ret =  -ENOMEM;
 		goto error_ret;
 	}
-	INIT_WORK(&st->work_thresh, lis3l02dq_thresh_handler_bh_no_check);
+
 	/* this is only used tor removal purposes */
 	spi_set_drvdata(spi, st);
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 028/111] staging:iio: Add infrastructure for irq_chip based triggers
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (26 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 027/111] staging:iio:accel:lis3l02dq make threshold interrupt threaded Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 029/111] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
                   ` (83 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V3: Get rid of separate interrupt pool. This is well handled
    by irq_get_descs and irq_free_descs.  Two functions I simply
    wasn't aware of previously.  Thus the allocation for a given
    trigger is now handled by core code rather than us reinventing
    the wheel.

V2: Stop silly name duplication.
    Move pool handling to industrialio-trigger as that is the only user.
    Changed over to using irq_modify_status rather than the arm
    specific set_irq_flags as per Thomas Gleixner's suggestion.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/Kconfig                |    7 +
 drivers/staging/iio/industrialio-trigger.c |  175 +++++++++++++++++++++++-----
 drivers/staging/iio/trigger.h              |   57 ++++++++-
 3 files changed, 203 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 6775bf9..e6235d1 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -48,6 +48,13 @@ config IIO_TRIGGER
 	  ring buffers.  The triggers are effectively a 'capture
 	  data now' interrupt.
 
+config IIO_CONSUMERS_PER_TRIGGER
+       int "Maximum number of consumers per trigger"
+       depends on IIO_TRIGGER
+       default "2"
+       help
+	This value controls the maximum number of consumers that a
+	given trigger may handle. Default is 2.
 
 source "drivers/staging/iio/accel/Kconfig"
 source "drivers/staging/iio/adc/Kconfig"
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 083847c..5496ee2 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -163,6 +163,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
 
 void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 {
+	int i;
 	struct iio_poll_func *pf_cursor;
 
 	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
@@ -178,6 +179,13 @@ void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 			trig->use_count++;
 		}
 	}
+	if (!trig->use_count) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
+			if (trig->subirqs[i].enabled) {
+				trig->use_count++;
+				generic_handle_irq(trig->subirq_base + i);
+			}
+	}
 }
 EXPORT_SYMBOL(iio_trigger_poll);
 
@@ -219,16 +227,31 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
 	int ret = 0;
 	unsigned long flags;
 
-	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-	list_add_tail(&pf->list, &trig->pollfunc_list);
-	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
-
-	if (trig->set_trigger_state)
-		ret = trig->set_trigger_state(trig, true);
-	if (ret) {
-		printk(KERN_ERR "set trigger state failed\n");
-		list_del(&pf->list);
+	if (pf->thread) {
+		bool notinuse
+			= bitmap_empty(trig->pool,
+				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+
+		pf->irq = iio_trigger_get_irq(trig);
+		ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
+					   pf->type, pf->name,
+					   pf);
+		if (trig->set_trigger_state && notinuse) {
+			ret = trig->set_trigger_state(trig, true);
+	} else {
+		spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+		list_add_tail(&pf->list, &trig->pollfunc_list);
+		spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+
+		if (trig->set_trigger_state)
+			ret = trig->set_trigger_state(trig, true);
+		}
+		if (ret) {
+			printk(KERN_ERR "set trigger state failed\n");
+			list_del(&pf->list);
+		}
 	}
+
 	return ret;
 }
 EXPORT_SYMBOL(iio_trigger_attach_poll_func);
@@ -240,37 +263,63 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 	unsigned long flags;
 	int ret = -EINVAL;
 
-	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list)
-		if (pf_cursor == pf) {
-			ret = 0;
-			break;
-		}
-	if (!ret) {
-		if (list_is_singular(&trig->pollfunc_list)
-		    && trig->set_trigger_state) {
-			spin_unlock_irqrestore(&trig->pollfunc_list_lock,
-					       flags);
-			/* May sleep hence cannot hold the spin lock */
+	if (pf->thread) {
+		bool no_other_users
+			= (bitmap_weight(trig->pool,
+					 CONFIG_IIO_CONSUMERS_PER_TRIGGER)
+			   == 1);
+		if (trig->set_trigger_state && no_other_users) {
 			ret = trig->set_trigger_state(trig, false);
 			if (ret)
 				goto error_ret;
-			spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+		} else
+			ret = 0;
+		iio_trigger_put_irq(trig, pf->irq);
+		free_irq(pf->irq, pf);
+	} else {
+		spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+		list_for_each_entry(pf_cursor, &trig->pollfunc_list, list)
+			if (pf_cursor == pf) {
+				ret = 0;
+				break;
+			}
+		if (!ret) {
+			if (list_is_singular(&trig->pollfunc_list)
+			    && trig->set_trigger_state) {
+				spin_unlock_irqrestore(&trig
+						       ->pollfunc_list_lock,
+						       flags);
+				/* May sleep hence cannot hold the spin lock */
+				ret = trig->set_trigger_state(trig, false);
+				if (ret)
+					goto error_ret;
+				spin_lock_irqsave(&trig->pollfunc_list_lock,
+						  flags);
+			}
+			/*
+			 * Now we can delete safe in the knowledge that, if
+			 * this is the last pollfunc then we have disabled
+			 * the trigger anyway and so nothing should be able
+			 * to call the pollfunc.
+			 */
+			list_del(&pf_cursor->list);
 		}
-		/*
-		 * Now we can delete safe in the knowledge that, if this is
-		 * the last pollfunc then we have disabled the trigger anyway
-		 * and so nothing should be able to call the pollfunc.
-		 */
-		list_del(&pf_cursor->list);
+		spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
 	}
-	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
 
 error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_trigger_dettach_poll_func);
 
+irqreturn_t iio_pollfunc_store_time(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	pf->timestamp = iio_get_time_ns();
+	return IRQ_WAKE_THREAD;
+}
+EXPORT_SYMBOL(iio_pollfunc_store_time);
+
 /**
  * iio_trigger_read_currrent() - trigger consumer sysfs query which trigger
  *
@@ -337,6 +386,22 @@ static const struct attribute_group iio_trigger_consumer_attr_group = {
 static void iio_trig_release(struct device *device)
 {
 	struct iio_trigger *trig = to_iio_trigger(device);
+	int i;
+
+	if (trig->subirq_base) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			irq_modify_status(trig->subirq_base + i,
+					  IRQ_NOAUTOEN,
+					  IRQ_NOREQUEST | IRQ_NOPROBE);
+			irq_set_chip(trig->subirq_base + i,
+				     NULL);
+			irq_set_handler(trig->subirq_base + i,
+					NULL);
+		}
+
+		irq_free_descs(trig->subirq_base,
+			       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+	}
 	kfree(trig);
 	iio_put();
 }
@@ -345,11 +410,30 @@ static struct device_type iio_trig_type = {
 	.release = iio_trig_release,
 };
 
-struct iio_trigger *iio_allocate_trigger(void)
+static void iio_trig_subirqmask(struct irq_data *d)
+{
+	struct irq_chip *chip = irq_data_get_irq_chip(d);
+	struct iio_trigger *trig
+		= container_of(chip,
+			       struct iio_trigger, subirq_chip);
+	trig->subirqs[d->irq - trig->subirq_base].enabled = false;
+}
+
+static void iio_trig_subirqunmask(struct irq_data *d)
+{
+	struct irq_chip *chip = irq_data_get_irq_chip(d);
+	struct iio_trigger *trig
+		= container_of(chip,
+			       struct iio_trigger, subirq_chip);
+	trig->subirqs[d->irq - trig->subirq_base].enabled = true;
+}
+
+struct iio_trigger *iio_allocate_trigger_named(const char *name)
 {
 	struct iio_trigger *trig;
 	trig = kzalloc(sizeof *trig, GFP_KERNEL);
 	if (trig) {
+		int i;
 		trig->dev.type = &iio_trig_type;
 		trig->dev.bus = &iio_bus_type;
 		device_initialize(&trig->dev);
@@ -357,10 +441,41 @@ struct iio_trigger *iio_allocate_trigger(void)
 		spin_lock_init(&trig->pollfunc_list_lock);
 		INIT_LIST_HEAD(&trig->list);
 		INIT_LIST_HEAD(&trig->pollfunc_list);
+
+		if (name) {
+			mutex_init(&trig->pool_lock);
+			trig->subirq_base
+				= irq_alloc_descs(-1, 0,
+					CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+					0);
+			if (trig->subirq_base < 0) {
+				kfree(trig);
+				return NULL;
+			}
+			trig->name = name;
+			trig->subirq_chip.name = name;
+			trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
+			trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
+			for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+				irq_set_chip(trig->subirq_base + i,
+					     &trig->subirq_chip);
+				irq_set_handler(trig->subirq_base + i,
+						&handle_simple_irq);
+				irq_modify_status(trig->subirq_base + i,
+						  IRQ_NOREQUEST | IRQ_NOAUTOEN,
+						  IRQ_NOPROBE);
+			}
+		}
 		iio_get();
 	}
 	return trig;
 }
+EXPORT_SYMBOL(iio_allocate_trigger_named);
+
+struct iio_trigger *iio_allocate_trigger(void)
+{
+	return iio_allocate_trigger_named(NULL);
+}
 EXPORT_SYMBOL(iio_allocate_trigger);
 
 void iio_free_trigger(struct iio_trigger *trig)
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index c6ab32f..0c44c5e 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -6,9 +6,15 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
+#include <linux/irq.h>
+
 #ifndef _IIO_TRIGGER_H_
 #define _IIO_TRIGGER_H_
 
+struct iio_subirq {
+	bool enabled;
+};
+
 /**
  * struct iio_trigger - industrial I/O trigger device
  *
@@ -43,6 +49,13 @@ struct iio_trigger {
 
 	int (*set_trigger_state)(struct iio_trigger *trig, bool state);
 	int (*try_reenable)(struct iio_trigger *trig);
+
+	struct irq_chip			subirq_chip;
+	int				subirq_base;
+
+	struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER];
+	unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)];
+	struct mutex			pool_lock;
 };
 
 static inline struct iio_trigger *to_iio_trigger(struct device *d)
@@ -114,6 +127,27 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 void iio_trigger_poll(struct iio_trigger *trig, s64 time);
 void iio_trigger_notify_done(struct iio_trigger *trig);
 
+static inline int iio_trigger_get_irq(struct iio_trigger *trig)
+{
+	int ret;
+	mutex_lock(&trig->pool_lock);
+	ret = bitmap_find_free_region(trig->pool,
+				      CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+				      ilog2(1));
+	mutex_unlock(&trig->pool_lock);
+	if (ret >= 0)
+		ret += trig->subirq_base;
+
+	return ret;
+};
+
+static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
+{
+	mutex_lock(&trig->pool_lock);
+	clear_bit(irq - trig->subirq_base, trig->pool);
+	mutex_unlock(&trig->pool_lock);
+};
+
 /**
  * struct iio_poll_func - poll function pair
  *
@@ -125,11 +159,14 @@ void iio_trigger_notify_done(struct iio_trigger *trig);
  * @poll_func_main:		function in here is run after all immediates.
  *				Reading from sensor etc typically involves
  *				scheduling from here.
- *
- * The two stage approach used here is only important when multiple sensors are
- * being triggered by a single trigger. This really comes into its own with
- * simultaneous sampling devices where a simple latch command can be used to
- * make the device store the values on all inputs.
+ * @h:				the function that is actually run on trigger
+ * @thread:			threaded interrupt part
+ * @type:			the type of interrupt (basically if oneshot)
+ * @irq:			the corresponding irq as allocated from the
+ *				trigger pool
+ * @timestamp:			some devices need a timestamp grabbed as soon
+ *				as possible after the trigger - hence handler
+ *				passes it via here.
  **/
 struct iio_poll_func {
 	struct				list_head list;
@@ -137,12 +174,20 @@ struct iio_poll_func {
 	void (*poll_func_immediate)(struct iio_dev *indio_dev);
 	void (*poll_func_main)(struct iio_dev *private_data, s64 time);
 
+	irqreturn_t (*h)(int irq, void *p);
+	irqreturn_t (*thread)(int irq, void *p);
+	int type;
+	char *name;
+	int irq;
+	s64 timestamp;
 };
 
 int iio_alloc_pollfunc(struct iio_dev *indio_dev,
 		       void (*immediate)(struct iio_dev *indio_dev),
 		       void (*main)(struct iio_dev *private_data, s64 time));
 
+irqreturn_t iio_pollfunc_store_time(int irq, void *p);
+
 /*
  * Two functions for common case where all that happens is a pollfunc
  * is attached and detached from a trigger
@@ -151,7 +196,7 @@ int iio_triggered_ring_postenable(struct iio_dev *indio_dev);
 int iio_triggered_ring_predisable(struct iio_dev *indio_dev);
 
 struct iio_trigger *iio_allocate_trigger(void);
-
+struct iio_trigger *iio_allocate_trigger_named(const char *name);
 void iio_free_trigger(struct iio_trigger *trig);
 
 #endif /* _IIO_TRIGGER_H_ */
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 029/111] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (27 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 028/111] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 030/111] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
                   ` (82 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Trivial space before newline fix incorporated.

Additional fixes related to handling of sign extension and shifted
data.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>

squash into buffer handling update.
---
 drivers/staging/iio/Documentation/generic_buffer.c |   93 +++++++------------
 drivers/staging/iio/Documentation/iio_utils.h      |   20 +---
 2 files changed, 39 insertions(+), 74 deletions(-)

diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index eb72e95..f82894f 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -27,6 +27,7 @@
 #include <sys/dir.h>
 #include <linux/types.h>
 #include <string.h>
+#include <poll.h>
 #include "iio_utils.h"
 
 /**
@@ -53,6 +54,24 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
 	return bytes;
 }
 
+void print2byte(int input, struct iio_channel_info *info)
+{
+	/* shift before conversion to avoid sign extension
+	   of left aligned data */
+	input = input >> info->shift;
+	if (info->is_signed) {
+		int16_t val = input;
+		val &= (1 << info->bits_used) - 1;
+		val = (int16_t)(val << (16 - info->bits_used)) >>
+			(16 - info->bits_used);
+		printf("%05f  ", val,
+		       (float)(val + info->offset)*info->scale);
+	} else {
+		uint16_t val = input;
+		val &= (1 << info->bits_used) - 1;
+		printf("%05f ", ((float)val + info->offset)*info->scale);
+	}
+}
 /**
  * process_scan() - print out the values in SI units
  * @data:		pointer to the start of the scan
@@ -70,25 +89,8 @@ void process_scan(char *data,
 		switch (infoarray[k].bytes) {
 			/* only a few cases implemented so far */
 		case 2:
-			if (infoarray[k].is_signed) {
-				int16_t val = *(int16_t *)
-					(data
-					 + infoarray[k].location);
-				if ((val >> infoarray[k].bits_used) & 1)
-					val = (val & infoarray[k].mask) |
-						~infoarray[k].mask;
-				printf("%05f ", ((float)val +
-						 infoarray[k].offset)*
-				       infoarray[k].scale);
-			} else {
-				uint16_t val = *(uint16_t *)
-					(data +
-					 infoarray[k].location);
-				val = (val & infoarray[k].mask);
-				printf("%05f ", ((float)val +
-						 infoarray[k].offset)*
-				       infoarray[k].scale);
-			}
+			print2byte(*(uint16_t *)(data + infoarray[k].location),
+				   &infoarray[k]);
 			break;
 		case 8:
 			if (infoarray[k].is_signed) {
@@ -133,9 +135,8 @@ int main(int argc, char **argv)
 	int datardytrigger = 1;
 	char *data;
 	ssize_t read_size;
-	struct iio_event_data dat;
 	int dev_num, trig_num;
-	char *buffer_access, *buffer_event;
+	char *buffer_access;
 	int scan_size;
 	int noevents = 0;
 	char *dummy;
@@ -210,7 +211,7 @@ int main(int argc, char **argv)
 	 */
 	ret = build_channel_array(dev_dir_name, &infoarray, &num_channels);
 	if (ret) {
-		printf("Problem reading scan element information \n");
+		printf("Problem reading scan element information\n");
 		goto error_free_triggername;
 	}
 
@@ -251,54 +252,32 @@ int main(int argc, char **argv)
 	}
 
 	ret = asprintf(&buffer_access,
-		       "/dev/device%d:buffer0:access0",
+		       "/dev/device%d:buffer0",
 		       dev_num);
 	if (ret < 0) {
 		ret = -ENOMEM;
 		goto error_free_data;
 	}
 
-	ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num);
-	if (ret < 0) {
-		ret = -ENOMEM;
-		goto error_free_buffer_access;
-	}
 	/* Attempt to open non blocking the access dev */
 	fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
 	if (fp == -1) { /*If it isn't there make the node */
 		printf("Failed to open %s\n", buffer_access);
 		ret = -errno;
-		goto error_free_buffer_event;
-	}
-	/* Attempt to open the event access dev (blocking this time) */
-	fp_ev = fopen(buffer_event, "rb");
-	if (fp_ev == NULL) {
-		printf("Failed to open %s\n", buffer_event);
-		ret = -errno;
-		goto error_close_buffer_access;
+		goto error_free_buffer_access;
 	}
 
 	/* Wait for events 10 times */
 	for (j = 0; j < num_loops; j++) {
 		if (!noevents) {
-			read_size = fread(&dat,
-					1,
-					sizeof(struct iio_event_data),
-					fp_ev);
-			switch (dat.id) {
-			case IIO_EVENT_CODE_RING_100_FULL:
-				toread = buf_len;
-				break;
-			case IIO_EVENT_CODE_RING_75_FULL:
-				toread = buf_len*3/4;
-				break;
-			case IIO_EVENT_CODE_RING_50_FULL:
-				toread = buf_len/2;
-				break;
-			default:
-				printf("Unexpecteded event code\n");
-				continue;
-			}
+			struct pollfd pfd = {
+				.fd = fp,
+				.events = POLLIN,
+			};
+
+			poll(&pfd, 1, -1);
+			toread = buf_len;
+
 		} else {
 			usleep(timedelay);
 			toread = 64;
@@ -320,22 +299,18 @@ int main(int argc, char **argv)
 	/* Stop the ring buffer */
 	ret = write_sysfs_int("enable", buf_dir_name, 0);
 	if (ret < 0)
-		goto error_close_buffer_event;
+		goto error_close_buffer_access;
 
 	/* Disconnect from the trigger - just write a dummy name.*/
 	write_sysfs_string("trigger/current_trigger",
 			dev_dir_name, "NULL");
 
-error_close_buffer_event:
-	fclose(fp_ev);
 error_close_buffer_access:
 	close(fp);
 error_free_data:
 	free(data);
 error_free_buffer_access:
 	free(buffer_access);
-error_free_buffer_event:
-	free(buffer_event);
 error_free_buf_dir_name:
 	free(buf_dir_name);
 error_free_triggername:
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index fd78e4f..150f440 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -16,25 +16,11 @@
 
 #define IIO_MAX_NAME_LENGTH 30
 
-#define IIO_EV_CLASS_BUFFER		0
-#define IIO_BUFFER_EVENT_CODE(code)		\
-	(IIO_EV_CLASS_BUFFER | (code << 8))
-
-#define IIO_EVENT_CODE_RING_50_FULL	IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_RING_75_FULL	IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_RING_100_FULL	IIO_BUFFER_EVENT_CODE(2)
-
-
 #define FORMAT_SCAN_ELEMENTS_DIR "%s:buffer0/scan_elements"
 #define FORMAT_TYPE_FILE "%s_type"
 
 const char *iio_dir = "/sys/bus/iio/devices/";
 
-struct iio_event_data {
-	int id;
-	__s64 timestamp;
-};
-
 /**
  * iioutils_break_up_name() - extract generic name from full channel name
  * @full_name: the full channel name
@@ -85,6 +71,7 @@ struct iio_channel_info {
 	unsigned index;
 	unsigned bytes;
 	unsigned bits_used;
+	unsigned shift;
 	uint64_t mask;
 	unsigned is_signed;
 	unsigned enabled;
@@ -103,6 +90,7 @@ struct iio_channel_info {
 inline int iioutils_get_type(unsigned *is_signed,
 			     unsigned *bytes,
 			     unsigned *bits_used,
+			     unsigned *shift,
 			     uint64_t *mask,
 			     const char *device_dir,
 			     const char *name,
@@ -157,7 +145,8 @@ inline int iioutils_get_type(unsigned *is_signed,
 				goto error_free_filename;
 			}
 			fscanf(sysfsfp,
-			       "%c%u/%u", &signchar, bits_used, &padint);
+			       "%c%u/%u>>%u", &signchar, bits_used,
+			       &padint, shift);
 			*bytes = padint / 8;
 			if (*bits_used == 64)
 				*mask = ~0;
@@ -395,6 +384,7 @@ inline int build_channel_array(const char *device_dir,
 			ret = iioutils_get_type(&current->is_signed,
 						&current->bytes,
 						&current->bits_used,
+						&current->shift,
 						&current->mask,
 						device_dir,
 						current->name,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 030/111] staging:iio:ring_sw add function needed for threaded irq.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (28 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 029/111] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 031/111] staging:iio: add generic data ready poll function Jonathan Cameron
                   ` (81 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/ring_sw.c |   14 ++++++++++----
 drivers/staging/iio/ring_sw.h |    1 +
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 40beadd..d55757b 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -455,11 +455,8 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 }
 EXPORT_SYMBOL(iio_sw_ring_preenable);
 
-void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
+void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st)
 {
-	struct iio_sw_ring_helper_state *st
-		= container_of(work_s, struct iio_sw_ring_helper_state,
-			work_trigger_to_ring);
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
 	int len = 0;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
@@ -488,6 +485,15 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
 
 	return;
 }
+EXPORT_SYMBOL(iio_sw_trigger_to_ring);
+
+void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct iio_sw_ring_helper_state *st
+		= container_of(work_s, struct iio_sw_ring_helper_state,
+			work_trigger_to_ring);
+	iio_sw_trigger_to_ring(st);
+}
 EXPORT_SYMBOL(iio_sw_trigger_bh_to_ring);
 
 void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index 7d56524..84b7c5a 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -216,6 +216,7 @@ struct iio_sw_ring_helper_state {
 
 void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time);
 void iio_sw_trigger_bh_to_ring(struct work_struct *work_s);
+void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st);
 
 #else /* CONFIG_IIO_RING_BUFFER*/
 struct iio_sw_ring_helper_state {
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 031/111] staging:iio: add generic data ready poll function.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (29 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 030/111] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 032/111] staging:iio:accel:lis3l02dq move to threaded trigger handling Jonathan Cameron
                   ` (80 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This case is extremely common, so let us only have the one
copy.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-trigger.c |    7 +++++++
 drivers/staging/iio/trigger.h              |    2 ++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 5496ee2..d045b6c 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -189,6 +189,13 @@ void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 }
 EXPORT_SYMBOL(iio_trigger_poll);
 
+irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private)
+{
+	iio_trigger_poll(private, iio_get_time_ns());
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
+
 void iio_trigger_notify_done(struct iio_trigger *trig)
 {
 	trig->use_count--;
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 0c44c5e..8e25c00 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -127,6 +127,8 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 void iio_trigger_poll(struct iio_trigger *trig, s64 time);
 void iio_trigger_notify_done(struct iio_trigger *trig);
 
+irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
+
 static inline int iio_trigger_get_irq(struct iio_trigger *trig)
 {
 	int ret;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 032/111] staging:iio:accel:lis3l02dq move to threaded trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (30 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 031/111] staging:iio: add generic data ready poll function Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 033/111] staging:iio:adc:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
                   ` (79 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V2: Cleaned up handling of name string.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    2 -
 drivers/staging/iio/accel/lis3l02dq_core.c |    6 -
 drivers/staging/iio/accel/lis3l02dq_ring.c |  139 +++++++++++-----------------
 3 files changed, 56 insertions(+), 91 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 67f312d..a910f2d 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -150,7 +150,6 @@ Form of high byte dependent on justification set in ctrl reg */
  * struct lis3l02dq_state - device instance specific data
  * @helper:		data and func pointer allowing generic functions
  * @us:			actual spi_device
- * @inter:		used to check if new interrupt has been triggered
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
@@ -159,7 +158,6 @@ Form of high byte dependent on justification set in ctrl reg */
 struct lis3l02dq_state {
 	struct iio_sw_ring_helper_state	help;
 	struct spi_device		*us;
-	bool				inter;
 	struct iio_trigger		*trig;
 	u8				*tx;
 	u8				*rx;
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 6c5f8a6..b1fb049 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -15,15 +15,12 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
-
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -724,7 +721,6 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 	}
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		st->inter = 0;
 		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
@@ -800,8 +796,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
-
 	lis3l02dq_remove_trigger(indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	lis3l02dq_unconfigure_ring(indio_dev);
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 9bc2e5f..d261bd6 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -1,13 +1,11 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/slab.h>
 
 #include "../iio.h"
@@ -29,37 +27,6 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
 }
 
 /**
- * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	/* in this case we need to slightly extend the helper function */
-	iio_sw_poll_func_th(indio_dev, time);
-
-	/* Indicate that this interrupt is being handled */
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently now way for the interrupt
-	 * to clear.
-	 */
-	st->inter = 1;
-}
-
-/**
- * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-
-	return IRQ_HANDLED;
-}
-
-/**
  * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
  **/
 ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
@@ -153,15 +120,16 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 	return ret;
 }
 
-static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
 {
-	struct iio_sw_ring_helper_state *h
-		= container_of(work_s, struct iio_sw_ring_helper_state,
-			work_trigger_to_ring);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
 
-	st->inter = 0;
-	iio_sw_trigger_bh_to_ring(work_s);
+	h->last_timestamp = pf->timestamp;
+	iio_sw_trigger_to_ring(h);
+
+	return IRQ_HANDLED;
 }
 
 static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
@@ -236,7 +204,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 		valold = ret |
 			LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
 		ret = request_irq(st->us->irq,
-				  lis3l02dq_data_rdy_trig_poll,
+				  &iio_trigger_generic_data_rdy_poll,
 				  IRQF_TRIGGER_RISING, "lis3l02dq_datardy",
 				  st->trig);
 		if (ret)
@@ -272,10 +240,10 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 
 	__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, state);
 	if (state == false) {
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-		/* Clear any outstanding ready events */
+		/*
+		 * A possible quirk with teh handler is currently worked around
+		 *  by ensuring outstanding read events are cleared.
+		 */
 		ret = lis3l02dq_read_all(st, NULL);
 	}
 	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
@@ -298,32 +266,23 @@ static const struct attribute_group lis3l02dq_trigger_attr_group = {
 /**
  * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
  * @trig:	the datardy trigger
- *
- * As the trigger may occur on any data element being updated it is
- * really rather likely to occur during the read from the previous
- * trigger event.  The only way to discover if this has occurred on
- * boards not supporting level interrupts is to take a look at the line.
- * If it is indicating another interrupt and we don't seem to have a
- * handler looking at it, then we need to notify the core that we need
- * to tell the triggering core to try reading all these again.
- **/
+ */
 static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
 {
 	struct lis3l02dq_state *st = trig->private_data;
-	enable_irq(st->us->irq);
+	int i;
+
 	/* If gpio still high (or high again) */
-	if (gpio_get_value(irq_to_gpio(st->us->irq)))
-		if (st->inter == 0) {
-			/* already interrupt handler dealing with it */
-			disable_irq_nosync(st->us->irq);
-			if (st->inter == 1) {
-				/* interrupt handler snuck in between test
-				 * and disable */
-				enable_irq(st->us->irq);
-				return 0;
-			}
-			return -EAGAIN;
-		}
+	/* In theory possible we will need to do this several times */
+	for (i = 0; i < 5; i++)
+		if (gpio_get_value(irq_to_gpio(st->us->irq)))
+			lis3l02dq_read_all(st, NULL);
+		else
+			break;
+	if (i == 5)
+		printk(KERN_INFO
+		       "Failed to clear the interrupt for lis3l02dq\n");
+
 	/* irq reenabled so success! */
 	return 0;
 }
@@ -334,17 +293,19 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (!st->trig)
-		return -ENOMEM;
-
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "lis3l02dq-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
+	name = kasprintf(GFP_KERNEL,
+			 "lis3l02dq-dev%d",
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
+	}
+	st->trig = iio_allocate_trigger_named(name);
+	if (!st->trig) {
+		ret = -ENOMEM;
+		goto error_free_name;
 	}
 
 	st->trig->dev.parent = &st->us->dev;
@@ -355,15 +316,15 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->control_attrs = &lis3l02dq_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_trig;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_free_name:
+	kfree(name);
+error_ret:
 	return ret;
 }
 
@@ -380,6 +341,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 
 void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	lis3l02dq_free_buf(indio_dev->ring);
 }
@@ -459,7 +421,7 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 	int ret;
 	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
+
 	h->get_ring_element = &lis3l02dq_get_ring_element;
 
 	ring = lis3l02dq_alloc_buf(indio_dev);
@@ -482,9 +444,20 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, 1);
 	iio_scan_mask_set(ring, 2);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
-	if (ret)
+	/* Functions are NULL as we set handler below */
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->thread = &lis3l02dq_trigger_handler;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->type = 0;
+	indio_dev->pollfunc->name
+		= kasprintf(GFP_KERNEL, "lis3l02dq_consumer%d", indio_dev->id);
+
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 033/111] staging:iio:adc:max1363 move to irqchip based threaded irq triggering
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (31 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 032/111] staging:iio:accel:lis3l02dq move to threaded trigger handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 034/111] staging:iio:adc:ad7476 use channel_spec Jonathan Cameron
                   ` (78 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V2: Fixed missing free of pollfunc->name as pointed out by
Michael Hennerich.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/max1363.h      |    4 --
 drivers/staging/iio/adc/max1363_core.c |    3 -
 drivers/staging/iio/adc/max1363_ring.c |   66 ++++++++++++-------------------
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 76635a0..2d41a27 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -180,8 +180,6 @@ struct max1363_chip_info {
  * @chip_info:		chip model specific constants, available modes etc
  * @current_mode:	the scan mode of this chip
  * @requestedmask:	a valid requested set of channels
- * @poll_work:		bottom half of polling interrupt handler
- * @protect_ring:	used to ensure only one polling bh running at a time
  * @reg:		supply regulator
  * @monitor_on:		whether monitor mode is enabled
  * @monitor_speed:	parameter corresponding to device monitor speed setting
@@ -197,8 +195,6 @@ struct max1363_state {
 	const struct max1363_chip_info	*chip_info;
 	const struct max1363_mode	*current_mode;
 	u32				requestedmask;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	struct iio_trigger		*trig;
 	struct regulator		*reg;
 
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 892bb41..935914e 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -22,7 +22,6 @@
   */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
@@ -1171,8 +1170,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	/* this is only used for device removal purposes */
 	i2c_set_clientdata(client, indio_dev);
 
-	atomic_set(&st->protect_ring, 0);
-
 	st->chip_info = &max1363_chip_info_tbl[id->driver_data];
 	st->client = client;
 
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 405f729..a387a99 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -9,8 +9,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
@@ -105,36 +103,11 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 	return 0;
 }
 
-
-/**
- * max1363_poll_func_th() - th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void max1363_poll_func_th(struct iio_dev *indio_dev, s64 time)
+static irqreturn_t max1363_trigger_handler(int irq, void *p)
 {
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
 	struct max1363_state *st = iio_priv(indio_dev);
-
-	schedule_work(&st->poll_work);
-
-	return;
-}
-/**
- * max1363_poll_bh_to_ring() - bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void max1363_poll_bh_to_ring(struct work_struct *work_s)
-{
-	struct max1363_state *st = container_of(work_s, struct max1363_state,
-						  poll_work);
-	struct iio_dev *indio_dev = iio_priv_to_dev(st);
 	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
@@ -150,20 +123,16 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
 	if (d_size % sizeof(s64))
 		d_size += sizeof(s64) - (d_size % sizeof(s64));
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	/* Monitor mode prevents reading. Whilst not currently implemented
 	 * might as well have this test in here in the meantime as it does
 	 * no harm.
 	 */
 	if (numvals == 0)
-		return;
+		return IRQ_HANDLED;
 
 	rxbuf = kmalloc(d_size,	GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		return -ENOMEM;
 	if (st->chip_info->bits != 8)
 		b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
 	else
@@ -177,8 +146,10 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
 
 	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
 done:
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+
+	return IRQ_HANDLED;
 }
 
 
@@ -194,19 +165,33 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->thread = &max1363_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "%s_consumer%d",
+			  st->client->name, indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_pollfunc;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->preenable = &max1363_ring_preenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	INIT_WORK(&st->poll_work, &max1363_poll_bh_to_ring);
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
+
 	return 0;
+error_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -221,6 +206,7 @@ void max1363_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 034/111] staging:iio:adc:ad7476 use channel_spec
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (32 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 033/111] staging:iio:adc:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 035/111] staging:iio:adc:ad7476 move to irqchip based triggering Jonathan Cameron
                   ` (77 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V3: Trivial rebase fixup.
V2: Move to new single IIO_CHAN macro.

Done without hardware.

Fix from Michael Hennerich incorporated to use
iio_ring_buffer_register_ex instead of
iio_ring_buffer_register and thus actually make it work.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7476.h      |    5 +-
 drivers/staging/iio/adc/ad7476_core.c |  139 ++++++++++++++++-----------------
 drivers/staging/iio/adc/ad7476_ring.c |   40 +---------
 3 files changed, 74 insertions(+), 110 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h
index f917e9c..17febd2 100644
--- a/drivers/staging/iio/adc/ad7476.h
+++ b/drivers/staging/iio/adc/ad7476.h
@@ -19,11 +19,8 @@ struct ad7476_platform_data {
 };
 
 struct ad7476_chip_info {
-	u8				bits;
-	u8				storagebits;
-	u8				res_shift;
-	char				sign;
 	u16				int_vref_mv;
+	struct iio_chan_spec		channel[2];
 };
 
 struct ad7476_state {
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index b16744c..0438923 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -35,42 +35,39 @@ static int ad7476_scan_direct(struct ad7476_state *st)
 	return (st->data[0] << 8) | st->data[1];
 }
 
-static ssize_t ad7476_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7476_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = dev_info->dev_data;
 	int ret;
-
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7476_scan_from_ring(st);
-	else
-		ret = ad7476_scan_direct(st);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (ret >> st->chip_info->res_shift) &
-		       RES_MASK(st->chip_info->bits));
-}
-static IIO_DEV_ATTR_IN_RAW(0, ad7476_scan, 0);
-
-static ssize_t ad7476_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
+	struct ad7476_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad7476_scan_from_ring(st);
+		else
+			ret = ad7476_scan_direct(st);
+		mutex_unlock(&dev_info->mlock);
+
+		if (ret < 0)
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv/1000;
+		*val2 = (scale_uv%1000)*1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7476_show_scale, NULL, 0);
 
 static ssize_t ad7476_show_name(struct device *dev,
 				 struct device_attribute *attr,
@@ -84,8 +81,6 @@ static ssize_t ad7476_show_name(struct device *dev,
 static IIO_DEVICE_ATTR(name, S_IRUGO, ad7476_show_name, NULL, 0);
 
 static struct attribute *ad7476_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
 	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
@@ -96,53 +91,53 @@ static const struct attribute_group ad7476_attribute_group = {
 
 static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
 	[ID_AD7466] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7467] = {
-		.bits = 10,
-		.storagebits = 16,
-		.res_shift = 2,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 2), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7468] = {
-		.bits = 8,
-		.storagebits = 16,
-		.res_shift = 4,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1 , 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 8, 16, 4), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7475] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7476] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7477] = {
-		.bits = 10,
-		.storagebits = 16,
-		.res_shift = 2,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 2), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7478] = {
-		.bits = 8,
-		.storagebits = 16,
-		.res_shift = 4,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 8, 16, 4), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7495] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 		.int_vref_mv = 2500,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
 	},
 };
 
@@ -196,11 +191,13 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
+	st->indio_dev->channels = st->chip_info->channel;
+	st->indio_dev->num_channels = 2;
+	st->indio_dev->read_raw = &ad7476_read_raw;
 	/* Setup default message */
 
 	st->xfer.rx_buf = &st->data;
-	st->xfer.len = st->chip_info->storagebits / 8;
+	st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	spi_message_init(&st->msg);
 	spi_message_add_tail(&st->xfer, &st->msg);
@@ -213,7 +210,9 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 	if (ret)
 		goto error_free_device;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->chip_info->channel,
+					  ARRAY_SIZE(st->chip_info->channel));
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 92d9378..8f00d6c 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -25,39 +25,6 @@
 
 #include "ad7476.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_TIMESTAMP(1);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7476_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7476_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->storagebits,
-		       st->chip_info->res_shift);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7476_show_type, NULL, 0);
-
-static struct attribute *ad7476_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7476_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7476_scan_el_attrs,
-};
-
 int ad7476_scan_from_ring(struct ad7476_state *st)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
@@ -93,7 +60,8 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev)
 	struct ad7476_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 
-	st->d_size = ring->scan_count * st->chip_info->storagebits / 8;
+	st->d_size = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		st->d_size += sizeof(s64);
@@ -150,7 +118,8 @@ static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
 	if (rxbuf == NULL)
 		return;
 
-	b_sent = spi_read(st->spi, rxbuf, st->chip_info->storagebits / 8);
+	b_sent = spi_read(st->spi, rxbuf,
+			  st->chip_info->channel[0].scan_type.storagebits / 8);
 	if (b_sent < 0)
 		goto done;
 
@@ -187,7 +156,6 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->preenable = &ad7476_ring_preenable;
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7476_scan_el_group;
 	indio_dev->ring->scan_timestamp = true;
 
 	INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 035/111] staging:iio:adc:ad7476 move to irqchip based triggering
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (33 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 034/111] staging:iio:adc:ad7476 use channel_spec Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 036/111] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
                   ` (76 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested

V2: Fixed missing free of pollfunc->name pointed out by
Michael Hennerich.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7476.h      |    2 -
 drivers/staging/iio/adc/ad7476_core.c |    4 --
 drivers/staging/iio/adc/ad7476_ring.c |   66 +++++++++++++--------------------
 3 files changed, 26 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h
index 17febd2..01a7021 100644
--- a/drivers/staging/iio/adc/ad7476.h
+++ b/drivers/staging/iio/adc/ad7476.h
@@ -28,8 +28,6 @@ struct ad7476_state {
 	struct spi_device		*spi;
 	const struct ad7476_chip_info	*chip_info;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
 	struct spi_transfer		xfer;
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index 0438923..9729a1c 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -6,13 +6,10 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
@@ -176,7 +173,6 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, st);
 
-	atomic_set(&st->protect_ring, 0);
 	st->spi = spi;
 
 	st->indio_dev = iio_allocate_device(0);
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 8f00d6c..ec1fa14 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -8,13 +8,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -77,46 +74,19 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev)
 	return 0;
 }
 
-/**
- * ad7476_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7476_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7476_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-/**
- * ad7476_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 {
-	struct ad7476_state *st = container_of(work_s, struct ad7476_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7476_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	rxbuf = kzalloc(st->d_size, GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		return -ENOMEM;
 
 	b_sent = spi_read(st->spi, rxbuf,
 			  st->chip_info->channel[0].scan_type.storagebits / 8);
@@ -131,8 +101,10 @@ static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
 
 	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
 done:
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+
+	return IRQ_HANDLED;
 }
 
 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
@@ -147,9 +119,22 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7476_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->thread = &ad7476_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name
+		= kasprintf(GFP_KERNEL, "%s_consumer%d",
+			    spi_get_device_id(st->spi)->name,
+			    indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_pollfunc;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
 
@@ -158,11 +143,11 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring);
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+error_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -177,6 +162,7 @@ void ad7476_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 036/111] staging:iio:meter:ade7758 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (34 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 035/111] staging:iio:adc:ad7476 move to irqchip based triggering Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 037/111] staging:iio:imu:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
                   ` (75 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758.h      |    5 ---
 drivers/staging/iio/meter/ade7758_ring.c |   58 +++++++++++++----------------
 2 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index c6fd94f..169982b 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -92,9 +92,6 @@
 /**
  * struct ade7758_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -103,8 +100,6 @@
  **/
 struct ade7758_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 274b4a0..2c9865d 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -50,23 +50,6 @@ static struct attribute_group ade7758_scan_el_group = {
 };
 
 /**
- * ade7758_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void ade7758_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
-
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
-}
-
-/**
  * ade7758_spi_read_burst() - read all data registers
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read (min size is 24 bytes)
@@ -117,13 +100,12 @@ static int ade7758_spi_read_burst(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void ade7758_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 {
-	struct ade7758_state *st
-		= container_of(work_s, struct ade7758_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
 	int i = 0;
 	s32 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
@@ -131,7 +113,7 @@ static void ade7758_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -145,20 +127,21 @@ static void ade7758_trigger_bh_to_ring(struct work_struct *work_s)
 	if (ring->scan_timestamp)
 		*((s64 *)
 		(((u32)data + 4 * ring->scan_count + 4) & ~0x7)) =
-			st->last_timestamp;
+			pf->timestamp;
 
 	ring->access.store_to(ring,
 			      (u8 *)data,
-			      st->last_timestamp);
+			      pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -166,9 +149,7 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct ade7758_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, ade7758_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -189,13 +170,26 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 	/* Set default scan mode */
 	iio_scan_mask_set(ring, iio_scan_el_wform.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ade7758_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
-
+	}
+	indio_dev->pollfunc->private_data = indio_dev->ring;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &ade7758_trigger_handler;
+	indio_dev->pollfunc->name
+		= kasprintf(GFP_KERNEL, "ade7759_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_pollfunc;
+	}
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
+
 	return 0;
 
+error_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 037/111] staging:iio:imu:adis16400 move to irq based triggers and channel spec channel registration.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (35 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 036/111] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 038/111] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
                   ` (74 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V2: rebase fixup.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/adis16400.h         |    7 +-
 drivers/staging/iio/imu/adis16400_core.c    |  424 ++++++++++++++-------------
 drivers/staging/iio/imu/adis16400_ring.c    |  160 +++--------
 drivers/staging/iio/imu/adis16400_trigger.c |   56 ++---
 4 files changed, 282 insertions(+), 365 deletions(-)

diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index e328bcc..1a7e23e 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -126,9 +126,6 @@
 /**
  * struct adis16400_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -137,8 +134,6 @@
  **/
 struct adis16400_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -146,7 +141,7 @@ struct adis16400_state {
 	struct mutex			buf_lock;
 };
 
-int adis16400_set_irq(struct device *dev, bool enable);
+int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 33c5f3c..6f43cc9 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -38,7 +38,7 @@
 
 #define DRIVER_NAME		"adis16400"
 
-static int adis16400_check_status(struct device *dev);
+static int adis16400_check_status(struct iio_dev *indio_dev);
 
 /* At the moment the spi framework doesn't allow global setting of cs_change.
  * It's in the likely to be added comment at the top of spi.h.
@@ -51,12 +51,11 @@ static int adis16400_check_status(struct device *dev);
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16400_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -76,13 +75,12 @@ static int adis16400_spi_write_reg_8(struct device *dev,
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16400_spi_write_reg_16(struct device *dev,
+static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -114,17 +112,16 @@ static int adis16400_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16400_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16400_spi_read_reg_16(struct device *dev,
+static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -163,100 +160,15 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16400_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16400_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16400_ERROR_ACTIVE)
-		adis16400_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16400_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16400_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16400_ERROR_ACTIVE)
-		adis16400_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16400_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16400_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16400_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16400_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16400_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16400_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static ssize_t adis16400_read_frequency(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret, len = 0;
 	u16 t;
 	int sps;
-	ret = adis16400_spi_read_reg_16(dev,
+	ret = adis16400_spi_read_reg_16(indio_dev,
 			ADIS16400_SMPL_PRD,
 			&t);
 	if (ret)
@@ -293,7 +205,7 @@ static ssize_t adis16400_write_frequency(struct device *dev,
 	else
 		st->us->max_speed_hz = ADIS16400_SPI_FAST;
 
-	ret = adis16400_spi_write_reg_8(dev,
+	ret = adis16400_spi_write_reg_8(indio_dev,
 			ADIS16400_SMPL_PRD,
 			t);
 
@@ -302,14 +214,14 @@ static ssize_t adis16400_write_frequency(struct device *dev,
 	return ret ? ret : len;
 }
 
-static int adis16400_reset(struct device *dev)
+static int adis16400_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16400_spi_write_reg_8(dev,
+	ret = adis16400_spi_write_reg_8(indio_dev,
 			ADIS16400_GLOB_CMD,
 			ADIS16400_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -318,22 +230,24 @@ static ssize_t adis16400_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -1;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16400_reset(dev);
+		return adis16400_reset(indio_dev);
 	}
 	return -1;
 }
 
-int adis16400_set_irq(struct device *dev, bool enable)
+int adis16400_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret;
 	u16 msc;
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_MSC_CTRL, &msc);
+	ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -343,7 +257,7 @@ int adis16400_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16400_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16400_spi_write_reg_16(dev, ADIS16400_MSC_CTRL, msc);
+	ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_MSC_CTRL, msc);
 	if (ret)
 		goto error_ret;
 
@@ -352,41 +266,45 @@ error_ret:
 }
 
 /* Power down the device */
-static int adis16400_stop_device(struct device *dev)
+static int adis16400_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 val = ADIS16400_SLP_CNT_POWER_OFF;
 
-	ret = adis16400_spi_write_reg_16(dev, ADIS16400_SLP_CNT, val);
+	ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_SLP_CNT, val);
 	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
+		dev_err(&indio_dev->dev,
+			"problem with turning device off: SLP_CNT");
 
 	return ret;
 }
 
-static int adis16400_self_test(struct device *dev)
+static int adis16400_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16400_spi_write_reg_16(dev,
+	ret = adis16400_spi_write_reg_16(indio_dev,
 			ADIS16400_MSC_CTRL,
 			ADIS16400_MSC_CTRL_MEM_TEST);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
+
 	msleep(ADIS16400_MTEST_DELAY);
-	adis16400_check_status(dev);
+	adis16400_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16400_check_status(struct device *dev)
+static int adis16400_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_DIAG_STAT, &status);
+	ret = adis16400_spi_read_reg_16(indio_dev,
+					ADIS16400_DIAG_STAT, &status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -440,33 +358,34 @@ static int adis16400_initial_setup(struct adis16400_state *st)
 	spi_setup(st->us);
 
 	/* Disable IRQ */
-	ret = adis16400_set_irq(dev, false);
+	ret = adis16400_set_irq(st->indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16400_self_test(dev);
+	ret = adis16400_self_test(st->indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16400_check_status(dev);
+	ret = adis16400_check_status(st->indio_dev);
 	if (ret) {
-		adis16400_reset(dev);
+		adis16400_reset(st->indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16400_STARTUP_DELAY);
-		ret = adis16400_check_status(dev);
+		ret = adis16400_check_status(st->indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_PRODUCT_ID, &prod_id);
+	ret = adis16400_spi_read_reg_16(st->indio_dev,
+					ADIS16400_PRODUCT_ID, &prod_id);
 	if (ret)
 		goto err_ret;
 
@@ -478,7 +397,8 @@ static int adis16400_initial_setup(struct adis16400_state *st)
 			prod_id, st->us->chip_select, st->us->irq);
 
 	/* use high spi speed if possible */
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_SMPL_PRD, &smp_prd);
+	ret = adis16400_spi_read_reg_16(st->indio_dev,
+					ADIS16400_SMPL_PRD, &smp_prd);
 	if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
 		st->us->max_speed_hz = ADIS16400_SPI_SLOW;
 		spi_setup(st->us);
@@ -490,58 +410,6 @@ err_ret:
 	return ret;
 }
 
-#define ADIS16400_DEV_ATTR_CALIBBIAS(_channel, _reg)		\
-	IIO_DEV_ATTR_##_channel##_CALIBBIAS(S_IWUSR | S_IRUGO,	\
-			adis16400_read_12bit_signed,		\
-			adis16400_write_16bit,			\
-			_reg)
-
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_YGYRO_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_ZGYRO_OFF);
-
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_YACCL_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_ZACCL_OFF);
-
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16400_read_14bit_signed,
-		ADIS16400_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.002418 V");
-
-static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed,
-		ADIS16400_XGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Y(adis16400_read_14bit_signed,
-		ADIS16400_YGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.0008726646");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16400_read_14bit_signed,
-		ADIS16400_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16400_read_14bit_signed,
-		ADIS16400_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZACCL_OUT);
-static IIO_CONST_ATTR(accel_scale, "0.0326561445");
-
-static IIO_DEV_ATTR_MAGN_X(adis16400_read_14bit_signed,
-		ADIS16400_XMAGN_OUT);
-static IIO_DEV_ATTR_MAGN_Y(adis16400_read_14bit_signed,
-		ADIS16400_YMAGN_OUT);
-static IIO_DEV_ATTR_MAGN_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZMAGN_OUT);
-static IIO_CONST_ATTR(magn_scale, "0.0005 Gs");
-
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16400_read_12bit_signed);
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
-static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16400_read_12bit_unsigned,
-		ADIS16400_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806 V");
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16400_read_frequency,
 		adis16400_write_frequency);
@@ -552,32 +420,184 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
 static IIO_CONST_ATTR_NAME("adis16400");
 
+enum adis16400_chan {
+	in_supply,
+	gyro_x,
+	gyro_y,
+	gyro_z,
+	accel_x,
+	accel_y,
+	accel_z,
+	magn_x,
+	magn_y,
+	magn_z,
+	temp,
+	in1
+};
+
+static u8 adis16400_addresses[12][2] = {
+	[in_supply] = { ADIS16400_SUPPLY_OUT, 0 },
+	[gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF },
+	[gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF },
+	[gyro_z] = { ADIS16400_ZGYRO_OUT, ADIS16400_ZGYRO_OFF },
+	[accel_x] = { ADIS16400_XACCL_OUT, ADIS16400_XACCL_OFF },
+	[accel_y] = { ADIS16400_YACCL_OUT, ADIS16400_YACCL_OFF },
+	[accel_z] = { ADIS16400_ZACCL_OUT, ADIS16400_ZACCL_OFF },
+	[magn_x] = { ADIS16400_XMAGN_OUT, 0 },
+	[magn_y] = { ADIS16400_YMAGN_OUT, 0 },
+	[magn_z] = { ADIS16400_ZMAGN_OUT, 0 },
+	[temp] = { ADIS16400_TEMP_OUT, 0 },
+	[in1] = { ADIS16400_AUX_ADC , 0 },
+};
+
+static int adis16400_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int ret;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_write_reg_16(indio_dev,
+				adis16400_addresses[chan->address][1],
+				val);
+		mutex_unlock(&indio_dev->mlock);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int adis16400_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val,
+			      int *val2,
+			      long mask)
+{
+	int ret;
+	s16 val16;
+	int shift;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_read_reg_16(indio_dev,
+				adis16400_addresses[chan->address][0],
+				&val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << chan->scan_type.realbits) - 1;
+		if (chan->scan_type.sign == 's') {
+			shift = 16 - chan->scan_type.realbits;
+			val16 = (s16)(val16 << shift) >> shift;
+		}
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			*val = 0;
+			*val2 = 873;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 2418;
+			else
+				*val2 = 806;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 32656;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_MAGN:
+			*val = 0;
+			*val2 = 500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 140000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_read_reg_16(indio_dev,
+				adis16400_addresses[chan->address][1],
+				&val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 = ((val16 & 0xFFF) << 4) >> 4;
+		*val = val16;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		/* currently only temperature */
+		*val = 198;
+		*val2 = 160000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct iio_chan_spec adis16400_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16400_SCAN_SUPPLY,
+		 IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_x, ADIS16400_SCAN_MAGN_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_y, ADIS16400_SCAN_MAGN_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_z, ADIS16400_SCAN_MAGN_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in1, ADIS16400_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(12)
+};
+
 static struct attribute *adis16400_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_y_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_magn_x_raw.dev_attr.attr,
-	&iio_dev_attr_magn_y_raw.dev_attr.attr,
-	&iio_dev_attr_magn_z_raw.dev_attr.attr,
-	&iio_const_attr_magn_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
@@ -622,6 +642,10 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16400_attribute_group;
+	st->indio_dev->channels = adis16400_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16400_channels);
+	st->indio_dev->read_raw = &adis16400_read_raw;
+	st->indio_dev->write_raw = &adis16400_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -682,12 +706,10 @@ static int adis16400_remove(struct spi_device *spi)
 	struct adis16400_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	ret = adis16400_stop_device(&(indio_dev->dev));
+	ret = adis16400_stop_device(indio_dev);
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
-
 	adis16400_remove_trigger(indio_dev);
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 	adis16400_unconfigure_ring(indio_dev);
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index da28cb4..f5b9bb8 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -17,93 +17,6 @@
 #include "../trigger.h"
 #include "adis16400.h"
 
-static IIO_SCAN_EL_C(in0_supply, ADIS16400_SCAN_SUPPLY,
-		     ADIS16400_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 14, 16);
-
-static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, ADIS16400_XGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_y, ADIS16400_SCAN_GYRO_Y, ADIS16400_YGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_z, ADIS16400_SCAN_GYRO_Z, ADIS16400_ZGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16400_SCAN_ACC_X, ADIS16400_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16400_SCAN_ACC_Y, ADIS16400_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16400_SCAN_ACC_Z, ADIS16400_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(magn_x, ADIS16400_SCAN_MAGN_X, ADIS16400_XMAGN_OUT, NULL);
-static IIO_SCAN_EL_C(magn_y, ADIS16400_SCAN_MAGN_Y, ADIS16400_YMAGN_OUT, NULL);
-static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, ADIS16400_ZMAGN_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(magn, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, ADIS16400_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16400_SCAN_ADC_0, ADIS16400_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(12);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16400_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_scan_el_gyro_y.dev_attr.attr,
-	&iio_const_attr_gyro_y_index.dev_attr.attr,
-	&iio_scan_el_gyro_z.dev_attr.attr,
-	&iio_const_attr_gyro_z_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_magn_x.dev_attr.attr,
-	&iio_const_attr_magn_x_index.dev_attr.attr,
-	&iio_scan_el_magn_y.dev_attr.attr,
-	&iio_const_attr_magn_y_index.dev_attr.attr,
-	&iio_scan_el_magn_z.dev_attr.attr,
-	&iio_const_attr_magn_z_index.dev_attr.attr,
-	&iio_const_attr_magn_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16400_scan_el_group = {
-	.attrs = adis16400_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16400_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16400_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
-
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
-}
-
 /**
  * adis16400_spi_read_burst() - read all data registers
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -153,13 +66,12 @@ static int adis16400_spi_read_burst(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 {
-	struct adis16400_state *st
-		= container_of(work_s, struct adis16400_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0, j;
 	s16 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
@@ -168,11 +80,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
-		if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
+		if (adis16400_spi_read_burst(&indio_dev->dev, st->rx) >= 0)
 			for (; i < ring->scan_count; i++) {
 				j = __ffs(mask);
 				mask &= ~(1 << j);
@@ -182,20 +94,18 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-	ring->access.store_to(ring,
-			(u8 *) data,
-			st->last_timestamp);
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
+	ring->access.store_to(indio_dev->ring, (u8 *) data, pf->timestamp);
 
-	iio_trigger_notify_done(st->indio_dev->trig);
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -203,9 +113,7 @@ void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16400_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16400_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -216,7 +124,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16400_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -224,26 +131,37 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
-
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
-	if (ret)
+	iio_scan_mask_set(ring, ADIS16400_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_X);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_Y);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_Z);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_Z);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_X);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_Y);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_Z);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16400_SCAN_ADC_0);
+
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16400_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16400_consumer%d", indio_dev->id);
+	if (ret)
+		goto error_iio_free_pollfunc;
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_iio_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index afa5e74..b80ae94 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -12,16 +12,6 @@
 #include "../trigger.h"
 #include "adis16400.h"
 
-/**
- * adis16400_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16400_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
 static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *adis16400_trigger_attrs[] = {
@@ -43,66 +33,58 @@ static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16400_set_irq(&st->indio_dev->dev, state);
-}
-
-/**
- * adis16400_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16400_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16400_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
+	return adis16400_set_irq(st->indio_dev, state);
 }
 
 int adis16400_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16400_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL,
+			 "%s-dev%d",
+			 spi_get_device_id(st->us)->name,
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
+
 	ret = request_irq(st->us->irq,
-			  adis16400_data_rdy_trig_poll,
+			  &iio_trigger_generic_data_rdy_poll,
 			  IRQF_TRIGGER_RISING,
 			  "adis16400",
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16400-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16400_trig_try_reen;
 	st->trig->control_attrs = &adis16400_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 038/111] staging:iio:imu:adis16350 etc support into adis16400 driver.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (36 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 037/111] staging:iio:imu:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 039/111] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
                   ` (73 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Next patch will remove the current adis16350 driver.
These should have been merged a long time ago, but there we are.

V3: rebase fixup + add missing extend_name for supply on adis16350

V2: Move to single IIO_CHAN macro + use the new extend_name
to make the naming of the temperature sensors contain x, y, z
rather than messing with modifiers.  This a very weird case
and I don't want temperature to use axial modifiers.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/Kconfig             |    8 +-
 drivers/staging/iio/imu/adis16400.h         |   22 +++-
 drivers/staging/iio/imu/adis16400_core.c    |  187 +++++++++++++++++++++++----
 drivers/staging/iio/imu/adis16400_ring.c    |   89 ++++++++++---
 drivers/staging/iio/imu/adis16400_trigger.c |    1 -
 5 files changed, 260 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index 31a6233..dbed7d7 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -22,10 +22,12 @@ config ADIS16350
 	  high precision tri-axis inertial sensor.
 
 config ADIS16400
-	tristate "Analog Devices ADIS16400/5 IMU SPI driver"
+	tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
 	depends on SPI
 	select IIO_SW_RING if IIO_RING_BUFFER
 	select IIO_TRIGGER if IIO_RING_BUFFER
 	help
-	  Say yes here to build support for Analog Devices adis16400/5 triaxial
-	  inertial sensor with Magnetometer.
+	  Say yes here to build support for Analog Devices adis16350, adis16354,
+	  adis16355, adis16360, adis16362, adis16364, adis16365, adis16400 and
+	  adis16405 triaxial inertial sensors (adis16400 series also have
+	  magnetometers).
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index 1a7e23e..ec3449b 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -37,6 +37,10 @@
 #define ADIS16400_TEMP_OUT  0x16 /* Temperature output */
 #define ADIS16400_AUX_ADC   0x18 /* Auxiliary ADC measurement */
 
+#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
+#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
+#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
+
 /* Calibration parameters */
 #define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
 #define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
@@ -68,7 +72,6 @@
 #define ADIS16400_AUX_DAC   0x4A /* Auxiliary DAC data */
 
 #define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
-#define ADIS16400_PRODUCT_ID_DEFAULT 0x4015	/* Datasheet says 0x4105, I get 0x4015 */
 
 #define ADIS16400_ERROR_ACTIVE			(1<<14)
 #define ADIS16400_NEW_DATA			(1<<14)
@@ -123,6 +126,18 @@
 #define ADIS16400_SPI_BURST	(u32)(1000 * 1000)
 #define ADIS16400_SPI_FAST	(u32)(2000 * 1000)
 
+#define ADIS16400_HAS_PROD_ID 1
+#define ADIS16400_NO_BURST 2
+struct adis16400_chip_info {
+	const struct iio_chan_spec *channels;
+	const int num_channels;
+	const int product_id;
+	const long flags;
+	unsigned int gyro_scale_micro;
+	unsigned int accel_scale_micro;
+	unsigned long default_scan_mask;
+};
+
 /**
  * struct adis16400_state - device instance specific data
  * @us:			actual spi_device
@@ -139,6 +154,7 @@ struct adis16400_state {
 	u8				*tx;
 	u8				*rx;
 	struct mutex			buf_lock;
+	struct adis16400_chip_info	*variant;
 };
 
 int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
@@ -156,9 +172,13 @@ int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
 #define ADIS16400_SCAN_ACC_Y	5
 #define ADIS16400_SCAN_ACC_Z	6
 #define ADIS16400_SCAN_MAGN_X	7
+#define ADIS16350_SCAN_TEMP_X	7
 #define ADIS16400_SCAN_MAGN_Y	8
+#define ADIS16350_SCAN_TEMP_Y	8
 #define ADIS16400_SCAN_MAGN_Z	9
+#define ADIS16350_SCAN_TEMP_Z	9
 #define ADIS16400_SCAN_TEMP	10
+#define ADIS16350_SCAN_ADC_0	10
 #define ADIS16400_SCAN_ADC_0	11
 
 void adis16400_remove_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 6f43cc9..fad7744 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -38,6 +38,15 @@
 
 #define DRIVER_NAME		"adis16400"
 
+enum adis16400_chip_variant {
+	ADIS16350,
+	ADIS16360,
+	ADIS16362,
+	ADIS16364,
+	ADIS16365,
+	ADIS16400,
+};
+
 static int adis16400_check_status(struct iio_dev *indio_dev);
 
 /* At the moment the spi framework doesn't allow global setting of cs_change.
@@ -383,19 +392,18 @@ static int adis16400_initial_setup(struct adis16400_state *st)
 			goto err_ret;
 		}
 	}
+	if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
+		ret = adis16400_spi_read_reg_16(st->indio_dev,
+						ADIS16400_PRODUCT_ID, &prod_id);
+		if (ret)
+			goto err_ret;
 
-	ret = adis16400_spi_read_reg_16(st->indio_dev,
-					ADIS16400_PRODUCT_ID, &prod_id);
-	if (ret)
-		goto err_ret;
-
-	if ((prod_id & 0xF000) != ADIS16400_PRODUCT_ID_DEFAULT)
-		dev_warn(dev, "unknown product id");
-
-
-	dev_info(dev, ": prod_id 0x%04x at CS%d (irq %d)\n",
-			prod_id, st->us->chip_select, st->us->irq);
+		if ((prod_id & 0xF000) != st->variant->product_id)
+			dev_warn(dev, "incorrect id");
 
+		printk(KERN_INFO DRIVER_NAME ": prod_id 0x%04x at CS%d (irq %d)\n",
+		       prod_id, st->us->chip_select, st->us->irq);
+	}
 	/* use high spi speed if possible */
 	ret = adis16400_spi_read_reg_16(st->indio_dev,
 					ADIS16400_SMPL_PRD, &smp_prd);
@@ -418,7 +426,15 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static IIO_CONST_ATTR_NAME("adis16400");
+static ssize_t adis16400_show_name(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct adis16400_state *st
+		= iio_dev_get_devdata(dev_get_drvdata(dev));
+	return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name);
+}
+static IIO_DEVICE_ATTR(name, S_IRUGO, adis16400_show_name, NULL, 0);
 
 enum adis16400_chan {
 	in_supply,
@@ -432,10 +448,11 @@ enum adis16400_chan {
 	magn_y,
 	magn_z,
 	temp,
+	temp0, temp1, temp2,
 	in1
 };
 
-static u8 adis16400_addresses[12][2] = {
+static u8 adis16400_addresses[16][2] = {
 	[in_supply] = { ADIS16400_SUPPLY_OUT, 0 },
 	[gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF },
 	[gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF },
@@ -447,6 +464,9 @@ static u8 adis16400_addresses[12][2] = {
 	[magn_y] = { ADIS16400_YMAGN_OUT, 0 },
 	[magn_z] = { ADIS16400_ZMAGN_OUT, 0 },
 	[temp] = { ADIS16400_TEMP_OUT, 0 },
+	[temp0] = { ADIS16350_XTEMP_OUT },
+	[temp1] = { ADIS16350_YTEMP_OUT },
+	[temp2] = { ADIS16350_ZTEMP_OUT },
 	[in1] = { ADIS16400_AUX_ADC , 0 },
 };
 
@@ -476,6 +496,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 			      int *val2,
 			      long mask)
 {
+	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	s16 val16;
 	int shift;
@@ -503,7 +524,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 		switch (chan->type) {
 		case IIO_GYRO:
 			*val = 0;
-			*val2 = 873;
+			*val2 = st->variant->gyro_scale_micro;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_IN:
 			*val = 0;
@@ -514,7 +535,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
-			*val2 = 32656;
+			*val2 = st->variant->accel_scale_micro;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_MAGN:
 			*val = 0;
@@ -532,10 +553,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 		ret = adis16400_spi_read_reg_16(indio_dev,
 				adis16400_addresses[chan->address][1],
 				&val16);
-		if (ret) {
-			mutex_unlock(&indio_dev->mlock);
+		mutex_unlock(&indio_dev->mlock);
+		if (ret)
 			return ret;
-		}
 		val16 = ((val16 & 0xFFF) << 4) >> 4;
 		*val = val16;
 		return IIO_VAL_INT;
@@ -597,11 +617,57 @@ static struct iio_chan_spec adis16400_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(12)
 };
 
+static struct iio_chan_spec adis16350_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "x", 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "y", 1, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "z", 2, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(11)
+};
+
 static struct attribute *adis16400_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -609,6 +675,64 @@ static const struct attribute_group adis16400_attribute_group = {
 	.attrs = adis16400_attributes,
 };
 
+static struct adis16400_chip_info adis16400_chips[] = {
+	[ADIS16350] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.gyro_scale_micro = 872664,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+		.flags = ADIS16400_NO_BURST,
+	},
+	[ADIS16360] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FE8,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16362] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FEA,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16364] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FEC,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16365] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FED,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16400] = {
+		.channels = adis16400_channels,
+		.num_channels = ARRAY_SIZE(adis16400_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x4015,
+		.gyro_scale_micro = 873,
+		.accel_scale_micro = 32656,
+		.default_scan_mask = 0xFFF,
+	}
+};
+
+
+
 static int __devinit adis16400_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -639,11 +763,11 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
-
+	st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16400_attribute_group;
-	st->indio_dev->channels = adis16400_channels;
-	st->indio_dev->num_channels = ARRAY_SIZE(adis16400_channels);
+	st->indio_dev->channels = st->variant->channels;
+	st->indio_dev->num_channels = st->variant->num_channels;
 	st->indio_dev->read_raw = &adis16400_read_raw;
 	st->indio_dev->write_raw = &adis16400_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
@@ -659,7 +783,9 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->variant->channels,
+					  st->variant->num_channels);
 	if (ret) {
 		dev_err(&spi->dev, "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -714,6 +840,7 @@ static int adis16400_remove(struct spi_device *spi)
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 	adis16400_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
+
 	kfree(st->tx);
 	kfree(st->rx);
 	kfree(st);
@@ -724,11 +851,25 @@ err_ret:
 	return ret;
 }
 
+static const struct spi_device_id adis16400_id[] = {
+	{"adis16350", ADIS16350},
+	{"adis16354", ADIS16350},
+	{"adis16355", ADIS16350},
+	{"adis16360", ADIS16360},
+	{"adis16362", ADIS16362},
+	{"adis16364", ADIS16364},
+	{"adis16365", ADIS16365},
+	{"adis16400", ADIS16400},
+	{"adis16405", ADIS16400},
+	{}
+};
+
 static struct spi_driver adis16400_driver = {
 	.driver = {
 		.name = "adis16400",
 		.owner = THIS_MODULE,
 	},
+	.id_table = adis16400_id,
 	.probe = adis16400_probe,
 	.remove = __devexit_p(adis16400_remove),
 };
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index f5b9bb8..c56c655 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <linux/bitops.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -63,6 +64,56 @@ static int adis16400_spi_read_burst(struct device *dev, u8 *rx)
 	return ret;
 }
 
+static const u16 read_all_tx_array[] = {
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_SUPPLY_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_XTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_YTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_ZTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_AUX_ADC)),
+};
+
+static int adis16350_spi_read_all(struct device *dev, u8 *rx)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+
+	struct spi_message msg;
+	int i, j = 0, ret;
+	struct spi_transfer *xfers;
+
+	xfers = kzalloc(sizeof(*xfers)*
+			st->indio_dev->ring->scan_count + 1,
+		GFP_KERNEL);
+	if (xfers == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
+		if (st->indio_dev->ring->scan_mask & (1 << i)) {
+			xfers[j].tx_buf = &read_all_tx_array[i];
+			xfers[j].bits_per_word = 16;
+			xfers[j].len = 2;
+			xfers[j + 1].rx_buf = rx + j*2;
+			j++;
+		}
+	xfers[j].bits_per_word = 16;
+	xfers[j].len = 2;
+
+	spi_message_init(&msg);
+	for (j = 0; j < st->indio_dev->ring->scan_count + 1; j++)
+		spi_message_add_tail(&xfers[j], &msg);
+
+	ret = spi_sync(st->us, &msg);
+	kfree(xfers);
+
+	return ret;
+}
+
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
@@ -72,7 +123,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	struct iio_dev *indio_dev = pf->private_data;
 	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	int i = 0, j;
+	int i = 0, j, ret = 0;
 	s16 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
 	unsigned long mask = ring->scan_mask;
@@ -83,15 +134,25 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16400_spi_read_burst(&indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++) {
+	if (ring->scan_count) {
+		if (st->variant->flags & ADIS16400_NO_BURST) {
+			ret = adis16350_spi_read_all(&indio_dev->dev, st->rx);
+			if (ret < 0)
+				return ret;
+			for (; i < ring->scan_count; i++)
+				data[i]	= *(s16 *)(st->rx + i*2);
+		} else {
+			ret = adis16400_spi_read_burst(&indio_dev->dev, st->rx);
+			if (ret < 0)
+				return ret;
+			for (; i < indio_dev->ring->scan_count; i++) {
 				j = __ffs(mask);
 				mask &= ~(1 << j);
-				data[i]	= be16_to_cpup(
+				data[i] = be16_to_cpup(
 					(__be16 *)&(st->rx[j*2]));
 			}
-
+		}
+	}
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
@@ -113,6 +174,7 @@ void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16400_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
+	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring;
 
 	ring = iio_sw_rb_allocate(indio_dev);
@@ -129,20 +191,9 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	ring->postenable = &iio_triggered_ring_postenable;
 	ring->predisable = &iio_triggered_ring_predisable;
 	ring->owner = THIS_MODULE;
-
+	ring->scan_mask = st->variant->default_scan_mask;
+	ring->scan_count = hweight_long(st->variant->default_scan_mask);
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, ADIS16400_SCAN_SUPPLY);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_X);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_Y);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_GYRO_Z);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_X);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_Y);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_ACC_Z);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_X);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_Y);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_MAGN_Z);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_TEMP);
-	iio_scan_mask_set(ring, ADIS16400_SCAN_ADC_0);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index b80ae94..d0c4aea 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -64,7 +64,6 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
-
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 039/111] staging:iio:imu remove old adis16350. Support now in adis16400 driver.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (37 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 038/111] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 040/111] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
                   ` (72 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/Kconfig             |    9 -
 drivers/staging/iio/imu/Makefile            |    4 -
 drivers/staging/iio/imu/adis16350.h         |  177 -------
 drivers/staging/iio/imu/adis16350_core.c    |  733 ---------------------------
 drivers/staging/iio/imu/adis16350_ring.c    |  236 ---------
 drivers/staging/iio/imu/adis16350_trigger.c |  119 -----
 6 files changed, 0 insertions(+), 1278 deletions(-)

diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index dbed7d7..d8f568f 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -12,15 +12,6 @@ config ADIS16300
 	  Say yes here to build support for Analog Devices adis16300 four degrees
 	  of freedom inertial sensor.
 
-config ADIS16350
-	tristate "Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver"
-	depends on SPI
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	select IIO_SW_RING if IIO_RING_BUFFER
-	help
-	  Say yes here to build support for Analog Devices adis16350/54/55/60/62/64/65
-	  high precision tri-axis inertial sensor.
-
 config ADIS16400
 	tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
 	depends on SPI
diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile
index f3b450b..de6b1e7 100644
--- a/drivers/staging/iio/imu/Makefile
+++ b/drivers/staging/iio/imu/Makefile
@@ -6,10 +6,6 @@ adis16300-y             := adis16300_core.o
 adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
 obj-$(CONFIG_ADIS16300) += adis16300.o
 
-adis16350-y             := adis16350_core.o
-adis16350-$(CONFIG_IIO_RING_BUFFER) += adis16350_ring.o adis16350_trigger.o
-obj-$(CONFIG_ADIS16350) += adis16350.o
-
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o
 obj-$(CONFIG_ADIS16400) += adis16400.o
diff --git a/drivers/staging/iio/imu/adis16350.h b/drivers/staging/iio/imu/adis16350.h
deleted file mode 100644
index b1ad486..0000000
--- a/drivers/staging/iio/imu/adis16350.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef SPI_ADIS16350_H_
-#define SPI_ADIS16350_H_
-
-#define ADIS16350_STARTUP_DELAY	220 /* ms */
-
-#define ADIS16350_READ_REG(a)    a
-#define ADIS16350_WRITE_REG(a) ((a) | 0x80)
-
-#define ADIS16350_FLASH_CNT  0x00 /* Flash memory write count */
-#define ADIS16350_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16350_XGYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16350_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
-#define ADIS16350_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
-#define ADIS16350_XACCL_OUT 0x0A /* X-axis accelerometer output */
-#define ADIS16350_YACCL_OUT 0x0C /* Y-axis accelerometer output */
-#define ADIS16350_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
-#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
-#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
-#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
-#define ADIS16350_AUX_ADC   0x16 /* Auxiliary ADC measurement */
-
-/* Calibration parameters */
-#define ADIS16350_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
-#define ADIS16350_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
-#define ADIS16350_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
-#define ADIS16350_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
-#define ADIS16350_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
-#define ADIS16350_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
-
-#define ADIS16350_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
-#define ADIS16350_MSC_CTRL  0x34 /* Miscellaneous control */
-#define ADIS16350_SMPL_PRD  0x36 /* Internal sample period (rate) control */
-#define ADIS16350_SENS_AVG  0x38 /* Dynamic range and digital filter control */
-#define ADIS16350_SLP_CNT   0x3A /* Sleep mode control */
-#define ADIS16350_DIAG_STAT 0x3C /* System status */
-
-/* Alarm functions */
-#define ADIS16350_GLOB_CMD  0x3E /* System command */
-#define ADIS16350_ALM_MAG1  0x26 /* Alarm 1 amplitude threshold */
-#define ADIS16350_ALM_MAG2  0x28 /* Alarm 2 amplitude threshold */
-#define ADIS16350_ALM_SMPL1 0x2A /* Alarm 1 sample size */
-#define ADIS16350_ALM_SMPL2 0x2C /* Alarm 2 sample size */
-#define ADIS16350_ALM_CTRL  0x2E /* Alarm control */
-#define ADIS16350_AUX_DAC   0x30 /* Auxiliary DAC data */
-
-#define ADIS16350_ERROR_ACTIVE			(1<<14)
-#define ADIS16350_NEW_DATA			(1<<15)
-
-/* MSC_CTRL */
-#define ADIS16350_MSC_CTRL_MEM_TEST		(1<<11)
-#define ADIS16350_MSC_CTRL_INT_SELF_TEST	(1<<10)
-#define ADIS16350_MSC_CTRL_NEG_SELF_TEST	(1<<9)
-#define ADIS16350_MSC_CTRL_POS_SELF_TEST	(1<<8)
-#define ADIS16350_MSC_CTRL_GYRO_BIAS		(1<<7)
-#define ADIS16350_MSC_CTRL_ACCL_ALIGN		(1<<6)
-#define ADIS16350_MSC_CTRL_DATA_RDY_EN		(1<<2)
-#define ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
-#define ADIS16350_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
-
-/* SMPL_PRD */
-#define ADIS16350_SMPL_PRD_TIME_BASE	(1<<7)
-#define ADIS16350_SMPL_PRD_DIV_MASK	0x7F
-
-/* DIAG_STAT */
-#define ADIS16350_DIAG_STAT_ZACCL_FAIL	(1<<15)
-#define ADIS16350_DIAG_STAT_YACCL_FAIL	(1<<14)
-#define ADIS16350_DIAG_STAT_XACCL_FAIL	(1<<13)
-#define ADIS16350_DIAG_STAT_XGYRO_FAIL	(1<<12)
-#define ADIS16350_DIAG_STAT_YGYRO_FAIL	(1<<11)
-#define ADIS16350_DIAG_STAT_ZGYRO_FAIL	(1<<10)
-#define ADIS16350_DIAG_STAT_ALARM2	(1<<9)
-#define ADIS16350_DIAG_STAT_ALARM1	(1<<8)
-#define ADIS16350_DIAG_STAT_FLASH_CHK	(1<<6)
-#define ADIS16350_DIAG_STAT_SELF_TEST	(1<<5)
-#define ADIS16350_DIAG_STAT_OVERFLOW	(1<<4)
-#define ADIS16350_DIAG_STAT_SPI_FAIL	(1<<3)
-#define ADIS16350_DIAG_STAT_FLASH_UPT	(1<<2)
-#define ADIS16350_DIAG_STAT_POWER_HIGH	(1<<1)
-#define ADIS16350_DIAG_STAT_POWER_LOW	(1<<0)
-
-/* GLOB_CMD */
-#define ADIS16350_GLOB_CMD_SW_RESET	(1<<7)
-#define ADIS16350_GLOB_CMD_P_AUTO_NULL	(1<<4)
-#define ADIS16350_GLOB_CMD_FLASH_UPD	(1<<3)
-#define ADIS16350_GLOB_CMD_DAC_LATCH	(1<<2)
-#define ADIS16350_GLOB_CMD_FAC_CALIB	(1<<1)
-#define ADIS16350_GLOB_CMD_AUTO_NULL	(1<<0)
-
-/* SLP_CNT */
-#define ADIS16350_SLP_CNT_POWER_OFF	(1<<8)
-
-#define ADIS16350_MAX_TX 24
-#define ADIS16350_MAX_RX 24
-
-#define ADIS16350_SPI_SLOW	(u32)(300 * 1000)
-#define ADIS16350_SPI_BURST	(u32)(1000 * 1000)
-#define ADIS16350_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct adis16350_state - device instance specific data
- * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
- * @trig:		data ready trigger registered with iio
- * @tx:			transmit buffer
- * @rx:			receive buffer
- * @buf_lock:		mutex to protect tx and rx
- **/
-struct adis16350_state {
-	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
-};
-
-int adis16350_set_irq(struct device *dev, bool enable);
-
-#ifdef CONFIG_IIO_RING_BUFFER
-
-#define ADIS16350_SCAN_SUPPLY	0
-#define ADIS16350_SCAN_GYRO_X	1
-#define ADIS16350_SCAN_GYRO_Y	2
-#define ADIS16350_SCAN_GYRO_Z	3
-#define ADIS16350_SCAN_ACC_X	4
-#define ADIS16350_SCAN_ACC_Y	5
-#define ADIS16350_SCAN_ACC_Z	6
-#define ADIS16350_SCAN_TEMP_X	7
-#define ADIS16350_SCAN_TEMP_Y	8
-#define ADIS16350_SCAN_TEMP_Z	9
-#define ADIS16350_SCAN_ADC_0	10
-
-void adis16350_remove_trigger(struct iio_dev *indio_dev);
-int adis16350_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16350_read_data_from_ring(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf);
-
-
-int adis16350_configure_ring(struct iio_dev *indio_dev);
-void adis16350_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_RING_BUFFER */
-
-static inline void adis16350_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16350_probe_trigger(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline ssize_t
-adis16350_read_data_from_ring(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	return 0;
-}
-
-static inline int adis16350_configure_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_IIO_RING_BUFFER */
-#endif /* SPI_ADIS16350_H_ */
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
deleted file mode 100644
index 741502d..0000000
--- a/drivers/staging/iio/imu/adis16350_core.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * ADIS16350/54/55/60/62/64/65 high precision tri-axis inertial sensor
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_generic.h"
-#include "../accel/accel.h"
-#include "../adc/adc.h"
-#include "../gyro/gyro.h"
-
-#include "adis16350.h"
-
-#define DRIVER_NAME		"adis16350"
-
-static int adis16350_check_status(struct device *dev);
-
-/**
- * adis16350_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16350_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16350_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16350_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
-{
-	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		}, {
-			.tx_buf = st->tx + 2,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_WRITE_REG(lower_reg_address);
-	st->tx[1] = value & 0xFF;
-	st->tx[2] = ADIS16350_WRITE_REG(lower_reg_address + 1);
-	st->tx[3] = (value >> 8) & 0xFF;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16350_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16350_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		}, {
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_READ_REG(lower_reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	if (ret) {
-		dev_err(&st->us->dev,
-			"problem when reading 16 bit register 0x%02X",
-			lower_reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-
-static ssize_t adis16350_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16350_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16350_ERROR_ACTIVE)
-		adis16350_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16350_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16350_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16350_ERROR_ACTIVE)
-		adis16350_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16350_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16350_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16350_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16350_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16350_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16350_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t adis16350_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u16 t;
-	int sps;
-	ret = adis16350_spi_read_reg_16(dev,
-			ADIS16350_SMPL_PRD,
-			&t);
-	if (ret)
-		return ret;
-	sps =  (t & ADIS16350_SMPL_PRD_TIME_BASE) ? 53 : 1638;
-	sps /= (t & ADIS16350_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
-	return len;
-}
-
-static ssize_t adis16350_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	long val;
-	int ret;
-	u8 t;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	t = (1638 / val);
-	if (t > 0)
-		t--;
-	t &= ADIS16350_SMPL_PRD_DIV_MASK;
-	if ((t & ADIS16350_SMPL_PRD_DIV_MASK) >= 0x0A)
-		st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADIS16350_SPI_FAST;
-
-	ret = adis16350_spi_write_reg_8(dev,
-			ADIS16350_SMPL_PRD,
-			t);
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-static int adis16350_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16350_spi_write_reg_8(dev,
-			ADIS16350_GLOB_CMD,
-			ADIS16350_GLOB_CMD_SW_RESET);
-	if (ret)
-		dev_err(dev, "problem resetting device");
-
-	return ret;
-}
-
-static ssize_t adis16350_write_reset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	if (len < 1)
-		return -1;
-	switch (buf[0]) {
-	case '1':
-	case 'y':
-	case 'Y':
-		return adis16350_reset(dev);
-	}
-	return -1;
-}
-
-int adis16350_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u16 msc;
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_MSC_CTRL, &msc);
-	if (ret)
-		goto error_ret;
-
-	msc |= ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH;
-	msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_DIO2;
-
-	if (enable)
-		msc |= ADIS16350_MSC_CTRL_DATA_RDY_EN;
-	else
-		msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_EN;
-
-	ret = adis16350_spi_write_reg_16(dev, ADIS16350_MSC_CTRL, msc);
-	if (ret)
-		goto error_ret;
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int adis16350_stop_device(struct device *dev)
-{
-	int ret;
-	u16 val = ADIS16350_SLP_CNT_POWER_OFF;
-
-	ret = adis16350_spi_write_reg_16(dev, ADIS16350_SLP_CNT, val);
-	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
-
-	return ret;
-}
-
-static int adis16350_self_test(struct device *dev)
-{
-	int ret;
-	ret = adis16350_spi_write_reg_16(dev,
-			ADIS16350_MSC_CTRL,
-			ADIS16350_MSC_CTRL_MEM_TEST);
-	if (ret) {
-		dev_err(dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	adis16350_check_status(dev);
-
-err_ret:
-	return ret;
-}
-
-static int adis16350_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_DIAG_STAT, &status);
-
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status;
-	if (status & ADIS16350_DIAG_STAT_ZACCL_FAIL)
-		dev_err(dev, "Z-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_YACCL_FAIL)
-		dev_err(dev, "Y-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_XACCL_FAIL)
-		dev_err(dev, "X-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_XGYRO_FAIL)
-		dev_err(dev, "X-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_YGYRO_FAIL)
-		dev_err(dev, "Y-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_ZGYRO_FAIL)
-		dev_err(dev, "Z-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_ALARM2)
-		dev_err(dev, "Alarm 2 active\n");
-	if (status & ADIS16350_DIAG_STAT_ALARM1)
-		dev_err(dev, "Alarm 1 active\n");
-	if (status & ADIS16350_DIAG_STAT_FLASH_CHK)
-		dev_err(dev, "Flash checksum error\n");
-	if (status & ADIS16350_DIAG_STAT_SELF_TEST)
-		dev_err(dev, "Self test error\n");
-	if (status & ADIS16350_DIAG_STAT_OVERFLOW)
-		dev_err(dev, "Sensor overrange\n");
-	if (status & ADIS16350_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16350_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16350_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 5.25V\n");
-	if (status & ADIS16350_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16350_initial_setup(struct adis16350_state *st)
-{
-	int ret;
-	u16 smp_prd;
-	struct device *dev = &st->indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = adis16350_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	/* Do self test */
-	ret = adis16350_self_test(dev);
-	if (ret) {
-		dev_err(dev, "self test failure");
-		goto err_ret;
-	}
-
-	/* Read status register to check the result */
-	ret = adis16350_check_status(dev);
-	if (ret) {
-		adis16350_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
-		msleep(ADIS16350_STARTUP_DELAY);
-		ret = adis16350_check_status(dev);
-		if (ret) {
-			dev_err(dev, "giving up");
-			goto err_ret;
-		}
-	}
-
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
-	/* use high spi speed if possible */
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_SMPL_PRD, &smp_prd);
-	if (!ret && (smp_prd & ADIS16350_SMPL_PRD_DIV_MASK) < 0x0A) {
-		st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-		spi_setup(st->us);
-	}
-
-err_ret:
-	return ret;
-}
-
-static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_XGYRO_OFF);
-
-static IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_YGYRO_OFF);
-
-static IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_ZGYRO_OFF);
-
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_XACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_YACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_ZACCL_OFF);
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16350_read_12bit_unsigned,
-		ADIS16350_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.002418");
-
-static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
-		ADIS16350_XGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Y(adis16350_read_14bit_signed,
-		ADIS16350_YGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Z(adis16350_read_14bit_signed,
-		ADIS16350_ZGYRO_OUT);
-static IIO_CONST_ATTR_GYRO_SCALE("0.00127862821");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
-		ADIS16350_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16350_read_14bit_signed,
-		ADIS16350_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16350_read_14bit_signed,
-		ADIS16350_ZACCL_OUT);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.0247323713");
-
-static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_XTEMP_OUT);
-static IIO_DEVICE_ATTR(temp_y_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_YTEMP_OUT);
-static IIO_DEVICE_ATTR(temp_z_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_ZTEMP_OUT);
-static IIO_CONST_ATTR_TEMP_SCALE("0.14534");
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16350_read_12bit_unsigned,
-		ADIS16350_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806");
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		adis16350_read_frequency,
-		adis16350_write_frequency);
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
-		adis16350_write_reset, 0);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-
-static IIO_CONST_ATTR_NAME("adis16350");
-
-static struct attribute *adis16350_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_y_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_temp_x_raw.dev_attr.attr,
-	&iio_dev_attr_temp_y_raw.dev_attr.attr,
-	&iio_dev_attr_temp_z_raw.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group adis16350_attribute_group = {
-	.attrs = adis16350_attributes,
-};
-
-static int __devinit adis16350_probe(struct spi_device *spi)
-{
-	int ret, regdone = 0;
-	struct adis16350_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
-		goto error_ret;
-	}
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
-
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16350_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16350_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
-
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16350_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = adis16350_configure_ring(st->indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	ret = iio_device_register(st->indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
-	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
-		goto error_unreg_ring_funcs;
-	}
-
-	if (spi->irq) {
-		ret = adis16350_probe_trigger(st->indio_dev);
-		if (ret)
-			goto error_uninitialize_ring;
-	}
-
-	/* Get the device into a sane initial state */
-	ret = adis16350_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
-	return 0;
-
-error_remove_trigger:
-	adis16350_remove_trigger(st->indio_dev);
-error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
-error_unreg_ring_funcs:
-	adis16350_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
-error_ret:
-	return ret;
-}
-
-static int adis16350_remove(struct spi_device *spi)
-{
-	int ret;
-	struct adis16350_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	ret = adis16350_stop_device(&(indio_dev->dev));
-	if (ret)
-		goto err_ret;
-
-	flush_scheduled_work();
-
-	adis16350_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
-	iio_device_unregister(indio_dev);
-	adis16350_unconfigure_ring(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
-
-	return 0;
-
-err_ret:
-	return ret;
-}
-
-static const struct spi_device_id adis16350_id[] = {
-	{"adis16350", 0},
-	{"adis16354", 0},
-	{"adis16355", 0},
-	{"adis16360", 0},
-	{"adis16362", 0},
-	{"adis16364", 0},
-	{"adis16365", 0},
-	{}
-};
-
-static struct spi_driver adis16350_driver = {
-	.driver = {
-		.name = "adis16350",
-		.owner = THIS_MODULE,
-	},
-	.probe = adis16350_probe,
-	.remove = __devexit_p(adis16350_remove),
-	.id_table = adis16350_id,
-};
-
-static __init int adis16350_init(void)
-{
-	return spi_register_driver(&adis16350_driver);
-}
-module_init(adis16350_init);
-
-static __exit void adis16350_exit(void)
-{
-	spi_unregister_driver(&adis16350_driver);
-}
-module_exit(adis16350_exit);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
deleted file mode 100644
index 56b70cf..0000000
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ /dev/null
@@ -1,236 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_sw.h"
-#include "../accel/accel.h"
-#include "../trigger.h"
-#include "adis16350.h"
-
-static IIO_SCAN_EL_C(in0_supply, ADIS16350_SCAN_SUPPLY,
-		ADIS16350_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 12, 16);
-
-static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, ADIS16350_XGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_y, ADIS16350_SCAN_GYRO_Y, ADIS16350_YGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_z, ADIS16350_SCAN_GYRO_Z, ADIS16350_ZGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACC_X, ADIS16350_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACC_Y, ADIS16350_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACC_Z, ADIS16350_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp_x, ADIS16350_SCAN_TEMP_X, ADIS16350_XTEMP_OUT, NULL);
-static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, ADIS16350_YTEMP_OUT, NULL);
-static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, ADIS16350_ZTEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16350_SCAN_ADC_0, ADIS16350_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(11);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16350_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_scan_el_gyro_y.dev_attr.attr,
-	&iio_const_attr_gyro_y_index.dev_attr.attr,
-	&iio_scan_el_gyro_z.dev_attr.attr,
-	&iio_const_attr_gyro_z_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_temp_x.dev_attr.attr,
-	&iio_const_attr_temp_x_index.dev_attr.attr,
-	&iio_scan_el_temp_y.dev_attr.attr,
-	&iio_const_attr_temp_y_index.dev_attr.attr,
-	&iio_scan_el_temp_z.dev_attr.attr,
-	&iio_const_attr_temp_z_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16350_scan_el_group = {
-	.attrs = adis16350_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16350_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16350_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
- * adis16350_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int adis16350_spi_read_burst(struct device *dev, u8 *rx)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	u32 old_speed_hz = st->us->max_speed_hz;
-	int ret;
-
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 0,
-		}, {
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 22,
-			.cs_change = 0,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_READ_REG(ADIS16350_GLOB_CMD);
-	st->tx[1] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-
-	st->us->max_speed_hz = ADIS16350_SPI_BURST;
-	spi_setup(st->us);
-
-	ret = spi_sync(st->us, &msg);
-	if (ret)
-		dev_err(&st->us->dev, "problem when burst reading");
-
-	st->us->max_speed_hz = old_speed_hz;
-	spi_setup(st->us);
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct adis16350_state *st
-		= container_of(work_s, struct adis16350_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0;
-	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize , GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
-
-	/* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-
-void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
-{
-	kfree(indio_dev->pollfunc);
-	iio_sw_rb_free(indio_dev->ring);
-}
-
-int adis16350_configure_ring(struct iio_dev *indio_dev)
-{
-	int ret = 0;
-	struct adis16350_state *st = indio_dev->dev_data;
-	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
-
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
-		ret = -ENOMEM;
-		return ret;
-	}
-	indio_dev->ring = ring;
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16350_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
-
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
-
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
-	if (ret)
-		goto error_iio_sw_rb_free;
-
-	indio_dev->modes |= INDIO_RING_TRIGGERED;
-	return 0;
-
-error_iio_sw_rb_free:
-	iio_sw_rb_free(indio_dev->ring);
-	return ret;
-}
-
diff --git a/drivers/staging/iio/imu/adis16350_trigger.c b/drivers/staging/iio/imu/adis16350_trigger.c
deleted file mode 100644
index 8d35913..0000000
--- a/drivers/staging/iio/imu/adis16350_trigger.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../trigger.h"
-#include "adis16350.h"
-
-/**
- * adis16350_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16350_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16350_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16350_trigger_attr_group = {
-	.attrs = adis16350_trigger_attrs,
-};
-
-/**
- * adis16350_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16350_data_rdy_trigger_set_state(struct iio_trigger *trig,
-						bool state)
-{
-	struct adis16350_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16350_set_irq(&st->indio_dev->dev, state);
-}
-
-/**
- * adis16350_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16350_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16350_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
-}
-
-int adis16350_probe_trigger(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct adis16350_state *st = indio_dev->dev_data;
-
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = request_irq(st->us->irq,
-			  adis16350_data_rdy_trig_poll,
-			  IRQF_TRIGGER_RISING,
-			  "adis16350",
-			  st->trig);
-	if (ret)
-		goto error_free_trig;
-
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16350-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
-	st->trig->dev.parent = &st->us->dev;
-	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
-	st->trig->set_trigger_state = &adis16350_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16350_trig_try_reen;
-	st->trig->control_attrs = &adis16350_trigger_attr_group;
-	ret = iio_trigger_register(st->trig);
-
-	/* select default trigger */
-	indio_dev->trig = st->trig;
-	if (ret)
-		goto error_free_trig_name;
-
-	return 0;
-
-error_free_trig_name:
-	kfree(st->trig->name);
-error_free_irq:
-	free_irq(st->us->irq, st->trig);
-error_free_trig:
-	iio_free_trigger(st->trig);
-error_ret:
-	return ret;
-}
-
-void adis16350_remove_trigger(struct iio_dev *indio_dev)
-{
-	struct adis16350_state *state = indio_dev->dev_data;
-
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	free_irq(state->us->irq, state->trig);
-	iio_free_trigger(state->trig);
-}
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 040/111] staging:iio:imu:adis16400 add support for adis16300
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (38 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 039/111] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 041/111] staging:iio:imu remove adis16300 driver Jonathan Cameron
                   ` (71 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Next patch will remove original driver.
Note this leaves holes in the scan indexing.

Untested - except via adis16350...

V3: rebase fixup.
V2: move to single IIO_CHAN macro.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/Kconfig          |    8 ++--
 drivers/staging/iio/imu/adis16400.h      |    2 +
 drivers/staging/iio/imu/adis16400_core.c |   50 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index d8f568f..082614d 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -18,7 +18,7 @@ config ADIS16400
 	select IIO_SW_RING if IIO_RING_BUFFER
 	select IIO_TRIGGER if IIO_RING_BUFFER
 	help
-	  Say yes here to build support for Analog Devices adis16350, adis16354,
-	  adis16355, adis16360, adis16362, adis16364, adis16365, adis16400 and
-	  adis16405 triaxial inertial sensors (adis16400 series also have
-	  magnetometers).
+	  Say yes here to build support for Analog Devices adis16300, adis16350,
+	  adis16354, adis16355, adis16360, adis16362, adis16364, adis16365,
+	  adis16400 and adis16405 triaxial inertial sensors (adis16400 series
+	  also have magnetometers).
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index ec3449b..9804c41 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -180,6 +180,8 @@ int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
 #define ADIS16400_SCAN_TEMP	10
 #define ADIS16350_SCAN_ADC_0	10
 #define ADIS16400_SCAN_ADC_0	11
+#define ADIS16300_SCAN_INCLI_X	12
+#define ADIS16300_SCAN_INCLI_Y	13
 
 void adis16400_remove_trigger(struct iio_dev *indio_dev);
 int adis16400_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index fad7744..ddcae43 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -39,6 +39,7 @@
 #define DRIVER_NAME		"adis16400"
 
 enum adis16400_chip_variant {
+	ADIS16300,
 	ADIS16350,
 	ADIS16360,
 	ADIS16362,
@@ -663,6 +664,42 @@ static struct iio_chan_spec adis16350_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(11)
 };
 
+static struct iio_chan_spec adis16300_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(14)
+};
+
 static struct attribute *adis16400_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
@@ -676,6 +713,18 @@ static const struct attribute_group adis16400_attribute_group = {
 };
 
 static struct adis16400_chip_info adis16400_chips[] = {
+	[ADIS16300] = {
+		.channels = adis16300_channels,
+		.num_channels = ARRAY_SIZE(adis16300_channels),
+		.gyro_scale_micro = 873,
+		.accel_scale_micro = 5884,
+		.default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) |
+		(1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) |
+		(1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) |
+		(1 << ADIS16400_SCAN_TEMP) | (1 << ADIS16400_SCAN_ADC_0) |
+		(1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) |
+		(1 << 14),
+	},
 	[ADIS16350] = {
 		.channels = adis16350_channels,
 		.num_channels = ARRAY_SIZE(adis16350_channels),
@@ -852,6 +901,7 @@ err_ret:
 }
 
 static const struct spi_device_id adis16400_id[] = {
+	{"adis16300", ADIS16300},
 	{"adis16350", ADIS16350},
 	{"adis16354", ADIS16350},
 	{"adis16355", ADIS16350},
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 041/111] staging:iio:imu remove adis16300 driver.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (39 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 040/111] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 042/111] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
                   ` (70 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Support is now provided by the unified adis16400 driver.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/Kconfig             |    9 -
 drivers/staging/iio/imu/Makefile            |    4 -
 drivers/staging/iio/imu/adis16300.h         |  184 -------
 drivers/staging/iio/imu/adis16300_core.c    |  732 ---------------------------
 drivers/staging/iio/imu/adis16300_ring.c    |  238 ---------
 drivers/staging/iio/imu/adis16300_trigger.c |  119 -----
 6 files changed, 0 insertions(+), 1286 deletions(-)

diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index 082614d..e0e0144 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -3,15 +3,6 @@
 #
 comment "Inertial measurement units"
 
-config ADIS16300
-	tristate "Analog Devices ADIS16300 IMU SPI driver"
-	depends on SPI
-	select IIO_SW_RING if IIO_RING_BUFFER
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	help
-	  Say yes here to build support for Analog Devices adis16300 four degrees
-	  of freedom inertial sensor.
-
 config ADIS16400
 	tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
 	depends on SPI
diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile
index de6b1e7..d46a691 100644
--- a/drivers/staging/iio/imu/Makefile
+++ b/drivers/staging/iio/imu/Makefile
@@ -2,10 +2,6 @@
 # Makefile for Inertial Measurement Units
 #
 
-adis16300-y             := adis16300_core.o
-adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
-obj-$(CONFIG_ADIS16300) += adis16300.o
-
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o
 obj-$(CONFIG_ADIS16400) += adis16400.o
diff --git a/drivers/staging/iio/imu/adis16300.h b/drivers/staging/iio/imu/adis16300.h
deleted file mode 100644
index c095759..0000000
--- a/drivers/staging/iio/imu/adis16300.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef SPI_ADIS16300_H_
-#define SPI_ADIS16300_H_
-
-#define ADIS16300_STARTUP_DELAY	220 /* ms */
-
-#define ADIS16300_READ_REG(a)    a
-#define ADIS16300_WRITE_REG(a) ((a) | 0x80)
-
-#define ADIS16300_FLASH_CNT  0x00 /* Flash memory write count */
-#define ADIS16300_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16300_XGYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16300_XACCL_OUT 0x0A /* X-axis accelerometer output */
-#define ADIS16300_YACCL_OUT 0x0C /* Y-axis accelerometer output */
-#define ADIS16300_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
-#define ADIS16300_TEMP_OUT  0x10 /* Temperature output */
-#define ADIS16300_XINCLI_OUT 0x12 /* X-axis inclinometer output measurement */
-#define ADIS16300_YINCLI_OUT 0x14 /* Y-axis inclinometer output measurement */
-#define ADIS16300_AUX_ADC   0x16 /* Auxiliary ADC measurement */
-
-/* Calibration parameters */
-#define ADIS16300_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
-#define ADIS16300_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
-#define ADIS16300_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
-#define ADIS16300_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
-
-#define ADIS16300_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
-#define ADIS16300_MSC_CTRL  0x34 /* Miscellaneous control */
-#define ADIS16300_SMPL_PRD  0x36 /* Internal sample period (rate) control */
-#define ADIS16300_SENS_AVG  0x38 /* Dynamic range and digital filter control */
-#define ADIS16300_SLP_CNT   0x3A /* Sleep mode control */
-#define ADIS16300_DIAG_STAT 0x3C /* System status */
-
-/* Alarm functions */
-#define ADIS16300_GLOB_CMD  0x3E /* System command */
-#define ADIS16300_ALM_MAG1  0x26 /* Alarm 1 amplitude threshold */
-#define ADIS16300_ALM_MAG2  0x28 /* Alarm 2 amplitude threshold */
-#define ADIS16300_ALM_SMPL1 0x2A /* Alarm 1 sample size */
-#define ADIS16300_ALM_SMPL2 0x2C /* Alarm 2 sample size */
-#define ADIS16300_ALM_CTRL  0x2E /* Alarm control */
-#define ADIS16300_AUX_DAC   0x30 /* Auxiliary DAC data */
-
-#define ADIS16300_ERROR_ACTIVE			(1<<14)
-#define ADIS16300_NEW_DATA			(1<<15)
-
-/* MSC_CTRL */
-#define ADIS16300_MSC_CTRL_MEM_TEST		(1<<11)
-#define ADIS16300_MSC_CTRL_INT_SELF_TEST	(1<<10)
-#define ADIS16300_MSC_CTRL_NEG_SELF_TEST	(1<<9)
-#define ADIS16300_MSC_CTRL_POS_SELF_TEST	(1<<8)
-#define ADIS16300_MSC_CTRL_GYRO_BIAS		(1<<7)
-#define ADIS16300_MSC_CTRL_ACCL_ALIGN		(1<<6)
-#define ADIS16300_MSC_CTRL_DATA_RDY_EN		(1<<2)
-#define ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
-#define ADIS16300_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
-
-/* SMPL_PRD */
-#define ADIS16300_SMPL_PRD_TIME_BASE	(1<<7)
-#define ADIS16300_SMPL_PRD_DIV_MASK	0x7F
-
-/* DIAG_STAT */
-#define ADIS16300_DIAG_STAT_ZACCL_FAIL	(1<<15)
-#define ADIS16300_DIAG_STAT_YACCL_FAIL	(1<<14)
-#define ADIS16300_DIAG_STAT_XACCL_FAIL	(1<<13)
-#define ADIS16300_DIAG_STAT_XGYRO_FAIL	(1<<10)
-#define ADIS16300_DIAG_STAT_ALARM2	(1<<9)
-#define ADIS16300_DIAG_STAT_ALARM1	(1<<8)
-#define ADIS16300_DIAG_STAT_FLASH_CHK	(1<<6)
-#define ADIS16300_DIAG_STAT_SELF_TEST	(1<<5)
-#define ADIS16300_DIAG_STAT_OVERFLOW	(1<<4)
-#define ADIS16300_DIAG_STAT_SPI_FAIL	(1<<3)
-#define ADIS16300_DIAG_STAT_FLASH_UPT	(1<<2)
-#define ADIS16300_DIAG_STAT_POWER_HIGH	(1<<1)
-#define ADIS16300_DIAG_STAT_POWER_LOW	(1<<0)
-
-/* GLOB_CMD */
-#define ADIS16300_GLOB_CMD_SW_RESET	(1<<7)
-#define ADIS16300_GLOB_CMD_P_AUTO_NULL	(1<<4)
-#define ADIS16300_GLOB_CMD_FLASH_UPD	(1<<3)
-#define ADIS16300_GLOB_CMD_DAC_LATCH	(1<<2)
-#define ADIS16300_GLOB_CMD_FAC_CALIB	(1<<1)
-#define ADIS16300_GLOB_CMD_AUTO_NULL	(1<<0)
-
-/* SLP_CNT */
-#define ADIS16300_SLP_CNT_POWER_OFF	(1<<8)
-
-#define ADIS16300_MAX_TX 18
-#define ADIS16300_MAX_RX 18
-
-#define ADIS16300_SPI_SLOW	(u32)(300 * 1000)
-#define ADIS16300_SPI_BURST	(u32)(1000 * 1000)
-#define ADIS16300_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct adis16300_state - device instance specific data
- * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
- * @trig:		data ready trigger registered with iio
- * @tx:			transmit buffer
- * @rx:			receive buffer
- * @buf_lock:		mutex to protect tx and rx
- **/
-struct adis16300_state {
-	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
-};
-
-int adis16300_set_irq(struct device *dev, bool enable);
-
-#ifdef CONFIG_IIO_RING_BUFFER
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16300_SCAN_SUPPLY	0
-#define ADIS16300_SCAN_GYRO_X	1
-#define ADIS16300_SCAN_ACC_X	2
-#define ADIS16300_SCAN_ACC_Y	3
-#define ADIS16300_SCAN_ACC_Z	4
-#define ADIS16300_SCAN_TEMP	5
-#define ADIS16300_SCAN_ADC_0	6
-#define ADIS16300_SCAN_INCLI_X	7
-#define ADIS16300_SCAN_INCLI_Y	8
-
-void adis16300_remove_trigger(struct iio_dev *indio_dev);
-int adis16300_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16300_read_data_from_ring(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf);
-
-
-int adis16300_configure_ring(struct iio_dev *indio_dev);
-void adis16300_unconfigure_ring(struct iio_dev *indio_dev);
-
-int adis16300_initialize_ring(struct iio_ring_buffer *ring);
-void adis16300_uninitialize_ring(struct iio_ring_buffer *ring);
-#else /* CONFIG_IIO_RING_BUFFER */
-
-static inline void adis16300_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16300_probe_trigger(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline ssize_t
-adis16300_read_data_from_ring(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	return 0;
-}
-
-static int adis16300_configure_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline void adis16300_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16300_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16300_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
-#endif /* CONFIG_IIO_RING_BUFFER */
-#endif /* SPI_ADIS16300_H_ */
diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c
deleted file mode 100644
index 903bb30..0000000
--- a/drivers/staging/iio/imu/adis16300_core.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * ADIS16300 Four Degrees of Freedom Inertial Sensor Driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_generic.h"
-#include "../accel/accel.h"
-#include "../accel/inclinometer.h"
-#include "../gyro/gyro.h"
-#include "../adc/adc.h"
-
-#include "adis16300.h"
-
-#define DRIVER_NAME		"adis16300"
-
-static int adis16300_check_status(struct device *dev);
-
-/**
- * adis16300_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16300_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16300_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16300_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
-{
-	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		}, {
-			.tx_buf = st->tx + 2,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_WRITE_REG(lower_reg_address);
-	st->tx[1] = value & 0xFF;
-	st->tx[2] = ADIS16300_WRITE_REG(lower_reg_address + 1);
-	st->tx[3] = (value >> 8) & 0xFF;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16300_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16300_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		}, {
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_READ_REG(lower_reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	if (ret) {
-		dev_err(&st->us->dev,
-			"problem when reading 16 bit register 0x%02X",
-			lower_reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t adis16300_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16300_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16300_read_14bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x3FFF);
-}
-
-static ssize_t adis16300_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_read_13bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 13);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16300_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t adis16300_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u16 t;
-	int sps;
-	ret = adis16300_spi_read_reg_16(dev,
-			ADIS16300_SMPL_PRD,
-			&t);
-	if (ret)
-		return ret;
-	sps =  (t & ADIS16300_SMPL_PRD_TIME_BASE) ? 53 : 1638;
-	sps /= (t & ADIS16300_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
-	return len;
-}
-
-static ssize_t adis16300_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	long val;
-	int ret;
-	u8 t;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	t = (1638 / val);
-	if (t > 0)
-		t--;
-	t &= ADIS16300_SMPL_PRD_DIV_MASK;
-	if ((t & ADIS16300_SMPL_PRD_DIV_MASK) >= 0x0A)
-		st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADIS16300_SPI_FAST;
-
-	ret = adis16300_spi_write_reg_8(dev,
-			ADIS16300_SMPL_PRD,
-			t);
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-static int adis16300_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16300_spi_write_reg_8(dev,
-			ADIS16300_GLOB_CMD,
-			ADIS16300_GLOB_CMD_SW_RESET);
-	if (ret)
-		dev_err(dev, "problem resetting device");
-
-	return ret;
-}
-
-static ssize_t adis16300_write_reset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	if (len < 1)
-		return -1;
-	switch (buf[0]) {
-	case '1':
-	case 'y':
-	case 'Y':
-		return adis16300_reset(dev);
-	}
-	return -1;
-}
-
-int adis16300_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u16 msc;
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_MSC_CTRL, &msc);
-	if (ret)
-		goto error_ret;
-
-	msc |= ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH;
-	msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_DIO2;
-	if (enable)
-		msc |= ADIS16300_MSC_CTRL_DATA_RDY_EN;
-	else
-		msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_EN;
-
-	ret = adis16300_spi_write_reg_16(dev, ADIS16300_MSC_CTRL, msc);
-	if (ret)
-		goto error_ret;
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int adis16300_stop_device(struct device *dev)
-{
-	int ret;
-	u16 val = ADIS16300_SLP_CNT_POWER_OFF;
-
-	ret = adis16300_spi_write_reg_16(dev, ADIS16300_SLP_CNT, val);
-	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
-
-	return ret;
-}
-
-static int adis16300_self_test(struct device *dev)
-{
-	int ret;
-	ret = adis16300_spi_write_reg_16(dev,
-			ADIS16300_MSC_CTRL,
-			ADIS16300_MSC_CTRL_MEM_TEST);
-	if (ret) {
-		dev_err(dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	adis16300_check_status(dev);
-
-err_ret:
-	return ret;
-}
-
-static int adis16300_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_DIAG_STAT, &status);
-
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status;
-	if (status & ADIS16300_DIAG_STAT_ZACCL_FAIL)
-		dev_err(dev, "Z-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_YACCL_FAIL)
-		dev_err(dev, "Y-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_XACCL_FAIL)
-		dev_err(dev, "X-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_XGYRO_FAIL)
-		dev_err(dev, "X-axis gyroscope self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_ALARM2)
-		dev_err(dev, "Alarm 2 active\n");
-	if (status & ADIS16300_DIAG_STAT_ALARM1)
-		dev_err(dev, "Alarm 1 active\n");
-	if (status & ADIS16300_DIAG_STAT_FLASH_CHK)
-		dev_err(dev, "Flash checksum error\n");
-	if (status & ADIS16300_DIAG_STAT_SELF_TEST)
-		dev_err(dev, "Self test error\n");
-	if (status & ADIS16300_DIAG_STAT_OVERFLOW)
-		dev_err(dev, "Sensor overrange\n");
-	if (status & ADIS16300_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16300_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16300_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 5.25V\n");
-	if (status & ADIS16300_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16300_initial_setup(struct adis16300_state *st)
-{
-	int ret;
-	u16 smp_prd;
-	struct device *dev = &st->indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = adis16300_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	/* Do self test */
-	ret = adis16300_self_test(dev);
-	if (ret) {
-		dev_err(dev, "self test failure");
-		goto err_ret;
-	}
-
-	/* Read status register to check the result */
-	ret = adis16300_check_status(dev);
-	if (ret) {
-		adis16300_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
-		msleep(ADIS16300_STARTUP_DELAY);
-		ret = adis16300_check_status(dev);
-		if (ret) {
-			dev_err(dev, "giving up");
-			goto err_ret;
-		}
-	}
-
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
-	/* use high spi speed if possible */
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_SMPL_PRD, &smp_prd);
-	if (!ret && (smp_prd & ADIS16300_SMPL_PRD_DIV_MASK) < 0x0A) {
-		st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-		spi_setup(st->us);
-	}
-
-err_ret:
-	return ret;
-}
-
-static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_XGYRO_OFF);
-
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_XACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_YACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_ZACCL_OFF);
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16300_read_14bit_unsigned,
-			   ADIS16300_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.00242");
-
-static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed,
-		ADIS16300_XGYRO_OUT);
-static IIO_CONST_ATTR_GYRO_SCALE("0.000872664");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
-		ADIS16300_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16300_read_14bit_signed,
-		ADIS16300_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16300_read_14bit_signed,
-		ADIS16300_ZACCL_OUT);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.00588399");
-
-static IIO_DEV_ATTR_INCLI_X(adis16300_read_13bit_signed,
-		ADIS16300_XINCLI_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed,
-		ADIS16300_YINCLI_OUT);
-static IIO_CONST_ATTR_INCLI_SCALE("0.00076794487");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
-static IIO_CONST_ATTR_TEMP_SCALE("0.14");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16300_read_12bit_unsigned,
-		ADIS16300_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806");
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		adis16300_read_frequency,
-		adis16300_write_frequency);
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-
-static IIO_CONST_ATTR_NAME("adis16300");
-
-static struct attribute *adis16300_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group adis16300_attribute_group = {
-	.attrs = adis16300_attributes,
-};
-
-static int __devinit adis16300_probe(struct spi_device *spi)
-{
-	int ret, regdone = 0;
-	struct adis16300_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
-		goto error_ret;
-	}
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
-
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16300_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16300_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
-
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16300_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = adis16300_configure_ring(st->indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	ret = iio_device_register(st->indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
-	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
-		goto error_unreg_ring_funcs;
-	}
-
-	if (spi->irq) {
-		ret = adis16300_probe_trigger(st->indio_dev);
-		if (ret)
-			goto error_uninitialize_ring;
-	}
-
-	/* Get the device into a sane initial state */
-	ret = adis16300_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
-	return 0;
-
-error_remove_trigger:
-	adis16300_remove_trigger(st->indio_dev);
-error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
-error_unreg_ring_funcs:
-	adis16300_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
-error_ret:
-	return ret;
-}
-
-static int adis16300_remove(struct spi_device *spi)
-{
-	int ret;
-	struct adis16300_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	ret = adis16300_stop_device(&(indio_dev->dev));
-	if (ret)
-		goto err_ret;
-
-	flush_scheduled_work();
-
-	adis16300_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
-	iio_device_unregister(indio_dev);
-	adis16300_unconfigure_ring(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
-
-	return 0;
-
-err_ret:
-	return ret;
-}
-
-static struct spi_driver adis16300_driver = {
-	.driver = {
-		.name = "adis16300",
-		.owner = THIS_MODULE,
-	},
-	.probe = adis16300_probe,
-	.remove = __devexit_p(adis16300_remove),
-};
-
-static __init int adis16300_init(void)
-{
-	return spi_register_driver(&adis16300_driver);
-}
-module_init(adis16300_init);
-
-static __exit void adis16300_exit(void)
-{
-	spi_unregister_driver(&adis16300_driver);
-}
-module_exit(adis16300_exit);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16300 IMU SPI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
deleted file mode 100644
index 114fdf4..0000000
--- a/drivers/staging/iio/imu/adis16300_ring.c
+++ /dev/null
@@ -1,238 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_sw.h"
-#include "../accel/accel.h"
-#include "../trigger.h"
-#include "adis16300.h"
-
-static IIO_SCAN_EL_C(in0_supply, ADIS16300_SCAN_SUPPLY,
-		     ADIS16300_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 12, 16);
-static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, ADIS16300_XGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16300_SCAN_ACC_X, ADIS16300_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16300_SCAN_ACC_Y, ADIS16300_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, ADIS16300_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, ADIS16300_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16300_SCAN_ADC_0, ADIS16300_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X,
-		     ADIS16300_XINCLI_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y,
-		     ADIS16300_YINCLI_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 13, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(9);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16300_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16300_scan_el_group = {
-	.attrs = adis16300_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16300_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16300_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
-
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
-}
-
-/**
- * adis16300_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int adis16300_spi_read_burst(struct device *dev, u8 *rx)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	u32 old_speed_hz = st->us->max_speed_hz;
-	int ret;
-
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 0,
-		}, {
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 18,
-			.cs_change = 0,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_READ_REG(ADIS16300_GLOB_CMD);
-	st->tx[1] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-
-	st->us->max_speed_hz = ADIS16300_SPI_BURST;
-	spi_setup(st->us);
-
-	ret = spi_sync(st->us, &msg);
-	if (ret)
-		dev_err(&st->us->dev, "problem when burst reading");
-
-	st->us->max_speed_hz = old_speed_hz;
-	spi_setup(st->us);
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct adis16300_state *st
-		= container_of(work_s, struct adis16300_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0;
-	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize , GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
-
-	/* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-
-void adis16300_unconfigure_ring(struct iio_dev *indio_dev)
-{
-	kfree(indio_dev->pollfunc);
-	iio_sw_rb_free(indio_dev->ring);
-}
-
-int adis16300_configure_ring(struct iio_dev *indio_dev)
-{
-	int ret = 0;
-	struct adis16300_state *st = indio_dev->dev_data;
-	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
-
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
-		ret = -ENOMEM;
-		return ret;
-	}
-	indio_dev->ring = ring;
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16300_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
-
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
-
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
-	if (ret)
-		goto error_iio_sw_rb_free;
-
-	indio_dev->modes |= INDIO_RING_TRIGGERED;
-	return 0;
-
-error_iio_sw_rb_free:
-	iio_sw_rb_free(indio_dev->ring);
-	return ret;
-}
-
diff --git a/drivers/staging/iio/imu/adis16300_trigger.c b/drivers/staging/iio/imu/adis16300_trigger.c
deleted file mode 100644
index fd7656f..0000000
--- a/drivers/staging/iio/imu/adis16300_trigger.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../trigger.h"
-#include "adis16300.h"
-
-/**
- * adis16300_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16300_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16300_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16300_trigger_attr_group = {
-	.attrs = adis16300_trigger_attrs,
-};
-
-/**
- * adis16300_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16300_data_rdy_trigger_set_state(struct iio_trigger *trig,
-						bool state)
-{
-	struct adis16300_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16300_set_irq(&st->indio_dev->dev, state);
-}
-
-/**
- * adis16300_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16300_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16300_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
-}
-
-int adis16300_probe_trigger(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct adis16300_state *st = indio_dev->dev_data;
-
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = request_irq(st->us->irq,
-			  adis16300_data_rdy_trig_poll,
-			  IRQF_TRIGGER_RISING,
-			  "adis16300",
-			  st->trig);
-	if (ret)
-		goto error_free_trig;
-
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16300-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
-	st->trig->dev.parent = &st->us->dev;
-	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
-	st->trig->set_trigger_state = &adis16300_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16300_trig_try_reen;
-	st->trig->control_attrs = &adis16300_trigger_attr_group;
-	ret = iio_trigger_register(st->trig);
-
-	/* select default trigger */
-	indio_dev->trig = st->trig;
-	if (ret)
-		goto error_free_trig_name;
-
-	return 0;
-
-error_free_trig_name:
-	kfree(st->trig->name);
-error_free_irq:
-	free_irq(st->us->irq, st->trig);
-error_free_trig:
-	iio_free_trigger(st->trig);
-error_ret:
-	return ret;
-}
-
-void adis16300_remove_trigger(struct iio_dev *indio_dev)
-{
-	struct adis16300_state *state = indio_dev->dev_data;
-
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	free_irq(state->us->irq, state->trig);
-	iio_free_trigger(state->trig);
-}
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 042/111] staging:iio:accel:adis16201 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (40 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 041/111] staging:iio:imu remove adis16300 driver Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 043/111] staging:iio:accel:adis16203 " Jonathan Cameron
                   ` (69 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201.h         |    5 --
 drivers/staging/iio/accel/adis16201_ring.c    |   51 +++++++++++++------------
 drivers/staging/iio/accel/adis16201_trigger.c |   49 +++++++-----------------
 3 files changed, 40 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h
index 23fe54d..6296a4f 100644
--- a/drivers/staging/iio/accel/adis16201.h
+++ b/drivers/staging/iio/accel/adis16201.h
@@ -64,9 +64,6 @@
 /**
  * struct adis16201_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -75,8 +72,6 @@
  **/
 struct adis16201_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index e6870a2..d0998b2 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -66,17 +66,6 @@ static struct attribute_group adis16201_scan_el_group = {
 };
 
 /**
- * adis16201_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16201_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16201_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -120,12 +109,12 @@ static int adis16201_read_ring_data(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16201_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 {
-	struct adis16201_state *st
-		= container_of(work_s, struct adis16201_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
@@ -134,7 +123,7 @@ static void adis16201_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -145,20 +134,21 @@ static void adis16201_trigger_bh_to_ring(struct work_struct *work_s)
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
 	ring->access.store_to(ring,
 			      (u8 *)data,
-			      st->last_timestamp);
+			      pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -166,9 +156,7 @@ void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16201_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16201_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16201_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -195,13 +183,26 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
 	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16201_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16201_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16201_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c
index 8a48bdd..a4fb410 100644
--- a/drivers/staging/iio/accel/adis16201_trigger.c
+++ b/drivers/staging/iio/accel/adis16201_trigger.c
@@ -12,16 +12,6 @@
 #include "../trigger.h"
 #include "adis16201.h"
 
-/**
- * adis16201_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16201_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
 static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
 
 static struct attribute *adis16201_trigger_attrs[] = {
@@ -46,62 +36,51 @@ static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16201_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16201_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16201_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16201_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16201_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16201_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL,
+			 "adis16201-dev%d",
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
 	ret = request_irq(st->us->irq,
-			  adis16201_data_rdy_trig_poll,
+			  &iio_trigger_generic_data_rdy_poll,
 			  IRQF_TRIGGER_RISING,
 			  "adis16201",
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16201-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16201_trig_try_reen;
 	st->trig->control_attrs = &adis16201_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 043/111] staging:iio:accel:adis16203 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (41 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 042/111] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 044/111] staging:iio:accel:adis16204 " Jonathan Cameron
                   ` (68 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16203.h         |    5 --
 drivers/staging/iio/accel/adis16203_ring.c    |   51 +++++++++++++------------
 drivers/staging/iio/accel/adis16203_trigger.c |   51 ++++++++-----------------
 3 files changed, 42 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h
index b886881..49fce30 100644
--- a/drivers/staging/iio/accel/adis16203.h
+++ b/drivers/staging/iio/accel/adis16203.h
@@ -59,9 +59,6 @@
 /**
  * struct adis16203_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -70,8 +67,6 @@
  **/
 struct adis16203_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 3d774f7..cdd0aff 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -58,17 +58,6 @@ static struct attribute_group adis16203_scan_el_group = {
 };
 
 /**
- * adis16203_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16203_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
-{
-	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16203_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -115,12 +104,12 @@ static int adis16203_read_ring_data(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16203_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16203_trigger_handler(int irq, void *p)
 {
-	struct adis16203_state *st
-		= container_of(work_s, struct adis16203_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
@@ -129,7 +118,7 @@ static void adis16203_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -140,20 +129,21 @@ static void adis16203_trigger_bh_to_ring(struct work_struct *work_s)
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
 	ring->access.store_to(ring,
 			      (u8 *)data,
-			      st->last_timestamp);
+			      pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -161,9 +151,7 @@ void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16203_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16203_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16203_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -188,13 +176,26 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
 	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16203_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16203_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16203_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c
index dbc75bd..b554049 100644
--- a/drivers/staging/iio/accel/adis16203_trigger.c
+++ b/drivers/staging/iio/accel/adis16203_trigger.c
@@ -12,16 +12,6 @@
 #include "../trigger.h"
 #include "adis16203.h"
 
-/**
- * adis16203_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16203_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
 static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
 
 static struct attribute *adis16203_trigger_attrs[] = {
@@ -46,63 +36,54 @@ static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16203_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16203_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16203_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16203_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16203_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16203_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL,
+			 "adis16203-dev%d",
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
 
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
+
 	ret = request_irq(st->us->irq,
-			  adis16203_data_rdy_trig_poll,
+			  &iio_trigger_generic_data_rdy_poll,
 			  IRQF_TRIGGER_RISING,
 			  "adis16203",
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16203-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16203_trig_try_reen;
 	st->trig->control_attrs = &adis16203_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 044/111] staging:iio:accel:adis16204 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (42 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 043/111] staging:iio:accel:adis16203 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 045/111] staging:iio:accel:adis16209 " Jonathan Cameron
                   ` (67 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16204.h         |    5 --
 drivers/staging/iio/accel/adis16204_ring.c    |   53 ++++++++++++-------------
 drivers/staging/iio/accel/adis16204_trigger.c |   51 +++++++----------------
 3 files changed, 42 insertions(+), 67 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h
index e618446..bdd20c6 100644
--- a/drivers/staging/iio/accel/adis16204.h
+++ b/drivers/staging/iio/accel/adis16204.h
@@ -67,9 +67,6 @@
 /**
  * struct adis16204_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -78,8 +75,6 @@
  **/
 struct adis16204_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 420b160..035e5c4 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -56,17 +56,6 @@ static struct attribute_group adis16204_scan_el_group = {
 };
 
 /**
- * adis16204_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16204_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
-{
-	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16204_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -110,13 +99,12 @@ static int adis16204_read_ring_data(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16204_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16204_trigger_handler(int irq, void *p)
 {
-	struct adis16204_state *st
-		= container_of(work_s, struct adis16204_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
@@ -124,7 +112,7 @@ static void adis16204_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -135,20 +123,19 @@ static void adis16204_trigger_bh_to_ring(struct work_struct *work_s)
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -156,9 +143,7 @@ void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16204_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16204_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16204_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -183,13 +168,27 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_temp.number);
 	iio_scan_mask_set(ring, iio_scan_el_in0.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16204_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16204_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16204_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
 
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c
index 85c6487..5f083f8 100644
--- a/drivers/staging/iio/accel/adis16204_trigger.c
+++ b/drivers/staging/iio/accel/adis16204_trigger.c
@@ -12,16 +12,6 @@
 #include "../trigger.h"
 #include "adis16204.h"
 
-/**
- * adis16204_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16204_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
 static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
 
 static struct attribute *adis16204_trigger_attrs[] = {
@@ -46,63 +36,54 @@ static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16204_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16204_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16204_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16204_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16204_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16204_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL,
+			 "adis16204-dev%d",
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
+
 	ret = request_irq(st->us->irq,
-			  adis16204_data_rdy_trig_poll,
+			  &iio_trigger_generic_data_rdy_poll,
 			  IRQF_TRIGGER_RISING,
 			  "adis16204",
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
 
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16204-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16204_trig_try_reen;
 	st->trig->control_attrs = &adis16204_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 045/111] staging:iio:accel:adis16209 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (43 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 044/111] staging:iio:accel:adis16204 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 046/111] staging:iio:accel:adis16240 " Jonathan Cameron
                   ` (66 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16209.h         |    4 --
 drivers/staging/iio/accel/adis16209_ring.c    |   62 ++++++++++++-------------
 drivers/staging/iio/accel/adis16209_trigger.c |   40 ++++++----------
 3 files changed, 45 insertions(+), 61 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
index 8b0da13..9ef596f 100644
--- a/drivers/staging/iio/accel/adis16209.h
+++ b/drivers/staging/iio/accel/adis16209.h
@@ -104,8 +104,6 @@
 /**
  * struct adis16209_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -114,8 +112,6 @@
  **/
 struct adis16209_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 8eba0af..6e66469 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -72,17 +72,6 @@ static struct attribute_group adis16209_scan_el_group = {
 };
 
 /**
- * adis16209_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16209_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -127,12 +116,12 @@ static int adis16209_read_ring_data(struct device *dev, u8 *rx)
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16209_trigger_handler(int irq, void *p)
 {
-	struct adis16209_state *st
-		= container_of(work_s, struct adis16209_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
@@ -141,31 +130,29 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -173,9 +160,7 @@ void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16209_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16209_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -203,13 +188,26 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
 	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16209_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16209_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
index 488e482..86e83c3 100644
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ b/drivers/staging/iio/accel/adis16209_trigger.c
@@ -17,7 +17,6 @@
  **/
 static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig)
 {
-	disable_irq_nosync(irq);
 	iio_trigger_poll(trig, iio_get_time_ns());
 	return IRQ_HANDLED;
 }
@@ -46,27 +45,26 @@ static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16209_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16209_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16209_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16209_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16209_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16209_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL,
+			 "adis16209-dev%d",
+			 indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
+
 	ret = request_irq(st->us->irq,
 			  adis16209_data_rdy_trig_poll,
 			  IRQF_TRIGGER_RISING,
@@ -74,34 +72,26 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev)
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16209-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16209_trig_try_reen;
 	st->trig->control_attrs = &adis16209_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 046/111] staging:iio:accel:adis16240 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (44 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 045/111] staging:iio:accel:adis16209 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 047/111] staging:iio:adc:ad7298 " Jonathan Cameron
                   ` (65 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16240.h         |    5 --
 drivers/staging/iio/accel/adis16240_ring.c    |   66 ++++++++++++-------------
 drivers/staging/iio/accel/adis16240_trigger.c |   37 +++++---------
 3 files changed, 43 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h
index 76a4579..364aabf 100644
--- a/drivers/staging/iio/accel/adis16240.h
+++ b/drivers/staging/iio/accel/adis16240.h
@@ -126,9 +126,6 @@
 /**
  * struct adis16240_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -137,8 +134,6 @@
  **/
 struct adis16240_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index f882e9c..a6d27d21 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -60,17 +60,6 @@ static struct attribute_group adis16240_scan_el_group = {
 };
 
 /**
- * adis16240_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16240_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16240_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -112,46 +101,43 @@ static int adis16240_read_ring_data(struct device *dev, u8 *rx)
 	return ret;
 }
 
-
-static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16240_trigger_handler(int irq, void *p)
 {
-	struct adis16240_state *st
-		= container_of(work_s, struct adis16240_state,
-				work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
-	data = kmalloc(datasize , GFP_KERNEL);
+	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
+	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -159,9 +145,7 @@ void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16240_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16240_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -187,13 +171,25 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_temp.number);
 	iio_scan_mask_set(ring, iio_scan_el_in0.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
-
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16240_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16240_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c
index 3976c85..55e2145 100644
--- a/drivers/staging/iio/accel/adis16240_trigger.c
+++ b/drivers/staging/iio/accel/adis16240_trigger.c
@@ -17,7 +17,6 @@
  **/
 static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig)
 {
-	disable_irq_nosync(irq);
 	iio_trigger_poll(trig, iio_get_time_ns());
 	return IRQ_HANDLED;
 }
@@ -46,27 +45,23 @@ static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16240_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16240_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16240_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16240_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16240_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16240_state *st = indio_dev->dev_data;
+	char *name;
 
-	st->trig = iio_allocate_trigger();
-	if (st->trig == NULL) {
+	name = kasprintf(GFP_KERNEL, "adis16240-dev%d", indio_dev->id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+	st->trig = iio_allocate_trigger_named(name);
+	if (st->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name;
+	}
+
 	ret = request_irq(st->us->irq,
 			  adis16240_data_rdy_trig_poll,
 			  IRQF_TRIGGER_RISING,
@@ -75,34 +70,26 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev)
 	if (ret)
 		goto error_free_trig;
 
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16240-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16240_trig_try_reen;
 	st->trig->control_attrs = &adis16240_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 047/111] staging:iio:adc:ad7298 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (45 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 046/111] staging:iio:accel:adis16240 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 048/111] staging:iio:adc:ad7606 conversion to irq_chip based polling Jonathan Cameron
                   ` (64 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested. This one is of a different form, so worth a closer look than
the previous incredibly similar patches (which were based on the
adis16400 that I have tested).

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7298.h      |    2 -
 drivers/staging/iio/adc/ad7298_core.c |    2 -
 drivers/staging/iio/adc/ad7298_ring.c |   65 +++++++++++++--------------------
 3 files changed, 26 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h
index fe7ed77..8d149c8 100644
--- a/drivers/staging/iio/adc/ad7298.h
+++ b/drivers/staging/iio/adc/ad7298.h
@@ -40,8 +40,6 @@ struct ad7298_state {
 	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
 	unsigned			ext_ref;
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 8b3a490..40bbb42 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -6,7 +6,6 @@
  * Licensed under the GPL-2.
  */
 
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -170,7 +169,6 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, st);
 
-	atomic_set(&st->protect_ring, 0);
 	st->spi = spi;
 
 	st->indio_dev = iio_allocate_device(0);
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 9068d7f..1b9752c 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -7,7 +7,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -155,47 +154,24 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
 }
 
 /**
- * ad7298_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on spi comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7298_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7298_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-
-/**
- * ad7298_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad7298_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad7298_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7298_trigger_handler(int irq, void *p)
 {
-	struct ad7298_state *st = container_of(work_s, struct ad7298_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7298_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u16 buf[16];
 	int b_sent, i;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	b_sent = spi_sync(st->spi, &st->ring_msg);
 	if (b_sent)
-		goto done;
+		return b_sent;
 
 	if (ring->scan_timestamp) {
 		time_ns = iio_get_time_ns();
@@ -206,14 +182,13 @@ static void ad7298_poll_bh_to_ring(struct work_struct *work_s)
 	for (i = 0; i < ring->scan_count; i++)
 		buf[i] = be16_to_cpu(st->rx_buf[i]);
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, (u8 *)buf, time_ns);
-done:
-	atomic_dec(&st->protect_ring);
+	indio_dev->ring->access.store_to(ring, (u8 *)buf, time_ns);
+
+	return IRQ_HANDLED;
 }
 
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7298_state *st = indio_dev->dev_data;
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -223,10 +198,21 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7298_poll_func_th);
-	if (ret)
-		goto error_deallocate_sw_rb;
 
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
+		goto error_deallocate_sw_rb;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->thread = &ad7298_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "ad7298_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 	/* Ring buffer functions - here trigger setup related */
 
 	indio_dev->ring->preenable = &ad7298_ring_preenable;
@@ -235,11 +221,11 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->scan_el_attrs = &ad7298_scan_el_group;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad7298_poll_bh_to_ring);
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -253,6 +239,7 @@ void ad7298_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 048/111] staging:iio:adc:ad7606 conversion to irq_chip based polling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (46 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 047/111] staging:iio:adc:ad7298 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 049/111] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
                   ` (63 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

I'm far from sure what the best way to handle this particular
part is, so have (I think) done the absolute minimum to change
it to the new interface.

V2: Trivial constification of device name.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
---
 drivers/staging/iio/adc/ad7606.h      |    2 +-
 drivers/staging/iio/adc/ad7606_core.c |    1 +
 drivers/staging/iio/adc/ad7606_ring.c |   28 ++++++++++++++++++++++------
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 338bade..c900090 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -50,7 +50,7 @@ struct ad7606_platform_data {
  */
 
 struct ad7606_chip_info {
-	char				name[10];
+	const char			*name;
 	u8				bits;
 	char				sign;
 	u16				int_vref_mv;
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 7ef9a6f..27090b9 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -458,6 +458,7 @@ struct ad7606_state *ad7606_probe(struct device *dev, int irq,
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	st->indio_dev->name = st->chip_info->name;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index b32cb0d..43caced 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -157,16 +157,19 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 }
 
 /**
- * ad7606_poll_func_th() th of trigger launched polling to ring buffer
+ * ad7606_trigger_handler_th() th of trigger launched polling to ring buffer
  *
  **/
-static void ad7606_poll_func_th(struct iio_dev *indio_dev, s64 time)
+static irqreturn_t ad7606_trigger_handler_th(int irq, void *p)
 {
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
 	struct ad7606_state *st = indio_dev->dev_data;
 	gpio_set_value(st->pdata->gpio_convst, 1);
 
-	return;
+	return IRQ_HANDLED;
 }
+
 /**
  * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer
  * @work_s:	the work struct through which this was scheduled
@@ -245,10 +248,20 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7606_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
-
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &ad7606_trigger_handler_th;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "%s_consumer%d", indio_dev->name,
+			  indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 	/* Ring buffer functions - here trigger setup related */
 
 	indio_dev->ring->preenable = &ad7606_ring_preenable;
@@ -262,6 +275,8 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -275,6 +290,7 @@ void ad7606_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 049/111] staging:iio:adc:ad7887 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (47 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 048/111] staging:iio:adc:ad7606 conversion to irq_chip based polling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 050/111] staging:iio:adc:ad799x " Jonathan Cameron
                   ` (62 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7887.h      |    2 -
 drivers/staging/iio/adc/ad7887_core.c |    1 -
 drivers/staging/iio/adc/ad7887_ring.c |   62 ++++++++++++++------------------
 3 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index 439c802..ffff403 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -61,8 +61,6 @@ struct ad7887_state {
 	struct spi_device		*spi;
 	const struct ad7887_chip_info	*chip_info;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
 	bool				en_dual;
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 11c9fcf..42e9cd7 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -150,7 +150,6 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, st);
 
-	atomic_set(&st->protect_ring, 0);
 	st->spi = spi;
 
 	st->indio_dev = iio_allocate_device(0);
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index da77f26..df5a2ae 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -163,48 +163,27 @@ static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
 }
 
 /**
- * ad7887_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on spi comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7887_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-/**
- * ad7887_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad7887_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 {
-	struct ad7887_state *st = container_of(work_s, struct ad7887_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7887_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
+	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *buf;
 	int b_sent;
 
 	unsigned int bytes = ring->scan_count * st->chip_info->storagebits / 8;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	buf = kzalloc(st->d_size, GFP_KERNEL);
 	if (buf == NULL)
-		return;
+		return -ENOMEM;
 
 	b_sent = spi_sync(st->spi, st->ring_msg);
 	if (b_sent)
@@ -215,17 +194,17 @@ static void ad7887_poll_bh_to_ring(struct work_struct *work_s)
 	memcpy(buf, st->data, bytes);
 	if (ring->scan_timestamp)
 		memcpy(buf + st->d_size - sizeof(s64),
-			&time_ns, sizeof(time_ns));
+		       &time_ns, sizeof(time_ns));
 
 	indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns);
 done:
 	kfree(buf);
-	atomic_dec(&st->protect_ring);
+
+	return IRQ_HANDLED;
 }
 
 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7887_state *st = indio_dev->dev_data;
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -235,10 +214,22 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7887_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
 
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &ad7887_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "ad7887_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_pollfunc;
+	}
 	/* Ring buffer functions - here trigger setup related */
 
 	indio_dev->ring->preenable = &ad7887_ring_preenable;
@@ -248,11 +239,11 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->scan_el_attrs = &ad7887_scan_el_group;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad7887_poll_bh_to_ring);
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+error_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -267,6 +258,7 @@ void ad7887_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 050/111] staging:iio:adc:ad799x move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (48 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 049/111] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 051/111] staging:iio:gyro:adis16260 " Jonathan Cameron
                   ` (61 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested. Also cleared out last_timestamp as it isn't used anywhere.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad799x.h      |    3 --
 drivers/staging/iio/adc/ad799x_core.c |    3 +-
 drivers/staging/iio/adc/ad799x_ring.c |   61 ++++++++++++++------------------
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index 503fa61..331435a 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -113,12 +113,9 @@ struct ad799x_state {
 	struct iio_dev			*indio_dev;
 	struct i2c_client		*client;
 	const struct ad799x_chip_info	*chip_info;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	struct iio_trigger		*trig;
 	struct regulator		*reg;
-	s64				last_timestamp;
 	u16				int_vref_mv;
 	unsigned			id;
 	char				*name;
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 34fc85c..009efb8 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -767,7 +767,6 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 	/* this is only used for device removal purposes */
 	i2c_set_clientdata(client, st);
 
-	atomic_set(&st->protect_ring, 0);
 	st->id = id->driver_data;
 	st->chip_info = &ad799x_chip_info_tbl[st->id];
 	st->config = st->chip_info->default_config;
@@ -797,7 +796,7 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 	st->indio_dev->dev.parent = &client->dev;
 	st->indio_dev->attrs = st->chip_info->dev_attrs;
 	st->indio_dev->event_attrs = st->chip_info->event_attrs;
-
+	st->indio_dev->name = id->name;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 0875a7e..f0a0aae 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -99,34 +99,17 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
 }
 
 /**
- * ad799x_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad799x_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad799x_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-
-	return;
-}
-/**
- * ad799x_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad799x_poll_bh_to_ring(struct work_struct *work_s)
+
+static irqreturn_t ad799x_trigger_handler(int irq, void *p)
 {
-	struct ad799x_state *st = container_of(work_s, struct ad799x_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad799x_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	struct iio_sw_ring_buffer *ring_sw = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
@@ -134,13 +117,9 @@ static void ad799x_poll_bh_to_ring(struct work_struct *work_s)
 	int b_sent;
 	u8 cmd;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	rxbuf = kmalloc(st->d_size, GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		return -ENOMEM;
 
 	switch (st->id) {
 	case ad7991:
@@ -176,7 +155,9 @@ static void ad799x_poll_bh_to_ring(struct work_struct *work_s)
 	ring->access.store_to(&ring_sw->buf, rxbuf, time_ns);
 done:
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+	if (b_sent < 0)
+		return b_sent;
+	return IRQ_HANDLED;
 }
 
 
@@ -192,10 +173,21 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad799x_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
-
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->thread = &ad799x_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "%s_consumer%d", indio_dev->name,
+			  indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_poll_func;
+	}
 	/* Ring buffer functions - here trigger setup related */
 
 	indio_dev->ring->preenable = &ad799x_ring_preenable;
@@ -203,13 +195,13 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad799x_poll_bh_to_ring);
-
 	indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+error_free_poll_func:
+	kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -224,6 +216,7 @@ void ad799x_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 051/111] staging:iio:gyro:adis16260 move to irqchip based trigger handling.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (49 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 050/111] staging:iio:adc:ad799x " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 052/111] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
                   ` (60 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/gyro/adis16260.h         |    5 --
 drivers/staging/iio/gyro/adis16260_ring.c    |   64 ++++++++++++--------------
 drivers/staging/iio/gyro/adis16260_trigger.c |   51 ++++++--------------
 3 files changed, 46 insertions(+), 74 deletions(-)

diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
index 1369501..5325c68 100644
--- a/drivers/staging/iio/gyro/adis16260.h
+++ b/drivers/staging/iio/gyro/adis16260.h
@@ -85,9 +85,6 @@
 /**
  * struct adis16260_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -97,8 +94,6 @@
  **/
 struct adis16260_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 2342889..2806d83 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -59,17 +59,6 @@ static struct attribute_group adis16260_scan_el_group = {
 };
 
 /**
- * adis16260_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16260_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
  * adis16260_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
@@ -117,14 +106,12 @@ static int adis16260_read_ring_data(struct device *dev, u8 *rx)
 	return ret;
 }
 
-
-static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16260_trigger_handler(int irq, void *p)
 {
-	struct adis16260_state *st
-		= container_of(work_s, struct adis16260_state,
-				work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
 	size_t datasize = ring->access.get_bytes_per_datum(ring);
@@ -132,31 +119,29 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
+	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
@@ -164,9 +149,7 @@ void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16260_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16260_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -191,13 +174,26 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, iio_scan_el_temp.number);
 	iio_scan_mask_set(ring, iio_scan_el_angl.number);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
+	indio_dev->pollfunc->thread = &adis16260_trigger_handler;
+	indio_dev->pollfunc->type = IRQF_ONESHOT;
+	indio_dev->pollfunc->name =
+		kasprintf(GFP_KERNEL, "adis16260_consumer%d", indio_dev->id);
+	if (indio_dev->pollfunc->name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_pollfunc;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
+error_free_pollfunc:
+	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
index 5eb3038..6b73927 100644
--- a/drivers/staging/iio/gyro/adis16260_trigger.c
+++ b/drivers/staging/iio/gyro/adis16260_trigger.c
@@ -12,16 +12,6 @@
 #include "../trigger.h"
 #include "adis16260.h"
 
-/**
- * adis16260_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t adis16260_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private, iio_get_time_ns());
-	return IRQ_HANDLED;
-}
-
 static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *adis16260_trigger_attrs[] = {
@@ -46,63 +36,54 @@ static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return adis16260_set_irq(&st->indio_dev->dev, state);
 }
 
-/**
- * adis16260_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16260_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16260_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
-}
-
 int adis16260_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16260_state *st = indio_dev->dev_data;
+	char *name;
+	name = kasprintf(GFP_KERNEL,
+			 "%s-dev%d",
+			 spi_get_device_id(st->us)->name,
+			 indio_dev->id);
+	if (name == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
 
-	st->trig = iio_allocate_trigger();
+	st->trig = iio_allocate_trigger_named(name);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_ret;
+		goto error_free_name;
 	}
+
 	ret = request_irq(st->us->irq,
-			  adis16260_data_rdy_trig_poll,
+			  &iio_trigger_generic_data_rdy_poll,
 			  IRQF_TRIGGER_RISING,
 			  "adis16260",
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
 
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16260-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16260_trig_try_reen;
 	st->trig->control_attrs = &adis16260_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 052/111] staging:iio:trigger remove legacy pollfunc elements.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (50 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 051/111] staging:iio:gyro:adis16260 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 053/111] staging:iio: Add core attribute handling for name of device Jonathan Cameron
                   ` (59 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-trigger.c |  124 +++++-----------------------
 drivers/staging/iio/trigger.h              |   19 ----
 2 files changed, 20 insertions(+), 123 deletions(-)

diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index d045b6c..dd762f0 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -164,21 +164,6 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
 void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 {
 	int i;
-	struct iio_poll_func *pf_cursor;
-
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
-		if (pf_cursor->poll_func_immediate) {
-			pf_cursor->poll_func_immediate(pf_cursor->private_data);
-			trig->use_count++;
-		}
-	}
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
-		if (pf_cursor->poll_func_main) {
-			pf_cursor->poll_func_main(pf_cursor->private_data,
-						  time);
-			trig->use_count++;
-		}
-	}
 	if (!trig->use_count) {
 		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
 			if (trig->subirqs[i].enabled) {
@@ -232,32 +217,15 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
 				 struct iio_poll_func *pf)
 {
 	int ret = 0;
-	unsigned long flags;
-
-	if (pf->thread) {
-		bool notinuse
-			= bitmap_empty(trig->pool,
-				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
-
-		pf->irq = iio_trigger_get_irq(trig);
-		ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
-					   pf->type, pf->name,
-					   pf);
-		if (trig->set_trigger_state && notinuse) {
-			ret = trig->set_trigger_state(trig, true);
-	} else {
-		spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-		list_add_tail(&pf->list, &trig->pollfunc_list);
-		spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
-
-		if (trig->set_trigger_state)
-			ret = trig->set_trigger_state(trig, true);
-		}
-		if (ret) {
-			printk(KERN_ERR "set trigger state failed\n");
-			list_del(&pf->list);
-		}
-	}
+	bool notinuse
+		= bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+
+	pf->irq = iio_trigger_get_irq(trig);
+	ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
+				   pf->type, pf->name,
+				   pf);
+	if (trig->set_trigger_state && notinuse)
+		ret = trig->set_trigger_state(trig, true);
 
 	return ret;
 }
@@ -266,53 +234,18 @@ EXPORT_SYMBOL(iio_trigger_attach_poll_func);
 int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 				  struct iio_poll_func *pf)
 {
-	struct iio_poll_func *pf_cursor;
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (pf->thread) {
-		bool no_other_users
-			= (bitmap_weight(trig->pool,
-					 CONFIG_IIO_CONSUMERS_PER_TRIGGER)
-			   == 1);
-		if (trig->set_trigger_state && no_other_users) {
-			ret = trig->set_trigger_state(trig, false);
-			if (ret)
-				goto error_ret;
-		} else
-			ret = 0;
-		iio_trigger_put_irq(trig, pf->irq);
-		free_irq(pf->irq, pf);
-	} else {
-		spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-		list_for_each_entry(pf_cursor, &trig->pollfunc_list, list)
-			if (pf_cursor == pf) {
-				ret = 0;
-				break;
-			}
-		if (!ret) {
-			if (list_is_singular(&trig->pollfunc_list)
-			    && trig->set_trigger_state) {
-				spin_unlock_irqrestore(&trig
-						       ->pollfunc_list_lock,
-						       flags);
-				/* May sleep hence cannot hold the spin lock */
-				ret = trig->set_trigger_state(trig, false);
-				if (ret)
-					goto error_ret;
-				spin_lock_irqsave(&trig->pollfunc_list_lock,
-						  flags);
-			}
-			/*
-			 * Now we can delete safe in the knowledge that, if
-			 * this is the last pollfunc then we have disabled
-			 * the trigger anyway and so nothing should be able
-			 * to call the pollfunc.
-			 */
-			list_del(&pf_cursor->list);
-		}
-		spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+	int ret = 0;
+	bool no_other_users
+		= (bitmap_weight(trig->pool,
+				 CONFIG_IIO_CONSUMERS_PER_TRIGGER)
+		   == 1);
+	if (trig->set_trigger_state && no_other_users) {
+		ret = trig->set_trigger_state(trig, false);
+		if (ret)
+			goto error_ret;
 	}
+	iio_trigger_put_irq(trig, pf->irq);
+	free_irq(pf->irq, pf);
 
 error_ret:
 	return ret;
@@ -445,9 +378,6 @@ struct iio_trigger *iio_allocate_trigger_named(const char *name)
 		trig->dev.bus = &iio_bus_type;
 		device_initialize(&trig->dev);
 		dev_set_drvdata(&trig->dev, (void *)trig);
-		spin_lock_init(&trig->pollfunc_list_lock);
-		INIT_LIST_HEAD(&trig->list);
-		INIT_LIST_HEAD(&trig->pollfunc_list);
 
 		if (name) {
 			mutex_init(&trig->pool_lock);
@@ -509,20 +439,6 @@ int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
 }
 EXPORT_SYMBOL(iio_device_unregister_trigger_consumer);
 
-int iio_alloc_pollfunc(struct iio_dev *indio_dev,
-		       void (*immediate)(struct iio_dev *indio_dev),
-		       void (*main)(struct iio_dev *private_data, s64 time))
-{
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-	if (indio_dev->pollfunc == NULL)
-		return -ENOMEM;
-	indio_dev->pollfunc->poll_func_immediate = immediate;
-	indio_dev->pollfunc->poll_func_main = main;
-	indio_dev->pollfunc->private_data = indio_dev;
-	return 0;
-}
-EXPORT_SYMBOL(iio_alloc_pollfunc);
-
 int iio_triggered_ring_postenable(struct iio_dev *indio_dev)
 {
 	return indio_dev->trig
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 8e25c00..e831a89 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -24,8 +24,6 @@ struct iio_subirq {
  * @private_data:	[DRIVER] device specific data
  * @list:		[INTERN] used in maintenance of global trigger list
  * @alloc_list:		[DRIVER] used for driver specific trigger list
- * @pollfunc_list_lock:	[INTERN] protection of the polling function list
- * @pollfunc_list:	[INTERN] list of functions to run on trigger.
  * @control_attrs:	[DRIVER] sysfs attributes relevant to trigger type
  * @owner:		[DRIVER] used to monitor usage count of the trigger.
  * @use_count:		use count for the trigger
@@ -41,8 +39,6 @@ struct iio_trigger {
 	void				*private_data;
 	struct list_head		list;
 	struct list_head		alloc_list;
-	spinlock_t			pollfunc_list_lock;
-	struct list_head		pollfunc_list;
 	const struct attribute_group	*control_attrs;
 	struct module			*owner;
 	int use_count;
@@ -153,14 +149,7 @@ static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
 /**
  * struct iio_poll_func - poll function pair
  *
- * @list:			associate this with a triggers pollfunc_list
  * @private_data:		data specific to device (passed into poll func)
- * @poll_func_immediate:	function in here is run first. They should be
- *				extremely lightweight.  Typically used for latch
- *				control on sensor supporting it.
- * @poll_func_main:		function in here is run after all immediates.
- *				Reading from sensor etc typically involves
- *				scheduling from here.
  * @h:				the function that is actually run on trigger
  * @thread:			threaded interrupt part
  * @type:			the type of interrupt (basically if oneshot)
@@ -171,11 +160,7 @@ static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
  *				passes it via here.
  **/
 struct iio_poll_func {
-	struct				list_head list;
 	void				*private_data;
-	void (*poll_func_immediate)(struct iio_dev *indio_dev);
-	void (*poll_func_main)(struct iio_dev *private_data, s64 time);
-
 	irqreturn_t (*h)(int irq, void *p);
 	irqreturn_t (*thread)(int irq, void *p);
 	int type;
@@ -184,10 +169,6 @@ struct iio_poll_func {
 	s64 timestamp;
 };
 
-int iio_alloc_pollfunc(struct iio_dev *indio_dev,
-		       void (*immediate)(struct iio_dev *indio_dev),
-		       void (*main)(struct iio_dev *private_data, s64 time));
-
 irqreturn_t iio_pollfunc_store_time(int irq, void *p);
 
 /*
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 053/111] staging:iio: Add core attribute handling for name of device.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (51 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 052/111] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 054/111] staging:iio: use the new central name attribute creation code Jonathan Cameron
                   ` (58 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Saves on a fair bit of code replication.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    2 +-
 drivers/staging/iio/industrialio-core.c |   23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 1c5e975..c6b471c 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -268,7 +268,7 @@ struct iio_dev {
 	int num_channels;
 	struct list_head channel_attr_list;
 
-	char *name; /*device name - IMPLEMENT */
+	const char *name;
 	int (*read_raw)(struct iio_dev *indio_dev,
 			struct iio_chan_spec const *chan,
 			int *val,
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 52188f9..e943dac 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -688,6 +688,16 @@ static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
 	kfree(p);
 }
 
+static ssize_t iio_show_dev_name(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", indio_dev->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
+
 static int iio_device_register_sysfs(struct iio_dev *dev_info)
 {
 	int i, ret = 0;
@@ -715,8 +725,15 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
 			if (ret < 0)
 				goto error_clear_attrs;
 		}
-
+	if (dev_info->name) {
+		ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
+					      &dev_attr_name.attr,
+					      NULL);
+		if (ret)
+			goto error_clear_attrs;
+	}
 	return 0;
+
 error_clear_attrs:
 	list_for_each_entry_safe(p, n,
 				 &dev_info->channel_attr_list, l) {
@@ -734,6 +751,10 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
 
 	struct iio_dev_attr *p, *n;
+	if (dev_info->name)
+		sysfs_remove_file_from_group(&dev_info->dev.kobj,
+					     &dev_attr_name.attr,
+					     NULL);
 	list_for_each_entry_safe(p, n, &dev_info->channel_attr_list, l) {
 		list_del(&p->l);
 		iio_device_remove_and_free_read_attr(dev_info, p);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 054/111] staging:iio: use the new central name attribute creation code
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (52 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 053/111] staging:iio: Add core attribute handling for name of device Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 055/111] staging:iio:light:tsl2563: chan_spec based channel setup Jonathan Cameron
                   ` (57 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201_core.c |    4 +--
 drivers/staging/iio/accel/adis16203_core.c |    5 +---
 drivers/staging/iio/accel/adis16204_core.c |    4 +--
 drivers/staging/iio/accel/adis16209_core.c |    4 +--
 drivers/staging/iio/accel/adis16220_core.c |    4 +--
 drivers/staging/iio/accel/adis16240_core.c |    4 +--
 drivers/staging/iio/accel/lis3l02dq_core.c |    4 +--
 drivers/staging/iio/accel/sca3000.h        |    2 -
 drivers/staging/iio/accel/sca3000_core.c   |   28 +++++++----------------
 drivers/staging/iio/adc/ad7150.c           |   15 +------------
 drivers/staging/iio/adc/ad7152.c           |   15 +------------
 drivers/staging/iio/adc/ad7291.c           |   17 +-------------
 drivers/staging/iio/adc/ad7298_core.c      |   13 +----------
 drivers/staging/iio/adc/ad7314.c           |   19 ++--------------
 drivers/staging/iio/adc/ad7476_core.c      |   22 +------------------
 drivers/staging/iio/adc/ad7745.c           |   15 +------------
 drivers/staging/iio/adc/ad7780.c           |   13 +----------
 drivers/staging/iio/adc/ad7816.c           |   32 +++++++--------------------
 drivers/staging/iio/adc/ad7887_core.c      |   13 +----------
 drivers/staging/iio/adc/ad799x_core.c      |   14 ------------
 drivers/staging/iio/adc/adt7310.c          |   21 +++--------------
 drivers/staging/iio/adc/adt7410.c          |   20 ++--------------
 drivers/staging/iio/adc/adt75.c            |   19 ++--------------
 drivers/staging/iio/adc/max1363_core.c     |   21 +-----------------
 drivers/staging/iio/addac/adt7316.c        |   21 ++---------------
 drivers/staging/iio/dac/ad5446.c           |   13 +----------
 drivers/staging/iio/dac/ad5504.c           |   15 +------------
 drivers/staging/iio/dac/ad5624r_spi.c      |   13 +----------
 drivers/staging/iio/dds/ad9832.c           |   13 +----------
 drivers/staging/iio/dds/ad9834.c           |   13 +----------
 drivers/staging/iio/gyro/adis16080_core.c  |    3 +-
 drivers/staging/iio/gyro/adis16130_core.c  |    4 +--
 drivers/staging/iio/gyro/adis16260_core.c  |    4 +--
 drivers/staging/iio/imu/adis16400_core.c   |   12 +---------
 drivers/staging/iio/light/isl29018.c       |   13 +----------
 drivers/staging/iio/meter/ade7753.c        |    4 +--
 drivers/staging/iio/meter/ade7754.c        |    4 +--
 drivers/staging/iio/meter/ade7758_core.c   |    4 +--
 drivers/staging/iio/meter/ade7759.c        |    4 +--
 drivers/staging/iio/sysfs.h                |    7 ------
 40 files changed, 65 insertions(+), 410 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 08e42f4..f45eb8f 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -477,8 +477,6 @@ static IIO_CONST_ATTR(temp_scale, "-0.47");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0);
 
-static IIO_CONST_ATTR(name, "adis16201");
-
 static struct attribute *adis16201_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -486,7 +484,6 @@ static struct attribute *adis16201_attributes[] = {
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_accel_x_raw.dev_attr.attr,
@@ -537,6 +534,7 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16201_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 4043a97..6162311 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -392,8 +392,6 @@ static IIO_CONST_ATTR(temp_scale, "-0.47");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0);
 
-static IIO_CONST_ATTR(name, "adis16203");
-
 static struct attribute *adis16203_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -401,7 +399,6 @@ static struct attribute *adis16203_attributes[] = {
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_incli_x_raw.dev_attr.attr,
@@ -445,7 +442,7 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
-
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16203_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index fe44b25..a9c890d 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -430,8 +430,6 @@ static IIO_CONST_ATTR(temp_scale, "-0.47");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
 
-static IIO_CONST_ATTR(name, "adis16204");
-
 static struct attribute *adis16204_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -439,7 +437,6 @@ static struct attribute *adis16204_attributes[] = {
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_accel_x_raw.dev_attr.attr,
@@ -491,6 +488,7 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16204_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 54b5bae..fa0a3ad 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -427,8 +427,6 @@ static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
 
-static IIO_CONST_ATTR_NAME("adis16209");
-
 static struct attribute *adis16209_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -436,7 +434,6 @@ static struct attribute *adis16209_attributes[] = {
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_accel_x_raw.dev_attr.attr,
@@ -486,6 +483,7 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16209_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 0689e41..7af48b8 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -521,8 +521,6 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO,
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200");
 
-static IIO_CONST_ATTR_NAME("adis16220");
-
 static struct attribute *adis16220_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -539,7 +537,6 @@ static struct attribute *adis16220_attributes[] = {
 	&iio_dev_attr_reset.dev_attr.attr,
 	&iio_dev_attr_capture.dev_attr.attr,
 	&iio_dev_attr_capture_count.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -578,6 +575,7 @@ static int __devinit adis16220_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16220_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 89ab810..6350c7c 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -422,8 +422,6 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
 
-static IIO_CONST_ATTR_NAME("adis16240");
-
 static struct attribute *adis16240_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -444,7 +442,6 @@ static struct attribute *adis16240_attributes[] = {
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -483,6 +480,7 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16240_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index b1fb049..a6b4631 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -644,12 +644,9 @@ error_ret:
 	return ret;
 }
 
-static IIO_CONST_ATTR_NAME("lis3l02dq");
-
 static struct attribute *lis3l02dq_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -689,6 +686,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->help.indio_dev->name = spi->dev.driver->name;
 	st->help.indio_dev->dev.parent = &spi->dev;
 	st->help.indio_dev->num_interrupt_lines = 1;
 	st->help.indio_dev->channels = lis3l02dq_channels;
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index f77eb74..cf0751d 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -186,7 +186,6 @@ struct sca3000_state {
 
 /**
  * struct sca3000_chip_info - model dependent parameters
- * @name:			model identification
  * @scale:			scale * 10^-6
  * @temp_output:		some devices have temperature sensors.
  * @measurement_mode_freq:	normal mode sampling frequency
@@ -199,7 +198,6 @@ struct sca3000_state {
  * sca3000 variant.
  **/
 struct sca3000_chip_info {
-	const char		*name;
 	unsigned int		scale;
 	bool			temp_output;
 	int			measurement_mode_freq;
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index d11fc94..5de07fd 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -40,8 +40,7 @@ enum sca3000_variant {
  * do not actually appear to be available.
  */
 static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
-	{
-		.name = "sca3000-d01",
+	[d01] = {
 		.scale = 7357,
 		.temp_output = true,
 		.measurement_mode_freq = 250,
@@ -49,16 +48,16 @@ static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
 		.option_mode_1_freq = 250,
 		.mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
 		.mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
-	}, {
-		.name = "sca3000-e02",
+	},
+	[e02] = {
 		.scale = 9810,
 		.measurement_mode_freq = 125,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 63,
 		.mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
 		.mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
-	}, {
-		.name = "sca3000-e04",
+	},
+	[e04] = {
 		.scale = 19620,
 		.measurement_mode_freq = 100,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
@@ -67,8 +66,8 @@ static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
 		.option_mode_2_freq = 400,
 		.mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
 		.mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
-	}, {
-		.name = "sca3000-e05",
+	},
+	[e05] = {
 		.scale = 61313,
 		.measurement_mode_freq = 200,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
@@ -260,14 +259,7 @@ error_ret:
 }
 #endif /* SCA3000_DEBUG */
 
-static ssize_t sca3000_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct sca3000_state *st = dev_info->dev_data;
-	return sprintf(buf, "%s\n", st->info->name);
-}
+
 /**
  * sca3000_show_reg() - sysfs interface to read the chip revision number
  **/
@@ -430,7 +422,6 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
 
 /* More standard attributes */
 
-static IIO_DEV_ATTR_NAME(sca3000_show_name);
 static IIO_DEV_ATTR_REV(sca3000_show_rev);
 
 #define SCA3000_INFO_MASK			\
@@ -765,7 +756,6 @@ static int sca3000_write_thresh(struct iio_dev *indio_dev,
 }
 
 static struct attribute *sca3000_attributes[] = {
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
@@ -775,7 +765,6 @@ static struct attribute *sca3000_attributes[] = {
 };
 
 static struct attribute *sca3000_attributes_with_temp[] = {
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
@@ -1134,6 +1123,7 @@ static int __devinit sca3000_probe(struct spi_device *spi)
 		goto error_clear_st;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->num_interrupt_lines = 1;
 	st->indio_dev->event_attrs = &sca3000_event_attribute_group;
 	if (st->info->temp_output)
diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 6a9f326..cbd1f96 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -58,7 +58,6 @@
  */
 
 struct ad7150_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	bool inter;
@@ -584,17 +583,6 @@ static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
 		ad7150_show_ch2_setup,
 		ad7150_store_ch2_setup);
 
-static ssize_t ad7150_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7150_show_name, NULL, 0);
-
 static ssize_t ad7150_show_powerdown_timer(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -643,7 +631,6 @@ static struct attribute *ad7150_attributes[] = {
 	&iio_dev_attr_powerdown_timer.dev_attr.attr,
 	&iio_dev_attr_ch1_value.dev_attr.attr,
 	&iio_dev_attr_ch2_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -724,7 +711,6 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -733,6 +719,7 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 	}
 
 	/* Echipabilish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &ad7150_attribute_group;
 	chip->indio_dev->event_attrs = &ad7150_event_attribute_group;
diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 25715f0..e53e3e9 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -50,7 +50,6 @@
  */
 
 struct ad7152_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u16 ch1_offset;     /* Channel 1 offset calibration coefficient */
@@ -479,17 +478,6 @@ static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
 		ad7152_show_filter_rate_setup,
 		ad7152_store_filter_rate_setup);
 
-static ssize_t ad7152_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7152_show_name, NULL, 0);
-
 static struct attribute *ad7152_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
@@ -502,7 +490,6 @@ static struct attribute *ad7152_attributes[] = {
 	&iio_dev_attr_ch1_setup.dev_attr.attr,
 	&iio_dev_attr_ch2_setup.dev_attr.attr,
 	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -528,7 +515,6 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -537,6 +523,7 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	}
 
 	/* Echipabilish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &ad7152_attribute_group;
 	chip->indio_dev->dev_data = (void *)(chip);
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 23ad18e..527311c 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -60,7 +60,6 @@
  */
 
 struct ad7291_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u16 command;
@@ -434,17 +433,6 @@ static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
 		ad7291_store_channel_mask,
 		0);
 
-static ssize_t ad7291_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7291_show_name, NULL, 0);
-
 static struct attribute *ad7291_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
@@ -455,7 +443,6 @@ static struct attribute *ad7291_attributes[] = {
 	&iio_dev_attr_t_average.dev_attr.attr,
 	&iio_dev_attr_voltage.dev_attr.attr,
 	&iio_dev_attr_channel_mask.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -784,7 +771,6 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 	chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK;
 
 	chip->indio_dev = iio_allocate_device(0);
@@ -793,6 +779,7 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &ad7291_attribute_group;
 	chip->indio_dev->event_attrs = &ad7291_event_attribute_group;
@@ -810,7 +797,7 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 					   NULL,
 					   &ad7291_event_handler,
 					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-					   chip->name,
+					   id->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 40bbb42..d43f63d 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -118,17 +118,6 @@ static ssize_t ad7298_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7298_show_scale, NULL, 0);
 
-static ssize_t ad7298_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0);
-
 static struct attribute *ad7298_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
@@ -140,7 +129,6 @@ static struct attribute *ad7298_attributes[] = {
 	&iio_dev_attr_in7_raw.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
 	&iio_dev_attr_temp0_input.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -177,6 +165,7 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 		goto error_disable_reg;
 	}
 
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &ad7298_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
index bc34e29..a1f1b43 100644
--- a/drivers/staging/iio/adc/ad7314.c
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -42,7 +42,6 @@
  */
 
 struct ad7314_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
 	s64 last_timestamp;
@@ -155,7 +154,7 @@ static ssize_t ad7314_show_temperature(struct device *dev,
 	if (chip->mode)
 		ad7314_spi_write(chip, chip->mode);
 
-	if (strcmp(chip->name, "ad7314")) {
+	if (strcmp(dev_info->name, "ad7314")) {
 		data = (data & AD7314_TEMP_MASK) >>
 			AD7314_TEMP_OFFSET;
 		if (data & AD7314_TEMP_SIGN) {
@@ -181,22 +180,10 @@ static ssize_t ad7314_show_temperature(struct device *dev,
 
 static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0);
 
-static ssize_t ad7314_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7314_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0);
-
 static struct attribute *ad7314_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_temperature.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -222,7 +209,6 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -230,6 +216,7 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
 	chip->indio_dev->attrs = &ad7314_attribute_group;
 	chip->indio_dev->dev_data = (void *)chip;
@@ -240,7 +227,7 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
 		goto error_free_dev;
 
 	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
-			 chip->name);
+			 chip->indio_dev->name);
 
 	return 0;
 error_free_dev:
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index 9729a1c..5b41e01 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -66,26 +66,6 @@ static int ad7476_read_raw(struct iio_dev *dev_info,
 	return -EINVAL;
 }
 
-static ssize_t ad7476_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7476_show_name, NULL, 0);
-
-static struct attribute *ad7476_attributes[] = {
-	&iio_dev_attr_name.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7476_attribute_group = {
-	.attrs = ad7476_attributes,
-};
-
 static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
 	[ID_AD7466] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -183,7 +163,7 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 
 	/* Establish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad7476_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
index cb1fc61..afa2648 100644
--- a/drivers/staging/iio/adc/ad7745.c
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -53,7 +53,6 @@
  */
 
 struct ad774x_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	bool inter;
@@ -499,17 +498,6 @@ static IIO_DEV_ATTR_CAP_GAIN(S_IRUGO | S_IWUSR,
 		ad774x_show_cap_gain,
 		ad774x_store_cap_gain);
 
-static ssize_t ad774x_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad774x_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad774x_show_name, NULL, 0);
-
 static struct attribute *ad774x_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
@@ -523,7 +511,6 @@ static struct attribute *ad774x_attributes[] = {
 	&iio_dev_attr_cap0_raw.dev_attr.attr,
 	&iio_dev_attr_capdac0_raw.dev_attr.attr,
 	&iio_dev_attr_capdac1_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -596,7 +583,6 @@ static int __devinit ad774x_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -605,6 +591,7 @@ static int __devinit ad774x_probe(struct i2c_client *client,
 	}
 
 	/* Establish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &ad774x_attribute_group;
 	chip->indio_dev->event_attrs = &ad774x_event_attribute_group;
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index ab23c5c..f828e83 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -132,21 +132,9 @@ static ssize_t ad7780_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7780_show_scale, NULL, 0);
 
-static ssize_t ad7780_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7780_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7780_show_name, NULL, 0);
-
 static struct attribute *ad7780_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -229,6 +217,7 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 
 	/* Establish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad7780_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index a062ec3..bee4209 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -42,7 +42,6 @@
  */
 
 struct ad7816_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
 	u16 rdwr_pin;
@@ -181,13 +180,13 @@ static ssize_t ad7816_store_channel(struct device *dev,
 
 	if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
 		dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
-			data, chip->name);
+			data, dev_info->name);
 		return -EINVAL;
-	} else if (strcmp(chip->name, "ad7818") == 0 && data > 1) {
+	} else if (strcmp(dev_info->name, "ad7818") == 0 && data > 1) {
 		dev_err(&chip->spi_dev->dev,
 			"Invalid channel id %lu for ad7818.\n", data);
 		return -EINVAL;
-	} else if (strcmp(chip->name, "ad7816") == 0 && data > 0) {
+	} else if (strcmp(dev_info->name, "ad7816") == 0 && data > 0) {
 		dev_err(&chip->spi_dev->dev,
 			"Invalid channel id %lu for ad7816.\n", data);
 		return -EINVAL;
@@ -232,23 +231,11 @@ static ssize_t ad7816_show_value(struct device *dev,
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
 
-static ssize_t ad7816_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7816_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7816_show_name, NULL, 0);
-
 static struct attribute *ad7816_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_channel.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -366,28 +353,27 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev)
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 	for (i = 0; i <= AD7816_CS_MAX; i++)
 		chip->oti_data[i] = 203;
 	chip->rdwr_pin = pins[0];
 	chip->convert_pin = pins[1];
 	chip->busy_pin = pins[2];
 
-	ret = gpio_request(chip->rdwr_pin, chip->name);
+	ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
 			chip->rdwr_pin);
 		goto error_free_chip;
 	}
 	gpio_direction_input(chip->rdwr_pin);
-	ret = gpio_request(chip->convert_pin, chip->name);
+	ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
 			chip->convert_pin);
 		goto error_free_gpio_rdwr;
 	}
 	gpio_direction_input(chip->convert_pin);
-	ret = gpio_request(chip->busy_pin, chip->name);
+	ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
 			chip->busy_pin);
@@ -400,7 +386,7 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev)
 		ret = -ENOMEM;
 		goto error_free_gpio;
 	}
-
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
 	chip->indio_dev->attrs = &ad7816_attribute_group;
 	chip->indio_dev->event_attrs = &ad7816_event_attribute_group;
@@ -419,14 +405,14 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev)
 					   NULL,
 					   &ad7816_event_handler,
 					   IRQF_TRIGGER_LOW,
-					   chip->name,
+					   chip->indio_dev->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 	}
 
 	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
-			 chip->name);
+			 chip->indio_dev->name);
 
 	return 0;
 
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 42e9cd7..27adff4 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -72,22 +72,10 @@ static ssize_t ad7887_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0);
 
-static ssize_t ad7887_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7887_show_name, NULL, 0);
-
 static struct attribute *ad7887_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -160,6 +148,7 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 
 	/* Estabilish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad7887_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 009efb8..3383a35 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -426,23 +426,11 @@ static ssize_t ad799x_show_scale(struct device *dev,
 
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, 0);
 
-static ssize_t ad799x_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	return sprintf(buf, "%s\n", st->client->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad799x_show_name, NULL, 0);
-
 static struct attribute *ad7991_5_9_3_4_device_attrs[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_dev_attr_in2_raw.dev_attr.attr,
 	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
 	NULL
 };
@@ -475,7 +463,6 @@ static struct attribute_group ad7991_5_9_3_4_scan_el_group = {
 static struct attribute *ad7992_device_attrs[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
 	NULL
 };
@@ -510,7 +497,6 @@ static struct attribute *ad7997_8_device_attrs[] = {
 	&iio_dev_attr_in5_raw.dev_attr.attr,
 	&iio_dev_attr_in6_raw.dev_attr.attr,
 	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_in_scale.dev_attr.attr,
 	NULL
 };
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index 9b2a8ec..2ade485 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -79,7 +79,6 @@
  */
 
 struct adt7310_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
 	u8  config;
@@ -375,24 +374,12 @@ static ssize_t adt7310_show_value(struct device *dev,
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
 
-static ssize_t adt7310_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7310_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7310_show_name, NULL, 0);
-
 static struct attribute *adt7310_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_resolution.dev_attr.attr,
 	&iio_dev_attr_id.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -781,7 +768,6 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -790,6 +776,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 	}
 
 	chip->indio_dev->dev.parent = &spi_dev->dev;
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->attrs = &adt7310_attribute_group;
 	chip->indio_dev->event_attrs = adt7310_event_attribute_group;
 	chip->indio_dev->dev_data = (void *)chip;
@@ -811,7 +798,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 					   NULL,
 					   &adt7310_event_handler,
 					   irq_flags,
-					   chip->name,
+					   chip->indio_dev->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
@@ -823,7 +810,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 					   NULL,
 					   &adt7310_event_handler,
 					   adt7310_platform_data[1],
-					   chip->name,
+					   chip->indio_dev->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
@@ -852,7 +839,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 	}
 
 	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
-			chip->name);
+			chip->indio_dev->name);
 
 	return 0;
 
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index dc59130..c102b42 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -74,7 +74,6 @@
  */
 
 struct adt7410_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u8  config;
@@ -343,24 +342,12 @@ static ssize_t adt7410_show_value(struct device *dev,
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
 
-static ssize_t adt7410_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7410_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7410_show_name, NULL, 0);
-
 static struct attribute *adt7410_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_resolution.dev_attr.attr,
 	&iio_dev_attr_id.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -748,14 +735,13 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
-
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &adt7410_attribute_group;
 	chip->indio_dev->event_attrs = adt7410_event_attribute_group;
@@ -774,7 +760,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 					   NULL,
 					   &adt7410_event_handler,
 					   IRQF_TRIGGER_LOW,
-					   chip->name,
+					   id->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
@@ -786,7 +772,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 					   NULL,
 					   &adt7410_event_handler,
 					   adt7410_platform_data[1],
-					   chip->name,
+					   id->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index 0d1cc75..4b1c0fa 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -50,7 +50,6 @@
  */
 
 struct adt75_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u8  config;
@@ -243,23 +242,11 @@ static ssize_t adt75_show_value(struct device *dev,
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0);
 
-static ssize_t adt75_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt75_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt75_show_name, NULL, 0);
-
 static struct attribute *adt75_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_oneshot.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -563,7 +550,6 @@ static int __devinit adt75_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
 	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
@@ -571,6 +557,7 @@ static int __devinit adt75_probe(struct i2c_client *client,
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->attrs = &adt75_attribute_group;
 	chip->indio_dev->event_attrs = &adt75_event_attribute_group;
@@ -588,7 +575,7 @@ static int __devinit adt75_probe(struct i2c_client *client,
 					   NULL,
 					   &adt75_event_handler,
 					   IRQF_TRIGGER_LOW,
-					   chip->name,
+					   chip->indio_dev->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
@@ -610,7 +597,7 @@ static int __devinit adt75_probe(struct i2c_client *client,
 	}
 
 	dev_info(&client->dev, "%s temperature sensor registered.\n",
-			 id->name);
+			 chip->indio_dev->name);
 
 	return 0;
 error_unreg_irq:
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 935914e..20c6aae 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -244,16 +244,6 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
 	return 0;
 }
 
-static ssize_t max1363_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct max1363_state *st = iio_priv(dev_get_drvdata(dev));
-	return sprintf(buf, "%s\n", st->client->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0);
-
 /* Applies to max1363 */
 static const enum max1363_modes max1363_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -333,15 +323,6 @@ static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8);
 static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10);
 static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12);
 
-static struct attribute *max1363_device_attrs[] = {
-	&iio_dev_attr_name.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group max1363_dev_attr_group = {
-	.attrs = max1363_device_attrs,
-};
-
 /* Appies to max1236, max1237 */
 static const enum max1363_modes max1236_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -1187,7 +1168,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 			.modemask;
 	/* Estabilish that the iio_dev is a child of the i2c device */
 	indio_dev->dev.parent = &client->dev;
-	indio_dev->attrs = &max1363_dev_attr_group;
+	indio_dev->name = id->name;
 	indio_dev->read_event_value = &max1363_read_thresh;
 	indio_dev->write_event_value = &max1363_write_thresh;
 	indio_dev->read_event_config = &max1363_read_event_config;
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 7174e7b..24dd2d2 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -174,7 +174,6 @@
  */
 
 struct adt7316_chip_info {
-	const char		*name;
 	struct iio_dev		*indio_dev;
 	struct adt7316_bus	bus;
 	u16			ldac_pin;
@@ -1672,18 +1671,6 @@ static ssize_t adt7316_show_bus_type(struct device *dev,
 
 static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
 
-static ssize_t adt7316_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7316_chip_info *chip = dev_info->dev_data;
-
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7316_show_name, NULL, 0);
-
 static struct attribute *adt7316_attributes[] = {
 	&iio_dev_attr_all_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
@@ -1720,7 +1707,6 @@ static struct attribute *adt7316_attributes[] = {
 	&iio_dev_attr_manufactorer_id.dev_attr.attr,
 	&iio_dev_attr_device_rev.dev_attr.attr,
 	&iio_dev_attr_bus_type.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -1769,7 +1755,6 @@ static struct attribute *adt7516_attributes[] = {
 	&iio_dev_attr_manufactorer_id.dev_attr.attr,
 	&iio_dev_attr_device_rev.dev_attr.attr,
 	&iio_dev_attr_bus_type.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -2118,7 +2103,6 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 	dev_set_drvdata(dev, chip);
 
 	chip->bus = *bus;
-	chip->name = name;
 
 	if (name[4] == '3')
 		chip->id = ID_ADT7316 + (name[6] - '6');
@@ -2151,6 +2135,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 		chip->indio_dev->attrs = &adt7316_attribute_group;
 		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
 	}
+	chip->indio_dev->name = name;
 	chip->indio_dev->dev_data = (void *)chip;
 	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->num_interrupt_lines = 1;
@@ -2168,7 +2153,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 					   NULL,
 					   &adt7316_event_handler,
 					   chip->bus.irq_flags | IRQF_ONESHOT,
-					   chip->name,
+					   chip->indio_dev->name,
 					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
@@ -2190,7 +2175,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 	}
 
 	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
-			chip->name);
+			chip->indio_dev->name);
 
 	return 0;
 
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
index fd4fa54..22646a6 100644
--- a/drivers/staging/iio/dac/ad5446.c
+++ b/drivers/staging/iio/dac/ad5446.c
@@ -106,17 +106,6 @@ static ssize_t ad5446_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0);
 
-static ssize_t ad5446_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad5446_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5446_show_name, NULL, 0);
-
 static ssize_t ad5446_write_powerdown_mode(struct device *dev,
 				       struct device_attribute *attr,
 				       const char *buf, size_t len)
@@ -204,7 +193,6 @@ static struct attribute *ad5446_attributes[] = {
 	&iio_dev_attr_out0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -381,6 +369,7 @@ static int __devinit ad5446_probe(struct spi_device *spi)
 
 	/* Estabilish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad5446_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
index 5534c41..351a9d3 100644
--- a/drivers/staging/iio/dac/ad5504.c
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -170,17 +170,6 @@ static ssize_t ad5504_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5504_show_scale, NULL, 0);
 
-static ssize_t ad5504_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5504_show_name, NULL, 0);
-
 #define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)		\
 	IIO_DEVICE_ATTR(out##_num##_raw,				\
 			S_IRUGO | S_IWUSR, _show, _store, _addr)
@@ -226,7 +215,6 @@ static struct attribute *ad5504_attributes[] = {
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
 	&iio_dev_attr_out_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -240,7 +228,6 @@ static struct attribute *ad5501_attributes[] = {
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
 	&iio_dev_attr_out_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -310,7 +297,7 @@ static int __devinit ad5504_probe(struct spi_device *spi)
 		goto error_disable_reg;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
-
+	st->indio_dev->name = spi_get_device_id(st->spi)->name;
 	st->indio_dev->attrs = spi_get_device_id(st->spi)->driver_data
 		== ID_AD5501 ? &ad5501_attribute_group :
 		&ad5504_attribute_group;
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
index cfb5828..b0e25e2 100644
--- a/drivers/staging/iio/dac/ad5624r_spi.c
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -174,17 +174,6 @@ static ssize_t ad5624r_show_scale(struct device *dev,
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5624r_show_scale, NULL, 0);
 
-static ssize_t ad5624r_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5624r_state *st = iio_dev_get_devdata(indio_dev);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5624r_show_name, NULL, 0);
-
 static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0);
 static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1);
 static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2);
@@ -222,7 +211,6 @@ static struct attribute *ad5624r_attributes[] = {
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
 	&iio_dev_attr_out_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -266,6 +254,7 @@ static int __devinit ad5624r_probe(struct spi_device *spi)
 		goto error_disable_reg;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad5624r_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c
index 9c6114f..4b5721c 100644
--- a/drivers/staging/iio/dds/ad9832.c
+++ b/drivers/staging/iio/dds/ad9832.c
@@ -153,17 +153,6 @@ error_ret:
 	return ret ? ret : len;
 }
 
-static ssize_t ad9832_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad9832_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad9832_show_name, NULL, 0);
-
 /**
  * see dds.h for further information
  */
@@ -199,7 +188,6 @@ static struct attribute *ad9832_attributes[] = {
 	&iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
 	&iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
 	&iio_dev_attr_dds0_out_enable.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -243,6 +231,7 @@ static int __devinit ad9832_probe(struct spi_device *spi)
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad9832_attribute_group;
 	st->indio_dev->dev_data = (void *) st;
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c
index 6dbc458..e5303e6 100644
--- a/drivers/staging/iio/dds/ad9834.c
+++ b/drivers/staging/iio/dds/ad9834.c
@@ -198,17 +198,6 @@ static ssize_t ad9834_store_wavetype(struct device *dev,
 	return ret ? ret : len;
 }
 
-static ssize_t ad9834_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad9834_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad9834_show_name, NULL, 0);
-
 static ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
 						struct device_attribute *attr,
 						char *buf)
@@ -288,7 +277,6 @@ static struct attribute *ad9834_attributes[] = {
 	&iio_dev_attr_dds0_out1_wavetype.dev_attr.attr,
 	&iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
 	&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -355,6 +343,7 @@ static int __devinit ad9834_probe(struct spi_device *spi)
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &ad9834_attribute_group;
 	st->indio_dev->dev_data = (void *) st;
 	st->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index 26af63f..fb48e9b 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -110,14 +110,12 @@ static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16080_read, NULL,
 		       ADIS16080_DIN_TEMP);
 static IIO_DEV_ATTR_IN_RAW(0, adis16080_read, ADIS16080_DIN_AIN1);
 static IIO_DEV_ATTR_IN_RAW(1, adis16080_read, ADIS16080_DIN_AIN2);
-static IIO_CONST_ATTR(name, "adis16080");
 
 static struct attribute *adis16080_attributes[] = {
 	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -146,6 +144,7 @@ static int __devinit adis16080_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16080_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
index 02fbe07..c2f338c 100644
--- a/drivers/staging/iio/gyro/adis16130_core.c
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -155,8 +155,6 @@ static ssize_t adis16130_bitsmode_write(struct device *dev,
 static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16130_val_read, NULL,
 		      ADIS16130_TEMPDATA);
 
-static IIO_CONST_ATTR(name, "adis16130");
-
 static IIO_DEV_ATTR_GYRO_Z(adis16130_val_read, ADIS16130_RATEDATA);
 
 static IIO_DEVICE_ATTR(gyro_z_type, S_IWUSR | S_IRUGO, adis16130_bitsmode_read,
@@ -167,7 +165,6 @@ static IIO_CONST_ATTR(gyro_z_type_available, "s16 s24");
 
 static struct attribute *adis16130_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
 	&iio_dev_attr_gyro_z_type.dev_attr.attr,
 	&iio_const_attr_gyro_z_type_available.dev_attr.attr,
@@ -197,6 +194,7 @@ static int __devinit adis16130_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16130_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index a50b645..3366bd0 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -505,8 +505,6 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
 static IIO_DEVICE_ATTR(sampling_frequency_available,
 		       S_IRUGO, adis16260_read_frequency_available, NULL, 0);
 
-static IIO_CONST_ATTR_NAME("adis16260");
-
 #define ADIS16260_GYRO_ATTR_SET(axis)					\
 	IIO_DEV_ATTR_GYRO##axis(adis16260_read_14bit_signed,		\
 				ADIS16260_GYRO_OUT);			\
@@ -547,7 +545,6 @@ static ADIS16260_GYRO_ATTR_SET(_Z);
 		&iio_dev_attr_sampling_frequency.dev_attr.attr,		\
 		&iio_dev_attr_sampling_frequency_available.dev_attr.attr, \
 		&iio_dev_attr_reset.dev_attr.attr,			\
-		&iio_const_attr_name.dev_attr.attr,			\
 		NULL							\
 	};								\
 	static const struct attribute_group adis16260_attribute_group##axis \
@@ -594,6 +591,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi_get_device_id(st->us)->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	if (pd && pd->direction)
 		switch (pd->direction) {
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index ddcae43..6419b75 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -427,16 +427,6 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static ssize_t adis16400_show_name(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
-{
-	struct adis16400_state *st
-		= iio_dev_get_devdata(dev_get_drvdata(dev));
-	return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, adis16400_show_name, NULL, 0);
-
 enum adis16400_chan {
 	in_supply,
 	gyro_x,
@@ -704,7 +694,6 @@ static struct attribute *adis16400_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -814,6 +803,7 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 	}
 	st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->attrs = &adis16400_attribute_group;
 	st->indio_dev->channels = st->variant->channels;
 	st->indio_dev->num_channels = st->variant->num_channels;
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index dfbc423..307c664 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -402,16 +402,6 @@ static ssize_t show_proxim_ir(struct device *dev,
 	return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE);
 }
 
-/* Read name */
-static ssize_t show_name(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct isl29018_chip *chip = indio_dev->dev_data;
-
-	return sprintf(buf, "%s\n", chip->client->name);
-}
-
 static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0);
 static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000");
 static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16");
@@ -424,12 +414,10 @@ static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression,
 static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0);
 static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0);
 static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0);
-static IIO_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
 
 #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
 #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
 static struct attribute *isl29018_attributes[] = {
-	ISL29018_DEV_ATTR(name),
 	ISL29018_DEV_ATTR(range),
 	ISL29018_CONST_ATTR(range_available),
 	ISL29018_DEV_ATTR(adc_resolution),
@@ -498,6 +486,7 @@ static int __devinit isl29018_probe(struct i2c_client *client,
 		goto exit_free;
 	}
 	chip->indio_dev->attrs = &isl29108_group;
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->dev_data = (void *)(chip);
 	chip->indio_dev->driver_module = THIS_MODULE;
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index d62d9e2..8b6bf50 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -463,8 +463,6 @@ static IIO_DEV_ATTR_RESET(ade7753_write_reset);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
 
-static IIO_CONST_ATTR(name, "ade7753");
-
 static struct attribute *ade7753_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -472,7 +470,6 @@ static struct attribute *ade7753_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_phcal.dev_attr.attr,
 	&iio_dev_attr_cfden.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
@@ -538,6 +535,7 @@ static int __devinit ade7753_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &ade7753_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 2d0b8cc..4179325 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -482,8 +482,6 @@ static IIO_DEV_ATTR_RESET(ade7754_write_reset);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
 
-static IIO_CONST_ATTR(name, "ade7754");
-
 static struct attribute *ade7754_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -491,7 +489,6 @@ static struct attribute *ade7754_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
 	&iio_dev_attr_laenergy.dev_attr.attr,
 	&iio_dev_attr_vaenergy.dev_attr.attr,
@@ -563,6 +560,7 @@ static int __devinit ade7754_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &ade7754_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index cab31dd..c9956c4 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -650,8 +650,6 @@ static IIO_DEV_ATTR_RESET(ade7758_write_reset);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
 
-static IIO_CONST_ATTR(name, "ade7758");
-
 static struct attribute *ade7758_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -660,7 +658,6 @@ static struct attribute *ade7758_attributes[] = {
 	&iio_dev_attr_waveform_type.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_awatthr.dev_attr.attr,
 	&iio_dev_attr_bwatthr.dev_attr.attr,
 	&iio_dev_attr_cwatthr.dev_attr.attr,
@@ -735,6 +732,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &ade7758_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 42b3b27..86fe0ae 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -422,8 +422,6 @@ static IIO_DEV_ATTR_RESET(ade7759_write_reset);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
 
-static IIO_CONST_ATTR(name, "ade7759");
-
 static struct attribute *ade7759_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -431,7 +429,6 @@ static struct attribute *ade7759_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_phcal.dev_attr.attr,
 	&iio_dev_attr_cfden.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
@@ -484,6 +481,7 @@ static int __devinit ade7759_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->num_interrupt_lines = 1;
 
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 6a7642e..9b855f3 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -89,13 +89,6 @@ struct iio_const_attr {
 	IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_NAME - chip type dependent identifier
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_NAME(_show)				\
-	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
-
-/**
  * IIO_DEV_ATTR_RESET: resets the device
  **/
 #define IIO_DEV_ATTR_RESET(_store)			\
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 055/111] staging:iio:light:tsl2563: chan_spec based channel setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (53 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 054/111] staging:iio: use the new central name attribute creation code Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 056/111] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
                   ` (56 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Makes a small interface change by splitting event _en attr
in two.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/light/tsl2563.c |  323 +++++++++++++----------------------
 1 files changed, 117 insertions(+), 206 deletions(-)

diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index d613086..ded3053 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -464,31 +464,6 @@ static unsigned int adc_to_lux(u32 adc0, u32 adc1)
 /*                      Sysfs interface                         */
 /*--------------------------------------------------------------*/
 
-static ssize_t tsl2563_adc_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-
-	mutex_lock(&chip->lock);
-
-	ret = tsl2563_get_adc(chip);
-	if (ret)
-		goto out;
-
-	switch (this_attr->address) {
-	case 0:
-		ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data0);
-		break;
-	case 1:
-		ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data1);
-		break;
-	}
-out:
-	mutex_unlock(&chip->lock);
-	return ret;
-}
 
 /* Apply calibration coefficient to ADC count. */
 static u32 calib_adc(u32 adc, u32 calib)
@@ -501,180 +476,138 @@ static u32 calib_adc(u32 adc, u32 calib)
 	return (u32) scaled;
 }
 
-static ssize_t tsl2563_lux_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static int tsl2563_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
 {
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	u32 calib0, calib1;
-	int ret;
-
-	mutex_lock(&chip->lock);
-
-	ret = tsl2563_get_adc(chip);
-	if (ret)
-		goto out;
-
-	calib0 = calib_adc(chip->data0, chip->calib0) * chip->cover_comp_gain;
-	calib1 = calib_adc(chip->data1, chip->calib1) * chip->cover_comp_gain;
-
-	ret = snprintf(buf, PAGE_SIZE, "%d\n", adc_to_lux(calib0, calib1));
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 
-out:
-	mutex_unlock(&chip->lock);
-	return ret;
-}
+	if (chan->channel == 0)
+		chip->calib0 = calib_from_sysfs(val);
+	else
+		chip->calib1 = calib_from_sysfs(val);
 
-static ssize_t format_calib(char *buf, int len, u32 calib)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n", calib_to_sysfs(calib));
+	return 0;
 }
 
-static ssize_t tsl2563_calib_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static int tsl2563_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long m)
 {
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
+	int ret = -EINVAL;
+	u32 calib0, calib1;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 
 	mutex_lock(&chip->lock);
-	switch (this_attr->address) {
+	switch (m) {
 	case 0:
-		ret = format_calib(buf, PAGE_SIZE, chip->calib0);
+		switch (chan->type) {
+		case IIO_LIGHT:
+			ret = tsl2563_get_adc(chip);
+			if (ret)
+				goto error_ret;
+			calib0 = calib_adc(chip->data0, chip->calib0) *
+				chip->cover_comp_gain;
+			calib1 = calib_adc(chip->data1, chip->calib1) *
+				chip->cover_comp_gain;
+			*val = adc_to_lux(calib0, calib1);
+			ret = IIO_VAL_INT;
+			break;
+		case IIO_INTENSITY:
+			ret = tsl2563_get_adc(chip);
+			if (ret)
+				goto error_ret;
+			if (chan->channel == 0)
+				*val = chip->data0;
+			else
+				*val = chip->data1;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			break;
+		}
 		break;
-	case 1:
-		ret = format_calib(buf, PAGE_SIZE, chip->calib1);
+
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		if (chan->channel == 0)
+			*val = calib_to_sysfs(chip->calib0);
+		else
+			*val = calib_to_sysfs(chip->calib1);
+		ret = IIO_VAL_INT;
 		break;
 	default:
-		ret = -ENODEV;
-	}
-	mutex_unlock(&chip->lock);
-	return ret;
-}
-
-static ssize_t tsl2563_calib_store(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t len)
-{
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int value;
-	u32 calib;
-
-	if (1 != sscanf(buf, "%d", &value))
 		return -EINVAL;
-
-	calib = calib_from_sysfs(value);
-
-	switch (this_attr->address) {
-	case 0:
-		chip->calib0 = calib;
-		break;
-	case 1:
-		chip->calib1 = calib;
-		break;
 	}
 
-	return len;
-}
-
-static IIO_DEVICE_ATTR(intensity0_both_raw, S_IRUGO,
-		tsl2563_adc_show, NULL, 0);
-static IIO_DEVICE_ATTR(intensity1_ir_raw, S_IRUGO,
-		tsl2563_adc_show, NULL, 1);
-static DEVICE_ATTR(illuminance0_input, S_IRUGO, tsl2563_lux_show, NULL);
-static IIO_DEVICE_ATTR(intensity0_both_calibgain, S_IRUGO | S_IWUSR,
-		tsl2563_calib_show, tsl2563_calib_store, 0);
-static IIO_DEVICE_ATTR(intensity1_ir_calibgain, S_IRUGO | S_IWUSR,
-		tsl2563_calib_show, tsl2563_calib_store, 1);
-
-static ssize_t tsl2563_show_name(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	return sprintf(buf, "%s\n", chip->client->name);
+error_ret:
+	mutex_unlock(&chip->lock);
+	return ret;
 }
 
-static DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL);
-
-static struct attribute *tsl2563_attributes[] = {
-	&iio_dev_attr_intensity0_both_raw.dev_attr.attr,
-	&iio_dev_attr_intensity1_ir_raw.dev_attr.attr,
-	&dev_attr_illuminance0_input.attr,
-	&iio_dev_attr_intensity0_both_calibgain.dev_attr.attr,
-	&iio_dev_attr_intensity1_ir_calibgain.dev_attr.attr,
-	&dev_attr_name.attr,
-	NULL
+static const struct iio_chan_spec tsl2563_channels[] = {
+	IIO_CHAN(IIO_LIGHT, 0, 1, 1, NULL, 0, 0, 0, 0, 0, {}, 0),
+	IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "both", 0,
+		 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {},
+		 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+		 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
+	IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "ir", 1,
+		 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {},
+		 0)
 };
 
-static const struct attribute_group tsl2563_group = {
-	.attrs = tsl2563_attributes,
-};
-
-static ssize_t tsl2563_read_thresh(struct device *dev,
-			struct device_attribute *attr,
-			char *buf)
+static int tsl2563_read_thresh(struct iio_dev *indio_dev,
+				int event_code,
+				int *val)
 {
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	u16 val = 0;
-	switch (this_attr->address) {
-	case TSL2563_REG_HIGHLOW:
-		val = chip->high_thres;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
+
+	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+	case IIO_EV_DIR_RISING:
+		*val = chip->high_thres;
 		break;
-	case TSL2563_REG_LOWLOW:
-		val = chip->low_thres;
+	case IIO_EV_DIR_FALLING:
+		*val = chip->low_thres;
 		break;
+	default:
+		return -EINVAL;
 	}
-	return snprintf(buf, PAGE_SIZE, "%d\n", val);
+
+	return 0;
 }
 
-static ssize_t tsl2563_write_thresh(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf,
-				size_t len)
+static ssize_t tsl2563_write_thresh(struct iio_dev *indio_dev,
+				  int event_code,
+				  int val)
 {
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	unsigned long val;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 	int ret;
+	u8 address;
 
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return ret;
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+		address = TSL2563_REG_HIGHLOW;
+	else
+		address = TSL2563_REG_LOWLOW;
 	mutex_lock(&chip->lock);
-	ret = tsl2563_write(chip->client, this_attr->address, val & 0xFF);
+	ret = tsl2563_write(chip->client, address, val & 0xFF);
 	if (ret)
 		goto error_ret;
-	ret = tsl2563_write(chip->client, this_attr->address + 1,
+	ret = tsl2563_write(chip->client, address + 1,
 			(val >> 8) & 0xFF);
-	switch (this_attr->address) {
-	case TSL2563_REG_HIGHLOW:
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
 		chip->high_thres = val;
-		break;
-	case TSL2563_REG_LOWLOW:
+	else
 		chip->low_thres = val;
-		break;
-	}
 
 error_ret:
 	mutex_unlock(&chip->lock);
 
-	return ret < 0 ? ret : len;
+	return ret;
 }
 
-static IIO_DEVICE_ATTR(intensity0_both_raw_thresh_rising_value,
-		S_IRUGO | S_IWUSR,
-		tsl2563_read_thresh,
-		tsl2563_write_thresh,
-		TSL2563_REG_HIGHLOW);
-
-static IIO_DEVICE_ATTR(intensity0_both_raw_thresh_falling_value,
-		S_IRUGO | S_IWUSR,
-		tsl2563_read_thresh,
-		tsl2563_write_thresh,
-		TSL2563_REG_LOWLOW);
-
 static irqreturn_t tsl2563_event_handler(int irq, void *private)
 {
 	struct iio_dev *dev_info = private;
@@ -693,20 +626,15 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
-static ssize_t tsl2563_write_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
+static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
+					int event_code,
+					int state)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct tsl2563_chip *chip = iio_priv(indio_dev);
-	int input, ret = 0;
+	int ret = 0;
 
-	ret = sscanf(buf, "%d", &input);
-	if (ret != 1)
-		return -EINVAL;
 	mutex_lock(&chip->lock);
-	if (input && !(chip->intr & 0x30)) {
+	if (state && !(chip->intr & 0x30)) {
 		chip->intr &= ~0x30;
 		chip->intr |= 0x10;
 		/* ensure the chip is actually on */
@@ -723,7 +651,7 @@ static ssize_t tsl2563_write_interrupt_config(struct device *dev,
 		chip->int_enabled = true;
 	}
 
-	if (!input && (chip->intr & 0x30)) {
+	if (!state && (chip->intr & 0x30)) {
 		chip->intr |= ~0x30;
 		ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
 		chip->int_enabled = false;
@@ -733,47 +661,27 @@ static ssize_t tsl2563_write_interrupt_config(struct device *dev,
 out:
 	mutex_unlock(&chip->lock);
 
-	return (ret < 0) ? ret : len;
+	return ret;
 }
 
-static ssize_t tsl2563_read_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
+					   int event_code)
 {
-	struct tsl2563_chip *chip = iio_priv(dev_get_drvdata(dev));
-	int ret;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 	u8 rxbuf;
-	ssize_t len;
+	int ret;
 
 	mutex_lock(&chip->lock);
-	ret = tsl2563_read(chip->client,
-			TSL2563_REG_INT,
-			&rxbuf,
-			sizeof(rxbuf));
+	ret = tsl2563_read(chip->client, TSL2563_REG_INT,
+			   &rxbuf, sizeof(rxbuf));
 	mutex_unlock(&chip->lock);
 	if (ret < 0)
 		goto error_ret;
-	len = snprintf(buf, PAGE_SIZE, "%d\n", !!(rxbuf & 0x30));
+	ret = !!(rxbuf & 0x30);
 error_ret:
 
-	return (ret < 0) ? ret : len;
+	return ret;
 }
-static IIO_DEVICE_ATTR(intensity0_both_thresh_en,
-		       S_IRUGO | S_IWUSR,
-		       tsl2563_read_interrupt_config,
-		       tsl2563_write_interrupt_config,
-		       0);
-
-static struct attribute *tsl2563_event_attributes[] = {
-	&iio_dev_attr_intensity0_both_thresh_en.dev_attr.attr,
-	&iio_dev_attr_intensity0_both_raw_thresh_rising_value.dev_attr.attr,
-	&iio_dev_attr_intensity0_both_raw_thresh_falling_value.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group tsl2563_event_attribute_group = {
-	.attrs = tsl2563_event_attributes,
-};
 
 /*--------------------------------------------------------------*/
 /*                      Probe, Attach, Remove                   */
@@ -825,20 +733,23 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 		chip->cover_comp_gain = 1;
 
 	dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
-
-	indio_dev->attrs = &tsl2563_group;
+	indio_dev->name = client->name;
+	indio_dev->channels = tsl2563_channels;
+	indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
+	indio_dev->read_raw = &tsl2563_read_raw;
+	indio_dev->write_raw = &tsl2563_write_raw;
+	indio_dev->read_event_value = &tsl2563_read_thresh;
+	indio_dev->write_event_value = &tsl2563_write_thresh;
+	indio_dev->read_event_config = &tsl2563_read_interrupt_config;
+	indio_dev->write_event_config = &tsl2563_write_interrupt_config;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-	if (client->irq) {
+	if (client->irq)
 		indio_dev->num_interrupt_lines = 1;
-		indio_dev->event_attrs
-			= &tsl2563_event_attribute_group;
-	}
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto fail1;
-
 	if (client->irq) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 056/111] staging:iio:accel:adis16201 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (54 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 055/111] staging:iio:light:tsl2563: chan_spec based channel setup Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 057/111] staging:iio:accel:adis16203 " Jonathan Cameron
                   ` (55 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Mainly motivated by wish to remove the remaing users of the
scan helpers.

Some minor cleanups done whilst here.

Untested.

V2: IIO_CHAN macro used.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201.h         |    4 +-
 drivers/staging/iio/accel/adis16201_core.c    |  454 +++++++++++--------------
 drivers/staging/iio/accel/adis16201_ring.c    |   87 +----
 drivers/staging/iio/accel/adis16201_trigger.c |    3 +-
 4 files changed, 220 insertions(+), 328 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h
index 6296a4f..0b9b854 100644
--- a/drivers/staging/iio/accel/adis16201.h
+++ b/drivers/staging/iio/accel/adis16201.h
@@ -79,7 +79,7 @@ struct adis16201_state {
 	struct mutex			buf_lock;
 };
 
-int adis16201_set_irq(struct device *dev, bool enable);
+int adis16201_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 enum adis16201_scan {
@@ -102,8 +102,6 @@ ssize_t adis16201_read_data_from_ring(struct device *dev,
 int adis16201_configure_ring(struct iio_dev *indio_dev);
 void adis16201_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16201_initialize_ring(struct iio_ring_buffer *ring);
-void adis16201_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16201_remove_trigger(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index f45eb8f..59b6ac2 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -16,20 +13,28 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
+
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16201.h"
 
 #define DRIVER_NAME		"adis16201"
 
-static int adis16201_check_status(struct device *dev);
+enum adis16201_chan {
+	in_supply,
+	temp,
+	accel_x,
+	accel_y,
+	incli_x,
+	incli_y,
+	in_aux,
+};
 
 /**
  * adis16201_spi_write_reg_8() - write single byte to a register
@@ -57,18 +62,17 @@ static int adis16201_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16201_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +84,6 @@ static int adis16201_spi_write_reg_16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -101,17 +104,16 @@ static int adis16201_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16201_spi_read_reg_16(struct device *dev,
+static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -125,7 +127,6 @@ static int adis16201_spi_read_reg_16(struct device *dev,
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -150,160 +151,6 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16201_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16201_ERROR_ACTIVE) {
-		ret = adis16201_check_status(dev);
-		if (ret)
-			return ret;
-	}
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16201_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_TEMP_OUT, (u16 *)&val);
-	if (ret)
-		goto error_ret;
-
-	if (val & ADIS16201_ERROR_ACTIVE) {
-		ret = adis16201_check_status(dev);
-		if (ret)
-			goto error_ret;
-	}
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16201_read_9bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-		val = ((s16)(val << 7) >> 7);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-
-		val = ((s16)(val << 4) >> 4);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16201_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static int adis16201_reset(struct device *dev)
 {
 	int ret;
@@ -331,12 +178,12 @@ static ssize_t adis16201_write_reset(struct device *dev,
 	return -EINVAL;
 }
 
-int adis16201_set_irq(struct device *dev, bool enable)
+int adis16201_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_MSC_CTRL, &msc);
+	ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -347,20 +194,21 @@ int adis16201_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16201_spi_write_reg_16(dev, ADIS16201_MSC_CTRL, msc);
+	ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16201_check_status(struct device *dev)
+static int adis16201_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
 
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_DIAG_STAT, &status);
+	ret = adis16201_spi_read_reg_16(indio_dev,
+					ADIS16201_DIAG_STAT, &status);
 	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
 	}
 	ret = status & 0xF;
@@ -368,30 +216,30 @@ static int adis16201_check_status(struct device *dev)
 		ret = -EFAULT;
 
 	if (status & ADIS16201_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
+		dev_err(&indio_dev->dev, "SPI failure\n");
 	if (status & ADIS16201_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
+		dev_err(&indio_dev->dev, "Flash update failed\n");
 	if (status & ADIS16201_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
 	if (status & ADIS16201_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
 	return ret;
 }
 
-static int adis16201_self_test(struct device *dev)
+static int adis16201_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16201_spi_write_reg_16(dev,
+	ret = adis16201_spi_write_reg_16(indio_dev,
 			ADIS16201_MSC_CTRL,
 			ADIS16201_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	ret = adis16201_check_status(dev);
+	ret = adis16201_check_status(indio_dev);
 
 err_ret:
 	return ret;
@@ -403,26 +251,26 @@ static int adis16201_initial_setup(struct adis16201_state *st)
 	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16201_set_irq(dev, false);
+	ret = adis16201_set_irq(st->indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16201_self_test(dev);
+	ret = adis16201_self_test(st->indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16201_check_status(dev);
+	ret = adis16201_check_status(st->indio_dev);
 	if (ret) {
 		adis16201_reset(dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16201_STARTUP_DELAY);
-		ret = adis16201_check_status(dev);
+		ret = adis16201_check_status(st->indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
@@ -436,66 +284,172 @@ err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16201_read_12bit_unsigned,
-		ADIS16201_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16201_read_12bit_unsigned,
-		ADIS16201_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16201_read_14bit_signed,
-		ADIS16201_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16201_read_14bit_signed,
-		ADIS16201_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_12bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_XACCL_OFFS);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_12bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_YACCL_OFFS);
-static IIO_CONST_ATTR(accel_scale, "0.4625");
-
-static IIO_DEV_ATTR_INCLI_X(adis16201_read_14bit_signed,
-		ADIS16201_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16201_read_14bit_signed,
-		ADIS16201_YINCL_OUT);
-static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_9bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_XACCL_OFFS);
-static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_9bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_YACCL_OFFS);
-static IIO_CONST_ATTR(incli_scale, "0.1");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16201_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static u8 adis16201_addresses[7][2] = {
+	[in_supply] = { ADIS16201_SUPPLY_OUT, },
+	[temp] = { ADIS16201_TEMP_OUT },
+	[accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS },
+	[accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS },
+	[in_aux] = { ADIS16201_AUX_ADC },
+	[incli_x] = { ADIS16201_XINCL_OUT },
+	[incli_y] = { ADIS16201_YINCL_OUT },
+};
+
+static int adis16201_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16201_addresses[chan->address][0];
+		ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16201_ERROR_ACTIVE) {
+			ret = adis16201_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 462500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 100000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		case IIO_INCLI:
+			bits = 9;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16201_addresses[chan->address][1];
+		ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16201_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		case IIO_INCLI:
+			bits = 9;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16201_addresses[chan->address][1];
+		return adis16201_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16201_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16201_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16201_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16201_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16201_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16201_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_x, ADIS16201_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_y, ADIS16201_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(7)
+};
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0);
 
 static struct attribute *adis16201_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_dev_attr_incli_x_offset.dev_attr.attr,
-	&iio_dev_attr_incli_y_offset.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
 	NULL
 };
 
@@ -537,6 +491,10 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16201_attribute_group;
+	st->indio_dev->channels = adis16201_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16201_channels);
+	st->indio_dev->read_raw = &adis16201_read_raw;
+	st->indio_dev->write_raw = &adis16201_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -550,7 +508,9 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16201_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16201_channels,
+					  ARRAY_SIZE(adis16201_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -571,7 +531,7 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16201_remove_trigger(st->indio_dev);
 error_uninitialize_ring:
-	adis16201_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16201_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -594,10 +554,8 @@ static int adis16201_remove(struct spi_device *spi)
 	struct adis16201_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16201_remove_trigger(indio_dev);
-	adis16201_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16201_unconfigure_ring(indio_dev);
 	kfree(st->tx);
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index d0998b2..5405a38 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -1,14 +1,11 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -17,63 +14,15 @@
 #include "../trigger.h"
 #include "adis16201.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16201_SCAN_SUPPLY, ADIS16201_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16201_SCAN_ACC_X, ADIS16201_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16201_SCAN_ACC_Y, ADIS16201_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16201_SCAN_AUX_ADC, ADIS16201_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16201_SCAN_TEMP, ADIS16201_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16201_SCAN_INCLI_X,
-		     ADIS16201_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16201_SCAN_INCLI_Y,
-		     ADIS16201_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(7);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16201_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16201_scan_el_group = {
-	.attrs = adis16201_scan_el_attrs,
-	.name = "scan_elements",
-};
 
 /**
  * adis16201_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
  **/
-static int adis16201_read_ring_data(struct device *dev, u8 *rx)
+static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[ADIS16201_OUTPUTS + 1];
 	int ret;
@@ -90,7 +39,8 @@ static int adis16201_read_ring_data(struct device *dev, u8 *rx)
 		xfers[i].len = 2;
 		xfers[i].delay_usecs = 20;
 		xfers[i].tx_buf = st->tx + 2 * i;
-		st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT +
+						   2 * i);
 		st->tx[2 * i + 1] = 0;
 		if (i >= 1)
 			xfers[i].rx_buf = rx + 2 * (i - 1);
@@ -127,7 +77,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 	}
 
 	if (ring->scan_count)
-		if (adis16201_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		if (adis16201_read_ring_data(st->indio_dev, st->rx) >= 0)
 			for (; i < ring->scan_count; i++)
 				data[i] = be16_to_cpup(
 					(__be16 *)&(st->rx[i*2]));
@@ -136,9 +86,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      pf->timestamp);
+	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -167,7 +115,6 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16201_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -175,13 +122,13 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring,	ADIS16201_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_Y);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
@@ -207,13 +154,3 @@ error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16201_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16201_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c
index a4fb410..bfd43c5 100644
--- a/drivers/staging/iio/accel/adis16201_trigger.c
+++ b/drivers/staging/iio/accel/adis16201_trigger.c
@@ -4,7 +4,6 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -33,7 +32,7 @@ static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16201_set_irq(&st->indio_dev->dev, state);
+	return adis16201_set_irq(st->indio_dev, state);
 }
 
 int adis16201_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 057/111] staging:iio:accel:adis16203 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (55 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 056/111] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 058/111] staging:iio:accel:adis16204 " Jonathan Cameron
                   ` (54 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Mainly motivated by wish to remove the remaing users of the
scan helpers.

Some minor cleanups done whilst here.

Untested.

V2: Use IIO_CHAN macro
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16203.h         |   13 +-
 drivers/staging/iio/accel/adis16203_core.c    |  376 ++++++++++++------------
 drivers/staging/iio/accel/adis16203_ring.c    |   61 +----
 drivers/staging/iio/accel/adis16203_trigger.c |    2 +-
 4 files changed, 195 insertions(+), 257 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h
index 49fce30..8bb8ce5 100644
--- a/drivers/staging/iio/accel/adis16203.h
+++ b/drivers/staging/iio/accel/adis16203.h
@@ -74,7 +74,7 @@ struct adis16203_state {
 	struct mutex			buf_lock;
 };
 
-int adis16203_set_irq(struct device *dev, bool enable);
+int adis16203_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 enum adis16203_scan {
@@ -95,8 +95,6 @@ ssize_t adis16203_read_data_from_ring(struct device *dev,
 int adis16203_configure_ring(struct iio_dev *indio_dev);
 void adis16203_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16203_initialize_ring(struct iio_ring_buffer *ring);
-void adis16203_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16203_remove_trigger(struct iio_dev *indio_dev)
@@ -125,14 +123,5 @@ static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16203_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16203_H_ */
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 6162311..1694a0c 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -16,33 +13,29 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
+#include "../ring_generic.h"
 #include "../adc/adc.h"
 
 #include "adis16203.h"
 
 #define DRIVER_NAME		"adis16203"
 
-static int adis16203_check_status(struct device *dev);
-
 /**
  * adis16203_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16203_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -57,18 +50,17 @@ static int adis16203_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16203_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +72,6 @@ static int adis16203_spi_write_reg_16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -101,17 +92,16 @@ static int adis16203_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16203_spi_read_reg_16(struct device *dev,
+static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -125,7 +115,6 @@ static int adis16203_spi_read_reg_16(struct device *dev,
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -150,101 +139,43 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16203_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static int adis16203_check_status(struct iio_dev *indio_dev)
 {
+	u16 status;
 	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16203_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16203_ERROR_ACTIVE)
-		adis16203_check_status(dev);
 
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16203_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_TEMP_OUT, (u16 *)&val);
-	if (ret)
+	ret = adis16203_spi_read_reg_16(indio_dev,
+					ADIS16203_DIAG_STAT,
+					&status);
+	if (ret < 0) {
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
-
-	if (val & ADIS16203_ERROR_ACTIVE)
-		adis16203_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16203_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16203_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16203_ERROR_ACTIVE)
-			adis16203_check_status(dev);
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
 	}
+	ret = status & 0x1F;
 
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16203_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16203_spi_write_reg_16(dev, this_attr->address, val);
+	if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(&indio_dev->dev, "Self test failure\n");
+	if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
+		dev_err(&indio_dev->dev, "SPI failure\n");
+	if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
+		dev_err(&indio_dev->dev, "Flash update failed\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_LOW)
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
-	return ret ? ret : len;
+	return ret;
 }
 
-static int adis16203_reset(struct device *dev)
+static int adis16203_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16203_spi_write_reg_8(dev,
+	ret = adis16203_spi_write_reg_8(indio_dev,
 			ADIS16203_GLOB_CMD,
 			ADIS16203_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -253,23 +184,24 @@ static ssize_t adis16203_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16203_reset(dev);
+		return adis16203_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16203_set_irq(struct device *dev, bool enable)
+int adis16203_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_MSC_CTRL, &msc);
+	ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -280,131 +212,195 @@ int adis16203_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16203_spi_write_reg_16(dev, ADIS16203_MSC_CTRL, msc);
-
-error_ret:
-	return ret;
-}
-
-static int adis16203_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_DIAG_STAT, &status);
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status & 0x1F;
-
-	if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
-	if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
-	if (status & ADIS16203_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+	ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16203_self_test(struct device *dev)
+static int adis16203_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16203_spi_write_reg_16(dev,
+	ret = adis16203_spi_write_reg_16(indio_dev,
 			ADIS16203_MSC_CTRL,
 			ADIS16203_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16203_check_status(dev);
+	adis16203_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16203_initial_setup(struct adis16203_state *st)
+static int adis16203_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16203_set_irq(dev, false);
+	ret = adis16203_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16203_self_test(dev);
+	ret = adis16203_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16203_check_status(dev);
+	ret = adis16203_check_status(indio_dev);
 	if (ret) {
-		adis16203_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16203_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16203_STARTUP_DELAY);
-		ret = adis16203_check_status(dev);
+		ret = adis16203_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16203_read_12bit_unsigned,
-		ADIS16203_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16203_read_12bit_unsigned,
-		ADIS16203_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
-
-static IIO_DEV_ATTR_INCLI_X(adis16203_read_14bit_signed,
-		ADIS16203_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16203_read_14bit_signed,
-		ADIS16203_YINCL_OUT);
-static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16203_read_14bit_signed,
-		adis16203_write_16bit,
-		ADIS16203_INCL_NULL);
-static IIO_CONST_ATTR(incli_scale, "0.025");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16203_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+enum adis16203_chan {
+	in_supply,
+	in_aux,
+	incli_x,
+	incli_y,
+	temp,
+};
+
+static u8 adis16203_addresses[5][2] = {
+	[in_supply] = { ADIS16203_SUPPLY_OUT },
+	[in_aux] = { ADIS16203_AUX_ADC },
+	[incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL},
+	[incli_y] = { ADIS16203_YINCL_OUT },
+	[temp] = { ADIS16203_TEMP_OUT }
+};
+
+static int adis16203_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	/* currently only one writable parameter which keeps this simple */
+	u8 addr = adis16203_addresses[chan->address][1];
+	return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF);
+}
+
+static int adis16203_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16203_addresses[chan->address][0];
+		ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16203_ERROR_ACTIVE) {
+			ret = adis16203_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 25000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		bits = 14;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16203_addresses[chan->address][1];
+		ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct iio_chan_spec adis16203_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16203_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16203_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_x, ADIS16203_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	/* Fixme: Not what it appears to be - see data sheet */
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_y, ADIS16203_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16203_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(5),
+};
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0);
 
 static struct attribute *adis16203_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_dev_attr_incli_x_offset.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
 	NULL
 };
 
@@ -445,6 +441,10 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16203_attribute_group;
+	st->indio_dev->channels = adis16203_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16203_channels);
+	st->indio_dev->read_raw = &adis16203_read_raw;
+	st->indio_dev->write_raw = &adis16203_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -458,7 +458,9 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16203_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16203_channels,
+					  ARRAY_SIZE(adis16203_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -471,7 +473,7 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16203_initial_setup(st);
+	ret = adis16203_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
@@ -479,7 +481,7 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16203_remove_trigger(st->indio_dev);
 error_uninitialize_ring:
-	adis16203_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16203_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -502,10 +504,8 @@ static int adis16203_remove(struct spi_device *spi)
 	struct adis16203_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16203_remove_trigger(indio_dev);
-	adis16203_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16203_unconfigure_ring(indio_dev);
 	kfree(st->tx);
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index cdd0aff..a21a71d 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -17,46 +17,6 @@
 #include "../trigger.h"
 #include "adis16203.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16203_SCAN_SUPPLY, ADIS16203_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(in0, ADIS16203_SCAN_AUX_ADC, ADIS16203_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16203_SCAN_TEMP, ADIS16203_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16203_SCAN_INCLI_X,
-		     ADIS16203_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16203_SCAN_INCLI_Y,
-		     ADIS16203_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16203_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16203_scan_el_group = {
-	.attrs = adis16203_scan_el_attrs,
-	.name = "scan_elements",
-};
-
 /**
  * adis16203_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -162,7 +122,6 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16203_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -170,11 +129,11 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_Y);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
@@ -200,13 +159,3 @@ error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16203_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c
index b554049..72710f8 100644
--- a/drivers/staging/iio/accel/adis16203_trigger.c
+++ b/drivers/staging/iio/accel/adis16203_trigger.c
@@ -33,7 +33,7 @@ static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16203_set_irq(&st->indio_dev->dev, state);
+	return adis16203_set_irq(st->indio_dev, state);
 }
 
 int adis16203_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 058/111] staging:iio:accel:adis16204 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (56 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 057/111] staging:iio:accel:adis16203 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 059/111] staging:iio:accel:adis16209 " Jonathan Cameron
                   ` (53 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

For clean drivers its easier to convert to chan_spec based
registration than to work around the scan_el attributes
going away.

Some minor cleanups done whilst here.

Untested.

V2: used IIO_CHAN macro

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16204.h         |   13 +-
 drivers/staging/iio/accel/adis16204_core.c    |  402 +++++++++++++------------
 drivers/staging/iio/accel/adis16204_ring.c    |   62 +----
 drivers/staging/iio/accel/adis16204_trigger.c |    2 +-
 4 files changed, 220 insertions(+), 259 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h
index bdd20c6..5310a42 100644
--- a/drivers/staging/iio/accel/adis16204.h
+++ b/drivers/staging/iio/accel/adis16204.h
@@ -82,7 +82,7 @@ struct adis16204_state {
 	struct mutex			buf_lock;
 };
 
-int adis16204_set_irq(struct device *dev, bool enable);
+int adis16204_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 enum adis16204_scan {
@@ -103,8 +103,6 @@ ssize_t adis16204_read_data_from_ring(struct device *dev,
 int adis16204_configure_ring(struct iio_dev *indio_dev);
 void adis16204_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16204_initialize_ring(struct iio_ring_buffer *ring);
-void adis16204_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16204_remove_trigger(struct iio_dev *indio_dev)
@@ -133,14 +131,5 @@ static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 {
 }
 
-static inline int adis16204_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16204_H_ */
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index a9c890d..4e4944c 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -20,28 +20,25 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "accel.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16204.h"
 
 #define DRIVER_NAME		"adis16204"
 
-static int adis16204_check_status(struct device *dev);
-
 /**
  * adis16204_spi_write_reg_8() - write single byte to a register
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16204_spi_write_reg_8(struct device *dev,
+static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev,
 		u8 reg_address,
 		u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +53,17 @@ static int adis16204_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16204_spi_write_reg_16(struct device *dev,
+static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -100,17 +96,16 @@ static int adis16204_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16204_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
+static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev,
+				     u8 lower_reg_address,
+				     u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -124,7 +119,6 @@ static int adis16204_spi_read_reg_16(struct device *dev,
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -149,72 +143,31 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16204_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static int adis16204_check_status(struct iio_dev *indio_dev)
 {
+	u16 status;
 	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16204_ERROR_ACTIVE)
-		adis16204_check_status(dev);
 
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16204_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_TEMP_OUT, (u16 *)&val);
-	if (ret)
+	ret = adis16204_spi_read_reg_16(indio_dev,
+					ADIS16204_DIAG_STAT, &status);
+	if (ret < 0) {
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
-
-	if (val & ADIS16204_ERROR_ACTIVE)
-		adis16204_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16204_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16204_ERROR_ACTIVE)
-			adis16204_check_status(dev);
-
-		val = ((s16)(val << 4) >> 4);
-		ret = sprintf(buf, "%d\n", val);
 	}
+	ret = status & 0x1F;
 
-	mutex_unlock(&indio_dev->mlock);
+	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(&indio_dev->dev, "Self test failure\n");
+	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
+		dev_err(&indio_dev->dev, "SPI failure\n");
+	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
+		dev_err(&indio_dev->dev, "Flash update failed\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
+		dev_err(&indio_dev->dev, "Power supply below 2.975V\n");
 
+error_ret:
 	return ret;
 }
 
@@ -229,10 +182,11 @@ static ssize_t adis16204_read_14bit_signed(struct device *dev,
 
 	mutex_lock(&indio_dev->mlock);
 
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	ret = adis16204_spi_read_reg_16(indio_dev,
+					this_attr->address, (u16 *)&val);
 	if (!ret) {
 		if (val & ADIS16204_ERROR_ACTIVE)
-			adis16204_check_status(dev);
+			adis16204_check_status(indio_dev);
 
 		val = ((s16)(val << 2) >> 2);
 		ret = sprintf(buf, "%d\n", val);
@@ -243,32 +197,14 @@ static ssize_t adis16204_read_14bit_signed(struct device *dev,
 	return ret;
 }
 
-static ssize_t adis16204_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int adis16204_reset(struct iio_dev *indio_dev)
 {
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16204_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16204_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16204_spi_write_reg_8(dev,
+	ret = adis16204_spi_write_reg_8(indio_dev,
 			ADIS16204_GLOB_CMD,
 			ADIS16204_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -277,23 +213,25 @@ static ssize_t adis16204_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16204_reset(dev);
+		return adis16204_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16204_set_irq(struct device *dev, bool enable)
+int adis16204_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_MSC_CTRL, &msc);
+	ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -304,106 +242,63 @@ int adis16204_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16204_spi_write_reg_16(dev, ADIS16204_MSC_CTRL, msc);
+	ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16204_check_status(struct device *dev)
+static int adis16204_self_test(struct iio_dev *indio_dev)
 {
-	u16 status;
 	int ret;
-
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_DIAG_STAT, &status);
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status & 0x1F;
-
-	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
-	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
-	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 2.975V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16204_self_test(struct device *dev)
-{
-	int ret;
-	ret = adis16204_spi_write_reg_16(dev,
+	ret = adis16204_spi_write_reg_16(indio_dev,
 			ADIS16204_MSC_CTRL,
 			ADIS16204_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16204_check_status(dev);
+	adis16204_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16204_initial_setup(struct adis16204_state *st)
+static int adis16204_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16204_set_irq(dev, false);
+	ret = adis16204_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16204_self_test(dev);
+	ret = adis16204_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16204_check_status(dev);
+	ret = adis16204_check_status(indio_dev);
 	if (ret) {
-		adis16204_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16204_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16204_STARTUP_DELAY);
-		ret = adis16204_check_status(dev);
+		ret = adis16204_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16204_read_12bit_unsigned,
-		ADIS16204_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16204_read_12bit_unsigned,
-		ADIS16204_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16204_read_14bit_signed,
-		ADIS16204_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16204_read_14bit_signed,
-		ADIS16204_YACCL_OUT);
 static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed,
 		ADIS16204_XY_RSS_OUT);
 static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed,
@@ -412,43 +307,164 @@ static IIO_DEV_ATTR_ACCEL_YPEAK(adis16204_read_14bit_signed,
 		ADIS16204_Y_PEAK_OUT);
 static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed,
 		ADIS16204_XY_PEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16204_read_12bit_signed,
-		adis16204_write_16bit,
-		ADIS16204_XACCL_NULL);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16204_read_12bit_signed,
-		adis16204_write_16bit,
-		ADIS16204_YACCL_NULL);
-static IIO_CONST_ATTR(accel_x_scale, "0.017125");
-static IIO_CONST_ATTR(accel_y_scale, "0.008407");
 static IIO_CONST_ATTR(accel_xy_scale, "0.017125");
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16204_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
-
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
 
+enum adis16204_channel {
+	in_supply,
+	in_aux,
+	temp,
+	accel_x,
+	accel_y,
+};
+
+static u8 adis16204_addresses[5][2] = {
+	[in_supply] = { ADIS16204_SUPPLY_OUT },
+	[in_aux] = { ADIS16204_AUX_ADC },
+	[temp] = { ADIS16204_TEMP_OUT },
+	[accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL },
+	[accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL },
+};
+static int adis16204_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16204_addresses[chan->address][0];
+		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16204_ERROR_ACTIVE) {
+			ret = adis16204_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			if (chan->channel == 'x')
+				*val2 = 17125;
+			else
+				*val2 = 8407;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16204_addresses[chan->address][1];
+		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16204_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16204_addresses[chan->address][1];
+		return adis16204_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16204_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 0, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16204_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16204_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16204_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16204_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16204_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(5),
+};
 static struct attribute *adis16204_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
 	&iio_dev_attr_accel_xy.dev_attr.attr,
 	&iio_dev_attr_accel_xpeak.dev_attr.attr,
 	&iio_dev_attr_accel_ypeak.dev_attr.attr,
 	&iio_dev_attr_accel_xypeak.dev_attr.attr,
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_const_attr_accel_x_scale.dev_attr.attr,
-	&iio_const_attr_accel_y_scale.dev_attr.attr,
 	&iio_const_attr_accel_xy_scale.dev_attr.attr,
 	NULL
 };
@@ -491,6 +507,10 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16204_attribute_group;
+	st->indio_dev->channels = adis16204_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
+	st->indio_dev->read_raw = &adis16204_read_raw;
+	st->indio_dev->write_raw = &adis16204_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -504,7 +524,9 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16204_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16204_channels,
+					  ARRAY_SIZE(adis16204_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -517,7 +539,7 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16204_initial_setup(st);
+	ret = adis16204_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
@@ -525,7 +547,7 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16204_remove_trigger(st->indio_dev);
 error_uninitialize_ring:
-	adis16204_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16204_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -548,10 +570,8 @@ static int adis16204_remove(struct spi_device *spi)
 	struct adis16204_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16204_remove_trigger(indio_dev);
-	adis16204_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16204_unconfigure_ring(indio_dev);
 	kfree(st->tx);
@@ -583,5 +603,5 @@ static __exit void adis16204_exit(void)
 module_exit(adis16204_exit);
 
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder");
+MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 035e5c4..50cd073 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -17,44 +17,6 @@
 #include "../trigger.h"
 #include "adis16204.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16204_SCAN_SUPPLY, ADIS16204_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16204_SCAN_ACC_X, ADIS16204_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16204_SCAN_ACC_Y, ADIS16204_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16204_SCAN_AUX_ADC, ADIS16204_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16204_SCAN_TEMP, ADIS16204_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16204_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16204_scan_el_group = {
-	.attrs = adis16204_scan_el_attrs,
-	.name = "scan_elements",
-};
-
 /**
  * adis16204_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -80,7 +42,8 @@ static int adis16204_read_ring_data(struct device *dev, u8 *rx)
 		xfers[i].len = 2;
 		xfers[i].delay_usecs = 20;
 		xfers[i].tx_buf = st->tx + 2 * i;
-		st->tx[2 * i] = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i]
+			= ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
 		st->tx[2 * i + 1] = 0;
 		if (i >= 1)
 			xfers[i].rx_buf = rx + 2 * (i - 1);
@@ -154,7 +117,6 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16204_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -162,11 +124,11 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_TEMP);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
@@ -193,13 +155,3 @@ error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16204_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c
index 5f083f8..a00668c 100644
--- a/drivers/staging/iio/accel/adis16204_trigger.c
+++ b/drivers/staging/iio/accel/adis16204_trigger.c
@@ -33,7 +33,7 @@ static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16204_set_irq(&st->indio_dev->dev, state);
+	return adis16204_set_irq(st->indio_dev, state);
 }
 
 int adis16204_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 059/111] staging:iio:accel:adis16209 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (57 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 058/111] staging:iio:accel:adis16204 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 060/111] staging:iio:adc:ad7887: Convert to new channel registration method Jonathan Cameron
                   ` (52 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

For clean drivers its easier to convert to chan_spec based
registration than to work around the scan_el attributes
going away.

Some minor cleanups done whilst here.

Untested.

V2: IIO_CHAN macro used.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16209.h         |    2 +-
 drivers/staging/iio/accel/adis16209_core.c    |  434 +++++++++++++------------
 drivers/staging/iio/accel/adis16209_ring.c    |   71 +----
 drivers/staging/iio/accel/adis16209_trigger.c |    2 +-
 4 files changed, 232 insertions(+), 277 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
index 9ef596f..58d08db 100644
--- a/drivers/staging/iio/accel/adis16209.h
+++ b/drivers/staging/iio/accel/adis16209.h
@@ -119,7 +119,7 @@ struct adis16209_state {
 	struct mutex			buf_lock;
 };
 
-int adis16209_set_irq(struct device *dev, bool enable);
+int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index fa0a3ad..d48babe 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -23,27 +20,23 @@
 #include "../ring_generic.h"
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16209.h"
 
 #define DRIVER_NAME		"adis16209"
 
-static int adis16209_check_status(struct device *dev);
-
 /**
  * adis16209_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with actual device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16209_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -58,18 +51,17 @@ static int adis16209_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16209_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -82,7 +74,6 @@ static int adis16209_spi_write_reg_16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -104,17 +95,16 @@ static int adis16209_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16209_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
+static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev,
+				     u8 lower_reg_address,
+				     u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -128,7 +118,6 @@ static int adis16209_spi_read_reg_16(struct device *dev,
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -154,119 +143,14 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16209_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16209_read_14bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static int adis16209_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x3FFF);
-}
-
-static ssize_t adis16209_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_TEMP_OUT, (u16 *)&val);
-	if (ret)
-		goto error_ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16209_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16209_ERROR_ACTIVE)
-			adis16209_check_status(dev);
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16209_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16209_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16209_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16209_spi_write_reg_8(dev,
+	ret = adis16209_spi_write_reg_8(indio_dev,
 			ADIS16209_GLOB_CMD,
 			ADIS16209_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -275,23 +159,25 @@ static ssize_t adis16209_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16209_reset(dev);
+		return adis16209_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16209_set_irq(struct device *dev, bool enable)
+int adis16209_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_MSC_CTRL, &msc);
+	ret = adis16209_spi_read_reg_16(indio_dev, ADIS16209_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -302,149 +188,267 @@ int adis16209_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16209_spi_write_reg_16(dev, ADIS16209_MSC_CTRL, msc);
+	ret = adis16209_spi_write_reg_16(indio_dev, ADIS16209_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16209_check_status(struct device *dev)
+static int adis16209_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
 
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_DIAG_STAT, &status);
+	ret = adis16209_spi_read_reg_16(indio_dev,
+					ADIS16209_DIAG_STAT, &status);
 	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
 	}
 	ret = status & 0x1F;
 
 	if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
+		dev_err(&indio_dev->dev, "Self test failure\n");
 	if (status & ADIS16209_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
+		dev_err(&indio_dev->dev, "SPI failure\n");
 	if (status & ADIS16209_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
+		dev_err(&indio_dev->dev, "Flash update failed\n");
 	if (status & ADIS16209_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
 	if (status & ADIS16209_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
 	return ret;
 }
 
-static int adis16209_self_test(struct device *dev)
+static int adis16209_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16209_spi_write_reg_16(dev,
+	ret = adis16209_spi_write_reg_16(indio_dev,
 			ADIS16209_MSC_CTRL,
 			ADIS16209_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16209_check_status(dev);
+	adis16209_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16209_initial_setup(struct adis16209_state *st)
+static int adis16209_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16209_set_irq(dev, false);
+	ret = adis16209_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16209_self_test(dev);
+	ret = adis16209_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16209_check_status(dev);
+	ret = adis16209_check_status(indio_dev);
 	if (ret) {
-		adis16209_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16209_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16209_STARTUP_DELAY);
-		ret = adis16209_check_status(dev);
+		ret = adis16209_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16209_read_14bit_unsigned,
-		ADIS16209_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.30518");
-static IIO_DEV_ATTR_IN_RAW(1, adis16209_read_12bit_unsigned,
-		ADIS16209_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.6105");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed,
-		ADIS16209_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed,
-		ADIS16209_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_XACCL_NULL);
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_YACCL_NULL);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.002394195531");
-
-static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed,
-		ADIS16209_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed,
-		ADIS16209_YINCL_OUT);
-static IIO_CONST_ATTR(incli_scale, "0.00043633231");
-
-static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
-		       NULL, ADIS16209_ROT_OUT);
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16209_read_temp);
-static IIO_CONST_ATTR_TEMP_OFFSET("25");
-static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
+enum adis16209_chan {
+	in_supply,
+	temp,
+	accel_x,
+	accel_y,
+	incli_x,
+	incli_y,
+	in_aux,
+	rot,
+};
+
+static const u8 adis16209_addresses[8][2] = {
+	[in_supply] = { ADIS16209_SUPPLY_OUT },
+	[in_aux] = { ADIS16209_AUX_ADC },
+	[accel_x] = { ADIS16209_XACCL_OUT, ADIS16209_XACCL_NULL },
+	[accel_y] = { ADIS16209_YACCL_OUT, ADIS16209_YACCL_NULL },
+	[incli_x] = { ADIS16209_XINCL_OUT, ADIS16209_XINCL_NULL },
+	[incli_y] = { ADIS16209_YINCL_OUT, ADIS16209_YINCL_NULL },
+	[rot] = { ADIS16209_ROT_OUT },
+	[temp] = { ADIS16209_TEMP_OUT },
+};
+
+static int adis16209_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+		case IIO_INCLI:
+			bits = 14;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16209_addresses[chan->address][1];
+		return adis16209_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static int adis16209_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16209_addresses[chan->address][0];
+		ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16209_ERROR_ACTIVE) {
+			ret = adis16209_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 305180;
+			else
+				*val2 = 610500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 2394;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 436;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 14;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16209_addresses[chan->address][1];
+		ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16209_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16209_SCAN_SUPPLY,
+		 IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16209_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16209_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16209_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16209_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 0, 1, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_x, ADIS16209_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 0, 1, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_y, ADIS16209_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ROT, 0, 1, 0, NULL, 0, IIO_MOD_X,
+		    0,
+		    rot, ADIS16209_SCAN_ROT,
+		    IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
 
 static struct attribute *adis16209_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
-	&iio_dev_attr_rot_raw.dev_attr.attr,
 	NULL
 };
 
@@ -486,6 +490,10 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16209_attribute_group;
+	st->indio_dev->channels = adis16209_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16209_channels);
+	st->indio_dev->read_raw = &adis16209_read_raw;
+	st->indio_dev->write_raw = &adis16209_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -499,7 +507,9 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16209_channels,
+					  ARRAY_SIZE(adis16209_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -512,7 +522,7 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16209_initial_setup(st);
+	ret = adis16209_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 6e66469..2c7be3b 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -17,60 +17,6 @@
 #include "../trigger.h"
 #include "adis16209.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY,
-		     ADIS16209_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 14, 16)
-static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, ADIS16209_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, ADIS16209_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, ADIS16209_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, ADIS16209_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X,
-		     ADIS16209_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y,
-		     ADIS16209_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, ADIS16209_ROT_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(rot, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16209_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_rot.dev_attr.attr,
-	&iio_const_attr_rot_index.dev_attr.attr,
-	&iio_const_attr_rot_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16209_scan_el_group = {
-	.attrs = adis16209_scan_el_attrs,
-	.name = "scan_elements",
-};
-
 /**
  * adis16209_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -171,7 +117,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16209_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -179,14 +124,14 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_rot.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_INCLI_Y);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ROT);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
index 86e83c3..0847ce5 100644
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ b/drivers/staging/iio/accel/adis16209_trigger.c
@@ -42,7 +42,7 @@ static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16209_set_irq(&st->indio_dev->dev, state);
+	return adis16209_set_irq(st->indio_dev, state);
 }
 
 int adis16209_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 060/111] staging:iio:adc:ad7887: Convert to new channel registration method.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (58 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 059/111] staging:iio:accel:adis16209 " Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 061/111] staging:iio:adc:ad7887: Use private data space from iio_allocate_device Jonathan Cameron
                   ` (51 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Convert to new channel registration method
Update / change license copyright header
Add missing call to iio_trigger_notify_done()

V2: use IIO_CHAN macro.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7887.h      |   14 ++--
 drivers/staging/iio/adc/ad7887_core.c |  123 ++++++++++++++-------------------
 drivers/staging/iio/adc/ad7887_ring.c |   68 ++----------------
 3 files changed, 67 insertions(+), 138 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index ffff403..a0c3742 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -48,12 +48,15 @@ struct ad7887_platform_data {
 	bool				use_onchip_ref;
 };
 
+/**
+ * struct ad7887_chip_info - chip specifc information
+ * @int_vref_mv:	the internal reference voltage
+ * @channel:		channel specification
+ */
+
 struct ad7887_chip_info {
-	u8				bits;		/* number of ADC bits */
-	u8				storagebits;	/* number of bits read from the ADC */
-	u8				left_shift;	/* number of bits the sample must be shifted */
-	char				sign;		/* [s]igned or [u]nsigned */
-	u16				int_vref_mv;	/* internal reference voltage */
+	u16				int_vref_mv;
+	struct iio_chan_spec		channel[3];
 };
 
 struct ad7887_state {
@@ -63,7 +66,6 @@ struct ad7887_state {
 	struct regulator		*reg;
 	size_t				d_size;
 	u16				int_vref_mv;
-	bool				en_dual;
 	struct spi_transfer		xfer[4];
 	struct spi_message		msg[3];
 	struct spi_message		*ring_msg;
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 27adff4..f394215 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -1,9 +1,9 @@
 /*
  * AD7887 SPI ADC driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 
 #include <linux/interrupt.h>
@@ -33,81 +33,55 @@ static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
 	return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1];
 }
 
-static ssize_t ad7887_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7887_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
+	struct ad7887_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7887_scan_from_ring(st, 1 << this_attr->address);
-	else
-		ret = ad7887_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (ret >> st->chip_info->left_shift) &
-		       RES_MASK(st->chip_info->bits));
-}
-static IIO_DEV_ATTR_IN_RAW(0, ad7887_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7887_scan, 1);
-
-static ssize_t ad7887_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0);
-
-static struct attribute *ad7887_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7887_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-
-	mode_t mode = attr->mode;
-
-	if ((attr == &iio_dev_attr_in1_raw.dev_attr.attr) && !st->en_dual)
-			mode = 0;
-
-	return mode;
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad7887_scan_from_ring(st, 1 << chan->address);
+		else
+			ret = ad7887_scan_direct(st, chan->address);
+		mutex_unlock(&dev_info->mlock);
+
+		if (ret < 0)
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv/1000;
+		*val2 = (scale_uv%1000)*1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
 
-static const struct attribute_group ad7887_attribute_group = {
-	.attrs = ad7887_attributes,
-	.is_visible = ad7887_attr_is_visible,
-};
 
 static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
 	/*
 	 * More devices added in future
 	 */
 	[ID_AD7887] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+
+		.channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
 		.int_vref_mv = 2500,
 	},
 };
@@ -149,8 +123,11 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 	/* Estabilish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad7887_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->channels = st->chip_info->channel;
+	st->indio_dev->num_channels = 3;
+	st->indio_dev->read_raw = &ad7887_read_raw;
+
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
@@ -196,8 +173,6 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 		spi_message_init(&st->msg[AD7887_CH1]);
 		spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
 
-		st->en_dual = true;
-
 		if (pdata && pdata->vref_mv)
 			st->int_vref_mv = pdata->vref_mv;
 		else if (voltage_uv)
@@ -205,6 +180,8 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
 
+		st->indio_dev->channels = st->chip_info->channel;
+		st->indio_dev->num_channels = 3;
 	} else {
 		if (pdata && pdata->vref_mv)
 			st->int_vref_mv = pdata->vref_mv;
@@ -212,8 +189,10 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 			st->int_vref_mv = st->chip_info->int_vref_mv;
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
-	}
 
+		st->indio_dev->channels = &st->chip_info->channel[1];
+		st->indio_dev->num_channels = 2;
+	}
 
 	ret = ad7887_register_ring_funcs_and_init(st->indio_dev);
 	if (ret)
@@ -223,7 +202,9 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 	if (ret)
 		goto error_free_device;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->indio_dev->channels,
+					  st->indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index df5a2ae..fa9ea73 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  * Copyright (C) 2008 Jonathan Cameron
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  *
  * ad7887_ring.c
  */
@@ -25,61 +25,6 @@
 
 #include "ad7887.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_TIMESTAMP(2);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7887_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->storagebits,
-		       st->chip_info->left_shift);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7887_show_type, NULL, 0);
-
-static struct attribute *ad7887_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7887_scan_el_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	mode_t mode = attr->mode;
-
-	if ((attr == &iio_scan_el_in1.dev_attr.attr) ||
-		(attr == &iio_const_attr_in1_index.dev_attr.attr))
-		if (!st->en_dual)
-			mode = 0;
-
-	return mode;
-}
-
-static struct attribute_group ad7887_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7887_scan_el_attrs,
-	.is_visible = ad7887_scan_el_attr_is_visible,
-};
-
 int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
@@ -124,7 +69,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
 	struct ad7887_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 
-	st->d_size = ring->scan_count * st->chip_info->storagebits / 8;
+	st->d_size = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		st->d_size += sizeof(s64);
@@ -179,7 +125,8 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 	__u8 *buf;
 	int b_sent;
 
-	unsigned int bytes = ring->scan_count * st->chip_info->storagebits / 8;
+	unsigned int bytes = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	buf = kzalloc(st->d_size, GFP_KERNEL);
 	if (buf == NULL)
@@ -199,6 +146,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 	indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns);
 done:
 	kfree(buf);
+	iio_trigger_notify_done(indio_dev->trig);
 
 	return IRQ_HANDLED;
 }
@@ -236,8 +184,6 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
 	indio_dev->ring->postdisable = &ad7887_ring_postdisable;
-	indio_dev->ring->scan_el_attrs = &ad7887_scan_el_group;
-	indio_dev->ring->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 061/111] staging:iio:adc:ad7887: Use private data space from iio_allocate_device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (59 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 060/111] staging:iio:adc:ad7887: Convert to new channel registration method Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 062/111] staging:iio:adc:ad799x: Convert to new channel registration method Jonathan Cameron
                   ` (50 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7887.h      |    1 -
 drivers/staging/iio/adc/ad7887_core.c |   83 ++++++++++++++------------------
 drivers/staging/iio/adc/ad7887_ring.c |    5 +--
 3 files changed, 37 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index a0c3742..837046c 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -60,7 +60,6 @@ struct ad7887_chip_info {
 };
 
 struct ad7887_state {
-	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	const struct ad7887_chip_info	*chip_info;
 	struct regulator		*reg;
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index f394215..6773fe1 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -6,13 +6,10 @@
  * Licensed under the GPL-2.
  */
 
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
@@ -90,13 +87,13 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 {
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
 	struct ad7887_state *st;
-	int ret, voltage_uv = 0;
+	int ret, voltage_uv = 0, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
 
 	st->reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -110,26 +107,16 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 	st->chip_info =
 		&ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 
-	spi_set_drvdata(spi, st);
-
+	spi_set_drvdata(spi, indio_dev);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
 	/* Estabilish that the iio_dev is a child of the spi device */
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->channels = st->chip_info->channel;
-	st->indio_dev->num_channels = 3;
-	st->indio_dev->read_raw = &ad7887_read_raw;
-
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->dev_data = (void *)(st);
+	indio_dev->read_raw = &ad7887_read_raw;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default message */
 
@@ -180,8 +167,8 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
 
-		st->indio_dev->channels = st->chip_info->channel;
-		st->indio_dev->num_channels = 3;
+		indio_dev->channels = st->chip_info->channel;
+		indio_dev->num_channels = 3;
 	} else {
 		if (pdata && pdata->vref_mv)
 			st->int_vref_mv = pdata->vref_mv;
@@ -190,53 +177,55 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
 
-		st->indio_dev->channels = &st->chip_info->channel[1];
-		st->indio_dev->num_channels = 2;
+		indio_dev->channels = &st->chip_info->channel[1];
+		indio_dev->num_channels = 2;
 	}
 
-	ret = ad7887_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7887_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
-					  st->indio_dev->channels,
-					  st->indio_dev->num_channels);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
 
 error_cleanup_ring:
-	ad7887_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
-error_free_device:
-	iio_free_device(st->indio_dev);
+	ad7887_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static int ad7887_remove(struct spi_device *spi)
 {
-	struct ad7887_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7887_state *st = iio_priv(indio_dev);
+
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7887_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index fa9ea73..113e97e 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -8,13 +8,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -27,7 +24,7 @@
 
 int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int count = 0, ret;
 	u16 *ring_data;
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 062/111] staging:iio:adc:ad799x: Convert to new channel registration method.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (60 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 061/111] staging:iio:adc:ad7887: Use private data space from iio_allocate_device Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 063/111] staging:iio:adc:ad799x: Use private data space from iio_allocate_device Jonathan Cameron
                   ` (49 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Convert to new channel registration method
Update copyright header
Add missing call to iio_trigger_notify_done()

V2: IIO_CHAN macro updates

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad799x.h      |   25 +-
 drivers/staging/iio/adc/ad799x_core.c |  491 +++++++++++++--------------------
 drivers/staging/iio/adc/ad799x_ring.c |    9 +-
 3 files changed, 206 insertions(+), 319 deletions(-)

diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index 331435a..2b2e1cb 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
+ * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
  * Copyright (C) 2008-2010 Jonathan Cameron
  *
  * This program is free software; you can redistribute it and/or modify
@@ -67,6 +67,8 @@
 
 #define AD7997_8_READ_SINGLE			0x80
 #define AD7997_8_READ_SEQUENCE			0x70
+/* TODO: move this into a common header */
+#define RES_MASK(bits)	((1 << (bits)) - 1)
 
 enum {
 	ad7991,
@@ -83,30 +85,21 @@ struct ad799x_state;
 
 /**
  * struct ad799x_chip_info - chip specifc information
- * @num_inputs:		number of physical inputs on chip
- * @bits:		accuracy of the adc in bits
+ * @channel:		channel specification
+ * @num_channels:	number of channels
  * @int_vref_mv:	the internal reference voltage
  * @monitor_mode:	whether the chip supports monitor interrupts
  * @default_config:	device default configuration
- * @dev_attrs:		pointer to the device attribute group
- * @scan_attrs:		pointer to the scan element attribute group
  * @event_attrs:	pointer to the monitor event attribute group
- * @ad799x_set_scan_mode: function pointer to the device specific mode function
-
  */
+
 struct ad799x_chip_info {
-	u8				num_inputs;
-	u8				bits;
-	u8				storagebits;
-	char				sign;
+	struct iio_chan_spec		channel[9];
+	int				num_channels;
 	u16				int_vref_mv;
 	bool				monitor_mode;
 	u16				default_config;
-	struct attribute_group		*dev_attrs;
-	struct attribute_group		*scan_attrs;
 	struct attribute_group		*event_attrs;
-	int (*ad799x_set_scan_mode)	(struct ad799x_state *st,
-					unsigned mask);
 };
 
 struct ad799x_state {
@@ -130,7 +123,7 @@ struct ad799x_platform_data {
 	u16				vref_mv;
 };
 
-int ad799x_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
 int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask);
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 3383a35..79580df 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -1,6 +1,6 @@
 /*
  * iio/adc/ad799x.c
- * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
+ * Copyright (C) 2010-1011 Michael Hennerich, Analog Devices Inc.
  *
  * based on iio/adc/max1363
  * Copyright (C) 2008-2010 Jonathan Cameron
@@ -100,130 +100,77 @@ static int ad799x_i2c_write8(struct ad799x_state *st, u8 reg, u8 data)
 	return ret;
 }
 
-static int ad799x_scan_el_set_state(struct iio_scan_el *scan_el,
-				       struct iio_dev *indio_dev,
-				       bool state)
-{
-	struct ad799x_state *st = indio_dev->dev_data;
-	return ad799x_set_scan_mode(st, st->indio_dev->ring->scan_mask);
-}
-
-/* Here we claim all are 16 bits. This currently does no harm and saves
- * us a lot of scan element listings */
-
-#define AD799X_SCAN_EL(number)						\
-	IIO_SCAN_EL_C(in##number, number, 0, ad799x_scan_el_set_state);
-
-static AD799X_SCAN_EL(0);
-static AD799X_SCAN_EL(1);
-static AD799X_SCAN_EL(2);
-static AD799X_SCAN_EL(3);
-static AD799X_SCAN_EL(4);
-static AD799X_SCAN_EL(5);
-static AD799X_SCAN_EL(6);
-static AD799X_SCAN_EL(7);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64)
-
-static ssize_t ad799x_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad799x_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d\n", st->chip_info->sign,
-		       st->chip_info->bits, AD799X_STORAGEBITS);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad799x_show_type, NULL, 0);
-
-static int ad7991_5_9_set_scan_mode(struct ad799x_state *st, unsigned mask)
-{
-	return i2c_smbus_write_byte(st->client,
-		st->config | (mask << AD799X_CHANNEL_SHIFT));
-}
-
-static int ad7992_3_4_set_scan_mode(struct ad799x_state *st, unsigned mask)
-{
-	return ad799x_i2c_write8(st, AD7998_CONF_REG,
-		st->config | (mask << AD799X_CHANNEL_SHIFT));
-}
-
-static int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask)
+int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask)
 {
 	return ad799x_i2c_write16(st, AD7998_CONF_REG,
 		st->config | (mask << AD799X_CHANNEL_SHIFT));
 }
 
-int ad799x_set_scan_mode(struct ad799x_state *st, unsigned mask)
+static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch)
 {
+	u16 rxbuf;
+	u8 cmd;
 	int ret;
 
-	if (st->chip_info->ad799x_set_scan_mode != NULL) {
-		ret = st->chip_info->ad799x_set_scan_mode(st, mask);
-		return (ret > 0) ? 0 : ret;
+	switch (st->id) {
+	case ad7991:
+	case ad7995:
+	case ad7999:
+		cmd = st->config | ((1 << ch) << AD799X_CHANNEL_SHIFT);
+		break;
+	case ad7992:
+	case ad7993:
+	case ad7994:
+		cmd = (1 << ch) << AD799X_CHANNEL_SHIFT;
+		break;
+	case ad7997:
+	case ad7998:
+		cmd = (ch << AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE;
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	return 0;
+	ret = ad799x_i2c_read16(st, cmd, &rxbuf);
+	if (ret < 0)
+		return ret;
+
+	return rxbuf;
 }
 
-static ssize_t ad799x_read_single_channel(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int ad799x_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret = 0, len = 0;
-	u32 data ;
-	u16 rxbuf[1];
-	u8 cmd;
-	long mask;
+	int ret;
+	struct ad799x_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad799x_single_channel_from_ring(st,
+				1 << chan->address);
+		else
+			ret = ad799x_scan_direct(st, chan->address);
+		mutex_unlock(&dev_info->mlock);
 
-	mutex_lock(&dev_info->mlock);
-	mask = 1 << this_attr->address;
-	/* If ring buffer capture is occurring, query the buffer */
-	if (iio_ring_enabled(dev_info)) {
-		data = ret = ad799x_single_channel_from_ring(st, mask);
-		if (ret < 0)
-			goto error_ret;
-		ret = 0;
-	} else {
-		switch (st->id) {
-		case ad7991:
-		case ad7995:
-		case ad7999:
-			cmd = st->config | (mask << AD799X_CHANNEL_SHIFT);
-			break;
-		case ad7992:
-		case ad7993:
-		case ad7994:
-			cmd = mask << AD799X_CHANNEL_SHIFT;
-			break;
-		case ad7997:
-		case ad7998:
-			cmd = (this_attr->address <<
-				AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE;
-			break;
-		default:
-			cmd = 0;
-
-		}
-		ret = ad799x_i2c_read16(st, cmd, rxbuf);
 		if (ret < 0)
-			goto error_ret;
-
-		data = rxbuf[0];
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
 	}
-
-	/* Pretty print the result */
-	len = sprintf(buf, "%u\n", data & ((1 << (st->chip_info->bits)) - 1));
-
-error_ret:
-	mutex_unlock(&dev_info->mlock);
-	return ret ? ret : len;
+	return -EINVAL;
 }
 
 static ssize_t ad799x_read_frequency(struct device *dev,
@@ -331,7 +278,6 @@ error_ret_mutex:
 	return ret ? ret : len;
 }
 
-
 static ssize_t ad799x_read_channel_config(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
@@ -400,140 +346,6 @@ static irqreturn_t ad799x_event_handler(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
-/* Direct read attribtues */
-static IIO_DEV_ATTR_IN_RAW(0, ad799x_read_single_channel, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad799x_read_single_channel, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad799x_read_single_channel, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad799x_read_single_channel, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad799x_read_single_channel, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad799x_read_single_channel, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad799x_read_single_channel, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad799x_read_single_channel, 7);
-
-static ssize_t ad799x_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, 0);
-
-static struct attribute *ad7991_5_9_3_4_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7991_5_9_3_4_dev_attr_group = {
-	.attrs = ad7991_5_9_3_4_device_attrs,
-};
-
-static struct attribute *ad7991_5_9_3_4_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7991_5_9_3_4_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7991_5_9_3_4_scan_el_attrs,
-};
-
-static struct attribute *ad7992_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7992_dev_attr_group = {
-	.attrs = ad7992_device_attrs,
-};
-
-static struct attribute *ad7992_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7992_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7992_scan_el_attrs,
-};
-
-static struct attribute *ad7997_8_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7997_8_dev_attr_group = {
-	.attrs = ad7997_8_device_attrs,
-};
-
-static struct attribute *ad7997_8_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7997_8_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7997_8_scan_el_attrs,
-};
-
 static IIO_DEVICE_ATTR(in0_thresh_low_value,
 		       S_IRUGO | S_IWUSR,
 		       ad799x_read_channel_config,
@@ -651,91 +463,173 @@ static struct attribute_group ad7992_event_attrs_group = {
 
 static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 	[ad7991] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 4096,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
 	},
 	[ad7995] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
 	},
 	[ad7999] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
 	},
 	[ad7992] = {
-		.num_inputs = 2,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
+		.num_channels = 3,
 		.int_vref_mv = 4096,
 		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7992_dev_attr_group,
-		.scan_attrs = &ad7992_scan_el_group,
 		.event_attrs = &ad7992_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
 	},
 	[ad7993] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
 		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
 		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
 	},
 	[ad7994] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 4096,
 		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
 		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
 	},
 	[ad7997] = {
-		.num_inputs = 8,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  4, 4, IIO_ST('u', 10, 16, 0), 0),
+		.channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  5, 5, IIO_ST('u', 10, 16, 0), 0),
+		.channel[6] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  6, 6, IIO_ST('u', 10, 16, 0), 0),
+		.channel[7] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  7, 7, IIO_ST('u', 10, 16, 0), 0),
+		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
+		.num_channels = 9,
 		.int_vref_mv = 1024,
 		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7997_8_dev_attr_group,
-		.scan_attrs = &ad7997_8_scan_el_group,
 		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7997_8_set_scan_mode,
 	},
 	[ad7998] = {
-		.num_inputs = 8,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       4, 4, IIO_ST('u', 12, 16, 0), 0),
+		.channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       5, 5, IIO_ST('u', 12, 16, 0), 0),
+		.channel[6] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       6, 6, IIO_ST('u', 12, 16, 0), 0),
+		.channel[7] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  7, 7, IIO_ST('u', 12, 16, 0), 0),
+		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
+		.num_channels = 9,
 		.int_vref_mv = 4096,
 		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7997_8_dev_attr_group,
-		.scan_attrs = &ad7997_8_scan_el_group,
 		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7997_8_set_scan_mode,
 	},
 };
 
@@ -778,19 +672,16 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 		goto error_disable_reg;
 	}
 
-	/* Estabilish that the iio_dev is a child of the i2c device */
 	st->indio_dev->dev.parent = &client->dev;
-	st->indio_dev->attrs = st->chip_info->dev_attrs;
 	st->indio_dev->event_attrs = st->chip_info->event_attrs;
 	st->indio_dev->name = id->name;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 	st->indio_dev->num_interrupt_lines = 1;
-
-	ret = ad799x_set_scan_mode(st, 0);
-	if (ret)
-		goto error_free_device;
+	st->indio_dev->channels = st->chip_info->channel;
+	st->indio_dev->num_channels = st->chip_info->num_channels;
+	st->indio_dev->read_raw = &ad799x_read_raw;
 
 	ret = ad799x_register_ring_funcs_and_init(st->indio_dev);
 	if (ret)
@@ -801,7 +692,9 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 		goto error_cleanup_ring;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->indio_dev->channels,
+					  st->indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index f0a0aae..488cbc4 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -80,7 +80,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
 	 */
 
 	if (st->id == ad7997 || st->id == ad7998)
-		ad799x_set_scan_mode(st, ring->scan_mask);
+		ad7997_8_set_scan_mode(st, ring->scan_mask);
 
 	st->d_size = ring->scan_count * 2;
 
@@ -119,7 +119,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
 
 	rxbuf = kmalloc(st->d_size, GFP_KERNEL);
 	if (rxbuf == NULL)
-		return -ENOMEM;
+		goto out;
 
 	switch (st->id) {
 	case ad7991:
@@ -157,6 +157,9 @@ done:
 	kfree(rxbuf);
 	if (b_sent < 0)
 		return b_sent;
+out:
+	iio_trigger_notify_done(indio_dev->trig);
+
 	return IRQ_HANDLED;
 }
 
@@ -195,8 +198,6 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
 	indio_dev->ring->scan_timestamp = true;
 
-	indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 063/111] staging:iio:adc:ad799x: Use private data space from iio_allocate_device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (61 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 062/111] staging:iio:adc:ad799x: Convert to new channel registration method Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 064/111] staging:iio:adc:ad799x removed unused headers Jonathan Cameron
                   ` (48 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Use private data space from iio_allocate_device

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad799x.h      |    1 -
 drivers/staging/iio/adc/ad799x_core.c |   78 +++++++++++++++------------------
 drivers/staging/iio/adc/ad799x_ring.c |    7 +--
 3 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index 2b2e1cb..0a8d6e2 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -103,7 +103,6 @@ struct ad799x_chip_info {
 };
 
 struct ad799x_state {
-	struct iio_dev			*indio_dev;
 	struct i2c_client		*client;
 	const struct ad799x_chip_info	*chip_info;
 	size_t				d_size;
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 79580df..94bd808 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -638,14 +638,15 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 {
 	int ret, regdone = 0;
 	struct ad799x_platform_data *pdata = client->dev.platform_data;
-	struct ad799x_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	struct ad799x_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+
+	if (indio_dev == NULL)
+		return -ENOMEM;
 
+	st = iio_priv(indio_dev);
 	/* this is only used for device removal purposes */
-	i2c_set_clientdata(client, st);
+	i2c_set_clientdata(client, indio_dev);
 
 	st->id = id->driver_data;
 	st->chip_info = &ad799x_chip_info_tbl[st->id];
@@ -666,35 +667,30 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 	}
 	st->client = client;
 
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	st->indio_dev->dev.parent = &client->dev;
-	st->indio_dev->event_attrs = st->chip_info->event_attrs;
-	st->indio_dev->name = id->name;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->channels = st->chip_info->channel;
-	st->indio_dev->num_channels = st->chip_info->num_channels;
-	st->indio_dev->read_raw = &ad799x_read_raw;
-
-	ret = ad799x_register_ring_funcs_and_init(st->indio_dev);
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
+	indio_dev->event_attrs = st->chip_info->event_attrs;
+	indio_dev->name = id->name;
+	indio_dev->dev_data = (void *)(st);
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->num_interrupt_lines = 1;
+	indio_dev->channels = st->chip_info->channel;
+	indio_dev->num_channels = st->chip_info->num_channels;
+	indio_dev->read_raw = &ad799x_read_raw;
+
+	ret = ad799x_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_cleanup_ring;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
-					  st->indio_dev->channels,
-					  st->indio_dev->num_channels);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
@@ -705,46 +701,44 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 					   IRQF_TRIGGER_FALLING |
 					   IRQF_ONESHOT,
 					   client->name,
-					   st->indio_dev);
+					   indio_dev);
 		if (ret)
 			goto error_cleanup_ring;
 	}
 
 	return 0;
+
 error_cleanup_ring:
-	ad799x_ring_cleanup(st->indio_dev);
-error_free_device:
-	if (!regdone)
-		iio_free_device(st->indio_dev);
-	else
-		iio_device_unregister(st->indio_dev);
+	ad799x_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static __devexit int ad799x_remove(struct i2c_client *client)
 {
-	struct ad799x_state *st = i2c_get_clientdata(client);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct ad799x_state *st = iio_priv(indio_dev);
 
 	if (client->irq > 0 && st->chip_info->monitor_mode)
 		free_irq(client->irq, indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad799x_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
 
 	return 0;
 }
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 488cbc4..c925318 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -29,7 +29,7 @@
 
 int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int count = 0, ret;
 	u16 *ring_data;
 
@@ -72,7 +72,7 @@ error_ret:
 static int ad799x_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct ad799x_state *st = indio_dev->dev_data;
+	struct ad799x_state *st = iio_dev_get_devdata(indio_dev);
 
 	/*
 	 * Need to figure out the current mode based upon the requested
@@ -166,7 +166,6 @@ out:
 
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad799x_state *st = indio_dev->dev_data;
 	int ret = 0;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -175,7 +174,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
+	iio_ring_sw_register_funcs(&indio_dev->ring->access);
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 064/111] staging:iio:adc:ad799x removed unused headers.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (62 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 063/111] staging:iio:adc:ad799x: Use private data space from iio_allocate_device Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 065/111] staging:iio:adc:ad7298: Convert to new channel registration method Jonathan Cameron
                   ` (47 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad799x_core.c |    2 --
 drivers/staging/iio/adc/ad799x_ring.c |    1 -
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 94bd808..a105910 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -23,11 +23,9 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index c925318..6906568 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -10,7 +10,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 065/111] staging:iio:adc:ad7298: Convert to new channel registration method
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (63 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 064/111] staging:iio:adc:ad799x removed unused headers Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 066/111] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
                   ` (46 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Convert to new channel registration method Update
Add missing call to iio_trigger_notify_done()

Backported to a point that will allow the driver to build all the
way through the series.

V2: IIO_CHAN macro usage updated.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7298.h      |    5 +-
 drivers/staging/iio/adc/ad7298_core.c |  171 +++++++++++++++++++--------------
 drivers/staging/iio/adc/ad7298_ring.c |   50 +---------
 3 files changed, 103 insertions(+), 123 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h
index 8d149c8..718e56a 100644
--- a/drivers/staging/iio/adc/ad7298.h
+++ b/drivers/staging/iio/adc/ad7298.h
@@ -17,14 +17,13 @@
 #define AD7298_TAVG	(1 << 1) /* temperature sensor averaging enable */
 #define AD7298_PDD	(1 << 0) /* partial power down enable */
 
-#define AD7298_CH_MASK	(AD7298_CH0 | AD7298_CH1 | AD7298_CH2 | AD7298_CH3 | \
-			AD7298_CH4 | AD7298_CH5 | AD7298_CH6 | AD7298_CH7)
-
 #define AD7298_MAX_CHAN		8
 #define AD7298_BITS		12
 #define AD7298_STORAGE_BITS	16
 #define AD7298_INTREF_mV	2500
 
+#define AD7298_CH_TEMP		9
+
 #define RES_MASK(bits)	((1 << (bits)) - 1)
 
 /*
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index d43f63d..35a30ae 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -22,6 +22,37 @@
 
 #include "ad7298.h"
 
+static struct iio_chan_spec ad7298_channels[] = {
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 6, 6, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 7, 7, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
 static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
 {
 	int ret;
@@ -35,55 +66,28 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
 	return be16_to_cpu(st->rx_buf[0]);
 }
 
-static ssize_t ad7298_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7298_scan_temp(struct ad7298_state *st, int *val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
+	int tmp, ret;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7298_scan_from_ring(st, this_attr->address);
-	else
-		ret = ad7298_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
+	tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
+			  AD7298_TAVG | st->ext_ref);
 
-	if (ret < 0)
+	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	if (ret)
 		return ret;
 
-	return sprintf(buf, "%d\n", ret & RES_MASK(AD7298_BITS));
-}
-
-static IIO_DEV_ATTR_IN_RAW(0, ad7298_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7298_scan, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad7298_scan, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad7298_scan, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad7298_scan, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad7298_scan, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad7298_scan, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad7298_scan, 7);
-
-static ssize_t ad7298_show_temp(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
-	int tmp;
+	tmp = 0;
 
-	tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
-			  AD7298_TAVG | st->ext_ref);
+	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	if (ret)
+		return ret;
 
-	mutex_lock(&dev_info->mlock);
-	spi_write(st->spi, (u8 *)&tmp, 2);
-	tmp = 0;
-	spi_write(st->spi, (u8 *)&tmp, 2);
 	usleep_range(101, 1000); /* sleep > 100us */
-	spi_read(st->spi, (u8 *)&tmp, 2);
-	mutex_unlock(&dev_info->mlock);
+
+	ret = spi_read(st->spi, (u8 *)&tmp, 2);
+	if (ret)
+		return ret;
 
 	tmp = be16_to_cpu(tmp) & RES_MASK(AD7298_BITS);
 
@@ -100,41 +104,56 @@ static ssize_t ad7298_show_temp(struct device *dev,
 		tmp *= 250; /* temperature in milli degrees Celsius */
 	}
 
-	return sprintf(buf, "%d\n", tmp);
-}
+	*val = tmp;
 
-static IIO_DEVICE_ATTR(temp0_input, S_IRUGO, ad7298_show_temp, NULL, 0);
+	return 0;
+}
 
-static ssize_t ad7298_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
+static int ad7298_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
+	int ret;
+	struct ad7298_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info)) {
+			if (chan->address == AD7298_CH_TEMP)
+				ret = -ENODEV;
+			else
+				ret = ad7298_scan_from_ring(st, chan->address);
+		} else {
+			if (chan->address == AD7298_CH_TEMP)
+				ret = ad7298_scan_temp(st, val);
+			else
+				ret = ad7298_scan_direct(st, chan->address);
+		}
+		mutex_unlock(&dev_info->mlock);
+
+		if (ret < 0)
+			return ret;
+
+		if (chan->address != AD7298_CH_TEMP)
+			*val = ret & RES_MASK(AD7298_BITS);
+
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		*val =  1;
+		*val2 = 0;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7298_show_scale, NULL, 0);
-
-static struct attribute *ad7298_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_temp0_input.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7298_attribute_group = {
-	.attrs = ad7298_attributes,
-};
 
 static int __devinit ad7298_probe(struct spi_device *spi)
 {
@@ -167,10 +186,12 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad7298_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	st->indio_dev->channels = ad7298_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
+	st->indio_dev->read_raw = &ad7298_read_raw;
 
 	/* Setup default message */
 
@@ -203,7 +224,9 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 	if (ret)
 		goto error_free_device;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  &ad7298_channels[1], /* skip temp0 */
+					  ARRAY_SIZE(ad7298_channels) - 1);
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 1b9752c..d3251f7 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -21,49 +21,6 @@
 
 #include "ad7298.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_C(in2, 2, 0, NULL);
-static IIO_SCAN_EL_C(in3, 3, 0, NULL);
-static IIO_SCAN_EL_C(in4, 4, 0, NULL);
-static IIO_SCAN_EL_C(in5, 5, 0, NULL);
-static IIO_SCAN_EL_C(in6, 6, 0, NULL);
-static IIO_SCAN_EL_C(in7, 7, 0, NULL);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static IIO_CONST_ATTR(in_type, "u12/16") ;
-
-static struct attribute *ad7298_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_const_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7298_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7298_scan_el_attrs,
-};
-
 int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
@@ -75,7 +32,8 @@ int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
@@ -183,6 +141,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
 		buf[i] = be16_to_cpu(st->rx_buf[i]);
 
 	indio_dev->ring->access.store_to(ring, (u8 *)buf, time_ns);
+	iio_trigger_notify_done(indio_dev->trig);
 
 	return IRQ_HANDLED;
 }
@@ -214,11 +173,10 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_free_poll_func;
 	}
 	/* Ring buffer functions - here trigger setup related */
-
 	indio_dev->ring->preenable = &ad7298_ring_preenable;
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7298_scan_el_group;
+
 	indio_dev->ring->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 066/111] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (64 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 065/111] staging:iio:adc:ad7298: Convert to new channel registration method Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 067/111] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
                   ` (45 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This was missed out in original chan_spec conversion.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq_core.c |   29 ++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index a6b4631..8793ee4 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -218,6 +218,34 @@ static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
 					   value);
 }
 
+static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int ret = -EINVAL, reg;
+	u8 uval;
+	s8 sval;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		if (val > 255 || val < -256)
+			return -EINVAL;
+		sval = val;
+		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, (u8 *)&sval);
+		break;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		if (val & ~0xFF)
+			return -EINVAL;
+		uval = val;
+		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, &uval);
+		break;
+	}
+	return ret;
+}
+
 static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 			      struct iio_chan_spec const *chan,
 			      int *val,
@@ -692,6 +720,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 	st->help.indio_dev->channels = lis3l02dq_channels;
 	st->help.indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
 	st->help.indio_dev->read_raw = &lis3l02dq_read_raw;
+	st->help.indio_dev->write_raw = &lis3l02dq_write_raw;
 	st->help.indio_dev->read_event_value = &lis3l02dq_read_thresh;
 	st->help.indio_dev->write_event_value = &lis3l02dq_write_thresh;
 	st->help.indio_dev->write_event_config = &lis3l02dq_write_event_config;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 067/111] staging:iio: Add chan info support for 'peak_raw' attributes.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (65 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 066/111] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 068/111] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
                   ` (44 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    6 +++++-
 drivers/staging/iio/industrialio-core.c |    2 ++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index c6b471c..1a6bedc 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -73,7 +73,11 @@ enum iio_chan_info_enum {
 	IIO_CHAN_INFO_CALIBSCALE_SHARED,
 	IIO_CHAN_INFO_CALIBSCALE_SEPARATE,
 	IIO_CHAN_INFO_CALIBBIAS_SHARED,
-	IIO_CHAN_INFO_CALIBBIAS_SEPARATE
+	IIO_CHAN_INFO_CALIBBIAS_SEPARATE,
+	IIO_CHAN_INFO_PEAK_SHARED,
+	IIO_CHAN_INFO_PEAK_SEPARATE,
+	IIO_CHAN_INFO_PEAK_SCALE_SHARED,
+	IIO_CHAN_INFO_PEAK_SCALE_SEPARATE,
 };
 
 /**
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index e943dac..e3582c9 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -80,6 +80,8 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_OFFSET_SHARED/2] = "offset",
 	[IIO_CHAN_INFO_CALIBSCALE_SHARED/2] = "calibscale",
 	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
+	[IIO_CHAN_INFO_PEAK_SHARED/2] = "peak_raw",
+	[IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale",
 };
 
 int iio_push_event(struct iio_dev *dev_info,
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 068/111] staging:iio:accel:adis16240 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (66 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 067/111] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:41 ` [PATCH 069/111] staging:iio:gyro:adis16260 " Jonathan Cameron
                   ` (43 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

For clean drivers its easier to convert to chan_spec based
registration than to work around the scan_el attributes
going away.

Some minor cleanups done whilst here.

Untested.
V2: IIO_CHAN macro use updated.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16240.h         |    2 +-
 drivers/staging/iio/accel/adis16240_core.c    |  360 +++++++++++++++----------
 drivers/staging/iio/accel/adis16240_ring.c    |   55 +----
 drivers/staging/iio/accel/adis16240_trigger.c |    2 +-
 4 files changed, 220 insertions(+), 199 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h
index 364aabf..162b1f4 100644
--- a/drivers/staging/iio/accel/adis16240.h
+++ b/drivers/staging/iio/accel/adis16240.h
@@ -141,7 +141,7 @@ struct adis16240_state {
 	struct mutex			buf_lock;
 };
 
-int adis16240_set_irq(struct device *dev, bool enable);
+int adis16240_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 6350c7c..537e0f2 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -28,20 +28,19 @@
 
 #define DRIVER_NAME		"adis16240"
 
-static int adis16240_check_status(struct device *dev);
+static int adis16240_check_status(struct iio_dev *indio_dev);
 
 /**
  * adis16240_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev associated with device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16240_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +55,17 @@ static int adis16240_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16240_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +78,6 @@ static int adis16240_spi_write_reg_16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 35,
 		},
 	};
@@ -102,17 +99,16 @@ static int adis16240_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16240_spi_read_reg_16(struct device *dev,
+static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -159,61 +155,30 @@ static ssize_t adis16240_spi_read_signed(struct device *dev,
 		char *buf,
 		unsigned bits)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret;
 	s16 val = 0;
 	unsigned shift = 16 - bits;
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
-	ret = adis16240_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					this_attr->address, (u16 *)&val);
 	if (ret)
 		return ret;
 
 	if (val & ADIS16240_ERROR_ACTIVE)
-		adis16240_check_status(dev);
+		adis16240_check_status(indio_dev);
 
 	val = ((s16)(val << shift) >> shift);
 	return sprintf(buf, "%d\n", val);
 }
 
-static ssize_t adis16240_read_10bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16240_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16240_ERROR_ACTIVE)
-		adis16240_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x03FF);
-}
-
-static ssize_t adis16240_read_10bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16240_spi_read_signed(dev, attr, buf, 10);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
 static ssize_t adis16240_read_12bit_signed(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	ssize_t ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
 	/* Take the iio_dev status lock */
 	mutex_lock(&indio_dev->mlock);
@@ -223,32 +188,14 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev,
 	return ret;
 }
 
-static ssize_t adis16240_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16240_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16240_reset(struct device *dev)
+static int adis16240_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16240_spi_write_reg_8(dev,
+	ret = adis16240_spi_write_reg_8(indio_dev,
 			ADIS16240_GLOB_CMD,
 			ADIS16240_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -257,23 +204,26 @@ static ssize_t adis16240_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16240_reset(dev);
+		return adis16240_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16240_set_irq(struct device *dev, bool enable)
+int adis16240_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16240_spi_read_reg_16(dev, ADIS16240_MSC_CTRL, &msc);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					ADIS16240_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -284,37 +234,40 @@ int adis16240_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16240_spi_write_reg_16(dev, ADIS16240_MSC_CTRL, msc);
+	ret = adis16240_spi_write_reg_16(indio_dev,
+					 ADIS16240_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16240_self_test(struct device *dev)
+static int adis16240_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16240_spi_write_reg_16(dev,
+	ret = adis16240_spi_write_reg_16(indio_dev,
 			ADIS16240_MSC_CTRL,
 			ADIS16240_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
 	msleep(ADIS16240_STARTUP_DELAY);
 
-	adis16240_check_status(dev);
+	adis16240_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16240_check_status(struct device *dev)
+static int adis16240_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16240_spi_read_reg_16(dev, ADIS16240_DIAG_STAT, &status);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					ADIS16240_DIAG_STAT, &status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -337,109 +290,214 @@ error_ret:
 	return ret;
 }
 
-static int adis16240_initial_setup(struct adis16240_state *st)
+static int adis16240_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16240_set_irq(dev, false);
+	ret = adis16240_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16240_self_test(dev);
+	ret = adis16240_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16240_check_status(dev);
+	ret = adis16240_check_status(indio_dev);
 	if (ret) {
-		adis16240_reset(dev);
+		adis16240_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16240_STARTUP_DELAY);
-		ret = adis16240_check_status(dev);
+		ret = adis16240_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16240_read_10bit_unsigned,
-		ADIS16240_SUPPLY_OUT);
-static IIO_DEV_ATTR_IN_RAW(1, adis16240_read_10bit_signed,
-		ADIS16240_AUX_ADC);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.00488");
-
-static IIO_CONST_ATTR_ACCEL_SCALE("0.50406181");
-static IIO_CONST_ATTR(accel_peak_scale, "6.6292954");
-static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed,
-		ADIS16240_XACCL_OUT);
-static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_XPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16240_read_10bit_signed,
-		ADIS16240_YACCL_OUT);
-static IIO_DEVICE_ATTR(accel_y_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_YPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16240_read_10bit_signed,
-		ADIS16240_ZACCL_OUT);
-static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_ZPEAK_OUT);
-
 static IIO_DEVICE_ATTR(accel_xyz_squared_peak_raw, S_IRUGO,
 		       adis16240_read_12bit_signed, NULL,
 		       ADIS16240_XYZPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_YACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_ZACCL_OFF);
-static IIO_DEV_ATTR_TEMP_RAW(adis16240_read_10bit_unsigned);
-static IIO_CONST_ATTR_TEMP_SCALE("0.244");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
 
+enum adis16240_chan {
+	in_supply,
+	in_aux,
+	accel_x,
+	accel_y,
+	accel_z,
+	temp,
+};
+
+static const u8 adis16240_addresses[6][3] = {
+	[in_supply] = { ADIS16240_SUPPLY_OUT },
+	[in_aux] = { ADIS16240_AUX_ADC },
+	[accel_x] = { ADIS16240_XACCL_OUT, ADIS16240_XACCL_OFF,
+		      ADIS16240_XPEAK_OUT },
+	[accel_y] = { ADIS16240_YACCL_OUT, ADIS16240_YACCL_OFF,
+		      ADIS16240_YPEAK_OUT },
+	[accel_z] = { ADIS16240_ZACCL_OUT, ADIS16240_ZACCL_OFF,
+		      ADIS16240_ZPEAK_OUT },
+	[temp] = { ADIS16240_TEMP_OUT },
+};
+
+static int adis16240_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][0];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16240_ERROR_ACTIVE) {
+			ret = adis16240_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 4880;
+			else
+				return -EINVAL;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 244000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 504062;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_PEAK_SCALE_SHARED):
+		*val = 6;
+		*val2 = 629295;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		bits = 10;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][1];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_PEAK_SEPARATE):
+		bits = 10;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][2];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16240_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits = 10;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16240_addresses[chan->address][1];
+		return adis16240_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16240_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16240_SCAN_SUPPLY,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 0,
+		 in_aux, ADIS16240_SCAN_AUX_ADC,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16240_SCAN_ACC_X,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16240_SCAN_ACC_Y,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_z, ADIS16240_SCAN_ACC_Z,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 temp, ADIS16240_SCAN_TEMP,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(6)
+};
+
 static struct attribute *adis16240_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_const_attr_accel_peak_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_peak_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_peak_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_peak_raw.dev_attr.attr,
 	&iio_dev_attr_accel_xyz_squared_peak_raw.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
 	NULL
@@ -483,6 +541,10 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->attrs = &adis16240_attribute_group;
+	st->indio_dev->channels = adis16240_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16240_channels);
+	st->indio_dev->read_raw = &adis16240_read_raw;
+	st->indio_dev->write_raw = &adis16240_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -496,7 +558,9 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16240_channels,
+					  ARRAY_SIZE(adis16240_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -509,7 +573,7 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16240_initial_setup(st);
+	ret = adis16240_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index a6d27d21..bddd699 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -17,48 +17,6 @@
 #include "../trigger.h"
 #include "adis16240.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY,
-		ADIS16240_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 10, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, ADIS16240_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, ADIS16240_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, ADIS16240_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 10, 16);
-static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, ADIS16240_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 10, 16);
-static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, ADIS16240_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 10, 16);
-static IIO_SCAN_EL_TIMESTAMP(6);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16240_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16240_scan_el_group = {
-	.attrs = adis16240_scan_el_attrs,
-	.name = "scan_elements",
-};
-
 /**
  * adis16240_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -156,7 +114,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16240_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -164,12 +121,12 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Z);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_TEMP);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c
index 55e2145..d5bda92 100644
--- a/drivers/staging/iio/accel/adis16240_trigger.c
+++ b/drivers/staging/iio/accel/adis16240_trigger.c
@@ -42,7 +42,7 @@ static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16240_set_irq(&st->indio_dev->dev, state);
+	return adis16240_set_irq(st->indio_dev, state);
 }
 
 int adis16240_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 069/111] staging:iio:gyro:adis16260 move to chan_spec based setup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (67 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 068/111] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
@ 2011-05-18 13:41 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 070/111] staging:iio:adc:ad7606 Convert to new channel registration method Update Add missing call to iio_trigger_notify_done() Set pollfunc top and bottom half handler Jonathan Cameron
                   ` (42 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:41 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

For clean drivers its easier to convert to chan_spec based
registration than to work around the scan_el attributes
going away.

Some minor cleanups done whilst here.

Untested.
V3: rebase fixup and make attribute_group static.

V2: IIO_CHAN macro updates.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/gyro/adis16260.h         |    2 +-
 drivers/staging/iio/gyro/adis16260_core.c    |  450 +++++++++++++-------------
 drivers/staging/iio/gyro/adis16260_ring.c    |   51 +---
 drivers/staging/iio/gyro/adis16260_trigger.c |    2 +-
 4 files changed, 239 insertions(+), 266 deletions(-)

diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
index 5325c68..702dc98 100644
--- a/drivers/staging/iio/gyro/adis16260.h
+++ b/drivers/staging/iio/gyro/adis16260.h
@@ -102,7 +102,7 @@ struct adis16260_state {
 	unsigned			negate:1;
 };
 
-int adis16260_set_irq(struct device *dev, bool enable);
+int adis16260_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 3366bd0..0eb6a87 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -28,20 +28,19 @@
 
 #define DRIVER_NAME		"adis16260"
 
-static int adis16260_check_status(struct device *dev);
+static int adis16260_check_status(struct iio_dev *indio_dev);
 
 /**
  * adis16260_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16260_spi_write_reg_8(struct device *dev,
+static int adis16260_spi_write_reg_8(struct iio_dev *indio_dev,
 		u8 reg_address,
 		u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +55,17 @@ static int adis16260_spi_write_reg_8(struct device *dev,
 
 /**
  * adis16260_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16260_spi_write_reg_16(struct device *dev,
+static int adis16260_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +78,6 @@ static int adis16260_spi_write_reg_16(struct device *dev,
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -102,17 +99,16 @@ static int adis16260_spi_write_reg_16(struct device *dev,
 
 /**
  * adis16260_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16260_spi_read_reg_16(struct device *dev,
+static int adis16260_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -126,7 +122,6 @@ static int adis16260_spi_read_reg_16(struct device *dev,
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -152,92 +147,6 @@ error_ret:
 	return ret;
 }
 
-static ssize_t adis16260_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16260_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16260_ERROR_ACTIVE)
-		adis16260_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16260_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16260_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16260_ERROR_ACTIVE)
-		adis16260_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16260_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16260_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16260_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16260_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16260_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16260_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static ssize_t adis16260_read_frequency_available(struct device *dev,
 						  struct device_attribute *attr,
 						  char *buf)
@@ -259,7 +168,7 @@ static ssize_t adis16260_read_frequency(struct device *dev,
 	int ret, len = 0;
 	u16 t;
 	int sps;
-	ret = adis16260_spi_read_reg_16(dev,
+	ret = adis16260_spi_read_reg_16(indio_dev,
 			ADIS16260_SMPL_PRD,
 			&t);
 	if (ret)
@@ -305,7 +214,7 @@ static ssize_t adis16260_write_frequency(struct device *dev,
 		st->us->max_speed_hz = ADIS16260_SPI_SLOW;
 	else
 		st->us->max_speed_hz = ADIS16260_SPI_FAST;
-	ret = adis16260_spi_write_reg_8(dev,
+	ret = adis16260_spi_write_reg_8(indio_dev,
 			ADIS16260_SMPL_PRD,
 			t);
 
@@ -314,33 +223,14 @@ static ssize_t adis16260_write_frequency(struct device *dev,
 	return ret ? ret : len;
 }
 
-static ssize_t adis16260_read_gyro_scale(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
-	ssize_t ret = 0;
-
-	if (st->negate)
-		ret = sprintf(buf, "-");
-	/* Take the iio_dev status lock */
-	if (spi_get_device_id(st->us)->driver_data)
-		ret += sprintf(buf + ret, "%s\n", "0.00031974432");
-	else
-		ret += sprintf(buf + ret, "%s\n", "0.00127862821");
-
-	return ret;
-}
-
-static int adis16260_reset(struct device *dev)
+static int adis16260_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16260_spi_write_reg_8(dev,
+	ret = adis16260_spi_write_reg_8(indio_dev,
 			ADIS16260_GLOB_CMD,
 			ADIS16260_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -349,22 +239,23 @@ static ssize_t adis16260_write_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16260_reset(dev);
+		return adis16260_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16260_set_irq(struct device *dev, bool enable)
+int adis16260_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret;
 	u16 msc;
-	ret = adis16260_spi_read_reg_16(dev, ADIS16260_MSC_CTRL, &msc);
+	ret = adis16260_spi_read_reg_16(indio_dev, ADIS16260_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -374,7 +265,7 @@ int adis16260_set_irq(struct device *dev, bool enable)
 	else
 		msc &= ~ADIS16260_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16260_spi_write_reg_16(dev, ADIS16260_MSC_CTRL, msc);
+	ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_MSC_CTRL, msc);
 	if (ret)
 		goto error_ret;
 
@@ -383,41 +274,44 @@ error_ret:
 }
 
 /* Power down the device */
-static int adis16260_stop_device(struct device *dev)
+static int adis16260_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
 
-	ret = adis16260_spi_write_reg_16(dev, ADIS16260_SLP_CNT, val);
+	ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_SLP_CNT, val);
 	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
+		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
 
 	return ret;
 }
 
-static int adis16260_self_test(struct device *dev)
+static int adis16260_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16260_spi_write_reg_16(dev,
+	ret = adis16260_spi_write_reg_16(indio_dev,
 			ADIS16260_MSC_CTRL,
 			ADIS16260_MSC_CTRL_MEM_TEST);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16260_check_status(dev);
+	adis16260_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16260_check_status(struct device *dev)
+static int adis16260_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16260_spi_read_reg_16(dev, ADIS16260_DIAG_STAT, &status);
+	ret = adis16260_spi_read_reg_16(indio_dev,
+					ADIS16260_DIAG_STAT,
+					&status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -443,119 +337,233 @@ error_ret:
 	return ret;
 }
 
-static int adis16260_initial_setup(struct adis16260_state *st)
+static int adis16260_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16260_set_irq(dev, false);
+	ret = adis16260_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16260_self_test(dev);
+	ret = adis16260_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16260_check_status(dev);
+	ret = adis16260_check_status(indio_dev);
 	if (ret) {
-		adis16260_reset(dev);
+		adis16260_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16260_STARTUP_DELAY);
-		ret = adis16260_check_status(dev);
+		ret = adis16260_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply,
-				adis16260_read_12bit_unsigned,
-				ADIS16260_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.0018315");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16260_read_12bit_unsigned);
-static IIO_CONST_ATTR_TEMP_OFFSET("25");
-static IIO_CONST_ATTR_TEMP_SCALE("0.1453");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16260_read_12bit_unsigned,
-		ADIS16260_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.0006105");
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16260_read_frequency,
 		adis16260_write_frequency);
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
 
-
 static IIO_DEVICE_ATTR(sampling_frequency_available,
 		       S_IRUGO, adis16260_read_frequency_available, NULL, 0);
 
-#define ADIS16260_GYRO_ATTR_SET(axis)					\
-	IIO_DEV_ATTR_GYRO##axis(adis16260_read_14bit_signed,		\
-				ADIS16260_GYRO_OUT);			\
-	static IIO_DEV_ATTR_GYRO##axis##_SCALE(S_IRUGO,			\
-					adis16260_read_gyro_scale,	\
-					NULL,				\
-					0);				\
-	static IIO_DEV_ATTR_GYRO##axis##_CALIBSCALE(S_IRUGO | S_IWUSR,	\
-					adis16260_read_12bit_unsigned,	\
-					adis16260_write_16bit,		\
-					ADIS16260_GYRO_SCALE);		\
-	static IIO_DEV_ATTR_GYRO##axis##_CALIBBIAS(S_IWUSR | S_IRUGO,	\
-					adis16260_read_12bit_signed,	\
-					adis16260_write_16bit,		\
-					ADIS16260_GYRO_OFF);		\
-	static IIO_DEV_ATTR_ANGL##axis(adis16260_read_14bit_signed,	\
-				       ADIS16260_ANGL_OUT);
-
-static ADIS16260_GYRO_ATTR_SET();
-static ADIS16260_GYRO_ATTR_SET(_X);
-static ADIS16260_GYRO_ATTR_SET(_Y);
-static ADIS16260_GYRO_ATTR_SET(_Z);
-
-#define ADIS16260_ATTR_GROUP(axis)					\
-	struct attribute *adis16260_attributes##axis[] = {		\
-		&iio_dev_attr_in0_supply_raw.dev_attr.attr,		\
-		&iio_const_attr_in0_supply_scale.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_raw.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_scale.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_calibscale.dev_attr.attr,	\
-		&iio_dev_attr_gyro##axis##_calibbias.dev_attr.attr,	\
-		&iio_dev_attr_angl##axis##_raw.dev_attr.attr,		\
-		&iio_dev_attr_temp_raw.dev_attr.attr,			\
-		&iio_const_attr_temp_offset.dev_attr.attr,		\
-		&iio_const_attr_temp_scale.dev_attr.attr,		\
-		&iio_dev_attr_in1_raw.dev_attr.attr,			\
-		&iio_const_attr_in1_scale.dev_attr.attr,		\
-		&iio_dev_attr_sampling_frequency.dev_attr.attr,		\
-		&iio_dev_attr_sampling_frequency_available.dev_attr.attr, \
-		&iio_dev_attr_reset.dev_attr.attr,			\
-		NULL							\
-	};								\
-	static const struct attribute_group adis16260_attribute_group##axis \
-	= {								\
-		.attrs = adis16260_attributes##axis,			\
-	};
+enum adis16260_channel {
+	gyro,
+	temp,
+	in_supply,
+	in_aux,
+	angle,
+};
+#define ADIS16260_GYRO_CHANNEL_SET(axis, mod)				\
+	struct iio_chan_spec adis16260_channels_##axis[] = {		\
+		IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, mod,		\
+			 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |	\
+			 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 gyro, ADIS16260_SCAN_GYRO,			\
+			 IIO_ST('s', 14, 16, 0), 0),			\
+		IIO_CHAN(IIO_ANGL, 1, 0, 0, NULL, 0, mod,		\
+			 0,						\
+			 angle, ADIS16260_SCAN_ANGL,			\
+			 IIO_ST('u', 14, 16, 0), 0),			\
+		IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,			\
+			 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |		\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 temp, ADIS16260_SCAN_TEMP,			\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,		\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 in_supply, ADIS16260_SCAN_SUPPLY,		\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,			\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 in_aux, ADIS16260_SCAN_AUX_ADC,		\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN_SOFT_TIMESTAMP(5)				\
+	}
+
+static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X);
+static const ADIS16260_GYRO_CHANNEL_SET(y, IIO_MOD_Y);
+static const ADIS16260_GYRO_CHANNEL_SET(z, IIO_MOD_Z);
+
+static const u8 adis16260_addresses[5][3] = {
+	[gyro] = { ADIS16260_GYRO_OUT,
+		   ADIS16260_GYRO_OFF,
+		   ADIS16260_GYRO_SCALE },
+	[angle] = { ADIS16260_ANGL_OUT },
+	[in_supply] = { ADIS16260_SUPPLY_OUT },
+	[in_aux] = { ADIS16260_AUX_ADC },
+	[temp] = { ADIS16260_TEMP_OUT },
+};
+static int adis16260_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][0];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16260_ERROR_ACTIVE) {
+			ret = adis16260_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_GYRO:
+			*val = 0;
+			if (spi_get_device_id(st->us)->driver_data)
+				*val2 = 320;
+			else
+				*val2 = 1278;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 18315;
+			else
+				*val2 = 610500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 145300;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][1];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][2];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		*val = (1 << bits) - 1;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16260_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits = 12;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16260_addresses[chan->address][1];
+		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16260_addresses[chan->address][2];
+		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
 
-static ADIS16260_ATTR_GROUP();
-static ADIS16260_ATTR_GROUP(_x);
-static ADIS16260_ATTR_GROUP(_y);
-static ADIS16260_ATTR_GROUP(_z);
+static struct attribute *adis16260_attributes[] = {
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16260_attribute_group = {
+	.attrs = adis16260_attributes,
+};
 
 static int __devinit adis16260_probe(struct spi_device *spi)
 {
@@ -593,24 +601,28 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi_get_device_id(st->us)->name;
 	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->attrs = &adis16260_attribute_group;
+	st->indio_dev->num_channels
+		= ARRAY_SIZE(adis16260_channels_x);
 	if (pd && pd->direction)
 		switch (pd->direction) {
 		case 'x':
-			st->indio_dev->attrs = &adis16260_attribute_group_x;
+			st->indio_dev->channels = adis16260_channels_x;
 			break;
 		case 'y':
-			st->indio_dev->attrs = &adis16260_attribute_group_y;
+			st->indio_dev->channels = adis16260_channels_y;
 			break;
 		case 'z':
-			st->indio_dev->attrs = &adis16260_attribute_group_z;
+			st->indio_dev->channels = adis16260_channels_z;
 			break;
 		default:
-			st->indio_dev->attrs = &adis16260_attribute_group;
-			break;
+			return -EINVAL;
 		}
 	else
-		st->indio_dev->attrs = &adis16260_attribute_group;
+		st->indio_dev->channels = adis16260_channels_x;
 
+	st->indio_dev->read_raw = &adis16260_read_raw;
+	st->indio_dev->write_raw = &adis16260_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
@@ -623,7 +635,9 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->indio_dev->channels,
+					  ARRAY_SIZE(adis16260_channels_x));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
@@ -636,7 +650,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16260_initial_setup(st);
+	ret = adis16260_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
@@ -668,7 +682,7 @@ static int adis16260_remove(struct spi_device *spi)
 	struct adis16260_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	ret = adis16260_stop_device(&(indio_dev->dev));
+	ret = adis16260_stop_device(indio_dev);
 	if (ret)
 		goto err_ret;
 
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 2806d83..12fbbf2 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -17,46 +17,6 @@
 #include "../trigger.h"
 #include "adis16260.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16260_SCAN_SUPPLY,
-		ADIS16260_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, ADIS16260_GYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16260_SCAN_AUX_ADC, ADIS16260_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, ADIS16260_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, ADIS16260_ANGL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(angl, u, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16260_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro.dev_attr.attr,
-	&iio_const_attr_gyro_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_angl.dev_attr.attr,
-	&iio_const_attr_angl_index.dev_attr.attr,
-	&iio_const_attr_angl_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16260_scan_el_group = {
-	.attrs = adis16260_scan_el_attrs,
-	.name = "scan_elements",
-};
 
 /**
  * adis16260_read_ring_data() read data registers which will be placed into ring
@@ -160,7 +120,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16260_scan_el_group;
 	ring->scan_timestamp = true;
 	ring->preenable = &iio_sw_ring_preenable;
 	ring->postenable = &iio_triggered_ring_postenable;
@@ -168,11 +127,11 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_angl.number);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_GYRO);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_ANGL);
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
index 6b73927..228272e 100644
--- a/drivers/staging/iio/gyro/adis16260_trigger.c
+++ b/drivers/staging/iio/gyro/adis16260_trigger.c
@@ -33,7 +33,7 @@ static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct iio_dev *indio_dev = st->indio_dev;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16260_set_irq(&st->indio_dev->dev, state);
+	return adis16260_set_irq(indio_dev, state);
 }
 
 int adis16260_probe_trigger(struct iio_dev *indio_dev)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 070/111] staging:iio:adc:ad7606 Convert to new channel registration method Update Add missing call to iio_trigger_notify_done() Set pollfunc top and bottom half handler
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (68 preceding siblings ...)
  2011-05-18 13:41 ` [PATCH 069/111] staging:iio:gyro:adis16260 " Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 071/111] staging:iio:adc:ad7606: Use private data space from iio_allocate_device Jonathan Cameron
                   ` (41 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

V3: rebase fixup.

Backported to relevant merge point by Jonathan Cameron.
V2: IIO_CHAN macro usage update

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7606.h      |    7 +-
 drivers/staging/iio/adc/ad7606_core.c |  185 +++++++++++++++++++--------------
 drivers/staging/iio/adc/ad7606_ring.c |   99 ++----------------
 3 files changed, 116 insertions(+), 175 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index c900090..364d89a 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -43,10 +43,9 @@ struct ad7606_platform_data {
 /**
  * struct ad7606_chip_info - chip specifc information
  * @name:		indentification string for chip
- * @bits:		accuracy of the adc in bits
- * @bits:		output coding [s]igned or [u]nsigned
  * @int_vref_mv:	the internal reference voltage
- * @num_channels:	number of physical inputs on chip
+ * @channels:		channel specification
+ * @num_channels:	number of channels
  */
 
 struct ad7606_chip_info {
@@ -54,6 +53,7 @@ struct ad7606_chip_info {
 	u8				bits;
 	char				sign;
 	u16				int_vref_mv;
+	struct iio_chan_spec		*channels;
 	unsigned			num_channels;
 };
 
@@ -69,7 +69,6 @@ struct ad7606_state {
 	struct regulator		*reg;
 	struct work_struct		poll_work;
 	wait_queue_head_t		wq_data_avail;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	const struct ad7606_bus_ops	*bops;
 	int				irq;
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 27090b9..ee61009 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -78,62 +78,39 @@ error_ret:
 	return ret;
 }
 
-static ssize_t ad7606_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7606_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
-
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7606_scan_from_ring(st, this_attr->address);
-	else
-		ret = ad7606_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (short) ret);
-}
-
-static IIO_DEV_ATTR_IN_RAW(0, ad7606_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7606_scan, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad7606_scan, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad7606_scan, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad7606_scan, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad7606_scan, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad7606_scan, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad7606_scan, 7);
-
-static ssize_t ad7606_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
-	unsigned int scale_uv = (st->range * 1000 * 2) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7606_show_scale, NULL, 0);
-
-static ssize_t ad7606_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", st->chip_info->name);
+	struct ad7606_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad7606_scan_from_ring(st, chan->address);
+		else
+			ret = ad7606_scan_direct(st, chan->address);
+		mutex_unlock(&dev_info->mlock);
+
+		if (ret < 0)
+			return ret;
+		*val = (short) ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->range * 1000 * 2)
+			>> st->chip_info->channels[0].scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
 
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7606_show_name, NULL, 0);
-
 static ssize_t ad7606_show_range(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
@@ -222,16 +199,6 @@ static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR,
 static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
 
 static struct attribute *ad7606_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_range.dev_attr.attr,
 	&iio_const_attr_range_available.dev_attr.attr,
 	&iio_dev_attr_oversampling_ratio.dev_attr.attr,
@@ -248,15 +215,7 @@ static mode_t ad7606_attr_is_visible(struct kobject *kobj,
 
 	mode_t mode = attr->mode;
 
-	if (st->chip_info->num_channels <= 6 &&
-		(attr == &iio_dev_attr_in7_raw.dev_attr.attr ||
-		attr == &iio_dev_attr_in6_raw.dev_attr.attr))
-		mode = 0;
-	else if (st->chip_info->num_channels <= 4 &&
-		(attr == &iio_dev_attr_in5_raw.dev_attr.attr ||
-		attr == &iio_dev_attr_in4_raw.dev_attr.attr))
-		mode = 0;
-	else if (!st->have_os &&
+	if (!st->have_os &&
 		(attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr ||
 		attr ==
 		&iio_const_attr_oversampling_ratio_available.dev_attr.attr))
@@ -274,29 +233,92 @@ static const struct attribute_group ad7606_attribute_group = {
 	.is_visible = ad7606_attr_is_visible,
 };
 
+static struct iio_chan_spec ad7606_8_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 6, 6, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 7, 7, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
+static struct iio_chan_spec ad7606_6_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(6),
+};
+
+static struct iio_chan_spec ad7606_4_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
 static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
 	/*
 	 * More devices added in future
 	 */
 	[ID_AD7606_8] = {
 		.name = "ad7606",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_8_channels,
 		.num_channels = 8,
 	},
 	[ID_AD7606_6] = {
 		.name = "ad7606-6",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_6_channels,
 		.num_channels = 6,
 	},
 	[ID_AD7606_4] = {
 		.name = "ad7606-4",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_4_channels,
 		.num_channels = 4,
 	},
 };
@@ -445,8 +467,6 @@ struct ad7606_state *ad7606_probe(struct device *dev, int irq,
 	st->pdata = pdata;
 	st->chip_info = &ad7606_chip_info_tbl[id];
 
-	atomic_set(&st->protect_ring, 0);
-
 	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
@@ -459,6 +479,9 @@ struct ad7606_state *ad7606_probe(struct device *dev, int irq,
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 	st->indio_dev->name = st->chip_info->name;
+	st->indio_dev->channels = st->chip_info->channels;
+	st->indio_dev->num_channels = st->chip_info->num_channels;
+	st->indio_dev->read_raw = &ad7606_read_raw;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
@@ -483,7 +506,9 @@ struct ad7606_state *ad7606_probe(struct device *dev, int irq,
 	if (ret)
 		goto error_free_irq;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->indio_dev->channels,
+					  st->indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 43caced..15531b6 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -21,87 +21,6 @@
 
 #include "ad7606.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_C(in2, 2, 0, NULL);
-static IIO_SCAN_EL_C(in3, 3, 0, NULL);
-static IIO_SCAN_EL_C(in4, 4, 0, NULL);
-static IIO_SCAN_EL_C(in5, 5, 0, NULL);
-static IIO_SCAN_EL_C(in6, 6, 0, NULL);
-static IIO_SCAN_EL_C(in7, 7, 0, NULL);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7606_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7606_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->bits);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7606_show_type, NULL, 0);
-
-static struct attribute *ad7606_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7606_scan_el_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7606_state *st = indio_dev->dev_data;
-
-	mode_t mode = attr->mode;
-
-	if (st->chip_info->num_channels <= 6 &&
-		(attr == &iio_scan_el_in7.dev_attr.attr ||
-		attr == &iio_const_attr_in7_index.dev_attr.attr ||
-		attr == &iio_scan_el_in6.dev_attr.attr ||
-		attr == &iio_const_attr_in6_index.dev_attr.attr))
-		mode = 0;
-	else if (st->chip_info->num_channels <= 4 &&
-		(attr == &iio_scan_el_in5.dev_attr.attr ||
-		attr == &iio_const_attr_in5_index.dev_attr.attr ||
-		attr == &iio_scan_el_in4.dev_attr.attr ||
-		attr == &iio_const_attr_in4_index.dev_attr.attr))
-		mode = 0;
-
-	return mode;
-}
-
-static struct attribute_group ad7606_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7606_scan_el_attrs,
-	.is_visible = ad7606_scan_el_attr_is_visible,
-};
-
 int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
@@ -139,7 +58,7 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 	size_t d_size;
 
 	d_size = st->chip_info->num_channels *
-		 st->chip_info->bits / 8;
+		 st->chip_info->channels[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		d_size += sizeof(s64);
@@ -157,14 +76,15 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 }
 
 /**
- * ad7606_trigger_handler_th() th of trigger launched polling to ring buffer
+ * ad7606_trigger_handler_th() th/bh of trigger launched polling to ring buffer
  *
  **/
-static irqreturn_t ad7606_trigger_handler_th(int irq, void *p)
+static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
 {
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
 	struct ad7606_state *st = indio_dev->dev_data;
+
 	gpio_set_value(st->pdata->gpio_convst, 1);
 
 	return IRQ_HANDLED;
@@ -190,10 +110,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
 	__u8 *buf;
 	int ret;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	buf = kzalloc(st->d_size, GFP_KERNEL);
 	if (buf == NULL)
 		return;
@@ -231,8 +147,8 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
 	ring->access.store_to(&sw_ring->buf, buf, time_ns);
 done:
 	gpio_set_value(st->pdata->gpio_convst, 0);
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(buf);
-	atomic_dec(&st->protect_ring);
 }
 
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
@@ -253,8 +169,10 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
+
 	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &ad7606_trigger_handler_th;
+	indio_dev->pollfunc->h = &ad7606_trigger_handler_th_bh;
+	indio_dev->pollfunc->thread = &ad7606_trigger_handler_th_bh;
 	indio_dev->pollfunc->name =
 		kasprintf(GFP_KERNEL, "%s_consumer%d", indio_dev->name,
 			  indio_dev->id);
@@ -267,7 +185,6 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->ring->preenable = &ad7606_ring_preenable;
 	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
 	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7606_scan_el_group;
 	indio_dev->ring->scan_timestamp = true ;
 
 	INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 071/111] staging:iio:adc:ad7606: Use private data space from iio_allocate_device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (69 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 070/111] staging:iio:adc:ad7606 Convert to new channel registration method Update Add missing call to iio_trigger_notify_done() Set pollfunc top and bottom half handler Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 072/111] staging:iio: Add channel types IIO_CURRENT and IIO_POWER Jonathan Cameron
                   ` (40 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Trivial backport done by Jonathan Cameron

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7606.h      |    9 ++--
 drivers/staging/iio/adc/ad7606_core.c |   92 +++++++++++++++++----------------
 drivers/staging/iio/adc/ad7606_par.c  |   30 ++++++-----
 drivers/staging/iio/adc/ad7606_ring.c |    7 ++-
 drivers/staging/iio/adc/ad7606_spi.c  |   24 +++++----
 5 files changed, 85 insertions(+), 77 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 364d89a..4d9d780 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -62,7 +62,6 @@ struct ad7606_chip_info {
  */
 
 struct ad7606_state {
-	struct iio_dev			*indio_dev;
 	struct device			*dev;
 	const struct ad7606_chip_info	*chip_info;
 	struct ad7606_platform_data	*pdata;
@@ -96,12 +95,12 @@ struct ad7606_bus_ops {
 	int (*read_block)(struct device *, int, void *);
 };
 
-void ad7606_suspend(struct ad7606_state *st);
-void ad7606_resume(struct ad7606_state *st);
-struct ad7606_state *ad7606_probe(struct device *dev, int irq,
+void ad7606_suspend(struct iio_dev *indio_dev);
+void ad7606_resume(struct iio_dev *indio_dev);
+struct iio_dev *ad7606_probe(struct device *dev, int irq,
 			      void __iomem *base_address, unsigned id,
 			      const struct ad7606_bus_ops *bops);
-int ad7606_remove(struct ad7606_state *st);
+int ad7606_remove(struct iio_dev *indio_dev);
 int ad7606_reset(struct ad7606_state *st);
 
 enum ad7606_supported_device_ids {
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index ee61009..3b4bb3e 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -365,8 +365,8 @@ static int ad7606_request_gpios(struct ad7606_state *st)
 		st->have_reset = true;
 
 	ret = gpio_request_one(st->pdata->gpio_range, GPIOF_DIR_OUT |
-			       ((st->range == 10000) ? GPIOF_INIT_HIGH :
-			       	GPIOF_INIT_LOW), "AD7606_RANGE");
+				((st->range == 10000) ? GPIOF_INIT_HIGH :
+				GPIOF_INIT_LOW), "AD7606_RANGE");
 	if (!ret)
 		st->have_range = true;
 
@@ -413,9 +413,10 @@ static void ad7606_free_gpios(struct ad7606_state *st)
  */
 static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
 {
-	struct ad7606_state *st = dev_id;
+	struct iio_dev *indio_dev = dev_id;
+	struct ad7606_state *st = iio_priv(indio_dev);
 
-	if (iio_ring_enabled(st->indio_dev)) {
+	if (iio_ring_enabled(indio_dev)) {
 		if (!work_pending(&st->poll_work))
 			schedule_work(&st->poll_work);
 	} else {
@@ -426,21 +427,23 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 };
 
-struct ad7606_state *ad7606_probe(struct device *dev, int irq,
+struct iio_dev *ad7606_probe(struct device *dev, int irq,
 			      void __iomem *base_address,
 			      unsigned id,
 			      const struct ad7606_bus_ops *bops)
 {
 	struct ad7606_platform_data *pdata = dev->platform_data;
 	struct ad7606_state *st;
-	int ret;
+	int ret, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
+	if (indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
 
+	st = iio_priv(indio_dev);
+
 	st->dev = dev;
 	st->id = id;
 	st->irq = irq;
@@ -467,97 +470,94 @@ struct ad7606_state *ad7606_probe(struct device *dev, int irq,
 	st->pdata = pdata;
 	st->chip_info = &ad7606_chip_info_tbl[id];
 
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	st->indio_dev->dev.parent = dev;
-	st->indio_dev->attrs = &ad7606_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->name = st->chip_info->name;
-	st->indio_dev->channels = st->chip_info->channels;
-	st->indio_dev->num_channels = st->chip_info->num_channels;
-	st->indio_dev->read_raw = &ad7606_read_raw;
+	indio_dev->dev.parent = dev;
+	indio_dev->attrs = &ad7606_attribute_group;
+	indio_dev->dev_data = (void *)(st);
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->name = st->chip_info->name;
+	indio_dev->channels = st->chip_info->channels;
+	indio_dev->num_channels = st->chip_info->num_channels;
+	indio_dev->read_raw = &ad7606_read_raw;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
 	ret = ad7606_request_gpios(st);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
 	ret = ad7606_reset(st);
 	if (ret)
 		dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
 
 	ret = request_irq(st->irq, ad7606_interrupt,
-		IRQF_TRIGGER_FALLING, st->chip_info->name, st);
+		IRQF_TRIGGER_FALLING, st->chip_info->name, indio_dev);
 	if (ret)
 		goto error_free_gpios;
 
-	ret = ad7606_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7606_register_ring_funcs_and_init(indio_dev);
 	if (ret)
 		goto error_free_irq;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_irq;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
-					  st->indio_dev->channels,
-					  st->indio_dev->num_channels);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
-	return st;
+	return indio_dev;
 
 error_cleanup_ring:
-	ad7606_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
+	ad7606_ring_cleanup(indio_dev);
 
 error_free_irq:
-	free_irq(st->irq, st);
+	free_irq(st->irq, indio_dev);
 
 error_free_gpios:
 	ad7606_free_gpios(st);
 
-error_free_device:
-	iio_free_device(st->indio_dev);
-
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
 error_ret:
 	return ERR_PTR(ret);
 }
 
-int ad7606_remove(struct ad7606_state *st)
+int ad7606_remove(struct iio_dev *indio_dev)
 {
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7606_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
-	free_irq(st->irq, st);
+
+	free_irq(st->irq, indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
 
 	ad7606_free_gpios(st);
+	iio_device_unregister(indio_dev);
 
-	kfree(st);
 	return 0;
 }
 
-void ad7606_suspend(struct ad7606_state *st)
+void ad7606_suspend(struct iio_dev *indio_dev)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	if (st->have_stby) {
 		if (st->have_range)
 			gpio_set_value(st->pdata->gpio_range, 1);
@@ -565,8 +565,10 @@ void ad7606_suspend(struct ad7606_state *st)
 	}
 }
 
-void ad7606_resume(struct ad7606_state *st)
+void ad7606_resume(struct iio_dev *indio_dev)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	if (st->have_stby) {
 		if (st->have_range)
 			gpio_set_value(st->pdata->gpio_range,
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index 43a554c..d21218d 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -12,13 +12,15 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "../iio.h"
 #include "ad7606.h"
 
 static int ad7606_par16_read_block(struct device *dev,
 				 int count, void *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	insw((unsigned long) st->base_address, buf, count);
 
@@ -33,7 +35,8 @@ static int ad7606_par8_read_block(struct device *dev,
 				 int count, void *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	insb((unsigned long) st->base_address, buf, count * 2);
 
@@ -47,7 +50,7 @@ static const struct ad7606_bus_ops ad7606_par8_bops = {
 static int __devinit ad7606_par_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	struct ad7606_state *st;
+	struct iio_dev *indio_dev;
 	void __iomem *addr;
 	resource_size_t remap_size;
 	int ret, irq;
@@ -75,17 +78,17 @@ static int __devinit ad7606_par_probe(struct platform_device *pdev)
 		goto out1;
 	}
 
-	st = ad7606_probe(&pdev->dev, irq, addr,
+	indio_dev = ad7606_probe(&pdev->dev, irq, addr,
 			  platform_get_device_id(pdev)->driver_data,
 			  remap_size > 1 ? &ad7606_par16_bops :
 			  &ad7606_par8_bops);
 
-	if (IS_ERR(st))  {
-		ret = PTR_ERR(st);
+	if (IS_ERR(indio_dev))  {
+		ret = PTR_ERR(indio_dev);
 		goto out2;
 	}
 
-	platform_set_drvdata(pdev, st);
+	platform_set_drvdata(pdev, indio_dev);
 
 	return 0;
 
@@ -99,10 +102,11 @@ out1:
 
 static int __devexit ad7606_par_remove(struct platform_device *pdev)
 {
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct resource *res;
+	struct ad7606_state *st = iio_priv(indio_dev);
 
-	ad7606_remove(st);
+	ad7606_remove(indio_dev);
 
 	iounmap(st->base_address);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -116,18 +120,18 @@ static int __devexit ad7606_par_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int ad7606_par_suspend(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_suspend(st);
+	ad7606_suspend(indio_dev);
 
 	return 0;
 }
 
 static int ad7606_par_resume(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_resume(st);
+	ad7606_resume(indio_dev);
 
 	return 0;
 }
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 15531b6..351d58e 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -23,11 +23,12 @@
 
 int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int ret;
 	u16 *ring_data;
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
@@ -103,7 +104,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
 {
 	struct ad7606_state *st = container_of(work_s, struct ad7606_state,
 						poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = iio_priv_to_dev(st);
 	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c
index d738491..0769c80 100644
--- a/drivers/staging/iio/adc/ad7606_spi.c
+++ b/drivers/staging/iio/adc/ad7606_spi.c
@@ -10,6 +10,8 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 #include <linux/err.h>
+
+#include "../iio.h"
 #include "ad7606.h"
 
 #define MAX_SPI_FREQ_HZ		23500000	/* VDRIVE above 4.75 V */
@@ -39,42 +41,42 @@ static const struct ad7606_bus_ops ad7606_spi_bops = {
 
 static int __devinit ad7606_spi_probe(struct spi_device *spi)
 {
-	struct ad7606_state *st;
+	struct iio_dev *indio_dev;
 
-	st = ad7606_probe(&spi->dev, spi->irq, NULL,
+	indio_dev = ad7606_probe(&spi->dev, spi->irq, NULL,
 			   spi_get_device_id(spi)->driver_data,
 			   &ad7606_spi_bops);
 
-	if (IS_ERR(st))
-		return PTR_ERR(st);
+	if (IS_ERR(indio_dev))
+		return PTR_ERR(indio_dev);
 
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
 	return 0;
 }
 
 static int __devexit ad7606_spi_remove(struct spi_device *spi)
 {
-	struct ad7606_state *st = dev_get_drvdata(&spi->dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
 
-	return ad7606_remove(st);
+	return ad7606_remove(indio_dev);
 }
 
 #ifdef CONFIG_PM
 static int ad7606_spi_suspend(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_suspend(st);
+	ad7606_suspend(indio_dev);
 
 	return 0;
 }
 
 static int ad7606_spi_resume(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_resume(st);
+	ad7606_resume(indio_dev);
 
 	return 0;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 072/111] staging:iio: Add channel types IIO_CURRENT and IIO_POWER.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (70 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 071/111] staging:iio:adc:ad7606: Use private data space from iio_allocate_device Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 073/111] staging:iio:meter:ade7758: Update trigger to the new API Jonathan Cameron
                   ` (39 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

This is required for the ADE7758 driver cleanup.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    2 ++
 drivers/staging/iio/industrialio-core.c |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 1a6bedc..c6fda58 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -36,6 +36,8 @@ enum iio_chan_type {
 
 	/* real channel types */
 	IIO_IN,
+	IIO_CURRENT,
+	IIO_POWER,
 	IIO_ACCEL,
 	IIO_IN_DIFF,
 	IIO_GYRO,
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index e3582c9..fc20a06 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -48,6 +48,8 @@ static const char * const iio_chan_type_name_spec_shared[] = {
 	[IIO_TIMESTAMP] = "timestamp",
 	[IIO_ACCEL] = "accel",
 	[IIO_IN] = "in",
+	[IIO_CURRENT] = "current",
+	[IIO_POWER] = "power",
 	[IIO_IN_DIFF] = "in-in",
 	[IIO_GYRO] = "gyro",
 	[IIO_TEMP] = "temp",
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 073/111] staging:iio:meter:ade7758: Update trigger to the new API
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (71 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 072/111] staging:iio: Add channel types IIO_CURRENT and IIO_POWER Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 074/111] staging:iio:meter:ade7758: Fix timing on SPI read accessor functions Jonathan Cameron
                   ` (38 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Update trigger to the new API.
Add file comment/license header.

Some backporting needed to keep the driver building all the way
through the core changes.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758_trigger.c |   52 ++++++++++++++-------------
 1 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
index 0adfcc6..06c921d 100644
--- a/drivers/staging/iio/meter/ade7758_trigger.c
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -1,3 +1,11 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/mutex.h>
@@ -19,20 +27,10 @@ static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
 {
 	disable_irq_nosync(irq);
 	iio_trigger_poll(private, iio_get_time_ns());
+
 	return IRQ_HANDLED;
 }
 
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *ade7758_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7758_trigger_attr_group = {
-	.attrs = ade7758_trigger_attrs,
-};
-
 /**
  * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -53,6 +51,7 @@ static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
 static int ade7758_trig_try_reen(struct iio_trigger *trig)
 {
 	struct ade7758_state *st = trig->private_data;
+
 	enable_irq(st->us->irq);
 	/* irq reenabled so success! */
 	return 0;
@@ -62,48 +61,51 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct ade7758_state *st = indio_dev->dev_data;
+	char *name;
 
+	name = kasprintf(GFP_KERNEL,
+			 "%s-dev%d",
+			 spi_get_device_id(st->us)->name,
+			 indio_dev->id);
+	if (name == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
 
-	st->trig = iio_allocate_trigger();
+	st->trig = iio_allocate_trigger_named(name);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_ret;
+		goto error_free_name;
 	}
+
 	ret = request_irq(st->us->irq,
 			  ade7758_data_rdy_trig_poll,
-			  IRQF_TRIGGER_FALLING, "ade7758",
+			  IRQF_TRIGGER_LOW,
+			  spi_get_device_id(st->us)->name,
 			  st->trig);
 	if (ret)
 		goto error_free_trig;
 
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"ade7758-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_irq;
-	}
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state;
 	st->trig->try_reenable = &ade7758_trig_try_reen;
-	st->trig->control_attrs = &ade7758_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
 error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
+error_free_name:
+	kfree(name);
 error_ret:
 	return ret;
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 074/111] staging:iio:meter:ade7758: Fix timing on SPI read accessor functions.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (72 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 073/111] staging:iio:meter:ade7758: Update trigger to the new API Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 075/111] iio:staging:meter:ade7758: Fix return value of ade7758_write_reset Jonathan Cameron
                   ` (37 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

According to the ADE7758 datasheet the minimum time between read command
(that is, a write to communication register) and data read must not be
less than 4us.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758_core.c |   43 +++++++++++++++++++++++-------
 1 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index c9956c4..8cfb617 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -100,7 +100,7 @@ static int ade7758_spi_write_reg_24(struct device *dev,
 	return ret;
 }
 
-static int ade7758_spi_read_reg_8(struct device *dev,
+int ade7758_spi_read_reg_8(struct device *dev,
 		u8 reg_address,
 		u8 *val)
 {
@@ -111,9 +111,15 @@ static int ade7758_spi_read_reg_8(struct device *dev,
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 2,
+			.len = 1,
 		},
 	};
 
@@ -122,14 +128,15 @@ static int ade7758_spi_read_reg_8(struct device *dev,
 	st->tx[1] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = st->rx[1];
+	*val = st->rx[0];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
@@ -147,26 +154,35 @@ static int ade7758_spi_read_reg_16(struct device *dev,
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 3,
+			.len = 2,
 		},
 	};
 
+
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADE7758_READ_REG(reg_address);
 	st->tx[1] = 0;
 	st->tx[2] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = (st->rx[1] << 8) | st->rx[2];
+
+	*val = (st->rx[0] << 8) | st->rx[1];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
@@ -184,9 +200,15 @@ static int ade7758_spi_read_reg_24(struct device *dev,
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 4,
+			.len = 3,
 		},
 	};
 
@@ -197,14 +219,15 @@ static int ade7758_spi_read_reg_24(struct device *dev,
 	st->tx[3] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 075/111] iio:staging:meter:ade7758: Fix return value of ade7758_write_reset
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (73 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 074/111] staging:iio:meter:ade7758: Fix timing on SPI read accessor functions Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 076/111] staging:iio:meter:ade7758: Fix list and set of available sample frequencies Jonathan Cameron
                   ` (36 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Update file comment/license header.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758_core.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 8cfb617..971b247 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -1,9 +1,9 @@
 /*
- * ADE7758 Polyphase Multifunction Energy Metering IC Driver
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 
 #include <linux/interrupt.h>
@@ -342,7 +342,7 @@ static ssize_t ade7758_write_reset(struct device *dev,
 	case 'Y':
 		return ade7758_reset(dev);
 	}
-	return -1;
+	return len;
 }
 
 static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 076/111] staging:iio:meter:ade7758: Fix list and set of available sample frequencies.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (74 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 075/111] iio:staging:meter:ade7758: Fix return value of ade7758_write_reset Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 077/111] staging:iio:meter:ade7758: Use iio channel spec and miscellaneous other changes Jonathan Cameron
                   ` (35 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Fix list of available sample frequencies.
Fix ade7758_write_frequency().

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758_core.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 971b247..26ff31b 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -533,7 +533,6 @@ static ssize_t ade7758_write_frequency(struct device *dev,
 		size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
 	unsigned long val;
 	int ret;
 	u8 reg, t;
@@ -544,14 +543,23 @@ static ssize_t ade7758_write_frequency(struct device *dev,
 
 	mutex_lock(&indio_dev->mlock);
 
-	t = (26040 / val);
-	if (t > 0)
-		t >>= 1;
-
-	if (t > 1)
-		st->us->max_speed_hz = ADE7758_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADE7758_SPI_FAST;
+	switch (val) {
+	case 26040:
+		t = 0;
+		break;
+	case 13020:
+		t = 1;
+		break;
+	case 6510:
+		t = 2;
+		break;
+	case 3255:
+		t = 3;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
 
 	ret = ade7758_spi_read_reg_8(dev,
 			ADE7758_WAVMODE,
@@ -671,7 +679,7 @@ static IIO_DEV_ATTR_WAVEFORM_TYPE(S_IWUSR | S_IRUGO,
 
 static IIO_DEV_ATTR_RESET(ade7758_write_reset);
 
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
 
 static struct attribute *ade7758_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 077/111] staging:iio:meter:ade7758: Use iio channel spec and miscellaneous other changes.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (75 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 076/111] staging:iio:meter:ade7758: Fix list and set of available sample frequencies Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 078/111] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
                   ` (34 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Use iio channel spec for the ring buffer channels.
Add/update file comment/license headers.
Use available_scan_masks to prevent that multiple channels are enabled.
Remove wavefrom type attributes. (no handled directly by the scan_elements)
Use SPI_MODE_1.
Move ade7758_initial_setup() before ade7758_probe_trigger() to ensure the
ADE7758 interrupt is disabled when the host interrupt get's enabled.
Add spi_device_id.
Update ring buffer setup.

Some backporting needed to ensure driver builds all the way through core
changes.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758.h      |   66 ++++++---
 drivers/staging/iio/meter/ade7758_core.c |  173 ++++++++++++-----------
 drivers/staging/iio/meter/ade7758_ring.c |  231 ++++++++++++++++--------------
 3 files changed, 258 insertions(+), 212 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index 169982b..372a9f6 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -1,3 +1,11 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
 #ifndef _ADE7758_H
 #define _ADE7758_H
 
@@ -83,12 +91,23 @@
 #define ADE7758_MAX_RX    4
 #define ADE7758_STARTUP_DELAY 1
 
-#define ADE7758_SPI_SLOW	(u32)(300 * 1000)
-#define ADE7758_SPI_BURST	(u32)(1000 * 1000)
-#define ADE7758_SPI_FAST	(u32)(2000 * 1000)
+#define AD7758_NUM_WAVSEL	5
+#define AD7758_NUM_PHSEL	3
+#define AD7758_NUM_WAVESRC	(AD7758_NUM_WAVSEL * AD7758_NUM_PHSEL)
+
+#define AD7758_PHASE_A		0
+#define AD7758_PHASE_B		1
+#define AD7758_PHASE_C		2
+#define AD7758_CURRENT		0
+#define AD7758_VOLTAGE		1
+#define AD7758_ACT_PWR		2
+#define AD7758_REACT_PWR	3
+#define AD7758_APP_PWR		4
+#define AD7758_WT(p, w)		(((w) << 2) | (p))
 
 #define DRIVER_NAME		"ade7758"
 
+
 /**
  * struct ade7758_state - device instance specific data
  * @us:			actual spi_device
@@ -99,22 +118,29 @@
  * @buf_lock:		mutex to protect tx and rx
  **/
 struct ade7758_state {
-	struct spi_device		*us;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
+	struct spi_device	*us;
+	struct iio_dev		*indio_dev;
+	struct iio_trigger	*trig;
+	u8			*tx;
+	u8			*rx;
+	struct mutex		buf_lock;
+	u32			available_scan_masks[AD7758_NUM_WAVESRC];
+	struct iio_chan_spec	*ade7758_ring_channels;
+	struct spi_transfer		ring_xfer[4];
+	struct spi_message		ring_msg;
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	unsigned char			rx_buf[8] ____cacheline_aligned;
+	unsigned char			tx_buf[8];
+
 };
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
 
-enum ade7758_scan {
-	ADE7758_SCAN_WFORM,
-};
-
 void ade7758_remove_trigger(struct iio_dev *indio_dev);
 int ade7758_probe_trigger(struct iio_dev *indio_dev);
 
@@ -129,6 +155,12 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev);
 int ade7758_initialize_ring(struct iio_ring_buffer *ring);
 void ade7758_uninitialize_ring(struct iio_ring_buffer *ring);
 int ade7758_set_irq(struct device *dev, bool enable);
+
+int ade7758_spi_write_reg_8(struct device *dev,
+		u8 reg_address, u8 val);
+int ade7758_spi_read_reg_8(struct device *dev,
+		u8 reg_address, u8 *val);
+
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void ade7758_remove_trigger(struct iio_dev *indio_dev)
@@ -139,14 +171,6 @@ static inline int ade7758_probe_trigger(struct iio_dev *indio_dev)
 	return 0;
 }
 
-static inline ssize_t
-ade7758_read_data_from_ring(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return 0;
-}
-
 static int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
 	return 0;
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 26ff31b..42682ad 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -20,10 +20,11 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "meter.h"
 #include "ade7758.h"
 
-static int ade7758_spi_write_reg_8(struct device *dev,
+int ade7758_spi_write_reg_8(struct device *dev,
 		u8 reg_address,
 		u8 val)
 {
@@ -490,7 +491,7 @@ static int ade7758_initial_setup(struct ade7758_state *st)
 	struct device *dev = &st->indio_dev->dev;
 
 	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_3;
+	st->us->mode = SPI_MODE_1;
 	spi_setup(st->us);
 
 	/* Disable IRQ */
@@ -580,63 +581,6 @@ out:
 	return ret ? ret : len;
 }
 
-static ssize_t ade7758_read_waveform_type(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u8 t;
-	ret = ade7758_spi_read_reg_8(dev,
-			ADE7758_WAVMODE,
-			&t);
-	if (ret)
-		return ret;
-
-	t = (t >> 2) & 0x7;
-
-	len = sprintf(buf, "%d\n", t);
-
-	return len;
-}
-
-static ssize_t ade7758_write_waveform_type(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	unsigned long val;
-	int ret;
-	u8 reg;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	if (val > 4)
-		return -EINVAL;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = ade7758_spi_read_reg_8(dev,
-			ADE7758_WAVMODE,
-			&reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(7 << 2);
-	reg |= val << 2;
-
-	ret = ade7758_spi_write_reg_8(dev,
-			ADE7758_WAVMODE,
-			reg);
-
-out:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
 static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit);
 static IIO_CONST_ATTR(temp_offset, "129 C");
 static IIO_CONST_ATTR(temp_scale, "4 C");
@@ -664,19 +608,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		ade7758_read_frequency,
 		ade7758_write_frequency);
 
-/**
- * IIO_DEV_ATTR_WAVEFORM_TYPE - set the type of waveform.
- * @_mode: sysfs file mode/permissions
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- **/
-#define IIO_DEV_ATTR_WAVEFORM_TYPE(_mode, _show, _store)			\
-	IIO_DEVICE_ATTR(waveform_type, _mode, _show, _store, 0)
-
-static IIO_DEV_ATTR_WAVEFORM_TYPE(S_IWUSR | S_IRUGO,
-		ade7758_read_waveform_type,
-		ade7758_write_waveform_type);
-
 static IIO_DEV_ATTR_RESET(ade7758_write_reset);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
@@ -686,7 +617,6 @@ static struct attribute *ade7758_attributes[] = {
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_dev_attr_waveform_type.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
 	&iio_dev_attr_awatthr.dev_attr.attr,
@@ -730,11 +660,73 @@ static const struct attribute_group ade7758_attribute_group = {
 	.attrs = ade7758_attributes,
 };
 
-
+static struct iio_chan_spec ade7758_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE),
+		0, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT),
+		1, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR),
+		2, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR),
+		3, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR),
+		4, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE),
+		5, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT),
+		6, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR),
+		7, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR),
+		8, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR),
+		9, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE),
+		10, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT),
+		11, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR),
+		12, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR),
+		13, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR),
+		14, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(15),
+};
 
 static int __devinit ade7758_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int i, ret, regdone = 0;
 	struct ade7758_state *st = kzalloc(sizeof *st, GFP_KERNEL);
 	if (!st) {
 		ret =  -ENOMEM;
@@ -755,6 +747,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 		goto error_free_rx;
 	}
 	st->us = spi;
+	st->ade7758_ring_channels = &ade7758_channels[0];
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
 	st->indio_dev = iio_allocate_device(0);
@@ -770,6 +763,11 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
+	for (i = 0; i < AD7758_NUM_WAVESRC; i++)
+		st->available_scan_masks[i] = 1 << i;
+
+	st->indio_dev->available_scan_masks = st->available_scan_masks;
+
 	ret = ade7758_configure_ring(st->indio_dev);
 	if (ret)
 		goto error_free_dev;
@@ -779,22 +777,25 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = ade7758_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  &ade7758_channels[0],
+					  ARRAY_SIZE(ade7758_channels));
 	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
+		dev_err(&spi->dev, "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
+	/* Get the device into a sane initial state */
+	ret = ade7758_initial_setup(st);
+	if (ret)
+		goto error_uninitialize_ring;
+
 	if (spi->irq) {
 		ret = ade7758_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_uninitialize_ring;
+			goto error_remove_trigger;
 	}
 
-	/* Get the device into a sane initial state */
-	ret = ade7758_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
@@ -829,8 +830,6 @@ static int ade7758_remove(struct spi_device *spi)
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
-
 	ade7758_remove_trigger(indio_dev);
 	ade7758_uninitialize_ring(indio_dev->ring);
 	iio_device_unregister(indio_dev);
@@ -845,6 +844,11 @@ err_ret:
 	return ret;
 }
 
+static const struct spi_device_id ade7758_id[] = {
+	{"ade7758", 0},
+	{}
+};
+
 static struct spi_driver ade7758_driver = {
 	.driver = {
 		.name = "ade7758",
@@ -852,6 +856,7 @@ static struct spi_driver ade7758_driver = {
 	},
 	.probe = ade7758_probe,
 	.remove = __devexit_p(ade7758_remove),
+	.id_table = ade7758_id,
 };
 
 static __init int ade7758_init(void)
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 2c9865d..c8ebfd2 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -1,3 +1,10 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -9,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <asm/unaligned.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -18,82 +26,40 @@
 #include "ade7758.h"
 
 /**
- * combine_8_to_32() utility function to munge to u8s into u32
- **/
-static inline u32 combine_8_to_32(u8 lower, u8 mid, u8 upper)
-{
-	u32 _lower = lower;
-	u32 _mid = mid;
-	u32 _upper = upper;
-
-	return _lower | (_mid << 8) | (_upper << 16);
-}
-
-static IIO_SCAN_EL_C(wform, ADE7758_SCAN_WFORM, ADE7758_WFORM, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(wform, s, 24, 32);
-static IIO_SCAN_EL_TIMESTAMP(1);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *ade7758_scan_el_attrs[] = {
-	&iio_scan_el_wform.dev_attr.attr,
-	&iio_const_attr_wform_index.dev_attr.attr,
-	&iio_const_attr_wform_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ade7758_scan_el_group = {
-	.attrs = ade7758_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * ade7758_spi_read_burst() - read all data registers
+ * ade7758_spi_read_burst() - read data registers
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
  **/
-static int ade7758_spi_read_burst(struct device *dev, u8 *rx)
+static int ade7758_spi_read_burst(struct device *dev)
 {
-	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 4,
-		}, {
-			.tx_buf = st->tx + 4,
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 4,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-	st->tx[4] = ADE7758_READ_REG(ADE7758_WFORM);
-	st->tx[5] = 0;
-	st->tx[6] = 0;
-	st->tx[7] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
+	ret = spi_sync(st->us, &st->ring_msg);
 	if (ret)
 		dev_err(&st->us->dev, "problem when reading WFORM value\n");
 
-	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7758_write_waveform_type(struct device *dev, unsigned type)
+{
+	int ret;
+	u8 reg;
+
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~0x1F;
+	reg |= type & 0x1F;
 
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_WAVMODE,
+			reg);
+out:
 	return ret;
 }
 
@@ -106,41 +72,70 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 	struct iio_dev *indio_dev = pf->private_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
-	int i = 0;
-	s32 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize, GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return -ENOMEM;
-	}
+	s64 dat64[2];
+	u32 *dat32 = (u32 *)dat64;
 
 	if (ring->scan_count)
-		if (ade7758_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = combine_8_to_32(st->rx[i*2+2],
-						st->rx[i*2+1],
-						st->rx[i*2]);
+		if (ade7758_spi_read_burst(&st->indio_dev->dev) >= 0)
+			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)
-		(((u32)data + 4 * ring->scan_count + 4) & ~0x7)) =
-			pf->timestamp;
+		dat64[1] = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      pf->timestamp);
+	ring->access.store_to(ring, (u8 *)dat64, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
 
 	return IRQ_HANDLED;
 }
 
+/**
+ * ade7758_ring_preenable() setup the parameters of the ring before enabling
+ *
+ * The complex nature of the setting of the nuber of bytes per datum is due
+ * to this driver currently ensuring that the timestamp is stored at an 8
+ * byte boundary.
+ **/
+static int ade7758_ring_preenable(struct iio_dev *indio_dev)
+{
+	struct ade7758_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	size_t d_size;
+	unsigned channel;
+
+	if (!ring->scan_count)
+		return -EINVAL;
+
+	channel = __ffs(ring->scan_mask);
+
+	d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
+
+	if (ring->scan_timestamp) {
+		d_size += sizeof(s64);
+
+		if (d_size % sizeof(s64))
+			d_size += sizeof(s64) - (d_size % sizeof(s64));
+	}
+
+	if (indio_dev->ring->access.set_bytes_per_datum)
+		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+							    d_size);
+
+	ade7758_write_waveform_type(&indio_dev->dev,
+		st->ade7758_ring_channels[channel].address);
+
+	return 0;
+}
+
 void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 {
+	/* ensure that the trigger has been detached */
+	if (indio_dev->trig) {
+		iio_put_trigger(indio_dev->trig);
+		iio_trigger_dettach_poll_func(indio_dev->trig,
+					      indio_dev->pollfunc);
+	}
 	kfree(indio_dev->pollfunc->name);
 	kfree(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
@@ -148,34 +143,28 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = indio_dev->dev_data;
 	int ret = 0;
-	struct iio_ring_buffer *ring;
 
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
+	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
+	if (!indio_dev->ring) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	indio_dev->ring = ring;
+
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 4;
-	ring->scan_el_attrs = &ade7758_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
-
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_wform.number);
+	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->preenable = &ade7758_ring_preenable;
+	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
+	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->owner = THIS_MODULE;
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev->ring;
+	indio_dev->pollfunc->private_data = indio_dev;
 	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
 	indio_dev->pollfunc->thread = &ade7758_trigger_handler;
 	indio_dev->pollfunc->name
@@ -186,6 +175,39 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 
+	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
+	st->tx_buf[1] = 0;
+	st->tx_buf[2] = 0;
+	st->tx_buf[3] = 0;
+	st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
+	st->tx_buf[5] = 0;
+	st->tx_buf[6] = 0;
+	st->tx_buf[7] = 0;
+
+	/* build spi ring message */
+	st->ring_xfer[0].tx_buf = &st->tx_buf[0];
+	st->ring_xfer[0].len = 1;
+	st->ring_xfer[0].bits_per_word = 8;
+	st->ring_xfer[0].delay_usecs = 4;
+	st->ring_xfer[1].rx_buf = &st->rx_buf[1];
+	st->ring_xfer[1].len = 3;
+	st->ring_xfer[1].bits_per_word = 8;
+	st->ring_xfer[1].cs_change = 1;
+
+	st->ring_xfer[2].tx_buf = &st->tx_buf[4];
+	st->ring_xfer[2].len = 1;
+	st->ring_xfer[2].bits_per_word = 8;
+	st->ring_xfer[2].delay_usecs = 1;
+	st->ring_xfer[3].rx_buf = &st->rx_buf[5];
+	st->ring_xfer[3].len = 3;
+	st->ring_xfer[3].bits_per_word = 8;
+
+	spi_message_init(&st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);
+
 	return 0;
 
 error_free_pollfunc:
@@ -195,11 +217,6 @@ error_iio_sw_rb_free:
 	return ret;
 }
 
-int ade7758_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
 void ade7758_uninitialize_ring(struct iio_ring_buffer *ring)
 {
 	iio_ring_buffer_unregister(ring);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 078/111] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (76 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 077/111] staging:iio:meter:ade7758: Use iio channel spec and miscellaneous other changes Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 079/111] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
                   ` (33 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Drivers have no need to use this functionality any more and we save a lot of
code by getting rid of it.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-ring.c |  101 ++++++++---------------------
 drivers/staging/iio/ring_generic.h      |  108 -------------------------------
 2 files changed, 26 insertions(+), 183 deletions(-)

diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 4497a50..853ebe9 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -193,53 +193,6 @@ static ssize_t iio_show_fixed_type(struct device *dev,
 		       this_attr->c->scan_type.shift);
 }
 
-static int __iio_add_chan_scan_elattr(const char *postfix,
-				      const char *group,
-				      const struct iio_chan_spec *chan,
-				      struct device *dev,
-				      struct list_head *attr_list)
-{
-	int ret;
-	struct iio_scan_el *scan_el;
-
-	scan_el = kzalloc(sizeof *scan_el, GFP_KERNEL);
-	if (scan_el == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	if (chan->type != IIO_TIMESTAMP)
-		ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
-					     iio_scan_el_show,
-					     iio_scan_el_store, 0);
-	else /*
-	      * Timestamp handled separately because it simplifies a lot of
-	      * drivers by ensuring they don't have to know its magic index
-	      */
-		ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
-					     iio_scan_el_ts_show,
-					     iio_scan_el_ts_store, 0);
-	if (ret)
-		goto error_free_scan_el;
-
-	scan_el->number = chan->scan_index;
-
-	ret = sysfs_add_file_to_group(&dev->kobj,
-				      &scan_el->dev_attr.attr,
-				      group);
-	if (ret < 0)
-		goto error_device_attr_deinit;
-
-	list_add(&scan_el->l, attr_list);
-
-	return 0;
-error_device_attr_deinit:
-	__iio_device_attr_deinit(&scan_el->dev_attr);
-error_free_scan_el:
-	kfree(scan_el);
-error_ret:
-	return ret;
-}
-
 static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 				      const struct iio_chan_spec *chan)
 {
@@ -268,23 +221,28 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 	if (ret)
 		goto error_ret;
 
-	ret = __iio_add_chan_scan_elattr("en", "scan_elements",
-					 chan, &ring->dev,
-					 &ring->scan_el_en_attr_list);
-
+	if (chan->type != IIO_TIMESTAMP)
+		ret = __iio_add_chan_devattr("en", "scan_elements",
+					     chan,
+					     &iio_scan_el_show,
+					     &iio_scan_el_store,
+					     chan->scan_index,
+					     0,
+					     &ring->dev,
+					     &ring->scan_el_dev_attr_list);
+	else
+		ret = __iio_add_chan_devattr("en", "scan_elements",
+					     chan,
+					     &iio_scan_el_ts_show,
+					     &iio_scan_el_ts_store,
+					     chan->scan_index,
+					     0,
+					     &ring->dev,
+					     &ring->scan_el_dev_attr_list);
 error_ret:
 	return ret;
 }
 
-static void iio_ring_remove_and_free_scan_el_attr(struct iio_ring_buffer *ring,
-						  struct iio_scan_el *p)
-{
-	sysfs_remove_file_from_group(&ring->dev.kobj,
-				     &p->dev_attr.attr, "scan_elements");
-	kfree(p->dev_attr.attr.name);
-	kfree(p);
-}
-
 static void iio_ring_remove_and_free_scan_dev_attr(struct iio_ring_buffer *ring,
 						   struct iio_dev_attr *p)
 {
@@ -306,15 +264,10 @@ static struct attribute_group iio_scan_el_dummy_group = {
 static void __iio_ring_attr_cleanup(struct iio_ring_buffer *ring)
 {
 	struct iio_dev_attr *p, *n;
-	struct iio_scan_el *q, *m;
-	int anydynamic = !(list_empty(&ring->scan_el_dev_attr_list) &&
-			   list_empty(&ring->scan_el_en_attr_list));
+	int anydynamic = !list_empty(&ring->scan_el_dev_attr_list);
 	list_for_each_entry_safe(p, n,
 				 &ring->scan_el_dev_attr_list, l)
 		iio_ring_remove_and_free_scan_dev_attr(ring, p);
-	list_for_each_entry_safe(q, m,
-				 &ring->scan_el_en_attr_list, l)
-		iio_ring_remove_and_free_scan_el_attr(ring, q);
 
 	if (ring->scan_el_attrs)
 		sysfs_remove_group(&ring->dev.kobj,
@@ -352,7 +305,6 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 	}
 
 	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
-	INIT_LIST_HEAD(&ring->scan_el_en_attr_list);
 	if (channels) {
 		/* new magic */
 		for (i = 0; i < num_channels; i++) {
@@ -554,9 +506,9 @@ ssize_t iio_scan_el_show(struct device *dev,
 {
 	int ret;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_scan_el *this_el = to_iio_scan_el(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
-	ret = iio_scan_mask_query(ring, this_el->number);
+	ret = iio_scan_mask_query(ring, this_attr->address);
 	if (ret < 0)
 		return ret;
 	return sprintf(buf, "%d\n", ret);
@@ -572,7 +524,7 @@ ssize_t iio_scan_el_store(struct device *dev,
 	bool state;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 	struct iio_dev *indio_dev = ring->indio_dev;
-	struct iio_scan_el *this_el = to_iio_scan_el(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	state = !(buf[0] == '0');
 	mutex_lock(&indio_dev->mlock);
@@ -580,20 +532,19 @@ ssize_t iio_scan_el_store(struct device *dev,
 		ret = -EBUSY;
 		goto error_ret;
 	}
-	ret = iio_scan_mask_query(ring, this_el->number);
+	ret = iio_scan_mask_query(ring, this_attr->address);
 	if (ret < 0)
 		goto error_ret;
 	if (!state && ret) {
-		ret = iio_scan_mask_clear(ring, this_el->number);
+		ret = iio_scan_mask_clear(ring, this_attr->address);
 		if (ret)
 			goto error_ret;
 	} else if (state && !ret) {
-		ret = iio_scan_mask_set(ring, this_el->number);
+		ret = iio_scan_mask_set(ring, this_attr->address);
 		if (ret)
 			goto error_ret;
 	}
-	if (this_el->set_state)
-		ret = this_el->set_state(this_el, indio_dev, state);
+
 error_ret:
 	mutex_unlock(&indio_dev->mlock);
 
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 671e9fd..15d15a4 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -108,7 +108,6 @@ struct iio_ring_buffer {
 	int				(*postdisable)(struct iio_dev *);
 
 	struct list_head scan_el_dev_attr_list;
-	struct list_head scan_el_en_attr_list;
 
 	wait_queue_head_t pollq;
 	bool stufftoread;
@@ -137,29 +136,6 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
 }
 
 /**
- * struct iio_scan_el - an individual element of a scan
- * @dev_attr:		control attribute (if directly controllable)
- * @number:		unique identifier of element (used for bit mask)
- * @label:		useful data for the scan el (often reg address)
- * @set_state:		for some devices datardy signals are generated
- *			for any enabled lines.  This allows unwanted lines
- *			to be disabled and hence not get in the way.
- **/
-struct iio_scan_el {
-	struct device_attribute		dev_attr;
-	unsigned int			number;
-	unsigned int			label;
-	struct list_head l;
-
-	int (*set_state)(struct iio_scan_el *scanel,
-			 struct iio_dev *dev_info,
-			 bool state);
-};
-
-#define to_iio_scan_el(_dev_attr)				\
-	container_of(_dev_attr, struct iio_scan_el, dev_attr);
-
-/**
  * iio_scan_el_store() - sysfs scan element selection interface
  * @dev: the target device
  * @attr: the device attribute that is being processed
@@ -197,90 +173,6 @@ ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr,
  **/
 ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
 			    char *buf);
-/**
- * IIO_SCAN_EL_C - declare and initialize a scan element with a control func
- *
- * @_name:	identifying name. Resulting struct is iio_scan_el_##_name,
- *		sysfs element, _name##_en.
- * @_number:	unique id number for the scan element.
- *		length devices).
- * @_label:	indentification variable used by drivers.  Often a reg address.
- * @_controlfunc: function used to notify hardware of whether state changes
- **/
-#define __IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)	\
-	struct iio_scan_el iio_scan_el_##_name = {			\
-		.dev_attr = __ATTR(_name##_en,				\
-				   S_IRUGO | S_IWUSR,			\
-				   iio_scan_el_show,			\
-				   iio_scan_el_store),			\
-		.number =  _number,					\
-		.label = _label,					\
-		.set_state = _controlfunc,				\
-	};								\
-	static IIO_CONST_ATTR(_name##_index, #_number)
-
-#define IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)	\
-	__IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)
-
-#define __IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf)	\
-	struct iio_scan_el iio_scan_el_##_name = {			\
-		.dev_attr = __ATTR(_string##_en,			\
-				   S_IRUGO | S_IWUSR,			\
-				   iio_scan_el_show,			\
-				   iio_scan_el_store),			\
-		.number =  _number,					\
-		.label = _label,					\
-		.set_state = _cf,					\
-	};								\
-	static struct iio_const_attr iio_const_attr_##_name##_index = {	\
-		.string = #_number,					\
-		.dev_attr = __ATTR(_string##_index,			\
-				   S_IRUGO, iio_read_const_attr, NULL)	\
-	}
-
-
-#define IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf) \
-	__IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf)
-/**
- * IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps
- * @number: specify where in the scan order this is stored.
- *
- * Odd one out. Handled slightly differently from other scan elements.
- **/
-#define IIO_SCAN_EL_TIMESTAMP(number)				\
-	struct iio_scan_el iio_scan_el_timestamp = {		\
-		.dev_attr = __ATTR(timestamp_en,		\
-				   S_IRUGO | S_IWUSR,		\
-				   iio_scan_el_ts_show,		\
-				   iio_scan_el_ts_store),	\
-	};							\
-	static IIO_CONST_ATTR(timestamp_index, #number)
-
-/**
- * IIO_CONST_ATTR_SCAN_EL_TYPE - attr to specify the data format of a scan el
- * @name: the scan el name (may be more general and cover a set of scan elements
- * @_sign: either s or u for signed or unsigned
- * @_bits: number of actual bits occuplied by the value
- * @_storagebits: number of bits _bits is padded to when read out of buffer
- **/
-#define IIO_CONST_ATTR_SCAN_EL_TYPE(_name, _sign, _bits, _storagebits) \
-	IIO_CONST_ATTR(_name##_type, #_sign#_bits"/"#_storagebits);
-
-/**
- * IIO_CONST_ATTR_SCAN_EL_TYPE_WITH_SHIFT - attr to specify the data format of a scan el
- * @name: the scan el name (may be more general and cover a set of scan elements
- * @_sign: either s or u for signed or unsigned
- * @_bits: number of actual bits occuplied by the value
- * @_storagebits: number of bits _bits is padded to when read out of buffer
- * @_shiftbits: number of bits _shiftbits the result must be shifted
- **/
-#define IIO_CONST_ATTR_SCAN_EL_TYPE_WITH_SHIFT(_name, _sign, _bits, \
-					       _storagebits, _shiftbits) \
-	IIO_CONST_ATTR(_name##_type, #_sign#_bits"/"#_storagebits \
-		       ">>"#_shiftbits);
-
-#define IIO_SCAN_EL_TYPE_SIGNED         's'
-#define IIO_SCAN_EL_TYPE_UNSIGNED       'u'
 
 /*
  * These are mainly provided to allow for a change of implementation if a device
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 079/111] staging:iio:max1363 trivial removal of unused trig pointer.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (77 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 078/111] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 080/111] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
                   ` (32 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/max1363.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 2d41a27..15227bd 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -195,7 +195,6 @@ struct max1363_state {
 	const struct max1363_chip_info	*chip_info;
 	const struct max1363_mode	*current_mode;
 	u32				requestedmask;
-	struct iio_trigger		*trig;
 	struct regulator		*reg;
 
 	/* Using monitor modes and buffer at the same time is
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 080/111] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (78 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 079/111] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 081/111] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
                   ` (31 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

V2: IIO_CHAN macro usage update.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/Kconfig        |    4 +-
 drivers/staging/iio/adc/max1363_core.c |   57 +++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 0a19cee..617af93 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -15,8 +15,8 @@ config MAX1363
 	  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
 	  max11602, max11603, max11604, max11605, max11606, max11607,
 	  max11608, max11609, max11610, max11611, max11612, max11613,
-	  max11614, max11615, max11616, max11617) Provides direct access
-	  via sysfs.
+	  max11614, max11615, max11616, max11617, max11644, max11645,
+	  max11646, max11647) Provides direct access via sysfs.
 
 config MAX1363_RING_BUFFER
 	bool "MAXIM max1363: use ring buffer"
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 20c6aae..0c80abb 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -417,6 +417,21 @@ static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
 static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
 static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
 
+static const enum max1363_modes max11644_mode_list[] = {
+	_s0, _s1, s0to1, d0m1, d1m0,
+};
+
+#define MAX1363_2X_CHANS(bits) {			\
+	MAX1363_CHAN_U(0, _s0, 0, bits),		\
+	MAX1363_CHAN_U(1, _s1, 1, bits),		\
+	MAX1363_CHAN_B(0, 1, d0m1, 2, bits),		\
+	MAX1363_CHAN_B(1, 0, d1m0, 3, bits),		\
+	IIO_CHAN_SOFT_TIMESTAMP(4)			\
+	}
+
+static struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
+static struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
+
 enum { max1361,
        max1362,
        max1363,
@@ -451,6 +466,10 @@ enum { max1361,
        max11615,
        max11616,
        max11617,
+       max11644,
+       max11645,
+       max11646,
+       max11647
 };
 
 /* max1363 and max1368 tested - rest from data sheet */
@@ -764,7 +783,43 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 		.default_mode = s0to11,
 		.channels = max1238_channels,
 		.num_channels = ARRAY_SIZE(max1238_channels),
-	}
+	},
+	[max11644] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11645] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11646] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
+	[max11647] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
 };
 
 static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 081/111] staging:iio:trigger sysfs userspace trigger rework.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (79 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 080/111] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 082/111] staging:iio:core clean out unused elements Jonathan Cameron
                   ` (30 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Awaiting comments on using the nested_irq_trick so that may change.
Moves away from platform device to sysfs controlled creation and
removal of these triggers.

Fix double free of name on trigger allocation failure thanks
to Michael Hennerich.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Reviewed-by: Michael Hennerich <michael.hennerich@analog.com>
---
 drivers/staging/iio/industrialio-trigger.c   |   13 ++
 drivers/staging/iio/trigger.h                |    1 +
 drivers/staging/iio/trigger/iio-trig-sysfs.c |  170 ++++++++++++++++++++------
 3 files changed, 149 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index dd762f0..86d026b 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -181,6 +181,19 @@ irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private)
 }
 EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
 
+void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
+{
+	int i;
+	if (!trig->use_count) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
+			if (trig->subirqs[i].enabled) {
+				trig->use_count++;
+				handle_nested_irq(trig->subirq_base + i);
+			}
+	}
+}
+EXPORT_SYMBOL(iio_trigger_poll_chained);
+
 void iio_trigger_notify_done(struct iio_trigger *trig)
 {
 	trig->use_count--;
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index e831a89..5efa0d5 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -121,6 +121,7 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
  * Typically called in relevant hardware interrupt handler.
  **/
 void iio_trigger_poll(struct iio_trigger *trig, s64 time);
+void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time);
 void iio_trigger_notify_done(struct iio_trigger *trig);
 
 irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c
index 127a2a3..6d3dee3 100644
--- a/drivers/staging/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c
@@ -9,15 +9,84 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/list.h>
 
 #include "../iio.h"
 #include "../trigger.h"
 
+struct iio_sysfs_trig {
+	struct iio_trigger *trig;
+	int id;
+	struct list_head l;
+};
+
+static LIST_HEAD(iio_sysfs_trig_list);
+static DEFINE_MUTEX(iio_syfs_trig_list_mut);
+
+static int iio_sysfs_trigger_probe(int id);
+static ssize_t iio_sysfs_trig_add(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = strict_strtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_probe(input);
+	if (ret)
+		return ret;
+	return len;
+}
+static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add);
+
+static int iio_sysfs_trigger_remove(int id);
+static ssize_t iio_sysfs_trig_remove(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf,
+				     size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = strict_strtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_remove(input);
+	if (ret)
+		return ret;
+	return len;
+}
+
+static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove);
+
+static struct attribute *iio_sysfs_trig_attrs[] = {
+	&dev_attr_add_trigger.attr,
+	&dev_attr_remove_trigger.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_sysfs_trig_group = {
+	.attrs = iio_sysfs_trig_attrs,
+};
+
+static const struct attribute_group *iio_sysfs_trig_groups[] = {
+	&iio_sysfs_trig_group,
+	NULL
+};
+
+static struct device iio_sysfs_trig_dev = {
+	.bus = &iio_bus_type,
+	.groups = iio_sysfs_trig_groups,
+};
+
 static ssize_t iio_sysfs_trigger_poll(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct iio_trigger *trig = dev_get_drvdata(dev);
-	iio_trigger_poll(trig, 0);
+	iio_trigger_poll_chained(trig, 0);
 
 	return count;
 }
@@ -35,70 +104,101 @@ static const struct attribute_group iio_sysfs_trigger_attr_group = {
 	.attrs = iio_sysfs_trigger_attrs,
 };
 
-static int __devinit iio_sysfs_trigger_probe(struct platform_device *pdev)
+static int iio_sysfs_trigger_probe(int id)
 {
-	struct iio_trigger *trig;
+	struct iio_sysfs_trig *t;
 	int ret;
+	char *name;
+	bool foundit = false;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (foundit) {
+		ret = -EINVAL;
+		goto out1;
+	}
 
-	trig = iio_allocate_trigger();
-	if (!trig) {
+	name = kasprintf(GFP_KERNEL, "sysfstrig%d", id);
+	if (name == NULL) {
 		ret = -ENOMEM;
 		goto out1;
 	}
-
-	trig->control_attrs = &iio_sysfs_trigger_attr_group;
-	trig->owner = THIS_MODULE;
-	trig->name = kasprintf(GFP_KERNEL, "sysfstrig%d", pdev->id);
-	if (trig->name == NULL) {
+	t = kmalloc(sizeof(*t), GFP_KERNEL);
+	if (t == NULL) {
 		ret = -ENOMEM;
-		goto out2;
+		goto free_name;
+	}
+	t->id = id;
+	t->trig = iio_allocate_trigger_named(name);
+	if (!t->trig) {
+		ret = -ENOMEM;
+		goto free_t;
 	}
 
-	ret = iio_trigger_register(trig);
-	if (ret)
-		goto out3;
-
-	platform_set_drvdata(pdev, trig);
+	t->trig->control_attrs = &iio_sysfs_trigger_attr_group;
+	t->trig->owner = THIS_MODULE;
+	t->trig->dev.parent = &iio_sysfs_trig_dev;
 
+	ret = iio_trigger_register(t->trig);
+	if (ret)
+		goto out2;
+	list_add(&t->l, &iio_sysfs_trig_list);
+	__module_get(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return 0;
-out3:
-	kfree(trig->name);
+
 out2:
-	iio_put_trigger(trig);
+	iio_put_trigger(t->trig);
+free_t:
+	kfree(t);
+free_name:
+	kfree(name);
 out1:
-
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return ret;
 }
 
-static int __devexit iio_sysfs_trigger_remove(struct platform_device *pdev)
+static int iio_sysfs_trigger_remove(int id)
 {
-	struct iio_trigger *trig = platform_get_drvdata(pdev);
+	bool foundit = false;
+	struct iio_sysfs_trig *t;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (!foundit) {
+		mutex_unlock(&iio_syfs_trig_list_mut);
+		return -EINVAL;
+	}
 
-	iio_trigger_unregister(trig);
-	kfree(trig->name);
-	iio_put_trigger(trig);
+	iio_trigger_unregister(t->trig);
+	kfree(t->trig->name);
+	iio_free_trigger(t->trig);
 
+	list_del(&t->l);
+	kfree(t);
+	module_put(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return 0;
 }
 
-static struct platform_driver iio_sysfs_trigger_driver = {
-	.driver = {
-		.name = "iio_sysfs_trigger",
-		.owner = THIS_MODULE,
-	},
-	.probe = iio_sysfs_trigger_probe,
-	.remove = __devexit_p(iio_sysfs_trigger_remove),
-};
 
 static int __init iio_sysfs_trig_init(void)
 {
-	return platform_driver_register(&iio_sysfs_trigger_driver);
+	device_initialize(&iio_sysfs_trig_dev);
+	dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
+	return device_add(&iio_sysfs_trig_dev);
 }
 module_init(iio_sysfs_trig_init);
 
 static void __exit iio_sysfs_trig_exit(void)
 {
-	platform_driver_unregister(&iio_sysfs_trigger_driver);
+	device_unregister(&iio_sysfs_trig_dev);
 }
 module_exit(iio_sysfs_trig_exit);
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 082/111] staging:iio:core clean out unused elements.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (80 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 081/111] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 083/111] staging:iio:adc:ad7150 fix event codes Jonathan Cameron
                   ` (29 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Trivial cleanup of things that have fallen by the way.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |   13 --------
 drivers/staging/iio/industrialio-core.c |   47 +-----------------------------
 2 files changed, 2 insertions(+), 58 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index c6fda58..1ad9480 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -25,8 +25,6 @@
 /* Event interface flags */
 #define IIO_BUSY_BIT_POS 1
 
-struct iio_dev;
-
 /* naughty temporary hack to match these against the event version
    - need to flattern these together */
 enum iio_chan_type {
@@ -221,7 +219,6 @@ static inline s64 iio_get_time_ns(void)
  *			ownership of chrdevs etc
  * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device
  * @event_attrs:	[DRIVER] event control attributes
- * @event_conf_attrs:	[DRIVER] event configuration attributes
  * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
  * @ring:		[DRIVER] any ring buffer present
  * @mlock:		[INTERN] lock used to prevent simultaneous device state
@@ -259,8 +256,6 @@ struct iio_dev {
 
 	int				num_interrupt_lines;
 	struct attribute_group		*event_attrs;
-	struct attribute_group		*event_conf_attrs;
-
 	struct iio_event_interface	*event_interfaces;
 
 	struct iio_ring_buffer		*ring;
@@ -326,14 +321,6 @@ int iio_push_event(struct iio_dev *dev_info,
 		  int ev_code,
 		  s64 timestamp);
 
-/**
- * iio_allocate_chrdev() - Allocate a chrdev
- * @handler:	struct that contains relevant file handling for chrdev
- * @dev_info:	iio_dev for which chrdev is being created
- **/
-int iio_allocate_chrdev(struct iio_handler *handler, struct iio_dev *dev_info);
-void iio_deallocate_chrdev(struct iio_handler *handler);
-
 /* Used to distinguish between bipolar and unipolar scan elemenents.
  * Whilst this may seem obvious, we may well want to change the representation
  * in the future!*/
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index fc20a06..49560e4 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -998,21 +998,6 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 {
 	int j;
 	int ret;
-	struct attribute **attrp, **attrq;
-
-	if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
-		attrp = dev_info->event_conf_attrs[i].attrs;
-		while (*attrp) {
-			ret =  sysfs_add_file_to_group(&dev_info
-						       ->event_interfaces[0]
-						       .dev.kobj,
-						       *attrp,
-						       NULL);
-			if (ret)
-				goto error_ret;
-			attrp++;
-		}
-	}
 	INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list);
 	/* Dynically created from the channels array */
 	if (dev_info->channels) {
@@ -1027,19 +1012,7 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
 	return 0;
 
 error_clear_attrs:
-	__iio_remove_all_event_sysfs(dev_info,
-				     NULL,
-				     i);
-error_ret:
-	attrq = dev_info->event_conf_attrs[i].attrs;
-	while (attrq != attrp) {
-			sysfs_remove_file_from_group(&dev_info
-						     ->event_interfaces[0]
-						     .dev.kobj,
-						     *attrq,
-						     NULL);
-		attrq++;
-	}
+	__iio_remove_all_event_sysfs(dev_info, NULL, i);
 
 	return ret;
 }
@@ -1047,23 +1020,7 @@ error_ret:
 static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
 						  int i)
 {
-	struct attribute **attrq;
-	__iio_remove_all_event_sysfs(dev_info,
-				     NULL,
-				     i);
-	if (dev_info->event_conf_attrs
-		&& dev_info->event_conf_attrs[i].attrs) {
-		attrq = dev_info->event_conf_attrs[i].attrs;
-		while (*attrq) {
-			sysfs_remove_file_from_group(&dev_info
-						     ->event_interfaces[0]
-						     .dev.kobj,
-						     *attrq,
-						     NULL);
-			attrq++;
-		}
-	}
-
+	__iio_remove_all_event_sysfs(dev_info, NULL, i);
 	return 0;
 }
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 083/111] staging:iio:adc:ad7150 fix event codes.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (81 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 082/111] staging:iio:core clean out unused elements Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 084/111] staging:iio:adc:ad7816 and adt75 change to meaningful event code Jonathan Cameron
                   ` (28 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

I won't guarantee I got these right, but they are certainly closer than
the abuse of buffer event codes that was perviously in here.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7150.c |   31 +++++++++++++++++++------------
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index cbd1f96..e23bb99 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -642,11 +642,6 @@ static const struct attribute_group ad7150_attribute_group = {
  * threshold events
  */
 
-#define IIO_EVENT_CODE_CH1_HIGH    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_CH1_LOW     IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_CH2_HIGH    IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_CH2_LOW     IIO_BUFFER_EVENT_CODE(3)
-
 static irqreturn_t ad7150_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -658,21 +653,33 @@ static irqreturn_t ad7150_event_handler(int irq, void *private)
 
 	if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1))
 		iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_CH1_HIGH,
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
 				timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1))
 		iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_CH1_LOW,
-				timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 
 	if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2))
 		iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_CH2_HIGH,
-				timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    1,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2))
 		iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_CH2_LOW,
-				timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    1,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 	return IRQ_HANDLED;
 }
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 084/111] staging:iio:adc:ad7816 and adt75 change to meaningful event code.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (82 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 083/111] staging:iio:adc:ad7150 fix event codes Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 085/111] staging:iio:adc:ad7291 remove abuse of buffer events and replace with something almost sane Jonathan Cameron
                   ` (27 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This was another abuse of the buffer event codes.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7816.c |    5 ++++-
 drivers/staging/iio/adc/adt75.c  |    5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index bee4209..873fe2b 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -247,7 +247,10 @@ static const struct attribute_group ad7816_attribute_group = {
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_AD7816_OTI    IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \
+						       0,		\
+						       IIO_EV_TYPE_THRESH, \
+						       IIO_EV_DIR_FALLING)
 
 static irqreturn_t ad7816_event_handler(int irq, void *private)
 {
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index 4b1c0fa..2a44428 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -258,7 +258,10 @@ static const struct attribute_group adt75_attribute_group = {
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_ADT75_OTI    IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \
+						      0,		\
+						      IIO_EV_TYPE_THRESH, \
+						      IIO_EV_DIR_FALLING)
 
 static irqreturn_t adt75_event_handler(int irq, void *private)
 {
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 085/111] staging:iio:adc:ad7291 remove abuse of buffer events and replace with something almost sane
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (83 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 084/111] staging:iio:adc:ad7816 and adt75 change to meaningful event code Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 086/111] staging:iio:adc:adt7310 replace abuse of buffer events Jonathan Cameron
                   ` (26 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This device has separate events for a sort of decaying average and for
the raw value.  We don't have a way of specifying this as yet.
For now I have both resulting in the same event code.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7291.c |   58 +++++++++++++++++++++++++++----------
 1 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 527311c..0e4c728 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -454,12 +454,6 @@ static const struct attribute_group ad7291_attribute_group = {
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_AD7291_T_SENSE_HIGH  IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_AD7291_T_SENSE_LOW   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_AD7291_T_AVG_HIGH    IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_AD7291_T_AVG_LOW     IIO_BUFFER_EVENT_CODE(3)
-#define IIO_EVENT_CODE_AD7291_VOLTAGE_BASE  IIO_BUFFER_EVENT_CODE(4)
-
 static irqreturn_t ad7291_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -484,18 +478,50 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
 	command = chip->command & ~AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
 
-	for (i = 0; i < 4; i++) {
-		if (t_status & (1 << i))
-			iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_AD7291_T_SENSE_HIGH + i,
-				timestamp);
-	}
-
-	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i++) {
+	if (t_status & (1 << 0))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+	if (t_status & (1 << 1))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+	if (t_status & (1 << 2))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+	if (t_status & (1 << 3))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+
+	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
 		if (v_status & (1 << i))
 			iio_push_event(indio_dev, 0,
-				IIO_EVENT_CODE_AD7291_VOLTAGE_BASE + i,
-				timestamp);
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    i/2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       timestamp);
+		if (v_status & (1 << (i + 1)))
+			iio_push_event(indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    i/2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       timestamp);
 	}
 
 	return IRQ_HANDLED;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 086/111] staging:iio:adc:adt7310 replace abuse of buffer events.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (84 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 085/111] staging:iio:adc:ad7291 remove abuse of buffer events and replace with something almost sane Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 087/111] staging:iio:adc:adt7410 " Jonathan Cameron
                   ` (25 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/adt7310.c |   24 +++++++++++-------------
 1 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index 2ade485..e405fc3 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -387,14 +387,6 @@ static const struct attribute_group adt7310_attribute_group = {
 	.attrs = adt7310_attributes,
 };
 
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7310_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
-
 static irqreturn_t adt7310_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -409,15 +401,21 @@ static irqreturn_t adt7310_event_handler(int irq, void *private)
 
 	if (status & ADT7310_STAT_T_HIGH)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_ABOVE_ALARM,
-			timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	if (status & ADT7310_STAT_T_LOW)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_BELLOW_ALARM,
-			timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 	if (status & ADT7310_STAT_T_CRIT)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_ABOVE_CRIT,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
 			timestamp);
 	return IRQ_HANDLED;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 087/111] staging:iio:adc:adt7410 replace abuse of buffer events.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (85 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 086/111] staging:iio:adc:adt7310 replace abuse of buffer events Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 088/111] staging:iio:addac:adt7316 " Jonathan Cameron
                   ` (24 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/adt7410.c |   26 ++++++++++++--------------
 1 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index c102b42..85b5c1a 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -355,14 +355,6 @@ static const struct attribute_group adt7410_attribute_group = {
 	.attrs = adt7410_attributes,
 };
 
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7410_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7410_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7410_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
-
 static irqreturn_t adt7410_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -375,16 +367,22 @@ static irqreturn_t adt7410_event_handler(int irq, void *private)
 
 	if (status & ADT7410_STAT_T_HIGH)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_ABOVE_ALARM,
-			timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	if (status & ADT7410_STAT_T_LOW)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_BELLOW_ALARM,
-			timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 	if (status & ADT7410_STAT_T_CRIT)
 		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_ABOVE_CRIT,
-			timestamp);
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 
 	return IRQ_HANDLED;
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 088/111] staging:iio:addac:adt7316 replace abuse of buffer events.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (86 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 087/111] staging:iio:adc:adt7410 " Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 089/111] staging:iio:buffer - remove unused event code for " Jonathan Cameron
                   ` (23 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Currently squashed the fault condition from external
temperature sensor - lots of other issues to be fixed
with this driver which obeys almost no elements of the
abi.

V2: removed a couple of usused variables that sparse found.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/addac/adt7316.c |   82 ++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 24dd2d2..b71994e 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -462,7 +462,7 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev,
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
 		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
-				"2 - External Temperature or AIN2\n"
+				"2 - External Temperature or AIN1\n"
 				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
 	else
 		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
@@ -1762,49 +1762,71 @@ static const struct attribute_group adt7516_attribute_group = {
 	.attrs = adt7516_attributes,
 };
 
-
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW    IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW    IIO_BUFFER_EVENT_CODE(3)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT  IIO_BUFFER_EVENT_CODE(4)
-#define IIO_EVENT_CODE_ADT7516_AIN1           IIO_BUFFER_EVENT_CODE(5)
-#define IIO_EVENT_CODE_ADT7516_AIN2           IIO_BUFFER_EVENT_CODE(6)
-#define IIO_EVENT_CODE_ADT7516_AIN3           IIO_BUFFER_EVENT_CODE(7)
-#define IIO_EVENT_CODE_ADT7516_AIN4           IIO_BUFFER_EVENT_CODE(8)
-#define IIO_EVENT_CODE_ADT7316_VDD            IIO_BUFFER_EVENT_CODE(9)
-
 static irqreturn_t adt7316_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
 	struct adt7316_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 stat1, stat2;
-	int i, ret, count;
+	int ret;
+	s64 time;
 
 	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
 	if (!ret) {
-		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
-			count = 8;
-		else
-			count = 5;
+		if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+			stat1 &= 0x1F;
 
-		for (i = 0; i < count; i++) {
-			if (stat1 & (1 << i))
-				iio_push_event(chip->indio_dev, 0,
-					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
-					iio_get_time_ns());
+		time = iio_get_time_ns();
+		if (stat1 & (1 << 0))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       time);
+		if (stat1 & (1 << 1))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       time);
+		if (stat1 & (1 << 2))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       time);
+		if (stat1 & (1 << 3))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       time);
+		if (stat1 & (1 << 5))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
+		if (stat1 & (1 << 6))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
+		if (stat1 & (1 << 7))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 3,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
 		}
-	}
-
 	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2);
 	if (!ret) {
 		if (stat2 & ADT7316_INT_MASK2_VDD)
 			iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_ADT7316_VDD,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
 				       iio_get_time_ns());
 	}
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 089/111] staging:iio:buffer - remove unused event code for buffer events.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (87 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 088/111] staging:iio:addac:adt7316 " Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 090/111] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron
                   ` (22 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

These events are no longer passed up to userspace.

ad7745 - was using these events to indicate directly dataready
events.  I'm not sure when it ever makes sense to push these
to userspace so for now I've taken them to event codes 0 and 1
until someone has time to make this driver do something more
standard. (they were arbitary before, they still are, be it
in a different way!)

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7745.c |    4 ++--
 drivers/staging/iio/iio.h        |    4 ----
 drivers/staging/iio/sysfs.h      |    1 -
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
index afa2648..98b510d 100644
--- a/drivers/staging/iio/adc/ad7745.c
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -522,8 +522,8 @@ static const struct attribute_group ad774x_attribute_group = {
  * data ready events
  */
 
-#define IIO_EVENT_CODE_CAP_RDY     IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_VT_RDY      IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_CAP_RDY     0
+#define IIO_EVENT_CODE_VT_RDY      1
 
 #define IIO_EVENT_ATTR_CAP_RDY_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(cap_rdy, _evlist, _show, _store, _mask)
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 1ad9480..4dc4ff0 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -28,10 +28,6 @@
 /* naughty temporary hack to match these against the event version
    - need to flattern these together */
 enum iio_chan_type {
-	/* Need this here for now to support buffer events
-	 * set to 0  to avoid changes to ring_generic.c */
-	IIO_BUFFER = 0,
-
 	/* real channel types */
 	IIO_IN,
 	IIO_CURRENT,
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 9b855f3..dd79b58 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -170,7 +170,6 @@ struct iio_const_attr {
 #define IIO_EV_CLASS_LIGHT		IIO_LIGHT
 #define IIO_EV_CLASS_PROXIMITY		IIO_PROXIMITY
 #define IIO_EV_CLASS_TEMP		IIO_TEMP
-#define IIO_EV_CLASS_BUFFER		IIO_BUFFER
 
 #define IIO_EV_MOD_X			IIO_MOD_X
 #define IIO_EV_MOD_Y			IIO_MOD_Y
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 090/111] staging:iio:lis3l02dq remerge the two interrupt handlers.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (88 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 089/111] staging:iio:buffer - remove unused event code for " Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 091/111] staging:iio: iio_event_interfaces - clean out unused elements Jonathan Cameron
                   ` (21 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Does add a small burden to both handlers, but the gain is somewhat
simpler code.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    5 +++
 drivers/staging/iio/accel/lis3l02dq_core.c |   52 ++++++++++++---------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   30 ++++++++++------
 3 files changed, 47 insertions(+), 40 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index a910f2d..3f1d7c6 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -162,6 +162,7 @@ struct lis3l02dq_state {
 	u8				*tx;
 	u8				*rx;
 	struct mutex			buf_lock;
+	bool				trigger_on;
 };
 
 #define lis3l02dq_h_to_s(_h)				\
@@ -202,7 +203,11 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
 #define lis3l02dq_alloc_buf iio_kfifo_allocate
 #define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
 #endif
+irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
+#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
+
 #else /* CONFIG_IIO_RING_BUFFER */
+#define lis3l02dq_th lis3l02dq_noring
 
 static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 {
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 8793ee4..42261b5 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -35,6 +35,13 @@
  * It's in the likely to be added comment at the top of spi.h.
  * This means that use cannot be made of spi_write etc.
  */
+/* direct copy of the irq_default_primary_handler */
+#ifndef CONFIG_IIO_RING_BUFFER
+static irqreturn_t lis3l02dq_noring(int irq, void *private)
+{
+	return IRQ_WAKE_THREAD;
+}
+#endif
 
 /**
  * lis3l02dq_spi_read_reg_8() - read single byte from a single register
@@ -557,19 +564,13 @@ static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
 
 int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	int ret;
 	u8 control, val;
-	bool irqtofree;
 
 	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_2_ADDR,
 				       &control);
 
-	irqtofree = !!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
-
 	control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
@@ -590,9 +591,6 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 	if (ret)
 		goto error_ret;
 
-	if (irqtofree)
-		free_irq(st->us->irq, indio_dev);
-
 	ret = control;
 error_ret:
 	return ret;
@@ -602,9 +600,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					int event_code,
 					int state)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	int ret = 0;
 	u8 val, control;
 	u8 currentlyset;
@@ -636,18 +631,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 	}
 
 	if (changed) {
-		if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
-			ret = request_threaded_irq(st->us->irq,
-						   NULL,
-						   &lis3l02dq_event_handler,
-						   IRQF_TRIGGER_RISING |
-						   IRQF_ONESHOT,
-						   "lis3l02dq_event",
-						   indio_dev);
-			if (ret)
-				goto error_ret;
-		}
-
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 						&val);
@@ -661,10 +644,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 					       &control);
 		if (ret)
 			goto error_ret;
-
-		/* remove interrupt handler if nothing is still on */
-		if (!(val & 0x3f))
-			free_irq(st->us->irq, indio_dev);
 	}
 
 error_ret:
@@ -748,9 +727,18 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 	}
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
+		ret = request_threaded_irq(st->us->irq,
+					   &lis3l02dq_th,
+					   &lis3l02dq_event_handler,
+					   IRQF_TRIGGER_RISING,
+					   "lis3l02dq",
+					   st->help.indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
+
+		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
+		if (ret)
+			goto error_free_interrupt;
 	}
 
 	/* Get the device into a sane initial state */
@@ -762,6 +750,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 error_remove_trigger:
 	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
 		lis3l02dq_remove_trigger(st->help.indio_dev);
+error_free_interrupt:
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		free_irq(st->us->irq, st->help.indio_dev);
 error_uninitialize_ring:
 	iio_ring_buffer_unregister(st->help.indio_dev->ring);
 error_unreg_ring_funcs:
@@ -823,6 +814,9 @@ static int lis3l02dq_remove(struct spi_device *spi)
 	if (ret)
 		goto err_ret;
 
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		free_irq(st->us->irq, indio_dev);
+
 	lis3l02dq_remove_trigger(indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	lis3l02dq_unconfigure_ring(indio_dev);
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index d261bd6..83f2bbe 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -27,6 +27,22 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
 }
 
 /**
+ * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct iio_sw_ring_helper_state *h =  iio_dev_get_devdata(indio_dev);
+	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+
+	if (st->trigger_on) {
+		iio_trigger_poll(st->trig, iio_get_time_ns());
+		return IRQ_HANDLED;
+	} else
+		return IRQ_WAKE_THREAD;
+}
+
+/**
  * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
  **/
 ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
@@ -191,8 +207,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 						&valold);
 		if (ret)
 			goto error_ret;
-
-		free_irq(st->us->irq, st->trig);
+		st->trigger_on = false;
 /* Enable requested */
 	} else if (state && !currentlyset) {
 		/* if not set, enable requested */
@@ -203,20 +218,13 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 
 		valold = ret |
 			LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
-		ret = request_irq(st->us->irq,
-				  &iio_trigger_generic_data_rdy_poll,
-				  IRQF_TRIGGER_RISING, "lis3l02dq_datardy",
-				  st->trig);
-		if (ret)
-			goto error_ret;
 
+		st->trigger_on = true;
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
 						&valold);
-		if (ret) {
-			free_irq(st->us->irq, st->trig);
+		if (ret)
 			goto error_ret;
-		}
 	}
 
 	return 0;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 091/111] staging:iio: iio_event_interfaces - clean out unused elements
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (89 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 090/111] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 092/111] staging:iio:trigger handle name attr in core, remove old alloc and register any control_attrs via struct device Jonathan Cameron
                   ` (20 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Also removed const casting of _name that was unnecessary.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/chrdev.h            |    8 +-------
 drivers/staging/iio/industrialio-core.c |   18 +++++++-----------
 2 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 10491f0..6523273 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -60,24 +60,18 @@ struct iio_detected_event_list {
  * @det_events:		list of detected events
  * @max_events:		maximum number of events before new ones are dropped
  * @current_events:	number of events in detected list
- * @owner:		ensure the driver module owns the file, not iio
- * @private:		driver specific data
  * @_name:		used internally to store the sysfs name for minor id
  *			attribute
- * @_attrname:		the event interface's attribute name
  */
 struct iio_event_interface {
 	struct device				dev;
 	struct iio_handler			handler;
 	wait_queue_head_t			wait;
 	struct mutex				event_list_lock;
-	struct iio_detected_event_list		det_events;
+	struct list_head			det_events;
 	int					max_events;
 	int					current_events;
-	struct module				*owner;
-	void					*private;
 	char					_name[35];
-	char					_attrname[20];
 	struct list_head dev_attr_list;
 };
 
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 49560e4..b5b658c 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -112,7 +112,7 @@ int iio_push_event(struct iio_dev *dev_info,
 		ev->ev.id = ev_code;
 		ev->ev.timestamp = timestamp;
 
-		list_add_tail(&ev->list, &ev_int->det_events.list);
+		list_add_tail(&ev->list, &ev_int->det_events);
 		ev_int->current_events++;
 		mutex_unlock(&ev_int->event_list_lock);
 		wake_up_interruptible(&ev_int->wait);
@@ -146,7 +146,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
 	size_t len;
 
 	mutex_lock(&ev_int->event_list_lock);
-	if (list_empty(&ev_int->det_events.list)) {
+	if (list_empty(&ev_int->det_events)) {
 		if (filep->f_flags & O_NONBLOCK) {
 			ret = -EAGAIN;
 			goto error_mutex_unlock;
@@ -155,14 +155,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
 		/* Blocking on device; waiting for something to be there */
 		ret = wait_event_interruptible(ev_int->wait,
 					       !list_empty(&ev_int
-							   ->det_events.list));
+							   ->det_events));
 		if (ret)
 			goto error_ret;
 		/* Single access device so no one else can get the data */
 		mutex_lock(&ev_int->event_list_lock);
 	}
 
-	el = list_first_entry(&ev_int->det_events.list,
+	el = list_first_entry(&ev_int->det_events,
 			      struct iio_detected_event_list,
 			      list);
 	len = sizeof el->ev;
@@ -197,7 +197,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 	 * clear out any awaiting events. The mask will prevent
 	 * any new __iio_push_event calls running.
 	 */
-	list_for_each_entry_safe(el, t, &ev_int->det_events.list, list) {
+	list_for_each_entry_safe(el, t, &ev_int->det_events, list) {
 		list_del(&el->list);
 		kfree(el);
 	}
@@ -300,7 +300,7 @@ static int iio_setup_ev_int(struct iio_event_interface *ev_int,
 	/* discussion point - make this variable? */
 	ev_int->max_events = 10;
 	ev_int->current_events = 0;
-	INIT_LIST_HEAD(&ev_int->det_events.list);
+	INIT_LIST_HEAD(&ev_int->det_events);
 	init_waitqueue_head(&ev_int->wait);
 	ev_int->handler.private = ev_int;
 	ev_int->handler.flags = 0;
@@ -1041,17 +1041,13 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 	}
 
 	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
-		dev_info->event_interfaces[i].owner = dev_info->driver_module;
-
 		snprintf(dev_info->event_interfaces[i]._name, 20,
 			 "%s:event%d",
 			 dev_name(&dev_info->dev),
 			 i);
 
 		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
-				       (const char *)(dev_info
-						      ->event_interfaces[i]
-						      ._name),
+				       dev_info->event_interfaces[i]._name,
 				       dev_info->driver_module,
 				       &dev_info->dev);
 		if (ret) {
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 092/111] staging:iio:trigger handle name attr in core, remove old alloc and register any control_attrs via struct device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (90 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 091/111] staging:iio: iio_event_interfaces - clean out unused elements Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 093/111] drivers:staging:iio:imu:adis16400 avoid allocating rx, tx, and state separately from iio_dev Jonathan Cameron
                   ` (19 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

As the majority of triggers don't actually have any other control_attrs lets use the fact
that struct device has a groups element when we do need to have these attributes registered.
A vargs function is used to cut down on lots of building strings in every single driver
just in order to pass them into the allocate.

Also iio_allocate_trigger_named -> iio_allocate_trigger as there is no
unamed version any more, so that is now just confusing.

Blackfin tested and fixed by Michael Hennerich.

V2: Elements from Michael Hennerich's patches for the ade7758

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201_trigger.c      |   27 +-----
 drivers/staging/iio/accel/adis16203_trigger.c      |   28 +-----
 drivers/staging/iio/accel/adis16204_trigger.c      |   28 +-----
 drivers/staging/iio/accel/adis16209_trigger.c      |   28 +-----
 drivers/staging/iio/accel/adis16240_trigger.c      |   25 +-----
 drivers/staging/iio/accel/lis3l02dq_ring.c         |   27 +-----
 drivers/staging/iio/gyro/adis16260_trigger.c       |   30 +-----
 drivers/staging/iio/imu/adis16400_trigger.c        |   31 +-----
 drivers/staging/iio/industrialio-trigger.c         |  103 ++++++++++----------
 drivers/staging/iio/meter/ade7758_trigger.c        |   19 +---
 drivers/staging/iio/trigger.h                      |   26 ++----
 drivers/staging/iio/trigger/iio-trig-bfin-timer.c  |   22 ++---
 drivers/staging/iio/trigger/iio-trig-gpio.c        |   25 +-----
 .../staging/iio/trigger/iio-trig-periodic-rtc.c    |   24 ++---
 drivers/staging/iio/trigger/iio-trig-sysfs.c       |   23 ++---
 15 files changed, 110 insertions(+), 356 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c
index bfd43c5..bea917e 100644
--- a/drivers/staging/iio/accel/adis16201_trigger.c
+++ b/drivers/staging/iio/accel/adis16201_trigger.c
@@ -11,17 +11,6 @@
 #include "../trigger.h"
 #include "adis16201.h"
 
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16201_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16201_trigger_attr_group = {
-	.attrs = adis16201_trigger_attrs,
-};
-
 /**
  * adis16201_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -39,19 +28,11 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16201_state *st = indio_dev->dev_data;
-	char *name;
 
-	name = kasprintf(GFP_KERNEL,
-			 "adis16201-dev%d",
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("adis16201-dev%d", indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 	ret = request_irq(st->us->irq,
 			  &iio_trigger_generic_data_rdy_poll,
@@ -64,7 +45,6 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16201_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -78,8 +58,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -89,7 +67,6 @@ void adis16201_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16201_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c
index 72710f8..ca5db17 100644
--- a/drivers/staging/iio/accel/adis16203_trigger.c
+++ b/drivers/staging/iio/accel/adis16203_trigger.c
@@ -12,17 +12,6 @@
 #include "../trigger.h"
 #include "adis16203.h"
 
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16203_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16203_trigger_attr_group = {
-	.attrs = adis16203_trigger_attrs,
-};
-
 /**
  * adis16203_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -40,20 +29,11 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16203_state *st = indio_dev->dev_data;
-	char *name;
-
-	name = kasprintf(GFP_KERNEL,
-			 "adis16203-dev%d",
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
 
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("adis16203-dev%d", indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -68,7 +48,6 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16203_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -82,8 +61,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -93,7 +70,6 @@ void adis16203_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16203_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c
index a00668c..5e1f9ae 100644
--- a/drivers/staging/iio/accel/adis16204_trigger.c
+++ b/drivers/staging/iio/accel/adis16204_trigger.c
@@ -12,17 +12,6 @@
 #include "../trigger.h"
 #include "adis16204.h"
 
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16204_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16204_trigger_attr_group = {
-	.attrs = adis16204_trigger_attrs,
-};
-
 /**
  * adis16204_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -40,20 +29,11 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16204_state *st = indio_dev->dev_data;
-	char *name;
-
-	name = kasprintf(GFP_KERNEL,
-			 "adis16204-dev%d",
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
 
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("adis16204-dev%d", indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -68,7 +48,6 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16204_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -82,8 +61,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -93,7 +70,6 @@ void adis16204_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16204_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
index 0847ce5..211ee70 100644
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ b/drivers/staging/iio/accel/adis16209_trigger.c
@@ -21,17 +21,6 @@ static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig)
 	return IRQ_HANDLED;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16209_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16209_trigger_attr_group = {
-	.attrs = adis16209_trigger_attrs,
-};
-
 /**
  * adis16209_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -49,20 +38,11 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16209_state *st = indio_dev->dev_data;
-	char *name;
-
-	name = kasprintf(GFP_KERNEL,
-			 "adis16209-dev%d",
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
 
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("adis16209-dev%d", indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -76,7 +56,6 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16209_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -90,8 +69,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -101,7 +78,6 @@ void adis16209_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16209_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c
index d5bda92..ece3ca8 100644
--- a/drivers/staging/iio/accel/adis16240_trigger.c
+++ b/drivers/staging/iio/accel/adis16240_trigger.c
@@ -21,17 +21,6 @@ static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig)
 	return IRQ_HANDLED;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16240_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16240_trigger_attr_group = {
-	.attrs = adis16240_trigger_attrs,
-};
-
 /**
  * adis16240_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -49,17 +38,11 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16240_state *st = indio_dev->dev_data;
-	char *name;
 
-	name = kasprintf(GFP_KERNEL, "adis16240-dev%d", indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("adis16240-dev%d", indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -74,7 +57,6 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16240_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -88,8 +70,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -99,7 +79,6 @@ void adis16240_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16240_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 83f2bbe..2b7219b 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -260,17 +260,6 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	return ret;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *lis3l02dq_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group lis3l02dq_trigger_attr_group = {
-	.attrs = lis3l02dq_trigger_attrs,
-};
-
 /**
  * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
  * @trig:	the datardy trigger
@@ -301,19 +290,11 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 	struct iio_sw_ring_helper_state *h
 		= iio_dev_get_devdata(indio_dev);
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	char *name;
 
-	name = kasprintf(GFP_KERNEL,
-			 "lis3l02dq-dev%d",
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id);
 	if (!st->trig) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	st->trig->dev.parent = &st->us->dev;
@@ -321,7 +302,6 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
 	st->trig->try_reenable = &lis3l02dq_trig_try_reen;
-	st->trig->control_attrs = &lis3l02dq_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 	if (ret)
 		goto error_free_trig;
@@ -330,8 +310,6 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -343,7 +321,6 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 
 	iio_trigger_unregister(st->trig);
-	kfree(st->trig->name);
 	iio_free_trigger(st->trig);
 }
 
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
index 228272e..4f10fb5 100644
--- a/drivers/staging/iio/gyro/adis16260_trigger.c
+++ b/drivers/staging/iio/gyro/adis16260_trigger.c
@@ -12,17 +12,6 @@
 #include "../trigger.h"
 #include "adis16260.h"
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16260_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16260_trigger_attr_group = {
-	.attrs = adis16260_trigger_attrs,
-};
-
 /**
  * adis16260_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -40,20 +29,13 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16260_state *st = indio_dev->dev_data;
-	char *name;
-	name = kasprintf(GFP_KERNEL,
-			 "%s-dev%d",
-			 spi_get_device_id(st->us)->name,
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
 
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -68,7 +50,6 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16260_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -82,8 +63,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -93,7 +72,6 @@ void adis16260_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16260_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index d0c4aea..d426fba 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -12,17 +12,6 @@
 #include "../trigger.h"
 #include "adis16400.h"
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16400_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16400_trigger_attr_group = {
-	.attrs = adis16400_trigger_attrs,
-};
-
 /**
  * adis16400_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -40,21 +29,13 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct adis16400_state *st = indio_dev->dev_data;
-	char *name;
-
-	name = kasprintf(GFP_KERNEL,
-			 "%s-dev%d",
-			 spi_get_device_id(st->us)->name,
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
 
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -68,7 +49,6 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state;
-	st->trig->control_attrs = &adis16400_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
@@ -82,8 +62,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -93,7 +71,6 @@ void adis16400_remove_trigger(struct iio_dev *indio_dev)
 	struct adis16400_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 86d026b..e83edac 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -39,6 +39,19 @@ static LIST_HEAD(iio_trigger_list);
 static DEFINE_MUTEX(iio_trigger_list_lock);
 
 /**
+ * iio_trigger_read_name() - retrieve useful identifying name
+ **/
+static ssize_t iio_trigger_read_name(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", trig->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+/**
  * iio_trigger_register_sysfs() - create a device for this trigger
  * @trig_info:	the trigger
  *
@@ -46,20 +59,16 @@ static DEFINE_MUTEX(iio_trigger_list_lock);
  **/
 static int iio_trigger_register_sysfs(struct iio_trigger *trig_info)
 {
-	int ret = 0;
-
-	if (trig_info->control_attrs)
-		ret = sysfs_create_group(&trig_info->dev.kobj,
-					 trig_info->control_attrs);
-
-	return ret;
+	return sysfs_add_file_to_group(&trig_info->dev.kobj,
+				       &dev_attr_name.attr,
+				       NULL);
 }
 
 static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info)
 {
-	if (trig_info->control_attrs)
-		sysfs_remove_group(&trig_info->dev.kobj,
-				   trig_info->control_attrs);
+	sysfs_remove_file_from_group(&trig_info->dev.kobj,
+					   &dev_attr_name.attr,
+					   NULL);
 }
 
 
@@ -205,18 +214,6 @@ void iio_trigger_notify_done(struct iio_trigger *trig)
 }
 EXPORT_SYMBOL(iio_trigger_notify_done);
 
-/**
- * iio_trigger_read_name() - retrieve useful identifying name
- **/
-ssize_t iio_trigger_read_name(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	struct iio_trigger *trig = dev_get_drvdata(dev);
-	return sprintf(buf, "%s\n", trig->name);
-}
-EXPORT_SYMBOL(iio_trigger_read_name);
-
 /* Trigger Consumer related functions */
 
 /* Complexity in here.  With certain triggers (datardy) an acknowledgement
@@ -355,6 +352,7 @@ static void iio_trig_release(struct device *device)
 		irq_free_descs(trig->subirq_base,
 			       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
 	}
+	kfree(trig->name);
 	kfree(trig);
 	iio_put();
 }
@@ -381,8 +379,9 @@ static void iio_trig_subirqunmask(struct irq_data *d)
 	trig->subirqs[d->irq - trig->subirq_base].enabled = true;
 }
 
-struct iio_trigger *iio_allocate_trigger_named(const char *name)
+struct iio_trigger *iio_allocate_trigger(const char *fmt, ...)
 {
+	va_list vargs;
 	struct iio_trigger *trig;
 	trig = kzalloc(sizeof *trig, GFP_KERNEL);
 	if (trig) {
@@ -392,40 +391,40 @@ struct iio_trigger *iio_allocate_trigger_named(const char *name)
 		device_initialize(&trig->dev);
 		dev_set_drvdata(&trig->dev, (void *)trig);
 
-		if (name) {
-			mutex_init(&trig->pool_lock);
-			trig->subirq_base
-				= irq_alloc_descs(-1, 0,
-					CONFIG_IIO_CONSUMERS_PER_TRIGGER,
-					0);
-			if (trig->subirq_base < 0) {
-				kfree(trig);
-				return NULL;
-			}
-			trig->name = name;
-			trig->subirq_chip.name = name;
-			trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
-			trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
-			for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
-				irq_set_chip(trig->subirq_base + i,
-					     &trig->subirq_chip);
-				irq_set_handler(trig->subirq_base + i,
-						&handle_simple_irq);
-				irq_modify_status(trig->subirq_base + i,
-						  IRQ_NOREQUEST | IRQ_NOAUTOEN,
-						  IRQ_NOPROBE);
-			}
+		mutex_init(&trig->pool_lock);
+		trig->subirq_base
+			= irq_alloc_descs(-1, 0,
+					  CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+					  0);
+		if (trig->subirq_base < 0) {
+			kfree(trig);
+			return NULL;
+		}
+		va_start(vargs, fmt);
+		trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+		va_end(vargs);
+		if (trig->name == NULL) {
+			irq_free_descs(trig->subirq_base,
+				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+			kfree(trig);
+			return NULL;
+		}
+		trig->subirq_chip.name = trig->name;
+		trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
+		trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			irq_set_chip(trig->subirq_base + i,
+				     &trig->subirq_chip);
+			irq_set_handler(trig->subirq_base + i,
+					&handle_simple_irq);
+			irq_modify_status(trig->subirq_base + i,
+					  IRQ_NOREQUEST | IRQ_NOAUTOEN,
+					  IRQ_NOPROBE);
 		}
 		iio_get();
 	}
 	return trig;
 }
-EXPORT_SYMBOL(iio_allocate_trigger_named);
-
-struct iio_trigger *iio_allocate_trigger(void)
-{
-	return iio_allocate_trigger_named(NULL);
-}
 EXPORT_SYMBOL(iio_allocate_trigger);
 
 void iio_free_trigger(struct iio_trigger *trig)
diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
index 06c921d..5442d79 100644
--- a/drivers/staging/iio/meter/ade7758_trigger.c
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -61,21 +61,13 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct ade7758_state *st = indio_dev->dev_data;
-	char *name;
 
-	name = kasprintf(GFP_KERNEL,
-			 "%s-dev%d",
-			 spi_get_device_id(st->us)->name,
-			 indio_dev->id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	st->trig = iio_allocate_trigger_named(name);
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_name;
+		goto error_ret;
 	}
 
 	ret = request_irq(st->us->irq,
@@ -104,8 +96,6 @@ error_free_irq:
 	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-error_free_name:
-	kfree(name);
 error_ret:
 	return ret;
 }
@@ -115,7 +105,6 @@ void ade7758_remove_trigger(struct iio_dev *indio_dev)
 	struct ade7758_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
 	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 5efa0d5..7faa31a 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -24,12 +24,16 @@ struct iio_subirq {
  * @private_data:	[DRIVER] device specific data
  * @list:		[INTERN] used in maintenance of global trigger list
  * @alloc_list:		[DRIVER] used for driver specific trigger list
- * @control_attrs:	[DRIVER] sysfs attributes relevant to trigger type
  * @owner:		[DRIVER] used to monitor usage count of the trigger.
  * @use_count:		use count for the trigger
  * @set_trigger_state:	[DRIVER] switch on/off the trigger on demand
  * @try_reenable:	function to reenable the trigger when the
  *			use count is zero (may be NULL)
+ * @subirq_chip:	[INTERN] associate 'virtual' irq chip.
+ * @subirq_base:	[INTERN] base number for irqs provided by trigger.
+ * @subirqs:		[INTERN] information about the 'child' irqs.
+ * @pool:		[INTERN] bitmap of irqs currently in use.
+ * @pool_lock:		[INTERN] protection of the irq pool.
  **/
 struct iio_trigger {
 	int				id;
@@ -39,7 +43,6 @@ struct iio_trigger {
 	void				*private_data;
 	struct list_head		list;
 	struct list_head		alloc_list;
-	const struct attribute_group	*control_attrs;
 	struct module			*owner;
 	int use_count;
 
@@ -72,20 +75,6 @@ static inline void iio_get_trigger(struct iio_trigger *trig)
 };
 
 /**
- * iio_trigger_read_name() - sysfs access function to get the trigger name
- * @dev: the system device
- * @attr: device attributes for the device
- * @buf: output buffer to store the trigger name
- **/
-ssize_t iio_trigger_read_name(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf);
-
-#define IIO_TRIGGER_NAME_ATTR DEVICE_ATTR(name, S_IRUGO,		\
-					  iio_trigger_read_name,	\
-					  NULL);
-
-/**
  * iio_trigger_register() - register a trigger with the IIO core
  * @trig_info:	trigger to be registered
  **/
@@ -154,6 +143,7 @@ static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
  * @h:				the function that is actually run on trigger
  * @thread:			threaded interrupt part
  * @type:			the type of interrupt (basically if oneshot)
+ * @name:			name used to identify the trigger consumer.
  * @irq:			the corresponding irq as allocated from the
  *				trigger pool
  * @timestamp:			some devices need a timestamp grabbed as soon
@@ -179,8 +169,8 @@ irqreturn_t iio_pollfunc_store_time(int irq, void *p);
 int iio_triggered_ring_postenable(struct iio_dev *indio_dev);
 int iio_triggered_ring_predisable(struct iio_dev *indio_dev);
 
-struct iio_trigger *iio_allocate_trigger(void);
-struct iio_trigger *iio_allocate_trigger_named(const char *name);
+struct iio_trigger *iio_allocate_trigger(const char *fmt, ...)
+	__attribute__((format(printf, 1, 2)));
 void iio_free_trigger(struct iio_trigger *trig);
 
 #endif /* _IIO_TRIGGER_H_ */
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 583bef0..4f17295 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -106,11 +106,9 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
 
 static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show,
 		   iio_bfin_tmr_frequency_store);
-static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *iio_bfin_tmr_trigger_attrs[] = {
 	&dev_attr_frequency.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
 
@@ -118,6 +116,11 @@ static const struct attribute_group iio_bfin_tmr_trigger_attr_group = {
 	.attrs = iio_bfin_tmr_trigger_attrs,
 };
 
+static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = {
+	&iio_bfin_tmr_trigger_attr_group,
+	NULL
+};
+
 
 static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
 {
@@ -165,24 +168,18 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
 	st->timer_num = ret;
 	st->t = &iio_bfin_timer_code[st->timer_num];
 
-	st->trig = iio_allocate_trigger();
+	st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num);
 	if (!st->trig) {
 		ret = -ENOMEM;
 		goto out1;
 	}
 
 	st->trig->private_data = st;
-	st->trig->control_attrs = &iio_bfin_tmr_trigger_attr_group;
 	st->trig->owner = THIS_MODULE;
-	st->trig->name = kasprintf(GFP_KERNEL, "bfintmr%d", st->timer_num);
-	if (st->trig->name == NULL) {
-		ret = -ENOMEM;
-		goto out2;
-	}
-
+	st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
 	ret = iio_trigger_register(st->trig);
 	if (ret)
-		goto out3;
+		goto out2;
 
 	ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
 			  0, st->trig->name, st);
@@ -201,8 +198,6 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
 	return 0;
 out4:
 	iio_trigger_unregister(st->trig);
-out3:
-	kfree(st->trig->name);
 out2:
 	iio_put_trigger(st->trig);
 out1:
@@ -218,7 +213,6 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
 	disable_gptimers(st->t->bit);
 	free_irq(st->irq, st);
 	iio_trigger_unregister(st->trig);
-	kfree(st->trig->name);
 	iio_put_trigger(st->trig);
 	kfree(st);
 
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
index 2ce95e9..b188635 100644
--- a/drivers/staging/iio/trigger/iio-trig-gpio.c
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -47,17 +47,6 @@ static irqreturn_t iio_gpio_trigger_poll(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *iio_gpio_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group iio_gpio_trigger_attr_group = {
-	.attrs = iio_gpio_trigger_attrs,
-};
-
 static int iio_gpio_trigger_probe(struct platform_device *pdev)
 {
 	struct iio_gpio_trigger_info *trig_info;
@@ -79,7 +68,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev)
 
 		for (irq = irq_res->start; irq <= irq_res->end; irq++) {
 
-			trig = iio_allocate_trigger();
+			trig = iio_allocate_trigger("irqtrig%d", irq);
 			if (!trig) {
 				ret = -ENOMEM;
 				goto error_free_completed_registrations;
@@ -90,21 +79,15 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev)
 				ret = -ENOMEM;
 				goto error_put_trigger;
 			}
-			trig->control_attrs = &iio_gpio_trigger_attr_group;
 			trig->private_data = trig_info;
 			trig_info->irq = irq;
 			trig->owner = THIS_MODULE;
-			trig->name = kasprintf(GFP_KERNEL, "irqtrig%d", irq);
-			if (trig->name == NULL) {
-				ret = -ENOMEM;
-				goto error_free_trig_info;
-			}
 			ret = request_irq(irq, iio_gpio_trigger_poll,
 					  irqflags, trig->name, trig);
 			if (ret) {
 				dev_err(&pdev->dev,
 					"request IRQ-%d failed", irq);
-				goto error_free_name;
+				goto error_free_trig_info;
 			}
 
 			ret = iio_trigger_register(trig);
@@ -124,8 +107,6 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev)
 /* First clean up the partly allocated trigger */
 error_release_irq:
 	free_irq(irq, trig);
-error_free_name:
-	kfree(trig->name);
 error_free_trig_info:
 	kfree(trig_info);
 error_put_trigger:
@@ -138,7 +119,6 @@ error_free_completed_registrations:
 				 alloc_list) {
 		trig_info = trig->private_data;
 		free_irq(gpio_to_irq(trig_info->irq), trig);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
@@ -159,7 +139,6 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev)
 		trig_info = trig->private_data;
 		iio_trigger_unregister(trig);
 		free_irq(trig_info->irq, trig);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_put_trigger(trig);
 	}
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 24f174e..01cf7e2 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -72,20 +72,24 @@ error_ret:
 	return ret;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
 static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR,
 	    iio_trig_periodic_read_freq,
 	    iio_trig_periodic_write_freq);
 
 static struct attribute *iio_trig_prtc_attrs[] = {
 	&dev_attr_frequency.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
+
 static const struct attribute_group iio_trig_prtc_attr_group = {
 	.attrs = iio_trig_prtc_attrs,
 };
 
+static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
+	&iio_trig_prtc_attr_group,
+	NULL
+};
+
 static void iio_prtc_trigger_poll(void *private_data)
 {
 	/* Timestamp is not provided currently */
@@ -103,7 +107,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
 	for (i = 0;; i++) {
 		if (pdata[i] == NULL)
 			break;
-		trig = iio_allocate_trigger();
+		trig = iio_allocate_trigger("periodic%s", pdata[i]);
 		if (!trig) {
 			ret = -ENOMEM;
 			goto error_free_completed_registrations;
@@ -118,25 +122,19 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
 		trig->private_data = trig_info;
 		trig->owner = THIS_MODULE;
 		trig->set_trigger_state = &iio_trig_periodic_rtc_set_state;
-		trig->name = kasprintf(GFP_KERNEL, "periodic%s", pdata[i]);
-		if (trig->name == NULL) {
-			ret = -ENOMEM;
-			goto error_free_trig_info;
-		}
-
 		/* RTC access */
 		trig_info->rtc
 			= rtc_class_open(pdata[i]);
 		if (trig_info->rtc == NULL) {
 			ret = -EINVAL;
-			goto error_free_name;
+			goto error_free_trig_info;
 		}
 		trig_info->task.func = iio_prtc_trigger_poll;
 		trig_info->task.private_data = trig;
 		ret = rtc_irq_register(trig_info->rtc, &trig_info->task);
 		if (ret)
 			goto error_close_rtc;
-		trig->control_attrs = &iio_trig_prtc_attr_group;
+		trig->dev.groups = iio_trig_prtc_attr_groups;
 		ret = iio_trigger_register(trig);
 		if (ret)
 			goto error_unregister_rtc_irq;
@@ -146,8 +144,6 @@ error_unregister_rtc_irq:
 	rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 error_close_rtc:
 	rtc_class_close(trig_info->rtc);
-error_free_name:
-	kfree(trig->name);
 error_free_trig_info:
 	kfree(trig_info);
 error_put_trigger_and_remove_from_list:
@@ -161,7 +157,6 @@ error_free_completed_registrations:
 		trig_info = trig->private_data;
 		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 		rtc_class_close(trig_info->rtc);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
@@ -180,7 +175,6 @@ static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
 		trig_info = trig->private_data;
 		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 		rtc_class_close(trig_info->rtc);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c
index 6d3dee3..47248cd 100644
--- a/drivers/staging/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c
@@ -92,11 +92,9 @@ static ssize_t iio_sysfs_trigger_poll(struct device *dev,
 }
 
 static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll);
-static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *iio_sysfs_trigger_attrs[] = {
 	&dev_attr_trigger_now.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
 
@@ -104,11 +102,15 @@ static const struct attribute_group iio_sysfs_trigger_attr_group = {
 	.attrs = iio_sysfs_trigger_attrs,
 };
 
+static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = {
+	&iio_sysfs_trigger_attr_group,
+	NULL
+};
+
 static int iio_sysfs_trigger_probe(int id)
 {
 	struct iio_sysfs_trig *t;
 	int ret;
-	char *name;
 	bool foundit = false;
 	mutex_lock(&iio_syfs_trig_list_mut);
 	list_for_each_entry(t, &iio_sysfs_trig_list, l)
@@ -120,25 +122,19 @@ static int iio_sysfs_trigger_probe(int id)
 		ret = -EINVAL;
 		goto out1;
 	}
-
-	name = kasprintf(GFP_KERNEL, "sysfstrig%d", id);
-	if (name == NULL) {
-		ret = -ENOMEM;
-		goto out1;
-	}
 	t = kmalloc(sizeof(*t), GFP_KERNEL);
 	if (t == NULL) {
 		ret = -ENOMEM;
-		goto free_name;
+		goto out1;
 	}
 	t->id = id;
-	t->trig = iio_allocate_trigger_named(name);
+	t->trig = iio_allocate_trigger("sysfstrig%d", id);
 	if (!t->trig) {
 		ret = -ENOMEM;
 		goto free_t;
 	}
 
-	t->trig->control_attrs = &iio_sysfs_trigger_attr_group;
+	t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
 	t->trig->owner = THIS_MODULE;
 	t->trig->dev.parent = &iio_sysfs_trig_dev;
 
@@ -154,8 +150,6 @@ out2:
 	iio_put_trigger(t->trig);
 free_t:
 	kfree(t);
-free_name:
-	kfree(name);
 out1:
 	mutex_unlock(&iio_syfs_trig_list_mut);
 	return ret;
@@ -177,7 +171,6 @@ static int iio_sysfs_trigger_remove(int id)
 	}
 
 	iio_trigger_unregister(t->trig);
-	kfree(t->trig->name);
 	iio_free_trigger(t->trig);
 
 	list_del(&t->l);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 093/111] drivers:staging:iio:imu:adis16400 avoid allocating rx, tx, and state separately from iio_dev.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (91 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 092/111] staging:iio:trigger handle name attr in core, remove old alloc and register any control_attrs via struct device Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 094/111] staging:iio: rationalization of different buffer implementation hooks Jonathan Cameron
                   ` (18 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Uses the iio_allocate_device parameter to set aside space for adis16400_state and
____cacheline_aligned buffers for tx and rx to avoid separatel allocating them.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/adis16400.h         |    7 +-
 drivers/staging/iio/imu/adis16400_core.c    |  112 +++++++++++----------------
 drivers/staging/iio/imu/adis16400_ring.c    |   17 ++--
 drivers/staging/iio/imu/adis16400_trigger.c |   17 ++--
 4 files changed, 63 insertions(+), 90 deletions(-)

diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index 9804c41..db184d1 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -141,7 +141,6 @@ struct adis16400_chip_info {
 /**
  * struct adis16400_state - device instance specific data
  * @us:			actual spi_device
- * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
@@ -149,12 +148,12 @@ struct adis16400_chip_info {
  **/
 struct adis16400_state {
 	struct spi_device		*us;
-	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
 	struct mutex			buf_lock;
 	struct adis16400_chip_info	*variant;
+
+	u8	tx[ADIS16400_MAX_TX] ____cacheline_aligned;
+	u8	rx[ADIS16400_MAX_RX] ____cacheline_aligned;
 };
 
 int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 6419b75..0067bc7 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -66,7 +66,7 @@ static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
 				     u8 val)
 {
 	int ret;
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADIS16400_WRITE_REG(reg_address);
@@ -91,7 +91,7 @@ static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
 {
 	int ret;
 	struct spi_message msg;
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -132,7 +132,7 @@ static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
@@ -195,7 +195,7 @@ static ssize_t adis16400_write_frequency(struct device *dev,
 		size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	long val;
 	int ret;
 	u8 t;
@@ -356,11 +356,12 @@ error_ret:
 	return ret;
 }
 
-static int adis16400_initial_setup(struct adis16400_state *st)
+static int adis16400_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 prod_id, smp_prd;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	/* use low spi speed for init */
 	st->us->max_speed_hz = ADIS16400_SPI_SLOW;
@@ -368,33 +369,33 @@ static int adis16400_initial_setup(struct adis16400_state *st)
 	spi_setup(st->us);
 
 	/* Disable IRQ */
-	ret = adis16400_set_irq(st->indio_dev, false);
+	ret = adis16400_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16400_self_test(st->indio_dev);
+	ret = adis16400_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16400_check_status(st->indio_dev);
+	ret = adis16400_check_status(indio_dev);
 	if (ret) {
-		adis16400_reset(st->indio_dev);
+		adis16400_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16400_STARTUP_DELAY);
-		ret = adis16400_check_status(st->indio_dev);
+		ret = adis16400_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 	if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
-		ret = adis16400_spi_read_reg_16(st->indio_dev,
+		ret = adis16400_spi_read_reg_16(indio_dev,
 						ADIS16400_PRODUCT_ID, &prod_id);
 		if (ret)
 			goto err_ret;
@@ -406,7 +407,7 @@ static int adis16400_initial_setup(struct adis16400_state *st)
 		       prod_id, st->us->chip_select, st->us->irq);
 	}
 	/* use high spi speed if possible */
-	ret = adis16400_spi_read_reg_16(st->indio_dev,
+	ret = adis16400_spi_read_reg_16(indio_dev,
 					ADIS16400_SMPL_PRD, &smp_prd);
 	if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
 		st->us->max_speed_hz = ADIS16400_SPI_SLOW;
@@ -487,7 +488,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 			      int *val2,
 			      long mask)
 {
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	int ret;
 	s16 val16;
 	int shift;
@@ -774,55 +775,41 @@ static struct adis16400_chip_info adis16400_chips[] = {
 static int __devinit adis16400_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
-	struct adis16400_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
+	struct adis16400_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
 		ret =  -ENOMEM;
 		goto error_ret;
 	}
+	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16400_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16400_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
 	st->us = spi;
 	mutex_init(&st->buf_lock);
+
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 	st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &adis16400_attribute_group;
-	st->indio_dev->channels = st->variant->channels;
-	st->indio_dev->num_channels = st->variant->num_channels;
-	st->indio_dev->read_raw = &adis16400_read_raw;
-	st->indio_dev->write_raw = &adis16400_write_raw;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = adis16400_configure_ring(st->indio_dev);
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->attrs = &adis16400_attribute_group;
+	indio_dev->channels = st->variant->channels;
+	indio_dev->num_channels = st->variant->num_channels;
+	indio_dev->read_raw = &adis16400_read_raw;
+	indio_dev->write_raw = &adis16400_write_raw;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16400_configure_ring(indio_dev);
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
 					  st->variant->channels,
 					  st->variant->num_channels);
 	if (ret) {
@@ -831,35 +818,29 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 	}
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		ret = adis16400_probe_trigger(st->indio_dev);
+		ret = adis16400_probe_trigger(indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16400_initial_setup(st);
+	ret = adis16400_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		adis16400_remove_trigger(st->indio_dev);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		adis16400_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 error_unreg_ring_funcs:
-	adis16400_unconfigure_ring(st->indio_dev);
+	adis16400_unconfigure_ring(indio_dev);
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(st->indio_dev);
+		iio_device_unregister(indio_dev);
 	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
@@ -868,22 +849,17 @@ error_ret:
 static int adis16400_remove(struct spi_device *spi)
 {
 	int ret;
-	struct adis16400_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev =  spi_get_drvdata(spi);
 
 	ret = adis16400_stop_device(indio_dev);
 	if (ret)
 		goto err_ret;
 
 	adis16400_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(st->indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	adis16400_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
 
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
-
 	return 0;
 
 err_ret:
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index c56c655..271fe1d 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -27,7 +27,7 @@ static int adis16400_spi_read_burst(struct device *dev, u8 *rx)
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	u32 old_speed_hz = st->us->max_speed_hz;
 	int ret;
 
@@ -81,20 +81,19 @@ static const u16 read_all_tx_array[] = {
 static int adis16350_spi_read_all(struct device *dev, u8 *rx)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	struct spi_message msg;
 	int i, j = 0, ret;
 	struct spi_transfer *xfers;
 
-	xfers = kzalloc(sizeof(*xfers)*
-			st->indio_dev->ring->scan_count + 1,
-		GFP_KERNEL);
+	xfers = kzalloc(sizeof(*xfers)*indio_dev->ring->scan_count + 1,
+			GFP_KERNEL);
 	if (xfers == NULL)
 		return -ENOMEM;
 
 	for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
-		if (st->indio_dev->ring->scan_mask & (1 << i)) {
+		if (indio_dev->ring->scan_mask & (1 << i)) {
 			xfers[j].tx_buf = &read_all_tx_array[i];
 			xfers[j].bits_per_word = 16;
 			xfers[j].len = 2;
@@ -105,7 +104,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx)
 	xfers[j].len = 2;
 
 	spi_message_init(&msg);
-	for (j = 0; j < st->indio_dev->ring->scan_count + 1; j++)
+	for (j = 0; j < indio_dev->ring->scan_count + 1; j++)
 		spi_message_add_tail(&xfers[j], &msg);
 
 	ret = spi_sync(st->us, &msg);
@@ -121,7 +120,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 {
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0, j, ret = 0;
 	s16 *data;
@@ -174,7 +173,7 @@ void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 int adis16400_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring;
 
 	ring = iio_sw_rb_allocate(indio_dev);
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index d426fba..c6ec41a 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -18,17 +18,16 @@
 static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct adis16400_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = trig->private_data;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	return adis16400_set_irq(st->indio_dev, state);
+	return adis16400_set_irq(indio_dev, state);
 }
 
 int adis16400_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct adis16400_state *st = indio_dev->dev_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	st->trig = iio_allocate_trigger("%s-dev%d",
 					spi_get_device_id(st->us)->name,
@@ -47,7 +46,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
 		goto error_free_trig;
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
+	st->trig->private_data = indio_dev;
 	st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state;
 	ret = iio_trigger_register(st->trig);
 
@@ -68,9 +67,9 @@ error_ret:
 
 void adis16400_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct adis16400_state *state = indio_dev->dev_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
-	iio_trigger_unregister(state->trig);
-	free_irq(state->us->irq, state->trig);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	free_irq(st->us->irq, st->trig);
+	iio_free_trigger(st->trig);
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 094/111] staging:iio: rationalization of different buffer implementation hooks.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (92 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 093/111] drivers:staging:iio:imu:adis16400 avoid allocating rx, tx, and state separately from iio_dev Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 095/111] staging:iio:adc:AD7298: Use private data space from iio_allocate_device Jonathan Cameron
                   ` (17 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

1) move a generic helper function out of ring_sw. It applies to other buffers as well.
2) Get rid of a lot of left over function definitions.
3) Move all the access functions into static structures.
4) Introduce and use a static structure for the setup functions, preenable etc.

Some driver conversions thanks to Michael Hennerich (pulled out of patches
that would otherwise sit after this).

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201_ring.c |   16 ++-
 drivers/staging/iio/accel/adis16203_ring.c |   16 ++-
 drivers/staging/iio/accel/adis16204_ring.c |   16 ++-
 drivers/staging/iio/accel/adis16209_ring.c |   16 ++-
 drivers/staging/iio/accel/adis16240_ring.c |   16 ++-
 drivers/staging/iio/accel/lis3l02dq.h      |    4 +-
 drivers/staging/iio/accel/lis3l02dq_ring.c |   15 ++-
 drivers/staging/iio/accel/sca3000_ring.c   |   19 ++-
 drivers/staging/iio/adc/ad7298_ring.c      |   23 ++--
 drivers/staging/iio/adc/ad7476_ring.c      |   25 +++--
 drivers/staging/iio/adc/ad7606_ring.c      |   23 ++--
 drivers/staging/iio/adc/ad7887_ring.c      |   27 +++--
 drivers/staging/iio/adc/ad799x_ring.c      |   24 ++--
 drivers/staging/iio/adc/max1363_ring.c     |   26 +++--
 drivers/staging/iio/gyro/adis16260_ring.c  |   16 ++-
 drivers/staging/iio/imu/adis16400_ring.c   |   16 ++-
 drivers/staging/iio/industrialio-ring.c    |   99 ++++++++++------
 drivers/staging/iio/kfifo_buf.c            |   58 ++++++----
 drivers/staging/iio/kfifo_buf.h            |   39 +------
 drivers/staging/iio/meter/ade7758_ring.c   |   18 ++-
 drivers/staging/iio/ring_generic.h         |   18 ++-
 drivers/staging/iio/ring_sw.c              |  120 +++++++++++---------
 drivers/staging/iio/ring_sw.h              |  176 +---------------------------
 23 files changed, 363 insertions(+), 463 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 5405a38..83b5336 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -68,7 +68,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
@@ -86,7 +86,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -101,6 +101,12 @@ void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16201_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16201_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -113,12 +119,10 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->access = &ring_sw_access_funcs;
+	ring->setup_ops = &adis16201_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index a21a71d..1b8863d 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -73,7 +73,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
@@ -91,7 +91,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
+	ring->access->store_to(ring,
 			      (u8 *)data,
 			      pf->timestamp);
 
@@ -108,6 +108,12 @@ void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16203_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16203_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -120,12 +126,10 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->access = &ring_sw_access_funcs;
+	ring->setup_ops = &adis16203_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 50cd073..7d99b48 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -70,7 +70,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
@@ -88,7 +88,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -103,6 +103,12 @@ void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16204_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16204_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -115,12 +121,10 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16204_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 2c7be3b..26028e9 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -71,7 +71,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -88,7 +88,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -103,6 +103,12 @@ void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16209_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16209_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -115,12 +121,10 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16209_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index bddd699..8450f7f 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -68,7 +68,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
@@ -85,7 +85,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -100,6 +100,12 @@ void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16240_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16240_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -112,12 +118,10 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16240_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 3f1d7c6..43277d1 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -196,12 +196,12 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
 #ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
 #define lis3l02dq_free_buf iio_sw_rb_free
 #define lis3l02dq_alloc_buf iio_sw_rb_allocate
-#define lis3l02dq_register_buf_funcs iio_ring_sw_register_funcs
+#define lis3l02dq_access_funcs ring_sw_access_funcs
 #endif
 #ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
 #define lis3l02dq_free_buf iio_kfifo_free
 #define lis3l02dq_alloc_buf iio_kfifo_allocate
-#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
+#define lis3l02dq_access_funcs kfifo_access_funcs
 #endif
 irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
 #define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 2b7219b..ab11e52 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -54,12 +54,12 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
 	if (!iio_scan_mask_query(ring, index))
 		return -EINVAL;
 
-	data = kmalloc(ring->access.get_bytes_per_datum(ring),
+	data = kmalloc(ring->access->get_bytes_per_datum(ring),
 		       GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
-	ret = ring->access.read_last(ring, (u8 *)data);
+	ret = ring->access->read_last(ring, (u8 *)data);
 	if (ret)
 		goto error_free_data;
 	*val = data[iio_scan_mask_count_to_right(ring, index)];
@@ -400,6 +400,11 @@ error_ret:
 	return ret;
 }
 
+static const struct iio_ring_setup_ops lis3l02dq_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &lis3l02dq_ring_postenable,
+	.predisable = &lis3l02dq_ring_predisable,
+};
 
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
@@ -415,13 +420,11 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	lis3l02dq_register_buf_funcs(&ring->access);
+	indio_dev->ring->access = &lis3l02dq_access_funcs;
 	ring->bpe = 2;
 
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &lis3l02dq_ring_postenable;
-	ring->predisable = &lis3l02dq_ring_predisable;
+	ring->setup_ops = &lis3l02dq_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index d3c3789..7c4ff0b 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -367,6 +367,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
 		iio_put_ring_buffer(r);
 }
 
+static const struct iio_ring_access_funcs sca3000_ring_access_funcs = {
+	.read_first_n = &sca3000_read_first_n_hw_rb,
+	.get_length = &sca3000_ring_get_length,
+	.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+};
+
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
 	indio_dev->ring = sca3000_rb_allocate(indio_dev);
@@ -374,10 +380,7 @@ int sca3000_configure_ring(struct iio_dev *indio_dev)
 		return -ENOMEM;
 	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
 
-	indio_dev->ring->access.read_first_n = &sca3000_read_first_n_hw_rb;
-	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
-	indio_dev->ring->access.get_bytes_per_datum =
-		&sca3000_ring_get_bytes_per_datum;
+	indio_dev->ring->access = &sca3000_ring_access_funcs;
 
 	iio_scan_mask_set(indio_dev->ring, 0);
 	iio_scan_mask_set(indio_dev->ring, 1);
@@ -432,10 +435,14 @@ static int sca3000_hw_ring_postdisable(struct iio_dev *indio_dev)
 	return __sca3000_hw_ring_state_set(indio_dev, 0);
 }
 
+static const struct iio_ring_setup_ops sca3000_ring_setup_ops = {
+	.preenable = &sca3000_hw_ring_preenable,
+	.postdisable = &sca3000_hw_ring_postdisable,
+};
+
 void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
 {
-	indio_dev->ring->preenable = &sca3000_hw_ring_preenable;
-	indio_dev->ring->postdisable = &sca3000_hw_ring_postdisable;
+	indio_dev->ring->setup_ops = &sca3000_ring_setup_ops;
 }
 
 /**
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index d3251f7..09b1477 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -32,13 +32,13 @@ int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring),
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
 			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -74,8 +74,8 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
 			d_size += sizeof(s64) - (d_size % sizeof(s64));
 	}
 
-	if (ring->access.set_bytes_per_datum)
-		ring->access.set_bytes_per_datum(ring, d_size);
+	if (ring->access->set_bytes_per_datum)
+		ring->access->set_bytes_per_datum(ring, d_size);
 
 	st->d_size = d_size;
 
@@ -140,12 +140,18 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
 	for (i = 0; i < ring->scan_count; i++)
 		buf[i] = be16_to_cpu(st->rx_buf[i]);
 
-	indio_dev->ring->access.store_to(ring, (u8 *)buf, time_ns);
+	indio_dev->ring->access->store_to(ring, (u8 *)buf, time_ns);
 	iio_trigger_notify_done(indio_dev->trig);
 
 	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7298_ring_setup_ops = {
+	.preenable = &ad7298_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	int ret;
@@ -156,7 +162,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->access = &ring_sw_access_funcs;
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
@@ -173,10 +179,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_free_poll_func;
 	}
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->ring->preenable = &ad7298_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-
+	indio_dev->ring->setup_ops = &ad7298_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index ec1fa14..1d696ef 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -28,12 +28,13 @@ int ad7476_scan_from_ring(struct ad7476_state *st)
 	int ret;
 	u8 *ring_data;
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, ring_data);
+	ret = ring->access->read_last(ring, ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -67,8 +68,8 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev)
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	return 0;
@@ -79,7 +80,6 @@ static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
 	struct ad7476_state *st = iio_dev_get_devdata(indio_dev);
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
@@ -99,7 +99,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 		memcpy(rxbuf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
 	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
@@ -107,6 +107,12 @@ done:
 	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7476_ring_setup_ops = {
+	.preenable = &ad7476_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	struct ad7476_state *st = indio_dev->dev_data;
@@ -118,7 +124,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = kzalloc(sizeof(indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
@@ -137,10 +143,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad7476_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->setup_ops = &ad7476_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 351d58e..925806c 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -27,13 +27,13 @@ int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch)
 	int ret;
 	u16 *ring_data;
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring),
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
 			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -68,8 +68,8 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 			d_size += sizeof(s64) - (d_size % sizeof(s64));
 	}
 
-	if (ring->access.set_bytes_per_datum)
-		ring->access.set_bytes_per_datum(ring, d_size);
+	if (ring->access->set_bytes_per_datum)
+		ring->access->set_bytes_per_datum(ring, d_size);
 
 	st->d_size = d_size;
 
@@ -105,7 +105,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
 	struct ad7606_state *st = container_of(work_s, struct ad7606_state,
 						poll_work);
 	struct iio_dev *indio_dev = iio_priv_to_dev(st);
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u8 *buf;
@@ -145,13 +144,19 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
 		memcpy(buf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	ring->access.store_to(&sw_ring->buf, buf, time_ns);
+	ring->access->store_to(indio_dev->ring, buf, time_ns);
 done:
 	gpio_set_value(st->pdata->gpio_convst, 0);
 	iio_trigger_notify_done(indio_dev->trig);
 	kfree(buf);
 }
 
+static const struct iio_ring_setup_ops ad7606_ring_setup_ops = {
+	.preenable = &ad7606_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	struct ad7606_state *st = indio_dev->dev_data;
@@ -164,7 +169,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
@@ -183,9 +188,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Ring buffer functions - here trigger setup related */
 
-	indio_dev->ring->preenable = &ad7606_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->setup_ops = &ad7606_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true ;
 
 	INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index 113e97e..f3485b3 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -33,12 +33,13 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -76,8 +77,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	switch (ring->scan_mask) {
@@ -117,7 +118,6 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 	struct iio_dev *indio_dev = pf->private_data;
 	struct ad7887_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *buf;
 	int b_sent;
@@ -140,7 +140,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 		memcpy(buf + st->d_size - sizeof(s64),
 		       &time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, buf, time_ns);
 done:
 	kfree(buf);
 	iio_trigger_notify_done(indio_dev->trig);
@@ -148,6 +148,13 @@ done:
 	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7887_ring_setup_ops = {
+	.preenable = &ad7887_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+	.postdisable = &ad7887_ring_postdisable,
+};
+
 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	int ret;
@@ -158,7 +165,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
@@ -176,11 +183,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_free_pollfunc;
 	}
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad7887_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->postdisable = &ad7887_ring_postdisable;
+	indio_dev->ring->setup_ops = &ad7887_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 6906568..57dca20 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -37,12 +37,13 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 	/* Need a count of channels prior to this one */
@@ -90,8 +91,8 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	return 0;
@@ -110,7 +111,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
 	struct iio_dev *indio_dev = pf->private_data;
 	struct ad799x_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct iio_sw_ring_buffer *ring_sw = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
@@ -151,7 +151,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
 		memcpy(rxbuf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	ring->access.store_to(&ring_sw->buf, rxbuf, time_ns);
+	ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
 	kfree(rxbuf);
 	if (b_sent < 0)
@@ -162,6 +162,11 @@ out:
 	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad799x_buf_setup_ops = {
+	.preenable = &ad799x_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
 
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
@@ -173,7 +178,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
@@ -190,10 +195,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_free_poll_func;
 	}
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad799x_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->setup_ops = &ad799x_buf_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index a387a99..9638909 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -35,12 +35,13 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, ring_data);
+	ret = ring->access->read_last(ring, ring_data);
 	if (ret)
 		goto error_free_ring_data;
 	/* Need a count of channels prior to this one */
@@ -88,7 +89,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 	max1363_set_scan_mode(st);
 
 	numvals = hweight_long(st->current_mode->modemask);
-	if (ring->access.set_bytes_per_datum) {
+	if (ring->access->set_bytes_per_datum) {
 		if (ring->scan_timestamp)
 			d_size += sizeof(s64);
 		if (st->chip_info->bits != 8)
@@ -97,7 +98,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 			d_size += numvals;
 		if (ring->scan_timestamp && (d_size % 8))
 			d_size += 8 - (d_size % 8);
-		ring->access.set_bytes_per_datum(ring, d_size);
+		ring->access->set_bytes_per_datum(ring, d_size);
 	}
 
 	return 0;
@@ -108,7 +109,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
 	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
@@ -144,7 +144,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
 
 	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
 	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
@@ -152,6 +152,11 @@ done:
 	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops max1363_ring_setup_ops = {
+	.postenable = &iio_triggered_ring_postenable,
+	.preenable = &max1363_ring_preenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
 
 int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
@@ -163,8 +168,6 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
@@ -180,11 +183,10 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_free_pollfunc;
 	}
-
+	/* Effectively select the ring buffer implementation */
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->preenable = &max1363_ring_preenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->setup_ops = &max1363_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 12fbbf2..85586e4 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -74,7 +74,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -91,7 +91,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)data, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -106,6 +106,12 @@ void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16260_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16260_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -118,12 +124,10 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16260_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 271fe1d..5d99fba 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -124,7 +124,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0, j, ret = 0;
 	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;
 
 	data = kmalloc(datasize , GFP_KERNEL);
@@ -155,7 +155,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
-	ring->access.store_to(indio_dev->ring, (u8 *) data, pf->timestamp);
+	ring->access->store_to(indio_dev->ring, (u8 *) data, pf->timestamp);
 
 	iio_trigger_notify_done(indio_dev->trig);
 	kfree(data);
@@ -170,6 +170,12 @@ void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16400_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16400_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
@@ -183,12 +189,10 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16400_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 	ring->scan_mask = st->variant->default_scan_mask;
 	ring->scan_count = hweight_long(st->variant->default_scan_mask);
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 853ebe9..050f9f9 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -36,8 +36,8 @@ static int iio_ring_open(struct inode *inode, struct file *filp)
 	struct iio_ring_buffer *rb = hand->private;
 
 	filp->private_data = hand->private;
-	if (rb->access.mark_in_use)
-		rb->access.mark_in_use(rb);
+	if (rb->access->mark_in_use)
+		rb->access->mark_in_use(rb);
 
 	return 0;
 }
@@ -55,8 +55,8 @@ static int iio_ring_release(struct inode *inode, struct file *filp)
 	struct iio_ring_buffer *rb = hand->private;
 
 	clear_bit(IIO_BUSY_BIT_POS, &rb->access_handler.flags);
-	if (rb->access.unmark_in_use)
-		rb->access.unmark_in_use(rb);
+	if (rb->access->unmark_in_use)
+		rb->access->unmark_in_use(rb);
 
 	return 0;
 }
@@ -74,9 +74,9 @@ static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
 	int ret;
 
 	/* rip lots must exist. */
-	if (!rb->access.read_first_n)
+	if (!rb->access->read_first_n)
 		return -EINVAL;
-	ret = rb->access.read_first_n(rb, n, buf);
+	ret = rb->access->read_first_n(rb, n, buf);
 
 	return ret;
 }
@@ -165,8 +165,6 @@ static void __iio_free_ring_buffer_chrdev(struct iio_ring_buffer *buf)
 void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 			  struct iio_dev *dev_info)
 {
-	if (ring->access.mark_param_change)
-		ring->access.mark_param_change(ring);
 	ring->indio_dev = dev_info;
 	ring->access_handler.private = ring;
 	init_waitqueue_head(&ring->pollq);
@@ -344,9 +342,9 @@ ssize_t iio_read_ring_length(struct device *dev,
 	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	if (ring->access.get_length)
+	if (ring->access->get_length)
 		len = sprintf(buf, "%d\n",
-			      ring->access.get_length(ring));
+			      ring->access->get_length(ring));
 
 	return len;
 }
@@ -364,14 +362,14 @@ ssize_t iio_write_ring_length(struct device *dev,
 	if (ret)
 		return ret;
 
-	if (ring->access.get_length)
-		if (val == ring->access.get_length(ring))
+	if (ring->access->get_length)
+		if (val == ring->access->get_length(ring))
 			return len;
 
-	if (ring->access.set_length) {
-		ring->access.set_length(ring, val);
-		if (ring->access.mark_param_change)
-			ring->access.mark_param_change(ring);
+	if (ring->access->set_length) {
+		ring->access->set_length(ring, val);
+		if (ring->access->mark_param_change)
+			ring->access->mark_param_change(ring);
 	}
 
 	return len;
@@ -385,9 +383,9 @@ ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
 	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	if (ring->access.get_bytes_per_datum)
+	if (ring->access->get_bytes_per_datum)
 		len = sprintf(buf, "%d\n",
-			      ring->access.get_bytes_per_datum(ring));
+			      ring->access->get_bytes_per_datum(ring));
 
 	return len;
 }
@@ -413,8 +411,8 @@ ssize_t iio_store_ring_enable(struct device *dev,
 		goto done;
 	}
 	if (requested_state) {
-		if (ring->preenable) {
-			ret = ring->preenable(dev_info);
+		if (ring->setup_ops->preenable) {
+			ret = ring->setup_ops->preenable(dev_info);
 			if (ret) {
 				printk(KERN_ERR
 				       "Buffer not started:"
@@ -422,8 +420,8 @@ ssize_t iio_store_ring_enable(struct device *dev,
 				goto error_ret;
 			}
 		}
-		if (ring->access.request_update) {
-			ret = ring->access.request_update(ring);
+		if (ring->access->request_update) {
+			ret = ring->access->request_update(ring);
 			if (ret) {
 				printk(KERN_INFO
 				       "Buffer not started:"
@@ -431,16 +429,16 @@ ssize_t iio_store_ring_enable(struct device *dev,
 				goto error_ret;
 			}
 		}
-		if (ring->access.mark_in_use)
-			ring->access.mark_in_use(ring);
+		if (ring->access->mark_in_use)
+			ring->access->mark_in_use(ring);
 		/* Definitely possible for devices to support both of these.*/
 		if (dev_info->modes & INDIO_RING_TRIGGERED) {
 			if (!dev_info->trig) {
 				printk(KERN_INFO
 				       "Buffer not started: no trigger\n");
 				ret = -EINVAL;
-				if (ring->access.unmark_in_use)
-					ring->access.unmark_in_use(ring);
+				if (ring->access->unmark_in_use)
+					ring->access->unmark_in_use(ring);
 				goto error_ret;
 			}
 			dev_info->currentmode = INDIO_RING_TRIGGERED;
@@ -451,32 +449,32 @@ ssize_t iio_store_ring_enable(struct device *dev,
 			goto error_ret;
 		}
 
-		if (ring->postenable) {
+		if (ring->setup_ops->postenable) {
 
-			ret = ring->postenable(dev_info);
+			ret = ring->setup_ops->postenable(dev_info);
 			if (ret) {
 				printk(KERN_INFO
 				       "Buffer not started:"
 				       "postenable failed\n");
-				if (ring->access.unmark_in_use)
-					ring->access.unmark_in_use(ring);
+				if (ring->access->unmark_in_use)
+					ring->access->unmark_in_use(ring);
 				dev_info->currentmode = previous_mode;
-				if (ring->postdisable)
-					ring->postdisable(dev_info);
+				if (ring->setup_ops->postdisable)
+					ring->setup_ops->postdisable(dev_info);
 				goto error_ret;
 			}
 		}
 	} else {
-		if (ring->predisable) {
-			ret = ring->predisable(dev_info);
+		if (ring->setup_ops->predisable) {
+			ret = ring->setup_ops->predisable(dev_info);
 			if (ret)
 				goto error_ret;
 		}
-		if (ring->access.unmark_in_use)
-			ring->access.unmark_in_use(ring);
+		if (ring->access->unmark_in_use)
+			ring->access->unmark_in_use(ring);
 		dev_info->currentmode = INDIO_DIRECT_MODE;
-		if (ring->postdisable) {
-			ret = ring->postdisable(dev_info);
+		if (ring->setup_ops->postdisable) {
+			ret = ring->setup_ops->postdisable(dev_info);
 			if (ret)
 				goto error_ret;
 		}
@@ -584,3 +582,28 @@ error_ret:
 	return ret ? ret : len;
 }
 EXPORT_SYMBOL(iio_scan_el_ts_store);
+
+int iio_sw_ring_preenable(struct iio_dev *indio_dev)
+{
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	size_t size;
+	dev_dbg(&indio_dev->dev, "%s\n", __func__);
+	/* Check if there are any scan elements enabled, if not fail*/
+	if (!(ring->scan_count || ring->scan_timestamp))
+		return -EINVAL;
+	if (ring->scan_timestamp)
+		if (ring->scan_count)
+			/* Timestamp (aligned to s64) and data */
+			size = (((ring->scan_count * ring->bpe)
+					+ sizeof(s64) - 1)
+				& ~(sizeof(s64) - 1))
+				+ sizeof(s64);
+		else /* Timestamp only  */
+			size = sizeof(s64);
+	else /* Data only */
+		size = ring->scan_count * ring->bpe;
+	ring->access->set_bytes_per_datum(ring, size);
+
+	return 0;
+}
+EXPORT_SYMBOL(iio_sw_ring_preenable);
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index fdd5d9e..cc14b96 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -8,6 +8,8 @@
 
 #include "kfifo_buf.h"
 
+#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring)
+
 static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
 				int bytes_per_datum, int length)
 {
@@ -18,7 +20,7 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
 	return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL);
 }
 
-int iio_request_update_kfifo(struct iio_ring_buffer *r)
+static int iio_request_update_kfifo(struct iio_ring_buffer *r)
 {
 	int ret = 0;
 	struct iio_kfifo *buf = iio_to_kfifo(r);
@@ -37,31 +39,27 @@ error_ret:
 	mutex_unlock(&buf->use_lock);
 	return ret;
 }
-EXPORT_SYMBOL(iio_request_update_kfifo);
 
-void iio_mark_kfifo_in_use(struct iio_ring_buffer *r)
+static void iio_mark_kfifo_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *buf = iio_to_kfifo(r);
 	mutex_lock(&buf->use_lock);
 	buf->use_count++;
 	mutex_unlock(&buf->use_lock);
 }
-EXPORT_SYMBOL(iio_mark_kfifo_in_use);
 
-void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r)
+static void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *buf = iio_to_kfifo(r);
 	mutex_lock(&buf->use_lock);
 	buf->use_count--;
 	mutex_unlock(&buf->use_lock);
 }
-EXPORT_SYMBOL(iio_unmark_kfifo_in_use);
 
-int iio_get_length_kfifo(struct iio_ring_buffer *r)
+static int iio_get_length_kfifo(struct iio_ring_buffer *r)
 {
 	return r->length;
 }
-EXPORT_SYMBOL(iio_get_length_kfifo);
 
 static inline void __iio_init_kfifo(struct iio_kfifo *kf)
 {
@@ -108,6 +106,7 @@ struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
 	kf = kzalloc(sizeof *kf, GFP_KERNEL);
 	if (!kf)
 		return NULL;
+	kf->update_needed = true;
 	iio_ring_buffer_init(&kf->ring, indio_dev);
 	__iio_init_kfifo(kf);
 	kf->ring.dev.type = &iio_kfifo_type;
@@ -120,41 +119,37 @@ struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
 }
 EXPORT_SYMBOL(iio_kfifo_allocate);
 
-int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r)
+static int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r)
 {
 	return r->bytes_per_datum;
 }
-EXPORT_SYMBOL(iio_get_bytes_per_datum_kfifo);
 
-int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd)
+static int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd)
 {
 	if (r->bytes_per_datum != bpd) {
 		r->bytes_per_datum = bpd;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_bytes_per_datum_kfifo);
 
-int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r)
+static int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *kf = iio_to_kfifo(r);
 	kf->update_needed = true;
 	return 0;
 }
-EXPORT_SYMBOL(iio_mark_update_needed_kfifo);
 
-int iio_set_length_kfifo(struct iio_ring_buffer *r, int length)
+static int iio_set_length_kfifo(struct iio_ring_buffer *r, int length)
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_length_kfifo);
 
 void iio_kfifo_free(struct iio_ring_buffer *r)
 {
@@ -163,7 +158,9 @@ void iio_kfifo_free(struct iio_ring_buffer *r)
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
-int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
+static int iio_store_to_kfifo(struct iio_ring_buffer *r,
+			      u8 *data,
+			      s64 timestamp)
 {
 	int ret;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -179,9 +176,8 @@ int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
 	kfree(datal);
 	return 0;
 }
-EXPORT_SYMBOL(iio_store_to_kfifo);
 
-int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
+static int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
 			   size_t n, char __user *buf)
 {
 	int ret, copied;
@@ -191,5 +187,19 @@ int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
 
 	return copied;
 }
-EXPORT_SYMBOL(iio_read_first_n_kfifo);
+
+const struct iio_ring_access_funcs kfifo_access_funcs = {
+	.mark_in_use = &iio_mark_kfifo_in_use,
+	.unmark_in_use = &iio_unmark_kfifo_in_use,
+	.store_to = &iio_store_to_kfifo,
+	.read_first_n = &iio_read_first_n_kfifo,
+	.mark_param_change = &iio_mark_update_needed_kfifo,
+	.request_update = &iio_request_update_kfifo,
+	.get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
+	.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
+	.get_length = &iio_get_length_kfifo,
+	.set_length = &iio_set_length_kfifo,
+};
+EXPORT_SYMBOL(kfifo_access_funcs);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h
index eb337a4..aac3053 100644
--- a/drivers/staging/iio/kfifo_buf.h
+++ b/drivers/staging/iio/kfifo_buf.h
@@ -11,44 +11,7 @@ struct iio_kfifo {
 	struct mutex use_lock;
 };
 
-#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring)
-
-int iio_create_kfifo(struct iio_ring_buffer **r);
-int iio_init_kfifo(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
-void iio_exit_kfifo(struct iio_ring_buffer *r);
-void iio_free_kfifo(struct iio_ring_buffer *r);
-void iio_mark_kfifo_in_use(struct iio_ring_buffer *r);
-void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r);
-
-int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
-int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
-			   size_t n,
-			   char __user *buf);
-
-int iio_request_update_kfifo(struct iio_ring_buffer *r);
-int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r);
-
-int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r);
-int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd);
-int iio_get_length_kfifo(struct iio_ring_buffer *r);
-int iio_set_length_kfifo(struct iio_ring_buffer *r, int length);
-
-static inline void iio_kfifo_register_funcs(struct iio_ring_access_funcs *ra)
-{
-	ra->mark_in_use = &iio_mark_kfifo_in_use;
-	ra->unmark_in_use = &iio_unmark_kfifo_in_use;
-
-	ra->store_to = &iio_store_to_kfifo;
-	ra->read_first_n = &iio_read_first_n_kfifo;
-
-	ra->mark_param_change = &iio_mark_update_needed_kfifo;
-	ra->request_update = &iio_request_update_kfifo;
-
-	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo;
-	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo;
-	ra->get_length = &iio_get_length_kfifo;
-	ra->set_length = &iio_set_length_kfifo;
-};
+extern const struct iio_ring_access_funcs kfifo_access_funcs;
 
 struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
 void iio_kfifo_free(struct iio_ring_buffer *r);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index c8ebfd2..564555a 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -83,7 +83,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 	if (ring->scan_timestamp)
 		dat64[1] = pf->timestamp;
 
-	ring->access.store_to(ring, (u8 *)dat64, pf->timestamp);
+	ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 
@@ -118,8 +118,8 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
 			d_size += sizeof(s64) - (d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    d_size);
 
 	ade7758_write_waveform_type(&indio_dev->dev,
@@ -128,6 +128,12 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
 	return 0;
 }
 
+static const struct iio_ring_setup_ops ade7758_ring_setup_ops = {
+	.preenable = &ade7758_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 {
 	/* ensure that the trigger has been detached */
@@ -153,10 +159,8 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 	}
 
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	indio_dev->ring->preenable = &ade7758_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->ring->setup_ops = &ade7758_ring_setup_ops;
 	indio_dev->ring->owner = THIS_MODULE;
 
 	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 15d15a4..3349676 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -64,6 +64,13 @@ struct iio_ring_access_funcs {
 	int (*enable)(struct iio_ring_buffer *ring);
 };
 
+struct iio_ring_setup_ops {
+	int				(*preenable)(struct iio_dev *);
+	int				(*postenable)(struct iio_dev *);
+	int				(*predisable)(struct iio_dev *);
+	int				(*postdisable)(struct iio_dev *);
+};
+
 /**
  * struct iio_ring_buffer - general ring buffer structure
  * @dev:		ring buffer device struct
@@ -101,12 +108,8 @@ struct iio_ring_buffer {
 	u32				scan_mask;
 	bool				scan_timestamp;
 	struct iio_handler		access_handler;
-	struct iio_ring_access_funcs	access;
-	int				(*preenable)(struct iio_dev *);
-	int				(*postenable)(struct iio_dev *);
-	int				(*predisable)(struct iio_dev *);
-	int				(*postdisable)(struct iio_dev *);
-
+	const struct iio_ring_access_funcs	*access;
+	const struct iio_ring_setup_ops	*setup_ops;
 	struct list_head scan_el_dev_attr_list;
 
 	wait_queue_head_t pollq;
@@ -349,6 +352,9 @@ ssize_t iio_show_ring_enable(struct device *dev,
 #define IIO_RING_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
 					 iio_show_ring_enable,		\
 					 iio_store_ring_enable)
+
+int iio_sw_ring_preenable(struct iio_dev *indio_dev);
+
 #else /* CONFIG_IIO_RING_BUFFER */
 static inline int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
 {
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index d55757b..35896cbb 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -17,6 +17,36 @@
 #include "ring_sw.h"
 #include "trigger.h"
 
+/**
+ * struct iio_sw_ring_buffer - software ring buffer
+ * @buf:		generic ring buffer elements
+ * @data:		the ring buffer memory
+ * @read_p:		read pointer (oldest available)
+ * @write_p:		write pointer
+ * @last_written_p:	read pointer (newest available)
+ * @half_p:		half buffer length behind write_p (event generation)
+ * @use_count:		reference count to prevent resizing when in use
+ * @update_needed:	flag to indicated change in size requested
+ * @use_lock:		lock to prevent change in size when in use
+ *
+ * Note that the first element of all ring buffers must be a
+ * struct iio_ring_buffer.
+**/
+struct iio_sw_ring_buffer {
+	struct iio_ring_buffer  buf;
+	unsigned char		*data;
+	unsigned char		*read_p;
+	unsigned char		*write_p;
+	unsigned char		*last_written_p;
+	/* used to act as a point at which to signal an event */
+	unsigned char		*half_p;
+	int			use_count;
+	int			update_needed;
+	spinlock_t		use_lock;
+};
+
+#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+
 static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
 						int bytes_per_datum, int length)
 {
@@ -41,23 +71,21 @@ static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
 	kfree(ring->data);
 }
 
-void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r)
+static void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	spin_lock(&ring->use_lock);
 	ring->use_count++;
 	spin_unlock(&ring->use_lock);
 }
-EXPORT_SYMBOL(iio_mark_sw_rb_in_use);
 
-void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r)
+static void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	spin_lock(&ring->use_lock);
 	ring->use_count--;
 	spin_unlock(&ring->use_lock);
 }
-EXPORT_SYMBOL(iio_unmark_sw_rb_in_use);
 
 
 /* Ring buffer related functionality */
@@ -138,8 +166,8 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	return ret;
 }
 
-int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
-			   size_t n, char __user *buf)
+static int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
+				  size_t n, char __user *buf)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
@@ -268,14 +296,14 @@ error_ret:
 
 	return ret;
 }
-EXPORT_SYMBOL(iio_read_first_n_sw_rb);
 
-int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
+static int iio_store_to_sw_rb(struct iio_ring_buffer *r,
+			      u8 *data,
+			      s64 timestamp)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	return iio_store_to_sw_ring(ring, data, timestamp);
 }
-EXPORT_SYMBOL(iio_store_to_sw_rb);
 
 static int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring,
 				      unsigned char *data)
@@ -299,14 +327,13 @@ again:
 	return 0;
 }
 
-int iio_read_last_from_sw_rb(struct iio_ring_buffer *r,
+static int iio_read_last_from_sw_rb(struct iio_ring_buffer *r,
 			     unsigned char *data)
 {
 	return iio_read_last_from_sw_ring(iio_to_sw_ring(r), data);
 }
-EXPORT_SYMBOL(iio_read_last_from_sw_rb);
 
-int iio_request_update_sw_rb(struct iio_ring_buffer *r)
+static int iio_request_update_sw_rb(struct iio_ring_buffer *r)
 {
 	int ret = 0;
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
@@ -326,50 +353,44 @@ error_ret:
 	spin_unlock(&ring->use_lock);
 	return ret;
 }
-EXPORT_SYMBOL(iio_request_update_sw_rb);
 
-int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
+static int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	return ring->buf.bytes_per_datum;
 }
-EXPORT_SYMBOL(iio_get_bytes_per_datum_sw_rb);
 
-int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
+static int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
 {
 	if (r->bytes_per_datum != bpd) {
 		r->bytes_per_datum = bpd;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_bytes_per_datum_sw_rb);
 
-int iio_get_length_sw_rb(struct iio_ring_buffer *r)
+static int iio_get_length_sw_rb(struct iio_ring_buffer *r)
 {
 	return r->length;
 }
-EXPORT_SYMBOL(iio_get_length_sw_rb);
 
-int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length)
+static int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length)
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_length_sw_rb);
 
-int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
+static int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	ring->update_needed = true;
 	return 0;
 }
-EXPORT_SYMBOL(iio_mark_update_needed_sw_rb);
 
 static void iio_sw_rb_release(struct device *dev)
 {
@@ -412,6 +433,7 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
 	ring = kzalloc(sizeof *ring, GFP_KERNEL);
 	if (!ring)
 		return NULL;
+	ring->update_needed = true;
 	buf = &ring->buf;
 	iio_ring_buffer_init(buf, indio_dev);
 	__iio_init_sw_ring_buffer(ring);
@@ -430,36 +452,11 @@ void iio_sw_rb_free(struct iio_ring_buffer *r)
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
 
-int iio_sw_ring_preenable(struct iio_dev *indio_dev)
-{
-	struct iio_ring_buffer *ring = indio_dev->ring;
-	size_t size;
-	dev_dbg(&indio_dev->dev, "%s\n", __func__);
-	/* Check if there are any scan elements enabled, if not fail*/
-	if (!(ring->scan_count || ring->scan_timestamp))
-		return -EINVAL;
-	if (ring->scan_timestamp)
-		if (ring->scan_count)
-			/* Timestamp (aligned to s64) and data */
-			size = (((ring->scan_count * ring->bpe)
-					+ sizeof(s64) - 1)
-				& ~(sizeof(s64) - 1))
-				+ sizeof(s64);
-		else /* Timestamp only  */
-			size = sizeof(s64);
-	else /* Data only */
-		size = ring->scan_count * ring->bpe;
-	ring->access.set_bytes_per_datum(ring, size);
-
-	return 0;
-}
-EXPORT_SYMBOL(iio_sw_ring_preenable);
-
 void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
 	int len = 0;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 	char *data = kmalloc(datasize, GFP_KERNEL);
 
 	if (data == NULL) {
@@ -476,7 +473,7 @@ void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st)
 		*(s64 *)(((phys_addr_t)data + len
 				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
 			= st->last_timestamp;
-	ring->access.store_to(ring,
+	ring->access->store_to(ring,
 			(u8 *)data,
 			st->last_timestamp);
 
@@ -504,5 +501,20 @@ void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
 }
 EXPORT_SYMBOL(iio_sw_poll_func_th);
 
+const struct iio_ring_access_funcs ring_sw_access_funcs = {
+	.mark_in_use = &iio_mark_sw_rb_in_use,
+	.unmark_in_use = &iio_unmark_sw_rb_in_use,
+	.store_to = &iio_store_to_sw_rb,
+	.read_last = &iio_read_last_from_sw_rb,
+	.read_first_n = &iio_read_first_n_sw_rb,
+	.mark_param_change = &iio_mark_update_needed_sw_rb,
+	.request_update = &iio_request_update_sw_rb,
+	.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
+	.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
+	.get_length = &iio_get_length_sw_rb,
+	.set_length = &iio_set_length_sw_rb,
+};
+EXPORT_SYMBOL(ring_sw_access_funcs);
+
 MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index 84b7c5a..9344989 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -23,190 +23,18 @@
 
 #ifndef _IIO_RING_SW_H_
 #define _IIO_RING_SW_H_
-/* NEEDS COMMENTS */
-/* The intention is that this should be a separate module from the iio core.
- * This is a bit like supporting algorithms dependent on what the device
- * driver requests - some may support multiple options */
-
-
 #include "iio.h"
 #include "ring_generic.h"
 
 #if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
-
-/**
- * iio_create_sw_rb() - software ring buffer allocation
- * @r:		pointer to ring buffer pointer
- **/
-int iio_create_sw_rb(struct iio_ring_buffer **r);
-
-/**
- * iio_init_sw_rb() - initialize the software ring buffer
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @indio_dev:		industrial I/O device structure
- **/
-int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
-
-/**
- * iio_exit_sw_rb() - reverse what was done in iio_init_sw_rb
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_exit_sw_rb(struct iio_ring_buffer *r);
-
 /**
- * iio_free_sw_rb() - free memory occupied by the core ring buffer struct
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
+ * ring_sw_access_funcs - access functions for a software ring buffer
  **/
-void iio_free_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_mark_sw_rb_in_use() - reference counting to prevent incorrect chances
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r);
-
-/**
- *  iio_unmark_sw_rb_in_use() - notify the ring buffer that we don't care anymore
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r);
-
-/**
- * iio_read_last_from_sw_rb() - attempt to read the last stored datum from the rb
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @data:	where to store the last datum
- **/
-int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data);
-
-/**
- * iio_store_to_sw_rb() - store a new datum to the ring buffer
- * @r:		pointer to ring buffer instance
- * @data:	the datum to be stored including timestamp if relevant
- * @timestamp:	timestamp which will be attached to buffer events if relevant
- **/
-int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
-
-/**
- * iio_read_first_n_sw_rb() - attempt to read data from the ring buffer
- * @r:			ring buffer instance
- * @n:			number of datum's to try and read
- * @buf:		userspace buffer into which data is copied
- *			the end of the copy.
- **/
-int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
-			   size_t n,
-			   char __user *buf);
-
-/**
- * iio_request_update_sw_rb() - update params if update needed
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_request_update_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_mark_update_needed_sw_rb() - tell the ring buffer it needs a param update
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
-
-
-/**
- * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @bpd:	bytes per datum value
- **/
-int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd);
-
-/**
- * iio_get_length_sw_rb() - get how many datums the rb may contain
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_get_length_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_set_length_sw_rb() - set how many datums the rb may contain
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @length:	max number of data items for the ring buffer
- **/
-int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length);
-
-/**
- * iio_ring_sw_register_funcs() - helper function to set up rb access
- * @ra:		pointer to @iio_ring_access_funcs
- **/
-static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
-{
-	ra->mark_in_use = &iio_mark_sw_rb_in_use;
-	ra->unmark_in_use = &iio_unmark_sw_rb_in_use;
-
-	ra->store_to = &iio_store_to_sw_rb;
-	ra->read_last = &iio_read_last_from_sw_rb;
-	ra->read_first_n = &iio_read_first_n_sw_rb;
-
-	ra->mark_param_change = &iio_mark_update_needed_sw_rb;
-	ra->request_update = &iio_request_update_sw_rb;
-
-	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb;
-	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb;
-
-	ra->get_length = &iio_get_length_sw_rb;
-	ra->set_length = &iio_set_length_sw_rb;
-};
-
-/**
- * struct iio_sw_ring_buffer - software ring buffer
- * @buf:		generic ring buffer elements
- * @data:		the ring buffer memory
- * @read_p:		read pointer (oldest available)
- * @write_p:		write pointer
- * @last_written_p:	read pointer (newest available)
- * @half_p:		half buffer length behind write_p (event generation)
- * @use_count:		reference count to prevent resizing when in use
- * @update_needed:	flag to indicated change in size requested
- * @use_lock:		lock to prevent change in size when in use
- *
- * Note that the first element of all ring buffers must be a
- * struct iio_ring_buffer.
-**/
-
-struct iio_sw_ring_buffer {
-	struct iio_ring_buffer  buf;
-	unsigned char		*data;
-	unsigned char		*read_p;
-	unsigned char		*write_p;
-	unsigned char		*last_written_p;
-	/* used to act as a point at which to signal an event */
-	unsigned char		*half_p;
-	int			use_count;
-	int			update_needed;
-	spinlock_t		use_lock;
-};
-
-#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+extern const struct iio_ring_access_funcs ring_sw_access_funcs;
 
 struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
 void iio_sw_rb_free(struct iio_ring_buffer *ring);
 
-int iio_sw_ring_preenable(struct iio_dev *indio_dev);
-
 struct iio_sw_ring_helper_state {
 	struct work_struct		work_trigger_to_ring;
 	struct iio_dev			*indio_dev;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 095/111] staging:iio:adc:AD7298: Use private data space from iio_allocate_device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (93 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 094/111] staging:iio: rationalization of different buffer implementation hooks Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 096/111] staging:iio: Rip out helper for software rings Jonathan Cameron
                   ` (16 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Use private data space from iio_allocate_device

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
---
 drivers/staging/iio/adc/ad7298.h      |    5 +-
 drivers/staging/iio/adc/ad7298_core.c |   72 ++++++++++++++++-----------------
 drivers/staging/iio/adc/ad7298_ring.c |    8 ++--
 3 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h
index 718e56a..628f5ad 100644
--- a/drivers/staging/iio/adc/ad7298.h
+++ b/drivers/staging/iio/adc/ad7298.h
@@ -36,7 +36,6 @@ struct ad7298_platform_data {
 };
 
 struct ad7298_state {
-	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	struct regulator		*reg;
 	size_t				d_size;
@@ -55,11 +54,11 @@ struct ad7298_state {
 };
 
 #ifdef CONFIG_IIO_RING_BUFFER
-int ad7298_scan_from_ring(struct ad7298_state *st, long ch);
+int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch);
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7298_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_RING_BUFFER */
-static inline int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
+static inline int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
 {
 	return 0;
 }
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 35a30ae..83b3d15 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -116,7 +116,7 @@ static int ad7298_read_raw(struct iio_dev *dev_info,
 			   long m)
 {
 	int ret;
-	struct ad7298_state *st = dev_info->dev_data;
+	struct ad7298_state *st = iio_priv(dev_info);
 	unsigned int scale_uv;
 
 	switch (m) {
@@ -126,7 +126,8 @@ static int ad7298_read_raw(struct iio_dev *dev_info,
 			if (chan->address == AD7298_CH_TEMP)
 				ret = -ENODEV;
 			else
-				ret = ad7298_scan_from_ring(st, chan->address);
+				ret = ad7298_scan_from_ring(dev_info,
+							    chan->address);
 		} else {
 			if (chan->address == AD7298_CH_TEMP)
 				ret = ad7298_scan_temp(st, val);
@@ -159,13 +160,13 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 {
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
 	struct ad7298_state *st;
-	int ret;
+	int ret, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
 
 	st->reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -174,24 +175,17 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 			goto error_put_reg;
 	}
 
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->channels = ad7298_channels;
-	st->indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
-	st->indio_dev->read_raw = &ad7298_read_raw;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ad7298_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
+	indio_dev->read_raw = &ad7298_read_raw;
 
 	/* Setup default message */
 
@@ -216,41 +210,44 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 		st->int_vref_mv = AD7298_INTREF_mV;
 	}
 
-	ret = ad7298_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7298_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
 					  &ad7298_channels[1], /* skip temp0 */
 					  ARRAY_SIZE(ad7298_channels) - 1);
 	if (ret)
 		goto error_cleanup_ring;
+
 	return 0;
 
 error_cleanup_ring:
-	ad7298_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
-error_free_device:
-	iio_free_device(st->indio_dev);
+	ad7298_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static int __devexit ad7298_remove(struct spi_device *spi)
 {
-	struct ad7298_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7298_state *st = iio_priv(indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7298_ring_cleanup(indio_dev);
@@ -259,7 +256,8 @@ static int __devexit ad7298_remove(struct spi_device *spi)
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 09b1477..d0a0aeaaf 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -21,9 +21,9 @@
 
 #include "ad7298.h"
 
-int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
+int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = dev_info->ring;
 	int ret;
 	u16 *ring_data;
 
@@ -59,7 +59,7 @@ error_ret:
  **/
 static int ad7298_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct ad7298_state *st = indio_dev->dev_data;
+	struct ad7298_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 	int i, m;
@@ -121,7 +121,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
 {
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
-	struct ad7298_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7298_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u16 buf[16];
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 096/111] staging:iio: Rip out helper for software rings.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (94 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 095/111] staging:iio:adc:AD7298: Use private data space from iio_allocate_device Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 097/111] staging:iio:adc: AD7606: Consitently use indio_dev Jonathan Cameron
                   ` (15 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron, Jonathan Cameron

It seemed like a good idea at the time, it wasn't.
The code with this in place is larger and more complex for
no real gain.  Basically we've cleaned up the core around
it so much that this no longer makes sense.

Only really effects the lis3l02dq driver.

Signed-off-by: Jonathan Cameron <jic23@cam.acuk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |   10 +--
 drivers/staging/iio/accel/lis3l02dq_core.c |  154 +++++++++++-----------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   88 +++++++++-------
 drivers/staging/iio/ring_sw.c              |   49 ---------
 drivers/staging/iio/ring_sw.h              |   19 ----
 5 files changed, 111 insertions(+), 209 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 43277d1..94d9869 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -148,7 +148,6 @@ Form of high byte dependent on justification set in ctrl reg */
 #define LIS3L02DQ_MAX_RX 12
 /**
  * struct lis3l02dq_state - device instance specific data
- * @helper:		data and func pointer allowing generic functions
  * @us:			actual spi_device
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -156,17 +155,14 @@ Form of high byte dependent on justification set in ctrl reg */
  * @buf_lock:		mutex to protect tx and rx
  **/
 struct lis3l02dq_state {
-	struct iio_sw_ring_helper_state	help;
 	struct spi_device		*us;
 	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
 	struct mutex			buf_lock;
 	bool				trigger_on;
-};
 
-#define lis3l02dq_h_to_s(_h)				\
-	container_of(_h, struct lis3l02dq_state, help)
+	u8	tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
+	u8	rx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
+};
 
 int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
 			     u8 reg_address,
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 42261b5..6b5414c 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -25,7 +25,6 @@
 #include "../iio.h"
 #include "../sysfs.h"
 #include "../ring_generic.h"
-#include "../ring_sw.h"
 
 #include "accel.h"
 
@@ -52,8 +51,7 @@ static irqreturn_t lis3l02dq_noring(int irq, void *private)
 int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
 			     u8 reg_address, u8 *val)
 {
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_message msg;
 	int ret;
 	struct spi_transfer xfer = {
@@ -87,9 +85,7 @@ int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 *val)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
@@ -113,9 +109,7 @@ static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = { {
 			.tx_buf = st->tx,
 			.bits_per_word = 8,
@@ -147,9 +141,7 @@ static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
 				  u8 lower_reg_address,
 				  int *val)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	struct spi_message msg;
 	int ret;
@@ -383,8 +375,9 @@ error_ret_mutex:
 	return ret ? ret : len;
 }
 
-static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
+static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 {
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	int ret;
 	u8 val, valtest;
 
@@ -394,7 +387,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
 	val = LIS3L02DQ_DEFAULT_CTRL1;
 	/* Write suitable defaults to ctrl1 */
-	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&val);
 	if (ret) {
@@ -402,7 +395,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 		goto err_ret;
 	}
 	/* Repeat as sometimes doesn't work first time?*/
-	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
 					&val);
 	if (ret) {
@@ -412,18 +405,18 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 
 	/* Read back to check this has worked acts as loose test of correct
 	 * chip */
-	ret = lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &valtest);
 	if (ret || (valtest != val)) {
-		dev_err(&st->help.indio_dev->dev,
+		dev_err(&indio_dev->dev,
 			"device not playing ball %d %d\n", valtest, val);
 		ret = -EINVAL;
 		goto err_ret;
 	}
 
 	val = LIS3L02DQ_DEFAULT_CTRL2;
-	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
 					&val);
 	if (ret) {
@@ -432,7 +425,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
 	}
 
 	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
-	ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 					&val);
 	if (ret)
@@ -451,19 +444,16 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	u8 t;
 
 	s64 timestamp = iio_get_time_ns();
 
-	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
@@ -472,7 +462,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
@@ -481,7 +471,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
@@ -490,7 +480,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
@@ -499,7 +489,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
@@ -508,7 +498,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
@@ -517,7 +507,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 			       timestamp);
 
 	/* Ack and allow for new interrupts */
-	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
 				 &t);
 
@@ -664,61 +654,45 @@ static const struct attribute_group lis3l02dq_attribute_group = {
 static int __devinit lis3l02dq_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
-	struct lis3l02dq_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
+	struct lis3l02dq_state *st;
+	struct iio_dev *indio_dev;
+
+	indio_dev = iio_allocate_device(sizeof *st);
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
 		goto error_ret;
 	}
-
+	st = iio_priv(indio_dev);
 	/* this is only used tor removal purposes */
 	spi_set_drvdata(spi, st);
 
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*LIS3L02DQ_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*LIS3L02DQ_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
 	st->us = spi;
 	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->help.indio_dev = iio_allocate_device(0);
-	if (st->help.indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
-
-	st->help.indio_dev->name = spi->dev.driver->name;
-	st->help.indio_dev->dev.parent = &spi->dev;
-	st->help.indio_dev->num_interrupt_lines = 1;
-	st->help.indio_dev->channels = lis3l02dq_channels;
-	st->help.indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
-	st->help.indio_dev->read_raw = &lis3l02dq_read_raw;
-	st->help.indio_dev->write_raw = &lis3l02dq_write_raw;
-	st->help.indio_dev->read_event_value = &lis3l02dq_read_thresh;
-	st->help.indio_dev->write_event_value = &lis3l02dq_write_thresh;
-	st->help.indio_dev->write_event_config = &lis3l02dq_write_event_config;
-	st->help.indio_dev->read_event_config = &lis3l02dq_read_event_config;
-	st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
-	st->help.indio_dev->dev_data = (void *)(&st->help);
-	st->help.indio_dev->driver_module = THIS_MODULE;
-	st->help.indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = lis3l02dq_configure_ring(st->help.indio_dev);
+	indio_dev->name = spi->dev.driver->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->num_interrupt_lines = 1;
+	indio_dev->channels = lis3l02dq_channels;
+	indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
+	indio_dev->read_raw = &lis3l02dq_read_raw;
+	indio_dev->write_raw = &lis3l02dq_write_raw;
+	indio_dev->read_event_value = &lis3l02dq_read_thresh;
+	indio_dev->write_event_value = &lis3l02dq_write_thresh;
+	indio_dev->write_event_config = &lis3l02dq_write_event_config;
+	indio_dev->read_event_config = &lis3l02dq_read_event_config;
+	indio_dev->attrs = &lis3l02dq_attribute_group;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = lis3l02dq_configure_ring(indio_dev);
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(st->help.indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->help.indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
 					  lis3l02dq_channels,
 					  ARRAY_SIZE(lis3l02dq_channels));
 	if (ret) {
@@ -732,42 +706,36 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 					   &lis3l02dq_event_handler,
 					   IRQF_TRIGGER_RISING,
 					   "lis3l02dq",
-					   st->help.indio_dev);
+					   indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
 
-		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
+		ret = lis3l02dq_probe_trigger(indio_dev);
 		if (ret)
 			goto error_free_interrupt;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = lis3l02dq_initial_setup(st);
+	ret = lis3l02dq_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
-	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
-		lis3l02dq_remove_trigger(st->help.indio_dev);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		lis3l02dq_remove_trigger(indio_dev);
 error_free_interrupt:
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		free_irq(st->us->irq, st->help.indio_dev);
+		free_irq(st->us->irq, indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->help.indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 error_unreg_ring_funcs:
-	lis3l02dq_unconfigure_ring(st->help.indio_dev);
+	lis3l02dq_unconfigure_ring(indio_dev);
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(st->help.indio_dev);
+		iio_device_unregister(indio_dev);
 	else
-		iio_free_device(st->help.indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
@@ -776,9 +744,7 @@ error_ret:
 static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	u8 val = 0;
 
 	mutex_lock(&indio_dev->mlock);
@@ -804,8 +770,9 @@ err_ret:
 static int lis3l02dq_remove(struct spi_device *spi)
 {
 	int ret;
-	struct lis3l02dq_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->help.indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
+
 	ret = lis3l02dq_disable_all_events(indio_dev);
 	if (ret)
 		goto err_ret;
@@ -821,9 +788,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
 	iio_ring_buffer_unregister(indio_dev->ring);
 	lis3l02dq_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
 
 	return 0;
 
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index ab11e52..5029c51 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -32,8 +32,7 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
 irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
-	struct iio_sw_ring_helper_state *h =  iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	if (st->trigger_on) {
 		iio_trigger_poll(st->trig, iio_get_time_ns());
@@ -83,9 +82,10 @@ static const u8 read_all_tx_array[] = {
  * @rx_array:	(dma capable) receive array, must be at least
  *		4*number of channels
  **/
-static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
+static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
 {
-	struct iio_ring_buffer *ring = st->help.indio_dev->ring;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_transfer *xfers;
 	struct spi_message msg;
 	int ret, i, j = 0;
@@ -136,32 +136,20 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 	return ret;
 }
 
-static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
-{
-	struct iio_poll_func *pf = p;
-	struct iio_dev *indio_dev = pf->private_data;
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-
-	h->last_timestamp = pf->timestamp;
-	iio_sw_trigger_to_ring(h);
-
-	return IRQ_HANDLED;
-}
-
-static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
+static int lis3l02dq_get_ring_element(struct iio_dev *indio_dev,
 				u8 *buf)
 {
 	int ret, i;
 	u8 *rx_array ;
 	s16 *data = (s16 *)buf;
 
-	rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
+	rx_array = kzalloc(4 * (indio_dev->ring->scan_count), GFP_KERNEL);
 	if (rx_array == NULL)
 		return -ENOMEM;
-	ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
+	ret = lis3l02dq_read_all(indio_dev, rx_array);
 	if (ret < 0)
 		return ret;
-	for (i = 0; i < h->indio_dev->ring->scan_count; i++)
+	for (i = 0; i < indio_dev->ring->scan_count; i++)
 		data[i] = combine_8_to_16(rx_array[i*4+1],
 					rx_array[i*4+3]);
 	kfree(rx_array);
@@ -169,6 +157,36 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
 	return i*sizeof(data[0]);
 }
 
+static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	int len = 0;
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
+	char *data = kmalloc(datasize, GFP_KERNEL);
+
+	if (data == NULL) {
+		dev_err(indio_dev->dev.parent,
+			"memory alloc failed in ring bh");
+		return -ENOMEM;
+	}
+
+	if (ring->scan_count)
+		len = lis3l02dq_get_ring_element(indio_dev, data);
+
+	  /* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*(s64 *)(((phys_addr_t)data + len
+				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
+			= pf->timestamp;
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+
+	iio_trigger_notify_done(indio_dev->trig);
+	kfree(data);
+	return IRQ_HANDLED;
+}
+
 /* Caller responsible for locking as necessary. */
 static int
 __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
@@ -177,9 +195,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 	u8 valold;
 	bool currentlyset;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h
-				= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 /* Get the current event mask register */
 	ret = lis3l02dq_spi_read_reg_8(indio_dev,
@@ -242,19 +258,19 @@ error_ret:
 static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct lis3l02dq_state *st = trig->private_data;
+	struct iio_dev *indio_dev = trig->private_data;
 	int ret = 0;
 	u8 t;
 
-	__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, state);
+	__lis3l02dq_write_data_ready_config(&indio_dev->dev, state);
 	if (state == false) {
 		/*
 		 * A possible quirk with teh handler is currently worked around
 		 *  by ensuring outstanding read events are cleared.
 		 */
-		ret = lis3l02dq_read_all(st, NULL);
+		ret = lis3l02dq_read_all(indio_dev, NULL);
 	}
-	lis3l02dq_spi_read_reg_8(st->help.indio_dev,
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 	return ret;
@@ -266,14 +282,15 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
  */
 static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
 {
-	struct lis3l02dq_state *st = trig->private_data;
+	struct iio_dev *indio_dev = trig->private_data;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	int i;
 
 	/* If gpio still high (or high again) */
 	/* In theory possible we will need to do this several times */
 	for (i = 0; i < 5; i++)
 		if (gpio_get_value(irq_to_gpio(st->us->irq)))
-			lis3l02dq_read_all(st, NULL);
+			lis3l02dq_read_all(indio_dev, NULL);
 		else
 			break;
 	if (i == 5)
@@ -287,9 +304,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id);
 	if (!st->trig) {
@@ -299,7 +314,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
+	st->trig->private_data = indio_dev;
 	st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
 	st->trig->try_reenable = &lis3l02dq_trig_try_reen;
 	ret = iio_trigger_register(st->trig);
@@ -316,9 +331,7 @@ error_ret:
 
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	iio_trigger_unregister(st->trig);
 	iio_free_trigger(st->trig);
@@ -409,11 +422,8 @@ static const struct iio_ring_setup_ops lis3l02dq_ring_setup_ops = {
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring;
 
-	h->get_ring_element = &lis3l02dq_get_ring_element;
-
 	ring = lis3l02dq_alloc_buf(indio_dev);
 	if (!ring)
 		return -ENOMEM;
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 35896cbb..feb84e2 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -452,55 +452,6 @@ void iio_sw_rb_free(struct iio_ring_buffer *r)
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
 
-void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st)
-{
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-	int len = 0;
-	size_t datasize = ring->access->get_bytes_per_datum(ring);
-	char *data = kmalloc(datasize, GFP_KERNEL);
-
-	if (data == NULL) {
-		dev_err(st->indio_dev->dev.parent,
-			"memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		len = st->get_ring_element(st, data);
-
-	  /* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*(s64 *)(((phys_addr_t)data + len
-				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
-			= st->last_timestamp;
-	ring->access->store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-EXPORT_SYMBOL(iio_sw_trigger_to_ring);
-
-void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct iio_sw_ring_helper_state *st
-		= container_of(work_s, struct iio_sw_ring_helper_state,
-			work_trigger_to_ring);
-	iio_sw_trigger_to_ring(st);
-}
-EXPORT_SYMBOL(iio_sw_trigger_bh_to_ring);
-
-void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	h->last_timestamp = time;
-	schedule_work(&h->work_trigger_to_ring);
-}
-EXPORT_SYMBOL(iio_sw_poll_func_th);
-
 const struct iio_ring_access_funcs ring_sw_access_funcs = {
 	.mark_in_use = &iio_mark_sw_rb_in_use,
 	.unmark_in_use = &iio_unmark_sw_rb_in_use,
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index 9344989..1527163 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -23,10 +23,8 @@
 
 #ifndef _IIO_RING_SW_H_
 #define _IIO_RING_SW_H_
-#include "iio.h"
 #include "ring_generic.h"
 
-#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
 /**
  * ring_sw_access_funcs - access functions for a software ring buffer
  **/
@@ -34,21 +32,4 @@ extern const struct iio_ring_access_funcs ring_sw_access_funcs;
 
 struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
 void iio_sw_rb_free(struct iio_ring_buffer *ring);
-
-struct iio_sw_ring_helper_state {
-	struct work_struct		work_trigger_to_ring;
-	struct iio_dev			*indio_dev;
-	int (*get_ring_element)(struct iio_sw_ring_helper_state *st, u8 *buf);
-	s64				last_timestamp;
-};
-
-void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time);
-void iio_sw_trigger_bh_to_ring(struct work_struct *work_s);
-void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st);
-
-#else /* CONFIG_IIO_RING_BUFFER*/
-struct iio_sw_ring_helper_state {
-	struct iio_dev			*indio_dev;
-};
-#endif /* !CONFIG_IIO_RING_BUFFER */
 #endif /* _IIO_RING_SW_H_ */
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 097/111] staging:iio:adc: AD7606: Consitently use indio_dev
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (95 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 096/111] staging:iio: Rip out helper for software rings Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 098/111] staging:iio:adc: AD7606: Drop dev_data in favour of iio_priv() Jonathan Cameron
                   ` (14 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7606_core.c |   38 ++++++++++++++++----------------
 1 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 3b4bb3e..0db11f1 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -78,24 +78,24 @@ error_ret:
 	return ret;
 }
 
-static int ad7606_read_raw(struct iio_dev *dev_info,
+static int ad7606_read_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan,
 			   int *val,
 			   int *val2,
 			   long m)
 {
 	int ret;
-	struct ad7606_state *st = dev_info->dev_data;
+	struct ad7606_state *st = indio_dev->dev_data;
 	unsigned int scale_uv;
 
 	switch (m) {
 	case 0:
-		mutex_lock(&dev_info->mlock);
-		if (iio_ring_enabled(dev_info))
+		mutex_lock(&indio_dev->mlock);
+		if (iio_ring_enabled(indio_dev))
 			ret = ad7606_scan_from_ring(st, chan->address);
 		else
 			ret = ad7606_scan_direct(st, chan->address);
-		mutex_unlock(&dev_info->mlock);
+		mutex_unlock(&indio_dev->mlock);
 
 		if (ret < 0)
 			return ret;
@@ -114,8 +114,8 @@ static int ad7606_read_raw(struct iio_dev *dev_info,
 static ssize_t ad7606_show_range(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
 
 	return sprintf(buf, "%u\n", st->range);
 }
@@ -123,8 +123,8 @@ static ssize_t ad7606_show_range(struct device *dev,
 static ssize_t ad7606_store_range(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
 	unsigned long lval;
 
 	if (strict_strtoul(buf, 10, &lval))
@@ -133,10 +133,10 @@ static ssize_t ad7606_store_range(struct device *dev,
 		dev_err(dev, "range is not supported\n");
 		return -EINVAL;
 	}
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	gpio_set_value(st->pdata->gpio_range, lval == 10000);
 	st->range = lval;
-	mutex_unlock(&dev_info->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
 	return count;
 }
@@ -148,8 +148,8 @@ static IIO_CONST_ATTR(range_available, "5000 10000");
 static ssize_t ad7606_show_oversampling_ratio(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
 
 	return sprintf(buf, "%u\n", st->oversampling);
 }
@@ -169,8 +169,8 @@ static int ad7606_oversampling_get_index(unsigned val)
 static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
 	unsigned long lval;
 	int ret;
 
@@ -183,12 +183,12 @@ static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
 		return ret;
 	}
 
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1);
 	gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1);
 	gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1);
 	st->oversampling = lval;
-	mutex_unlock(&dev_info->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
 	return count;
 }
@@ -210,8 +210,8 @@ static mode_t ad7606_attr_is_visible(struct kobject *kobj,
 				     struct attribute *attr, int n)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
 
 	mode_t mode = attr->mode;
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 098/111] staging:iio:adc: AD7606: Drop dev_data in favour of iio_priv()
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (96 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 097/111] staging:iio:adc: AD7606: Consitently use indio_dev Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 099/111] staging:iio:adc:AD7780: Convert to new channel registration method Jonathan Cameron
                   ` (13 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Some other small cleanups including excess header removals.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7606.h      |    2 +-
 drivers/staging/iio/adc/ad7606_core.c |   22 ++++++++++------------
 drivers/staging/iio/adc/ad7606_ring.c |   11 +++++------
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 4d9d780..b8b3d8e 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -109,7 +109,7 @@ enum ad7606_supported_device_ids {
 	ID_AD7606_4
 };
 
-int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch);
+int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch);
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7606_ring_cleanup(struct iio_dev *indio_dev);
 #endif /* IIO_ADC_AD7606_H_ */
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 0db11f1..fb96802 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -7,12 +7,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
@@ -38,8 +36,9 @@ int ad7606_reset(struct ad7606_state *st)
 	return -ENODEV;
 }
 
-static int ad7606_scan_direct(struct ad7606_state *st, unsigned ch)
+static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	int ret;
 
 	st->done = false;
@@ -85,16 +84,16 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
 			   long m)
 {
 	int ret;
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned int scale_uv;
 
 	switch (m) {
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_ring_enabled(indio_dev))
-			ret = ad7606_scan_from_ring(st, chan->address);
+			ret = ad7606_scan_from_ring(indio_dev, chan->address);
 		else
-			ret = ad7606_scan_direct(st, chan->address);
+			ret = ad7606_scan_direct(indio_dev, chan->address);
 		mutex_unlock(&indio_dev->mlock);
 
 		if (ret < 0)
@@ -115,7 +114,7 @@ static ssize_t ad7606_show_range(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	return sprintf(buf, "%u\n", st->range);
 }
@@ -124,7 +123,7 @@ static ssize_t ad7606_store_range(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned long lval;
 
 	if (strict_strtoul(buf, 10, &lval))
@@ -149,7 +148,7 @@ static ssize_t ad7606_show_oversampling_ratio(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	return sprintf(buf, "%u\n", st->oversampling);
 }
@@ -170,7 +169,7 @@ static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned long lval;
 	int ret;
 
@@ -211,7 +210,7 @@ static mode_t ad7606_attr_is_visible(struct kobject *kobj,
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(indio_dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	mode_t mode = attr->mode;
 
@@ -472,7 +471,6 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
 
 	indio_dev->dev.parent = dev;
 	indio_dev->attrs = &ad7606_attribute_group;
-	indio_dev->dev_data = (void *)(st);
 	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->name = st->chip_info->name;
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 925806c..85cde6a 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -7,7 +7,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -21,9 +20,9 @@
 
 #include "ad7606.h"
 
-int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch)
+int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch)
 {
-	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int ret;
 	u16 *ring_data;
 
@@ -54,7 +53,7 @@ error_ret:
  **/
 static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 
@@ -84,7 +83,7 @@ static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
 {
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	gpio_set_value(st->pdata->gpio_convst, 1);
 
@@ -159,7 +158,7 @@ static const struct iio_ring_setup_ops ad7606_ring_setup_ops = {
 
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 099/111] staging:iio:adc:AD7780: Convert to new channel registration method
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (97 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 098/111] staging:iio:adc: AD7606: Drop dev_data in favour of iio_priv() Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 100/111] staging:iio:adc: AD7780: Use private data space from iio_allocate_device + trivial fixes Jonathan Cameron
                   ` (12 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Convert to new channel registration method

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7780.c |  113 +++++++++++++++++---------------------
 1 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index f828e83..14b16b5 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -36,9 +36,7 @@
 #define AD7780_PAT0	(1 << 0)
 
 struct ad7780_chip_info {
-	u8				bits;
-	u8				storagebits;
-	u8				res_shift;
+	struct iio_chan_spec		channel;
 };
 
 struct ad7780_state {
@@ -88,70 +86,59 @@ out:
 	return ret;
 }
 
-static ssize_t ad7780_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7780_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7780_state *st = dev_info->dev_data;
-	int ret, val, smpl;
-
-	mutex_lock(&dev_info->mlock);
-	ret = ad7780_read(st, &smpl);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	if ((smpl & AD7780_ERR) ||
-		!((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
-		return -EIO;
-
-	val = (smpl >> st->chip_info->res_shift) &
-		((1 << (st->chip_info->bits)) - 1);
-	val -= (1 << (st->chip_info->bits - 1));
-
-	if (!(smpl & AD7780_GAIN))
-		val *= 128;
-
-	return sprintf(buf, "%d\n", val);
-}
-static IIO_DEV_ATTR_IN_RAW(0, ad7780_scan, 0);
-
-static ssize_t ad7780_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7780_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits-1) */
-	unsigned int scale = (st->int_vref_mv * 100000) >>
-		(st->chip_info->bits - 1);
-
-	return sprintf(buf, "%d.%05d\n", scale / 100000, scale % 100000);
+	int ret, smpl;
+	struct ad7780_state *st = indio_dev->dev_data;
+	unsigned int scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		ret = ad7780_read(st, &smpl);
+		mutex_unlock(&indio_dev->mlock);
+
+		if (ret < 0)
+			return ret;
+
+		if ((smpl & AD7780_ERR) ||
+			!((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
+			return -EIO;
+
+		*val = (smpl >> st->chip_info->channel.scan_type.shift) &
+			((1 << (st->chip_info->channel.scan_type.realbits))
+			- 1);
+		*val -= (1 << (st->chip_info->channel.scan_type.realbits
+			- 1));
+
+		if (!(smpl & AD7780_GAIN))
+			*val *= 128;
+
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 100000)
+			>> (st->chip_info->channel.scan_type.realbits - 1);
+		*val =  scale_uv / 100000;
+		*val2 = (scale_uv % 100000) * 10;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7780_show_scale, NULL, 0);
-
-static struct attribute *ad7780_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7780_attribute_group = {
-	.attrs = ad7780_attributes,
-};
 
 static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
 	[ID_AD7780] = {
-		.bits = 24,
-		.storagebits = 32,
-		.res_shift = 8,
+		.channel = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    0, 0, IIO_ST('s', 24, 32, 8), 0),
 	},
 	[ID_AD7781] = {
-		.bits = 20,
-		.storagebits = 32,
-		.res_shift = 12,
+		.channel = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    0, 0, IIO_ST('s', 20, 32, 12), 0),
 	},
 };
 
@@ -218,17 +205,19 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 	/* Establish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad7780_attribute_group;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	st->indio_dev->channels = &st->chip_info->channel;
+	st->indio_dev->num_channels = 1;
+	st->indio_dev->read_raw = &ad7780_read_raw;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
 	/* Setup default message */
 
 	st->xfer.rx_buf = &st->data;
-	st->xfer.len = st->chip_info->storagebits / 8;
+	st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8;
 
 	spi_message_init(&st->msg);
 	spi_message_add_tail(&st->xfer, &st->msg);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 100/111] staging:iio:adc: AD7780: Use private data space from iio_allocate_device + trivial fixes
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (98 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 099/111] staging:iio:adc:AD7780: Convert to new channel registration method Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 101/111] staging:iio:ad7780 trivial unused header cleanup Jonathan Cameron
                   ` (11 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Use private data space from iio_allocate_device
Drop dev_data in favour of iio_priv()
Fix typo in gpio name
Fix error return path, free gpio
Make scale_uv type unsigned long

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7780.c |   80 +++++++++++++++++---------------------
 1 files changed, 36 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 14b16b5..06d3b6a 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -40,7 +40,6 @@ struct ad7780_chip_info {
 };
 
 struct ad7780_state {
-	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	const struct ad7780_chip_info	*chip_info;
 	struct regulator		*reg;
@@ -92,9 +91,10 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
 			   int *val2,
 			   long m)
 {
-	int ret, smpl;
-	struct ad7780_state *st = indio_dev->dev_data;
-	unsigned int scale_uv;
+	struct ad7780_state *st = iio_priv(indio_dev);
+	struct iio_chan_spec channel = st->chip_info->channel;
+	int ret, smpl = 0;
+	unsigned long scale_uv;
 
 	switch (m) {
 	case 0:
@@ -109,11 +109,9 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
 			!((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
 			return -EIO;
 
-		*val = (smpl >> st->chip_info->channel.scan_type.shift) &
-			((1 << (st->chip_info->channel.scan_type.realbits))
-			- 1);
-		*val -= (1 << (st->chip_info->channel.scan_type.realbits
-			- 1));
+		*val = (smpl >> channel.scan_type.shift) &
+			((1 << (channel.scan_type.realbits)) - 1);
+		*val -= (1 << (channel.scan_type.realbits - 1));
 
 		if (!(smpl & AD7780_GAIN))
 			*val *= 128;
@@ -121,7 +119,7 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
 		scale_uv = (st->int_vref_mv * 100000)
-			>> (st->chip_info->channel.scan_type.realbits - 1);
+			>> (channel.scan_type.realbits - 1);
 		*val =  scale_uv / 100000;
 		*val2 = (scale_uv % 100000) * 10;
 		return IIO_VAL_INT_PLUS_MICRO;
@@ -159,6 +157,7 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 {
 	struct ad7780_platform_data *pdata = spi->dev.platform_data;
 	struct ad7780_state *st;
+	struct iio_dev *indio_dev;
 	int ret, voltage_uv = 0;
 
 	if (!pdata) {
@@ -166,11 +165,11 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 		return -ENODEV;
 	}
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
 
 	st->reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -193,24 +192,16 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 	else
 		dev_warn(&spi->dev, "reference voltage unspecified\n");
 
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	/* Establish that the iio_dev is a child of the spi device */
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->channels = &st->chip_info->channel;
-	st->indio_dev->num_channels = 1;
-	st->indio_dev->read_raw = &ad7780_read_raw;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = &st->chip_info->channel;
+	indio_dev->num_channels = 1;
+	indio_dev->read_raw = &ad7780_read_raw;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
@@ -223,20 +214,20 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 	spi_message_add_tail(&st->xfer, &st->msg);
 
 	ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
-			       "AD7877 /PDRST");
+			       "AD7780 /PDRST");
 	if (ret) {
 		dev_err(&spi->dev, "failed to request GPIO PDRST\n");
-		goto error_free_device;
+		goto error_disable_reg;
 	}
 
 	ret = request_irq(spi->irq, ad7780_interrupt,
 		IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st);
 	if (ret)
-		goto error_free_device;
+		goto error_free_gpio;
 
 	disable_irq(spi->irq);
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_irq;
 
@@ -244,32 +235,33 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 
 error_free_irq:
 	free_irq(spi->irq, st);
-
-error_free_device:
-	iio_free_device(st->indio_dev);
+error_free_gpio:
+	gpio_free(st->pdata->gpio_pdrst);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+
+	iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static int ad7780_remove(struct spi_device *spi)
 {
-	struct ad7780_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7780_state *st = iio_priv(indio_dev);
+
 	free_irq(spi->irq, st);
 	gpio_free(st->pdata->gpio_pdrst);
-	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 101/111] staging:iio:ad7780 trivial unused header cleanup.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (99 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 100/111] staging:iio:adc: AD7780: Use private data space from iio_allocate_device + trivial fixes Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 102/111] staging:iio: poll func allocation clean up Jonathan Cameron
                   ` (10 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7780.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 06d3b6a..713e202 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -7,12 +7,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 102/111] staging:iio: poll func allocation clean up.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (100 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 101/111] staging:iio:ad7780 trivial unused header cleanup Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 103/111] staging:iio:core cleanup: squash tiny wrappers and use dev_set_name to handle creation of event interface name Jonathan Cameron
                   ` (9 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Add a function to neatly deal with allocation of poll functions.
Ultimately this allows us to more easily change the implementation.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201_ring.c |   22 +++++-----------
 drivers/staging/iio/accel/adis16203_ring.c |   23 ++++++-----------
 drivers/staging/iio/accel/adis16204_ring.c |   23 ++++++-----------
 drivers/staging/iio/accel/adis16209_ring.c |   24 +++++++-----------
 drivers/staging/iio/accel/adis16240_ring.c |   26 +++++++------------
 drivers/staging/iio/imu/adis16400_ring.c   |   23 +++++++-----------
 drivers/staging/iio/industrialio-trigger.c |   36 ++++++++++++++++++++++++++++
 drivers/staging/iio/trigger.h              |    8 ++++++
 8 files changed, 95 insertions(+), 90 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 83b5336..c61f981 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -96,8 +96,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 
 void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -134,26 +133,19 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_X);
 	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_Y);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16201_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16201_consumer%d",
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16201_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16201_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 1b8863d..a9a789d 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -103,8 +103,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
 
 void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -139,26 +138,20 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_X);
 	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_Y);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16203_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16203_consumer%d",
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16203_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16203_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 7d99b48..a2d36fb 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -98,8 +98,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
 
 void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -134,27 +133,21 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16204_SCAN_AUX_ADC);
 	iio_scan_mask_set(ring, ADIS16204_SCAN_TEMP);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16204_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16204_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16204_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
 
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 26028e9..390908b 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -98,8 +98,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
 
 void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -137,26 +136,21 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16209_SCAN_INCLI_Y);
 	iio_scan_mask_set(ring, ADIS16209_SCAN_ROT);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16209_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16209_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16209_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 8450f7f..0c6d781 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -95,8 +95,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
 
 void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -132,27 +131,22 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16240_SCAN_AUX_ADC);
 	iio_scan_mask_set(ring, ADIS16240_SCAN_TEMP);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16240_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16240_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16240_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
+
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 5d99fba..2589a7e 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -165,8 +165,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 
 void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -194,28 +193,24 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	ring->scan_timestamp = true;
 	ring->setup_ops = &adis16400_ring_setup_ops;
 	ring->owner = THIS_MODULE;
+	/* Set default scan mode */
 	ring->scan_mask = st->variant->default_scan_mask;
 	ring->scan_count = hweight_long(st->variant->default_scan_mask);
-	/* Set default scan mode */
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16400_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16400_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16400_consumer%d", indio_dev->id);
-	if (ret)
-		goto error_iio_free_pollfunc;
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_iio_free_pollfunc:
-	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index e83edac..6159023 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -270,6 +270,42 @@ irqreturn_t iio_pollfunc_store_time(int irq, void *p)
 }
 EXPORT_SYMBOL(iio_pollfunc_store_time);
 
+struct iio_poll_func
+*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p),
+		    irqreturn_t (*thread)(int irq, void *p),
+		    int type,
+		    void *private,
+		    const char *fmt,
+		    ...)
+{
+	va_list vargs;
+	struct iio_poll_func *pf;
+
+	pf = kmalloc(sizeof *pf, GFP_KERNEL);
+	if (pf == NULL)
+		return NULL;
+	va_start(vargs, fmt);
+	pf->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+	va_end(vargs);
+	if (pf->name == NULL) {
+		kfree(pf);
+		return NULL;
+	}
+	pf->h = h;
+	pf->thread = thread;
+	pf->type = type;
+
+	return pf;
+}
+EXPORT_SYMBOL_GPL(iio_alloc_pollfunc);
+
+void iio_dealloc_pollfunc(struct iio_poll_func *pf)
+{
+	kfree(pf->name);
+	kfree(pf);
+}
+EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc);
+
 /**
  * iio_trigger_read_currrent() - trigger consumer sysfs query which trigger
  *
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 7faa31a..f329fe1 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -160,6 +160,14 @@ struct iio_poll_func {
 	s64 timestamp;
 };
 
+struct iio_poll_func
+*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p),
+		    irqreturn_t (*thread)(int irq, void *p),
+		    int type,
+		    void *private,
+		    const char *fmt,
+		    ...);
+void iio_dealloc_pollfunc(struct iio_poll_func *pf);
 irqreturn_t iio_pollfunc_store_time(int irq, void *p);
 
 /*
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 103/111] staging:iio:core cleanup: squash tiny wrappers and use dev_set_name to handle creation of event interface name.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (101 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 102/111] staging:iio: poll func allocation clean up Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 104/111] staging:iio: ring core cleanups + check if read_last available in lis3l02dq Jonathan Cameron
                   ` (8 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/chrdev.h            |    3 --
 drivers/staging/iio/industrialio-core.c |   54 ++++++++++--------------------
 2 files changed, 18 insertions(+), 39 deletions(-)

diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 6523273..3e31ee6 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -60,8 +60,6 @@ struct iio_detected_event_list {
  * @det_events:		list of detected events
  * @max_events:		maximum number of events before new ones are dropped
  * @current_events:	number of events in detected list
- * @_name:		used internally to store the sysfs name for minor id
- *			attribute
  */
 struct iio_event_interface {
 	struct device				dev;
@@ -71,7 +69,6 @@ struct iio_event_interface {
 	struct list_head			det_events;
 	int					max_events;
 	int					current_events;
-	char					_name[35];
 	struct list_head dev_attr_list;
 };
 
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index b5b658c..9218fee 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -16,7 +16,6 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/fs.h>
-#include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
@@ -270,9 +269,10 @@ void iio_device_free_chrdev_minor(int val)
 }
 
 static int iio_setup_ev_int(struct iio_event_interface *ev_int,
-		     const char *name,
-		     struct module *owner,
-		     struct device *dev)
+			    const char *dev_name,
+			    int index,
+			    struct module *owner,
+			    struct device *dev)
 {
 	int ret, minor;
 
@@ -287,7 +287,7 @@ static int iio_setup_ev_int(struct iio_event_interface *ev_int,
 		goto error_device_put;
 	}
 	ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
-	dev_set_name(&ev_int->dev, "%s", name);
+	dev_set_name(&ev_int->dev, "%s:event%d", dev_name, index);
 
 	ret = device_add(&ev_int->dev);
 	if (ret)
@@ -798,20 +798,6 @@ void iio_free_ida_val(struct ida *this_ida, int id)
 }
 EXPORT_SYMBOL(iio_free_ida_val);
 
-static int iio_device_register_id(struct iio_dev *dev_info,
-				  struct ida *this_ida)
-{
-	dev_info->id = iio_get_new_ida_val(&iio_ida);
-	if (dev_info->id < 0)
-		return dev_info->id;
-	return 0;
-}
-
-static void iio_device_unregister_id(struct iio_dev *dev_info)
-{
-	iio_free_ida_val(&iio_ida, dev_info->id);
-}
-
 static const char * const iio_ev_type_text[] = {
 	[IIO_EV_TYPE_THRESH] = "thresh",
 	[IIO_EV_TYPE_MAG] = "mag",
@@ -832,10 +818,11 @@ static ssize_t iio_ev_state_store(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
-	unsigned long val;
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret || val < 0 || val > 1)
-		return -EINVAL;
+	bool val;
+
+	ret = strtobool(buf, &val);
+	if (ret < 0)
+		return ret;
 
 	ret = indio_dev->write_event_config(indio_dev, this_attr->address,
 					    val);
@@ -1041,13 +1028,9 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 	}
 
 	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
-		snprintf(dev_info->event_interfaces[i]._name, 20,
-			 "%s:event%d",
-			 dev_name(&dev_info->dev),
-			 i);
-
 		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
-				       dev_info->event_interfaces[i]._name,
+				       dev_name(&dev_info->dev),
+				       i,
 				       dev_info->driver_module,
 				       &dev_info->dev);
 		if (ret) {
@@ -1120,10 +1103,8 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 
 static void iio_dev_release(struct device *device)
 {
-	struct iio_dev *dev = to_iio_dev(device);
-
 	iio_put();
-	kfree(dev);
+	kfree(to_iio_dev(device));
 }
 
 static struct device_type iio_dev_type = {
@@ -1170,8 +1151,9 @@ int iio_device_register(struct iio_dev *dev_info)
 {
 	int ret;
 
-	ret = iio_device_register_id(dev_info, &iio_ida);
-	if (ret) {
+	dev_info->id = iio_get_new_ida_val(&iio_ida);
+	if (dev_info->id < 0) {
+		ret = dev_info->id;
 		dev_err(&dev_info->dev, "Failed to get id\n");
 		goto error_ret;
 	}
@@ -1202,7 +1184,7 @@ error_free_sysfs:
 error_del_device:
 	device_del(&dev_info->dev);
 error_free_ida:
-	iio_device_unregister_id(dev_info);
+	iio_free_ida_val(&iio_ida, dev_info->id);
 error_ret:
 	return ret;
 }
@@ -1214,7 +1196,7 @@ void iio_device_unregister(struct iio_dev *dev_info)
 		iio_device_unregister_trigger_consumer(dev_info);
 	iio_device_unregister_eventset(dev_info);
 	iio_device_unregister_sysfs(dev_info);
-	iio_device_unregister_id(dev_info);
+	iio_free_ida_val(&iio_ida, dev_info->id);
 	device_unregister(&dev_info->dev);
 }
 EXPORT_SYMBOL(iio_device_unregister);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 104/111] staging:iio: ring core cleanups + check if read_last available in lis3l02dq
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (102 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 103/111] staging:iio:core cleanup: squash tiny wrappers and use dev_set_name to handle creation of event interface name Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 105/111] staging:iio:accel:lis3l02dq make write_reg_8 take value not a pointer to value Jonathan Cameron
                   ` (7 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq_ring.c |    7 +-
 drivers/staging/iio/industrialio-ring.c    |  237 +++++++++++++---------------
 drivers/staging/iio/ring_generic.h         |  125 ++-------------
 3 files changed, 136 insertions(+), 233 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 5029c51..c8f29bc 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -50,9 +50,13 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
 {
 	int ret;
 	s16 *data;
+
 	if (!iio_scan_mask_query(ring, index))
 		return -EINVAL;
 
+	if (!ring->access->read_last)
+		return -EBUSY;
+
 	data = kmalloc(ring->access->get_bytes_per_datum(ring),
 		       GFP_KERNEL);
 	if (data == NULL)
@@ -61,9 +65,10 @@ 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[iio_scan_mask_count_to_right(ring, index)];
+	*val = data[bitmap_weight(&ring->scan_mask, index)];
 error_free_data:
 	kfree(data);
+
 	return ret;
 }
 
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 050f9f9..843eb82 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -71,14 +71,10 @@ static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
 				  size_t n, loff_t *f_ps)
 {
 	struct iio_ring_buffer *rb = filp->private_data;
-	int ret;
 
-	/* rip lots must exist. */
 	if (!rb->access->read_first_n)
 		return -EINVAL;
-	ret = rb->access->read_first_n(rb, n, buf);
-
-	return ret;
+	return rb->access->read_first_n(rb, n, buf);
 }
 
 /**
@@ -88,13 +84,12 @@ static unsigned int iio_ring_poll(struct file *filp,
 				  struct poll_table_struct *wait)
 {
 	struct iio_ring_buffer *rb = filp->private_data;
-	int ret = 0;
 
 	poll_wait(filp, &rb->pollq, wait);
 	if (rb->stufftoread)
 		return POLLIN | POLLRDNORM;
 	/* need a way of knowing if there may be enough data... */
-	return ret;
+	return 0;
 }
 
 static const struct file_operations iio_ring_fileops = {
@@ -117,24 +112,23 @@ EXPORT_SYMBOL(iio_ring_access_release);
 
 static inline int
 __iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
-					struct module *owner)
+				 struct module *owner,
+				 int id)
 {
-	int ret, minor;
+	int ret;
 
 	buf->access_handler.flags = 0;
-
 	buf->dev.bus = &iio_bus_type;
 	device_initialize(&buf->dev);
 
-	minor = iio_device_get_chrdev_minor();
-	if (minor < 0) {
-		ret = minor;
+	ret = iio_device_get_chrdev_minor();
+	if (ret < 0)
 		goto error_device_put;
-	}
-	buf->dev.devt = MKDEV(MAJOR(iio_devt), minor);
+
+	buf->dev.devt = MKDEV(MAJOR(iio_devt), ret);
 	dev_set_name(&buf->dev, "%s:buffer%d",
 		     dev_name(buf->dev.parent),
-		     buf->id);
+		     id);
 	ret = device_add(&buf->dev);
 	if (ret < 0) {
 		printk(KERN_ERR "failed to add the ring dev\n");
@@ -172,11 +166,10 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 EXPORT_SYMBOL(iio_ring_buffer_init);
 
 static ssize_t iio_show_scan_index(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
+				   struct device_attribute *attr,
+				   char *buf)
 {
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	return sprintf(buf, "%u\n", this_attr->c->scan_index);
+	return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index);
 }
 
 static ssize_t iio_show_fixed_type(struct device *dev,
@@ -191,6 +184,95 @@ static ssize_t iio_show_fixed_type(struct device *dev,
 		       this_attr->c->scan_type.shift);
 }
 
+static ssize_t iio_scan_el_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	int ret;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+
+	ret = iio_scan_mask_query(ring, to_iio_dev_attr(attr)->address);
+	if (ret < 0)
+		return ret;
+	return sprintf(buf, "%d\n", ret);
+}
+
+static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	ring->scan_mask &= ~(1 << bit);
+	ring->scan_count--;
+	return 0;
+}
+
+static ssize_t iio_scan_el_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t len)
+{
+	int ret = 0;
+	bool state;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	ret = iio_scan_mask_query(ring, this_attr->address);
+	if (ret < 0)
+		goto error_ret;
+	if (!state && ret) {
+		ret = iio_scan_mask_clear(ring, this_attr->address);
+		if (ret)
+			goto error_ret;
+	} else if (state && !ret) {
+		ret = iio_scan_mask_set(ring, this_attr->address);
+		if (ret)
+			goto error_ret;
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+
+}
+
+static ssize_t iio_scan_el_ts_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", ring->scan_timestamp);
+}
+
+static ssize_t iio_scan_el_ts_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t len)
+{
+	int ret = 0;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	bool state;
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	ring->scan_timestamp = state;
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
 static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 				      const struct iio_chan_spec *chan)
 {
@@ -215,7 +297,6 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 				     0,
 				     &ring->dev,
 				     &ring->scan_el_dev_attr_list);
-
 	if (ret)
 		goto error_ret;
 
@@ -281,12 +362,10 @@ int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
 {
 	int ret, i;
 
-	ring->id = id;
-
-	ret = __iio_request_ring_buffer_chrdev(ring, ring->owner);
-
+	ret = __iio_request_ring_buffer_chrdev(ring, ring->owner, id);
 	if (ret)
 		goto error_ret;
+
 	if (ring->scan_el_attrs) {
 		ret = sysfs_create_group(&ring->dev.kobj,
 					 ring->scan_el_attrs);
@@ -322,12 +401,6 @@ error_ret:
 }
 EXPORT_SYMBOL(iio_ring_buffer_register_ex);
 
-int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
-{
-	return iio_ring_buffer_register_ex(ring, id, NULL, 0);
-}
-EXPORT_SYMBOL(iio_ring_buffer_register);
-
 void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
 	__iio_ring_attr_cleanup(ring);
@@ -339,14 +412,13 @@ ssize_t iio_read_ring_length(struct device *dev,
 			     struct device_attribute *attr,
 			     char *buf)
 {
-	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
 	if (ring->access->get_length)
-		len = sprintf(buf, "%d\n",
-			      ring->access->get_length(ring));
+		return sprintf(buf, "%d\n",
+			       ring->access->get_length(ring));
 
-	return len;
+	return 0;
 }
 EXPORT_SYMBOL(iio_read_ring_length);
 
@@ -358,6 +430,7 @@ ssize_t iio_write_ring_length(struct device *dev,
 	int ret;
 	ulong val;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
 		return ret;
@@ -380,14 +453,13 @@ ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
 			  struct device_attribute *attr,
 			  char *buf)
 {
-	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
 	if (ring->access->get_bytes_per_datum)
-		len = sprintf(buf, "%d\n",
-			      ring->access->get_bytes_per_datum(ring));
+		return sprintf(buf, "%d\n",
+			       ring->access->get_bytes_per_datum(ring));
 
-	return len;
+	return 0;
 }
 EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
 
@@ -450,7 +522,6 @@ ssize_t iio_store_ring_enable(struct device *dev,
 		}
 
 		if (ring->setup_ops->postenable) {
-
 			ret = ring->setup_ops->postenable(dev_info);
 			if (ret) {
 				printk(KERN_INFO
@@ -488,6 +559,7 @@ error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_store_ring_enable);
+
 ssize_t iio_show_ring_enable(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
@@ -498,91 +570,6 @@ ssize_t iio_show_ring_enable(struct device *dev,
 }
 EXPORT_SYMBOL(iio_show_ring_enable);
 
-ssize_t iio_scan_el_show(struct device *dev,
-			 struct device_attribute *attr,
-			 char *buf)
-{
-	int ret;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = iio_scan_mask_query(ring, this_attr->address);
-	if (ret < 0)
-		return ret;
-	return sprintf(buf, "%d\n", ret);
-}
-EXPORT_SYMBOL(iio_scan_el_show);
-
-ssize_t iio_scan_el_store(struct device *dev,
-			  struct device_attribute *attr,
-			  const char *buf,
-			  size_t len)
-{
-	int ret = 0;
-	bool state;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	state = !(buf[0] == '0');
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-	ret = iio_scan_mask_query(ring, this_attr->address);
-	if (ret < 0)
-		goto error_ret;
-	if (!state && ret) {
-		ret = iio_scan_mask_clear(ring, this_attr->address);
-		if (ret)
-			goto error_ret;
-	} else if (state && !ret) {
-		ret = iio_scan_mask_set(ring, this_attr->address);
-		if (ret)
-			goto error_ret;
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-
-}
-EXPORT_SYMBOL(iio_scan_el_store);
-
-ssize_t iio_scan_el_ts_show(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", ring->scan_timestamp);
-}
-EXPORT_SYMBOL(iio_scan_el_ts_show);
-
-ssize_t iio_scan_el_ts_store(struct device *dev,
-			     struct device_attribute *attr,
-			     const char *buf,
-			     size_t len)
-{
-	int ret = 0;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	bool state;
-	state = !(buf[0] == '0');
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-	ring->scan_timestamp = state;
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-EXPORT_SYMBOL(iio_scan_el_ts_store);
-
 int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct iio_ring_buffer *ring = indio_dev->ring;
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 3349676..3f26f71 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -76,11 +76,9 @@ struct iio_ring_setup_ops {
  * @dev:		ring buffer device struct
  * @indio_dev:		industrial I/O device structure
  * @owner:		module that owns the ring buffer (for ref counting)
- * @id:			unique id number
  * @length:		[DEVICE] number of datums in ring
  * @bytes_per_datum:	[DEVICE] size of individual datum including timestamp
  * @bpe:		[DEVICE] size of individual channel value
- * @loopcount:		[INTERN] number of times the ring has looped
  * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
  *			control method is used
  * @scan_count:	[INTERN] the number of elements in the current scan mode
@@ -93,27 +91,25 @@ struct iio_ring_setup_ops {
  * @postenable:		[DRIVER] function to run after marking ring enabled
  * @predisable:		[DRIVER] function to run prior to marking ring disabled
  * @postdisable:	[DRIVER] function to run after marking ring disabled
-  **/
+ **/
 struct iio_ring_buffer {
-	struct device dev;
-	struct iio_dev *indio_dev;
-	struct module *owner;
-	int				id;
-	int				length;
-	int				bytes_per_datum;
-	int				bpe;
-	int				loopcount;
-	struct attribute_group		*scan_el_attrs;
-	int				scan_count;
-	u32				scan_mask;
-	bool				scan_timestamp;
-	struct iio_handler		access_handler;
+	struct device				dev;
+	struct iio_dev				*indio_dev;
+	struct module				*owner;
+	int					length;
+	int					bytes_per_datum;
+	int					bpe;
+	struct attribute_group			*scan_el_attrs;
+	int					scan_count;
+	unsigned long				scan_mask;
+	bool					scan_timestamp;
+	struct iio_handler			access_handler;
 	const struct iio_ring_access_funcs	*access;
-	const struct iio_ring_setup_ops	*setup_ops;
-	struct list_head scan_el_dev_attr_list;
+	const struct iio_ring_setup_ops		*setup_ops;
+	struct list_head			scan_el_dev_attr_list;
 
-	wait_queue_head_t pollq;
-	bool stufftoread;
+	wait_queue_head_t			pollq;
+	bool					stufftoread;
 };
 
 /**
@@ -135,48 +131,8 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
 {
 	ring->bytes_per_datum = bytes_per_datum;
 	ring->length = length;
-	ring->loopcount = 0;
 }
 
-/**
- * iio_scan_el_store() - sysfs scan element selection interface
- * @dev: the target device
- * @attr: the device attribute that is being processed
- * @buf: input from userspace
- * @len: length of input
- *
- * A generic function used to enable various scan elements.  In some
- * devices explicit read commands for each channel mean this is merely
- * a software switch.  In others this must actively disable the channel.
- * Complexities occur when this interacts with data ready type triggers
- * which may not reset unless every channel that is enabled is explicitly
- * read.
- **/
-ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr,
-			  const char *buf, size_t len);
-/**
- * iio_scan_el_show() -	sysfs interface to query whether a scan element
- *			is enabled or not
- * @dev: the target device
- * @attr: the device attribute that is being processed
- * @buf: output buffer
- **/
-ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr,
-			 char *buf);
-
-/**
- * iio_scan_el_ts_store() - sysfs interface to set whether a timestamp is included
- *			    in the scan.
- **/
-ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr,
-			     const char *buf, size_t len);
-/**
- * iio_scan_el_ts_show() - sysfs interface to query if a timestamp is included
- *			   in the scan.
- **/
-ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
-			    char *buf);
-
 /*
  * These are mainly provided to allow for a change of implementation if a device
  * has a large number of scan elements
@@ -243,41 +199,6 @@ static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
 };
 
 /**
- * iio_scan_mask_clear() - clear a particular element from the scan mask
- * @ring: the ring buffer whose scan mask we are interested in
- * @bit: the bit to clear
- **/
-static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
-{
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	ring->scan_mask &= ~(1 << bit);
-	ring->scan_count--;
-	return 0;
-};
-
-/**
- * iio_scan_mask_count_to_right() - how many scan elements occur before here
- * @ring: the ring buffer whose scan mask we interested in
- * @bit: which number scan element is this
- **/
-static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
-						int bit)
-{
-	int count = 0;
-	int mask = (1 << bit);
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	while (mask) {
-		mask >>= 1;
-		if (mask & ring->scan_mask)
-			count++;
-	}
-
-	return count;
-}
-
-/**
  * iio_put_ring_buffer() - notify done with buffer
  * @ring: the buffer we are done with.
  **/
@@ -286,17 +207,11 @@ static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
 	put_device(&ring->dev);
 };
 
-#define to_iio_ring_buffer(d)			\
+#define to_iio_ring_buffer(d)				\
 	container_of(d, struct iio_ring_buffer, dev)
 
 /**
- * iio_ring_buffer_register() - register the buffer with IIO core
- * @ring: the buffer to be registered
- * @id: the id of the buffer (typically 0)
- **/
-int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id);
-
-/** iio_ring_buffer_register_ex() - register the buffer with IIO core
+ * iio_ring_buffer_register_ex() - register the buffer with IIO core
  * @ring: the buffer to be registered
  * @id: the id of the buffer (typically 0)
  **/
@@ -356,10 +271,6 @@ ssize_t iio_show_ring_enable(struct device *dev,
 int iio_sw_ring_preenable(struct iio_dev *indio_dev);
 
 #else /* CONFIG_IIO_RING_BUFFER */
-static inline int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
-{
-	return 0;
-};
 
 static inline int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring,
 					      int id,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 105/111] staging:iio:accel:lis3l02dq make write_reg_8 take value not a pointer to value.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (103 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 104/111] staging:iio: ring core cleanups + check if read_last available in lis3l02dq Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 106/111] staging:iio:meter:ade7758: Use private data space from iio_allocate_device Jonathan Cameron
                   ` (6 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Silliness that has been there a long time.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    2 +-
 drivers/staging/iio/accel/lis3l02dq_core.c |   30 ++++++++++++++--------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   10 ++++----
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 94d9869..18b23ac 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -170,7 +170,7 @@ int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
 
 int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
-			      u8 *val);
+			      u8 val);
 
 int lis3l02dq_disable_all_events(struct iio_dev *indio_dev);
 
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 6b5414c..942139a 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -82,14 +82,14 @@ int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
  **/
 int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
-			      u8 *val)
+			      u8 val)
 {
 	int ret;
 	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
-	st->tx[1] = *val;
+	st->tx[1] = val;
 	ret = spi_write(st->us, st->tx, 2);
 	mutex_unlock(&st->buf_lock);
 
@@ -232,14 +232,14 @@ static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
 			return -EINVAL;
 		sval = val;
 		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
-		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, (u8 *)&sval);
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
 		break;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 		if (val & ~0xFF)
 			return -EINVAL;
 		uval = val;
 		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
-		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, &uval);
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, uval);
 		break;
 	}
 	return ret;
@@ -367,7 +367,7 @@ static ssize_t lis3l02dq_write_frequency(struct device *dev,
 
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&t);
+					t);
 
 error_ret_mutex:
 	mutex_unlock(&indio_dev->mlock);
@@ -389,7 +389,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 	/* Write suitable defaults to ctrl1 */
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 1");
 		goto err_ret;
@@ -397,7 +397,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 	/* Repeat as sometimes doesn't work first time?*/
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 1");
 		goto err_ret;
@@ -418,7 +418,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 	val = LIS3L02DQ_DEFAULT_CTRL2;
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 2");
 		goto err_ret;
@@ -427,7 +427,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-					&val);
+					val);
 	if (ret)
 		dev_err(&st->us->dev, "problem with interrupt cfg register");
 err_ret:
@@ -564,7 +564,7 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 	control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
-					&control);
+					control);
 	if (ret)
 		goto error_ret;
 	/* Also for consistency clear the mask */
@@ -577,7 +577,7 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-					&val);
+					val);
 	if (ret)
 		goto error_ret;
 
@@ -623,7 +623,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 	if (changed) {
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-						&val);
+						val);
 		if (ret)
 			goto error_ret;
 		control = val & 0x3f ?
@@ -631,7 +631,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					       LIS3L02DQ_REG_CTRL_2_ADDR,
-					       &control);
+					       control);
 		if (ret)
 			goto error_ret;
 	}
@@ -750,7 +750,7 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 	mutex_lock(&indio_dev->mlock);
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with turning device off: ctrl1");
 		goto err_ret;
@@ -758,7 +758,7 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
-					&val);
+					val);
 	if (ret)
 		dev_err(&st->us->dev, "problem with turning device off: ctrl2");
 err_ret:
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index c8f29bc..1c208d2 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -220,12 +220,12 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 		/* The double write is to overcome a hardware bug?*/
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
 		st->trigger_on = false;
@@ -243,7 +243,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 		st->trigger_on = true;
 		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
 	}
@@ -382,7 +382,7 @@ static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
 		return -EINVAL;
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&t);
+					t);
 	if (ret)
 		goto error_ret;
 
@@ -412,7 +412,7 @@ static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
 
 	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&t);
+					t);
 
 error_ret:
 	return ret;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 106/111] staging:iio:meter:ade7758: Use private data space from iio_allocate_device
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (104 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 105/111] staging:iio:accel:lis3l02dq make write_reg_8 take value not a pointer to value Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 107/111] staging:iio: implement an iio_info structure to take some of the constant elements out of iio_dev Jonathan Cameron
                   ` (5 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

Use private data space from iio_allocate_device.
Drop dev_data in favor of iio_priv().
Fix indention issues from previous patches.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/meter/ade7758.h         |   10 +--
 drivers/staging/iio/meter/ade7758_core.c    |   92 +++++++++++++--------------
 drivers/staging/iio/meter/ade7758_ring.c    |   12 ++--
 drivers/staging/iio/meter/ade7758_trigger.c |   18 +++---
 4 files changed, 62 insertions(+), 70 deletions(-)

diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index 372a9f6..fd74e15 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -111,7 +111,6 @@
 /**
  * struct ade7758_state - device instance specific data
  * @us:			actual spi_device
- * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
@@ -119,21 +118,20 @@
  **/
 struct ade7758_state {
 	struct spi_device	*us;
-	struct iio_dev		*indio_dev;
 	struct iio_trigger	*trig;
 	u8			*tx;
 	u8			*rx;
 	struct mutex		buf_lock;
 	u32			available_scan_masks[AD7758_NUM_WAVESRC];
 	struct iio_chan_spec	*ade7758_ring_channels;
-	struct spi_transfer		ring_xfer[4];
-	struct spi_message		ring_msg;
+	struct spi_transfer	ring_xfer[4];
+	struct spi_message	ring_msg;
 	/*
 	 * DMA (thus cache coherency maintenance) requires the
 	 * transfer buffers to live in their own cache lines.
 	 */
-	unsigned char			rx_buf[8] ____cacheline_aligned;
-	unsigned char			tx_buf[8];
+	unsigned char		rx_buf[8] ____cacheline_aligned;
+	unsigned char		tx_buf[8];
 
 };
 #ifdef CONFIG_IIO_RING_BUFFER
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 42682ad..d9dfd83 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -30,7 +30,7 @@ int ade7758_spi_write_reg_8(struct device *dev,
 {
 	int ret;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADE7758_WRITE_REG(reg_address);
@@ -49,7 +49,7 @@ static int ade7758_spi_write_reg_16(struct device *dev,
 	int ret;
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -78,7 +78,7 @@ static int ade7758_spi_write_reg_24(struct device *dev,
 	int ret;
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -107,7 +107,7 @@ int ade7758_spi_read_reg_8(struct device *dev,
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
@@ -150,7 +150,7 @@ static int ade7758_spi_read_reg_16(struct device *dev,
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
@@ -196,7 +196,7 @@ static int ade7758_spi_read_reg_24(struct device *dev,
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
@@ -485,10 +485,11 @@ static int ade7758_stop_device(struct device *dev)
 	return ret;
 }
 
-static int ade7758_initial_setup(struct ade7758_state *st)
+static int ade7758_initial_setup(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = iio_priv(indio_dev);
+	struct device *dev = &indio_dev->dev;
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* use low spi speed for init */
 	st->us->mode = SPI_MODE_1;
@@ -727,19 +728,23 @@ static struct iio_chan_spec ade7758_channels[] = {
 static int __devinit ade7758_probe(struct spi_device *spi)
 {
 	int i, ret, regdone = 0;
-	struct ade7758_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
+	struct ade7758_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
 		goto error_ret;
 	}
+
+	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
 	/* Allocate the comms buffers */
 	st->rx = kzalloc(sizeof(*st->rx)*ADE7758_MAX_RX, GFP_KERNEL);
 	if (st->rx == NULL) {
 		ret = -ENOMEM;
-		goto error_free_st;
+		goto error_free_dev;
 	}
 	st->tx = kzalloc(sizeof(*st->tx)*ADE7758_MAX_TX, GFP_KERNEL);
 	if (st->tx == NULL) {
@@ -749,35 +754,28 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 	st->us = spi;
 	st->ade7758_ring_channels = &ade7758_channels[0];
 	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device(0);
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 
-	st->indio_dev->name = spi->dev.driver->name;
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ade7758_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->name = spi->dev.driver->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->attrs = &ade7758_attribute_group;
+	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	for (i = 0; i < AD7758_NUM_WAVESRC; i++)
 		st->available_scan_masks[i] = 1 << i;
 
-	st->indio_dev->available_scan_masks = st->available_scan_masks;
+	indio_dev->available_scan_masks = st->available_scan_masks;
 
-	ret = ade7758_configure_ring(st->indio_dev);
+	ret = ade7758_configure_ring(indio_dev);
 	if (ret)
-		goto error_free_dev;
+		goto error_free_tx;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
 					  &ade7758_channels[0],
 					  ARRAY_SIZE(ade7758_channels));
 	if (ret) {
@@ -786,12 +784,12 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 	}
 
 	/* Get the device into a sane initial state */
-	ret = ade7758_initial_setup(st);
+	ret = ade7758_initial_setup(indio_dev);
 	if (ret)
 		goto error_uninitialize_ring;
 
 	if (spi->irq) {
-		ret = ade7758_probe_trigger(st->indio_dev);
+		ret = ade7758_probe_trigger(indio_dev);
 		if (ret)
 			goto error_remove_trigger;
 	}
@@ -799,47 +797,43 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 	return 0;
 
 error_remove_trigger:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		ade7758_remove_trigger(st->indio_dev);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7758_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	ade7758_uninitialize_ring(st->indio_dev->ring);
+	ade7758_uninitialize_ring(indio_dev->ring);
 error_unreg_ring_funcs:
-	ade7758_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
+	ade7758_unconfigure_ring(indio_dev);
 error_free_tx:
 	kfree(st->tx);
 error_free_rx:
 	kfree(st->rx);
-error_free_st:
-	kfree(st);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
 
 static int ade7758_remove(struct spi_device *spi)
 {
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
-	struct ade7758_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
 
-	ret = ade7758_stop_device(&(indio_dev->dev));
+	ret = ade7758_stop_device(&indio_dev->dev);
 	if (ret)
 		goto err_ret;
 
 	ade7758_remove_trigger(indio_dev);
 	ade7758_uninitialize_ring(indio_dev->ring);
-	iio_device_unregister(indio_dev);
 	ade7758_unconfigure_ring(indio_dev);
 	kfree(st->tx);
 	kfree(st->rx);
-	kfree(st);
+	iio_device_unregister(indio_dev);
 
 	return 0;
-
 err_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 564555a..a5e48c1 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -32,7 +32,7 @@
 static int ade7758_spi_read_burst(struct device *dev)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 
 	ret = spi_sync(st->us, &st->ring_msg);
@@ -71,12 +71,12 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->private_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	s64 dat64[2];
 	u32 *dat32 = (u32 *)dat64;
 
 	if (ring->scan_count)
-		if (ade7758_spi_read_burst(&st->indio_dev->dev) >= 0)
+		if (ade7758_spi_read_burst(&indio_dev->dev) >= 0)
 			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
 	/* Guaranteed to be aligned with 8 byte boundary */
@@ -85,7 +85,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 
 	ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
 
-	iio_trigger_notify_done(st->indio_dev->trig);
+	iio_trigger_notify_done(indio_dev->trig);
 
 	return IRQ_HANDLED;
 }
@@ -99,7 +99,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
  **/
 static int ade7758_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct ade7758_state *st = indio_dev->dev_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 	unsigned channel;
@@ -149,7 +149,7 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
-	struct ade7758_state *st = indio_dev->dev_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret = 0;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
index 5442d79..a5c3248 100644
--- a/drivers/staging/iio/meter/ade7758_trigger.c
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -37,8 +37,7 @@ static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
 static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct ade7758_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = trig->private_data;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
 	return ade7758_set_irq(&indio_dev->dev, state);
@@ -50,7 +49,8 @@ static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
  **/
 static int ade7758_trig_try_reen(struct iio_trigger *trig)
 {
-	struct ade7758_state *st = trig->private_data;
+	struct iio_dev *indio_dev = trig->private_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
 
 	enable_irq(st->us->irq);
 	/* irq reenabled so success! */
@@ -59,8 +59,8 @@ static int ade7758_trig_try_reen(struct iio_trigger *trig)
 
 int ade7758_probe_trigger(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
-	struct ade7758_state *st = indio_dev->dev_data;
 
 	st->trig = iio_allocate_trigger("%s-dev%d",
 					spi_get_device_id(st->us)->name,
@@ -80,7 +80,7 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev)
 
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
+	st->trig->private_data = indio_dev;
 	st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state;
 	st->trig->try_reenable = &ade7758_trig_try_reen;
 	ret = iio_trigger_register(st->trig);
@@ -102,9 +102,9 @@ error_ret:
 
 void ade7758_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct ade7758_state *state = indio_dev->dev_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
 
-	iio_trigger_unregister(state->trig);
-	free_irq(state->us->irq, state->trig);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	free_irq(st->us->irq, st->trig);
+	iio_free_trigger(st->trig);
 }
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 107/111] staging:iio: implement an iio_info structure to take some of the constant elements out of iio_dev.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (105 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 106/111] staging:iio:meter:ade7758: Use private data space from iio_allocate_device Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 108/111] staging:iio:max1363 misc cleanups and use of for_each_bit_set to simplify event code spitting out Jonathan Cameron
                   ` (4 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

This was suggested by Arnd Bergmann,  Other elements may well
move in here in future, but it definitely makes sense for these.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16201_core.c |   13 +-
 drivers/staging/iio/accel/adis16203_core.c |   12 +-
 drivers/staging/iio/accel/adis16204_core.c |   12 +-
 drivers/staging/iio/accel/adis16209_core.c |   12 +-
 drivers/staging/iio/accel/adis16220_core.c |    7 +-
 drivers/staging/iio/accel/adis16240_core.c |   12 +-
 drivers/staging/iio/accel/kxsd9.c          |   12 +-
 drivers/staging/iio/accel/lis3l02dq_core.c |   23 +-
 drivers/staging/iio/accel/sca3000_core.c   |   33 +-
 drivers/staging/iio/adc/ad7150.c           |   15 +-
 drivers/staging/iio/adc/ad7152.c           |    7 +-
 drivers/staging/iio/adc/ad7291.c           |   11 +-
 drivers/staging/iio/adc/ad7298_core.c      |    8 +-
 drivers/staging/iio/adc/ad7314.c           |    7 +-
 drivers/staging/iio/adc/ad7476_core.c      |    8 +-
 drivers/staging/iio/adc/ad7606_core.c      |   10 +-
 drivers/staging/iio/adc/ad7745.c           |   11 +-
 drivers/staging/iio/adc/ad7780.c           |    8 +-
 drivers/staging/iio/adc/ad7816.c           |   12 +-
 drivers/staging/iio/adc/ad7887_core.c      |    8 +-
 drivers/staging/iio/adc/ad799x.h           |    3 +-
 drivers/staging/iio/adc/ad799x_core.c      |   47 ++-
 drivers/staging/iio/adc/adt7310.c          |   12 +-
 drivers/staging/iio/adc/adt7410.c          |   12 +-
 drivers/staging/iio/adc/adt75.c            |   12 +-
 drivers/staging/iio/adc/max1363.h          |   14 +-
 drivers/staging/iio/adc/max1363_core.c     |  782 +++++++++++++++-------------
 drivers/staging/iio/addac/adt7316.c        |   27 +-
 drivers/staging/iio/dac/ad5446.c           |    8 +-
 drivers/staging/iio/dac/ad5504.c           |   24 +-
 drivers/staging/iio/dac/ad5624r_spi.c      |    8 +-
 drivers/staging/iio/dac/ad5791.c           |    8 +-
 drivers/staging/iio/dac/max517.c           |   15 +-
 drivers/staging/iio/dds/ad5930.c           |   12 +-
 drivers/staging/iio/dds/ad9832.c           |    8 +-
 drivers/staging/iio/dds/ad9834.c           |    8 +-
 drivers/staging/iio/dds/ad9850.c           |   10 +-
 drivers/staging/iio/dds/ad9852.c           |   10 +-
 drivers/staging/iio/dds/ad9910.c           |   10 +-
 drivers/staging/iio/dds/ad9951.c           |   10 +-
 drivers/staging/iio/gyro/adis16060_core.c  |    8 +-
 drivers/staging/iio/gyro/adis16080_core.c  |    8 +-
 drivers/staging/iio/gyro/adis16130_core.c  |    8 +-
 drivers/staging/iio/gyro/adis16260_core.c  |   12 +-
 drivers/staging/iio/gyro/adxrs450_core.c   |    8 +-
 drivers/staging/iio/iio.h                  |  105 ++--
 drivers/staging/iio/imu/adis16400_core.c   |   12 +-
 drivers/staging/iio/industrialio-core.c    |   73 ++--
 drivers/staging/iio/light/isl29018.c       |    8 +-
 drivers/staging/iio/light/tsl2563.c        |   26 +-
 drivers/staging/iio/light/tsl2583.c        |    8 +-
 drivers/staging/iio/magnetometer/ak8975.c  |    8 +-
 drivers/staging/iio/magnetometer/hmc5843.c |    8 +-
 drivers/staging/iio/meter/ade7753.c        |    8 +-
 drivers/staging/iio/meter/ade7754.c        |    8 +-
 drivers/staging/iio/meter/ade7758_core.c   |    8 +-
 drivers/staging/iio/meter/ade7759.c        |    9 +-
 drivers/staging/iio/meter/ade7854.c        |    8 +-
 drivers/staging/iio/resolver/ad2s120x.c    |   11 +-
 drivers/staging/iio/resolver/ad2s1210.c    |   10 +-
 drivers/staging/iio/resolver/ad2s90.c      |   10 +-
 61 files changed, 970 insertions(+), 675 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 59b6ac2..e4c49f0 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -457,6 +457,13 @@ static const struct attribute_group adis16201_attribute_group = {
 	.attrs = adis16201_attributes,
 };
 
+static const struct iio_info adis16201_info = {
+	.attrs = &adis16201_attribute_group,
+	.read_raw = &adis16201_read_raw,
+	.write_raw = &adis16201_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16201_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -490,13 +497,11 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16201_attribute_group;
+	st->indio_dev->info = &adis16201_info;
+
 	st->indio_dev->channels = adis16201_channels;
 	st->indio_dev->num_channels = ARRAY_SIZE(adis16201_channels);
-	st->indio_dev->read_raw = &adis16201_read_raw;
-	st->indio_dev->write_raw = &adis16201_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16201_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 1694a0c..36be4d5 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -408,6 +408,13 @@ static const struct attribute_group adis16203_attribute_group = {
 	.attrs = adis16203_attributes,
 };
 
+static const struct iio_info adis16203_info = {
+	.attrs = &adis16203_attribute_group,
+	.read_raw = &adis16203_read_raw,
+	.write_raw = &adis16203_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16203_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -440,13 +447,10 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 	}
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16203_attribute_group;
 	st->indio_dev->channels = adis16203_channels;
 	st->indio_dev->num_channels = ARRAY_SIZE(adis16203_channels);
-	st->indio_dev->read_raw = &adis16203_read_raw;
-	st->indio_dev->write_raw = &adis16203_write_raw;
+	st->indio_dev->info = &adis16203_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16203_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 4e4944c..1680670 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -473,6 +473,13 @@ static const struct attribute_group adis16204_attribute_group = {
 	.attrs = adis16204_attributes,
 };
 
+static const struct iio_info adis16204_info = {
+	.attrs = &adis16204_attribute_group,
+	.read_raw = &adis16204_read_raw,
+	.write_raw = &adis16204_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16204_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -506,13 +513,10 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16204_attribute_group;
+	st->indio_dev->info = &adis16204_info;
 	st->indio_dev->channels = adis16204_channels;
 	st->indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
-	st->indio_dev->read_raw = &adis16204_read_raw;
-	st->indio_dev->write_raw = &adis16204_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16204_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index d48babe..c423cc9 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -456,6 +456,13 @@ static const struct attribute_group adis16209_attribute_group = {
 	.attrs = adis16209_attributes,
 };
 
+static const struct iio_info adis16209_info = {
+	.attrs = &adis16209_attribute_group,
+	.read_raw = &adis16209_read_raw,
+	.write_raw = &adis16209_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16209_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -489,13 +496,10 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16209_attribute_group;
+	st->indio_dev->info = &adis16209_info;
 	st->indio_dev->channels = adis16209_channels;
 	st->indio_dev->num_channels = ARRAY_SIZE(adis16209_channels);
-	st->indio_dev->read_raw = &adis16209_read_raw;
-	st->indio_dev->write_raw = &adis16209_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16209_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 7af48b8..605a75e 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -544,6 +544,10 @@ static const struct attribute_group adis16220_attribute_group = {
 	.attrs = adis16220_attributes,
 };
 
+static const struct iio_info adis16220_info = {
+	.attrs = &adis16220_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 static int __devinit adis16220_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -577,9 +581,8 @@ static int __devinit adis16220_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16220_attribute_group;
+	st->indio_dev->info = &adis16220_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 537e0f2..ac60385 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -507,6 +507,13 @@ static const struct attribute_group adis16240_attribute_group = {
 	.attrs = adis16240_attributes,
 };
 
+static const struct iio_info adis16240_info = {
+	.attrs = &adis16240_attribute_group,
+	.read_raw = &adis16240_read_raw,
+	.write_raw = &adis16240_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16240_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -540,13 +547,10 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16240_attribute_group;
+	st->indio_dev->info = &adis16240_info;
 	st->indio_dev->channels = adis16240_channels;
 	st->indio_dev->num_channels = ARRAY_SIZE(adis16240_channels);
-	st->indio_dev->read_raw = &adis16240_read_raw;
-	st->indio_dev->write_raw = &adis16240_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16240_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
index 431aa0f..973156e 100644
--- a/drivers/staging/iio/accel/kxsd9.c
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -301,6 +301,11 @@ error_ret:
 
 };
 
+static const struct iio_info kxsd9_info = {
+	.attrs = &kxsd9_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit kxsd9_probe(struct spi_device *spi)
 {
 
@@ -335,13 +340,8 @@ static int __devinit kxsd9_probe(struct spi_device *spi)
 		goto error_free_tx;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
-	/* for now */
-	st->indio_dev->num_interrupt_lines = 0;
-	st->indio_dev->event_attrs = NULL;
-
-	st->indio_dev->attrs = &kxsd9_attribute_group;
+	st->indio_dev->info = &kxsd9_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 942139a..ba5bc67 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -651,6 +651,18 @@ static const struct attribute_group lis3l02dq_attribute_group = {
 	.attrs = lis3l02dq_attributes,
 };
 
+static const struct iio_info lis3l02dq_info = {
+	.num_interrupt_lines = 1,
+	.read_raw = &lis3l02dq_read_raw,
+	.write_raw = &lis3l02dq_write_raw,
+	.read_event_value = &lis3l02dq_read_thresh,
+	.write_event_value = &lis3l02dq_write_thresh,
+	.write_event_config = &lis3l02dq_write_event_config,
+	.read_event_config = &lis3l02dq_read_event_config,
+	.driver_module = THIS_MODULE,
+	.attrs = &lis3l02dq_attribute_group,
+};
+
 static int __devinit lis3l02dq_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -670,17 +682,10 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 	mutex_init(&st->buf_lock);
 	indio_dev->name = spi->dev.driver->name;
 	indio_dev->dev.parent = &spi->dev;
-	indio_dev->num_interrupt_lines = 1;
+	indio_dev->info = &lis3l02dq_info;
 	indio_dev->channels = lis3l02dq_channels;
 	indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
-	indio_dev->read_raw = &lis3l02dq_read_raw;
-	indio_dev->write_raw = &lis3l02dq_write_raw;
-	indio_dev->read_event_value = &lis3l02dq_read_thresh;
-	indio_dev->write_event_value = &lis3l02dq_write_thresh;
-	indio_dev->write_event_config = &lis3l02dq_write_event_config;
-	indio_dev->read_event_config = &lis3l02dq_read_event_config;
-	indio_dev->attrs = &lis3l02dq_attribute_group;
-	indio_dev->driver_module = THIS_MODULE;
+
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = lis3l02dq_configure_ring(indio_dev);
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 5de07fd..f213b86 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -1100,6 +1100,28 @@ error_ret:
 	return ret;
 }
 
+static const struct iio_info sca3000_info = {
+	.attrs = &sca3000_attribute_group,
+	.read_raw = &sca3000_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &sca3000_event_attribute_group,
+	.read_event_value = &sca3000_read_thresh,
+	.write_event_value = &sca3000_write_thresh,
+	.read_event_config = &sca3000_read_event_config,
+	.write_event_config = &sca3000_write_event_config,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info sca3000_info_with_temp = {
+	.attrs = &sca3000_attribute_group_with_temp,
+	.read_raw = &sca3000_read_raw,
+	.read_event_value = &sca3000_read_thresh,
+	.write_event_value = &sca3000_write_thresh,
+	.read_event_config = &sca3000_read_event_config,
+	.write_event_config = &sca3000_write_event_config,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit sca3000_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -1124,20 +1146,13 @@ static int __devinit sca3000_probe(struct spi_device *spi)
 	}
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &sca3000_event_attribute_group;
 	if (st->info->temp_output)
-		st->indio_dev->attrs = &sca3000_attribute_group_with_temp;
+		st->indio_dev->info = &sca3000_info_with_temp;
 	else {
-		st->indio_dev->attrs = &sca3000_attribute_group;
+		st->indio_dev->info = &sca3000_info;
 		st->indio_dev->channels = sca3000_channels;
 		st->indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
 	}
-	st->indio_dev->read_raw = &sca3000_read_raw;
-	st->indio_dev->read_event_value = &sca3000_read_thresh;
-	st->indio_dev->write_event_value = &sca3000_write_thresh;
-	st->indio_dev->read_event_config = &sca3000_read_event_config;
-	st->indio_dev->write_event_config = &sca3000_write_event_config;
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index e23bb99..ca32b67 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -700,6 +700,12 @@ static struct attribute_group ad7150_event_attribute_group = {
 	.attrs = ad7150_event_attributes,
 };
 
+static const struct iio_info ad7150_info = {
+	.attrs = &ad7150_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7150_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -725,14 +731,13 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 		goto error_free_chip;
 	}
 
-	/* Echipabilish that the iio_dev is a child of the i2c device */
+	/* Establish that the iio_dev is a child of the i2c device */
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7150_attribute_group;
-	chip->indio_dev->event_attrs = &ad7150_event_attribute_group;
+
+	chip->indio_dev->info = &ad7150_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
+
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index e53e3e9..7a38bcb 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -497,6 +497,10 @@ static const struct attribute_group ad7152_attribute_group = {
 	.attrs = ad7152_attributes,
 };
 
+static const struct iio_info ad7152_info = {
+	.attrs = &ad7152_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -525,9 +529,8 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	/* Echipabilish that the iio_dev is a child of the i2c device */
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7152_attribute_group;
+	chip->indio_dev->info = &ad7152_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 0e4c728..1be3453 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -778,6 +778,12 @@ static struct attribute_group ad7291_event_attribute_group = {
 	.attrs = ad7291_event_attributes,
 };
 
+static const struct iio_info ad7291_info = {
+	.attrs = &ad7291_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7291_event_attribute_group,
+};
+
 /*
  * device probe and remove
  */
@@ -807,11 +813,8 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7291_attribute_group;
-	chip->indio_dev->event_attrs = &ad7291_event_attribute_group;
+	chip->indio_dev->info = &ad7291_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 83b3d15..b8e4ae2 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -156,6 +156,11 @@ static int ad7298_read_raw(struct iio_dev *dev_info,
 	return -EINVAL;
 }
 
+static const struct iio_info ad7298_info = {
+	.read_raw = &ad7298_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad7298_probe(struct spi_device *spi)
 {
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
@@ -181,11 +186,10 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->dev.parent = &spi->dev;
-	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = ad7298_channels;
 	indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
-	indio_dev->read_raw = &ad7298_read_raw;
+	indio_dev->info = &ad7298_info;
 
 	/* Setup default message */
 
diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
index a1f1b43..98bb16f 100644
--- a/drivers/staging/iio/adc/ad7314.c
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -191,6 +191,10 @@ static const struct attribute_group ad7314_attribute_group = {
 	.attrs = ad7314_attributes,
 };
 
+static const struct iio_info ad7314_info = {
+	.attrs = &ad7314_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -218,9 +222,8 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
 
 	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
-	chip->indio_dev->attrs = &ad7314_attribute_group;
+	chip->indio_dev->info = &ad7314_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
 
 	ret = iio_device_register(chip->indio_dev);
 	if (ret)
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index 5b41e01..50cedb4 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -118,6 +118,11 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
 	},
 };
 
+static const struct iio_info ad7476_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7476_read_raw,
+};
+
 static int __devinit ad7476_probe(struct spi_device *spi)
 {
 	struct ad7476_platform_data *pdata = spi->dev.platform_data;
@@ -165,11 +170,10 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 	st->indio_dev->channels = st->chip_info->channel;
 	st->indio_dev->num_channels = 2;
-	st->indio_dev->read_raw = &ad7476_read_raw;
+	st->indio_dev->info = &ad7476_info;
 	/* Setup default message */
 
 	st->xfer.rx_buf = &st->data;
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index fb96802..459371a 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -426,6 +426,12 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 };
 
+static const struct iio_info ad7606_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7606_read_raw,
+	.attrs = &ad7606_attribute_group,
+};
+
 struct iio_dev *ad7606_probe(struct device *dev, int irq,
 			      void __iomem *base_address,
 			      unsigned id,
@@ -470,13 +476,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
 	st->chip_info = &ad7606_chip_info_tbl[id];
 
 	indio_dev->dev.parent = dev;
-	indio_dev->attrs = &ad7606_attribute_group;
-	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->info = &ad7606_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->name = st->chip_info->name;
 	indio_dev->channels = st->chip_info->channels;
 	indio_dev->num_channels = st->chip_info->num_channels;
-	indio_dev->read_raw = &ad7606_read_raw;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
index 98b510d..1944223 100644
--- a/drivers/staging/iio/adc/ad7745.c
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -565,6 +565,12 @@ static struct attribute_group ad774x_event_attribute_group = {
 	.attrs = ad774x_event_attributes,
 };
 
+static const struct iio_info ad774x_info = {
+	.attrs = &ad774x_event_attribute_group,
+	.event_attrs = &ad774x_event_attribute_group,
+	.num_interrupt_lines = 1,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -593,11 +599,8 @@ static int __devinit ad774x_probe(struct i2c_client *client,
 	/* Establish that the iio_dev is a child of the i2c device */
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad774x_attribute_group;
-	chip->indio_dev->event_attrs = &ad774x_event_attribute_group;
+	chip->indio_dev->info = &ad774x_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 713e202..e0c7b6c 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -151,6 +151,11 @@ static irqreturn_t ad7780_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 };
 
+static const struct iio_info ad7780_info = {
+	.read_raw = &ad7780_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad7780_probe(struct spi_device *spi)
 {
 	struct ad7780_platform_data *pdata = spi->dev.platform_data;
@@ -195,11 +200,10 @@ static int __devinit ad7780_probe(struct spi_device *spi)
 
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(spi)->name;
-	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = &st->chip_info->channel;
 	indio_dev->num_channels = 1;
-	indio_dev->read_raw = &ad7780_read_raw;
+	indio_dev->info = &ad7780_info;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 873fe2b..11379e4 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -331,6 +331,13 @@ static struct attribute_group ad7816_event_attribute_group = {
 	.attrs = ad7816_event_attributes,
 };
 
+static const struct iio_info ad7816_info = {
+	.attrs = &ad7816_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7816_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -391,11 +398,8 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev)
 	}
 	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
-	chip->indio_dev->attrs = &ad7816_attribute_group;
-	chip->indio_dev->event_attrs = &ad7816_event_attribute_group;
+	chip->indio_dev->info = &ad7816_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 6773fe1..de14b17 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -83,6 +83,11 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
 	},
 };
 
+static const struct iio_info ad7887_info = {
+	.read_raw = &ad7887_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad7887_probe(struct spi_device *spi)
 {
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
@@ -114,8 +119,7 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->dev_data = (void *)(st);
-	indio_dev->read_raw = &ad7887_read_raw;
-	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->info = &ad7887_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default message */
diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index 0a8d6e2..0dc9b4c 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -97,9 +97,8 @@ struct ad799x_chip_info {
 	struct iio_chan_spec		channel[9];
 	int				num_channels;
 	u16				int_vref_mv;
-	bool				monitor_mode;
 	u16				default_config;
-	struct attribute_group		*event_attrs;
+	const struct iio_info		*info;
 };
 
 struct ad799x_state {
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index a105910..29bfbcf 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -459,6 +459,25 @@ static struct attribute_group ad7992_event_attrs_group = {
 	.attrs = ad7992_event_attributes,
 };
 
+static const struct iio_info ad7991_info = {
+	.read_raw = &ad799x_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad7992_info = {
+	.read_raw = &ad799x_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7992_event_attrs_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad7993_4_7_8_info = {
+	.read_raw = &ad799x_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7993_4_7_8_event_attrs_group,
+	.driver_module = THIS_MODULE,
+};
+
 static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 	[ad7991] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -476,6 +495,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
 		.num_channels = 5,
 		.int_vref_mv = 4096,
+		.info = &ad7991_info,
 	},
 	[ad7995] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -493,6 +513,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
 		.num_channels = 5,
 		.int_vref_mv = 1024,
+		.info = &ad7991_info,
 	},
 	[ad7999] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -510,6 +531,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
 		.num_channels = 5,
 		.int_vref_mv = 1024,
+		.info = &ad7991_info,
 	},
 	[ad7992] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -521,9 +543,8 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
 		.num_channels = 3,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.event_attrs = &ad7992_event_attrs_group,
+		.info = &ad7992_info,
 	},
 	[ad7993] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -541,9 +562,8 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
 		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7994] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -561,9 +581,8 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
 		.num_channels = 5,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7997] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -593,9 +612,8 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
 		.num_channels = 9,
 		.int_vref_mv = 1024,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7998] = {
 		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
@@ -625,9 +643,8 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
 		.num_channels = 9,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
+		.info = &ad7993_4_7_8_info,
 	},
 };
 
@@ -667,15 +684,13 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->name = id->name;
-	indio_dev->event_attrs = st->chip_info->event_attrs;
+	indio_dev->info = st->chip_info->info;
 	indio_dev->name = id->name;
 	indio_dev->dev_data = (void *)(st);
-	indio_dev->driver_module = THIS_MODULE;
+
 	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->num_interrupt_lines = 1;
 	indio_dev->channels = st->chip_info->channel;
 	indio_dev->num_channels = st->chip_info->num_channels;
-	indio_dev->read_raw = &ad799x_read_raw;
 
 	ret = ad799x_register_ring_funcs_and_init(indio_dev);
 	if (ret)
@@ -692,7 +707,7 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 	if (ret)
 		goto error_cleanup_ring;
 
-	if (client->irq > 0 && st->chip_info->monitor_mode) {
+	if (client->irq > 0) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
 					   ad799x_event_handler,
@@ -727,7 +742,7 @@ static __devexit int ad799x_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct ad799x_state *st = iio_priv(indio_dev);
 
-	if (client->irq > 0 && st->chip_info->monitor_mode)
+	if (client->irq > 0)
 		free_irq(client->irq, indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index e405fc3..68eca0b 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -746,6 +746,13 @@ static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
 	}
 };
 
+static const struct iio_info adt7310_info = {
+	.attrs = &adt7310_attribute_group,
+	.num_interrupt_lines = ADT7310_IRQS,
+	.event_attrs = adt7310_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -775,11 +782,8 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev)
 
 	chip->indio_dev->dev.parent = &spi_dev->dev;
 	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
-	chip->indio_dev->attrs = &adt7310_attribute_group;
-	chip->indio_dev->event_attrs = adt7310_event_attribute_group;
+	chip->indio_dev->info = &adt7310_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = ADT7310_IRQS;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index 85b5c1a..c40a84f 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -713,6 +713,13 @@ static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
 	}
 };
 
+static const struct iio_info adt7410_info = {
+	.attrs = &adt7410_attribute_group,
+	.num_interrupt_lines = ADT7410_IRQS,
+	.event_attrs = adt7410_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -741,11 +748,8 @@ static int __devinit adt7410_probe(struct i2c_client *client,
 	}
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &adt7410_attribute_group;
-	chip->indio_dev->event_attrs = adt7410_event_attribute_group;
+	chip->indio_dev->info = &adt7410_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = ADT7410_IRQS;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index 2a44428..1171fb9 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -534,6 +534,13 @@ static struct attribute_group adt75_event_attribute_group = {
 	.attrs = adt75_event_attributes,
 };
 
+static const struct iio_info adt75_info = {
+	.attrs = &adt75_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt75_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -562,11 +569,8 @@ static int __devinit adt75_probe(struct i2c_client *client,
 
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &adt75_attribute_group;
-	chip->indio_dev->event_attrs = &adt75_event_attribute_group;
+	chip->indio_dev->info = &adt75_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 15227bd..5243b5a 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -154,7 +154,7 @@ enum max1363_modes {
  * @name:		indentification string for chip
  * @bits:		accuracy of the adc in bits
  * @int_vref_mv:	the internal reference voltage
- * @monitor_mode:	whether the chip supports monitor interrupts
+ * @info:		iio core function callbacks structure
  * @mode_list:		array of available scan modes
  * @num_modes:		the number of scan modes available
  * @default_mode:	the scan mode in which the chip starts up
@@ -162,14 +162,14 @@ enum max1363_modes {
  * @num_channels:	number of channels
  */
 struct max1363_chip_info {
-	u8				bits;
-	u16				int_vref_mv;
-	bool				monitor_mode;
-	const enum max1363_modes	*mode_list;
-	int				num_modes;
-	enum max1363_modes		default_mode;
+	const struct iio_info		*info;
 	struct iio_chan_spec *channels;
 	int num_channels;
+	const enum max1363_modes	*mode_list;
+	enum max1363_modes		default_mode;
+	u16				int_vref_mv;
+	u8				num_modes;
+	u8				bits;
 };
 
 /**
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 0c80abb..8d09bf3 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -472,356 +472,6 @@ enum { max1361,
        max11647
 };
 
-/* max1363 and max1368 tested - rest from data sheet */
-static const struct max1363_chip_info max1363_chip_info_tbl[] = {
-	[max1361] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.channels = max1361_channels,
-		.num_channels = ARRAY_SIZE(max1361_channels),
-	},
-	[max1362] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.channels = max1361_channels,
-		.num_channels = ARRAY_SIZE(max1361_channels),
-	},
-	[max1363] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.channels = max1363_channels,
-		.num_channels = ARRAY_SIZE(max1363_channels),
-	},
-	[max1364] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.channels = max1363_channels,
-		.num_channels = ARRAY_SIZE(max1363_channels),
-	},
-	[max1036] = {
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1036_channels,
-		.num_channels = ARRAY_SIZE(max1036_channels),
-	},
-	[max1037] = {
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1036_channels,
-		.num_channels = ARRAY_SIZE(max1036_channels),
-	},
-	[max1038] = {
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1038_channels,
-		.num_channels = ARRAY_SIZE(max1038_channels),
-	},
-	[max1039] = {
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1038_channels,
-		.num_channels = ARRAY_SIZE(max1038_channels),
-	},
-	[max1136] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1136_channels,
-		.num_channels = ARRAY_SIZE(max1136_channels),
-	},
-	[max1137] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1136_channels,
-		.num_channels = ARRAY_SIZE(max1136_channels),
-	},
-	[max1138] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1138_channels,
-		.num_channels = ARRAY_SIZE(max1138_channels),
-	},
-	[max1139] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1138_channels,
-		.num_channels = ARRAY_SIZE(max1138_channels),
-	},
-	[max1236] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1236_channels,
-		.num_channels = ARRAY_SIZE(max1236_channels),
-	},
-	[max1237] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.channels = max1236_channels,
-		.num_channels = ARRAY_SIZE(max1236_channels),
-	},
-	[max1238] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max1239] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11600] = {
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1036_channels,
-		.num_channels = ARRAY_SIZE(max1036_channels),
-	},
-	[max11601] = {
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1036_channels,
-		.num_channels = ARRAY_SIZE(max1036_channels),
-	},
-	[max11602] = {
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11602_channels,
-		.num_channels = ARRAY_SIZE(max11602_channels),
-	},
-	[max11603] = {
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11602_channels,
-		.num_channels = ARRAY_SIZE(max11602_channels),
-	},
-	[max11604] = {
-		.bits = 8,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11605] = {
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11606] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1136_channels,
-		.num_channels = ARRAY_SIZE(max1136_channels),
-	},
-	[max11607] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1136_channels,
-		.num_channels = ARRAY_SIZE(max1136_channels),
-	},
-	[max11608] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11608_channels,
-		.num_channels = ARRAY_SIZE(max11608_channels),
-	},
-	[max11609] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11608_channels,
-		.num_channels = ARRAY_SIZE(max11608_channels),
-	},
-	[max11610] = {
-		.bits = 10,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11611] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11612] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1363_channels,
-		.num_channels = ARRAY_SIZE(max1363_channels),
-	},
-	[max11613] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.channels = max1363_channels,
-		.num_channels = ARRAY_SIZE(max1363_channels),
-	},
-	[max11614] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11614_channels,
-		.num_channels = ARRAY_SIZE(max11614_channels),
-	},
-	[max11615] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.channels = max11614_channels,
-		.num_channels = ARRAY_SIZE(max11614_channels),
-	},
-	[max11616] = {
-		.bits = 12,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11617] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
-	},
-	[max11644] = {
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max11644_mode_list,
-		.num_modes = ARRAY_SIZE(max11644_mode_list),
-		.default_mode = s0to1,
-		.channels = max11644_channels,
-		.num_channels = ARRAY_SIZE(max11644_channels),
-	},
-	[max11645] = {
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max11644_mode_list,
-		.num_modes = ARRAY_SIZE(max11644_mode_list),
-		.default_mode = s0to1,
-		.channels = max11644_channels,
-		.num_channels = ARRAY_SIZE(max11644_channels),
-	},
-	[max11646] = {
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max11644_mode_list,
-		.num_modes = ARRAY_SIZE(max11644_mode_list),
-		.default_mode = s0to1,
-		.channels = max11644_channels,
-		.num_channels = ARRAY_SIZE(max11646_channels),
-	},
-	[max11647] = {
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max11644_mode_list,
-		.num_modes = ARRAY_SIZE(max11644_mode_list),
-		.default_mode = s0to1,
-		.channels = max11644_channels,
-		.num_channels = ARRAY_SIZE(max11646_channels),
-	},
-};
-
 static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
 					      8300, 4200, 2000, 1000 };
 
@@ -1161,9 +811,414 @@ static struct attribute *max1363_event_attributes[] = {
 	NULL,
 };
 
-static struct attribute_group max1363_event_attribute_group = {
-	.attrs = max1363_event_attributes,
-};
+static struct attribute_group max1363_event_attribute_group = {
+	.attrs = max1363_event_attributes,
+};
+
+#define MAX1363_EVENT_FUNCS						\
+
+
+static const struct iio_info max1238_info = {
+	.read_raw = &max1363_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info max1363_info = {
+	.read_event_value = &max1363_read_thresh,
+	.write_event_value = &max1363_write_thresh,
+	.read_event_config = &max1363_read_event_config,
+	.write_event_config = &max1363_write_event_config,
+	.read_raw = &max1363_read_raw,
+	.driver_module = THIS_MODULE,
+	.num_interrupt_lines = 1,
+	.event_attrs = &max1363_event_attribute_group,
+};
+
+/* max1363 and max1368 tested - rest from data sheet */
+static const struct max1363_chip_info max1363_chip_info_tbl[] = {
+	[max1361] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
+		.info = &max1363_info,
+	},
+	[max1362] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
+		.info = &max1363_info,
+	},
+	[max1363] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+		.info = &max1363_info,
+	},
+	[max1364] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+		.info = &max1363_info,
+	},
+	[max1036] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max1037] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max1038] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
+	},
+	[max1039] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
+	},
+	[max1136] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max1137] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max1138] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
+	},
+	[max1139] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
+	},
+	[max1236] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
+	},
+	[max1237] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
+	},
+	[max1238] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max1239] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11600] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max11601] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max11602] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
+	},
+	[max11603] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
+	},
+	[max11604] = {
+		.bits = 8,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11605] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11606] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max11607] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max11608] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
+	},
+	[max11609] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
+	},
+	[max11610] = {
+		.bits = 10,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11611] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11612] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+	},
+	[max11613] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+	},
+	[max11614] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
+	},
+	[max11615] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
+	},
+	[max11616] = {
+		.bits = 12,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11617] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11644] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11645] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11646] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11646_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
+	[max11647] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11646_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
+};
+
+
 
 static int max1363_initial_setup(struct max1363_state *st)
 {
@@ -1224,22 +1279,9 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	/* Estabilish that the iio_dev is a child of the i2c device */
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->name = id->name;
-	indio_dev->read_event_value = &max1363_read_thresh;
-	indio_dev->write_event_value = &max1363_write_thresh;
-	indio_dev->read_event_config = &max1363_read_event_config;
-	indio_dev->write_event_config = &max1363_write_event_config;
-	indio_dev->channels = st->chip_info->channels;
-	indio_dev->num_channels = st->chip_info->num_channels;
-	indio_dev->read_raw = &max1363_read_raw;
-	/* Todo: this shouldn't be here. */
-	indio_dev->driver_module = THIS_MODULE;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	if (st->chip_info->monitor_mode && client->irq) {
-		indio_dev->num_interrupt_lines = 1;
-		indio_dev->event_attrs
-			= &max1363_event_attribute_group;
-	}
 
+	indio_dev->info = st->chip_info->info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 	ret = max1363_initial_setup(st);
 	if (ret)
 		goto error_free_available_scan_masks;
@@ -1258,7 +1300,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	if (ret)
 		goto error_cleanup_ring;
 
-	if (st->chip_info->monitor_mode && client->irq) {
+	if (client->irq) {
 		ret = request_threaded_irq(st->client->irq,
 					   NULL,
 					   &max1363_event_handler,
@@ -1298,7 +1340,7 @@ static int max1363_remove(struct i2c_client *client)
 	struct max1363_state *st = iio_priv(indio_dev);
 	struct regulator *reg = st->reg;
 
-	if (st->chip_info->monitor_mode && client->irq)
+	if (client->irq)
 		free_irq(st->client->irq, indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	max1363_ring_cleanup(indio_dev);
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index b71994e..7097deb 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -2106,6 +2106,20 @@ int adt7316_enable(struct device *dev)
 EXPORT_SYMBOL(adt7316_enable);
 #endif
 
+static const struct iio_info adt7316_info = {
+	.attrs = &adt7316_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt7316_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info adt7516_info = {
+	.attrs = &adt7516_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt7516_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -2150,17 +2164,12 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
 	}
 
 	chip->indio_dev->dev.parent = dev;
-	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
-		chip->indio_dev->attrs = &adt7516_attribute_group;
-		chip->indio_dev->event_attrs = &adt7516_event_attribute_group;
-	} else {
-		chip->indio_dev->attrs = &adt7316_attribute_group;
-		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
-	}
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		chip->indio_dev->info = &adt7516_info;
+	else
+		chip->indio_dev->info = &adt7316_info;
 	chip->indio_dev->name = name;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
index 22646a6..86cb08c 100644
--- a/drivers/staging/iio/dac/ad5446.c
+++ b/drivers/staging/iio/dac/ad5446.c
@@ -334,6 +334,11 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
 	},
 };
 
+static const struct iio_info ad5446_info = {
+	.attrs = &ad5446_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5446_probe(struct spi_device *spi)
 {
 	struct ad5446_state *st;
@@ -370,9 +375,8 @@ static int __devinit ad5446_probe(struct spi_device *spi)
 	/* Estabilish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad5446_attribute_group;
+	st->indio_dev->info = &ad5446_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default message */
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
index 351a9d3..ed029cd 100644
--- a/drivers/staging/iio/dac/ad5504.c
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -260,6 +260,20 @@ static irqreturn_t ad5504_event_handler(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
+static const struct iio_info ad5504_info = {
+	.attrs = &ad5504_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad5504_ev_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad5501_info = {
+	.attrs = &ad5501_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad5504_ev_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5504_probe(struct spi_device *spi)
 {
 	struct ad5504_platform_data *pdata = spi->dev.platform_data;
@@ -298,14 +312,12 @@ static int __devinit ad5504_probe(struct spi_device *spi)
 	}
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(st->spi)->name;
-	st->indio_dev->attrs = spi_get_device_id(st->spi)->driver_data
-		== ID_AD5501 ? &ad5501_attribute_group :
-		&ad5504_attribute_group;
+	if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
+		st->indio_dev->info = &ad5501_info;
+	else
+		st->indio_dev->info = &ad5504_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &ad5504_ev_attribute_group,
 
 	ret = iio_device_register(st->indio_dev);
 	if (ret)
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
index b0e25e2..c679981 100644
--- a/drivers/staging/iio/dac/ad5624r_spi.c
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -218,6 +218,11 @@ static const struct attribute_group ad5624r_attribute_group = {
 	.attrs = ad5624r_attributes,
 };
 
+static const struct iio_info ad5624r_info = {
+	.attrs = &ad5624r_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5624r_probe(struct spi_device *spi)
 {
 	struct ad5624r_state *st;
@@ -255,9 +260,8 @@ static int __devinit ad5624r_probe(struct spi_device *spi)
 	}
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad5624r_attribute_group;
+	st->indio_dev->info = &ad5624r_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
index acfd13b..4eda25c 100644
--- a/drivers/staging/iio/dac/ad5791.c
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -287,6 +287,11 @@ static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
 	},
 };
 
+static const struct iio_info ad5791_info = {
+	.attrs = &ad5791_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5791_probe(struct spi_device *spi)
 {
 	struct ad5791_platform_data *pdata = spi->dev.platform_data;
@@ -353,8 +358,7 @@ static int __devinit ad5791_probe(struct spi_device *spi)
 	}
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->attrs = &ad5791_attribute_group;
-	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->info = &ad5791_info;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c
index 3eb48b6..881768d 100644
--- a/drivers/staging/iio/dac/max517.c
+++ b/drivers/staging/iio/dac/max517.c
@@ -189,6 +189,16 @@ static int max517_resume(struct i2c_client *client)
 	return i2c_master_send(client, &outbuf, 1);
 }
 
+static const struct iio_info max517_info = {
+	.attrs = &max517_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info max518_info = {
+	.attrs = &max517_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int max517_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -217,11 +227,10 @@ static int max517_probe(struct i2c_client *client,
 
 	/* reduced attribute set for MAX517 */
 	if (id->driver_data == ID_MAX517)
-		data->indio_dev->attrs = &max517_attribute_group;
+		data->indio_dev->info = &max517_info;
 	else
-		data->indio_dev->attrs = &max518_attribute_group;
+		data->indio_dev->info = &max518_info;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/*
diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c
index 5d98f93..490c363 100644
--- a/drivers/staging/iio/dds/ad5930.c
+++ b/drivers/staging/iio/dds/ad5930.c
@@ -87,6 +87,12 @@ static const struct attribute_group ad5930_attribute_group = {
 	.attrs = ad5930_attributes,
 };
 
+static const struct iio_info ad5930_info = {
+	.attrs = &ad5930_attribute_group,
+
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5930_probe(struct spi_device *spi)
 {
 	struct ad5930_state *st;
@@ -108,12 +114,8 @@ static int __devinit ad5930_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
-
-	st->idev->attrs = &ad5930_attribute_group;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
+	st->idev->info = &ad5930_info;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c
index 4b5721c..e8fe142 100644
--- a/drivers/staging/iio/dds/ad9832.c
+++ b/drivers/staging/iio/dds/ad9832.c
@@ -195,6 +195,11 @@ static const struct attribute_group ad9832_attribute_group = {
 	.attrs = ad9832_attributes,
 };
 
+static const struct iio_info ad9832_info = {
+	.attrs = &ad9832_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9832_probe(struct spi_device *spi)
 {
 	struct ad9832_platform_data *pdata = spi->dev.platform_data;
@@ -232,9 +237,8 @@ static int __devinit ad9832_probe(struct spi_device *spi)
 
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad9832_attribute_group;
+	st->indio_dev->info = &ad9832_info;
 	st->indio_dev->dev_data = (void *) st;
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default messages */
diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c
index e5303e6..0ebe8d5 100644
--- a/drivers/staging/iio/dds/ad9834.c
+++ b/drivers/staging/iio/dds/ad9834.c
@@ -305,6 +305,11 @@ static const struct attribute_group ad9834_attribute_group = {
 	.is_visible = ad9834_attr_is_visible,
 };
 
+static const struct iio_info ad9834_info = {
+	.attrs = &ad9834_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9834_probe(struct spi_device *spi)
 {
 	struct ad9834_platform_data *pdata = spi->dev.platform_data;
@@ -344,9 +349,8 @@ static int __devinit ad9834_probe(struct spi_device *spi)
 
 	st->indio_dev->dev.parent = &spi->dev;
 	st->indio_dev->name = spi_get_device_id(spi)->name;
-	st->indio_dev->attrs = &ad9834_attribute_group;
+	st->indio_dev->info = &ad9834_info;
 	st->indio_dev->dev_data = (void *) st;
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default messages */
diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c
index 34bc0e6..b580d85 100644
--- a/drivers/staging/iio/dds/ad9850.c
+++ b/drivers/staging/iio/dds/ad9850.c
@@ -73,6 +73,11 @@ static const struct attribute_group ad9850_attribute_group = {
 	.attrs = ad9850_attributes,
 };
 
+static const struct iio_info ad9850_info = {
+	.attrs = &ad9850_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9850_probe(struct spi_device *spi)
 {
 	struct ad9850_state *st;
@@ -94,12 +99,9 @@ static int __devinit ad9850_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9850_attribute_group;
+	st->idev->info = &ad9850_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c
index 899a72a..08020f9 100644
--- a/drivers/staging/iio/dds/ad9852.c
+++ b/drivers/staging/iio/dds/ad9852.c
@@ -222,6 +222,11 @@ static const struct attribute_group ad9852_attribute_group = {
 	.attrs = ad9852_attributes,
 };
 
+static const struct iio_info ad9852_info = {
+	.attrs = &ad9852_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9852_probe(struct spi_device *spi)
 {
 	struct ad9852_state *st;
@@ -243,12 +248,9 @@ static int __devinit ad9852_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9852_attribute_group;
+	st->idev->info = &ad9852_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c
index fddb6e7..97d75d7 100644
--- a/drivers/staging/iio/dds/ad9910.c
+++ b/drivers/staging/iio/dds/ad9910.c
@@ -357,6 +357,11 @@ static const struct attribute_group ad9910_attribute_group = {
 	.attrs = ad9910_attributes,
 };
 
+static const struct iio_info ad9910_info = {
+	.attrs = &ad9910_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9910_probe(struct spi_device *spi)
 {
 	struct ad9910_state *st;
@@ -378,12 +383,9 @@ static int __devinit ad9910_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9910_attribute_group;
+	st->idev->info = &ad9910_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c
index a9e56c6..d4dfcd4 100644
--- a/drivers/staging/iio/dds/ad9951.c
+++ b/drivers/staging/iio/dds/ad9951.c
@@ -166,6 +166,11 @@ static const struct attribute_group ad9951_attribute_group = {
 	.attrs = ad9951_attributes,
 };
 
+static const struct iio_info ad9951_info = {
+	.attrs = &ad9951_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9951_probe(struct spi_device *spi)
 {
 	struct ad9951_state *st;
@@ -187,12 +192,9 @@ static int __devinit ad9951_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9951_attribute_group;
+	st->idev->info = &ad9951_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index e1f8a70..edf9e3b 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -133,6 +133,11 @@ static const struct attribute_group adis16060_attribute_group = {
 	.attrs = adis16060_attributes,
 };
 
+static const struct iio_info adis16060_info = {
+	.attrs = &adis16060_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16060_r_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -154,9 +159,8 @@ static int __devinit adis16060_r_probe(struct spi_device *spi)
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16060_attribute_group;
+	st->indio_dev->info = &adis16060_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index fb48e9b..d42690b 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -123,6 +123,11 @@ static const struct attribute_group adis16080_attribute_group = {
 	.attrs = adis16080_attributes,
 };
 
+static const struct iio_info adis16080_info = {
+	.attrs = &adis16080_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16080_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -146,9 +151,8 @@ static int __devinit adis16080_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16080_attribute_group;
+	st->indio_dev->info = &adis16080_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
index c2f338c..14d5a34 100644
--- a/drivers/staging/iio/gyro/adis16130_core.c
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -175,6 +175,11 @@ static const struct attribute_group adis16130_attribute_group = {
 	.attrs = adis16130_attributes,
 };
 
+static const struct iio_info adis16130_info = {
+	.attrs = &adis16130_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16130_probe(struct spi_device *spi)
 {
 	int ret;
@@ -196,9 +201,8 @@ static int __devinit adis16130_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16130_attribute_group;
+	st->indio_dev->info = &adis16130_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 	st->mode = 1;
 
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 0eb6a87..3dc9a27 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -565,6 +565,13 @@ static const struct attribute_group adis16260_attribute_group = {
 	.attrs = adis16260_attributes,
 };
 
+static const struct iio_info adis16260_info = {
+	.attrs = &adis16260_attribute_group,
+	.read_raw = &adis16260_read_raw,
+	.write_raw = &adis16260_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16260_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -601,7 +608,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi_get_device_id(st->us)->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16260_attribute_group;
+	st->indio_dev->info = &adis16260_info;
 	st->indio_dev->num_channels
 		= ARRAY_SIZE(adis16260_channels_x);
 	if (pd && pd->direction)
@@ -621,10 +628,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 	else
 		st->indio_dev->channels = adis16260_channels_x;
 
-	st->indio_dev->read_raw = &adis16260_read_raw;
-	st->indio_dev->write_raw = &adis16260_write_raw;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16260_configure_ring(st->indio_dev);
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c
index 7a9d7c2..3714e4a 100644
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ b/drivers/staging/iio/gyro/adxrs450_core.c
@@ -349,6 +349,11 @@ static const struct attribute_group adxrs450_attribute_group = {
 	.attrs = adxrs450_attributes,
 };
 
+static const struct iio_info adxrs450_info = {
+	.attrs = &adxrs450_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adxrs450_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -381,9 +386,8 @@ static int __devinit adxrs450_probe(struct spi_device *spi)
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adxrs450_attribute_group;
+	st->indio_dev->info = &adxrs450_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 4dc4ff0..38f1425 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -202,6 +202,61 @@ static inline s64 iio_get_time_ns(void)
  * call to iio_device_register. */
 #define IIO_VAL_INT 1
 #define IIO_VAL_INT_PLUS_MICRO 2
+
+/**
+ * struct iio_info - constant information about device
+ * @driver_module:	module structure used to ensure correct
+ *			ownership of chrdevs etc
+ * @num_interrupt_lines:number of physical interrupt lines from device
+ * @event_attrs:	event control attributes
+ * @attrs:		general purpose device attributes
+ * @read_raw:		function to request a value from the device.
+ *			mask specifies which value. Note 0 means a reading of
+ *			the channel in question.  Return value will specify the
+ *			type of value returned by the device. val and val2 will
+ *			contain the elements making up the returned value.
+ * @write_raw:		function to write a value to the device.
+ *			Parameters are the same as for read_raw.
+ * @read_event_config:	find out if the event is enabled.
+ * @write_event_config:	set if the event is enabled.
+ * @read_event_value:	read a value associated with the event. Meaning
+ *			is event dependant. event_code specifies which event.
+ * @write_event_value:	write the value associate with the event.
+ *			Meaning is event dependent.
+ **/
+struct iio_info {
+	struct module			*driver_module;
+	int				num_interrupt_lines;
+	struct attribute_group		*event_attrs;
+	const struct attribute_group	*attrs;
+
+	int (*read_raw)(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val,
+			int *val2,
+			long mask);
+
+	int (*write_raw)(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan,
+			 int val,
+			 int val2,
+			 long mask);
+
+	int (*read_event_config)(struct iio_dev *indio_dev,
+				 int event_code);
+
+	int (*write_event_config)(struct iio_dev *indio_dev,
+				  int event_code,
+				  int state);
+
+	int (*read_event_value)(struct iio_dev *indio_dev,
+				int event_code,
+				int *val);
+	int (*write_event_value)(struct iio_dev *indio_dev,
+				 int event_code,
+				 int val);
+};
+
 /**
  * struct iio_dev - industrial I/O device
  * @id:			[INTERN] used to identify device internally
@@ -210,11 +265,6 @@ static inline s64 iio_get_time_ns(void)
  * @currentmode:	[DRIVER] current operating mode
  * @dev:		[DRIVER] device structure, should be assigned a parent
  *			and owner
- * @attrs:		[DRIVER] general purpose device attributes
- * @driver_module:	[DRIVER] module structure used to ensure correct
- *			ownership of chrdevs etc
- * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device
- * @event_attrs:	[DRIVER] event control attributes
  * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
  * @ring:		[DRIVER] any ring buffer present
  * @mlock:		[INTERN] lock used to prevent simultaneous device state
@@ -227,19 +277,6 @@ static inline s64 iio_get_time_ns(void)
  * @channel_attr_list:	[INTERN] keep track of automatically created channel
  *			attributes.
  * @name:		[DRIVER] name of the device.
- * @read_raw:		[DRIVER] function to request a value from the device.
- *			mask specifies which value. Note 0 means a reading of
- *			the channel in question.  Return value will specify the
- *			type of value returned by the device. val and val2 will
- *			contain the elements making up the returned value.
- * @write_raw:		[DRIVER] function to write a value to the device.
- *			Parameters are the same as for read_raw.
- * @read_event_config:	[DRIVER] find out if the event is enabled.
- * @write_event_config:	[DRIVER] set if the event is enabled.
- * @read_event_value:	[DRIVER] read a value associated with the event. Meaning
- *			is event dependant. event_code specifies which event.
- * @write_event_value:	[DRIVER] write the value associate with the event.
- *			Meaning is event dependent.
  **/
 struct iio_dev {
 	int				id;
@@ -247,11 +284,7 @@ struct iio_dev {
 	int				modes;
 	int				currentmode;
 	struct device			dev;
-	const struct attribute_group	*attrs;
-	struct module			*driver_module;
 
-	int				num_interrupt_lines;
-	struct attribute_group		*event_attrs;
 	struct iio_event_interface	*event_interfaces;
 
 	struct iio_ring_buffer		*ring;
@@ -263,34 +296,10 @@ struct iio_dev {
 
 	struct iio_chan_spec const *channels;
 	int num_channels;
-	struct list_head channel_attr_list;
 
+	struct list_head channel_attr_list;
 	const char *name;
-	int (*read_raw)(struct iio_dev *indio_dev,
-			struct iio_chan_spec const *chan,
-			int *val,
-			int *val2,
-			long mask);
-
-	int (*write_raw)(struct iio_dev *indio_dev,
-			 struct iio_chan_spec const *chan,
-			 int val,
-			 int val2,
-			 long mask);
-
-	int (*read_event_config)(struct iio_dev *indio_dev,
-				 int event_code);
-
-	int (*write_event_config)(struct iio_dev *indio_dev,
-				  int event_code,
-				  int state);
-
-	int (*read_event_value)(struct iio_dev *indio_dev,
-				int event_code,
-				int *val);
-	int (*write_event_value)(struct iio_dev *indio_dev,
-				 int event_code,
-				 int val);
+	const struct iio_info *info;
 };
 
 /**
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 0067bc7..fe89802 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -770,7 +770,12 @@ static struct adis16400_chip_info adis16400_chips[] = {
 	}
 };
 
-
+static const struct iio_info adis16400_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &adis16400_read_raw,
+	.write_raw = &adis16400_write_raw,
+	.attrs = &adis16400_attribute_group,
+};
 
 static int __devinit adis16400_probe(struct spi_device *spi)
 {
@@ -792,12 +797,9 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 	st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(spi)->name;
-	indio_dev->attrs = &adis16400_attribute_group;
 	indio_dev->channels = st->variant->channels;
 	indio_dev->num_channels = st->variant->num_channels;
-	indio_dev->read_raw = &adis16400_read_raw;
-	indio_dev->write_raw = &adis16400_write_raw;
-	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->info = &adis16400_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16400_configure_ring(indio_dev);
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 9218fee..94d3bfa 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -383,8 +383,8 @@ static ssize_t iio_read_channel_info(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int val, val2;
-	int ret = indio_dev->read_raw(indio_dev, this_attr->c,
-				      &val, &val2, this_attr->address);
+	int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
+					    &val, &val2, this_attr->address);
 
 	if (ret < 0)
 		return ret;
@@ -411,7 +411,7 @@ static ssize_t iio_write_channel_info(struct device *dev,
 	bool integer_part = true, negative = false;
 
 	/* Assumes decimal - precision based on number of digits */
-	if (!indio_dev->write_raw)
+	if (!indio_dev->info->write_raw)
 		return -EINVAL;
 	if (buf[0] == '-') {
 		negative = true;
@@ -446,8 +446,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
 			micro = -micro;
 	}
 
-	ret = indio_dev->write_raw(indio_dev, this_attr->c,
-				       integer, micro, this_attr->address);
+	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
+					 integer, micro, this_attr->address);
 	if (ret)
 		return ret;
 
@@ -707,8 +707,9 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
 	int i, ret = 0;
 	struct iio_dev_attr *p, *n;
 
-	if (dev_info->attrs) {
-		ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
+	if (dev_info->info->attrs) {
+		ret = sysfs_create_group(&dev_info->dev.kobj,
+					 dev_info->info->attrs);
 		if (ret) {
 			dev_err(dev_info->dev.parent,
 				"Failed to register sysfs hooks\n");
@@ -744,8 +745,8 @@ error_clear_attrs:
 		list_del(&p->l);
 		iio_device_remove_and_free_read_attr(dev_info, p);
 	}
-	if (dev_info->attrs)
-		sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
+	if (dev_info->info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
 error_ret:
 	return ret;
 
@@ -764,8 +765,8 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 		iio_device_remove_and_free_read_attr(dev_info, p);
 	}
 
-	if (dev_info->attrs)
-		sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
+	if (dev_info->info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
 }
 
 /* Return a negative errno on failure */
@@ -824,8 +825,9 @@ static ssize_t iio_ev_state_store(struct device *dev,
 	if (ret < 0)
 		return ret;
 
-	ret = indio_dev->write_event_config(indio_dev, this_attr->address,
-					    val);
+	ret = indio_dev->info->write_event_config(indio_dev,
+						  this_attr->address,
+						  val);
 	return (ret < 0) ? ret : len;
 }
 
@@ -835,7 +837,8 @@ static ssize_t iio_ev_state_show(struct device *dev,
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int val = indio_dev->read_event_config(indio_dev, this_attr->address);
+	int val = indio_dev->info->read_event_config(indio_dev,
+						     this_attr->address);
 
 	if (val < 0)
 		return val;
@@ -851,8 +854,8 @@ static ssize_t iio_ev_value_show(struct device *dev,
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int val, ret;
 
-	ret = indio_dev->read_event_value(indio_dev,
-					  this_attr->address, &val);
+	ret = indio_dev->info->read_event_value(indio_dev,
+						this_attr->address, &val);
 	if (ret < 0)
 		return ret;
 
@@ -873,8 +876,8 @@ static ssize_t iio_ev_value_store(struct device *dev,
 	if (ret)
 		return ret;
 
-	ret = indio_dev->write_event_value(indio_dev, this_attr->address,
-					   val);
+	ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
+						 val);
 	if (ret < 0)
 		return ret;
 
@@ -930,8 +933,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 					       extending the bitmask - but
 					       how far*/
 					     0,
-					     &dev_info->event_interfaces[0]
-					     .dev,
+					     &dev_info->event_interfaces[0].dev,
 					     &dev_info->event_interfaces[0].
 					     dev_attr_list);
 		kfree(postfix);
@@ -1015,23 +1017,23 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 {
 	int ret = 0, i, j;
 
-	if (dev_info->num_interrupt_lines == 0)
+	if (dev_info->info->num_interrupt_lines == 0)
 		return 0;
 
 	dev_info->event_interfaces =
 		kzalloc(sizeof(struct iio_event_interface)
-			*dev_info->num_interrupt_lines,
+			*dev_info->info->num_interrupt_lines,
 			GFP_KERNEL);
 	if (dev_info->event_interfaces == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
 
-	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
 				       dev_name(&dev_info->dev),
 				       i,
-				       dev_info->driver_module,
+				       dev_info->info->driver_module,
 				       &dev_info->dev);
 		if (ret) {
 			dev_err(&dev_info->dev,
@@ -1042,11 +1044,12 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 		dev_set_drvdata(&dev_info->event_interfaces[i].dev,
 				(void *)dev_info);
 
-		if (dev_info->event_attrs != NULL)
+		if (dev_info->info->event_attrs != NULL)
 			ret = sysfs_create_group(&dev_info
 						 ->event_interfaces[i]
 						 .dev.kobj,
-						 &dev_info->event_attrs[i]);
+						 &dev_info->info
+						 ->event_attrs[i]);
 
 		if (ret) {
 			dev_err(&dev_info->dev,
@@ -1055,7 +1058,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 		}
 	}
 
-	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		ret = __iio_add_event_config_attrs(dev_info, i);
 		if (ret)
 			goto error_unregister_config_attrs;
@@ -1066,13 +1069,13 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 error_unregister_config_attrs:
 	for (j = 0; j < i; j++)
 		__iio_remove_event_config_attrs(dev_info, i);
-	i = dev_info->num_interrupt_lines - 1;
+	i = dev_info->info->num_interrupt_lines - 1;
 error_remove_sysfs_interfaces:
 	for (j = 0; j < i; j++)
-		if (dev_info->event_attrs != NULL)
+		if (dev_info->info->event_attrs != NULL)
 			sysfs_remove_group(&dev_info
 				   ->event_interfaces[j].dev.kobj,
-				   &dev_info->event_attrs[j]);
+				   &dev_info->info->event_attrs[j]);
 error_free_setup_ev_ints:
 	for (j = 0; j < i; j++)
 		iio_free_ev_int(&dev_info->event_interfaces[j]);
@@ -1086,17 +1089,17 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 {
 	int i;
 
-	if (dev_info->num_interrupt_lines == 0)
+	if (dev_info->info->num_interrupt_lines == 0)
 		return;
-	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		__iio_remove_event_config_attrs(dev_info, i);
-		if (dev_info->event_attrs != NULL)
+		if (dev_info->info->event_attrs != NULL)
 			sysfs_remove_group(&dev_info
 					   ->event_interfaces[i].dev.kobj,
-					   &dev_info->event_attrs[i]);
+					   &dev_info->info->event_attrs[i]);
 	}
 
-	for (i = 0; i < dev_info->num_interrupt_lines; i++)
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++)
 		iio_free_ev_int(&dev_info->event_interfaces[i]);
 	kfree(dev_info->event_interfaces);
 }
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 307c664..4794ffd 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -455,6 +455,11 @@ static int isl29018_chip_init(struct i2c_client *client)
 	return 0;
 }
 
+static const struct iio_info isl29108_info = {
+	.attrs = &isl29108_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit isl29018_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -485,11 +490,10 @@ static int __devinit isl29018_probe(struct i2c_client *client,
 		dev_err(&client->dev, "iio allocation fails\n");
 		goto exit_free;
 	}
-	chip->indio_dev->attrs = &isl29108_group;
+	chip->indio_dev->info = &isl29108_info;
 	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 	err = iio_device_register(chip->indio_dev);
 	if (err) {
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index ded3053..9cffa2e 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -688,6 +688,21 @@ error_ret:
 /*--------------------------------------------------------------*/
 static struct i2c_driver tsl2563_i2c_driver;
 
+static const struct iio_info tsl2563_info_no_irq = {
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info tsl2563_info = {
+	.driver_module = THIS_MODULE,
+	.num_interrupt_lines = 1,
+	.read_raw = &tsl2563_read_raw,
+	.write_raw = &tsl2563_write_raw,
+	.read_event_value = &tsl2563_read_thresh,
+	.write_event_value = &tsl2563_write_thresh,
+	.read_event_config = &tsl2563_read_interrupt_config,
+	.write_event_config = &tsl2563_write_interrupt_config,
+};
+
 static int __devinit tsl2563_probe(struct i2c_client *client,
 				const struct i2c_device_id *device_id)
 {
@@ -736,17 +751,12 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 	indio_dev->name = client->name;
 	indio_dev->channels = tsl2563_channels;
 	indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
-	indio_dev->read_raw = &tsl2563_read_raw;
-	indio_dev->write_raw = &tsl2563_write_raw;
-	indio_dev->read_event_value = &tsl2563_read_thresh;
-	indio_dev->write_event_value = &tsl2563_write_thresh;
-	indio_dev->read_event_config = &tsl2563_read_interrupt_config;
-	indio_dev->write_event_config = &tsl2563_write_interrupt_config;
 	indio_dev->dev.parent = &client->dev;
-	indio_dev->driver_module = THIS_MODULE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	if (client->irq)
-		indio_dev->num_interrupt_lines = 1;
+		indio_dev->info = &tsl2563_info;
+	else
+		indio_dev->info = &tsl2563_info_no_irq;
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto fail1;
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index b87ccd5..5694610 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -786,6 +786,11 @@ static int taos_tsl258x_device(unsigned char *bufp)
 	return ((bufp[TSL258X_CHIPID] & 0xf0) == 0x90);
 }
 
+static const struct iio_info tsl2583_info = {
+	.attrs = &tsl2583_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * Client probe function - When a valid device is found, the driver's device
  * data structure is updated, and initialization completes successfully.
@@ -854,10 +859,9 @@ static int __devinit taos_probe(struct i2c_client *clientp,
 		goto fail1;
 	}
 
-	chip->iio_dev->attrs = &tsl2583_attribute_group;
+	chip->iio_dev->info = &tsl2583_info;
 	chip->iio_dev->dev.parent = &clientp->dev;
 	chip->iio_dev->dev_data = (void *)(chip);
-	chip->iio_dev->driver_module = THIS_MODULE;
 	chip->iio_dev->modes = INDIO_DIRECT_MODE;
 	ret = iio_device_register(chip->iio_dev);
 	if (ret) {
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
index 2226b88..700f96c 100644
--- a/drivers/staging/iio/magnetometer/ak8975.c
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -474,6 +474,11 @@ static struct attribute_group ak8975_attr_group = {
 	.attrs = ak8975_attr,
 };
 
+static const struct iio_info ak8975_info = {
+	.attrs = &ak8975_attr_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int ak8975_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -533,9 +538,8 @@ static int ak8975_probe(struct i2c_client *client,
 	}
 
 	data->indio_dev->dev.parent = &client->dev;
-	data->indio_dev->attrs = &ak8975_attr_group;
+	data->indio_dev->info = &ak8975_info;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	err = iio_device_register(data->indio_dev);
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index d0676e9..dd9a3bb 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -529,6 +529,11 @@ static void hmc5843_init_client(struct i2c_client *client)
 	pr_info("HMC5843 initialized\n");
 }
 
+static const struct iio_info hmc5843_info = {
+	.attrs = &hmc5843_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int hmc5843_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -557,10 +562,9 @@ static int hmc5843_probe(struct i2c_client *client,
 		err = -ENOMEM;
 		goto exit_free1;
 	}
-	data->indio_dev->attrs = &hmc5843_group;
+	data->indio_dev->info = &hmc5843_info;
 	data->indio_dev->dev.parent = &client->dev;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 	err = iio_device_register(data->indio_dev);
 	if (err)
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 8b6bf50..6c9c23f 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -504,6 +504,11 @@ static const struct attribute_group ade7753_attribute_group = {
 	.attrs = ade7753_attributes,
 };
 
+static const struct iio_info ade7753_info = {
+	.attrs = &ade7753_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ade7753_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -537,9 +542,8 @@ static int __devinit ade7753_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ade7753_attribute_group;
+	st->indio_dev->info = &ade7753_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 4179325..378f2c8 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -527,7 +527,10 @@ static const struct attribute_group ade7754_attribute_group = {
 	.attrs = ade7754_attributes,
 };
 
-
+static const struct iio_info ade7754_info = {
+	.attrs = &ade7754_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 
 static int __devinit ade7754_probe(struct spi_device *spi)
 {
@@ -562,9 +565,8 @@ static int __devinit ade7754_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ade7754_attribute_group;
+	st->indio_dev->info = &ade7754_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index d9dfd83..299b954 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -725,6 +725,11 @@ static struct iio_chan_spec ade7758_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(15),
 };
 
+static const struct iio_info ade7758_info = {
+	.attrs = &ade7758_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ade7758_probe(struct spi_device *spi)
 {
 	int i, ret, regdone = 0;
@@ -757,8 +762,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 
 	indio_dev->name = spi->dev.driver->name;
 	indio_dev->dev.parent = &spi->dev;
-	indio_dev->attrs = &ade7758_attribute_group;
-	indio_dev->driver_module = THIS_MODULE;
+	indio_dev->info = &ade7758_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	for (i = 0; i < AD7758_NUM_WAVESRC; i++)
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 86fe0ae..730f6d9 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -450,6 +450,11 @@ static const struct attribute_group ade7759_attribute_group = {
 	.attrs = ade7759_attributes,
 };
 
+static const struct iio_info ade7759_info = {
+	.attrs = &ade7759_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ade7759_probe(struct spi_device *spi)
 {
 	int ret;
@@ -483,11 +488,9 @@ static int __devinit ade7759_probe(struct spi_device *spi)
 
 	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
 
-	st->indio_dev->attrs = &ade7759_attribute_group;
+	st->indio_dev->info = &ade7759_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index d3f1df7..44cd3ec 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -551,6 +551,11 @@ static const struct attribute_group ade7854_attribute_group = {
 	.attrs = ade7854_attributes,
 };
 
+static const struct iio_info ade7854_info = {
+	.attrs = &ade7854_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 int ade7854_probe(struct ade7854_state *st, struct device *dev)
 {
 	int ret;
@@ -575,9 +580,8 @@ int ade7854_probe(struct ade7854_state *st, struct device *dev)
 	}
 
 	st->indio_dev->dev.parent = dev;
-	st->indio_dev->attrs = &ade7854_attribute_group;
+	st->indio_dev->info = &ade7854_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c
index e0237ff..f83e142 100644
--- a/drivers/staging/iio/resolver/ad2s120x.c
+++ b/drivers/staging/iio/resolver/ad2s120x.c
@@ -209,10 +209,14 @@ static struct attribute *ad2s120x_attributes[] = {
 };
 
 static const struct attribute_group ad2s120x_attribute_group = {
-	.name = DRV_NAME,
 	.attrs = ad2s120x_attributes,
 };
 
+static const struct iio_info ad2s120x_info = {
+	.attrs = &ad2s120x_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s120x_probe(struct spi_device *spi)
 {
 	struct ad2s120x_state *st;
@@ -246,12 +250,9 @@ static int __devinit ad2s120x_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s120x_attribute_group;
+	st->idev->info = &ad2s120x_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index dc7cae8..09f4fcf 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -755,6 +755,11 @@ error_ret:
 	return ret;
 }
 
+static const struct iio_info ad2s1210_info = {
+	.attrs = &ad2s1210_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s1210_probe(struct spi_device *spi)
 {
 	struct ad2s1210_state *st;
@@ -806,12 +811,9 @@ static int __devinit ad2s1210_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s1210_attribute_group;
+	st->idev->info = &ad2s1210_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
index e300ade..9b72a95 100644
--- a/drivers/staging/iio/resolver/ad2s90.c
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -75,6 +75,11 @@ static const struct attribute_group ad2s90_attribute_group = {
 	.attrs = ad2s90_attributes,
 };
 
+static const struct iio_info ad2s90_info = {
+	.attrs = &ad2s90_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s90_probe(struct spi_device *spi)
 {
 	struct ad2s90_state *st;
@@ -96,12 +101,9 @@ static int __devinit ad2s90_probe(struct spi_device *spi)
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s90_attribute_group;
+	st->idev->info = &ad2s90_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 108/111] staging:iio:max1363 misc cleanups and use of for_each_bit_set to simplify event code spitting out.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (106 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 107/111] staging:iio: implement an iio_info structure to take some of the constant elements out of iio_dev Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 109/111] staging:iio: use pollfunc allocation helpers in remaining drivers Jonathan Cameron
                   ` (3 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/max1363.h      |   64 ------------------
 drivers/staging/iio/adc/max1363_core.c |  114 +++++++++++++++++--------------
 drivers/staging/iio/adc/max1363_ring.c |    1 +
 3 files changed, 63 insertions(+), 116 deletions(-)

diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 5243b5a..360bfc5 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -67,70 +67,6 @@ struct max1363_mode {
 	long		modemask;
 };
 
-#define MAX1363_MODE_SINGLE(_num, _mask) {				\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_SINGLE_1			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask,				\
-			}
-
-#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_TO_CS			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask,				\
-			}
-
-
-/* note not available for max1363 hence naming */
-#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1236_SCAN_MID_TO_CHANNEL			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask				\
-}
-
-#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
-		.conf = MAX1363_CHANNEL_SEL(_nump)			\
-			| MAX1363_CONFIG_SCAN_SINGLE_1			\
-			| MAX1363_CONFIG_DE,				\
-			.modemask = _mask				\
-			}
-
-/* Can't think how to automate naming so specify for now */
-#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_TO_CS			\
-			| MAX1363_CONFIG_DE,				\
-			.modemask = _mask				\
-			}
-
-/* note only available for max1363 hence naming */
-#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1236_SCAN_MID_TO_CHANNEL			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask				\
-}
-
-/* This may seem an overly long winded way to do this, but at least it makes
- * clear what all the various options actually do. Alternative suggestions
- * that don't require user to have intimate knowledge of the chip welcomed.
- */
-enum max1363_channels {
-	max1363_in0, max1363_in1, max1363_in2, max1363_in3,
-	max1363_in4, max1363_in5, max1363_in6, max1363_in7,
-	max1363_in8, max1363_in9, max1363_in10, max1363_in11,
-
-	max1363_in0min1, max1363_in2min3,
-	max1363_in4min5, max1363_in6min7,
-	max1363_in8min9, max1363_in10min11,
-
-	max1363_in1min0, max1363_in3min2,
-	max1363_in5min4, max1363_in7min6,
-	max1363_in9min8, max1363_in11min10,
-};
-
 /* This must be maintained along side the max1363_mode_table in max1363_core */
 enum max1363_modes {
 	/* Single read of a single channel */
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 8d09bf3..98cebd2 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -38,8 +38,50 @@
 #include "adc.h"
 #include "max1363.h"
 
-/* Here we claim all are 16 bits. This currently does no harm and saves
- * us a lot of scan element listings */
+#define MAX1363_MODE_SINGLE(_num, _mask) {				\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask,				\
+			}
+
+#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask,				\
+			}
+
+/* note not available for max1363 hence naming */
+#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask				\
+}
+
+#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
+		.conf = MAX1363_CHANNEL_SEL(_nump)			\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_DE,				\
+			.modemask = _mask				\
+			}
+
+/* Can't think how to automate naming so specify for now */
+#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) {	\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_DE,				\
+			.modemask = _mask				\
+			}
+
+/* note only available for max1363 hence naming */
+#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) {	\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask				\
+}
 
 static const struct max1363_mode max1363_mode_table[] = {
 	/* All of the single channel options first */
@@ -120,18 +162,9 @@ static int max1363_write_basic_config(struct i2c_client *client,
 				      unsigned char d1,
 				      unsigned char d2)
 {
-	int ret;
-	u8 *tx_buf = kmalloc(2, GFP_KERNEL);
-
-	if (!tx_buf)
-		return -ENOMEM;
-	tx_buf[0] = d1;
-	tx_buf[1] = d2;
-
-	ret = i2c_master_send(client, tx_buf, 2);
-	kfree(tx_buf);
+	u8 tx_buf[2] = {d1, d2};
 
-	return (ret > 0) ? 0 : ret;
+	return i2c_master_send(client, tx_buf, 2);
 }
 
 int max1363_set_scan_mode(struct max1363_state *st)
@@ -179,13 +212,11 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
 		}
 	} else {
 		/* Check to see if current scan mode is correct */
-		if (st->current_mode !=
-		    &max1363_mode_table[chan->address]) {
+		if (st->current_mode != &max1363_mode_table[chan->address]) {
 			/* Update scan mode if needed */
-			st->current_mode
-				= &max1363_mode_table[chan->address];
+			st->current_mode = &max1363_mode_table[chan->address];
 			ret = max1363_set_scan_mode(st);
-			if (ret)
+			if (ret < 0)
 				goto error_ret;
 		}
 		if (st->chip_info->bits != 8) {
@@ -560,49 +591,28 @@ static int max1363_write_thresh(struct iio_dev *indio_dev,
 	return 0;
 }
 
+static const int max1363_event_codes[] = {
+	IIO_EVENT_CODE_IN_LOW_THRESH(3), IIO_EVENT_CODE_IN_HIGH_THRESH(3),
+	IIO_EVENT_CODE_IN_LOW_THRESH(2), IIO_EVENT_CODE_IN_HIGH_THRESH(2),
+	IIO_EVENT_CODE_IN_LOW_THRESH(1), IIO_EVENT_CODE_IN_HIGH_THRESH(1),
+	IIO_EVENT_CODE_IN_LOW_THRESH(0), IIO_EVENT_CODE_IN_HIGH_THRESH(0)
+};
+
 static irqreturn_t max1363_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
 	struct max1363_state *st = iio_priv(indio_dev);
 	s64 timestamp = iio_get_time_ns();
+	unsigned long mask, loc;
 	u8 rx;
 	u8 tx[2] = { st->setupbyte,
 		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
 
 	i2c_master_recv(st->client, &rx, 1);
-	/* todo - begging for use of for_each_set_bit */
-	if (rx & (1 << 0))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(3),
-			timestamp);
-	if (rx & (1 << 1))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(3),
-			timestamp);
-	if (rx & (1 << 2))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(2),
-			timestamp);
-	if (rx & (1 << 3))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(2),
-			timestamp);
-	if (rx & (1 << 4))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(1),
-			timestamp);
-	if (rx & (1 << 5))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(1),
-			timestamp);
-	if (rx & (1 << 6))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(0),
-			timestamp);
-	if (rx & (1 << 7))
-		iio_push_event(indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(0),
-			timestamp);
+	mask = rx;
+	for_each_set_bit(loc, &mask, 8)
+		iio_push_event(indio_dev, 0, max1363_event_codes[loc],
+			       timestamp);
 	i2c_master_send(st->client, tx, 2);
 
 	return IRQ_HANDLED;
@@ -1283,7 +1293,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	indio_dev->info = st->chip_info->info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	ret = max1363_initial_setup(st);
-	if (ret)
+	if (ret < 0)
 		goto error_free_available_scan_masks;
 
 	ret = max1363_register_ring_funcs_and_init(indio_dev);
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 9638909..1587aec1 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -63,6 +63,7 @@ error_ret:
 	return ret;
 }
 
+
 /**
  * max1363_ring_preenable() - setup the parameters of the ring before enabling
  *
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 109/111] staging:iio: use pollfunc allocation helpers in remaining drivers.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (107 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 108/111] staging:iio:max1363 misc cleanups and use of for_each_bit_set to simplify event code spitting out Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 110/111] staging:iio:documenation partial update Jonathan Cameron
                   ` (2 subsequent siblings)
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Some didn't get converted the first time around.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq_ring.c |   16 +++++++---------
 drivers/staging/iio/adc/ad7298_ring.c      |   24 ++++++++++--------------
 drivers/staging/iio/adc/ad7476_ring.c      |   26 ++++++++++----------------
 drivers/staging/iio/adc/ad7606_ring.c      |   24 +++++++++---------------
 drivers/staging/iio/adc/ad7887_ring.c      |   24 ++++++++----------------
 drivers/staging/iio/adc/ad799x_ring.c      |   25 ++++++++++---------------
 drivers/staging/iio/adc/max1363_ring.c     |   24 +++++++++---------------
 drivers/staging/iio/gyro/adis16260_ring.c  |   23 ++++++++---------------
 drivers/staging/iio/meter/ade7758_ring.c   |   22 ++++++++--------------
 9 files changed, 79 insertions(+), 129 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 1c208d2..8d5c8ac 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -344,8 +344,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 
 void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	lis3l02dq_free_buf(indio_dev->ring);
 }
 
@@ -448,18 +447,17 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, 2);
 
 	/* Functions are NULL as we set handler below */
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &lis3l02dq_trigger_handler,
+						 0,
+						 indio_dev,
+						 "lis3l02dq_consumer%d",
+						 indio_dev->id);
 
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->thread = &lis3l02dq_trigger_handler;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->type = 0;
-	indio_dev->pollfunc->name
-		= kasprintf(GFP_KERNEL, "lis3l02dq_consumer%d", indio_dev->id);
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index d0a0aeaaf..a04c033 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -164,20 +164,18 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &ad7298_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "ad7298_consumer%d",
+						 indio_dev->id);
+
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->thread = &ad7298_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "ad7298_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
+
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->ring->setup_ops = &ad7298_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
@@ -185,8 +183,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -200,7 +197,6 @@ void ad7298_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 1d696ef..b1b2ee2 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -125,22 +125,18 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
-	indio_dev->pollfunc = kzalloc(sizeof(indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc
+		= iio_alloc_pollfunc(NULL,
+				     &ad7476_trigger_handler,
+				     IRQF_ONESHOT,
+				     indio_dev,
+				     "%s_consumer%d",
+				     spi_get_device_id(st->spi)->name,
+				     indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->thread = &ad7476_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name
-		= kasprintf(GFP_KERNEL, "%s_consumer%d",
-			    spi_get_device_id(st->spi)->name,
-			    indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_pollfunc;
-	}
 
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->ring->setup_ops = &ad7476_ring_setup_ops;
@@ -149,8 +145,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_pollfunc:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -165,7 +160,6 @@ void ad7476_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 85cde6a..a199bf4 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -169,22 +169,18 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
+						 &ad7606_trigger_handler_th_bh,
+						 0,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
 
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &ad7606_trigger_handler_th_bh;
-	indio_dev->pollfunc->thread = &ad7606_trigger_handler_th_bh;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "%s_consumer%d", indio_dev->name,
-			  indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
 	/* Ring buffer functions - here trigger setup related */
 
 	indio_dev->ring->setup_ops = &ad7606_ring_setup_ops;
@@ -195,8 +191,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -210,7 +205,6 @@ void ad7606_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index f3485b3..0e4a5f4 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -166,30 +166,23 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &ad7887_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "ad7887_consumer%d",
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &ad7887_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "ad7887_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_pollfunc;
-	}
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->ring->setup_ops = &ad7887_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_pollfunc:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -204,7 +197,6 @@ void ad7887_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 57dca20..1ae8857 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -179,21 +179,18 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	}
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &ad799x_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->thread = &ad799x_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "%s_consumer%d", indio_dev->name,
-			  indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_poll_func;
-	}
+
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->ring->setup_ops = &ad799x_buf_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
@@ -201,8 +198,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_poll_func:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -217,7 +213,6 @@ void ad799x_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 1587aec1..f43befd 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -169,21 +169,17 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &max1363_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 st->client->name,
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->thread = &max1363_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "%s_consumer%d",
-			  st->client->name, indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_pollfunc;
-	}
 	/* Effectively select the ring buffer implementation */
 	indio_dev->ring->access = &ring_sw_access_funcs;
 	/* Ring buffer functions - here trigger setup related */
@@ -193,8 +189,7 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 
 	return 0;
-error_free_pollfunc:
-	kfree(indio_dev->pollfunc);
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -209,7 +204,6 @@ void max1363_ring_cleanup(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 85586e4..a092504 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -101,8 +101,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
 
 void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -137,26 +136,20 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	iio_scan_mask_set(ring, ADIS16260_SCAN_TEMP);
 	iio_scan_mask_set(ring, ADIS16260_SCAN_ANGL);
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16260_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16260_consumer%d",
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &adis16260_trigger_handler;
-	indio_dev->pollfunc->type = IRQF_ONESHOT;
-	indio_dev->pollfunc->name =
-		kasprintf(GFP_KERNEL, "adis16260_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_pollfunc;
-	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-error_free_pollfunc:
-	kfree(indio_dev->pollfunc);
+
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index a5e48c1..b89b7f8 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -142,8 +142,7 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc->name);
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
@@ -163,20 +162,17 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 	indio_dev->ring->setup_ops = &ade7758_ring_setup_ops;
 	indio_dev->ring->owner = THIS_MODULE;
 
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &ade7758_trigger_handler,
+						 0,
+						 indio_dev,
+						 "ade7759_consumer%d",
+						 indio_dev->id);
 	if (indio_dev->pollfunc == NULL) {
 		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
 	}
-	indio_dev->pollfunc->private_data = indio_dev;
-	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
-	indio_dev->pollfunc->thread = &ade7758_trigger_handler;
-	indio_dev->pollfunc->name
-		= kasprintf(GFP_KERNEL, "ade7759_consumer%d", indio_dev->id);
-	if (indio_dev->pollfunc->name == NULL) {
-		ret = -ENOMEM;
-		goto error_free_pollfunc;
-	}
+
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 
 	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
@@ -214,8 +210,6 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 
 	return 0;
 
-error_free_pollfunc:
-	kfree(indio_dev->pollfunc);
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 110/111] staging:iio:documenation partial update.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (108 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 109/111] staging:iio: use pollfunc allocation helpers in remaining drivers Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 13:42 ` [PATCH 111/111] staging:iio: Trivial kconfig reorganization and uniformity improvements Jonathan Cameron
  2011-05-18 15:25 ` [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Greg KH
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

More to be added, but this brings the docs in line with
the current code. Now they are hopefully just uninformative
rather than actually incorrect.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/Documentation/device.txt    |   78 ++++++++++++++++-------
 drivers/staging/iio/Documentation/overview.txt  |   19 ++----
 drivers/staging/iio/Documentation/ring.txt      |   44 ++++++-------
 drivers/staging/iio/Documentation/trigger.txt   |   16 +++---
 drivers/staging/iio/Documentation/userspace.txt |   12 ----
 5 files changed, 91 insertions(+), 78 deletions(-)

diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
index c81e517..1abb80c 100644
--- a/drivers/staging/iio/Documentation/device.txt
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -8,34 +8,66 @@ The crucial structure for device drivers in iio is iio_dev.
 
 First allocate one using:
 
-struct iio_dev *indio_dev = iio_allocate_device(0);
+struct iio_dev *indio_dev = iio_allocate_device(sizeof(struct chip_state));
+where chip_state is a structure of local state data for this instance of
+the chip.
 
-Then fill in the following:
-
-indio_dev->dev.parent
-  the struct device associated with the underlying hardware.
-
-indio_dev->num_interrupt_lines
-   number of event triggering hardware lines the device has.
+That data can be accessed using iio_priv(struct iio_dev *)
 
-indio_dev->event_attrs
-   attributes used to enable / disable hardware events - note the
-   attributes are embedded in iio_event_attr structures with an
-   associated iio_event_handler which may or may note be shared.
-   If num_interrupt_lines = 0, then no need to fill this in.
-
-indio_dev->attrs
-   general attributes such as polled access to device channels.
+Then fill in the following:
 
-indio_dev->dev_data
-   private device specific data.
+- indio_dev->dev.parent
+	Struct device associated with the underlying hardware.
+- indio_dev->name
+	Name of the device being driven - made available as the name
+	attribute in sysfs.
 
-indio_dev->driver_module
-   typically set to THIS_MODULE. Used to specify ownership of some
-   iio created resources.
+- indio_dev->info
+	pointer to a structure with elements that tend to be fixed for
+	large sets of different parts supported by a given driver.
+	This contains:
+	* info->driver_module:
+		Set to THIS_MODULE. Used to ensure correct ownership
+		of various resources allocate by the core.
+	* info->num_interrupt_lines:
+		Number of event triggering hardware lines the device has.
+	* info->event_attrs:
+		Attributes used to enable / disable hardware events.
+	* info->attrs:
+		General device attributes. Typically used for the weird
+		and the wonderful bits not covered by the channel specification.
+	* info->read_raw:
+		Raw data reading function. Used for both raw channel access
+		and for associate parameters such as offsets and scales.
+	* info->write_raw:
+		Raw value writing function. Used for writable device values such
+		as DAC values and caliboffset.
+	* info->read_event_config:
+		Typically only set if there are some interrupt lines.  This
+		is used to read if an on sensor event detector is enabled.
+	* info->write_event_config:
+		Enable / disable an on sensor event detector.
+	* info->read_event_value:
+		Read value associated with on sensor event detectors. Note that
+		the meaning of the returned value is dependent on the event
+		type.
+	* info->write_event_value:
+		Write the value associated with on sensor event detectors. E.g.
+		a threshold above which an interrupt occurs.  Note that the
+		meaning of the value to be set is event type dependant.
 
-indio_dev->modes
-   whether direct access and / or ring buffer access is supported.
+- indio_dev->modes:
+	Specify whether direct access and / or ring buffer access is supported.
+- indio_dev->ring:
+	An optional associated buffer.
+- indio_dev->pollfunc:
+	Poll function related elements. This controls what occurs when a trigger
+	to which this device is attached sends and event.
+- indio_dev->channels:
+	Specification of device channels. Most attributes etc are built
+	form this spec.
+- indio_dev->num_channels:
+	How many channels are there?
 
 Once these are set up, a call to iio_device_register(indio_dev),
 will register the device with the iio core.
diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt
index d97106c..afc39ec 100644
--- a/drivers/staging/iio/Documentation/overview.txt
+++ b/drivers/staging/iio/Documentation/overview.txt
@@ -3,8 +3,7 @@ Overview of IIO
 The Industrial I/O subsystem is intended to provide support for devices
 that in some sense are analog to digital converters (ADCs). As many
 actual devices combine some ADCs with digital to analog converters
-(DACs) the intention is to add that functionality at a future date
-(hence the name).
+(DACs) that functionality is also supported.
 
 The aim is to fill the gap between the somewhat similar hwmon and
 input subsystems.  Hwmon is very much directed at low sample rate
@@ -31,32 +30,28 @@ event must be accessed via polling.
 Note: A given device may have one or more event channel.  These events are
 turned on or off (if possible) via sysfs interfaces.
 
-* Hardware ring buffer support.  Some recent sensors have included
+* Hardware buffer support.  Some recent sensors have included
 fifo / ring buffers on the sensor chip.  These greatly reduce the load
 on the host CPU by buffering relatively large numbers of data samples
 based on an internal sampling clock. Examples include VTI SCA3000
-series and Analog Device ADXL345 accelerometers.  Each ring buffer
-typically has an event chrdev (similar to the more general ones above)
-to pass on events such as buffer 50% full and an access chrdev via
-which the raw data it self may be read back.
+series and Analog Device ADXL345 accelerometers.  Each buffer supports
+polling to establish when data is available.
 
-* Trigger and software ring buffer support. In many data analysis
+* Trigger and software buffer support. In many data analysis
 applications it it useful to be able to capture data based on some
 external signal (trigger).  These triggers might be a data ready
 signal, a gpio line connected to some external system or an on
 processor periodic interrupt.  A single trigger may initialize data
 capture or reading from a number of sensors.  These triggers are
-used in IIO to fill software ring buffers acting in a very similar
+used in IIO to fill software buffers acting in a very similar
 fashion to the hardware buffers described above.
 
 Other documentation:
 
-userspace.txt - overview of ring buffer reading from userspace.
-
 device.txt - elements of a typical device driver.
 
 trigger.txt - elements of a typical trigger driver.
 
-ring.txt - additional elements required for ring buffer support.
+ring.txt - additional elements required for buffer support.
 
 sysfs-bus-iio - abi documentation file.
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index 3696c36..7e99ef2 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -1,57 +1,55 @@
-Ring buffer support within IIO
+Buffer support within IIO
 
 This document is intended as a general overview of the functionality
-a ring buffer may supply and how it is specified within IIO.  For more
-specific information on a given ring buffer implementation, see the
-comments in the source code.  Note that the intention is to allow
-some drivers to specify ring buffers choice at probe or runtime, but
-for now the selection is hard coded within a given driver.
+a buffer may supply and how it is specified within IIO.  For more
+specific information on a given buffer implementation, see the
+comments in the source code.  Note that some drivers allow buffer
+implementation to be selected at compile time via Kconfig options.
 
-A given ring buffer implementation typically embedded a struct
+A given buffer implementation typically embeds a struct
 iio_ring_buffer and it is a pointer to this that is provided to the
 IIO core. Access to the embedding structure is typically done via
 container_of functions.
 
-struct iio_ring_buffer contains 4 function pointers
-(preenable, postenable, predisable, postdisable).
-These are used to perform implementation specific steps on either side
-of the core changing it's current mode to indicate that the ring buffer
+struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops
+which in turn contains the 4 function pointers
+(preenable, postenable, predisable and postdisable).
+These are used to perform device specific steps on either side
+of the core changing it's current mode to indicate that the buffer
 is enabled or disabled (along with enabling triggering etc as appropriate).
 
 Also in struct iio_ring_buffer is a struct iio_ring_access_funcs.
 The function pointers within here are used to allow the core to handle
-as much ring buffer functionality as possible. Note almost all of these
+as much buffer functionality as possible. Note almost all of these
 are optional.
 
 mark_in_use, unmark_in_use
-  Basically indicate that not changes should be made to the ring
-  buffer state that will effect the form of the data being captures
-  (e.g. scan elements or length)
+  Basically indicate that not changes should be made to the buffer state that
+  will effect the form of the data being captures (e.g. scan elements or length)
 
 store_to
-  If possible, push data to ring buffer.
+  If possible, push data to the buffer.
 
 read_last
-  If possible get the most recent entry from the buffer (without removal).
+  If possible, get the most recent scan from the buffer (without removal).
   This provides polling like functionality whilst the ring buffering is in
   use without a separate read from the device.
 
-rip_lots
-  The primary ring buffer reading function. Note that it may well not return
-  as much data as requested.  The deadoffset is used to indicate that some
-  initial data in the data array is not guaranteed to be valid.
+rip_first_n
+  The primary buffer reading function. Note that it may well not return
+  as much data as requested.
 
 mark_param_changed
   Used to indicate that something has changed. Used in conjunction with
 request_update
   If parameters have changed that require reinitialization or configuration of
-  the ring buffer this will trigger it.
+  the buffer this will trigger it.
 
 get_bytes_per_datum, set_bytes_per_datum
   Get/set the number of bytes for a complete scan. (All samples + timestamp)
 
 get_length / set_length
-  Get/set the number of sample sets that may be held by the buffer.
+  Get/set the number of complete scans that may be held by the buffer.
 
 is_enabled
   Query if ring buffer is in use
diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt
index 650157f..fc2012e 100644
--- a/drivers/staging/iio/Documentation/trigger.txt
+++ b/drivers/staging/iio/Documentation/trigger.txt
@@ -5,14 +5,11 @@ an IIO device.  Whilst this can create device specific complexities
 such triggers are registered with the core in the same way as
 stand-alone triggers.
 
-struct iio_trig *trig = iio_allocate_trigger();
+struct iio_trig *trig = iio_allocate_trigger("<trigger format string>", ...);
 
 allocates a trigger structure.  The key elements to then fill in within
 a driver are:
 
-trig->control_attrs
-	Any sysfs attributes needed to control parameters of the trigger
-
 trig->private_data
 	Device specific private data.
 
@@ -20,8 +17,12 @@ trig->owner
 	Typically set to THIS_MODULE. Used to ensure correct
 	ownership of core allocated resources.
 
-trig->name
-	A unique name for the trigger.
+trig->set_trigger_state:
+	Function that enables / disables the underlying source of the trigger.
+
+There is also a
+trig->alloc_list which is useful for drivers that allocate multiple
+triggers to keep track of what they have created.
 
 When these have been set call:
 
@@ -30,9 +31,8 @@ iio_trigger_register(trig);
 to register the trigger with the core, making it available to trigger
 consumers.
 
-
 Trigger Consumers
 
-Currently triggers are only used for the filling of software ring
+Currently triggers are only used for the filling of software
 buffers and as such any device supporting INDIO_RING_TRIGGERED has the
 consumer interface automatically created.
diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
deleted file mode 100644
index ff06e5d..0000000
--- a/drivers/staging/iio/Documentation/userspace.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Userspace access to IIO
-
-The sysfs attributes are documented in sysfs-bus-iio.
-
-Udev will create the following entries under /dev by default:
-
-device0:buffer0:access0 - ring access chrdev
-device0:buffer0:event0 - ring event chrdev
-device0:event0 - general event chrdev.
-
-The files, lis3l02dqbuffersimple.c and iio_utils.h in this directory provide an example
-of how to use the ring buffer and event interfaces.
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* [PATCH 111/111] staging:iio: Trivial kconfig reorganization and uniformity improvements.
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (109 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 110/111] staging:iio:documenation partial update Jonathan Cameron
@ 2011-05-18 13:42 ` Jonathan Cameron
  2011-05-18 15:25 ` [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Greg KH
  111 siblings, 0 replies; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 13:42 UTC (permalink / raw)
  To: greg; +Cc: linux-iio, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/Kconfig       |    8 +++---
 drivers/staging/iio/adc/Kconfig   |   48 ++++++++++++++++++------------------
 drivers/staging/iio/light/Kconfig |   26 ++++++++++----------
 3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index e6235d1..f96d5b5 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -5,17 +5,17 @@
 menuconfig IIO
 	tristate "Industrial I/O support"
 	depends on !S390
-	---help---
+	help
 	  The industrial I/O subsystem provides a unified framework for
 	  drivers for many different types of embedded sensors using a
 	  number of different physical interfaces (i2c, spi, etc). See
-	  Documentation/industrialio for more information.
+	  drivers/staging/iio/Documentation for more information.
 if IIO
 
 config IIO_RING_BUFFER
-	bool "Enable ring buffer support within IIO"
+	bool "Enable buffer support within IIO"
 	help
-	  Provide core support for various ring buffer based data
+	  Provide core support for various buffer based data
 	  acquisition methods.
 
 if IIO_RING_BUFFER
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 617af93..8c751c4 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -3,30 +3,6 @@
 #
 comment "Analog to digital convertors"
 
-config MAX1363
-	tristate "MAXIM max1363 ADC driver"
-	depends on I2C
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	select MAX1363_RING_BUFFER
-	help
-	  Say yes here to build support for many MAXIM i2c analog to digital
-	  convertors (ADC). (max1361, max1362, max1363, max1364, max1036,
-	  max1037, max1038, max1039, max1136, max1136, max1137, max1138,
-	  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
-	  max11602, max11603, max11604, max11605, max11606, max11607,
-	  max11608, max11609, max11610, max11611, max11612, max11613,
-	  max11614, max11615, max11616, max11617, max11644, max11645,
-	  max11646, max11647) Provides direct access via sysfs.
-
-config MAX1363_RING_BUFFER
-	bool "MAXIM max1363: use ring buffer"
-	depends on MAX1363
-	select IIO_RING_BUFFER
-	select IIO_SW_RING
-	help
-	  Say yes here to include ring buffer support in the MAX1363
-	  ADC driver.
-
 config AD7150
 	tristate "Analog Devices ad7150/1/6 capacitive sensor driver"
 	depends on I2C
@@ -191,3 +167,27 @@ config ADT7410
 	help
 	  Say yes here to build support for Analog Devices ADT7410
 	  temperature sensors.
+
+config MAX1363
+	tristate "Maxim max1363 ADC driver"
+	depends on I2C
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select MAX1363_RING_BUFFER
+	help
+	  Say yes here to build support for many Maxim i2c analog to digital
+	  convertors (ADC). (max1361, max1362, max1363, max1364, max1036,
+	  max1037, max1038, max1039, max1136, max1136, max1137, max1138,
+	  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
+	  max11602, max11603, max11604, max11605, max11606, max11607,
+	  max11608, max11609, max11610, max11611, max11612, max11613,
+	  max11614, max11615, max11616, max11617, max11644, max11645,
+	  max11646, max11647) Provides direct access via sysfs.
+
+config MAX1363_RING_BUFFER
+	bool "Maxim max1363: use ring buffer"
+	depends on MAX1363
+	select IIO_RING_BUFFER
+	select IIO_SW_RING
+	help
+	  Say yes here to include ring buffer support in the MAX1363
+	  ADC driver.
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
index e9f3794..46d62d1 100644
--- a/drivers/staging/iio/light/Kconfig
+++ b/drivers/staging/iio/light/Kconfig
@@ -1,18 +1,8 @@
-#
+\#
 # Light sensors
 #
 comment "Light sensors"
 
-config SENSORS_TSL2563
-	tristate "TAOS TSL256[0-3] ambient light sensor"
-	depends on I2C
-	help
-	 If you say yes here you get support for the Taos TSL2560,
-	 TSL2561, TSL2562 and TSL2563 ambient light sensors.
-
-	 This driver can also be built as a module.  If so, the module
-	 will be called tsl2563.
-
 config SENSORS_ISL29018
         tristate "ISL 29018 light and proximity sensor"
         depends on I2C
@@ -24,9 +14,19 @@ config SENSORS_ISL29018
          in lux, proximity infrared sensing and normal infrared sensing.
          Data from sensor is accessible via sysfs.
 
+config SENSORS_TSL2563
+	tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
+	depends on I2C
+	help
+	 If you say yes here you get support for the Taos TSL2560,
+	 TSL2561, TSL2562 and TSL2563 ambient light sensors.
+
+	 This driver can also be built as a module.  If so, the module
+	 will be called tsl2563.
+
 config TSL2583
-	tristate "TAOS TSL2580, TSL2581, and TSL2583 light-to-digital converters"
+	tristate "TAOS TSL2580, TSL2581 and TSL2583 light-to-digital converters"
 	depends on I2C
 	help
-	 Provides support for the TAOS tsl2580, tsl2581, and tsl2583 devices.
+	 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices.
 	 Access ALS data via iio, sysfs.
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 117+ messages in thread

* Re: [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
  2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
                   ` (110 preceding siblings ...)
  2011-05-18 13:42 ` [PATCH 111/111] staging:iio: Trivial kconfig reorganization and uniformity improvements Jonathan Cameron
@ 2011-05-18 15:25 ` Greg KH
  2011-05-18 15:35   ` Jonathan Cameron
  111 siblings, 1 reply; 117+ messages in thread
From: Greg KH @ 2011-05-18 15:25 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On Wed, May 18, 2011 at 02:40:50PM +0100, Jonathan Cameron wrote:
> Dear Greg,
> 
> Here is the set I mentioned was coming.
> 
> Thomas Gleixner just pushed the required irq patches to the tip tree
> (though they aren't visible yet).
> 
> [tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
> fe12bc2c996d3e492b2920e32ac79f7bbae3e15d
> 
> and
> 
> [tip:irq/core] irq: Export functions to allow modular irq drivers
> edf76f8307c350bcb81f0c760118a991b3e62956
> 
> There are two other dependencies. One is a trivial missing header
> in arm (patch on it's way through the arm tree). Doesn't break building
> except on arm anyway.
> 
> The other is the strtobool that you added to driver-core
> Add a strtobool function matching semantics of existing in kernel equivalents
> ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e

Hm, this is going to be "interesting" then.  I'll see if I can pull
these patches into my staging-next tree, or if I can just wait for them
to be merged before staging-next and hope that linux-next all works fine
for everyone...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
  2011-05-18 15:25 ` [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Greg KH
@ 2011-05-18 15:35   ` Jonathan Cameron
  2011-05-19 23:17     ` Greg KH
  0 siblings, 1 reply; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-18 15:35 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-iio

On 05/18/11 16:25, Greg KH wrote:
> On Wed, May 18, 2011 at 02:40:50PM +0100, Jonathan Cameron wrote:
>> Dear Greg,
>>
>> Here is the set I mentioned was coming.
>>
>> Thomas Gleixner just pushed the required irq patches to the tip tree
>> (though they aren't visible yet).
>>
>> [tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
>> fe12bc2c996d3e492b2920e32ac79f7bbae3e15d
>>
>> and
>>
>> [tip:irq/core] irq: Export functions to allow modular irq drivers
>> edf76f8307c350bcb81f0c760118a991b3e62956
>>
>> There are two other dependencies. One is a trivial missing header
>> in arm (patch on it's way through the arm tree). Doesn't break building
>> except on arm anyway.
>>
>> The other is the strtobool that you added to driver-core
>> Add a strtobool function matching semantics of existing in kernel equivalents
>> ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e
> 
> Hm, this is going to be "interesting" then.  I'll see if I can pull
> these patches into my staging-next tree, or if I can just wait for them
> to be merged before staging-next and hope that linux-next all works fine
> for everyone...
> 
I 'think' they all apply directly to current mainline and that nothing else
has changed in the relevant areas for a little while, so with a bit
of luck they should be cherry-pickable directly into staging-next

Or as you say, wait for them to merge which I'd imagine will happen fairly
soon anyway.

Thanks,

Jonathan

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
  2011-05-18 15:35   ` Jonathan Cameron
@ 2011-05-19 23:17     ` Greg KH
  2011-05-20 12:50       ` Jonathan Cameron
  0 siblings, 1 reply; 117+ messages in thread
From: Greg KH @ 2011-05-19 23:17 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On Wed, May 18, 2011 at 04:35:54PM +0100, Jonathan Cameron wrote:
> On 05/18/11 16:25, Greg KH wrote:
> > On Wed, May 18, 2011 at 02:40:50PM +0100, Jonathan Cameron wrote:
> >> Dear Greg,
> >>
> >> Here is the set I mentioned was coming.
> >>
> >> Thomas Gleixner just pushed the required irq patches to the tip tree
> >> (though they aren't visible yet).
> >>
> >> [tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
> >> fe12bc2c996d3e492b2920e32ac79f7bbae3e15d
> >>
> >> and
> >>
> >> [tip:irq/core] irq: Export functions to allow modular irq drivers
> >> edf76f8307c350bcb81f0c760118a991b3e62956
> >>
> >> There are two other dependencies. One is a trivial missing header
> >> in arm (patch on it's way through the arm tree). Doesn't break building
> >> except on arm anyway.
> >>
> >> The other is the strtobool that you added to driver-core
> >> Add a strtobool function matching semantics of existing in kernel equivalents
> >> ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e
> > 
> > Hm, this is going to be "interesting" then.  I'll see if I can pull
> > these patches into my staging-next tree, or if I can just wait for them
> > to be merged before staging-next and hope that linux-next all works fine
> > for everyone...
> > 
> I 'think' they all apply directly to current mainline and that nothing else
> has changed in the relevant areas for a little while, so with a bit
> of luck they should be cherry-pickable directly into staging-next
> 
> Or as you say, wait for them to merge which I'd imagine will happen fairly
> soon anyway.

Ok, I've merged them to my tree, and all should be good in the next
linux-next tree.  Can you verify it tomorrow when it comes out?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
  2011-05-19 23:17     ` Greg KH
@ 2011-05-20 12:50       ` Jonathan Cameron
  2011-05-20 13:02         ` Greg KH
  0 siblings, 1 reply; 117+ messages in thread
From: Jonathan Cameron @ 2011-05-20 12:50 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-iio

On 05/20/11 00:17, Greg KH wrote:
> On Wed, May 18, 2011 at 04:35:54PM +0100, Jonathan Cameron wrote:
>> On 05/18/11 16:25, Greg KH wrote:
>>> On Wed, May 18, 2011 at 02:40:50PM +0100, Jonathan Cameron wrote:
>>>> Dear Greg,
>>>>
>>>> Here is the set I mentioned was coming.
>>>>
>>>> Thomas Gleixner just pushed the required irq patches to the tip tree
>>>> (though they aren't visible yet).
>>>>
>>>> [tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
>>>> fe12bc2c996d3e492b2920e32ac79f7bbae3e15d
>>>>
>>>> and
>>>>
>>>> [tip:irq/core] irq: Export functions to allow modular irq drivers
>>>> edf76f8307c350bcb81f0c760118a991b3e62956
>>>>
>>>> There are two other dependencies. One is a trivial missing header
>>>> in arm (patch on it's way through the arm tree). Doesn't break building
>>>> except on arm anyway.
>>>>
>>>> The other is the strtobool that you added to driver-core
>>>> Add a strtobool function matching semantics of existing in kernel equivalents
>>>> ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e
>>>
>>> Hm, this is going to be "interesting" then.  I'll see if I can pull
>>> these patches into my staging-next tree, or if I can just wait for them
>>> to be merged before staging-next and hope that linux-next all works fine
>>> for everyone...
>>>
>> I 'think' they all apply directly to current mainline and that nothing else
>> has changed in the relevant areas for a little while, so with a bit
>> of luck they should be cherry-pickable directly into staging-next
>>
>> Or as you say, wait for them to merge which I'd imagine will happen fairly
>> soon anyway.
> 
> Ok, I've merged them to my tree, and all should be good in the next
> linux-next tree.  Can you verify it tomorrow when it comes out?
> 
> thanks,
> 
> greg k-h
> 
All looks good seems to work.

Thanks,

Jonathan

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers,
  2011-05-20 12:50       ` Jonathan Cameron
@ 2011-05-20 13:02         ` Greg KH
  0 siblings, 0 replies; 117+ messages in thread
From: Greg KH @ 2011-05-20 13:02 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On Fri, May 20, 2011 at 01:50:56PM +0100, Jonathan Cameron wrote:
> On 05/20/11 00:17, Greg KH wrote:
> > On Wed, May 18, 2011 at 04:35:54PM +0100, Jonathan Cameron wrote:
> >> On 05/18/11 16:25, Greg KH wrote:
> >>> On Wed, May 18, 2011 at 02:40:50PM +0100, Jonathan Cameron wrote:
> >>>> Dear Greg,
> >>>>
> >>>> Here is the set I mentioned was coming.
> >>>>
> >>>> Thomas Gleixner just pushed the required irq patches to the tip tree
> >>>> (though they aren't visible yet).
> >>>>
> >>>> [tip:irq/core] genirq: Uninline and sanity check generic_handle_irq()
> >>>> fe12bc2c996d3e492b2920e32ac79f7bbae3e15d
> >>>>
> >>>> and
> >>>>
> >>>> [tip:irq/core] irq: Export functions to allow modular irq drivers
> >>>> edf76f8307c350bcb81f0c760118a991b3e62956
> >>>>
> >>>> There are two other dependencies. One is a trivial missing header
> >>>> in arm (patch on it's way through the arm tree). Doesn't break building
> >>>> except on arm anyway.
> >>>>
> >>>> The other is the strtobool that you added to driver-core
> >>>> Add a strtobool function matching semantics of existing in kernel equivalents
> >>>> ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e
> >>>
> >>> Hm, this is going to be "interesting" then.  I'll see if I can pull
> >>> these patches into my staging-next tree, or if I can just wait for them
> >>> to be merged before staging-next and hope that linux-next all works fine
> >>> for everyone...
> >>>
> >> I 'think' they all apply directly to current mainline and that nothing else
> >> has changed in the relevant areas for a little while, so with a bit
> >> of luck they should be cherry-pickable directly into staging-next
> >>
> >> Or as you say, wait for them to merge which I'd imagine will happen fairly
> >> soon anyway.
> > 
> > Ok, I've merged them to my tree, and all should be good in the next
> > linux-next tree.  Can you verify it tomorrow when it comes out?
> > 
> > thanks,
> > 
> > greg k-h
> > 
> All looks good seems to work.

Thanks for testing.  The above mentioned patches are now in Linus's tree
so I'll do this merge with him soon.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 117+ messages in thread

end of thread, other threads:[~2011-05-20 13:02 UTC | newest]

Thread overview: 117+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-18 13:40 [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Jonathan Cameron
2011-05-18 13:40 ` [PATCH 001/111] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
2011-05-18 13:40 ` [PATCH 002/111] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
2011-05-18 13:40 ` [PATCH 003/111] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
2011-05-18 13:40 ` [PATCH 004/111] staging:iio: remove ability to escalate events Jonathan Cameron
2011-05-18 13:40 ` [PATCH 005/111] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
2011-05-18 13:40 ` [PATCH 006/111] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
2011-05-18 13:40 ` [PATCH 007/111] staging:iio: Buffer device flattening Jonathan Cameron
2011-05-18 13:40 ` [PATCH 008/111] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
2011-05-18 13:40 ` [PATCH 009/111] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
2011-05-18 13:41 ` [PATCH 010/111] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
2011-05-18 13:41 ` [PATCH 011/111] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
2011-05-18 13:41 ` [PATCH 012/111] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
2011-05-18 13:41 ` [PATCH 013/111] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
2011-05-18 13:41 ` [PATCH 014/111] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 015/111] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
2011-05-18 13:41 ` [PATCH 016/111] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 017/111] staging:iio:adc:ad7816 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 018/111] staging:iio:adc:ad7150 move from deprecated event handling plus remove irq as gpio requirement Jonathan Cameron
2011-05-18 13:41 ` [PATCH 019/111] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
2011-05-18 13:41 ` [PATCH 020/111] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
2011-05-18 13:41 ` [PATCH 021/111] staging:iio:ad7291 move from old event system to current Jonathan Cameron
2011-05-18 13:41 ` [PATCH 022/111] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 023/111] staging:iio:adt7310 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 024/111] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
2011-05-18 13:41 ` [PATCH 025/111] staging:iio:adc:ad799x move to new event handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 026/111] staging:iio: Remove legacy " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 027/111] staging:iio:accel:lis3l02dq make threshold interrupt threaded Jonathan Cameron
2011-05-18 13:41 ` [PATCH 028/111] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
2011-05-18 13:41 ` [PATCH 029/111] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
2011-05-18 13:41 ` [PATCH 030/111] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
2011-05-18 13:41 ` [PATCH 031/111] staging:iio: add generic data ready poll function Jonathan Cameron
2011-05-18 13:41 ` [PATCH 032/111] staging:iio:accel:lis3l02dq move to threaded trigger handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 033/111] staging:iio:adc:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
2011-05-18 13:41 ` [PATCH 034/111] staging:iio:adc:ad7476 use channel_spec Jonathan Cameron
2011-05-18 13:41 ` [PATCH 035/111] staging:iio:adc:ad7476 move to irqchip based triggering Jonathan Cameron
2011-05-18 13:41 ` [PATCH 036/111] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 037/111] staging:iio:imu:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
2011-05-18 13:41 ` [PATCH 038/111] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
2011-05-18 13:41 ` [PATCH 039/111] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 040/111] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
2011-05-18 13:41 ` [PATCH 041/111] staging:iio:imu remove adis16300 driver Jonathan Cameron
2011-05-18 13:41 ` [PATCH 042/111] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 043/111] staging:iio:accel:adis16203 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 044/111] staging:iio:accel:adis16204 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 045/111] staging:iio:accel:adis16209 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 046/111] staging:iio:accel:adis16240 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 047/111] staging:iio:adc:ad7298 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 048/111] staging:iio:adc:ad7606 conversion to irq_chip based polling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 049/111] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
2011-05-18 13:41 ` [PATCH 050/111] staging:iio:adc:ad799x " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 051/111] staging:iio:gyro:adis16260 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 052/111] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
2011-05-18 13:41 ` [PATCH 053/111] staging:iio: Add core attribute handling for name of device Jonathan Cameron
2011-05-18 13:41 ` [PATCH 054/111] staging:iio: use the new central name attribute creation code Jonathan Cameron
2011-05-18 13:41 ` [PATCH 055/111] staging:iio:light:tsl2563: chan_spec based channel setup Jonathan Cameron
2011-05-18 13:41 ` [PATCH 056/111] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
2011-05-18 13:41 ` [PATCH 057/111] staging:iio:accel:adis16203 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 058/111] staging:iio:accel:adis16204 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 059/111] staging:iio:accel:adis16209 " Jonathan Cameron
2011-05-18 13:41 ` [PATCH 060/111] staging:iio:adc:ad7887: Convert to new channel registration method Jonathan Cameron
2011-05-18 13:41 ` [PATCH 061/111] staging:iio:adc:ad7887: Use private data space from iio_allocate_device Jonathan Cameron
2011-05-18 13:41 ` [PATCH 062/111] staging:iio:adc:ad799x: Convert to new channel registration method Jonathan Cameron
2011-05-18 13:41 ` [PATCH 063/111] staging:iio:adc:ad799x: Use private data space from iio_allocate_device Jonathan Cameron
2011-05-18 13:41 ` [PATCH 064/111] staging:iio:adc:ad799x removed unused headers Jonathan Cameron
2011-05-18 13:41 ` [PATCH 065/111] staging:iio:adc:ad7298: Convert to new channel registration method Jonathan Cameron
2011-05-18 13:41 ` [PATCH 066/111] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
2011-05-18 13:41 ` [PATCH 067/111] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
2011-05-18 13:41 ` [PATCH 068/111] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
2011-05-18 13:41 ` [PATCH 069/111] staging:iio:gyro:adis16260 " Jonathan Cameron
2011-05-18 13:42 ` [PATCH 070/111] staging:iio:adc:ad7606 Convert to new channel registration method Update Add missing call to iio_trigger_notify_done() Set pollfunc top and bottom half handler Jonathan Cameron
2011-05-18 13:42 ` [PATCH 071/111] staging:iio:adc:ad7606: Use private data space from iio_allocate_device Jonathan Cameron
2011-05-18 13:42 ` [PATCH 072/111] staging:iio: Add channel types IIO_CURRENT and IIO_POWER Jonathan Cameron
2011-05-18 13:42 ` [PATCH 073/111] staging:iio:meter:ade7758: Update trigger to the new API Jonathan Cameron
2011-05-18 13:42 ` [PATCH 074/111] staging:iio:meter:ade7758: Fix timing on SPI read accessor functions Jonathan Cameron
2011-05-18 13:42 ` [PATCH 075/111] iio:staging:meter:ade7758: Fix return value of ade7758_write_reset Jonathan Cameron
2011-05-18 13:42 ` [PATCH 076/111] staging:iio:meter:ade7758: Fix list and set of available sample frequencies Jonathan Cameron
2011-05-18 13:42 ` [PATCH 077/111] staging:iio:meter:ade7758: Use iio channel spec and miscellaneous other changes Jonathan Cameron
2011-05-18 13:42 ` [PATCH 078/111] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
2011-05-18 13:42 ` [PATCH 079/111] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
2011-05-18 13:42 ` [PATCH 080/111] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
2011-05-18 13:42 ` [PATCH 081/111] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
2011-05-18 13:42 ` [PATCH 082/111] staging:iio:core clean out unused elements Jonathan Cameron
2011-05-18 13:42 ` [PATCH 083/111] staging:iio:adc:ad7150 fix event codes Jonathan Cameron
2011-05-18 13:42 ` [PATCH 084/111] staging:iio:adc:ad7816 and adt75 change to meaningful event code Jonathan Cameron
2011-05-18 13:42 ` [PATCH 085/111] staging:iio:adc:ad7291 remove abuse of buffer events and replace with something almost sane Jonathan Cameron
2011-05-18 13:42 ` [PATCH 086/111] staging:iio:adc:adt7310 replace abuse of buffer events Jonathan Cameron
2011-05-18 13:42 ` [PATCH 087/111] staging:iio:adc:adt7410 " Jonathan Cameron
2011-05-18 13:42 ` [PATCH 088/111] staging:iio:addac:adt7316 " Jonathan Cameron
2011-05-18 13:42 ` [PATCH 089/111] staging:iio:buffer - remove unused event code for " Jonathan Cameron
2011-05-18 13:42 ` [PATCH 090/111] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron
2011-05-18 13:42 ` [PATCH 091/111] staging:iio: iio_event_interfaces - clean out unused elements Jonathan Cameron
2011-05-18 13:42 ` [PATCH 092/111] staging:iio:trigger handle name attr in core, remove old alloc and register any control_attrs via struct device Jonathan Cameron
2011-05-18 13:42 ` [PATCH 093/111] drivers:staging:iio:imu:adis16400 avoid allocating rx, tx, and state separately from iio_dev Jonathan Cameron
2011-05-18 13:42 ` [PATCH 094/111] staging:iio: rationalization of different buffer implementation hooks Jonathan Cameron
2011-05-18 13:42 ` [PATCH 095/111] staging:iio:adc:AD7298: Use private data space from iio_allocate_device Jonathan Cameron
2011-05-18 13:42 ` [PATCH 096/111] staging:iio: Rip out helper for software rings Jonathan Cameron
2011-05-18 13:42 ` [PATCH 097/111] staging:iio:adc: AD7606: Consitently use indio_dev Jonathan Cameron
2011-05-18 13:42 ` [PATCH 098/111] staging:iio:adc: AD7606: Drop dev_data in favour of iio_priv() Jonathan Cameron
2011-05-18 13:42 ` [PATCH 099/111] staging:iio:adc:AD7780: Convert to new channel registration method Jonathan Cameron
2011-05-18 13:42 ` [PATCH 100/111] staging:iio:adc: AD7780: Use private data space from iio_allocate_device + trivial fixes Jonathan Cameron
2011-05-18 13:42 ` [PATCH 101/111] staging:iio:ad7780 trivial unused header cleanup Jonathan Cameron
2011-05-18 13:42 ` [PATCH 102/111] staging:iio: poll func allocation clean up Jonathan Cameron
2011-05-18 13:42 ` [PATCH 103/111] staging:iio:core cleanup: squash tiny wrappers and use dev_set_name to handle creation of event interface name Jonathan Cameron
2011-05-18 13:42 ` [PATCH 104/111] staging:iio: ring core cleanups + check if read_last available in lis3l02dq Jonathan Cameron
2011-05-18 13:42 ` [PATCH 105/111] staging:iio:accel:lis3l02dq make write_reg_8 take value not a pointer to value Jonathan Cameron
2011-05-18 13:42 ` [PATCH 106/111] staging:iio:meter:ade7758: Use private data space from iio_allocate_device Jonathan Cameron
2011-05-18 13:42 ` [PATCH 107/111] staging:iio: implement an iio_info structure to take some of the constant elements out of iio_dev Jonathan Cameron
2011-05-18 13:42 ` [PATCH 108/111] staging:iio:max1363 misc cleanups and use of for_each_bit_set to simplify event code spitting out Jonathan Cameron
2011-05-18 13:42 ` [PATCH 109/111] staging:iio: use pollfunc allocation helpers in remaining drivers Jonathan Cameron
2011-05-18 13:42 ` [PATCH 110/111] staging:iio:documenation partial update Jonathan Cameron
2011-05-18 13:42 ` [PATCH 111/111] staging:iio: Trivial kconfig reorganization and uniformity improvements Jonathan Cameron
2011-05-18 15:25 ` [PATCH 000/111] IIO: chan_spec intro, generic irq based triggers, Greg KH
2011-05-18 15:35   ` Jonathan Cameron
2011-05-19 23:17     ` Greg KH
2011-05-20 12:50       ` Jonathan Cameron
2011-05-20 13:02         ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.