All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/70] IIO: Major rework set (review request).
@ 2011-04-17 19:05 Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 01/70] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
                   ` (69 more replies)
  0 siblings, 70 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Dear all,

A few of these have been posted before. A lot are conversion patches
and hence fairly mechanical but that's not saying I didn't do anything
silly.

So this is really just a request for anyone with any time at all to
take one of these patches and do a sanity check on it.  Of course, if
people have the parts, testing would be the best form of sanity check.
Obviously, starting at the beginning would be best, but then quite
a few of these patches introduce bits of intermediate code that gets
wiped out late, so commenting on issues with the results of these
patches is fine too!

My test set (which, 'touch wood' work) are:

sca3000-e05, max1363, max1238, lis3l02dq and adis16350.

Towards the end of the set a few drivers will not build for one
of two reasons:

a) They abuse the old buffer event codes.  These uses need to
go ASAP, but will take some datasheet trawling as we really want
to know what the heck those events actually are.

b) They are an adc driver which hasn't been converted to chan_spec
registration yet and still has some IIO_SCAN_EL_C macro usage.

Everything should build up to

staging:iio: rip out scan_el attributes.  Now handled as
    iio_dev_attrs like everything else.

Note this set sits on top of

* if you are on arm, a missing header fix deep in the cpu_type code
  which is needed to build one of the gyro types - its in Russells
  fix branch so should go to Linus in a day or two if it hasn't already.

* [PATCH] irq: export handle_simple_irq, irq_modify_status and irq_to_desc

* [PATCH 0/8 V2] staging:iio:mixed bag of fixes and cleanups.
which it turns sits on various new driver patches.

* [PATCH 00/12] IIO: precursor cleanups to even system rewrite

All in all, if you actually want to run this, then take a look at
the iio-onwards tree.

http://git.kernel.org/?p=linux/kernel/git/jic23/iio-onwards.git;a=summary

Please take a look if you possibly can.  Note I will be rebasing the above
tree in response to reviews.


Anyhow, lets briefly summarize what we have here for the record

All the way through I carry max1363 and lis3l02dq along, using new
functionality as it becomes available.  This leads to some
'fun and games' with interrupts in lis3l02dq that perhaps I could
have avoided, but there we are.

Patch 1 introduces the use of iio_chan_spec structures to specify
a channel.  Note this adds a set of callbacks to iio_dev. Arnd
pointed out that we can pull these out into constant iio_ops
structures.  I haven't done this yet, but it should be easy
to retrofit on at the end.

Patches 5-9 remove the event interface for buffers and replace
with use of poll.

11 fixes sca3000 to use the new approach and generally actually
work. It's been broken for some time.

13-25 Interrupt registration for event lines is then pushed into the
drivers (and various other fixes accomplished). Between 9 and these
patches some event lines may not work.

26 removes the old event methods.  Boy were they over engineered.
oops.

28 adds irq_chip route for triggers as suggested by Thomas Gleixner.
52 removes the old method.  Everything in between is driver conversions
- note that in the imu cases I merged all the drivers (as per a somewhat
old previous proposal - I'll add the event support that was in the
original patches at a later date).

53 is a cheeky cleanup that makes a lot of sense now we have very
few directly registered attributes in chan_spec using drivers.  Basically
it moves handling the device name into the core.
54 makes extensive use of this.

55-63 are mechanical switching over to chan_spec so I can get rid of
the whole SCAN_EL_C stuff.  Given all these drivers never use the
calbacks for setting the scan up, this was straight forward - if
lengthy.  Fixed a few bugs and generally cleaned up the drivers whilst
I was there (may well have introduced some new ones)

64 removes SCAN_EL_C and iio_scan_attr and all the support code.
Its' at this stage that the chan_spec code introduced in  patch (1)
actually reaches it's full potential, so if considering whether that
was worth while, take a look at the tree at this point.  What we have
is a lot simpler and more consise than the previous approach.
There are cases that are not yet handled, but it makes life easier
for the vast majority of drivers we have.  Thanks to Arnd for the
suggestion.

65,66 and 68 and trivial bits that should probably have been separated
out from this set. Hence I've pushed them down to the end.

70 puts lis3l02dq's interrupt handlers back together playing a slightly
unusual game with the top half handler.

67 is the sysfs-trigger rework.  Note the other non device triggers
need converting over - they build right now, but that's it.

69 removes the buffer event codes.  The only remaining uses are hideous
abuses that need to be hunted down and removed.

Sorry for the mass set.  There was a lot to do and separating it out
into coherent themes would be a real pain (yes I'm being lazy - if
we weren't still in staging I probably wouldn't try and get away
with it).

I'm convinced it was worth the pain.  What do others think?

The one big thing left to consider (to my mind anyway) is a better
way of pushing events up to userspace, but that's a topic for another day.


Thanks all.

Jonathan

Jonathan Cameron (70):
  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.
  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:ad799x move to new event handling
  staging:iio: Remove legacy event handling.
  staging:iio: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:lis3l02dq move to threaded trigger handling.
  staging:iio:max1363 move to irqchip based threaded irq triggering
  staging:iio:ad7476 use channel_spec
  staging:iio:ad7476 move to irqchip based triggering
  staging:iio:meter:ade7758 move to irqchip based trigger handling.
  staging:iio: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: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: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: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: Add angl parameters to the chan spec code.
  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:buffer - remove unused event code for buffer events.
  staging:iio:lis3l02dq remerge the two interrupt handlers.

 drivers/staging/Makefile                           |    2 +-
 drivers/staging/iio/Documentation/generic_buffer.c |   93 +-
 drivers/staging/iio/Documentation/iio_utils.h      |   20 +-
 drivers/staging/iio/Kconfig                        |   12 +
 drivers/staging/iio/Makefile                       |    2 +
 drivers/staging/iio/accel/adis16201.h              |    9 +-
 drivers/staging/iio/accel/adis16201_core.c         |  458 +++----
 drivers/staging/iio/accel/adis16201_ring.c         |  138 +--
 drivers/staging/iio/accel/adis16201_trigger.c      |   52 +-
 drivers/staging/iio/accel/adis16203.h              |   18 +-
 drivers/staging/iio/accel/adis16203_core.c         |  379 +++---
 drivers/staging/iio/accel/adis16203_ring.c         |  116 +--
 drivers/staging/iio/accel/adis16203_trigger.c      |   53 +-
 drivers/staging/iio/accel/adis16204.h              |   18 +-
 drivers/staging/iio/accel/adis16204_core.c         |  404 +++---
 drivers/staging/iio/accel/adis16204_ring.c         |  117 +--
 drivers/staging/iio/accel/adis16204_trigger.c      |   55 +-
 drivers/staging/iio/accel/adis16209.h              |    6 +-
 drivers/staging/iio/accel/adis16209_core.c         |  438 ++++---
 drivers/staging/iio/accel/adis16209_ring.c         |  135 +--
 drivers/staging/iio/accel/adis16209_trigger.c      |   42 +-
 drivers/staging/iio/accel/adis16220_core.c         |    4 +-
 drivers/staging/iio/accel/adis16240.h              |    7 +-
 drivers/staging/iio/accel/adis16240_core.c         |  362 +++---
 drivers/staging/iio/accel/adis16240_ring.c         |  125 +--
 drivers/staging/iio/accel/adis16240_trigger.c      |   41 +-
 drivers/staging/iio/accel/lis3l02dq.h              |   30 +-
 drivers/staging/iio/accel/lis3l02dq_core.c         |  715 +++++------
 drivers/staging/iio/accel/lis3l02dq_ring.c         |  443 +++----
 drivers/staging/iio/accel/sca3000.h                |   76 +-
 drivers/staging/iio/accel/sca3000_core.c           |  933 +++++---------
 drivers/staging/iio/accel/sca3000_ring.c           |  250 +++--
 drivers/staging/iio/adc/Kconfig                    |    4 +-
 drivers/staging/iio/adc/ad7150.c                   |  129 +--
 drivers/staging/iio/adc/ad7152.c                   |   20 +-
 drivers/staging/iio/adc/ad7291.c                   |  437 ++-----
 drivers/staging/iio/adc/ad7298.h                   |    2 -
 drivers/staging/iio/adc/ad7298_core.c              |   14 +-
 drivers/staging/iio/adc/ad7298_ring.c              |   65 +-
 drivers/staging/iio/adc/ad7314.c                   |   21 +-
 drivers/staging/iio/adc/ad7476.h                   |    7 +-
 drivers/staging/iio/adc/ad7476_core.c              |  162 +--
 drivers/staging/iio/adc/ad7476_ring.c              |  102 +-
 drivers/staging/iio/adc/ad7606_ring.c              |   27 +-
 drivers/staging/iio/adc/ad7745.c                   |  104 +--
 drivers/staging/iio/adc/ad7780.c                   |   13 +-
 drivers/staging/iio/adc/ad7816.c                   |   92 +-
 drivers/staging/iio/adc/ad7887.h                   |    2 -
 drivers/staging/iio/adc/ad7887_core.c              |   14 +-
 drivers/staging/iio/adc/ad7887_ring.c              |   63 +-
 drivers/staging/iio/adc/ad799x.h                   |    4 -
 drivers/staging/iio/adc/ad799x_core.c              |  268 ++---
 drivers/staging/iio/adc/ad799x_ring.c              |   60 +-
 drivers/staging/iio/adc/adt7310.c                  |  172 +--
 drivers/staging/iio/adc/adt7410.c                  |  167 +--
 drivers/staging/iio/adc/adt75.c                    |  159 +--
 drivers/staging/iio/adc/max1363.h                  |   17 +-
 drivers/staging/iio/adc/max1363_core.c             | 1371 ++++++++------------
 drivers/staging/iio/adc/max1363_ring.c             |   65 +-
 drivers/staging/iio/addac/adt7316.c                |  385 ++----
 drivers/staging/iio/chrdev.h                       |   33 +-
 drivers/staging/iio/dac/ad5446.c                   |   13 +-
 drivers/staging/iio/dac/ad5504.c                   |   68 +-
 drivers/staging/iio/dac/ad5504.h                   |    4 -
 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.h               |    7 +-
 drivers/staging/iio/gyro/adis16260_core.c          |  450 ++++----
 drivers/staging/iio/gyro/adis16260_ring.c          |  117 +--
 drivers/staging/iio/gyro/adis16260_trigger.c       |   55 +-
 drivers/staging/iio/iio-board-info.h               |   24 +
 drivers/staging/iio/iio-core.h                     |   13 +
 drivers/staging/iio/iio.h                          |  276 +++--
 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                |   31 +-
 drivers/staging/iio/imu/adis16400_core.c           |  631 ++++++---
 drivers/staging/iio/imu/adis16400_ring.c           |  223 ++--
 drivers/staging/iio/imu/adis16400_trigger.c        |   55 +-
 drivers/staging/iio/industrialio-board-info.c      |   25 +
 drivers/staging/iio/industrialio-core.c            |  793 ++++++++----
 drivers/staging/iio/industrialio-ring.c            |  319 +++--
 drivers/staging/iio/industrialio-trigger.c         |  218 +++-
 drivers/staging/iio/kfifo_buf.c                    |    3 +-
 drivers/staging/iio/kfifo_buf.h                    |    3 +-
 drivers/staging/iio/light/isl29018.c               |   13 +-
 drivers/staging/iio/light/tsl2563.c                |   62 +-
 drivers/staging/iio/meter/ade7753.c                |    4 +-
 drivers/staging/iio/meter/ade7754.c                |    4 +-
 drivers/staging/iio/meter/ade7758.h                |    5 -
 drivers/staging/iio/meter/ade7758_core.c           |    4 +-
 drivers/staging/iio/meter/ade7758_ring.c           |   58 +-
 drivers/staging/iio/meter/ade7759.c                |    4 +-
 drivers/staging/iio/ring_generic.h                 |  166 +--
 drivers/staging/iio/ring_sw.c                      |   57 +-
 drivers/staging/iio/ring_sw.h                      |    5 +-
 drivers/staging/iio/sysfs.h                        |  161 +--
 drivers/staging/iio/trigger.h                      |   77 +-
 drivers/staging/iio/trigger/iio-trig-sysfs.c       |  170 ++-
 110 files changed, 6094 insertions(+), 10174 deletions(-)
 create mode 100644 drivers/staging/iio/iio-board-info.h
 create mode 100644 drivers/staging/iio/iio-core.h
 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
 create mode 100644 drivers/staging/iio/industrialio-board-info.c

-- 
1.7.3.4

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

* [PATCH 01/70] staging:iio: allow channels to be set up using a table of iio_channel_spec structures.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 02/70] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
                   ` (68 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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               |  171 ++++++++-
 drivers/staging/iio/industrialio-core.c |  645 +++++++++++++++++++++++++++++--
 drivers/staging/iio/industrialio-ring.c |  188 +++++++++-
 drivers/staging/iio/ring_generic.h      |   20 +
 drivers/staging/iio/sysfs.h             |   34 ++-
 6 files changed, 1019 insertions(+), 42 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..d6c6cab 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -26,6 +26,142 @@
 
 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_PROXIMITY,
+	IIO_TEMP,
+	IIO_INCLI,
+	IIO_ROT,
+	IIO_TIMESTAMP,
+};
+
+/* 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.
+ * @address:	driver specific identifier.
+ * @scan_index:	monotonic index to give ordering in scans when read
+ *		from a buffer.
+ * @scan_type:	sign is 's' or 'u' to specify signed or unsigned
+ *		realbits is the number of valid bits of data
+ *		storage bits is realbits + padding
+ *		shift tells you how much to shift right 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.
+ * @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;
+	/* 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, _chan, _inf_mask, _address, _si, _stype)	\
+	{ .type = _type, .channel = _chan, .info_mask = _inf_mask,	\
+			.address = _address,				\
+			.scan_index = _si, .scan_type = _stype }
+
+#define IIO_CHAN_EV(_type, _chan, _inf_mask, _address, _si,		\
+		    _stype, _event_mask, _shared_h)			\
+	{ .type = _type,						\
+			.channel = _chan,				\
+			.info_mask = _inf_mask,				\
+			.address = _address,				\
+			.scan_index = _si, .scan_type = _stype,		\
+			.event_mask = _event_mask,			\
+			.shared_handler = _shared_h }
+
+#define IIO_CHAN_COMPOUND(_type, _chan1, _chan2, _inf_mask,		\
+			  _address, _si, _stype)			\
+	{ .type = _type, .channel = _chan1, .channel2 = _chan2,		\
+			.info_mask = _inf_mask,				\
+			.address = _address,				\
+			.scan_index = _si, .scan_type = _stype }
+
+#define IIO_CHAN_COMPOUND_EV(_type, _chan1, _chan2, _inf_mask,		\
+			     _address, _si, _stype, _event_mask, _shared_h) \
+	{ .type = _type,						\
+			.channel = _chan1, .channel2 = _chan2,		\
+			.info_mask = _inf_mask,				\
+			.address = _address,				\
+			.scan_index = _si, .scan_type = _stype,		\
+			.event_mask = _event_mask,			\
+			.shared_handler = _shared_h}
+
+#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 +206,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
@@ -116,6 +253,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..4d9a8bc 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -44,6 +44,38 @@ 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",
+};
+
+static const char * const iio_chan_type_name_spec[] = {
+	[IIO_TIMESTAMP] = "timestamp",
+	[IIO_ACCEL] = "accel_%c",
+	[IIO_IN] = "in%d",
+	[IIO_IN_DIFF] = "in%d-in%d",
+	[IIO_GYRO] = "gyro_%c",
+	[IIO_TEMP] = "temp%d",
+	[IIO_MAGN] = "magn_%c",
+	[IIO_INCLI] = "incli_%c",
+	[IIO_ROT] = "rot_%c",
+};
+
+/* 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 +520,304 @@ 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;
+}
+
+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;
+	sysfs_attr_init(&dev_attr->attr);
+	if (generic)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    postfix);
+	else
+		name_format = kasprintf(GFP_KERNEL, "%s_%s",
+					iio_chan_type_name_spec[chan->type],
+					postfix);
+	if (name_format == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	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);
+
+	return 0;
+
+error_free_name_format:
+	kfree(name_format);
+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;
+
+	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 +864,261 @@ 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;
+	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);
+
+	name_format = kasprintf(GFP_KERNEL, "%s_%s",
+				iio_chan_type_name_spec[chan->type],
+				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 +1126,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 +1172,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 +1237,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 +1265,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 +1286,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..f80d789 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,14 +263,16 @@ 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
+/* 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			0
 #define IIO_EV_MOD_Y			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] 77+ messages in thread

* [PATCH 02/70] staging:iio:lis3l02dq - move to new channel_spec approach.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 01/70] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 03/70] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
                   ` (67 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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 |  546 +++++++++++-----------------
 drivers/staging/iio/accel/lis3l02dq_ring.c |  227 +++++-------
 3 files changed, 309 insertions(+), 477 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 958c8ec..a487923 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,159 +430,130 @@ 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_EV(IIO_ACCEL, 'x', LIS3L02DQ_INFO_MASK,
+		    0, 0, IIO_ST('s', 12, 16, 0),
+		    LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+	IIO_CHAN_EV(IIO_ACCEL, 'y', LIS3L02DQ_INFO_MASK,
+		    1, 1, IIO_ST('s', 12, 16, 0),
+		    LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+	IIO_CHAN(IIO_ACCEL, 'z', LIS3L02DQ_INFO_MASK,
+		 2, 2, IIO_ST('s', 12, 16, 0)),
+	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);
-		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);
+						&val);
 		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.
  */
@@ -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] 77+ messages in thread

* [PATCH 03/70] staging:iio:max1363 - move to channel_spec registration.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 01/70] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 02/70] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 04/70] staging:iio: remove ability to escalate events Jonathan Cameron
                   ` (66 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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 | 1285 ++++++++++++--------------------
 drivers/staging/iio/adc/max1363_ring.c |    1 -
 3 files changed, 485 insertions(+), 809 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..b5b175c 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,119 @@ 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_EV(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0,
+		    IIO_ST('u', 12, 16, 0),
+		    MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_EV(IIO_IN, 1, MAX1363_INFO_MASK,
+		    _s1, 1, IIO_ST('u', 12, 16, 0),
+		    MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_EV(IIO_IN, 2, MAX1363_INFO_MASK,
+		    _s2, 2, IIO_ST('u', 12, 16, 0),
+		    MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_EV(IIO_IN, 3, MAX1363_INFO_MASK,
+		    _s3, 3, IIO_ST('u', 12, 16, 0),
+		    MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			     d0m1, 4, IIO_ST('s', 12, 16, 0),
+			     MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			     d2m3, 5, IIO_ST('s', 12, 16, 0),
+			     MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			     d1m0, 6, IIO_ST('s', 12, 16, 0),
+			     MAX1363_EV_M, &iio_event_max1363_thresh),
+	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 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 max1236_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s1, 1, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s2, 2, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s3, 3, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 4, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 5, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 6, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 7, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
+static struct iio_chan_spec max1361_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s1, 1, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s2, 2, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s3, 3, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 4, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 5, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 6, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 7, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
+static struct iio_chan_spec max1136_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s1, 1, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s2, 2, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s3, 3, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 4, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 5, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 6, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 7, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
+static struct iio_chan_spec max1036_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s1, 1, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s2, 2, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s3, 3, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 4, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 5, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 6, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 7, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
+};
+
 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 +383,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,101 +405,130 @@ 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 iio_chan_spec max1038_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 8, MAX1363_INFO_MASK, _s0, 8, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 9, MAX1363_INFO_MASK, _s0, 9, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 10, MAX1363_INFO_MASK, _s0, 10, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 11, MAX1363_INFO_MASK, _s0, 11, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 12, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 13, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 14, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 15, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 8, 9, MAX1363_INFO_MASK,
+			  d8m9, 16, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 10, 11, MAX1363_INFO_MASK,
+			  d10m11, 17, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 18, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 19, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 20, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 21, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 9, 8, MAX1363_INFO_MASK,
+			  d9m8, 22, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 11, 10, MAX1363_INFO_MASK,
+			  d11m10, 23, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(24)
 };
 
-static struct attribute_group max1238_dev_attr_group = {
-	.attrs = max1238_device_attrs,
+static struct iio_chan_spec max1138_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 8, MAX1363_INFO_MASK, _s0, 8, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 9, MAX1363_INFO_MASK, _s0, 9, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 10, MAX1363_INFO_MASK, _s0, 10,
+		 IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 11, MAX1363_INFO_MASK, _s0, 11,
+		 IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 12, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 13, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 14, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 15, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 8, 9, MAX1363_INFO_MASK,
+			  d8m9, 16, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 10, 11, MAX1363_INFO_MASK,
+			  d10m11, 17, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 18, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 19, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 20, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 21, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 9, 8, MAX1363_INFO_MASK,
+			  d9m8, 22, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 11, 10, MAX1363_INFO_MASK,
+			  d11m10, 23, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(24)
 };
 
-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 iio_chan_spec max1238_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 8, MAX1363_INFO_MASK, _s0, 8, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 9, MAX1363_INFO_MASK, _s0, 9, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 10, MAX1363_INFO_MASK, _s0,
+		 10, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 11, MAX1363_INFO_MASK, _s0,
+		 11, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 12, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 13, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 14, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 15, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 8, 9, MAX1363_INFO_MASK,
+			  d8m9, 16, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 10, 11, MAX1363_INFO_MASK,
+			  d10m11, 17, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 18, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 19, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 20, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 21, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 9, 8, MAX1363_INFO_MASK,
+			  d9m8, 22, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 11, 10, MAX1363_INFO_MASK,
+			  d11m10, 23, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(24)
 };
 
-static struct attribute_group max1238_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max1238_scan_el_attrs,
-};
-
-
 static const enum max1363_modes max11607_mode_list[] = {
 	_s0, _s1, _s2, _s3,
 	s0to1, s0to2, s0to3,
@@ -547,74 +547,88 @@ 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 iio_chan_spec max11602_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 8, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 9, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 10, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 11, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 12, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 13, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 14, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 15, IIO_ST('s', 8, 8, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(16)
 };
 
-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 iio_chan_spec max11608_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 8, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 9, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 10, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 11, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 12, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 13, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 14, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 15, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(16)
 };
 
-static struct attribute_group max11608_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max11608_scan_el_attrs,
+static struct iio_chan_spec max11614_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 2, MAX1363_INFO_MASK, _s0, 2, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 3, MAX1363_INFO_MASK, _s0, 3, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 4, MAX1363_INFO_MASK, _s0, 4, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 5, MAX1363_INFO_MASK, _s0, 5, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 6, MAX1363_INFO_MASK, _s0, 6, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 7, MAX1363_INFO_MASK, _s0, 7, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 8, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
+			  d2m3, 9, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 4, 5, MAX1363_INFO_MASK,
+			  d4m5, 10, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 6, 7, MAX1363_INFO_MASK,
+			  d6m7, 11, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 12, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
+			  d3m2, 13, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 5, 4, MAX1363_INFO_MASK,
+			  d5m4, 14, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 7, 6, MAX1363_INFO_MASK,
+			  d7m6, 15, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(16)
 };
 
 enum { max1361,
@@ -656,348 +670,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 +1028,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 +1057,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 +1079,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 +1116,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 +1247,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 +1268,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 +1390,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 +1419,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 +1431,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] 77+ messages in thread

* [PATCH 04/70] staging:iio: remove ability to escalate events.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (2 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 03/70] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 05/70] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
                   ` (65 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 d6c6cab..cfbd6a5 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -357,22 +357,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 4d9a8bc..334bb35 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -76,15 +76,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
@@ -93,9 +84,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;
@@ -115,9 +104,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++;
@@ -137,7 +123,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);
 
@@ -305,18 +291,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] 77+ messages in thread

* [PATCH 05/70] staging:iio: Add polling of events on the ring access chrdev.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (3 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 04/70] staging:iio: remove ability to escalate events Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 06/70] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
                   ` (64 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 06/70] staging:iio: remove legacy event chrdev for the buffers
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (4 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 05/70] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 07/70] staging:iio: Buffer device flattening Jonathan Cameron
                   ` (63 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 cfbd6a5..57c978f 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -363,20 +363,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 334bb35..a057744 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -387,7 +387,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)
@@ -439,7 +439,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] 77+ messages in thread

* [PATCH 07/70] staging:iio: Buffer device flattening.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (5 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 06/70] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 08/70] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
                   ` (62 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 08/70] staging:iio:lis3l02dq: General cleanup
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (6 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 07/70] staging:iio: Buffer device flattening Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 09/70] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
                   ` (61 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 a487923..3e057b0 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)
@@ -487,7 +467,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)
@@ -511,12 +491,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)
@@ -536,7 +516,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)
@@ -544,7 +524,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)
 
 	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] 77+ messages in thread

* [PATCH 09/70] staging:iio: Push interrupt setup down into the drivers for event lines.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (7 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 08/70] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 10/70] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
                   ` (60 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 57c978f..662cb8e 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"
 
@@ -339,6 +340,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 a057744..d73f8d8 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -128,7 +128,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;
@@ -151,6 +151,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)
 {
@@ -169,7 +170,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) {
@@ -180,16 +181,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;
 }
@@ -209,8 +200,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] 77+ messages in thread

* [PATCH 10/70] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (8 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 09/70] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 11/70] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
                   ` (59 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

This removes the one and only real user of the rather complex event list management.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq.h      |    2 +
 drivers/staging/iio/accel/lis3l02dq_core.c |  102 +++++++++++++++++++++------
 drivers/staging/iio/accel/lis3l02dq_ring.c |   55 ++++++++-------
 3 files changed, 110 insertions(+), 49 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 3e057b0..e17a2d7 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,12 +443,13 @@ IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
 static struct iio_chan_spec lis3l02dq_channels[] = {
 	IIO_CHAN_EV(IIO_ACCEL, 'x', LIS3L02DQ_INFO_MASK,
 		    0, 0, IIO_ST('s', 12, 16, 0),
-		    LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
+		    LIS3L02DQ_EVENT_MASK, NULL),
 	IIO_CHAN_EV(IIO_ACCEL, 'y', LIS3L02DQ_INFO_MASK,
 		    1, 1, IIO_ST('s', 12, 16, 0),
-		    LIS3L02DQ_EVENT_MASK, &iio_event_threshold),
-	IIO_CHAN(IIO_ACCEL, 'z', LIS3L02DQ_INFO_MASK,
-		 2, 2, IIO_ST('s', 12, 16, 0)),
+		    LIS3L02DQ_EVENT_MASK, NULL),
+	IIO_CHAN_EV(IIO_ACCEL, 'z', LIS3L02DQ_INFO_MASK,
+		    2, 2, IIO_ST('s', 12, 16, 0),
+		    LIS3L02DQ_EVENT_MASK, NULL),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -476,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;
@@ -506,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:
@@ -539,7 +593,7 @@ error_ret:
  */
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
-       struct lis3l02dq_state *st
+	struct lis3l02dq_state *st
 	       = container_of(work_s,
 		       struct lis3l02dq_state, work_thresh);
 
@@ -697,7 +751,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 +821,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] 77+ messages in thread

* [PATCH 11/70] staging:iio:sca3000 extract old event handling and move to poll for events from buffer
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (9 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 10/70] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 12/70] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
                   ` (58 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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..b21e0b3 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_EV(IIO_ACCEL, 'x', SCA3000_INFO_MASK,
+		    0, 0, IIO_ST('s', 11, 16, 5),
+		    SCA3000_EVENT_MASK, NULL),
+	IIO_CHAN_EV(IIO_ACCEL, 'y', SCA3000_INFO_MASK,
+		    1, 1, IIO_ST('s', 11, 16, 5),
+		    SCA3000_EVENT_MASK, NULL),
+	IIO_CHAN_EV(IIO_ACCEL, '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] 77+ messages in thread

* [PATCH 12/70] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (10 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 11/70] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 13/70] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
                   ` (57 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 13/70] staging:iio:light:tsl2563 remove old style event registration.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (11 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 12/70] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 14/70] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
                   ` (56 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 14/70] staging:iio:dac:ad5504 move from old to new event handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (12 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 13/70] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 15/70] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
                   ` (55 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 15/70] staging:iio:adt7316 get rid of legacy event handling code.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (13 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 14/70] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 16/70] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
                   ` (54 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 6145963..9e96b5f 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] 77+ messages in thread

* [PATCH 16/70] staging:iio:adc:ad7745 move from old to current event handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (14 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 15/70] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 17/70] staging:iio:adc:ad7816 " Jonathan Cameron
                   ` (53 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 17/70] staging:iio:adc:ad7816 move from old to current event handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (15 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 16/70] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 18/70] staging:iio:adc:ad7150 move from deprecated " Jonathan Cameron
                   ` (52 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 18/70] staging:iio:adc:ad7150 move from deprecated event handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (16 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 17/70] staging:iio:adc:ad7816 " Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 19/70] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
                   ` (51 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 5a2991a..a236caf 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.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"
@@ -66,9 +64,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 +84,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 +663,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,
 };
 
@@ -799,18 +750,15 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 	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");
+		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);
@@ -834,7 +782,7 @@ static int __devexit ad7150_remove(struct i2c_client *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);
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
-- 
1.7.3.4

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

* [PATCH 19/70] staging:iio:adc:ad7152 remove unregister of interrupt line.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (17 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 18/70] staging:iio:adc:ad7150 move from deprecated " Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 20/70] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
                   ` (50 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 163c307..46a0b67 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -72,7 +72,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 +568,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] 77+ messages in thread

* [PATCH 20/70] staging:iio:adc:adt75 old to new event handling conversion
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (18 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 19/70] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 21/70] staging:iio:ad7291 move from old event system to current Jonathan Cameron
                   ` (49 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |  142 ++++++++++++---------------------------
 1 files changed, 43 insertions(+), 99 deletions(-)

diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index f247c4c..cf0e5e4 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.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"
@@ -57,8 +55,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 +275,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 +436,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 +463,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 +503,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 +586,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 +616,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 +633,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] 77+ messages in thread

* [PATCH 21/70] staging:iio:ad7291 move from old event system to current.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (19 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 20/70] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 22/70] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
                   ` (48 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 22/70] staging:iio:adc:adt7410 move to current event handling
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (20 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 21/70] staging:iio:ad7291 move from old event system to current Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 23/70] staging:iio:adt7310 " Jonathan Cameron
                   ` (47 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 23/70] staging:iio:adt7310 move to current event handling
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (21 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 22/70] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 24/70] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
                   ` (46 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 24/70] staging:iio:adc:ad7314 remove unmatched unregister of event line.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (22 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 23/70] staging:iio:adt7310 " Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 25/70] staging:iio:ad799x move to new event handling Jonathan Cameron
                   ` (45 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
index dffbec1..00bf3f4 100644
--- a/drivers/staging/iio/adc/ad7314.c
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -262,8 +262,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] 77+ messages in thread

* [PATCH 25/70] staging:iio:ad799x move to new event handling
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (23 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 24/70] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:05 ` [PATCH 26/70] staging:iio: Remove legacy " Jonathan Cameron
                   ` (44 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 26/70] staging:iio: Remove legacy event handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (24 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 25/70] staging:iio:ad799x move to new event handling Jonathan Cameron
@ 2011-04-17 19:05 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 27/70] staging:iio:lis3l02dq make threshold interrupt threaded Jonathan Cameron
                   ` (43 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:05 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/lis3l02dq_core.c |   33 +---
 drivers/staging/iio/accel/sca3000_core.c   |   24 +--
 drivers/staging/iio/adc/max1363.h          |    4 -
 drivers/staging/iio/adc/max1363_core.c     |   77 ++++------
 drivers/staging/iio/chrdev.h               |   21 ---
 drivers/staging/iio/iio.h                  |   90 +----------
 drivers/staging/iio/industrialio-core.c    |  250 +++-------------------------
 drivers/staging/iio/sysfs.h                |  129 --------------
 8 files changed, 77 insertions(+), 551 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index e17a2d7..d650ab9 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);
@@ -443,13 +442,13 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *_int_info)
 static struct iio_chan_spec lis3l02dq_channels[] = {
 	IIO_CHAN_EV(IIO_ACCEL, 'x', LIS3L02DQ_INFO_MASK,
 		    0, 0, IIO_ST('s', 12, 16, 0),
-		    LIS3L02DQ_EVENT_MASK, NULL),
+		    LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN_EV(IIO_ACCEL, 'y', LIS3L02DQ_INFO_MASK,
 		    1, 1, IIO_ST('s', 12, 16, 0),
-		    LIS3L02DQ_EVENT_MASK, NULL),
+		    LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN_EV(IIO_ACCEL, 'z', LIS3L02DQ_INFO_MASK,
 		    2, 2, IIO_ST('s', 12, 16, 0),
-		    LIS3L02DQ_EVENT_MASK, NULL),
+		    LIS3L02DQ_EVENT_MASK),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -508,7 +507,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 +516,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 +557,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 +578,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:
@@ -744,16 +742,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 */
@@ -765,9 +756,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:
@@ -832,9 +820,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 b21e0b3..c8b8325 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -441,13 +441,13 @@ static IIO_DEV_ATTR_REV(sca3000_show_rev);
 static struct iio_chan_spec sca3000_channels[] = {
 	IIO_CHAN_EV(IIO_ACCEL, 'x', SCA3000_INFO_MASK,
 		    0, 0, IIO_ST('s', 11, 16, 5),
-		    SCA3000_EVENT_MASK, NULL),
+		    SCA3000_EVENT_MASK),
 	IIO_CHAN_EV(IIO_ACCEL, 'y', SCA3000_INFO_MASK,
 		    1, 1, IIO_ST('s', 11, 16, 5),
-		    SCA3000_EVENT_MASK, NULL),
+		    SCA3000_EVENT_MASK),
 	IIO_CHAN_EV(IIO_ACCEL, 'z', SCA3000_INFO_MASK,
 		    2, 2, IIO_ST('s', 11, 16, 5),
-		    SCA3000_EVENT_MASK, NULL),
+		    SCA3000_EVENT_MASK),
 };
 
 static u8 sca3000_addresses[3][3] = {
@@ -977,7 +977,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 +1031,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 b5b175c..e8d10f9 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))
@@ -285,28 +271,28 @@ IIO_EVENT_SH(max1363_thresh, max1363_int_th);
 static struct iio_chan_spec max1363_channels[] = {
 	IIO_CHAN_EV(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0,
 		    IIO_ST('u', 12, 16, 0),
-		    MAX1363_EV_M, &iio_event_max1363_thresh),
+		    MAX1363_EV_M),
 	IIO_CHAN_EV(IIO_IN, 1, MAX1363_INFO_MASK,
 		    _s1, 1, IIO_ST('u', 12, 16, 0),
-		    MAX1363_EV_M, &iio_event_max1363_thresh),
+		    MAX1363_EV_M),
 	IIO_CHAN_EV(IIO_IN, 2, MAX1363_INFO_MASK,
 		    _s2, 2, IIO_ST('u', 12, 16, 0),
-		    MAX1363_EV_M, &iio_event_max1363_thresh),
+		    MAX1363_EV_M),
 	IIO_CHAN_EV(IIO_IN, 3, MAX1363_INFO_MASK,
 		    _s3, 3, IIO_ST('u', 12, 16, 0),
-		    MAX1363_EV_M, &iio_event_max1363_thresh),
+		    MAX1363_EV_M),
 	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
 			     d0m1, 4, IIO_ST('s', 12, 16, 0),
-			     MAX1363_EV_M, &iio_event_max1363_thresh),
+			     MAX1363_EV_M),
 	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 2, 3, MAX1363_INFO_MASK,
 			     d2m3, 5, IIO_ST('s', 12, 16, 0),
-			     MAX1363_EV_M, &iio_event_max1363_thresh),
+			     MAX1363_EV_M),
 	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
 			     d1m0, 6, IIO_ST('s', 12, 16, 0),
-			     MAX1363_EV_M, &iio_event_max1363_thresh),
+			     MAX1363_EV_M),
 	IIO_CHAN_COMPOUND_EV(IIO_IN_DIFF, 3, 2, MAX1363_INFO_MASK,
 			     d3m2, 7, IIO_ST('s', 12, 16, 0),
-			     MAX1363_EV_M, &iio_event_max1363_thresh),
+			     MAX1363_EV_M),
 	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
@@ -1069,11 +1055,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 };
@@ -1083,37 +1069,39 @@ 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);
+			timestamp);
 	enable_irq(st->client->irq);
 	i2c_master_send(st->client, tx, 2);
+
+	return IRQ_HANDLED;
 }
 
 static int max1363_read_event_config(struct iio_dev *indio_dev,
@@ -1270,7 +1258,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;
@@ -1302,12 +1289,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:
@@ -1426,15 +1407,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;
@@ -1466,7 +1447,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 662cb8e..b818f5f 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -77,7 +77,6 @@ enum iio_chan_info_enum {
  * @info_mask:	what information is to be exported about this channel.
  *		This includes calibbias, scale etc.
  * @event_mask:	what events can this channel produce.
- * @shared_handler: single handler for the events registered.
  */
 struct iio_chan_spec {
 	enum iio_chan_type type;
@@ -93,9 +92,6 @@ struct iio_chan_spec {
 	} scan_type;
 	const long info_mask;
 	const long event_mask;
-	/* 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);
@@ -119,14 +115,13 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
 			.scan_index = _si, .scan_type = _stype }
 
 #define IIO_CHAN_EV(_type, _chan, _inf_mask, _address, _si,		\
-		    _stype, _event_mask, _shared_h)			\
+		    _stype, _event_mask)				\
 	{ .type = _type,						\
 			.channel = _chan,				\
 			.info_mask = _inf_mask,				\
 			.address = _address,				\
 			.scan_index = _si, .scan_type = _stype,		\
-			.event_mask = _event_mask,			\
-			.shared_handler = _shared_h }
+			.event_mask = _event_mask }
 
 #define IIO_CHAN_COMPOUND(_type, _chan1, _chan2, _inf_mask,		\
 			  _address, _si, _stype)			\
@@ -136,14 +131,13 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
 			.scan_index = _si, .scan_type = _stype }
 
 #define IIO_CHAN_COMPOUND_EV(_type, _chan1, _chan2, _inf_mask,		\
-			     _address, _si, _stype, _event_mask, _shared_h) \
+			     _address, _si, _stype, _event_mask)	\
 	{ .type = _type,						\
 			.channel = _chan1, .channel2 = _chan2,		\
 			.info_mask = _inf_mask,				\
 			.address = _address,				\
 			.scan_index = _si, .scan_type = _stype,		\
-			.event_mask = _event_mask,			\
-			.shared_handler = _shared_h}
+			.event_mask = _event_mask }
 
 #define IIO_CHAN_SOFT_TIMESTAMP(_si)					\
 	{ .type = IIO_TIMESTAMP, .channel = -1,				\
@@ -178,26 +172,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
@@ -221,7 +195,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
@@ -242,7 +215,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;
 
@@ -277,7 +249,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,
@@ -301,49 +272,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)
@@ -356,16 +284,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 d73f8d8..2e2e51d 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -76,16 +76,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;
 
@@ -115,76 +112,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,
@@ -195,52 +124,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,
@@ -845,15 +728,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;
 }
@@ -863,8 +745,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;
@@ -910,67 +792,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;
-	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);
-
-	name_format = kasprintf(GFP_KERNEL, "%s_%s",
-				iio_chan_type_name_spec[chan->type],
-				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)
 {
@@ -1009,18 +830,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;
@@ -1056,7 +880,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) {
@@ -1067,23 +890,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) {
@@ -1099,7 +911,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) {
@@ -1170,14 +981,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;
 
@@ -1235,8 +1038,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:
 
@@ -1259,7 +1060,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 f80d789..47d1afb 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] 77+ messages in thread

* [PATCH 27/70] staging:iio:lis3l02dq make threshold interrupt threaded.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (25 preceding siblings ...)
  2011-04-17 19:05 ` [PATCH 26/70] staging:iio: Remove legacy " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
                   ` (42 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |  160 +++++++++++++---------------
 2 files changed, 73 insertions(+), 91 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 d650ab9..f54a16d 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;
 }
@@ -553,11 +615,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;
 		}
@@ -586,84 +650,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[] = {
@@ -685,7 +671,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] 77+ messages in thread

* [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (26 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 27/70] staging:iio:lis3l02dq make threshold interrupt threaded Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-21 16:51   ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 29/70] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
                   ` (41 subsequent siblings)
  69 siblings, 1 reply; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

fix to merge back for the incorrect multiple trigger handling

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/Makefile                      |    2 +-
 drivers/staging/iio/Kconfig                   |   12 ++
 drivers/staging/iio/Makefile                  |    2 +
 drivers/staging/iio/iio-board-info.h          |   24 +++
 drivers/staging/iio/iio-core.h                |   13 ++
 drivers/staging/iio/industrialio-board-info.c |   25 +++
 drivers/staging/iio/industrialio-trigger.c    |  200 +++++++++++++++++++++----
 drivers/staging/iio/trigger.h                 |   57 +++++++-
 8 files changed, 298 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index eb93012..0955c7c 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_HYPERV)		+= hv/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_DX_SEP)            += sep/
-obj-$(CONFIG_IIO)		+= iio/
+obj-y				+= iio/
 obj-$(CONFIG_CS5535_GPIO)	+= cs5535_gpio/
 obj-$(CONFIG_ZRAM)		+= zram/
 obj-$(CONFIG_XVMALLOC)		+= zram/
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 6775bf9..df9aa08 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -12,6 +12,10 @@ menuconfig IIO
 	  Documentation/industrialio for more information.
 if IIO
 
+config IIO_BOARDINFO
+       boolean
+       default y
+
 config IIO_RING_BUFFER
 	bool "Enable ring buffer support within IIO"
 	help
@@ -42,12 +46,20 @@ endif # IIO_RINGBUFFER
 
 config IIO_TRIGGER
 	boolean "Enable triggered sampling support"
+	depends on IIO_BOARDINFO
 	help
 	  Provides IIO core support for triggers.  Currently these
 	  are used to initialize capture of samples to push into
 	  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/Makefile b/drivers/staging/iio/Makefile
index bb5c95c..37b4d12 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -2,6 +2,8 @@
 # Makefile for the industrial I/O core.
 #
 
+obj-$(CONFIG_IIO_BOARDINFO) += industrialio-board-info.o
+
 obj-$(CONFIG_IIO) += industrialio.o
 industrialio-y := industrialio-core.o
 industrialio-$(CONFIG_IIO_RING_BUFFER) += industrialio-ring.o
diff --git a/drivers/staging/iio/iio-board-info.h b/drivers/staging/iio/iio-board-info.h
new file mode 100644
index 0000000..c608a4d
--- /dev/null
+++ b/drivers/staging/iio/iio-board-info.h
@@ -0,0 +1,24 @@
+/*
+ * Board information for IIO.
+ *
+ * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_IIO_BOARDINFO
+
+/**
+ * iio_set_irq_pool() - provid iio with a pool of virtaul interrupts to use
+ * @start: start of the pool
+ * @num: number of interupts in the pool
+ **/
+void iio_set_irq_pool(int start, int num);
+
+#else
+
+static inline void iio_set_irq_pool(int start, int num) {};
+
+#endif
diff --git a/drivers/staging/iio/iio-core.h b/drivers/staging/iio/iio-core.h
new file mode 100644
index 0000000..2c4f433
--- /dev/null
+++ b/drivers/staging/iio/iio-core.h
@@ -0,0 +1,13 @@
+/*
+ * IIO core header. Should never be included by drivers.
+ *
+ * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define IIO_MAX_POOL 128
+extern int __iio_irqstart;
+extern int __iio_irqnum;
diff --git a/drivers/staging/iio/industrialio-board-info.c b/drivers/staging/iio/industrialio-board-info.c
new file mode 100644
index 0000000..28f9156
--- /dev/null
+++ b/drivers/staging/iio/industrialio-board-info.c
@@ -0,0 +1,25 @@
+/* IIO Board info
+ *
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include "iio-core.h"
+
+int __iio_irqstart;
+EXPORT_SYMBOL(__iio_irqstart);
+int __iio_irqnum;
+EXPORT_SYMBOL(__iio_irqnum);
+
+void __init iio_set_irq_pool(int start, int num)
+{
+	__iio_irqstart = start;
+	__iio_irqnum = num;
+	if (num > IIO_MAX_POOL)
+		__iio_irqnum = IIO_MAX_POOL;
+}
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 083847c..9ccc789 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -19,6 +19,7 @@
 #include "iio.h"
 #include "trigger.h"
 #include "trigger_consumer.h"
+#include "iio-core.h"
 
 /* RFC - Question of approach
  * Make the common case (single sensor single trigger)
@@ -38,6 +39,31 @@ static DEFINE_SPINLOCK(iio_trigger_idr_lock);
 static LIST_HEAD(iio_trigger_list);
 static DEFINE_MUTEX(iio_trigger_list_lock);
 
+static DEFINE_MUTEX(iio_irq_pool_lock);
+static unsigned long iio_irq_pool_mask[BITS_TO_LONGS(IIO_MAX_POOL)] = {};
+
+static int iio_irq_pool_get_range(int num)
+{
+	int ret;
+
+	mutex_lock(&iio_irq_pool_lock);
+	ret = bitmap_find_free_region(iio_irq_pool_mask,
+				      __iio_irqnum, ilog2(num));
+	if (ret >= 0)
+		ret += __iio_irqstart;
+	mutex_unlock(&iio_irq_pool_lock);
+
+	return ret;
+}
+
+static void iio_irq_pool_put_range(int start, int num)
+{
+	mutex_lock(&iio_irq_pool_lock);
+	bitmap_release_region(iio_irq_pool_mask,
+			      start - __iio_irqstart, ilog2(num));
+	mutex_unlock(&iio_irq_pool_lock);
+}
+
 /**
  * iio_trigger_register_sysfs() - create a device for this trigger
  * @trig_info:	the trigger
@@ -163,6 +189,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 +205,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 +253,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 +289,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 +412,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);
+		}
+
+		iio_irq_pool_put_range(trig->subirq_base,
+				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+	}
 	kfree(trig);
 	iio_put();
 }
@@ -345,11 +436,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 +467,40 @@ 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
+				= iio_irq_pool_get_range(
+					CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+			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] 77+ messages in thread

* [PATCH 29/70] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (27 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 30/70] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
                   ` (40 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 30/70] staging:iio:ring_sw add function needed for threaded irq.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (28 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 29/70] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 31/70] staging:iio: add generic data ready poll function Jonathan Cameron
                   ` (39 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 31/70] staging:iio: add generic data ready poll function.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (29 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 30/70] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 32/70] staging:iio:lis3l02dq move to threaded trigger handling Jonathan Cameron
                   ` (38 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 9ccc789..b2c48d5b 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -215,6 +215,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] 77+ messages in thread

* [PATCH 32/70] staging:iio:lis3l02dq move to threaded trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (30 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 31/70] staging:iio: add generic data ready poll function Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 33/70] staging:iio:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
                   ` (37 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |    2 -
 drivers/staging/iio/accel/lis3l02dq_ring.c |  137 +++++++++++----------------
 3 files changed, 56 insertions(+), 85 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 f54a16d..5d57110 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -15,7 +15,6 @@
 #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>
@@ -727,7 +726,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;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 9bc2e5f..108b956 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -29,37 +29,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 +122,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 +206,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 +242,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 +268,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 +295,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 +318,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 +343,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 +423,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 +446,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] 77+ messages in thread

* [PATCH 33/70] staging:iio:max1363 move to irqchip based threaded irq triggering
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (31 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 32/70] staging:iio:lis3l02dq move to threaded trigger handling Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 34/70] staging:iio:ad7476 use channel_spec Jonathan Cameron
                   ` (36 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/max1363.h      |    4 --
 drivers/staging/iio/adc/max1363_core.c |    2 -
 drivers/staging/iio/adc/max1363_ring.c |   64 +++++++++++++-------------------
 3 files changed, 26 insertions(+), 44 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 e8d10f9..48a2a28 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1352,8 +1352,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..ef3c2bc 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -105,36 +105,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 +125,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 +148,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 +167,34 @@ 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:
-- 
1.7.3.4

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

* [PATCH 34/70] staging:iio:ad7476 use channel_spec
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (32 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 33/70] staging:iio:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 35/70] staging:iio:ad7476 move to irqchip based triggering Jonathan Cameron
                   ` (35 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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..9f7e904 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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_EV(IIO_IN, 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] 77+ messages in thread

* [PATCH 35/70] staging:iio:ad7476 move to irqchip based triggering
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (33 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 34/70] staging:iio:ad7476 use channel_spec Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 36/70] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
                   ` (34 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Untested

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7476.h      |    2 -
 drivers/staging/iio/adc/ad7476_core.c |    1 -
 drivers/staging/iio/adc/ad7476_ring.c |   62 +++++++++++++-------------------
 3 files changed, 25 insertions(+), 40 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 9f7e904..efeb0dc 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -176,7 +176,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..e018b96 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -77,46 +77,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 +104,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 +122,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 +146,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:
-- 
1.7.3.4

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

* [PATCH 36/70] staging:iio:meter:ade7758 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (34 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 35/70] staging:iio:ad7476 move to irqchip based triggering Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 37/70] staging:iio:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
                   ` (33 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 37/70] staging:iio:adis16400 move to irq based triggers and channel spec channel registration.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (35 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 36/70] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 38/70] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
                   ` (32 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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..fe7ccfd 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16400_SCAN_SUPPLY,
+		    IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_GYRO, '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_EV(IIO_GYRO, '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_EV(IIO_GYRO, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_MAGN, 'x',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    magn_x, ADIS16400_SCAN_MAGN_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_MAGN, 'y',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    magn_y, ADIS16400_SCAN_MAGN_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_MAGN, 'z',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    magn_z, ADIS16400_SCAN_MAGN_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_TEMP, 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_EV(IIO_IN, 1,
+		    (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] 77+ messages in thread

* [PATCH 38/70] staging:iio:imu:adis16350 etc support into adis16400 driver.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (36 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 37/70] staging:iio:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 39/70] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
                   ` (31 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

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 fe7ccfd..a0092b5 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_GYRO, '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_EV(IIO_GYRO, '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_EV(IIO_GYRO, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_TEMP, 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_EV(IIO_TEMP, 1,
+		    (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_EV(IIO_TEMP, 2,
+		    (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_EV(IIO_IN, 1,
+		    (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] 77+ messages in thread

* [PATCH 39/70] staging:iio:imu remove old adis16350. Support now in adis16400 driver.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (37 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 38/70] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 40/70] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
                   ` (30 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 40/70] staging:iio:imu:adis16400 add support for adis16300
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (38 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 39/70] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 41/70] staging:iio:imu remove adis16300 driver Jonathan Cameron
                   ` (29 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

Untested.

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 a0092b5..aa3fca0 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_GYRO, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_TEMP, 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_EV(IIO_IN, 1,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, 'x',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    0, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, '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] 77+ messages in thread

* [PATCH 41/70] staging:iio:imu remove adis16300 driver.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (39 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 40/70] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 42/70] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
                   ` (28 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 42/70] staging:iio:accel:adis16201 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (40 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 41/70] staging:iio:imu remove adis16300 driver Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 43/70] staging:iio:accel:adis16203 " Jonathan Cameron
                   ` (27 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 43/70] staging:iio:accel:adis16203 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (41 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 42/70] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 44/70] staging:iio:accel:adis16204 " Jonathan Cameron
                   ` (26 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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    |   53 +++++++++++++------------
 drivers/staging/iio/accel/adis16203_trigger.c |   51 +++++++----------------
 3 files changed, 43 insertions(+), 66 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..da6715a 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)
-		goto error_iio_sw_rb_free;
+	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..e8930d2 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] 77+ messages in thread

* [PATCH 44/70] staging:iio:accel:adis16204 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (42 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 43/70] staging:iio:accel:adis16203 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 45/70] staging:iio:accel:adis16209 " Jonathan Cameron
                   ` (25 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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    |   55 ++++++++++++-------------
 drivers/staging/iio/accel/adis16204_trigger.c |   53 ++++++++----------------
 3 files changed, 44 insertions(+), 69 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..dfc09c3 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)
-		goto error_iio_sw_rb_free;
+	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 c1dcb94..ef9b84f 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] 77+ messages in thread

* [PATCH 45/70] staging:iio:accel:adis16209 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (43 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 44/70] staging:iio:accel:adis16204 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 46/70] staging:iio:accel:adis16240 " Jonathan Cameron
                   ` (24 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 46/70] staging:iio:accel:adis16240 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (44 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 45/70] staging:iio:accel:adis16209 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 47/70] staging:iio:adc:ad7298 " Jonathan Cameron
                   ` (23 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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    |   68 ++++++++++++-------------
 drivers/staging/iio/accel/adis16240_trigger.c |   39 +++++---------
 3 files changed, 45 insertions(+), 67 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..c289b66 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)
-		goto error_iio_sw_rb_free;
-
+	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 c5a26ae..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,
@@ -74,35 +69,27 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev)
 			  st->trig);
 	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] 77+ messages in thread

* [PATCH 47/70] staging:iio:adc:ad7298 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (45 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 46/70] staging:iio:accel:adis16240 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling Jonathan Cameron
                   ` (22 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |    1 -
 drivers/staging/iio/adc/ad7298_ring.c |   65 +++++++++++++--------------------
 3 files changed, 26 insertions(+), 42 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..5a60481 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -170,7 +170,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] 77+ messages in thread

* [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (46 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 47/70] staging:iio:adc:ad7298 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-18  7:52   ` Hennerich, Michael
  2011-04-17 19:06 ` [PATCH 49/70] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
                   ` (21 subsequent siblings)
  69 siblings, 1 reply; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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

diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index b32cb0d..ace376d 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,19 @@ 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, "adis16203_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 = &ad7606_ring_preenable;
@@ -262,6 +274,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 +289,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] 77+ messages in thread

* [PATCH 49/70] staging:iio:adc:ad7887 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (47 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 50/70] staging:iio:adc:ad799x " Jonathan Cameron
                   ` (20 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |   63 ++++++++++++++-------------------
 3 files changed, 27 insertions(+), 39 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..8e3653c 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)
@@ -214,18 +193,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));
+		memcpy(buf + st->d_size - sizeof(s64), &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 +213,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 +238,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 +257,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] 77+ messages in thread

* [PATCH 50/70] staging:iio:adc:ad799x move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (48 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 49/70] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 51/70] staging:iio:gyro:adis16260 " Jonathan Cameron
                   ` (19 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |    1 -
 drivers/staging/iio/adc/ad799x_ring.c |   60 ++++++++++++++------------------
 3 files changed, 26 insertions(+), 38 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..dadb320 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;
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 0875a7e..417f627 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,20 @@ 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, "adis16203_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 = &ad799x_ring_preenable;
@@ -203,13 +194,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 +215,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] 77+ messages in thread

* [PATCH 51/70] staging:iio:gyro:adis16260 move to irqchip based trigger handling.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (49 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 50/70] staging:iio:adc:ad799x " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 52/70] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
                   ` (18 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |   53 +++++++--------------
 3 files changed, 47 insertions(+), 75 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..88b9ff3 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;
-
-	st->trig = iio_allocate_trigger();
+	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);
 	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] 77+ messages in thread

* [PATCH 52/70] staging:iio:trigger remove legacy pollfunc elements.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (50 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 51/70] staging:iio:gyro:adis16260 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 53/70] staging:iio: Add core attribute handling for name of device Jonathan Cameron
                   ` (17 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index b2c48d5b..b8e7ce4 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -190,21 +190,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) {
@@ -258,32 +243,15 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
 				 struct iio_poll_func *pf)
 {
 	int ret = 0;
-	unsigned long flags;
+	bool notinuse
+		= bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
 
-	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);
-		}
-	}
+	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;
 }
@@ -292,53 +260,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;
@@ -471,9 +404,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);
@@ -534,20 +464,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] 77+ messages in thread

* [PATCH 53/70] staging:iio: Add core attribute handling for name of device.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (51 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 52/70] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 20:06   ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 54/70] staging:iio: use the new central name attribute creation code Jonathan Cameron
                   ` (16 subsequent siblings)
  69 siblings, 1 reply; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |   36 ++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index b818f5f..febf20e 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -231,7 +231,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 2e2e51d..67e7ade 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -610,6 +610,13 @@ static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
 	kfree(p->dev_attr.attr.name);
 	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 int iio_device_register_sysfs(struct iio_dev *dev_info)
 {
@@ -638,8 +645,35 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
 			if (ret < 0)
 				goto error_clear_attrs;
 		}
-
+	if (dev_info->name) {
+		p = kzalloc(sizeof *p, GFP_KERNEL);
+		if (p == NULL) {
+			ret = -ENOMEM;
+			goto error_clear_attrs;
+		}
+		sysfs_attr_init(&p->dev_attr.attr);
+	
+		p->dev_attr.attr.name = kstrdup("name", GFP_KERNEL);
+		if (p->dev_attr.attr.name == NULL) {
+			ret = -ENOMEM;
+			kfree(p);
+			goto error_free_attr;
+		}
+		p->dev_attr.attr.mode = S_IRUGO;
+		p->dev_attr.show = &iio_show_dev_name;
+		ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
+					      &p->dev_attr.attr, NULL);
+		if (ret < 0)
+			goto error_free_name_name;	
+		
+		list_add(&p->l, &dev_info->channel_attr_list);
+	}
 	return 0;
+
+error_free_name_name:
+	kfree(p->dev_attr.attr.name);
+error_free_attr:
+	kfree(p);
 error_clear_attrs:
 	list_for_each_entry_safe(p, n,
 				 &dev_info->channel_attr_list, l) {
-- 
1.7.3.4

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

* [PATCH 54/70] staging:iio: use the new central name attribute creation code
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (52 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 53/70] staging:iio: Add core attribute handling for name of device Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 55/70] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
                   ` (15 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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      |   15 +------------
 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, 66 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 5d57110..61045a5 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -649,12 +649,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
 };
 
@@ -694,6 +691,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 c8b8325..c636928 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			\
@@ -768,7 +759,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,
@@ -778,7 +768,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,
@@ -1137,6 +1126,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 a236caf..f804edf 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -61,7 +61,6 @@
  */
 
 struct ad7150_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	bool inter;
@@ -587,17 +586,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)
@@ -646,7 +634,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,
 };
 
@@ -727,7 +714,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) {
@@ -736,6 +722,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 46a0b67..fe85219b 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -54,7 +54,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 */
@@ -483,17 +482,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,
@@ -506,7 +494,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,
 };
 
@@ -532,7 +519,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) {
@@ -541,6 +527,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 5a60481..5fe0dff 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -119,17 +119,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,
@@ -141,7 +130,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,
 };
 
@@ -178,6 +166,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 00bf3f4..0ef6db4 100644
--- a/drivers/staging/iio/adc/ad7314.c
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -47,7 +47,6 @@
  */
 
 struct ad7314_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
 	s64 last_timestamp;
@@ -160,7 +159,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) {
@@ -186,22 +185,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,
 };
 
@@ -227,7 +214,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) {
@@ -235,6 +221,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;
@@ -245,7 +232,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 efeb0dc..f26f7a1 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -69,26 +69,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_EV(IIO_IN, 0,
@@ -186,7 +166,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 dadb320..70006ec 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
 };
@@ -794,6 +780,7 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 
 	/* Estabilish that the iio_dev is a child of the i2c device */
 	st->indio_dev->dev.parent = &client->dev;
+	st->indio_dev->name = id->name;
 	st->indio_dev->attrs = st->chip_info->dev_attrs;
 	st->indio_dev->event_attrs = st->chip_info->event_attrs;
 
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 cf0e5e4..f0f62bc 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -52,7 +52,6 @@
  */
 
 struct adt75_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u8  config;
@@ -245,23 +244,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,
 };
 
@@ -565,7 +552,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) {
@@ -573,6 +559,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;
@@ -590,7 +577,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;
@@ -612,7 +599,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 48a2a28..ab07a59 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -245,16 +245,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,
@@ -360,15 +350,6 @@ static struct iio_chan_spec max1036_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
-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,
@@ -1369,7 +1350,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 9e96b5f..05b48b1 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 da5e302..ae03df2 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,
 };
 
@@ -356,6 +344,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 aa3fca0..09d0efb 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 47d1afb..1dc32eb 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] 77+ messages in thread

* [PATCH 55/70] staging:iio:accel:adis16201 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (53 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 54/70] staging:iio: use the new central name attribute creation code Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 56/70] staging:iio:accel:adis16203 " Jonathan Cameron
                   ` (14 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

Some minor cleanups done whilst here.

Untested.

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..7832b68 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16201_SCAN_SUPPLY,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_TEMP, 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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_IN, 1,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_aux, ADIS16201_SCAN_AUX_ADC,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, '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_EV(IIO_INCLI, '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] 77+ messages in thread

* [PATCH 56/70] staging:iio:accel:adis16203 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (54 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 55/70] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 57/70] staging:iio:accel:adis16204 " Jonathan Cameron
                   ` (13 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

Some minor cleanups done whilst here.

Untested.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/accel/adis16203.h         |   13 +-
 drivers/staging/iio/accel/adis16203_core.c    |  374 ++++++++++++-------------
 drivers/staging/iio/accel/adis16203_ring.c    |   61 +----
 drivers/staging/iio/accel/adis16203_trigger.c |    2 +-
 4 files changed, 193 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..6b46c92 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,41 @@ 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 +182,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 +210,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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16203_SCAN_SUPPLY,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_IN, 1,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_aux, ADIS16203_SCAN_AUX_ADC,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, '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_EV(IIO_INCLI, 'y',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    incli_y, ADIS16203_SCAN_INCLI_Y,
+		    IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_TEMP, 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 +439,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 +456,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 +471,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 +479,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 +502,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 da6715a..1c5578a 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 e8930d2..66c6978 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] 77+ messages in thread

* [PATCH 57/70] staging:iio:accel:adis16204 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (55 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 56/70] staging:iio:accel:adis16203 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 58/70] staging:iio:accel:adis16209 " Jonathan Cameron
                   ` (12 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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    |   64 +----
 drivers/staging/iio/accel/adis16204_trigger.c |    4 +-
 4 files changed, 222 insertions(+), 261 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..9f8dc1f 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16204_SCAN_SUPPLY,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_IN, 1,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16204_SCAN_SUPPLY,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_TEMP, 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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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 dfc09c3..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,16 +124,16 @@ 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) {
 		ret = -ENOMEM;
- 		goto error_iio_sw_rb_free;
+		goto error_iio_sw_rb_free;
 	}
 	indio_dev->pollfunc->private_data = indio_dev;
 	indio_dev->pollfunc->h = &iio_pollfunc_store_time;
@@ -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 ef9b84f..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)
@@ -49,7 +49,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	
+
 	st->trig = iio_allocate_trigger_named(name);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-- 
1.7.3.4

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

* [PATCH 58/70] staging:iio:accel:adis16209 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (56 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 57/70] staging:iio:accel:adis16204 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 59/70] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
                   ` (11 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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..0e68d2d 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16209_SCAN_SUPPLY,
+		    IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_TEMP, 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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_IN, 1,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_aux, ADIS16209_SCAN_AUX_ADC,
+		    IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, 'x',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    incli_x, ADIS16209_SCAN_INCLI_X,
+		    IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_INCLI, 'y',
+		    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		    incli_y, ADIS16209_SCAN_INCLI_Y,
+		    IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_EV(IIO_ROT, '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] 77+ messages in thread

* [PATCH 59/70] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (57 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 58/70] staging:iio:accel:adis16209 " Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 60/70] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
                   ` (10 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 61045a5..ceae5b4 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -220,6 +220,33 @@ 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);	
+	}
+	return ret;
+}
+
 static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 			      struct iio_chan_spec const *chan,
 			      int *val,
@@ -697,6 +724,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] 77+ messages in thread

* [PATCH 60/70] staging:iio: Add chan info support for 'peak_raw' attributes.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (58 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 59/70] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 61/70] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
                   ` (9 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 febf20e..4946006 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -57,7 +57,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 67e7ade..79145df 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -74,6 +74,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] 77+ messages in thread

* [PATCH 61/70] staging:iio:accel:adis16240 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (59 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 60/70] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 62/70] staging:iio: Add angl parameters to the chan spec code Jonathan Cameron
                   ` (8 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

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..80a571a 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_EV(IIO_IN, 0,
+		    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		    in_supply, ADIS16240_SCAN_SUPPLY,
+		    IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN_EV(IIO_IN, 1,
+		    0,
+		    in_aux, ADIS16240_SCAN_AUX_ADC,
+		    IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_ACCEL, '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_EV(IIO_TEMP, 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 c289b66..ae9100c 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] 77+ messages in thread

* [PATCH 62/70] staging:iio: Add angl parameters to the chan spec code.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (60 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 61/70] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 63/70] staging:iio:gyro:adis16260 move to chan_spec based setup Jonathan Cameron
                   ` (7 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 4946006..0bba445 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -45,6 +45,7 @@ enum iio_chan_type {
 	IIO_TEMP,
 	IIO_INCLI,
 	IIO_ROT,
+	IIO_ANGL,
 	IIO_TIMESTAMP,
 };
 
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 79145df..3f7df85 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -54,6 +54,7 @@ static const char * const iio_chan_type_name_spec_shared[] = {
 	[IIO_MAGN] = "magn",
 	[IIO_INCLI] = "incli",
 	[IIO_ROT] = "rot",
+	[IIO_ANGL] = "angl",
 };
 
 static const char * const iio_chan_type_name_spec[] = {
@@ -66,6 +67,7 @@ static const char * const iio_chan_type_name_spec[] = {
 	[IIO_MAGN] = "magn_%c",
 	[IIO_INCLI] = "incli_%c",
 	[IIO_ROT] = "rot_%c",
+	[IIO_ANGL] = "angl_%c",
 };
 
 /* relies on pairs of these shared then separate */
-- 
1.7.3.4


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

* [PATCH 63/70] staging:iio:gyro:adis16260 move to chan_spec based setup.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (61 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 62/70] staging:iio: Add angl parameters to the chan spec code Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 64/70] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
                   ` (6 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/gyro/adis16260.h         |    2 +-
 drivers/staging/iio/gyro/adis16260_core.c    |  446 +++++++++++++-------------
 drivers/staging/iio/gyro/adis16260_ring.c    |   51 +---
 drivers/staging/iio/gyro/adis16260_trigger.c |    2 +-
 4 files changed, 235 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..b3bb644 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,42 @@ 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 +335,231 @@ 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, chr)				\
+	struct iio_chan_spec adis16260_channels_##axis[] = {		\
+		IIO_CHAN_EV(IIO_GYRO, chr,				\
+			    (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_EV(IIO_ANGL, chr,				\
+			    0,						\
+			    angle, ADIS16260_SCAN_ANGL,			\
+			    IIO_ST('u', 14, 16, 0), 0),			\
+		IIO_CHAN_EV(IIO_TEMP, 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_EV(IIO_IN, 0,					\
+			    (1 << IIO_CHAN_INFO_SCALE_SEPARATE),	\
+			    in_supply, ADIS16260_SCAN_SUPPLY,		\
+			    IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN_EV(IIO_IN, 1,					\
+			    (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 ADIS16260_ATTR_GROUP();
-static ADIS16260_ATTR_GROUP(_x);
-static ADIS16260_ATTR_GROUP(_y);
-static ADIS16260_ATTR_GROUP(_z);
+static const ADIS16260_GYRO_CHANNEL_SET(x, 'x');
+static const ADIS16260_GYRO_CHANNEL_SET(y, 'y');
+static const ADIS16260_GYRO_CHANNEL_SET(z, '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;
+}
+
+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 +597,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 +631,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 +646,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 +678,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 88b9ff3..c5dc83b 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] 77+ messages in thread

* [PATCH 64/70] staging:iio: rip out scan_el attributes.  Now handled as iio_dev_attrs like everything else.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (62 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 63/70] staging:iio:gyro:adis16260 move to chan_spec based setup Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 65/70] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
                   ` (5 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 65/70] staging:iio:max1363 trivial removal of unused trig pointer.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (63 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 64/70] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 66/70] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
                   ` (4 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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] 77+ messages in thread

* [PATCH 66/70] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (64 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 65/70] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 67/70] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
                   ` (3 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

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

diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 4159389..228274b 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 ab07a59..10c75c0 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -598,6 +598,30 @@ static struct iio_chan_spec max11614_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(16)
 };
 
+static const enum max1363_modes max11644_mode_list[] = {
+	_s0, _s1, s0to1, d0m1, d1m0,
+};
+
+static struct iio_chan_spec max11644_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 2, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 3, IIO_ST('s', 12, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(4)
+};
+
+static struct iio_chan_spec max11646_channels[] = {
+	IIO_CHAN(IIO_IN, 0, MAX1363_INFO_MASK, _s0, 0, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN(IIO_IN, 1, MAX1363_INFO_MASK, _s0, 1, IIO_ST('u', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 0, 1, MAX1363_INFO_MASK,
+			  d0m1, 2, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_COMPOUND(IIO_IN_DIFF, 1, 0, MAX1363_INFO_MASK,
+			  d1m0, 3, IIO_ST('s', 10, 16, 0)),
+	IIO_CHAN_SOFT_TIMESTAMP(4)
+};
+
 enum { max1361,
        max1362,
        max1363,
@@ -632,6 +656,10 @@ enum { max1361,
        max11615,
        max11616,
        max11617,
+       max11644,
+       max11645,
+       max11646,
+       max11647
 };
 
 /* max1363 and max1368 tested - rest from data sheet */
@@ -945,7 +973,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] 77+ messages in thread

* [PATCH 67/70] staging:iio:trigger sysfs userspace trigger rework.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (65 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 66/70] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 68/70] staging:iio:core clean out unused elements Jonathan Cameron
                   ` (2 subsequent siblings)
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 b8e7ce4..273b327 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -207,6 +207,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] 77+ messages in thread

* [PATCH 68/70] staging:iio:core clean out unused elements.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (66 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 67/70] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 69/70] staging:iio:buffer - remove unused event code for buffer events Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 70/70] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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 0bba445..47ca59a 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 {
@@ -201,7 +199,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
@@ -221,8 +218,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;
@@ -288,14 +283,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 3f7df85..1aa0d30 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -934,21 +934,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) {
@@ -963,19 +948,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;
 }
@@ -983,23 +956,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] 77+ messages in thread

* [PATCH 69/70] staging:iio:buffer - remove unused event code for buffer events.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (67 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 68/70] staging:iio:core clean out unused elements Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  2011-04-17 19:06 ` [PATCH 70/70] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

These events are no longer passed up to userspace.

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

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 47ca59a..7f94197 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_ACCEL,
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 1dc32eb..8bbb286 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			0
 #define IIO_EV_MOD_Y			1
-- 
1.7.3.4

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

* [PATCH 70/70] staging:iio:lis3l02dq remerge the two interrupt handlers.
  2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
                   ` (68 preceding siblings ...)
  2011-04-17 19:06 ` [PATCH 69/70] staging:iio:buffer - remove unused event code for buffer events Jonathan Cameron
@ 2011-04-17 19:06 ` Jonathan Cameron
  69 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 19:06 UTC (permalink / raw)
  To: linux-iio; +Cc: 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, 46 insertions(+), 41 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 ceae5b4..04b7048 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -37,6 +37,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
@@ -561,19 +568,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,
@@ -594,9 +595,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;
@@ -606,9 +604,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;
@@ -640,18 +635,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);
@@ -665,10 +648,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:
@@ -752,9 +731,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 */
@@ -766,6 +754,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:
@@ -828,7 +819,8 @@ static int lis3l02dq_remove(struct spi_device *spi)
 		goto err_ret;
 
 	flush_scheduled_work();
-
+	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 108b956..e315f97 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -29,6 +29,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,
@@ -193,8 +209,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 */
@@ -205,20 +220,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] 77+ messages in thread

* Re: [PATCH 53/70] staging:iio: Add core attribute handling for name of device.
  2011-04-17 19:06 ` [PATCH 53/70] staging:iio: Add core attribute handling for name of device Jonathan Cameron
@ 2011-04-17 20:06   ` Jonathan Cameron
  2011-04-18 12:17     ` Jonathan Cameron
  0 siblings, 1 reply; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-17 20:06 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On 04/17/11 20:06, Jonathan Cameron wrote:
> Saves on a fair bit of code replication.
I clearly didn't think this through properly.  It can be done much
more neatly with a single static iio_dev_attr and just explicitly
adding and removing it.  See the trigger equivalent in the
iio-onwards tree that I have just pushed.

Jonathan
> 
> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/iio.h               |    2 +-
>  drivers/staging/iio/industrialio-core.c |   36 ++++++++++++++++++++++++++++++-
>  2 files changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
> index b818f5f..febf20e 100644
> --- a/drivers/staging/iio/iio.h
> +++ b/drivers/staging/iio/iio.h
> @@ -231,7 +231,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 2e2e51d..67e7ade 100644
> --- a/drivers/staging/iio/industrialio-core.c
> +++ b/drivers/staging/iio/industrialio-core.c
> @@ -610,6 +610,13 @@ static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
>  	kfree(p->dev_attr.attr.name);
>  	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 int iio_device_register_sysfs(struct iio_dev *dev_info)
>  {
> @@ -638,8 +645,35 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
>  			if (ret < 0)
>  				goto error_clear_attrs;
>  		}
> -
> +	if (dev_info->name) {
> +		p = kzalloc(sizeof *p, GFP_KERNEL);
> +		if (p == NULL) {
> +			ret = -ENOMEM;
> +			goto error_clear_attrs;
> +		}
> +		sysfs_attr_init(&p->dev_attr.attr);
> +	
> +		p->dev_attr.attr.name = kstrdup("name", GFP_KERNEL);
> +		if (p->dev_attr.attr.name == NULL) {
> +			ret = -ENOMEM;
> +			kfree(p);
> +			goto error_free_attr;
> +		}
> +		p->dev_attr.attr.mode = S_IRUGO;
> +		p->dev_attr.show = &iio_show_dev_name;
> +		ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
> +					      &p->dev_attr.attr, NULL);
> +		if (ret < 0)
> +			goto error_free_name_name;	
> +		
> +		list_add(&p->l, &dev_info->channel_attr_list);
> +	}
>  	return 0;
> +
> +error_free_name_name:
> +	kfree(p->dev_attr.attr.name);
> +error_free_attr:
> +	kfree(p);
>  error_clear_attrs:
>  	list_for_each_entry_safe(p, n,
>  				 &dev_info->channel_attr_list, l) {

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

* RE: [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling.
  2011-04-17 19:06 ` [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling Jonathan Cameron
@ 2011-04-18  7:52   ` Hennerich, Michael
  2011-04-18  9:57     ` Jonathan Cameron
  0 siblings, 1 reply; 77+ messages in thread
From: Hennerich, Michael @ 2011-04-18  7:52 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio; +Cc: device-drivers-devel, Drivers

Jonathan Cameron wrote on 2011-04-17:
> 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.

Typo below "adis16203_consumer%d"

Acked-by: Michael Hennerich <michael.hennerich@analog.com>

>
> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/adc/ad7606_ring.c |   27 +++++++++++++++++++++----

Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368; Gesch=
aeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin, Margaret=
 Seif

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

* Re: [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling.
  2011-04-18  7:52   ` Hennerich, Michael
@ 2011-04-18  9:57     ` Jonathan Cameron
  0 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-18  9:57 UTC (permalink / raw)
  To: Hennerich, Michael; +Cc: linux-iio, device-drivers-devel, Drivers

On 04/18/11 08:52, Hennerich, Michael wrote:
> Jonathan Cameron wrote on 2011-04-17:
>> 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.
> 
> Typo below "adis16203_consumer%d"
Doh!  I wonder how many times I forgot to update that one.  Time for some grepping.

> Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Thanks.
> 
>>
>> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
>> ---
>>  drivers/staging/iio/adc/ad7606_ring.c |   27 +++++++++++++++++++++----
> 
> Greetings,
> Michael
> 
> --
> Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
> Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368; Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin, Margaret Seif
> 
> 
> 


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

* Re: [PATCH 53/70] staging:iio: Add core attribute handling for name of device.
  2011-04-17 20:06   ` Jonathan Cameron
@ 2011-04-18 12:17     ` Jonathan Cameron
  0 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-18 12:17 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On 04/17/11 21:06, Jonathan Cameron wrote:
> On 04/17/11 20:06, Jonathan Cameron wrote:
>> Saves on a fair bit of code replication.
> I clearly didn't think this through properly.  It can be done much
> more neatly with a single static iio_dev_attr and just explicitly
> adding and removing it.  See the trigger equivalent in the
> iio-onwards tree that I have just pushed.
> 
The following is how I 'should' have done it.

Subject: [PATCH] staging:iio: Add core attribute handling for name of device.

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 b818f5f..febf20e 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -231,7 +231,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 2e2e51d..8ee8f40 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -611,6 +611,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;
@@ -638,8 +648,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) {
@@ -657,6 +674,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] 77+ messages in thread

* Re: [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers
  2011-04-17 19:06 ` [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
@ 2011-04-21 16:51   ` Jonathan Cameron
  2011-04-26 15:10     ` Jonathan Cameron
  0 siblings, 1 reply; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-21 16:51 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

Change of plan here.

It's perfectly possible, (but somewhat under utilized) to call irq_alloc_descs
to give us a dynamically allocated range of irq's. It may be dependant on sparse irq
though so will need to look into that or provide alternative method such
as this one.
> fix to merge back for the incorrect multiple trigger handling
> 
> 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/Makefile                      |    2 +-
>  drivers/staging/iio/Kconfig                   |   12 ++
>  drivers/staging/iio/Makefile                  |    2 +
>  drivers/staging/iio/iio-board-info.h          |   24 +++
>  drivers/staging/iio/iio-core.h                |   13 ++
>  drivers/staging/iio/industrialio-board-info.c |   25 +++
>  drivers/staging/iio/industrialio-trigger.c    |  200 +++++++++++++++++++++----
>  drivers/staging/iio/trigger.h                 |   57 +++++++-
>  8 files changed, 298 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
> index eb93012..0955c7c 100644
> --- a/drivers/staging/Makefile
> +++ b/drivers/staging/Makefile
> @@ -41,7 +41,7 @@ obj-$(CONFIG_VT6656)		+= vt6656/
>  obj-$(CONFIG_HYPERV)		+= hv/
>  obj-$(CONFIG_VME_BUS)		+= vme/
>  obj-$(CONFIG_DX_SEP)            += sep/
> -obj-$(CONFIG_IIO)		+= iio/
> +obj-y				+= iio/
>  obj-$(CONFIG_CS5535_GPIO)	+= cs5535_gpio/
>  obj-$(CONFIG_ZRAM)		+= zram/
>  obj-$(CONFIG_XVMALLOC)		+= zram/
> diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
> index 6775bf9..df9aa08 100644
> --- a/drivers/staging/iio/Kconfig
> +++ b/drivers/staging/iio/Kconfig
> @@ -12,6 +12,10 @@ menuconfig IIO
>  	  Documentation/industrialio for more information.
>  if IIO
>  
> +config IIO_BOARDINFO
> +       boolean
> +       default y
> +
>  config IIO_RING_BUFFER
>  	bool "Enable ring buffer support within IIO"
>  	help
> @@ -42,12 +46,20 @@ endif # IIO_RINGBUFFER
>  
>  config IIO_TRIGGER
>  	boolean "Enable triggered sampling support"
> +	depends on IIO_BOARDINFO
>  	help
>  	  Provides IIO core support for triggers.  Currently these
>  	  are used to initialize capture of samples to push into
>  	  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/Makefile b/drivers/staging/iio/Makefile
> index bb5c95c..37b4d12 100644
> --- a/drivers/staging/iio/Makefile
> +++ b/drivers/staging/iio/Makefile
> @@ -2,6 +2,8 @@
>  # Makefile for the industrial I/O core.
>  #
>  
> +obj-$(CONFIG_IIO_BOARDINFO) += industrialio-board-info.o
> +
>  obj-$(CONFIG_IIO) += industrialio.o
>  industrialio-y := industrialio-core.o
>  industrialio-$(CONFIG_IIO_RING_BUFFER) += industrialio-ring.o
> diff --git a/drivers/staging/iio/iio-board-info.h b/drivers/staging/iio/iio-board-info.h
> new file mode 100644
> index 0000000..c608a4d
> --- /dev/null
> +++ b/drivers/staging/iio/iio-board-info.h
> @@ -0,0 +1,24 @@
> +/*
> + * Board information for IIO.
> + *
> + * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifdef CONFIG_IIO_BOARDINFO
> +
> +/**
> + * iio_set_irq_pool() - provid iio with a pool of virtaul interrupts to use
> + * @start: start of the pool
> + * @num: number of interupts in the pool
> + **/
> +void iio_set_irq_pool(int start, int num);
> +
> +#else
> +
> +static inline void iio_set_irq_pool(int start, int num) {};
> +
> +#endif
> diff --git a/drivers/staging/iio/iio-core.h b/drivers/staging/iio/iio-core.h
> new file mode 100644
> index 0000000..2c4f433
> --- /dev/null
> +++ b/drivers/staging/iio/iio-core.h
> @@ -0,0 +1,13 @@
> +/*
> + * IIO core header. Should never be included by drivers.
> + *
> + * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define IIO_MAX_POOL 128
> +extern int __iio_irqstart;
> +extern int __iio_irqnum;
> diff --git a/drivers/staging/iio/industrialio-board-info.c b/drivers/staging/iio/industrialio-board-info.c
> new file mode 100644
> index 0000000..28f9156
> --- /dev/null
> +++ b/drivers/staging/iio/industrialio-board-info.c
> @@ -0,0 +1,25 @@
> +/* IIO Board info
> + *
> + * Copyright (c) 2011 Jonathan Cameron
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include "iio-core.h"
> +
> +int __iio_irqstart;
> +EXPORT_SYMBOL(__iio_irqstart);
> +int __iio_irqnum;
> +EXPORT_SYMBOL(__iio_irqnum);
> +
> +void __init iio_set_irq_pool(int start, int num)
> +{
> +	__iio_irqstart = start;
> +	__iio_irqnum = num;
> +	if (num > IIO_MAX_POOL)
> +		__iio_irqnum = IIO_MAX_POOL;
> +}
> diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
> index 083847c..9ccc789 100644
> --- a/drivers/staging/iio/industrialio-trigger.c
> +++ b/drivers/staging/iio/industrialio-trigger.c
> @@ -19,6 +19,7 @@
>  #include "iio.h"
>  #include "trigger.h"
>  #include "trigger_consumer.h"
> +#include "iio-core.h"
>  
>  /* RFC - Question of approach
>   * Make the common case (single sensor single trigger)
> @@ -38,6 +39,31 @@ static DEFINE_SPINLOCK(iio_trigger_idr_lock);
>  static LIST_HEAD(iio_trigger_list);
>  static DEFINE_MUTEX(iio_trigger_list_lock);
>  
> +static DEFINE_MUTEX(iio_irq_pool_lock);
> +static unsigned long iio_irq_pool_mask[BITS_TO_LONGS(IIO_MAX_POOL)] = {};
> +
> +static int iio_irq_pool_get_range(int num)
> +{
> +	int ret;
> +
> +	mutex_lock(&iio_irq_pool_lock);
> +	ret = bitmap_find_free_region(iio_irq_pool_mask,
> +				      __iio_irqnum, ilog2(num));
> +	if (ret >= 0)
> +		ret += __iio_irqstart;
> +	mutex_unlock(&iio_irq_pool_lock);
> +
> +	return ret;
> +}
> +
> +static void iio_irq_pool_put_range(int start, int num)
> +{
> +	mutex_lock(&iio_irq_pool_lock);
> +	bitmap_release_region(iio_irq_pool_mask,
> +			      start - __iio_irqstart, ilog2(num));
> +	mutex_unlock(&iio_irq_pool_lock);
> +}
> +
>  /**
>   * iio_trigger_register_sysfs() - create a device for this trigger
>   * @trig_info:	the trigger
> @@ -163,6 +189,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 +205,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 +253,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 +289,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 +412,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);
> +		}
> +
> +		iio_irq_pool_put_range(trig->subirq_base,
> +				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
> +	}
>  	kfree(trig);
>  	iio_put();
>  }
> @@ -345,11 +436,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 +467,40 @@ 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
> +				= iio_irq_pool_get_range(
> +					CONFIG_IIO_CONSUMERS_PER_TRIGGER);
> +			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_ */

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

* Re: [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers
  2011-04-21 16:51   ` Jonathan Cameron
@ 2011-04-26 15:10     ` Jonathan Cameron
  0 siblings, 0 replies; 77+ messages in thread
From: Jonathan Cameron @ 2011-04-26 15:10 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On 04/21/11 17:51, Jonathan Cameron wrote:
> Change of plan here.
> 
> It's perfectly possible, (but somewhat under utilized) to call irq_alloc_descs
> to give us a dynamically allocated range of irq's. It may be dependant on sparse irq
> though so will need to look into that or provide alternative method such
> as this one.

New implementation using that approach is now available in the iio-onwards tree.
Please take a look.  I'd like to start pushing some of this tree
out to Greg asap as it would be good to have it place for a while pre
merge window opening.  I'll be posting a new revision of the whole set
sometime in the next few days.  Before then I'm trying to squash the remaining
build issues with a few drivers.

Jonathan
>> fix to merge back for the incorrect multiple trigger handling
>>
>> 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/Makefile                      |    2 +-
>>  drivers/staging/iio/Kconfig                   |   12 ++
>>  drivers/staging/iio/Makefile                  |    2 +
>>  drivers/staging/iio/iio-board-info.h          |   24 +++
>>  drivers/staging/iio/iio-core.h                |   13 ++
>>  drivers/staging/iio/industrialio-board-info.c |   25 +++
>>  drivers/staging/iio/industrialio-trigger.c    |  200 +++++++++++++++++++++----
>>  drivers/staging/iio/trigger.h                 |   57 +++++++-
>>  8 files changed, 298 insertions(+), 37 deletions(-)
>>
>> diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
>> index eb93012..0955c7c 100644
>> --- a/drivers/staging/Makefile
>> +++ b/drivers/staging/Makefile
>> @@ -41,7 +41,7 @@ obj-$(CONFIG_VT6656)		+= vt6656/
>>  obj-$(CONFIG_HYPERV)		+= hv/
>>  obj-$(CONFIG_VME_BUS)		+= vme/
>>  obj-$(CONFIG_DX_SEP)            += sep/
>> -obj-$(CONFIG_IIO)		+= iio/
>> +obj-y				+= iio/
>>  obj-$(CONFIG_CS5535_GPIO)	+= cs5535_gpio/
>>  obj-$(CONFIG_ZRAM)		+= zram/
>>  obj-$(CONFIG_XVMALLOC)		+= zram/
>> diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
>> index 6775bf9..df9aa08 100644
>> --- a/drivers/staging/iio/Kconfig
>> +++ b/drivers/staging/iio/Kconfig
>> @@ -12,6 +12,10 @@ menuconfig IIO
>>  	  Documentation/industrialio for more information.
>>  if IIO
>>  
>> +config IIO_BOARDINFO
>> +       boolean
>> +       default y
>> +
>>  config IIO_RING_BUFFER
>>  	bool "Enable ring buffer support within IIO"
>>  	help
>> @@ -42,12 +46,20 @@ endif # IIO_RINGBUFFER
>>  
>>  config IIO_TRIGGER
>>  	boolean "Enable triggered sampling support"
>> +	depends on IIO_BOARDINFO
>>  	help
>>  	  Provides IIO core support for triggers.  Currently these
>>  	  are used to initialize capture of samples to push into
>>  	  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/Makefile b/drivers/staging/iio/Makefile
>> index bb5c95c..37b4d12 100644
>> --- a/drivers/staging/iio/Makefile
>> +++ b/drivers/staging/iio/Makefile
>> @@ -2,6 +2,8 @@
>>  # Makefile for the industrial I/O core.
>>  #
>>  
>> +obj-$(CONFIG_IIO_BOARDINFO) += industrialio-board-info.o
>> +
>>  obj-$(CONFIG_IIO) += industrialio.o
>>  industrialio-y := industrialio-core.o
>>  industrialio-$(CONFIG_IIO_RING_BUFFER) += industrialio-ring.o
>> diff --git a/drivers/staging/iio/iio-board-info.h b/drivers/staging/iio/iio-board-info.h
>> new file mode 100644
>> index 0000000..c608a4d
>> --- /dev/null
>> +++ b/drivers/staging/iio/iio-board-info.h
>> @@ -0,0 +1,24 @@
>> +/*
>> + * Board information for IIO.
>> + *
>> + * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#ifdef CONFIG_IIO_BOARDINFO
>> +
>> +/**
>> + * iio_set_irq_pool() - provid iio with a pool of virtaul interrupts to use
>> + * @start: start of the pool
>> + * @num: number of interupts in the pool
>> + **/
>> +void iio_set_irq_pool(int start, int num);
>> +
>> +#else
>> +
>> +static inline void iio_set_irq_pool(int start, int num) {};
>> +
>> +#endif
>> diff --git a/drivers/staging/iio/iio-core.h b/drivers/staging/iio/iio-core.h
>> new file mode 100644
>> index 0000000..2c4f433
>> --- /dev/null
>> +++ b/drivers/staging/iio/iio-core.h
>> @@ -0,0 +1,13 @@
>> +/*
>> + * IIO core header. Should never be included by drivers.
>> + *
>> + * Copyright (c) 2011 Jonathan Cameron <jic23@cam.ac.uk>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#define IIO_MAX_POOL 128
>> +extern int __iio_irqstart;
>> +extern int __iio_irqnum;
>> diff --git a/drivers/staging/iio/industrialio-board-info.c b/drivers/staging/iio/industrialio-board-info.c
>> new file mode 100644
>> index 0000000..28f9156
>> --- /dev/null
>> +++ b/drivers/staging/iio/industrialio-board-info.c
>> @@ -0,0 +1,25 @@
>> +/* IIO Board info
>> + *
>> + * Copyright (c) 2011 Jonathan Cameron
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include "iio-core.h"
>> +
>> +int __iio_irqstart;
>> +EXPORT_SYMBOL(__iio_irqstart);
>> +int __iio_irqnum;
>> +EXPORT_SYMBOL(__iio_irqnum);
>> +
>> +void __init iio_set_irq_pool(int start, int num)
>> +{
>> +	__iio_irqstart = start;
>> +	__iio_irqnum = num;
>> +	if (num > IIO_MAX_POOL)
>> +		__iio_irqnum = IIO_MAX_POOL;
>> +}
>> diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
>> index 083847c..9ccc789 100644
>> --- a/drivers/staging/iio/industrialio-trigger.c
>> +++ b/drivers/staging/iio/industrialio-trigger.c
>> @@ -19,6 +19,7 @@
>>  #include "iio.h"
>>  #include "trigger.h"
>>  #include "trigger_consumer.h"
>> +#include "iio-core.h"
>>  
>>  /* RFC - Question of approach
>>   * Make the common case (single sensor single trigger)
>> @@ -38,6 +39,31 @@ static DEFINE_SPINLOCK(iio_trigger_idr_lock);
>>  static LIST_HEAD(iio_trigger_list);
>>  static DEFINE_MUTEX(iio_trigger_list_lock);
>>  
>> +static DEFINE_MUTEX(iio_irq_pool_lock);
>> +static unsigned long iio_irq_pool_mask[BITS_TO_LONGS(IIO_MAX_POOL)] = {};
>> +
>> +static int iio_irq_pool_get_range(int num)
>> +{
>> +	int ret;
>> +
>> +	mutex_lock(&iio_irq_pool_lock);
>> +	ret = bitmap_find_free_region(iio_irq_pool_mask,
>> +				      __iio_irqnum, ilog2(num));
>> +	if (ret >= 0)
>> +		ret += __iio_irqstart;
>> +	mutex_unlock(&iio_irq_pool_lock);
>> +
>> +	return ret;
>> +}
>> +
>> +static void iio_irq_pool_put_range(int start, int num)
>> +{
>> +	mutex_lock(&iio_irq_pool_lock);
>> +	bitmap_release_region(iio_irq_pool_mask,
>> +			      start - __iio_irqstart, ilog2(num));
>> +	mutex_unlock(&iio_irq_pool_lock);
>> +}
>> +
>>  /**
>>   * iio_trigger_register_sysfs() - create a device for this trigger
>>   * @trig_info:	the trigger
>> @@ -163,6 +189,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 +205,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 +253,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 +289,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 +412,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);
>> +		}
>> +
>> +		iio_irq_pool_put_range(trig->subirq_base,
>> +				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
>> +	}
>>  	kfree(trig);
>>  	iio_put();
>>  }
>> @@ -345,11 +436,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 +467,40 @@ 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
>> +				= iio_irq_pool_get_range(
>> +					CONFIG_IIO_CONSUMERS_PER_TRIGGER);
>> +			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_ */
> 
> 


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

end of thread, other threads:[~2011-04-26 15:08 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-17 19:05 [PATCH 00/70] IIO: Major rework set (review request) Jonathan Cameron
2011-04-17 19:05 ` [PATCH 01/70] staging:iio: allow channels to be set up using a table of iio_channel_spec structures Jonathan Cameron
2011-04-17 19:05 ` [PATCH 02/70] staging:iio:lis3l02dq - move to new channel_spec approach Jonathan Cameron
2011-04-17 19:05 ` [PATCH 03/70] staging:iio:max1363 - move to channel_spec registration Jonathan Cameron
2011-04-17 19:05 ` [PATCH 04/70] staging:iio: remove ability to escalate events Jonathan Cameron
2011-04-17 19:05 ` [PATCH 05/70] staging:iio: Add polling of events on the ring access chrdev Jonathan Cameron
2011-04-17 19:05 ` [PATCH 06/70] staging:iio: remove legacy event chrdev for the buffers Jonathan Cameron
2011-04-17 19:05 ` [PATCH 07/70] staging:iio: Buffer device flattening Jonathan Cameron
2011-04-17 19:05 ` [PATCH 08/70] staging:iio:lis3l02dq: General cleanup Jonathan Cameron
2011-04-17 19:05 ` [PATCH 09/70] staging:iio: Push interrupt setup down into the drivers for event lines Jonathan Cameron
2011-04-17 19:05 ` [PATCH 10/70] staging:iio: lis3l02dq - separate entirely interrupt handling for thesholds from that for the datardy signal Jonathan Cameron
2011-04-17 19:05 ` [PATCH 11/70] staging:iio:sca3000 extract old event handling and move to poll for events from buffer Jonathan Cameron
2011-04-17 19:05 ` [PATCH 12/70] staging:iio:buffering remove unused parameter dead_offset from read_last_n in all buffer implementations Jonathan Cameron
2011-04-17 19:05 ` [PATCH 13/70] staging:iio:light:tsl2563 remove old style event registration Jonathan Cameron
2011-04-17 19:05 ` [PATCH 14/70] staging:iio:dac:ad5504 move from old to new event handling Jonathan Cameron
2011-04-17 19:05 ` [PATCH 15/70] staging:iio:adt7316 get rid of legacy event handling code Jonathan Cameron
2011-04-17 19:05 ` [PATCH 16/70] staging:iio:adc:ad7745 move from old to current event handling Jonathan Cameron
2011-04-17 19:05 ` [PATCH 17/70] staging:iio:adc:ad7816 " Jonathan Cameron
2011-04-17 19:05 ` [PATCH 18/70] staging:iio:adc:ad7150 move from deprecated " Jonathan Cameron
2011-04-17 19:05 ` [PATCH 19/70] staging:iio:adc:ad7152 remove unregister of interrupt line Jonathan Cameron
2011-04-17 19:05 ` [PATCH 20/70] staging:iio:adc:adt75 old to new event handling conversion Jonathan Cameron
2011-04-17 19:05 ` [PATCH 21/70] staging:iio:ad7291 move from old event system to current Jonathan Cameron
2011-04-17 19:05 ` [PATCH 22/70] staging:iio:adc:adt7410 move to current event handling Jonathan Cameron
2011-04-17 19:05 ` [PATCH 23/70] staging:iio:adt7310 " Jonathan Cameron
2011-04-17 19:05 ` [PATCH 24/70] staging:iio:adc:ad7314 remove unmatched unregister of event line Jonathan Cameron
2011-04-17 19:05 ` [PATCH 25/70] staging:iio:ad799x move to new event handling Jonathan Cameron
2011-04-17 19:05 ` [PATCH 26/70] staging:iio: Remove legacy " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 27/70] staging:iio:lis3l02dq make threshold interrupt threaded Jonathan Cameron
2011-04-17 19:06 ` [PATCH 28/70] staging:iio: Add infrastructure for irq_chip based triggers Jonathan Cameron
2011-04-21 16:51   ` Jonathan Cameron
2011-04-26 15:10     ` Jonathan Cameron
2011-04-17 19:06 ` [PATCH 29/70] staging:iio:Documentation generic_buffer.c update to new abi for buffers + misc fixes Jonathan Cameron
2011-04-17 19:06 ` [PATCH 30/70] staging:iio:ring_sw add function needed for threaded irq Jonathan Cameron
2011-04-17 19:06 ` [PATCH 31/70] staging:iio: add generic data ready poll function Jonathan Cameron
2011-04-17 19:06 ` [PATCH 32/70] staging:iio:lis3l02dq move to threaded trigger handling Jonathan Cameron
2011-04-17 19:06 ` [PATCH 33/70] staging:iio:max1363 move to irqchip based threaded irq triggering Jonathan Cameron
2011-04-17 19:06 ` [PATCH 34/70] staging:iio:ad7476 use channel_spec Jonathan Cameron
2011-04-17 19:06 ` [PATCH 35/70] staging:iio:ad7476 move to irqchip based triggering Jonathan Cameron
2011-04-17 19:06 ` [PATCH 36/70] staging:iio:meter:ade7758 move to irqchip based trigger handling Jonathan Cameron
2011-04-17 19:06 ` [PATCH 37/70] staging:iio:adis16400 move to irq based triggers and channel spec channel registration Jonathan Cameron
2011-04-17 19:06 ` [PATCH 38/70] staging:iio:imu:adis16350 etc support into adis16400 driver Jonathan Cameron
2011-04-17 19:06 ` [PATCH 39/70] staging:iio:imu remove old adis16350. Support now in " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 40/70] staging:iio:imu:adis16400 add support for adis16300 Jonathan Cameron
2011-04-17 19:06 ` [PATCH 41/70] staging:iio:imu remove adis16300 driver Jonathan Cameron
2011-04-17 19:06 ` [PATCH 42/70] staging:iio:accel:adis16201 move to irqchip based trigger handling Jonathan Cameron
2011-04-17 19:06 ` [PATCH 43/70] staging:iio:accel:adis16203 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 44/70] staging:iio:accel:adis16204 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 45/70] staging:iio:accel:adis16209 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 46/70] staging:iio:accel:adis16240 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 47/70] staging:iio:adc:ad7298 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 48/70] staging:iio:ad7606 conversion to irq_chip based polling Jonathan Cameron
2011-04-18  7:52   ` Hennerich, Michael
2011-04-18  9:57     ` Jonathan Cameron
2011-04-17 19:06 ` [PATCH 49/70] staging:iio:adc:ad7887 move to irqchip based trigger handling Jonathan Cameron
2011-04-17 19:06 ` [PATCH 50/70] staging:iio:adc:ad799x " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 51/70] staging:iio:gyro:adis16260 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 52/70] staging:iio:trigger remove legacy pollfunc elements Jonathan Cameron
2011-04-17 19:06 ` [PATCH 53/70] staging:iio: Add core attribute handling for name of device Jonathan Cameron
2011-04-17 20:06   ` Jonathan Cameron
2011-04-18 12:17     ` Jonathan Cameron
2011-04-17 19:06 ` [PATCH 54/70] staging:iio: use the new central name attribute creation code Jonathan Cameron
2011-04-17 19:06 ` [PATCH 55/70] staging:iio:accel:adis16201 move to chan_spec based setup Jonathan Cameron
2011-04-17 19:06 ` [PATCH 56/70] staging:iio:accel:adis16203 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 57/70] staging:iio:accel:adis16204 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 58/70] staging:iio:accel:adis16209 " Jonathan Cameron
2011-04-17 19:06 ` [PATCH 59/70] staging:iio:accel: lis3l02dq add writing for calibscale and calibbias Jonathan Cameron
2011-04-17 19:06 ` [PATCH 60/70] staging:iio: Add chan info support for 'peak_raw' attributes Jonathan Cameron
2011-04-17 19:06 ` [PATCH 61/70] staging:iio:accel:adis16240 move to chan_spec based setup Jonathan Cameron
2011-04-17 19:06 ` [PATCH 62/70] staging:iio: Add angl parameters to the chan spec code Jonathan Cameron
2011-04-17 19:06 ` [PATCH 63/70] staging:iio:gyro:adis16260 move to chan_spec based setup Jonathan Cameron
2011-04-17 19:06 ` [PATCH 64/70] staging:iio: rip out scan_el attributes. Now handled as iio_dev_attrs like everything else Jonathan Cameron
2011-04-17 19:06 ` [PATCH 65/70] staging:iio:max1363 trivial removal of unused trig pointer Jonathan Cameron
2011-04-17 19:06 ` [PATCH 66/70] staging:iio:max1363 add new 2 channels parts form maxim, 11644-7 Jonathan Cameron
2011-04-17 19:06 ` [PATCH 67/70] staging:iio:trigger sysfs userspace trigger rework Jonathan Cameron
2011-04-17 19:06 ` [PATCH 68/70] staging:iio:core clean out unused elements Jonathan Cameron
2011-04-17 19:06 ` [PATCH 69/70] staging:iio:buffer - remove unused event code for buffer events Jonathan Cameron
2011-04-17 19:06 ` [PATCH 70/70] staging:iio:lis3l02dq remerge the two interrupt handlers Jonathan Cameron

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.