Linux IIO development
 help / color / mirror / Atom feed
* [IIO] Cleanup userspace
@ 2010-08-27  8:57 Manuel Stahl
       [not found] ` <4C77AC01.3090204@cam.ac.uk>
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-27  8:57 UTC (permalink / raw)
  To: Jonathan Cameron, Song, Barry; +Cc: linux-iio, uclinux-dist-devel


[-- Attachment #1.1: Type: text/plain, Size: 1710 bytes --]

Hi guys,

I updated my drivers and the iio_utils to the current state in linux 
staging and I must say I'm still not very satisfied with the userspace 
ABI. Maybe we can clean this up until more drivers get into staging and 
would have to be restructured accordingly.

The points I'd like to clean up are:
- We currently have plenty of (optional) information per channel:
   * the raw value
   * an offset and scale to apply in user software
   * calibration offset and gain applied in the device
   * enable and bit size (not implemented yet) in the ring buffer

   Should we put all that stuff into a channel directory?
   |- /sys/bus/iio/device0/accel_x/
      |- raw_value
      |- offset
      |- scale
      |- calib_offset
      |- calib_scale
   The enable and bit size are maybe buffer specific and could go
   into the buffer directory.

- The trigger is also an iio device so I'd prefer to have:
   |- /sys/bus/iio/iio0 (can be empty, if it's a pure trigger)
   |- /sys/bus/iio/iio0:trigger0

- Consitent names in ABI and code:
   * bps: 'bits per sample' or 'bytes per scan'?
   * bpd: 'bytes per datum' but named bps in user space

- Endianess of the buffers:
   * Device specific? Then we need a sysfs file to publish this info.
   * CPU native byte order?
   * Network byte order?
   * Allow packed buffers for samples with fractional sizes?

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #1.2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 6148 bytes --]

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

* Re: [IIO] Cleanup userspace
       [not found]   ` <4C77B68B.4060805@iis.fraunhofer.de>
@ 2010-08-27 14:24     ` Jonathan Cameron
  2010-08-27 14:31       ` Manuel Stahl
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-27 14:24 UTC (permalink / raw)
  To: Manuel Stahl, Song, Barry
  Cc: linux-iio@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org

Hi Manuel,
> 
> Am 27.08.2010 14:13, schrieb Jonathan Cameron:
>>>
>>> The points I'd like to clean up are:
>>> - We currently have plenty of (optional) information per channel:
>>>    * the raw value
>>>    * an offset and scale to apply in user software
>>>    * calibration offset and gain applied in the device
>>>    * enable and bit size (not implemented yet) in the ring buffer
>>>
>>>    Should we put all that stuff into a channel directory?
>>>    |- /sys/bus/iio/device0/accel_x/
>>>       |- raw_value
>>>       |- offset
>>>       |- scale
>>>       |- calib_offset
>>>       |- calib_scale
>> Maybe...
>>
>> The disadvantages are:
>> * Breaks the abi compatibility we have been trying to maintain with hwmon.
>> * Lots more attribute groups (actually this is an advantage in some places where
>>    we have a driver covering devices with different numbers of channels)
>> * Cannot share attributes of the above types - e.g. often the offset and scale
>>    apply to all channels.  The abi allows this to be specified by a single attribute.
>>    It also allows say all acceleration offsets to be given by simply accel_offset.
> Actually we still could have these shared files or a shared directory:
>     |- /sys/bus/iio/device0/accel/
>        |- offset
>        |- scale
>     |- /sys/bus/iio/device0/accel_x/
>        |- raw_value
>     |- /sys/bus/iio/device0/accel_y/
>        |- raw_value
> 
> Not that nice, I have to agree. Another idea would be to use some other separator, like ':'. Then it's also clear for the human user, what's the name and what's the postfix:
>     |- /sys/bus/iio/device0/accel_x:raw
>     |- /sys/bus/iio/device0/accel_x:offset
>     |- /sys/bus/iio/device0/accel_x:scale
That would be nice, but breaks with hwmon style...  Given average user is going to be using your tools anyway
I don't think this being that readable is critical.
> 
> 
>> Advantages:
>> * It looks nicer to a human reader. (though anyone can deploy "ls *accel_x*" to get much the same.
>> * Possibly some minor simplifications in library code. (fairly trivial I would expect?)
> 
> Yes, that's not too complicated now. We just have to define the postfixes somewhere. Right now, adis16400 uses _offset for the internal calibration offset and _scale for user space scaling.
> 
>> Note that a similar level of complexity exists for the event interfaces.
>> ..zip..
> 
> I'm not so familiar with the event stuff, but I don't think we need
> to make it consistent, if there are different arguments for the one
> or the other solution. Yet we should use the same seperator, so if we
> switch to ':' in the channels, we should also switch in the event
> interface.
Firstly, the situation is so similar I think we would need to change both
just to avoid confusion from anyone looking at the files.  Also I'd imagine
it will allow some code to be shared in the userspace utils.

Second, I still think the issues with breaking hwmon consistency make this a bad idea
(and that stuff is from Greg KH + I think Andrew Morton is in favour of such unifying
based on discussions elswhere)  Keep both of them happy is going to make our eventual
move out of staging easier.
> 
> 
>>>    The enable and bit size are maybe buffer specific and could go
>>>    into the buffer directory.
>> We could do this now I guess (couldn't before the max1363 was switched to the current abi)
>>
>> As things currently stand these are in iio:device[n]/scan_elements. I guess we could move
>> them into iio:device[n]/buffer0  It is a bit of a pain in code as the buffer directory is
>> completely managed by the buffer implementation rather than the driver. Still I guess this
>> could be passed to the buffer initialization code.  Things are a bit tricky as there are
>> other attributes caused by the buffer it self. It cleans up the abi at the cost of further
>> messing up the separation between buffer implementation and device driver and some complexity
>> in driver.  It would be easier to move the scan_elements directory into the buffer directory?
>> Perhaps that is the better option?
>> What do others think on this?
> 
> I have no problem with moving the whole directory.
Cool.  I'll have a look to see how clean we can make the move.  It is going to break
a lot of drivers in the Analog devices tree so it might be worth delaying it for now
(perhaps updating the abi and saying the old location is deprecated).
> 
>>> - The trigger is also an iio device so I'd prefer to have:
>>>    |- /sys/bus/iio/iio0 (can be empty, if it's a pure trigger)
>>>    |- /sys/bus/iio/iio0:trigger0
>> I did think about this one (note it was marked as to be considered in the last abi
>> discussion). The only reason to have the iio0 directory is if it tells us
>> something.  Currently the iio:device0 is the top level device.
>> Is your intent that iio0 will have children of iio0:device0 and iio0:trigger0 etc?
>> Thus it won't be empty under any circumstances. It will always contain at least
>> iio0:device0 or iio0:trigger0
> 
> I just thought of renaming device<n> to iio<n> but we can also move the whole device directory. In 'lsiio' I have a structure like:
Ah, fair enough. Ah. I see you proposed the name change in a previous email to the list.  Sorry
as stated below my subscription clearly died for a few days! To what you state there I'd
rather we just added iio: to the beginning of all the naming. 

The question that arises is whether triggers and the base device should be at the same
level as it is perfectly possible to have a driver implementing one and not the other.
Perhaps we do want to introduce a top level grouping above them both?  So have iio[n]
containing either or both of trigger0 and device0 with the names under dev being
iio3:device0:buffer0:access0 etc?
> 
> Device 000: <name>
>   <channel_group> (if available)
>     <channel>
>         :
>   <channel_group> (if available)
>     <channel>
>         :
> 
>   buffer<n>       (if available)
>     bytes per datum: <bpd>,     length: 64
>     event:  /dev/device0:buffer0:event0
>     access: /dev/device0:buffer0:access0
> 
>   trigger<m>: <trigger_name>  (if available)
> 
> So for a single trigger it would be:
Ah I see.  I don't want to see the gpio triggers sharing a directory.
It implies a connection between them when they are no more connected
than two separate instances of an accelerometer.  The gpios in question
may even be on completely different physical chips.
> 
> # lsiio -v
> Device 000: gpio_trigger
>   trigger0: irqtrig30
>   trigger1: irqtrig45
>   trigger2: irqtrig51
> 
> or in sysfs:
>     |- /sys/bus/iio/iio0/
>        |- name
>        |- iio0:trigger0
>           |- name
>        |- iio0:trigger1
>           |- name
>        |- iio0:trigger2
>           |- name
> 
> 
>>> - Consitent names in ABI and code:
>>>    * bps: 'bits per sample' or 'bytes per scan'?
>> Yup, that's why bpd was introduced in the code.
>>>    * bpd: 'bytes per datum' but named bps in user space
>> Hmm. there does seem to be some confusion still around this.
>> Given we also have bpse (bits per scan element) the confusion gets even worse.
>> Perhaps the right option is to loose the acronyms entirely and have it long hand
>> both in core code (drivers don't really matter for this) and the userspace abi?
> 
> OK, I'll prepare a patch.
Excellent. Beware that these turn up a fair bit in the docs as well.
> 
>>> - Endianess of the buffers:
>>>    * Device specific? Then we need a sysfs file to publish this info.
>>>    * CPU native byte order?
>> It is currently cpu native for all software ring buffers. Agreed this may
>> change and hardware buffers may do either.  So you are quite right, we
>> need an attribute for this.  So I guess we support 3 options, cpu native, big endian,
>> little endian. So what shall we call it?
>>
>> byte_order - [big little native]  Mostly read only, though sooner or later I expect
>> we will get some device that allows this to be controlled.
> 
> Do we really need native? I think the driver can figure out what the native order is, and just give that one (even at compile time).
Good point.
> Another possibility is to let the driver always convert to native.
Bad idea.  In a hw ring buffer case that adds a lot of overhead for straight logging applications where we just want
to store what the data is rather than do anything with it live.
 At least that's what most userspace software want's to have. I recently sent a patch for sca3000 to the linux-iio list.
Strange, those never made it to my inbox.  I'm guessing my iio subscription must have borked.  I'll get them
from the archive.

On those patches, I'm happy to ack the first (not sure when that bug snuck in and I'm not in a possition
to test the fix today).

As per this discussion I'd rather avoid the data munging of the second. That's a job for userspace.
Obviously we'll be needing the stuff you specify below for that though.
> 
>>>    * Allow packed buffers for samples with fractional sizes?
>> Probably not using the current ring buffer. As you say a big issue is how
>> to describe a packed storage particularly if not all of it is packed.
>> (so say 2 x 11 bit readings in 3 bytes - for say a 4 channel device, this is a better
>> bet than packing it tightly into 44 bits.)  So far we haven't had a hardware
>> ring device giving us packed data, but I'm sure one will turn up and force
>> this element sometime in the future.  I think we leave this until a user comes
>> along then pin it down then. I agree it is definitely something we need to consider,
>> just not now!  Still if you want to lay out some guidance for discussion feel
>> free.
> 
> OK, no packed buffers for now, but we should implement variable
> sample sizes for standard types. Indeed we already have this for the
> timestamp, which is always 64 bit.

Agreed. These ought to be in there and will be needed 

> To be compatible with future extensions we could have:
>   |- /sys/bus/iio/ii0/buffer0/scan_elements/
>      |- accel_x:en    (0 or 1)
>      |- accel_x:type  (i.e. s14/16, see *)
>      |- accel_x:index
> 

> * s14/16 means signed 14 bits, stored in 16 bits, right aligned. If
> it's left aligned we can just modify the scale attribute and give the
> 16 bit interpretation in <channel>:raw.
That is quite a neat way of doing it though I'm not sure 'type' is the
ideal name.  My immediate thought is that type would be 'acceleration'!
We definitely want this on list.  We'd also want to drop the precision
attribute as that will just confuse things.

> I don't like the index prefix any more, even I had proposed this
> once. This is because for devices with more than 10 channels
> (adis16400) we have to get a leading 0 in the name to maintain
> alphabetical sorting, which is nearly impossible with the current
> macros.
Does alphabetical sorting really matter? + Doesn't putting 01 etc
in the macro give the right name?  I thought it was stringified in the
first step (could be wrong, that macro stuff always gives me a headache).
We definitely need the prefix or equivalent so this is worth clearing up.

Thanks,

Jonathan

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

* Re: [IIO] Cleanup userspace
  2010-08-27 14:24     ` Jonathan Cameron
@ 2010-08-27 14:31       ` Manuel Stahl
  2010-08-27 15:09         ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-27 14:31 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Song, Barry, linux-iio@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org


[-- Attachment #1.1: Type: text/plain, Size: 5638 bytes --]

Hi Jonathan,

Am 27.08.2010 16:24, schrieb Jonathan Cameron:

>>> As things currently stand these are in iio:device[n]/scan_elements. I guess we could move
>>> them into iio:device[n]/buffer0  It is a bit of a pain in code as the buffer directory is
>>> completely managed by the buffer implementation rather than the driver. Still I guess this
>>> could be passed to the buffer initialization code.  Things are a bit tricky as there are
>>> other attributes caused by the buffer it self. It cleans up the abi at the cost of further
>>> messing up the separation between buffer implementation and device driver and some complexity
>>> in driver.  It would be easier to move the scan_elements directory into the buffer directory?
>>> Perhaps that is the better option?
>>> What do others think on this?
>>
>> I have no problem with moving the whole directory.
> Cool.  I'll have a look to see how clean we can make the move.  It is going to break
> a lot of drivers in the Analog devices tree so it might be worth delaying it for now
> (perhaps updating the abi and saying the old location is deprecated).

Indeed I did that for the last few hours. A patch is coming on Monday.


>>>> - Endianess of the buffers:
>>>>     * Device specific? Then we need a sysfs file to publish this info.
>>>>     * CPU native byte order?
>>> It is currently cpu native for all software ring buffers. Agreed this may
>>> change and hardware buffers may do either.  So you are quite right, we
>>> need an attribute for this.  So I guess we support 3 options, cpu native, big endian,
>>> little endian. So what shall we call it?
>>>
>>> byte_order - [big little native]  Mostly read only, though sooner or later I expect
>>> we will get some device that allows this to be controlled.
>>
>> Do we really need native? I think the driver can figure out what the native order is, and just give that one (even at compile time).
> Good point.
>> Another possibility is to let the driver always convert to native.
> Bad idea.  In a hw ring buffer case that adds a lot of overhead for straight logging applications where we just want
> to store what the data is rather than do anything with it live.
>   At least that's what most userspace software want's to have. I recently sent a patch for sca3000 to the linux-iio list.
> Strange, those never made it to my inbox.  I'm guessing my iio subscription must have borked.  I'll get them
> from the archive.
>
> On those patches, I'm happy to ack the first (not sure when that bug snuck in and I'm not in a possition
> to test the fix today).
>
> As per this discussion I'd rather avoid the data munging of the second. That's a job for userspace.
> Obviously we'll be needing the stuff you specify below for that though.

OK, will be my next task.

>>> Probably not using the current ring buffer. As you say a big issue is how
>>> to describe a packed storage particularly if not all of it is packed.
>>> (so say 2 x 11 bit readings in 3 bytes - for say a 4 channel device, this is a better
>>> bet than packing it tightly into 44 bits.)  So far we haven't had a hardware
>>> ring device giving us packed data, but I'm sure one will turn up and force
>>> this element sometime in the future.  I think we leave this until a user comes
>>> along then pin it down then. I agree it is definitely something we need to consider,
>>> just not now!  Still if you want to lay out some guidance for discussion feel
>>> free.
>>
>> OK, no packed buffers for now, but we should implement variable
>> sample sizes for standard types. Indeed we already have this for the
>> timestamp, which is always 64 bit.
>
> Agreed. These ought to be in there and will be needed
>
>> To be compatible with future extensions we could have:
>>    |- /sys/bus/iio/ii0/buffer0/scan_elements/
>>       |- accel_x:en    (0 or 1)
>>       |- accel_x:type  (i.e. s14/16, see *)
>>       |- accel_x:index
>>
>
>> * s14/16 means signed 14 bits, stored in 16 bits, right aligned. If
>> it's left aligned we can just modify the scale attribute and give the
>> 16 bit interpretation in <channel>:raw.
> That is quite a neat way of doing it though I'm not sure 'type' is the
> ideal name.  My immediate thought is that type would be 'acceleration'!
> We definitely want this on list.  We'd also want to drop the precision
> attribute as that will just confuse things.

I'm open for any other name.

>> I don't like the index prefix any more, even I had proposed this
>> once. This is because for devices with more than 10 channels
>> (adis16400) we have to get a leading 0 in the name to maintain
>> alphabetical sorting, which is nearly impossible with the current
>> macros.
> Does alphabetical sorting really matter? + Doesn't putting 01 etc
> in the macro give the right name?  I thought it was stringified in the
> first step (could be wrong, that macro stuff always gives me a headache).
> We definitely need the prefix or equivalent so this is worth clearing up.

If it doesn't sort alphabetically, there no point in having a prefix. It 
was thought as a helper for the human user. Currently the number is a 
preprocessor definition and used both as prefix and as number. If 
there's a 0 in front, it will be interpreted as octal number.

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #1.2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 6148 bytes --]

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

* Re: [IIO] Cleanup userspace
  2010-08-27 14:31       ` Manuel Stahl
@ 2010-08-27 15:09         ` Jonathan Cameron
  2010-08-30 10:55           ` [PATCH 1/2] staging:iio rename ring attributes Manuel Stahl
                             ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-27 15:09 UTC (permalink / raw)
  To: Manuel Stahl
  Cc: Song, Barry, linux-iio@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org

...
>>
>> Agreed. These ought to be in there and will be needed
>>
>>> To be compatible with future extensions we could have:
>>>    |- /sys/bus/iio/ii0/buffer0/scan_elements/
>>>       |- accel_x:en    (0 or 1)
>>>       |- accel_x:type  (i.e. s14/16, see *)
>>>       |- accel_x:index
>>>
>>
>>> * s14/16 means signed 14 bits, stored in 16 bits, right aligned. If
>>> it's left aligned we can just modify the scale attribute and give the
>>> 16 bit interpretation in <channel>:raw.
>> That is quite a neat way of doing it though I'm not sure 'type' is the
>> ideal name.  My immediate thought is that type would be 'acceleration'!
>> We definitely want this on list.  We'd also want to drop the precision
>> attribute as that will just confuse things.
> 
> I'm open for any other name.
Lets see if anyone else has a suggestion...
> 
>>> I don't like the index prefix any more, even I had proposed this
>>> once. This is because for devices with more than 10 channels
>>> (adis16400) we have to get a leading 0 in the name to maintain
>>> alphabetical sorting, which is nearly impossible with the current
>>> macros.
>> Does alphabetical sorting really matter? + Doesn't putting 01 etc
>> in the macro give the right name?  I thought it was stringified in the
>> first step (could be wrong, that macro stuff always gives me a headache).
>> We definitely need the prefix or equivalent so this is worth clearing up.
> 
> If it doesn't sort alphabetically, there no point in having a prefix.
> It was thought as a helper for the human user. Currently the number
> is a preprocessor definition and used both as prefix and as number.
> If there's a 0 in front, it will be interpreted as octal number.
Ah. The octal bit hadn't occurred to me.

The prefix isn't for the helper user at all.  It is to tell userspace
code reading from the ring buffer which element is which.  Without it there
is no way userspace can know the order.  Frankly I don't think a human browsing
that directory will care what the ordering in a buffer record is!

Jonathan

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

* [PATCH 1/2] staging:iio rename ring attributes
  2010-08-27 15:09         ` Jonathan Cameron
@ 2010-08-30 10:55           ` Manuel Stahl
  2010-08-30 12:28             ` Jonathan Cameron
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
  2010-09-04 17:26           ` [IIO] Cleanup userspace Jonathan Cameron
  2 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 10:55 UTC (permalink / raw)
  To: linux-iio

bps -> bytes_per_datum
ring_enable -> enable

Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
---
 drivers/staging/iio/accel/adis16209_ring.c |    2 +-
 drivers/staging/iio/accel/adis16240_ring.c |    2 +-
 drivers/staging/iio/accel/lis3l02dq_ring.c |    2 +-
 drivers/staging/iio/accel/sca3000_ring.c   |   10 ++--
 drivers/staging/iio/adc/max1363_ring.c     |    4 +-
 drivers/staging/iio/gyro/adis16260_ring.c  |    2 +-
 drivers/staging/iio/imu/adis16300_ring.c   |    2 +-
 drivers/staging/iio/imu/adis16350_ring.c   |    2 +-
 drivers/staging/iio/imu/adis16400_ring.c   |    2 +-
 drivers/staging/iio/industrialio-ring.c    |    8 ++--
 drivers/staging/iio/ring_generic.h         |   22 +++++-----
 drivers/staging/iio/ring_sw.c              |   58 ++++++++++++++--------------
 drivers/staging/iio/ring_sw.h              |   12 +++---
 13 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 25fde65..d40b95f 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -119,7 +119,7 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index cd69a2e..462d452 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -111,7 +111,7 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index a960a8f..4c1b36a 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -169,7 +169,7 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
 	if (ret < 0)
 		goto error_ret;
 	if (ret) {
-		data = kmalloc(dev_info->ring->access.get_bpd(dev_info->ring),
+		data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
 			       GFP_KERNEL);
 		if (data == NULL)
 			return -ENOMEM;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 8e8c068..eff5b9a 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -100,7 +100,7 @@ static int sca3000_ring_get_length(struct iio_ring_buffer *r)
 }
 
 /* only valid if resolution is kept at 11bits */
-static int sca3000_ring_get_bpd(struct iio_ring_buffer *r)
+static int sca3000_ring_get_bytes_per_datum(struct iio_ring_buffer *r)
 {
 	return 6;
 }
@@ -111,7 +111,7 @@ static void sca3000_ring_release(struct device *dev)
 }
 
 static IIO_RING_ENABLE_ATTR;
-static IIO_RING_BPS_ATTR;
+static IIO_RING_BYTES_PER_DATUM_ATTR;
 static IIO_RING_LENGTH_ATTR;
 
 /**
@@ -218,8 +218,8 @@ static struct attribute_group sca3000_scan_el_group = {
  */
 static struct attribute *sca3000_ring_attributes[] = {
 	&dev_attr_length.attr,
-	&dev_attr_bps.attr,
-	&dev_attr_ring_enable.attr,
+	&dev_attr_bytes_per_datum.attr,
+	&dev_attr_enable.attr,
 	NULL,
 };
 
@@ -272,7 +272,7 @@ int sca3000_configure_ring(struct iio_dev *indio_dev)
 
 	indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
 	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
-	indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd;
+	indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
 
 	return 0;
 }
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 786b17a..edac0ba 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -92,14 +92,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 	max1363_set_scan_mode(st);
 
 	numvals = hweight_long(st->current_mode->modemask);
-	if (indio_dev->ring->access.set_bpd) {
+	if (indio_dev->ring->access.set_bytes_per_datum) {
 		if (st->chip_info->bits != 8)
 			d_size = numvals*2 + sizeof(s64);
 		else
 			d_size = numvals + sizeof(s64);
 		if (d_size % 8)
 			d_size += 8 - (d_size % 8);
-		indio_dev->ring->access.set_bpd(indio_dev->ring, d_size);
+		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
 	}
 
 	return 0;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 9ef7f90..055d5e8 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -114,7 +114,7 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
index fc93160..854183c 100644
--- a/drivers/staging/iio/imu/adis16300_ring.c
+++ b/drivers/staging/iio/imu/adis16300_ring.c
@@ -138,7 +138,7 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
index e053e9a..9620cbe 100644
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -138,7 +138,7 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 949db76..c8e2316 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -147,7 +147,7 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 	int i = 0;
 	s16 *data;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 6ab578e..610c2b6 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -338,20 +338,20 @@ EXPORT_SYMBOL(iio_read_ring_length);
 }
 EXPORT_SYMBOL(iio_write_ring_length);
 
-ssize_t iio_read_ring_bps(struct device *dev,
+ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
 			  struct device_attribute *attr,
 			  char *buf)
 {
 	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	if (ring->access.get_bpd)
+	if (ring->access.get_bytes_per_datum)
 		len = sprintf(buf, "%d\n",
-			      ring->access.get_bpd(ring));
+			      ring->access.get_bytes_per_datum(ring));
 
 	return len;
 }
-EXPORT_SYMBOL(iio_read_ring_bps);
+EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
 
 ssize_t iio_store_ring_enable(struct device *dev,
 			      struct device_attribute *attr,
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index a872d39..ac017b1 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -52,8 +52,8 @@ int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
  *			change.
  * @request_update:	if a parameter change has been marked, update underlying
  *			storage.
- * @get_bpd:		get current bytes per datum
- * @set_bpd:		set number of bytes per datum
+ * @get_bytes_per_datum:		get current bytes per datum
+ * @set_bytes_per_datum:		set number of bytes per datum
  * @get_length:		get number of datums in ring
  * @set_length:		set number of datums in ring
  * @is_enabled:		query if ring is currently being used
@@ -81,8 +81,8 @@ struct iio_ring_access_funcs {
 	int (*mark_param_change)(struct iio_ring_buffer *ring);
 	int (*request_update)(struct iio_ring_buffer *ring);
 
-	int (*get_bpd)(struct iio_ring_buffer *ring);
-	int (*set_bpd)(struct iio_ring_buffer *ring, size_t bpd);
+	int (*get_bytes_per_datum)(struct iio_ring_buffer *ring);
+	int (*set_bytes_per_datum)(struct iio_ring_buffer *ring, size_t bpd);
 	int (*get_length)(struct iio_ring_buffer *ring);
 	int (*set_length)(struct iio_ring_buffer *ring, int length);
 
@@ -99,7 +99,7 @@ struct iio_ring_access_funcs {
  * @id:			unique id number
  * @access_id:		device id number
  * @length:		[DEVICE] number of datums in ring
- * @bpd:		[DEVICE] size of individual datum including timestamp
+ * @bytes_per_datum	[DEVICE] size of individual datum including timestamp
  * @bpe:		[DEVICE] size of individual channel value
  * @loopcount:		[INTERN] number of times the ring has looped
  * @access_handler:	[INTERN] chrdev access handling
@@ -121,7 +121,7 @@ struct iio_ring_buffer {
 	int				id;
 	int				access_id;
 	int				length;
-	int				bpd;
+	int				bytes_per_datum;
 	int				bpe;
 	int				loopcount;
 	struct iio_handler		access_handler;
@@ -146,7 +146,7 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
 					    int bytes_per_datum, int length)
 {
-	ring->bpd = bytes_per_datum;
+	ring->bytes_per_datum = bytes_per_datum;
 	ring->length = length;
 	ring->loopcount = 0;
 }
@@ -277,7 +277,7 @@ ssize_t iio_write_ring_length(struct device *dev,
 			      struct device_attribute *attr,
 			      const char *buf,
 			      size_t len);
-ssize_t iio_read_ring_bps(struct device *dev,
+ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
 			  struct device_attribute *attr,
 			  char *buf);
 ssize_t iio_store_ring_enable(struct device *dev,
@@ -290,9 +290,9 @@ ssize_t iio_show_ring_enable(struct device *dev,
 #define IIO_RING_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR,	\
 					 iio_read_ring_length,		\
 					 iio_write_ring_length)
-#define IIO_RING_BPS_ATTR DEVICE_ATTR(bps, S_IRUGO | S_IWUSR,	\
-				      iio_read_ring_bps, NULL)
-#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(ring_enable, S_IRUGO | S_IWUSR, \
+#define IIO_RING_BYTES_PER_DATUM_ATTR DEVICE_ATTR(bytes_per_datum, S_IRUGO | S_IWUSR,	\
+				      iio_read_ring_bytes_per_datum, NULL)
+#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
 					 iio_show_ring_enable,		\
 					 iio_store_ring_enable)
 #else /* CONFIG_IIO_RING_BUFFER */
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index e2f01c6..99efb6b 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -21,7 +21,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
 	if ((length == 0) || (bytes_per_datum == 0))
 		return -EINVAL;
 	__iio_update_ring_buffer(&ring->buf, bytes_per_datum, length);
-	ring->data = kmalloc(length*ring->buf.bpd, GFP_ATOMIC);
+	ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC);
 	ring->read_p = NULL;
 	ring->write_p = NULL;
 	ring->last_written_p = NULL;
@@ -77,10 +77,10 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 		 * as long as the read pointer is valid before this
 		 * passes it - guaranteed as set later in this function.
 		 */
-		ring->half_p = ring->data - ring->buf.length*ring->buf.bpd/2;
+		ring->half_p = ring->data - ring->buf.length*ring->buf.bytes_per_datum/2;
 	}
 	/* Copy data to where ever the current write pointer says */
-	memcpy(ring->write_p, data, ring->buf.bpd);
+	memcpy(ring->write_p, data, ring->buf.bytes_per_datum);
 	barrier();
 	/* Update the pointer used to get most recent value.
 	 * Always valid as either points to latest or second latest value.
@@ -91,9 +91,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	/* temp_ptr used to ensure we never have an invalid pointer
 	 * it may be slightly lagging, but never invalid
 	 */
-	temp_ptr = ring->write_p + ring->buf.bpd;
+	temp_ptr = ring->write_p + ring->buf.bytes_per_datum;
 	/* End of ring, back to the beginning */
-	if (temp_ptr == ring->data + ring->buf.length*ring->buf.bpd)
+	if (temp_ptr == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
 		temp_ptr = ring->data;
 	/* Update the write pointer
 	 * always valid as long as this is the only function able to write.
@@ -112,9 +112,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	 */
 	else if (ring->write_p == ring->read_p) {
 		change_test_ptr = ring->read_p;
-		temp_ptr = change_test_ptr + ring->buf.bpd;
+		temp_ptr = change_test_ptr + ring->buf.bytes_per_datum;
 		if (temp_ptr
-		    == ring->data + ring->buf.length*ring->buf.bpd) {
+		    == ring->data + ring->buf.length*ring->buf.bytes_per_datum) {
 			temp_ptr = ring->data;
 		}
 		/* We are moving pointer on one because the ring is full.  Any
@@ -135,8 +135,8 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
 	/* There are definite 'issues' with this and chances of
 	 * simultaneous read */
 	/* Also need to use loop count to ensure this only happens once */
-	ring->half_p += ring->buf.bpd;
-	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bpd)
+	ring->half_p += ring->buf.bytes_per_datum;
+	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);
@@ -164,15 +164,15 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
 	 *  read something that is not a whole number of bpds.
 	 * Return an error.
 	 */
-	if (count % ring->buf.bpd) {
+	if (count % ring->buf.bytes_per_datum) {
 		ret = -EINVAL;
 		printk(KERN_INFO "Ring buffer read request not whole number of"
-		       "samples: Request bytes %zd, Current bpd %d\n",
-		       count, ring->buf.bpd);
+		       "samples: Request bytes %zd, Current bytes per datum %d\n",
+		       count, ring->buf.bytes_per_datum);
 		goto error_ret;
 	}
 	/* Limit size to whole of ring buffer */
-	bytes_to_rip = min((size_t)(ring->buf.bpd*ring->buf.length), count);
+	bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), count);
 
 	*data = kmalloc(bytes_to_rip, GFP_KERNEL);
 	if (*data == NULL) {
@@ -214,7 +214,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
 	} else {
 		/* going through 'end' of ring buffer */
 		max_copied = ring->data
-			+ ring->buf.length*ring->buf.bpd - initial_read_p;
+			+ ring->buf.length*ring->buf.bytes_per_datum - initial_read_p;
 		memcpy(*data, initial_read_p, max_copied);
 		/* possible we are done if we align precisely with end */
 		if (max_copied == bytes_to_rip)
@@ -240,7 +240,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
 	if (initial_read_p <= current_read_p)
 		*dead_offset = current_read_p - initial_read_p;
 	else
-		*dead_offset = ring->buf.length*ring->buf.bpd
+		*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
@@ -293,7 +293,7 @@ again:
 	/* Check there is anything here */
 	if (last_written_p_copy == NULL)
 		return -EAGAIN;
-	memcpy(data, last_written_p_copy, ring->buf.bpd);
+	memcpy(data, last_written_p_copy, ring->buf.bytes_per_datum);
 
 	if (unlikely(ring->last_written_p != last_written_p_copy))
 		goto again;
@@ -322,7 +322,7 @@ int iio_request_update_sw_rb(struct iio_ring_buffer *r)
 		goto error_ret;
 	}
 	__iio_free_sw_ring_buffer(ring);
-	ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bpd,
+	ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bytes_per_datum,
 					    ring->buf.length);
 error_ret:
 	spin_unlock(&ring->use_lock);
@@ -330,23 +330,23 @@ error_ret:
 }
 EXPORT_SYMBOL(iio_request_update_sw_rb);
 
-int iio_get_bpd_sw_rb(struct iio_ring_buffer *r)
+int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-	return ring->buf.bpd;
+	return ring->buf.bytes_per_datum;
 }
-EXPORT_SYMBOL(iio_get_bpd_sw_rb);
+EXPORT_SYMBOL(iio_get_bytes_per_datum_sw_rb);
 
-int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd)
+int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
 {
-	if (r->bpd != bpd) {
-		r->bpd = bpd;
+	if (r->bytes_per_datum != bpd) {
+		r->bytes_per_datum = bpd;
 		if (r->access.mark_param_change)
 			r->access.mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_bpd_sw_rb);
+EXPORT_SYMBOL(iio_set_bytes_per_datum_sw_rb);
 
 int iio_get_length_sw_rb(struct iio_ring_buffer *r)
 {
@@ -380,14 +380,14 @@ static void iio_sw_rb_release(struct device *dev)
 }
 
 static IIO_RING_ENABLE_ATTR;
-static IIO_RING_BPS_ATTR;
+static IIO_RING_BYTES_PER_DATUM_ATTR;
 static IIO_RING_LENGTH_ATTR;
 
 /* Standard set of ring buffer attributes */
 static struct attribute *iio_ring_attributes[] = {
 	&dev_attr_length.attr,
-	&dev_attr_bps.attr,
-	&dev_attr_ring_enable.attr,
+	&dev_attr_bytes_per_datum.attr,
+	&dev_attr_enable.attr,
 	NULL,
 };
 
@@ -451,7 +451,7 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 			size = sizeof(s64);
 	else /* Data only */
 		size = indio_dev->scan_count * indio_dev->ring->bpe;
-	indio_dev->ring->access.set_bpd(indio_dev->ring, size);
+	indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
 
 	return 0;
 }
@@ -464,7 +464,7 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
 			work_trigger_to_ring);
 	int len = 0;
 	size_t datasize = st->indio_dev
-		->ring->access.get_bpd(st->indio_dev->ring);
+		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
 	char *data = kmalloc(datasize, GFP_KERNEL);
 
 	if (data == NULL) {
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index 61f1ed6..ad03d83 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -121,19 +121,19 @@ int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
 
 
 /**
- * iio_get_bpd_sw_rb() - get the datum size in bytes
+ * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes
  * @r:		pointer to a software ring buffer created by an
  *		iio_create_sw_rb call
  **/
-int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
+int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_set_bpd_sw_rb() - set the datum size in bytes
+ * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes
  * @r:		pointer to a software ring buffer created by an
  *		iio_create_sw_rb call
  * @bpd:	bytes per datum value
  **/
-int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
+int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd);
 
 /**
  * iio_get_length_sw_rb() - get how many datums the rb may contain
@@ -166,8 +166,8 @@ static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
 	ra->mark_param_change = &iio_mark_update_needed_sw_rb;
 	ra->request_update = &iio_request_update_sw_rb;
 
-	ra->get_bpd = &iio_get_bpd_sw_rb;
-	ra->set_bpd = &iio_set_bpd_sw_rb;
+	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb;
+	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb;
 
 	ra->get_length = &iio_get_length_sw_rb;
 	ra->set_length = &iio_set_length_sw_rb;
-- 
1.7.0.6


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

* [PATCH 2/2] staging:iio move scan_elements into ring buffer
  2010-08-27 15:09         ` Jonathan Cameron
  2010-08-30 10:55           ` [PATCH 1/2] staging:iio rename ring attributes Manuel Stahl
@ 2010-08-30 10:55           ` Manuel Stahl
  2010-08-30 12:58             ` Jonathan Cameron
                               ` (3 more replies)
  2010-09-04 17:26           ` [IIO] Cleanup userspace Jonathan Cameron
  2 siblings, 4 replies; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 10:55 UTC (permalink / raw)
  To: linux-iio


Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
---
 drivers/staging/iio/accel/adis16209_ring.c |   41 ++++++------
 drivers/staging/iio/accel/adis16240_ring.c |   33 +++++-----
 drivers/staging/iio/accel/lis3l02dq_ring.c |   62 +++++++++--------
 drivers/staging/iio/accel/sca3000_ring.c   |    2 +-
 drivers/staging/iio/adc/max1363_core.c     |    1 -
 drivers/staging/iio/adc/max1363_ring.c     |   18 +++--
 drivers/staging/iio/gyro/adis16260_ring.c  |   31 ++++-----
 drivers/staging/iio/iio.h                  |  102 +---------------------------
 drivers/staging/iio/imu/adis16300_ring.c   |   43 ++++++------
 drivers/staging/iio/imu/adis16350_ring.c   |   47 ++++++-------
 drivers/staging/iio/imu/adis16400_ring.c   |   49 +++++++-------
 drivers/staging/iio/industrialio-core.c    |   12 ---
 drivers/staging/iio/industrialio-ring.c    |   28 ++++++--
 drivers/staging/iio/ring_generic.h         |  100 +++++++++++++++++++++++++++
 drivers/staging/iio/ring_sw.c              |   25 ++++---
 15 files changed, 298 insertions(+), 296 deletions(-)

diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index d40b95f..120bf91 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
 	struct adis16209_state *st
 		= container_of(work_s, struct adis16209_state,
 			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-					    (u8 *)data,
-					    st->last_timestamp);
+	ring->access.store_to(ring,
+			      (u8 *)data,
+			      st->last_timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16209_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -182,11 +169,23 @@ 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;
 	ring->predisable = &iio_triggered_ring_predisable;
 	ring->owner = THIS_MODULE;
 
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.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, &adis16209_poll_func_th);
 	if (ret)
 		goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 462d452..581d0e5 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
 	struct adis16240_state *st
 		= container_of(work_s, struct adis16240_state,
 				work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+	ring->access.store_to(ring,
 			(u8 *)data,
 			st->last_timestamp);
 
@@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16240_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -172,11 +161,21 @@ 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;
 	ring->predisable = &iio_triggered_ring_predisable;
 	ring->owner = THIS_MODULE;
 
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.number);
+
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
 	if (ret)
 		goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 4c1b36a..a68a381 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
 	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;
 	s16 *data;
 
-	while (dev_info->scan_el_attrs->attrs[i]) {
+	while (scan_el_attrs->attrs[i]) {
 		el = to_iio_scan_el((struct device_attribute *)
-				    (dev_info->scan_el_attrs->attrs[i]));
+				    (scan_el_attrs->attrs[i]));
 		/* label is in fact the address */
 		if (el->label == this_attr->address)
 			break;
 		i++;
 	}
-	if (!dev_info->scan_el_attrs->attrs[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(dev_info, el->number);
+	ret = iio_scan_mask_query(ring, el->number);
 	if (ret < 0)
 		goto error_ret;
 	if (ret) {
-		data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
+		data = kmalloc(ring->access.get_bytes_per_datum(ring),
 			       GFP_KERNEL);
 		if (data == NULL)
 			return -ENOMEM;
-		ret = dev_info->ring->access.read_last(dev_info->ring,
-						      (u8 *)data);
+		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(dev_info, el->number);
+	len = iio_scan_mask_count_to_right(ring, el->number);
 	if (len < 0) {
 		ret = len;
 		goto error_free_data;
@@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
  **/
 static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 {
+	struct iio_ring_buffer *ring = st->help.indio_dev->ring;
 	struct spi_transfer *xfers;
 	struct spi_message msg;
 	int ret, i, j = 0;
 
-	xfers = kzalloc((st->help.indio_dev->scan_count) * 2
+	xfers = kzalloc((ring->scan_count) * 2
 			* sizeof(*xfers), GFP_KERNEL);
 	if (!xfers)
 		return -ENOMEM;
@@ -223,7 +226,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++) {
-		if (st->help.indio_dev->scan_mask & (1 << i)) {
+		if (ring->scan_mask & (1 << i)) {
 			/* lower byte */
 			xfers[j].tx_buf = st->tx + 2*j;
 			st->tx[2*j] = read_all_tx_array[i*4];
@@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 	 * values in alternate bytes
 	 */
 	spi_message_init(&msg);
-	for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
+	for (j = 0; j < ring->scan_count * 2; j++)
 		spi_message_add_tail(&xfers[j], &msg);
 
 	ret = spi_sync(st->us, &msg);
@@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
 	u8 *rx_array ;
 	s16 *data = (s16 *)buf;
 
-	rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
+	rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
 	if (rx_array == NULL)
 		return -ENOMEM;
 	ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
 	if (ret < 0)
 		return ret;
-	for (i = 0; i < h->indio_dev->scan_count; i++)
+	for (i = 0; i < h->indio_dev->ring->scan_count; i++)
 		data[i] = combine_8_to_16(rx_array[i*4+1],
 					rx_array[i*4+3]);
 	kfree(rx_array);
@@ -479,28 +482,29 @@ 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);
-	/* Set default scan mode */
 	h->get_ring_element = &lis3l02dq_get_ring_element;
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
 
-	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
-	if (!indio_dev->ring)
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring)
 		return -ENOMEM;
 
+	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	indio_dev->ring->bpe = 2;
-	indio_dev->ring->preenable = &iio_sw_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->owner = THIS_MODULE;
+	iio_ring_sw_register_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->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);
 
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
 	if (ret)
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index eff5b9a..6d19d15 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
 
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
-	indio_dev->scan_el_attrs = &sca3000_scan_el_group;
 	indio_dev->ring = sca3000_rb_allocate(indio_dev);
 	if (indio_dev->ring == NULL)
 		return -ENOMEM;
 	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
 
+	indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
 	indio_dev->ring->access.rip_lots = &sca3000_rip_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;
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 6435e50..1dc428f 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	st->indio_dev->attrs = st->chip_info->dev_attrs;
 
 	/* Todo: this shouldn't be here. */
-	st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
 	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/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index edac0ba..1d6ce54 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -30,6 +30,7 @@
 /* Todo: test this */
 int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 {
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 	unsigned long numvals;
 	int count = 0, ret;
 	u8 *ring_data;
@@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
-						ring_data);
+	ret = ring->access.read_last(ring, ring_data);
 	if (ret)
 		goto error_free_ring_data;
 	/* Need a count of channels prior to this one */
@@ -77,6 +77,7 @@ error_ret:
 static int max1363_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct max1363_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 	unsigned long numvals;
 
@@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 	 * Need to figure out the current mode based upon the requested
 	 * scan mask in iio_dev
 	 */
-	st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
+	st->current_mode = max1363_match_mode(ring->scan_mask,
 					st->chip_info);
 	if (!st->current_mode)
 		return -EINVAL;
@@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 	max1363_set_scan_mode(st);
 
 	numvals = hweight_long(st->current_mode->modemask);
-	if (indio_dev->ring->access.set_bytes_per_datum) {
+	if (ring->access.set_bytes_per_datum) {
 		if (st->chip_info->bits != 8)
 			d_size = numvals*2 + sizeof(s64);
 		else
 			d_size = numvals + sizeof(s64);
 		if (d_size % 8)
 			d_size += 8 - (d_size % 8);
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
+		ring->access.set_bytes_per_datum(ring, d_size);
 	}
 
 	return 0;
@@ -135,7 +136,7 @@ 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 = st->indio_dev;
-	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
@@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
 
 	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
+	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
 done:
 	kfree(rxbuf);
 	atomic_dec(&st->protect_ring);
@@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
+	iio_ring_sw_register_funcs(&indio_dev->ring->access);
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
 	if (ret)
 		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;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 055d5e8..0334860 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
 	struct adis16260_state *st
 		= container_of(work_s, struct adis16260_state,
 				work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+	ring->access.store_to(ring,
 			(u8 *)data,
 			st->last_timestamp);
 
@@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16260_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -174,11 +164,20 @@ 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;
 	ring->predisable = &iio_triggered_ring_predisable;
 	ring->owner = THIS_MODULE;
 
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_gyro.number);
+	iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
+	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)
 		goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 9d0ca12..3a4e8c3 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -87,15 +87,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
  * @event_attrs:	[DRIVER] event control attributes
  * @event_conf_attrs:	[DRIVER] event configuration attributes
  * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
+ * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @ring:		[DRIVER] any ring buffer present
  * @mlock:		[INTERN] lock used to prevent simultaneous device state
  *			changes
- * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
- *			control method is used
- * @scan_count:	[INTERN] the number of elements in the current scan mode
- * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
- * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
- * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
  * @trig:		[INTERN] current device trigger (ring buffer modes)
  * @pollfunc:		[DRIVER] function run on trigger being recieved
  **/
@@ -115,107 +110,14 @@ struct iio_dev {
 
 	struct iio_event_interface	*event_interfaces;
 
+	u32				*available_scan_masks;
 	struct iio_ring_buffer		*ring;
 	struct mutex			mlock;
 
-	struct attribute_group		*scan_el_attrs;
-	int				scan_count;
-
-	u32				scan_mask;
-	u32				*available_scan_masks;
-	bool				scan_timestamp;
 	struct iio_trigger		*trig;
 	struct iio_poll_func		*pollfunc;
 };
 
-/*
- * These are mainly provided to allow for a change of implementation if a device
- * has a large number of scan elements
- */
-#define IIO_MAX_SCAN_LENGTH 31
-
-/* note 0 used as error indicator as it doesn't make sense. */
-static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
-{
-	while (*av_masks) {
-		if (!(~*av_masks & mask))
-			return *av_masks;
-		av_masks++;
-	}
-	return 0;
-}
-
-static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
-{
-	u32 mask;
-
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-
-	if (!dev_info->scan_mask)
-		return 0;
-
-	if (dev_info->available_scan_masks)
-		mask = iio_scan_mask_match(dev_info->available_scan_masks,
-					dev_info->scan_mask);
-	else
-		mask = dev_info->scan_mask;
-
-	if (!mask)
-		return -EINVAL;
-
-	return !!(mask & (1 << bit));
-};
-
-static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
-{
-	u32 mask;
-	u32 trialmask = dev_info->scan_mask | (1 << bit);
-
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	if (dev_info->available_scan_masks) {
-		mask = iio_scan_mask_match(dev_info->available_scan_masks,
-					trialmask);
-		if (!mask)
-			return -EINVAL;
-	}
-	dev_info->scan_mask = trialmask;
-	dev_info->scan_count++;
-
-	return 0;
-};
-
-static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
-{
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	dev_info->scan_mask &= ~(1 << bit);
-	dev_info->scan_count--;
-	return 0;
-};
-
-/**
- * iio_scan_mask_count_to_right() - how many scan elements occur before here
- * @dev_info: the iio_device whose scan mode we are querying
- * @bit: which number scan element is this
- **/
-static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
-						int bit)
-{
-	int count = 0;
-	int mask = (1 << bit);
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	while (mask) {
-		mask >>= 1;
-		if (mask & dev_info->scan_mask)
-			count++;
-	}
-
-	return count;
-}
-
 /**
  * iio_device_register() - register a device with the IIO subsystem
  * @dev_info:		Device structure filled by the device driver
diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
index 854183c..742cad6 100644
--- a/drivers/staging/iio/imu/adis16300_ring.c
+++ b/drivers/staging/iio/imu/adis16300_ring.c
@@ -134,11 +134,11 @@ 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 = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-					    (u8 *)data,
-					    st->last_timestamp);
+	ring->access.store_to(ring,
+			(u8 *)data,
+			st->last_timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16300_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -202,11 +188,24 @@ int adis16300_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 = &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_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_adc_0.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;
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
index 9620cbe..a0b80e4 100644
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -134,11 +134,11 @@ 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 = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-					    (u8 *)data,
-					    st->last_timestamp);
+	ring->access.store_to(ring,
+			(u8 *)data,
+			st->last_timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16350_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -204,11 +188,26 @@ int adis16350_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 = &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_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_adc_0.number);
+
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
 	if (ret)
 		goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index c8e2316..667f77b 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 	struct adis16400_state *st
 		= container_of(work_s, struct adis16400_state,
 			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
@@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < st->indio_dev->scan_count; i++)
+			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 (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-					    (u8 *)data,
-					    st->last_timestamp);
+	ring->access.store_to(ring,
+			(u8 *) data,
+			st->last_timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
@@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	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);
-	/* Set default scan mode */
-
-	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-	indio_dev->scan_timestamp = true;
-
-	indio_dev->scan_el_attrs = &adis16400_scan_el_group;
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -214,11 +197,27 @@ 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;
 	ring->predisable = &iio_triggered_ring_predisable;
 	ring->owner = THIS_MODULE;
 
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_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_adc_0.number);
+
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
 	if (ret)
 		goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index dd4d87a..5c0e56a 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
 		goto error_ret;
 	}
 
-	if (dev_info->scan_el_attrs) {
-		ret = sysfs_create_group(&dev_info->dev.kobj,
-					 dev_info->scan_el_attrs);
-		if (ret)
-			dev_err(&dev_info->dev,
-				"Failed to add sysfs scan els\n");
-	}
-
 error_ret:
 	return ret;
 }
 
 static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
-	if (dev_info->scan_el_attrs)
-		sysfs_remove_group(&dev_info->dev.kobj,
-				   dev_info->scan_el_attrs);
-
 	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 610c2b6..148ca5c 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
 	if (ret)
 		goto error_free_ring_buffer_event_chrdev;
 
+	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_event_chrdev;
+		}
+	}
+
 	return ret;
 error_free_ring_buffer_event_chrdev:
 	__iio_free_ring_buffer_event_chrdev(ring);
@@ -291,6 +301,10 @@ 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_free_ring_buffer_access_chrdev(ring);
 	__iio_free_ring_buffer_event_chrdev(ring);
 	device_del(&ring->dev);
@@ -468,7 +482,7 @@ ssize_t iio_scan_el_show(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_scan_el *this_el = to_iio_scan_el(attr);
 
-	ret = iio_scan_mask_query(indio_dev, this_el->number);
+	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
 	if (ret < 0)
 		return ret;
 	return sprintf(buf, "%d\n", ret);
@@ -491,19 +505,17 @@ ssize_t iio_scan_el_store(struct device *dev,
 		ret = -EBUSY;
 		goto error_ret;
 	}
-	ret = iio_scan_mask_query(indio_dev, this_el->number);
+	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
 	if (ret < 0)
 		goto error_ret;
 	if (!state && ret) {
-		ret = iio_scan_mask_clear(indio_dev, this_el->number);
+		ret = iio_scan_mask_clear(indio_dev->ring, this_el->number);
 		if (ret)
 			goto error_ret;
-		indio_dev->scan_count--;
 	} else if (state && !ret) {
-		ret = iio_scan_mask_set(indio_dev, this_el->number);
+		ret = iio_scan_mask_set(indio_dev->ring, this_el->number);
 		if (ret)
 			goto error_ret;
-		indio_dev->scan_count++;
 	}
 	if (this_el->set_state)
 		ret = this_el->set_state(this_el, indio_dev, state);
@@ -520,7 +532,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
 			    char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
+	return sprintf(buf, "%d\n", indio_dev->ring->scan_timestamp);
 }
 EXPORT_SYMBOL(iio_scan_el_ts_show);
 
@@ -538,7 +550,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
 		ret = -EBUSY;
 		goto error_ret;
 	}
-	indio_dev->scan_timestamp = state;
+	indio_dev->ring->scan_timestamp = 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 ac017b1..6124353 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
  * @bytes_per_datum	[DEVICE] size of individual datum including timestamp
  * @bpe:		[DEVICE] size of individual channel value
  * @loopcount:		[INTERN] number of times the ring has looped
+ * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
+ *			control method is used
+ * @scan_count:	[INTERN] the number of elements in the current scan mode
+ * @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
  * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
@@ -124,6 +129,10 @@ struct iio_ring_buffer {
 	int				bytes_per_datum;
 	int				bpe;
 	int				loopcount;
+	struct attribute_group		*scan_el_attrs;
+	int				scan_count;
+	u32				scan_mask;
+	bool				scan_timestamp;
 	struct iio_handler		access_handler;
 	struct iio_event_interface	ev_int;
 	struct iio_shared_ev_pointer	shared_ev_pointer;
@@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
 				   iio_scan_el_ts_store),	\
 	}
 
+/*
+ * These are mainly provided to allow for a change of implementation if a device
+ * has a large number of scan elements
+ */
+#define IIO_MAX_SCAN_LENGTH 31
+
+/* note 0 used as error indicator as it doesn't make sense. */
+static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
+{
+	while (*av_masks) {
+		if (!(~*av_masks & mask))
+			return *av_masks;
+		av_masks++;
+	}
+	return 0;
+}
+
+static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
+{
+	struct iio_dev *dev_info = ring->indio_dev;
+	u32 mask;
+
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+
+	if (!ring->scan_mask)
+		return 0;
+
+	if (dev_info->available_scan_masks)
+		mask = iio_scan_mask_match(dev_info->available_scan_masks,
+					ring->scan_mask);
+	else
+		mask = ring->scan_mask;
+
+	if (!mask)
+		return -EINVAL;
+
+	return !!(mask & (1 << bit));
+};
+
+static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
+{
+	struct iio_dev *dev_info = ring->indio_dev;
+	u32 mask;
+	u32 trialmask = ring->scan_mask | (1 << bit);
+
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	if (dev_info->available_scan_masks) {
+		mask = iio_scan_mask_match(dev_info->available_scan_masks,
+					trialmask);
+		if (!mask)
+			return -EINVAL;
+	}
+	ring->scan_mask = trialmask;
+	ring->scan_count++;
+
+	return 0;
+};
+
+static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	ring->scan_mask &= ~(1 << bit);
+	ring->scan_count--;
+	return 0;
+};
+
+/**
+ * iio_scan_mask_count_to_right() - how many scan elements occur before here
+ * @dev_info: the iio_device whose scan mode we are querying
+ * @bit: which number scan element is this
+ **/
+static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
+						int bit)
+{
+	int count = 0;
+	int mask = (1 << bit);
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	while (mask) {
+		mask >>= 1;
+		if (mask & ring->scan_mask)
+			count++;
+	}
+
+	return count;
+}
+
+
 static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
 {
 	put_device(&ring->dev);
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 99efb6b..52624ac 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
 
 int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 {
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t size;
 	dev_dbg(&indio_dev->dev, "%s\n", __func__);
 	/* Check if there are any scan elements enabled, if not fail*/
-	if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
+	if (!(ring->scan_count || ring->scan_timestamp))
 		return -EINVAL;
-	if (indio_dev->scan_timestamp)
-		if (indio_dev->scan_count)
+	if (ring->scan_timestamp)
+		if (ring->scan_count)
 			/* Timestamp (aligned to s64) and data */
-			size = (((indio_dev->scan_count * indio_dev->ring->bpe)
+			size = (((ring->scan_count * ring->bpe)
 					+ sizeof(s64) - 1)
 				& ~(sizeof(s64) - 1))
 				+ sizeof(s64);
 		else /* Timestamp only  */
 			size = sizeof(s64);
 	else /* Data only */
-		size = indio_dev->scan_count * indio_dev->ring->bpe;
-	indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
+		size = ring->scan_count * ring->bpe;
+	ring->access.set_bytes_per_datum(ring, size);
 
 	return 0;
 }
@@ -462,9 +463,9 @@ 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);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
 	int len = 0;
-	size_t datasize = st->indio_dev
-		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
 	char *data = kmalloc(datasize, GFP_KERNEL);
 
 	if (data == NULL) {
@@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
 		return;
 	}
 
-	if (st->indio_dev->scan_count)
+	if (ring->scan_count)
 		len = st->get_ring_element(st, data);
 
 	  /* Guaranteed to be aligned with 8 byte boundary */
-	if (st->indio_dev->scan_timestamp)
+	if (ring->scan_timestamp)
 		*(s64 *)(((phys_addr_t)data + len
 				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
 			= st->last_timestamp;
-	  st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-					(u8 *)data,
+	ring->access.store_to(ring,
+			(u8 *)data,
 			st->last_timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
-- 
1.7.0.6


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

* Re: [PATCH 1/2] staging:iio rename ring attributes
  2010-08-30 10:55           ` [PATCH 1/2] staging:iio rename ring attributes Manuel Stahl
@ 2010-08-30 12:28             ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 12:28 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio, Song, Barry

On 08/30/10 11:55, Manuel Stahl wrote:
> bps -> bytes_per_datum
> ring_enable -> enable
Excellent.  Thanks for doing this.  At some point I'll do a cleanup
patch to do ring -> buffer wherever it appears and isn't guaranteed
to be a ring buffer.

Does need a follow up patch to deal with the Documentation for these
though.  Do you want to do it or shall I?  Simple spot of find an
replace I think...

Please send this on to Greg KH.

(cc'd Barry as a heads up...)
Sorry Analog guys, this is going to cause some more breakage
with your tree.  All easy fixes though + will encourage you to merge
drivers faster so it becomes our problem ;)
> 
> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/accel/adis16209_ring.c |    2 +-
>  drivers/staging/iio/accel/adis16240_ring.c |    2 +-
>  drivers/staging/iio/accel/lis3l02dq_ring.c |    2 +-
>  drivers/staging/iio/accel/sca3000_ring.c   |   10 ++--
>  drivers/staging/iio/adc/max1363_ring.c     |    4 +-
>  drivers/staging/iio/gyro/adis16260_ring.c  |    2 +-
>  drivers/staging/iio/imu/adis16300_ring.c   |    2 +-
>  drivers/staging/iio/imu/adis16350_ring.c   |    2 +-
>  drivers/staging/iio/imu/adis16400_ring.c   |    2 +-
>  drivers/staging/iio/industrialio-ring.c    |    8 ++--
>  drivers/staging/iio/ring_generic.h         |   22 +++++-----
>  drivers/staging/iio/ring_sw.c              |   58 ++++++++++++++--------------
>  drivers/staging/iio/ring_sw.h              |   12 +++---
>  13 files changed, 64 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
> index 25fde65..d40b95f 100644
> --- a/drivers/staging/iio/accel/adis16209_ring.c
> +++ b/drivers/staging/iio/accel/adis16209_ring.c
> @@ -119,7 +119,7 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
> index cd69a2e..462d452 100644
> --- a/drivers/staging/iio/accel/adis16240_ring.c
> +++ b/drivers/staging/iio/accel/adis16240_ring.c
> @@ -111,7 +111,7 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
> index a960a8f..4c1b36a 100644
> --- a/drivers/staging/iio/accel/lis3l02dq_ring.c
> +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
> @@ -169,7 +169,7 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
>  	if (ret < 0)
>  		goto error_ret;
>  	if (ret) {
> -		data = kmalloc(dev_info->ring->access.get_bpd(dev_info->ring),
> +		data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
>  			       GFP_KERNEL);
>  		if (data == NULL)
>  			return -ENOMEM;
> diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
> index 8e8c068..eff5b9a 100644
> --- a/drivers/staging/iio/accel/sca3000_ring.c
> +++ b/drivers/staging/iio/accel/sca3000_ring.c
> @@ -100,7 +100,7 @@ static int sca3000_ring_get_length(struct iio_ring_buffer *r)
>  }
>  
>  /* only valid if resolution is kept at 11bits */
> -static int sca3000_ring_get_bpd(struct iio_ring_buffer *r)
> +static int sca3000_ring_get_bytes_per_datum(struct iio_ring_buffer *r)
>  {
>  	return 6;
>  }
> @@ -111,7 +111,7 @@ static void sca3000_ring_release(struct device *dev)
>  }
>  
>  static IIO_RING_ENABLE_ATTR;
> -static IIO_RING_BPS_ATTR;
> +static IIO_RING_BYTES_PER_DATUM_ATTR;
>  static IIO_RING_LENGTH_ATTR;
>  
>  /**
> @@ -218,8 +218,8 @@ static struct attribute_group sca3000_scan_el_group = {
>   */
>  static struct attribute *sca3000_ring_attributes[] = {
>  	&dev_attr_length.attr,
> -	&dev_attr_bps.attr,
> -	&dev_attr_ring_enable.attr,
> +	&dev_attr_bytes_per_datum.attr,
> +	&dev_attr_enable.attr,
>  	NULL,
>  };
>  
> @@ -272,7 +272,7 @@ int sca3000_configure_ring(struct iio_dev *indio_dev)
>  
>  	indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
>  	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
> -	indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd;
> +	indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
>  
>  	return 0;
>  }
> diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
> index 786b17a..edac0ba 100644
> --- a/drivers/staging/iio/adc/max1363_ring.c
> +++ b/drivers/staging/iio/adc/max1363_ring.c
> @@ -92,14 +92,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>  	max1363_set_scan_mode(st);
>  
>  	numvals = hweight_long(st->current_mode->modemask);
> -	if (indio_dev->ring->access.set_bpd) {
> +	if (indio_dev->ring->access.set_bytes_per_datum) {
>  		if (st->chip_info->bits != 8)
>  			d_size = numvals*2 + sizeof(s64);
>  		else
>  			d_size = numvals + sizeof(s64);
>  		if (d_size % 8)
>  			d_size += 8 - (d_size % 8);
> -		indio_dev->ring->access.set_bpd(indio_dev->ring, d_size);
> +		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
>  	}
>  
>  	return 0;
> diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
> index 9ef7f90..055d5e8 100644
> --- a/drivers/staging/iio/gyro/adis16260_ring.c
> +++ b/drivers/staging/iio/gyro/adis16260_ring.c
> @@ -114,7 +114,7 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
> index fc93160..854183c 100644
> --- a/drivers/staging/iio/imu/adis16300_ring.c
> +++ b/drivers/staging/iio/imu/adis16300_ring.c
> @@ -138,7 +138,7 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
> index e053e9a..9620cbe 100644
> --- a/drivers/staging/iio/imu/adis16350_ring.c
> +++ b/drivers/staging/iio/imu/adis16350_ring.c
> @@ -138,7 +138,7 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
> index 949db76..c8e2316 100644
> --- a/drivers/staging/iio/imu/adis16400_ring.c
> +++ b/drivers/staging/iio/imu/adis16400_ring.c
> @@ -147,7 +147,7 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>  	int i = 0;
>  	s16 *data;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
> index 6ab578e..610c2b6 100644
> --- a/drivers/staging/iio/industrialio-ring.c
> +++ b/drivers/staging/iio/industrialio-ring.c
> @@ -338,20 +338,20 @@ EXPORT_SYMBOL(iio_read_ring_length);
>  }
>  EXPORT_SYMBOL(iio_write_ring_length);
>  
> -ssize_t iio_read_ring_bps(struct device *dev,
> +ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
>  			  struct device_attribute *attr,
>  			  char *buf)
>  {
>  	int len = 0;
>  	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
>  
> -	if (ring->access.get_bpd)
> +	if (ring->access.get_bytes_per_datum)
>  		len = sprintf(buf, "%d\n",
> -			      ring->access.get_bpd(ring));
> +			      ring->access.get_bytes_per_datum(ring));
>  
>  	return len;
>  }
> -EXPORT_SYMBOL(iio_read_ring_bps);
> +EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
>  
>  ssize_t iio_store_ring_enable(struct device *dev,
>  			      struct device_attribute *attr,
> diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
> index a872d39..ac017b1 100644
> --- a/drivers/staging/iio/ring_generic.h
> +++ b/drivers/staging/iio/ring_generic.h
> @@ -52,8 +52,8 @@ int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
>   *			change.
>   * @request_update:	if a parameter change has been marked, update underlying
>   *			storage.
> - * @get_bpd:		get current bytes per datum
> - * @set_bpd:		set number of bytes per datum
> + * @get_bytes_per_datum:		get current bytes per datum
> + * @set_bytes_per_datum:		set number of bytes per datum
>   * @get_length:		get number of datums in ring
>   * @set_length:		set number of datums in ring
>   * @is_enabled:		query if ring is currently being used
> @@ -81,8 +81,8 @@ struct iio_ring_access_funcs {
>  	int (*mark_param_change)(struct iio_ring_buffer *ring);
>  	int (*request_update)(struct iio_ring_buffer *ring);
>  
> -	int (*get_bpd)(struct iio_ring_buffer *ring);
> -	int (*set_bpd)(struct iio_ring_buffer *ring, size_t bpd);
> +	int (*get_bytes_per_datum)(struct iio_ring_buffer *ring);
> +	int (*set_bytes_per_datum)(struct iio_ring_buffer *ring, size_t bpd);
>  	int (*get_length)(struct iio_ring_buffer *ring);
>  	int (*set_length)(struct iio_ring_buffer *ring, int length);
>  
> @@ -99,7 +99,7 @@ struct iio_ring_access_funcs {
>   * @id:			unique id number
>   * @access_id:		device id number
>   * @length:		[DEVICE] number of datums in ring
> - * @bpd:		[DEVICE] size of individual datum including timestamp
> + * @bytes_per_datum	[DEVICE] size of individual datum including timestamp
>   * @bpe:		[DEVICE] size of individual channel value
>   * @loopcount:		[INTERN] number of times the ring has looped
>   * @access_handler:	[INTERN] chrdev access handling
> @@ -121,7 +121,7 @@ struct iio_ring_buffer {
>  	int				id;
>  	int				access_id;
>  	int				length;
> -	int				bpd;
> +	int				bytes_per_datum;
>  	int				bpe;
>  	int				loopcount;
>  	struct iio_handler		access_handler;
> @@ -146,7 +146,7 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
>  static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
>  					    int bytes_per_datum, int length)
>  {
> -	ring->bpd = bytes_per_datum;
> +	ring->bytes_per_datum = bytes_per_datum;
>  	ring->length = length;
>  	ring->loopcount = 0;
>  }
> @@ -277,7 +277,7 @@ ssize_t iio_write_ring_length(struct device *dev,
>  			      struct device_attribute *attr,
>  			      const char *buf,
>  			      size_t len);
> -ssize_t iio_read_ring_bps(struct device *dev,
> +ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
>  			  struct device_attribute *attr,
>  			  char *buf);
>  ssize_t iio_store_ring_enable(struct device *dev,
> @@ -290,9 +290,9 @@ ssize_t iio_show_ring_enable(struct device *dev,
>  #define IIO_RING_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR,	\
>  					 iio_read_ring_length,		\
>  					 iio_write_ring_length)
> -#define IIO_RING_BPS_ATTR DEVICE_ATTR(bps, S_IRUGO | S_IWUSR,	\
> -				      iio_read_ring_bps, NULL)
> -#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(ring_enable, S_IRUGO | S_IWUSR, \
> +#define IIO_RING_BYTES_PER_DATUM_ATTR DEVICE_ATTR(bytes_per_datum, S_IRUGO | S_IWUSR,	\
> +				      iio_read_ring_bytes_per_datum, NULL)
> +#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
>  					 iio_show_ring_enable,		\
>  					 iio_store_ring_enable)
>  #else /* CONFIG_IIO_RING_BUFFER */
> diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
> index e2f01c6..99efb6b 100644
> --- a/drivers/staging/iio/ring_sw.c
> +++ b/drivers/staging/iio/ring_sw.c
> @@ -21,7 +21,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
>  	if ((length == 0) || (bytes_per_datum == 0))
>  		return -EINVAL;
>  	__iio_update_ring_buffer(&ring->buf, bytes_per_datum, length);
> -	ring->data = kmalloc(length*ring->buf.bpd, GFP_ATOMIC);
> +	ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC);
>  	ring->read_p = NULL;
>  	ring->write_p = NULL;
>  	ring->last_written_p = NULL;
> @@ -77,10 +77,10 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
>  		 * as long as the read pointer is valid before this
>  		 * passes it - guaranteed as set later in this function.
>  		 */
> -		ring->half_p = ring->data - ring->buf.length*ring->buf.bpd/2;
> +		ring->half_p = ring->data - ring->buf.length*ring->buf.bytes_per_datum/2;
>  	}
>  	/* Copy data to where ever the current write pointer says */
> -	memcpy(ring->write_p, data, ring->buf.bpd);
> +	memcpy(ring->write_p, data, ring->buf.bytes_per_datum);
>  	barrier();
>  	/* Update the pointer used to get most recent value.
>  	 * Always valid as either points to latest or second latest value.
> @@ -91,9 +91,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
>  	/* temp_ptr used to ensure we never have an invalid pointer
>  	 * it may be slightly lagging, but never invalid
>  	 */
> -	temp_ptr = ring->write_p + ring->buf.bpd;
> +	temp_ptr = ring->write_p + ring->buf.bytes_per_datum;
>  	/* End of ring, back to the beginning */
> -	if (temp_ptr == ring->data + ring->buf.length*ring->buf.bpd)
> +	if (temp_ptr == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
>  		temp_ptr = ring->data;
>  	/* Update the write pointer
>  	 * always valid as long as this is the only function able to write.
> @@ -112,9 +112,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
>  	 */
>  	else if (ring->write_p == ring->read_p) {
>  		change_test_ptr = ring->read_p;
> -		temp_ptr = change_test_ptr + ring->buf.bpd;
> +		temp_ptr = change_test_ptr + ring->buf.bytes_per_datum;
>  		if (temp_ptr
> -		    == ring->data + ring->buf.length*ring->buf.bpd) {
> +		    == ring->data + ring->buf.length*ring->buf.bytes_per_datum) {
>  			temp_ptr = ring->data;
>  		}
>  		/* We are moving pointer on one because the ring is full.  Any
> @@ -135,8 +135,8 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
>  	/* There are definite 'issues' with this and chances of
>  	 * simultaneous read */
>  	/* Also need to use loop count to ensure this only happens once */
> -	ring->half_p += ring->buf.bpd;
> -	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bpd)
> +	ring->half_p += ring->buf.bytes_per_datum;
> +	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);
> @@ -164,15 +164,15 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
>  	 *  read something that is not a whole number of bpds.
>  	 * Return an error.
>  	 */
> -	if (count % ring->buf.bpd) {
> +	if (count % ring->buf.bytes_per_datum) {
>  		ret = -EINVAL;
>  		printk(KERN_INFO "Ring buffer read request not whole number of"
> -		       "samples: Request bytes %zd, Current bpd %d\n",
> -		       count, ring->buf.bpd);
> +		       "samples: Request bytes %zd, Current bytes per datum %d\n",
> +		       count, ring->buf.bytes_per_datum);
>  		goto error_ret;
>  	}
>  	/* Limit size to whole of ring buffer */
> -	bytes_to_rip = min((size_t)(ring->buf.bpd*ring->buf.length), count);
> +	bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), count);
>  
>  	*data = kmalloc(bytes_to_rip, GFP_KERNEL);
>  	if (*data == NULL) {
> @@ -214,7 +214,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
>  	} else {
>  		/* going through 'end' of ring buffer */
>  		max_copied = ring->data
> -			+ ring->buf.length*ring->buf.bpd - initial_read_p;
> +			+ ring->buf.length*ring->buf.bytes_per_datum - initial_read_p;
>  		memcpy(*data, initial_read_p, max_copied);
>  		/* possible we are done if we align precisely with end */
>  		if (max_copied == bytes_to_rip)
> @@ -240,7 +240,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
>  	if (initial_read_p <= current_read_p)
>  		*dead_offset = current_read_p - initial_read_p;
>  	else
> -		*dead_offset = ring->buf.length*ring->buf.bpd
> +		*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
> @@ -293,7 +293,7 @@ again:
>  	/* Check there is anything here */
>  	if (last_written_p_copy == NULL)
>  		return -EAGAIN;
> -	memcpy(data, last_written_p_copy, ring->buf.bpd);
> +	memcpy(data, last_written_p_copy, ring->buf.bytes_per_datum);
>  
>  	if (unlikely(ring->last_written_p != last_written_p_copy))
>  		goto again;
> @@ -322,7 +322,7 @@ int iio_request_update_sw_rb(struct iio_ring_buffer *r)
>  		goto error_ret;
>  	}
>  	__iio_free_sw_ring_buffer(ring);
> -	ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bpd,
> +	ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bytes_per_datum,
>  					    ring->buf.length);
>  error_ret:
>  	spin_unlock(&ring->use_lock);
> @@ -330,23 +330,23 @@ error_ret:
>  }
>  EXPORT_SYMBOL(iio_request_update_sw_rb);
>  
> -int iio_get_bpd_sw_rb(struct iio_ring_buffer *r)
> +int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
>  {
>  	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
> -	return ring->buf.bpd;
> +	return ring->buf.bytes_per_datum;
>  }
> -EXPORT_SYMBOL(iio_get_bpd_sw_rb);
> +EXPORT_SYMBOL(iio_get_bytes_per_datum_sw_rb);
>  
> -int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd)
> +int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
>  {
> -	if (r->bpd != bpd) {
> -		r->bpd = bpd;
> +	if (r->bytes_per_datum != bpd) {
> +		r->bytes_per_datum = bpd;
>  		if (r->access.mark_param_change)
>  			r->access.mark_param_change(r);
>  	}
>  	return 0;
>  }
> -EXPORT_SYMBOL(iio_set_bpd_sw_rb);
> +EXPORT_SYMBOL(iio_set_bytes_per_datum_sw_rb);
>  
>  int iio_get_length_sw_rb(struct iio_ring_buffer *r)
>  {
> @@ -380,14 +380,14 @@ static void iio_sw_rb_release(struct device *dev)
>  }
>  
>  static IIO_RING_ENABLE_ATTR;
> -static IIO_RING_BPS_ATTR;
> +static IIO_RING_BYTES_PER_DATUM_ATTR;
>  static IIO_RING_LENGTH_ATTR;
>  
>  /* Standard set of ring buffer attributes */
>  static struct attribute *iio_ring_attributes[] = {
>  	&dev_attr_length.attr,
> -	&dev_attr_bps.attr,
> -	&dev_attr_ring_enable.attr,
> +	&dev_attr_bytes_per_datum.attr,
> +	&dev_attr_enable.attr,
>  	NULL,
>  };
>  
> @@ -451,7 +451,7 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev)
>  			size = sizeof(s64);
>  	else /* Data only */
>  		size = indio_dev->scan_count * indio_dev->ring->bpe;
> -	indio_dev->ring->access.set_bpd(indio_dev->ring, size);
> +	indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
>  
>  	return 0;
>  }
> @@ -464,7 +464,7 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
>  			work_trigger_to_ring);
>  	int len = 0;
>  	size_t datasize = st->indio_dev
> -		->ring->access.get_bpd(st->indio_dev->ring);
> +		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>  	char *data = kmalloc(datasize, GFP_KERNEL);
>  
>  	if (data == NULL) {
> diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
> index 61f1ed6..ad03d83 100644
> --- a/drivers/staging/iio/ring_sw.h
> +++ b/drivers/staging/iio/ring_sw.h
> @@ -121,19 +121,19 @@ int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
>  
>  
>  /**
> - * iio_get_bpd_sw_rb() - get the datum size in bytes
> + * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes
>   * @r:		pointer to a software ring buffer created by an
>   *		iio_create_sw_rb call
>   **/
> -int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
> +int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r);
>  
>  /**
> - * iio_set_bpd_sw_rb() - set the datum size in bytes
> + * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes
>   * @r:		pointer to a software ring buffer created by an
>   *		iio_create_sw_rb call
>   * @bpd:	bytes per datum value
>   **/
> -int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
> +int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd);
>  
>  /**
>   * iio_get_length_sw_rb() - get how many datums the rb may contain
> @@ -166,8 +166,8 @@ static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
>  	ra->mark_param_change = &iio_mark_update_needed_sw_rb;
>  	ra->request_update = &iio_request_update_sw_rb;
>  
> -	ra->get_bpd = &iio_get_bpd_sw_rb;
> -	ra->set_bpd = &iio_set_bpd_sw_rb;
> +	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb;
> +	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb;
>  
>  	ra->get_length = &iio_get_length_sw_rb;
>  	ra->set_length = &iio_set_length_sw_rb;


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

* Re: [PATCH 2/2] staging:iio move scan_elements into ring buffer
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
@ 2010-08-30 12:58             ` Jonathan Cameron
  2010-08-30 13:37               ` Manuel Stahl
  2010-08-30 14:03             ` [PATCH 1/3] staging:iio update documentation Manuel Stahl
                               ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 12:58 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio, Song, Barry

On 08/30/10 11:55, Manuel Stahl wrote:
> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>

On more complex patches like this, could you verify which devices
you have tested against? Given the nature of that patch it
probably doesn't matter that much, but it's nice to save people
from wondering if they need to test on devices you have already
tried it with.

This one certainly turned out to be more complex that I was
anticipating! Mostly movement of code so easy enough to
review.

In one place as commented you made a change that obscured exactly
which bits your patch was changing. (see below).  I have nothing
against what you did, but would rather not have seen it in this
patch as it obscures what you are doing and that is never a good
idea! (in lis3l02dq_configure_ring).

There is also a movement of available_scan_masks in the iio_dev
structure that is unexplained.  It doesn't matter in the slightest
but is an odd thing to do without reason.

Neither of the above matter, they are just things I picked up
on whilst reviewing.

Thanks for doing this!

More than happy to add

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

Please forward to Greg KH (assuming no one shouts - might be worth
holding this one for a day or so given it effects a lot of drivers)

Again, sorry to the Analog guys, this one is going to thoroughly break
you tree when it hits it.  Still better now than later when it effects
even more drivers.

Note this also needs a patch updating the documentation.


> ---
>  drivers/staging/iio/accel/adis16209_ring.c |   41 ++++++------
>  drivers/staging/iio/accel/adis16240_ring.c |   33 +++++-----
>  drivers/staging/iio/accel/lis3l02dq_ring.c |   62 +++++++++--------
>  drivers/staging/iio/accel/sca3000_ring.c   |    2 +-
>  drivers/staging/iio/adc/max1363_core.c     |    1 -
>  drivers/staging/iio/adc/max1363_ring.c     |   18 +++--
>  drivers/staging/iio/gyro/adis16260_ring.c  |   31 ++++-----
>  drivers/staging/iio/iio.h                  |  102 +---------------------------
>  drivers/staging/iio/imu/adis16300_ring.c   |   43 ++++++------
>  drivers/staging/iio/imu/adis16350_ring.c   |   47 ++++++-------
>  drivers/staging/iio/imu/adis16400_ring.c   |   49 +++++++-------
>  drivers/staging/iio/industrialio-core.c    |   12 ---
>  drivers/staging/iio/industrialio-ring.c    |   28 ++++++--
>  drivers/staging/iio/ring_generic.h         |  100 +++++++++++++++++++++++++++
>  drivers/staging/iio/ring_sw.c              |   25 ++++---
>  15 files changed, 298 insertions(+), 296 deletions(-)
> 
> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
> index d40b95f..120bf91 100644
> --- a/drivers/staging/iio/accel/adis16209_ring.c
> +++ b/drivers/staging/iio/accel/adis16209_ring.c
> @@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>  	struct adis16209_state *st
>  		= container_of(work_s, struct adis16209_state,
>  			       work_trigger_to_ring);
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  
>  	int i = 0;
>  	s16 *data;
> -	size_t datasize = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> -					    (u8 *)data,
> -					    st->last_timestamp);
> +	ring->access.store_to(ring,
> +			      (u8 *)data,
> +			      st->last_timestamp);
>  
>  	iio_trigger_notify_done(st->indio_dev->trig);
>  	kfree(data);
> @@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16209_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -182,11 +169,23 @@ 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;
>  	ring->predisable = &iio_triggered_ring_predisable;
>  	ring->owner = THIS_MODULE;
>  
> +	/* Set default scan mode */
> +	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.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, &adis16209_poll_func_th);
>  	if (ret)
>  		goto error_iio_sw_rb_free;
> diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
> index 462d452..581d0e5 100644
> --- a/drivers/staging/iio/accel/adis16240_ring.c
> +++ b/drivers/staging/iio/accel/adis16240_ring.c
> @@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>  	struct adis16240_state *st
>  		= container_of(work_s, struct adis16240_state,
>  				work_trigger_to_ring);
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  
>  	int i = 0;
>  	s16 *data;
> -	size_t datasize = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> +	ring->access.store_to(ring,
>  			(u8 *)data,
>  			st->last_timestamp);
>  
> @@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16240_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -172,11 +161,21 @@ 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;
>  	ring->predisable = &iio_triggered_ring_predisable;
>  	ring->owner = THIS_MODULE;
>  
> +	/* Set default scan mode */
> +	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.number);
> +
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
>  	if (ret)
>  		goto error_iio_sw_rb_free;
> diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
> index 4c1b36a..a68a381 100644
> --- a/drivers/staging/iio/accel/lis3l02dq_ring.c
> +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
> @@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
>  	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;
>  	s16 *data;
>  
> -	while (dev_info->scan_el_attrs->attrs[i]) {
> +	while (scan_el_attrs->attrs[i]) {
>  		el = to_iio_scan_el((struct device_attribute *)
> -				    (dev_info->scan_el_attrs->attrs[i]));
> +				    (scan_el_attrs->attrs[i]));
>  		/* label is in fact the address */
>  		if (el->label == this_attr->address)
>  			break;
>  		i++;
>  	}
> -	if (!dev_info->scan_el_attrs->attrs[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(dev_info, el->number);
> +	ret = iio_scan_mask_query(ring, el->number);
>  	if (ret < 0)
>  		goto error_ret;
>  	if (ret) {
> -		data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
> +		data = kmalloc(ring->access.get_bytes_per_datum(ring),
>  			       GFP_KERNEL);
>  		if (data == NULL)
>  			return -ENOMEM;
> -		ret = dev_info->ring->access.read_last(dev_info->ring,
> -						      (u8 *)data);
> +		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(dev_info, el->number);
> +	len = iio_scan_mask_count_to_right(ring, el->number);
>  	if (len < 0) {
>  		ret = len;
>  		goto error_free_data;
> @@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
>   **/
>  static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>  {
> +	struct iio_ring_buffer *ring = st->help.indio_dev->ring;
>  	struct spi_transfer *xfers;
>  	struct spi_message msg;
>  	int ret, i, j = 0;
>  
> -	xfers = kzalloc((st->help.indio_dev->scan_count) * 2
> +	xfers = kzalloc((ring->scan_count) * 2
>  			* sizeof(*xfers), GFP_KERNEL);
>  	if (!xfers)
>  		return -ENOMEM;
> @@ -223,7 +226,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++) {
> -		if (st->help.indio_dev->scan_mask & (1 << i)) {
> +		if (ring->scan_mask & (1 << i)) {
>  			/* lower byte */
>  			xfers[j].tx_buf = st->tx + 2*j;
>  			st->tx[2*j] = read_all_tx_array[i*4];
> @@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>  	 * values in alternate bytes
>  	 */
>  	spi_message_init(&msg);
> -	for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
> +	for (j = 0; j < ring->scan_count * 2; j++)
>  		spi_message_add_tail(&xfers[j], &msg);
>  
>  	ret = spi_sync(st->us, &msg);
> @@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
>  	u8 *rx_array ;
>  	s16 *data = (s16 *)buf;
>  
> -	rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
> +	rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
>  	if (rx_array == NULL)
>  		return -ENOMEM;
>  	ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
>  	if (ret < 0)
>  		return ret;
> -	for (i = 0; i < h->indio_dev->scan_count; i++)
> +	for (i = 0; i < h->indio_dev->ring->scan_count; i++)
>  		data[i] = combine_8_to_16(rx_array[i*4+1],
>  					rx_array[i*4+3]);
>  	kfree(rx_array);
> @@ -479,28 +482,29 @@ 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);
> -	/* Set default scan mode */
>  	h->get_ring_element = &lis3l02dq_get_ring_element;
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
>  
> -	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
> -	if (!indio_dev->ring)
Personally I'd have done this directly into indio_dev->ring
as it would have reduced the lines changed count and kept
your changes more apparent.  Still doesn't really matter and
not worth respining the patch.
> +	ring = iio_sw_rb_allocate(indio_dev);
> +	if (!ring)
>  		return -ENOMEM;
>  
> +	indio_dev->ring = ring;
>  	/* Effectively select the ring buffer implementation */
> -	iio_ring_sw_register_funcs(&indio_dev->ring->access);
> -	indio_dev->ring->bpe = 2;
> -	indio_dev->ring->preenable = &iio_sw_ring_preenable;
> -	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
> -	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
> -	indio_dev->ring->owner = THIS_MODULE;
> +	iio_ring_sw_register_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->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);
>  
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
>  	if (ret)
> diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
> index eff5b9a..6d19d15 100644
> --- a/drivers/staging/iio/accel/sca3000_ring.c
> +++ b/drivers/staging/iio/accel/sca3000_ring.c
> @@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
>  
>  int sca3000_configure_ring(struct iio_dev *indio_dev)
>  {
> -	indio_dev->scan_el_attrs = &sca3000_scan_el_group;
>  	indio_dev->ring = sca3000_rb_allocate(indio_dev);
>  	if (indio_dev->ring == NULL)
>  		return -ENOMEM;
>  	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
>  
> +	indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
>  	indio_dev->ring->access.rip_lots = &sca3000_rip_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;
> diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
> index 6435e50..1dc428f 100644
> --- a/drivers/staging/iio/adc/max1363_core.c
> +++ b/drivers/staging/iio/adc/max1363_core.c
> @@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
>  	st->indio_dev->attrs = st->chip_info->dev_attrs;
>  
>  	/* Todo: this shouldn't be here. */
> -	st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
>  	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/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
> index edac0ba..1d6ce54 100644
> --- a/drivers/staging/iio/adc/max1363_ring.c
> +++ b/drivers/staging/iio/adc/max1363_ring.c
> @@ -30,6 +30,7 @@
>  /* Todo: test this */
>  int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>  {
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  	unsigned long numvals;
>  	int count = 0, ret;
>  	u8 *ring_data;
> @@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>  		ret = -ENOMEM;
>  		goto error_ret;
>  	}
> -	ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
> -						ring_data);
> +	ret = ring->access.read_last(ring, ring_data);
>  	if (ret)
>  		goto error_free_ring_data;
>  	/* Need a count of channels prior to this one */
> @@ -77,6 +77,7 @@ error_ret:
>  static int max1363_ring_preenable(struct iio_dev *indio_dev)
>  {
>  	struct max1363_state *st = indio_dev->dev_data;
> +	struct iio_ring_buffer *ring = indio_dev->ring;
>  	size_t d_size;
>  	unsigned long numvals;
>  
> @@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>  	 * Need to figure out the current mode based upon the requested
>  	 * scan mask in iio_dev
>  	 */
> -	st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
> +	st->current_mode = max1363_match_mode(ring->scan_mask,
>  					st->chip_info);
>  	if (!st->current_mode)
>  		return -EINVAL;
> @@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>  	max1363_set_scan_mode(st);
>  
>  	numvals = hweight_long(st->current_mode->modemask);
> -	if (indio_dev->ring->access.set_bytes_per_datum) {
> +	if (ring->access.set_bytes_per_datum) {
>  		if (st->chip_info->bits != 8)
>  			d_size = numvals*2 + sizeof(s64);
>  		else
>  			d_size = numvals + sizeof(s64);
>  		if (d_size % 8)
>  			d_size += 8 - (d_size % 8);
> -		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
> +		ring->access.set_bytes_per_datum(ring, d_size);
>  	}
>  
>  	return 0;
> @@ -135,7 +136,7 @@ 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 = st->indio_dev;
> -	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
> +	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
>  	s64 time_ns;
>  	__u8 *rxbuf;
>  	int b_sent;
> @@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
>  
>  	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
>  
> -	indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
> +	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
>  done:
>  	kfree(rxbuf);
>  	atomic_dec(&st->protect_ring);
> @@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
>  		goto error_ret;
>  	}
>  	/* Effectively select the ring buffer implementation */
> -	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
> +	iio_ring_sw_register_funcs(&indio_dev->ring->access);
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
>  	if (ret)
>  		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;
> diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
> index 055d5e8..0334860 100644
> --- a/drivers/staging/iio/gyro/adis16260_ring.c
> +++ b/drivers/staging/iio/gyro/adis16260_ring.c
> @@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>  	struct adis16260_state *st
>  		= container_of(work_s, struct adis16260_state,
>  				work_trigger_to_ring);
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  
>  	int i = 0;
>  	s16 *data;
> -	size_t datasize = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> +	ring->access.store_to(ring,
>  			(u8 *)data,
>  			st->last_timestamp);
>  
> @@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16260_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -174,11 +164,20 @@ 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;
>  	ring->predisable = &iio_triggered_ring_predisable;
>  	ring->owner = THIS_MODULE;
>  
> +	/* Set default scan mode */
> +	iio_scan_mask_set(ring, iio_scan_el_supply.number);
> +	iio_scan_mask_set(ring, iio_scan_el_gyro.number);
> +	iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
> +	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)
>  		goto error_iio_sw_rb_free;
> diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
> index 9d0ca12..3a4e8c3 100644
> --- a/drivers/staging/iio/iio.h
> +++ b/drivers/staging/iio/iio.h
> @@ -87,15 +87,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
>   * @event_attrs:	[DRIVER] event control attributes
>   * @event_conf_attrs:	[DRIVER] event configuration attributes
>   * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
> + * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
>   * @ring:		[DRIVER] any ring buffer present
>   * @mlock:		[INTERN] lock used to prevent simultaneous device state
>   *			changes
> - * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
> - *			control method is used
> - * @scan_count:	[INTERN] the number of elements in the current scan mode
> - * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
> - * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
> - * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
>   * @trig:		[INTERN] current device trigger (ring buffer modes)
>   * @pollfunc:		[DRIVER] function run on trigger being recieved
>   **/
> @@ -115,107 +110,14 @@ struct iio_dev {
>  
>  	struct iio_event_interface	*event_interfaces;
>  
Why move this element?
> +	u32				*available_scan_masks;
>  	struct iio_ring_buffer		*ring;
>  	struct mutex			mlock;
>  
> -	struct attribute_group		*scan_el_attrs;
> -	int				scan_count;
> -
> -	u32				scan_mask;
> -	u32				*available_scan_masks;
> -	bool				scan_timestamp;
>  	struct iio_trigger		*trig;
>  	struct iio_poll_func		*pollfunc;
>  };
>  
> -/*
> - * These are mainly provided to allow for a change of implementation if a device
> - * has a large number of scan elements
> - */
> -#define IIO_MAX_SCAN_LENGTH 31
> -
> -/* note 0 used as error indicator as it doesn't make sense. */
> -static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
> -{
> -	while (*av_masks) {
> -		if (!(~*av_masks & mask))
> -			return *av_masks;
> -		av_masks++;
> -	}
> -	return 0;
> -}
> -
> -static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
> -{
> -	u32 mask;
> -
> -	if (bit > IIO_MAX_SCAN_LENGTH)
> -		return -EINVAL;
> -
> -	if (!dev_info->scan_mask)
> -		return 0;
> -
> -	if (dev_info->available_scan_masks)
> -		mask = iio_scan_mask_match(dev_info->available_scan_masks,
> -					dev_info->scan_mask);
> -	else
> -		mask = dev_info->scan_mask;
> -
> -	if (!mask)
> -		return -EINVAL;
> -
> -	return !!(mask & (1 << bit));
> -};
> -
> -static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
> -{
> -	u32 mask;
> -	u32 trialmask = dev_info->scan_mask | (1 << bit);
> -
> -	if (bit > IIO_MAX_SCAN_LENGTH)
> -		return -EINVAL;
> -	if (dev_info->available_scan_masks) {
> -		mask = iio_scan_mask_match(dev_info->available_scan_masks,
> -					trialmask);
> -		if (!mask)
> -			return -EINVAL;
> -	}
> -	dev_info->scan_mask = trialmask;
> -	dev_info->scan_count++;
> -
> -	return 0;
> -};
> -
> -static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
> -{
> -	if (bit > IIO_MAX_SCAN_LENGTH)
> -		return -EINVAL;
> -	dev_info->scan_mask &= ~(1 << bit);
> -	dev_info->scan_count--;
> -	return 0;
> -};
> -
> -/**
> - * iio_scan_mask_count_to_right() - how many scan elements occur before here
> - * @dev_info: the iio_device whose scan mode we are querying
> - * @bit: which number scan element is this
> - **/
> -static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
> -						int bit)
> -{
> -	int count = 0;
> -	int mask = (1 << bit);
> -	if (bit > IIO_MAX_SCAN_LENGTH)
> -		return -EINVAL;
> -	while (mask) {
> -		mask >>= 1;
> -		if (mask & dev_info->scan_mask)
> -			count++;
> -	}
> -
> -	return count;
> -}
> -
>  /**
>   * iio_device_register() - register a device with the IIO subsystem
>   * @dev_info:		Device structure filled by the device driver
> diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
> index 854183c..742cad6 100644
> --- a/drivers/staging/iio/imu/adis16300_ring.c
> +++ b/drivers/staging/iio/imu/adis16300_ring.c
> @@ -134,11 +134,11 @@ 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 = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> -					    (u8 *)data,
> -					    st->last_timestamp);
> +	ring->access.store_to(ring,
> +			(u8 *)data,
> +			st->last_timestamp);
>  
>  	iio_trigger_notify_done(st->indio_dev->trig);
>  	kfree(data);
> @@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16300_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -202,11 +188,24 @@ int adis16300_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 = &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_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_adc_0.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;
> diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
> index 9620cbe..a0b80e4 100644
> --- a/drivers/staging/iio/imu/adis16350_ring.c
> +++ b/drivers/staging/iio/imu/adis16350_ring.c
> @@ -134,11 +134,11 @@ 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 = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> -					    (u8 *)data,
> -					    st->last_timestamp);
> +	ring->access.store_to(ring,
> +			(u8 *)data,
> +			st->last_timestamp);
>  
>  	iio_trigger_notify_done(st->indio_dev->trig);
>  	kfree(data);
> @@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16350_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -204,11 +188,26 @@ int adis16350_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 = &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_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_adc_0.number);
> +
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
>  	if (ret)
>  		goto error_iio_sw_rb_free;
> diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
> index c8e2316..667f77b 100644
> --- a/drivers/staging/iio/imu/adis16400_ring.c
> +++ b/drivers/staging/iio/imu/adis16400_ring.c
> @@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>  	struct adis16400_state *st
>  		= container_of(work_s, struct adis16400_state,
>  			       work_trigger_to_ring);
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  
>  	int i = 0;
>  	s16 *data;
> -	size_t datasize = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  
>  	data = kmalloc(datasize , GFP_KERNEL);
>  	if (data == NULL) {
> @@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
> -			for (; i < st->indio_dev->scan_count; i++)
> +			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 (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>  
> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> -					    (u8 *)data,
> -					    st->last_timestamp);
> +	ring->access.store_to(ring,
> +			(u8 *) data,
> +			st->last_timestamp);
>  
>  	iio_trigger_notify_done(st->indio_dev->trig);
>  	kfree(data);
> @@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
>  	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);
> -	/* Set default scan mode */
> -
> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
> -	indio_dev->scan_timestamp = true;
> -
> -	indio_dev->scan_el_attrs = &adis16400_scan_el_group;
>  
>  	ring = iio_sw_rb_allocate(indio_dev);
>  	if (!ring) {
> @@ -214,11 +197,27 @@ 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;
>  	ring->predisable = &iio_triggered_ring_predisable;
>  	ring->owner = THIS_MODULE;
>  
> +	/* Set default scan mode */
> +	iio_scan_mask_set(ring, iio_scan_el_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_adc_0.number);
> +
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
>  	if (ret)
>  		goto error_iio_sw_rb_free;
> diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
> index dd4d87a..5c0e56a 100644
> --- a/drivers/staging/iio/industrialio-core.c
> +++ b/drivers/staging/iio/industrialio-core.c
> @@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
>  		goto error_ret;
>  	}
>  
> -	if (dev_info->scan_el_attrs) {
> -		ret = sysfs_create_group(&dev_info->dev.kobj,
> -					 dev_info->scan_el_attrs);
> -		if (ret)
> -			dev_err(&dev_info->dev,
> -				"Failed to add sysfs scan els\n");
> -	}
> -
>  error_ret:
>  	return ret;
>  }
>  
>  static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
>  {
> -	if (dev_info->scan_el_attrs)
> -		sysfs_remove_group(&dev_info->dev.kobj,
> -				   dev_info->scan_el_attrs);
> -
>  	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
>  }
>  
> diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
> index 610c2b6..148ca5c 100644
> --- a/drivers/staging/iio/industrialio-ring.c
> +++ b/drivers/staging/iio/industrialio-ring.c
> @@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
>  	if (ret)
>  		goto error_free_ring_buffer_event_chrdev;
>  
> +	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_event_chrdev;
> +		}
> +	}
> +
>  	return ret;
>  error_free_ring_buffer_event_chrdev:
>  	__iio_free_ring_buffer_event_chrdev(ring);
> @@ -291,6 +301,10 @@ 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_free_ring_buffer_access_chrdev(ring);
>  	__iio_free_ring_buffer_event_chrdev(ring);
>  	device_del(&ring->dev);
> @@ -468,7 +482,7 @@ ssize_t iio_scan_el_show(struct device *dev,
>  	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct iio_scan_el *this_el = to_iio_scan_el(attr);
>  
> -	ret = iio_scan_mask_query(indio_dev, this_el->number);
> +	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>  	if (ret < 0)
>  		return ret;
>  	return sprintf(buf, "%d\n", ret);
> @@ -491,19 +505,17 @@ ssize_t iio_scan_el_store(struct device *dev,
>  		ret = -EBUSY;
>  		goto error_ret;
>  	}
> -	ret = iio_scan_mask_query(indio_dev, this_el->number);
> +	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>  	if (ret < 0)
>  		goto error_ret;
>  	if (!state && ret) {
> -		ret = iio_scan_mask_clear(indio_dev, this_el->number);
> +		ret = iio_scan_mask_clear(indio_dev->ring, this_el->number);
>  		if (ret)
>  			goto error_ret;
> -		indio_dev->scan_count--;
>  	} else if (state && !ret) {
> -		ret = iio_scan_mask_set(indio_dev, this_el->number);
> +		ret = iio_scan_mask_set(indio_dev->ring, this_el->number);
>  		if (ret)
>  			goto error_ret;
> -		indio_dev->scan_count++;
>  	}
>  	if (this_el->set_state)
>  		ret = this_el->set_state(this_el, indio_dev, state);
> @@ -520,7 +532,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
>  			    char *buf)
>  {
>  	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> -	return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
> +	return sprintf(buf, "%d\n", indio_dev->ring->scan_timestamp);
>  }
>  EXPORT_SYMBOL(iio_scan_el_ts_show);
>  
> @@ -538,7 +550,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
>  		ret = -EBUSY;
>  		goto error_ret;
>  	}
> -	indio_dev->scan_timestamp = state;
> +	indio_dev->ring->scan_timestamp = 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 ac017b1..6124353 100644
> --- a/drivers/staging/iio/ring_generic.h
> +++ b/drivers/staging/iio/ring_generic.h
> @@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
>   * @bytes_per_datum	[DEVICE] size of individual datum including timestamp
>   * @bpe:		[DEVICE] size of individual channel value
>   * @loopcount:		[INTERN] number of times the ring has looped
> + * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
> + *			control method is used
> + * @scan_count:	[INTERN] the number of elements in the current scan mode
> + * @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
>   * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
> @@ -124,6 +129,10 @@ struct iio_ring_buffer {
>  	int				bytes_per_datum;
>  	int				bpe;
>  	int				loopcount;
> +	struct attribute_group		*scan_el_attrs;
> +	int				scan_count;
> +	u32				scan_mask;
> +	bool				scan_timestamp;
>  	struct iio_handler		access_handler;
>  	struct iio_event_interface	ev_int;
>  	struct iio_shared_ev_pointer	shared_ev_pointer;
> @@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
>  				   iio_scan_el_ts_store),	\
>  	}
>  
> +/*
> + * These are mainly provided to allow for a change of implementation if a device
> + * has a large number of scan elements
> + */
> +#define IIO_MAX_SCAN_LENGTH 31
> +
> +/* note 0 used as error indicator as it doesn't make sense. */
> +static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
> +{
> +	while (*av_masks) {
> +		if (!(~*av_masks & mask))
> +			return *av_masks;
> +		av_masks++;
> +	}
> +	return 0;
> +}
> +
> +static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
> +{
> +	struct iio_dev *dev_info = ring->indio_dev;
> +	u32 mask;
> +
> +	if (bit > IIO_MAX_SCAN_LENGTH)
> +		return -EINVAL;
> +
> +	if (!ring->scan_mask)
> +		return 0;
> +
> +	if (dev_info->available_scan_masks)
> +		mask = iio_scan_mask_match(dev_info->available_scan_masks,
> +					ring->scan_mask);
> +	else
> +		mask = ring->scan_mask;
> +
> +	if (!mask)
> +		return -EINVAL;
> +
> +	return !!(mask & (1 << bit));
> +};
> +
> +static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
> +{
> +	struct iio_dev *dev_info = ring->indio_dev;
> +	u32 mask;
> +	u32 trialmask = ring->scan_mask | (1 << bit);
> +
> +	if (bit > IIO_MAX_SCAN_LENGTH)
> +		return -EINVAL;
> +	if (dev_info->available_scan_masks) {
> +		mask = iio_scan_mask_match(dev_info->available_scan_masks,
> +					trialmask);
> +		if (!mask)
> +			return -EINVAL;
> +	}
> +	ring->scan_mask = trialmask;
> +	ring->scan_count++;
> +
> +	return 0;
> +};
> +
> +static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
> +{
> +	if (bit > IIO_MAX_SCAN_LENGTH)
> +		return -EINVAL;
> +	ring->scan_mask &= ~(1 << bit);
> +	ring->scan_count--;
> +	return 0;
> +};
> +
> +/**
> + * iio_scan_mask_count_to_right() - how many scan elements occur before here
> + * @dev_info: the iio_device whose scan mode we are querying
> + * @bit: which number scan element is this
> + **/
> +static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
> +						int bit)
> +{
> +	int count = 0;
> +	int mask = (1 << bit);
> +	if (bit > IIO_MAX_SCAN_LENGTH)
> +		return -EINVAL;
> +	while (mask) {
> +		mask >>= 1;
> +		if (mask & ring->scan_mask)
> +			count++;
> +	}
> +
> +	return count;
> +}
> +
> +
>  static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
>  {
>  	put_device(&ring->dev);
> diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
> index 99efb6b..52624ac 100644
> --- a/drivers/staging/iio/ring_sw.c
> +++ b/drivers/staging/iio/ring_sw.c
> @@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
>  
>  int iio_sw_ring_preenable(struct iio_dev *indio_dev)
>  {
> +	struct iio_ring_buffer *ring = indio_dev->ring;
>  	size_t size;
>  	dev_dbg(&indio_dev->dev, "%s\n", __func__);
>  	/* Check if there are any scan elements enabled, if not fail*/
> -	if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
> +	if (!(ring->scan_count || ring->scan_timestamp))
>  		return -EINVAL;
> -	if (indio_dev->scan_timestamp)
> -		if (indio_dev->scan_count)
> +	if (ring->scan_timestamp)
> +		if (ring->scan_count)
>  			/* Timestamp (aligned to s64) and data */
> -			size = (((indio_dev->scan_count * indio_dev->ring->bpe)
> +			size = (((ring->scan_count * ring->bpe)
>  					+ sizeof(s64) - 1)
>  				& ~(sizeof(s64) - 1))
>  				+ sizeof(s64);
>  		else /* Timestamp only  */
>  			size = sizeof(s64);
>  	else /* Data only */
> -		size = indio_dev->scan_count * indio_dev->ring->bpe;
> -	indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
> +		size = ring->scan_count * ring->bpe;
> +	ring->access.set_bytes_per_datum(ring, size);
>  
>  	return 0;
>  }
> @@ -462,9 +463,9 @@ 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);
> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>  	int len = 0;
> -	size_t datasize = st->indio_dev
> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>  	char *data = kmalloc(datasize, GFP_KERNEL);
>  
>  	if (data == NULL) {
> @@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
>  		return;
>  	}
>  
> -	if (st->indio_dev->scan_count)
> +	if (ring->scan_count)
>  		len = st->get_ring_element(st, data);
>  
>  	  /* Guaranteed to be aligned with 8 byte boundary */
> -	if (st->indio_dev->scan_timestamp)
> +	if (ring->scan_timestamp)
>  		*(s64 *)(((phys_addr_t)data + len
>  				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
>  			= st->last_timestamp;
> -	  st->indio_dev->ring->access.store_to(st->indio_dev->ring,
> -					(u8 *)data,
> +	ring->access.store_to(ring,
> +			(u8 *)data,
>  			st->last_timestamp);
>  
>  	iio_trigger_notify_done(st->indio_dev->trig);


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

* Re: [PATCH 2/2] staging:iio move scan_elements into ring buffer
  2010-08-30 12:58             ` Jonathan Cameron
@ 2010-08-30 13:37               ` Manuel Stahl
  2010-08-30 14:09                 ` Jonathan Cameron
       [not found]                 ` <4C7BD886.3060109@cam.ac.uk>
  0 siblings, 2 replies; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 13:37 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Song, Barry

[-- Attachment #1: Type: text/plain, Size: 53108 bytes --]

Am 30.08.2010 14:58, schrieb Jonathan Cameron:
> On 08/30/10 11:55, Manuel Stahl wrote:
>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
>
> On more complex patches like this, could you verify which devices
> you have tested against? Given the nature of that patch it
> probably doesn't matter that much, but it's nice to save people
> from wondering if they need to test on devices you have already
> tried it with.

I have an sca3000 and an adis16405 to test with. The patch was made 
against v26.36-rc2 and compiled fine for all drivers in staging.

> This one certainly turned out to be more complex that I was
> anticipating! Mostly movement of code so easy enough to
> review.
>
> In one place as commented you made a change that obscured exactly
> which bits your patch was changing. (see below).  I have nothing
> against what you did, but would rather not have seen it in this
> patch as it obscures what you are doing and that is never a good
> idea! (in lis3l02dq_configure_ring).

I just wanted to have the same structure as for the adisXXXXX devices. 
Then maybe future changes can be done easier with find and replace.

> There is also a movement of available_scan_masks in the iio_dev
> structure that is unexplained.  It doesn't matter in the slightest
> but is an odd thing to do without reason.

Oh, this was an accident. I also moved available_scan_masks and realised 
afterwards that it's not buffer but device dependant.

> Neither of the above matter, they are just things I picked up
> on whilst reviewing.

The next patch will be a sync of docu and device ABI. Will again break 
most analog drivers, but should be doable by find and replace ;)

> Thanks for doing this!
>
> More than happy to add
>
> Signed-off-by: Jonathan Cameron<jic23@cam.ac.uk>
>
> Please forward to Greg KH (assuming no one shouts - might be worth
> holding this one for a day or so given it effects a lot of drivers)
>
> Again, sorry to the Analog guys, this one is going to thoroughly break
> you tree when it hits it.  Still better now than later when it effects
> even more drivers.
>
> Note this also needs a patch updating the documentation.
>
>
>> ---
>>   drivers/staging/iio/accel/adis16209_ring.c |   41 ++++++------
>>   drivers/staging/iio/accel/adis16240_ring.c |   33 +++++-----
>>   drivers/staging/iio/accel/lis3l02dq_ring.c |   62 +++++++++--------
>>   drivers/staging/iio/accel/sca3000_ring.c   |    2 +-
>>   drivers/staging/iio/adc/max1363_core.c     |    1 -
>>   drivers/staging/iio/adc/max1363_ring.c     |   18 +++--
>>   drivers/staging/iio/gyro/adis16260_ring.c  |   31 ++++-----
>>   drivers/staging/iio/iio.h                  |  102 +---------------------------
>>   drivers/staging/iio/imu/adis16300_ring.c   |   43 ++++++------
>>   drivers/staging/iio/imu/adis16350_ring.c   |   47 ++++++-------
>>   drivers/staging/iio/imu/adis16400_ring.c   |   49 +++++++-------
>>   drivers/staging/iio/industrialio-core.c    |   12 ---
>>   drivers/staging/iio/industrialio-ring.c    |   28 ++++++--
>>   drivers/staging/iio/ring_generic.h         |  100 +++++++++++++++++++++++++++
>>   drivers/staging/iio/ring_sw.c              |   25 ++++---
>>   15 files changed, 298 insertions(+), 296 deletions(-)
>>
>> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
>> index d40b95f..120bf91 100644
>> --- a/drivers/staging/iio/accel/adis16209_ring.c
>> +++ b/drivers/staging/iio/accel/adis16209_ring.c
>> @@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>>   	struct adis16209_state *st
>>   		= container_of(work_s, struct adis16209_state,
>>   			       work_trigger_to_ring);
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>
>>   	int i = 0;
>>   	s16 *data;
>> -	size_t datasize = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> -					    (u8 *)data,
>> -					    st->last_timestamp);
>> +	ring->access.store_to(ring,
>> +			      (u8 *)data,
>> +			      st->last_timestamp);
>>
>>   	iio_trigger_notify_done(st->indio_dev->trig);
>>   	kfree(data);
>> @@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16209_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -182,11 +169,23 @@ 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;
>>   	ring->predisable =&iio_triggered_ring_predisable;
>>   	ring->owner = THIS_MODULE;
>>
>> +	/* Set default scan mode */
>> +	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.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,&adis16209_poll_func_th);
>>   	if (ret)
>>   		goto error_iio_sw_rb_free;
>> diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
>> index 462d452..581d0e5 100644
>> --- a/drivers/staging/iio/accel/adis16240_ring.c
>> +++ b/drivers/staging/iio/accel/adis16240_ring.c
>> @@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>>   	struct adis16240_state *st
>>   		= container_of(work_s, struct adis16240_state,
>>   				work_trigger_to_ring);
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>
>>   	int i = 0;
>>   	s16 *data;
>> -	size_t datasize = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> +	ring->access.store_to(ring,
>>   			(u8 *)data,
>>   			st->last_timestamp);
>>
>> @@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16240_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -172,11 +161,21 @@ 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;
>>   	ring->predisable =&iio_triggered_ring_predisable;
>>   	ring->owner = THIS_MODULE;
>>
>> +	/* Set default scan mode */
>> +	iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.number);
>> +
>>   	ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16240_poll_func_th);
>>   	if (ret)
>>   		goto error_iio_sw_rb_free;
>> diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
>> index 4c1b36a..a68a381 100644
>> --- a/drivers/staging/iio/accel/lis3l02dq_ring.c
>> +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
>> @@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
>>   	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;
>>   	s16 *data;
>>
>> -	while (dev_info->scan_el_attrs->attrs[i]) {
>> +	while (scan_el_attrs->attrs[i]) {
>>   		el = to_iio_scan_el((struct device_attribute *)
>> -				    (dev_info->scan_el_attrs->attrs[i]));
>> +				    (scan_el_attrs->attrs[i]));
>>   		/* label is in fact the address */
>>   		if (el->label == this_attr->address)
>>   			break;
>>   		i++;
>>   	}
>> -	if (!dev_info->scan_el_attrs->attrs[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(dev_info, el->number);
>> +	ret = iio_scan_mask_query(ring, el->number);
>>   	if (ret<  0)
>>   		goto error_ret;
>>   	if (ret) {
>> -		data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
>> +		data = kmalloc(ring->access.get_bytes_per_datum(ring),
>>   			       GFP_KERNEL);
>>   		if (data == NULL)
>>   			return -ENOMEM;
>> -		ret = dev_info->ring->access.read_last(dev_info->ring,
>> -						      (u8 *)data);
>> +		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(dev_info, el->number);
>> +	len = iio_scan_mask_count_to_right(ring, el->number);
>>   	if (len<  0) {
>>   		ret = len;
>>   		goto error_free_data;
>> @@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
>>    **/
>>   static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>>   {
>> +	struct iio_ring_buffer *ring = st->help.indio_dev->ring;
>>   	struct spi_transfer *xfers;
>>   	struct spi_message msg;
>>   	int ret, i, j = 0;
>>
>> -	xfers = kzalloc((st->help.indio_dev->scan_count) * 2
>> +	xfers = kzalloc((ring->scan_count) * 2
>>   			* sizeof(*xfers), GFP_KERNEL);
>>   	if (!xfers)
>>   		return -ENOMEM;
>> @@ -223,7 +226,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++) {
>> -		if (st->help.indio_dev->scan_mask&  (1<<  i)) {
>> +		if (ring->scan_mask&  (1<<  i)) {
>>   			/* lower byte */
>>   			xfers[j].tx_buf = st->tx + 2*j;
>>   			st->tx[2*j] = read_all_tx_array[i*4];
>> @@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>>   	 * values in alternate bytes
>>   	 */
>>   	spi_message_init(&msg);
>> -	for (j = 0; j<  st->help.indio_dev->scan_count * 2; j++)
>> +	for (j = 0; j<  ring->scan_count * 2; j++)
>>   		spi_message_add_tail(&xfers[j],&msg);
>>
>>   	ret = spi_sync(st->us,&msg);
>> @@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
>>   	u8 *rx_array ;
>>   	s16 *data = (s16 *)buf;
>>
>> -	rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
>> +	rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
>>   	if (rx_array == NULL)
>>   		return -ENOMEM;
>>   	ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
>>   	if (ret<  0)
>>   		return ret;
>> -	for (i = 0; i<  h->indio_dev->scan_count; i++)
>> +	for (i = 0; i<  h->indio_dev->ring->scan_count; i++)
>>   		data[i] = combine_8_to_16(rx_array[i*4+1],
>>   					rx_array[i*4+3]);
>>   	kfree(rx_array);
>> @@ -479,28 +482,29 @@ 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);
>> -	/* Set default scan mode */
>>   	h->get_ring_element =&lis3l02dq_get_ring_element;
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&lis3l02dq_scan_el_group;
>>
>> -	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
>> -	if (!indio_dev->ring)
> Personally I'd have done this directly into indio_dev->ring
> as it would have reduced the lines changed count and kept
> your changes more apparent.  Still doesn't really matter and
> not worth respining the patch.
>> +	ring = iio_sw_rb_allocate(indio_dev);
>> +	if (!ring)
>>   		return -ENOMEM;
>>
>> +	indio_dev->ring = ring;
>>   	/* Effectively select the ring buffer implementation */
>> -	iio_ring_sw_register_funcs(&indio_dev->ring->access);
>> -	indio_dev->ring->bpe = 2;
>> -	indio_dev->ring->preenable =&iio_sw_ring_preenable;
>> -	indio_dev->ring->postenable =&iio_triggered_ring_postenable;
>> -	indio_dev->ring->predisable =&iio_triggered_ring_predisable;
>> -	indio_dev->ring->owner = THIS_MODULE;
>> +	iio_ring_sw_register_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->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);
>>
>>   	ret = iio_alloc_pollfunc(indio_dev, NULL,&lis3l02dq_poll_func_th);
>>   	if (ret)
>> diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
>> index eff5b9a..6d19d15 100644
>> --- a/drivers/staging/iio/accel/sca3000_ring.c
>> +++ b/drivers/staging/iio/accel/sca3000_ring.c
>> @@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
>>
>>   int sca3000_configure_ring(struct iio_dev *indio_dev)
>>   {
>> -	indio_dev->scan_el_attrs =&sca3000_scan_el_group;
>>   	indio_dev->ring = sca3000_rb_allocate(indio_dev);
>>   	if (indio_dev->ring == NULL)
>>   		return -ENOMEM;
>>   	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
>>
>> +	indio_dev->ring->scan_el_attrs =&sca3000_scan_el_group;
>>   	indio_dev->ring->access.rip_lots =&sca3000_rip_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;
>> diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
>> index 6435e50..1dc428f 100644
>> --- a/drivers/staging/iio/adc/max1363_core.c
>> +++ b/drivers/staging/iio/adc/max1363_core.c
>> @@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
>>   	st->indio_dev->attrs = st->chip_info->dev_attrs;
>>
>>   	/* Todo: this shouldn't be here. */
>> -	st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
>>   	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/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
>> index edac0ba..1d6ce54 100644
>> --- a/drivers/staging/iio/adc/max1363_ring.c
>> +++ b/drivers/staging/iio/adc/max1363_ring.c
>> @@ -30,6 +30,7 @@
>>   /* Todo: test this */
>>   int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>>   {
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>   	unsigned long numvals;
>>   	int count = 0, ret;
>>   	u8 *ring_data;
>> @@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>>   		ret = -ENOMEM;
>>   		goto error_ret;
>>   	}
>> -	ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
>> -						ring_data);
>> +	ret = ring->access.read_last(ring, ring_data);
>>   	if (ret)
>>   		goto error_free_ring_data;
>>   	/* Need a count of channels prior to this one */
>> @@ -77,6 +77,7 @@ error_ret:
>>   static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>   {
>>   	struct max1363_state *st = indio_dev->dev_data;
>> +	struct iio_ring_buffer *ring = indio_dev->ring;
>>   	size_t d_size;
>>   	unsigned long numvals;
>>
>> @@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>   	 * Need to figure out the current mode based upon the requested
>>   	 * scan mask in iio_dev
>>   	 */
>> -	st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
>> +	st->current_mode = max1363_match_mode(ring->scan_mask,
>>   					st->chip_info);
>>   	if (!st->current_mode)
>>   		return -EINVAL;
>> @@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>   	max1363_set_scan_mode(st);
>>
>>   	numvals = hweight_long(st->current_mode->modemask);
>> -	if (indio_dev->ring->access.set_bytes_per_datum) {
>> +	if (ring->access.set_bytes_per_datum) {
>>   		if (st->chip_info->bits != 8)
>>   			d_size = numvals*2 + sizeof(s64);
>>   		else
>>   			d_size = numvals + sizeof(s64);
>>   		if (d_size % 8)
>>   			d_size += 8 - (d_size % 8);
>> -		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
>> +		ring->access.set_bytes_per_datum(ring, d_size);
>>   	}
>>
>>   	return 0;
>> @@ -135,7 +136,7 @@ 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 = st->indio_dev;
>> -	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
>> +	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
>>   	s64 time_ns;
>>   	__u8 *rxbuf;
>>   	int b_sent;
>> @@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
>>
>>   	memcpy(rxbuf + d_size - sizeof(s64),&time_ns, sizeof(time_ns));
>>
>> -	indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
>> +	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
>>   done:
>>   	kfree(rxbuf);
>>   	atomic_dec(&st->protect_ring);
>> @@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
>>   		goto error_ret;
>>   	}
>>   	/* Effectively select the ring buffer implementation */
>> -	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
>> +	iio_ring_sw_register_funcs(&indio_dev->ring->access);
>>   	ret = iio_alloc_pollfunc(indio_dev, NULL,&max1363_poll_func_th);
>>   	if (ret)
>>   		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;
>> diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
>> index 055d5e8..0334860 100644
>> --- a/drivers/staging/iio/gyro/adis16260_ring.c
>> +++ b/drivers/staging/iio/gyro/adis16260_ring.c
>> @@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>>   	struct adis16260_state *st
>>   		= container_of(work_s, struct adis16260_state,
>>   				work_trigger_to_ring);
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>
>>   	int i = 0;
>>   	s16 *data;
>> -	size_t datasize = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> +	ring->access.store_to(ring,
>>   			(u8 *)data,
>>   			st->last_timestamp);
>>
>> @@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16260_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -174,11 +164,20 @@ 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;
>>   	ring->predisable =&iio_triggered_ring_predisable;
>>   	ring->owner = THIS_MODULE;
>>
>> +	/* Set default scan mode */
>> +	iio_scan_mask_set(ring, iio_scan_el_supply.number);
>> +	iio_scan_mask_set(ring, iio_scan_el_gyro.number);
>> +	iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
>> +	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)
>>   		goto error_iio_sw_rb_free;
>> diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
>> index 9d0ca12..3a4e8c3 100644
>> --- a/drivers/staging/iio/iio.h
>> +++ b/drivers/staging/iio/iio.h
>> @@ -87,15 +87,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
>>    * @event_attrs:	[DRIVER] event control attributes
>>    * @event_conf_attrs:	[DRIVER] event configuration attributes
>>    * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
>> + * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
>>    * @ring:		[DRIVER] any ring buffer present
>>    * @mlock:		[INTERN] lock used to prevent simultaneous device state
>>    *			changes
>> - * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
>> - *			control method is used
>> - * @scan_count:	[INTERN] the number of elements in the current scan mode
>> - * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
>> - * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
>> - * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
>>    * @trig:		[INTERN] current device trigger (ring buffer modes)
>>    * @pollfunc:		[DRIVER] function run on trigger being recieved
>>    **/
>> @@ -115,107 +110,14 @@ struct iio_dev {
>>
>>   	struct iio_event_interface	*event_interfaces;
>>
> Why move this element?
>> +	u32				*available_scan_masks;
>>   	struct iio_ring_buffer		*ring;
>>   	struct mutex			mlock;
>>
>> -	struct attribute_group		*scan_el_attrs;
>> -	int				scan_count;
>> -
>> -	u32				scan_mask;
>> -	u32				*available_scan_masks;
>> -	bool				scan_timestamp;
>>   	struct iio_trigger		*trig;
>>   	struct iio_poll_func		*pollfunc;
>>   };
>>
>> -/*
>> - * These are mainly provided to allow for a change of implementation if a device
>> - * has a large number of scan elements
>> - */
>> -#define IIO_MAX_SCAN_LENGTH 31
>> -
>> -/* note 0 used as error indicator as it doesn't make sense. */
>> -static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
>> -{
>> -	while (*av_masks) {
>> -		if (!(~*av_masks&  mask))
>> -			return *av_masks;
>> -		av_masks++;
>> -	}
>> -	return 0;
>> -}
>> -
>> -static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
>> -{
>> -	u32 mask;
>> -
>> -	if (bit>  IIO_MAX_SCAN_LENGTH)
>> -		return -EINVAL;
>> -
>> -	if (!dev_info->scan_mask)
>> -		return 0;
>> -
>> -	if (dev_info->available_scan_masks)
>> -		mask = iio_scan_mask_match(dev_info->available_scan_masks,
>> -					dev_info->scan_mask);
>> -	else
>> -		mask = dev_info->scan_mask;
>> -
>> -	if (!mask)
>> -		return -EINVAL;
>> -
>> -	return !!(mask&  (1<<  bit));
>> -};
>> -
>> -static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
>> -{
>> -	u32 mask;
>> -	u32 trialmask = dev_info->scan_mask | (1<<  bit);
>> -
>> -	if (bit>  IIO_MAX_SCAN_LENGTH)
>> -		return -EINVAL;
>> -	if (dev_info->available_scan_masks) {
>> -		mask = iio_scan_mask_match(dev_info->available_scan_masks,
>> -					trialmask);
>> -		if (!mask)
>> -			return -EINVAL;
>> -	}
>> -	dev_info->scan_mask = trialmask;
>> -	dev_info->scan_count++;
>> -
>> -	return 0;
>> -};
>> -
>> -static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
>> -{
>> -	if (bit>  IIO_MAX_SCAN_LENGTH)
>> -		return -EINVAL;
>> -	dev_info->scan_mask&= ~(1<<  bit);
>> -	dev_info->scan_count--;
>> -	return 0;
>> -};
>> -
>> -/**
>> - * iio_scan_mask_count_to_right() - how many scan elements occur before here
>> - * @dev_info: the iio_device whose scan mode we are querying
>> - * @bit: which number scan element is this
>> - **/
>> -static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
>> -						int bit)
>> -{
>> -	int count = 0;
>> -	int mask = (1<<  bit);
>> -	if (bit>  IIO_MAX_SCAN_LENGTH)
>> -		return -EINVAL;
>> -	while (mask) {
>> -		mask>>= 1;
>> -		if (mask&  dev_info->scan_mask)
>> -			count++;
>> -	}
>> -
>> -	return count;
>> -}
>> -
>>   /**
>>    * iio_device_register() - register a device with the IIO subsystem
>>    * @dev_info:		Device structure filled by the device driver
>> diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
>> index 854183c..742cad6 100644
>> --- a/drivers/staging/iio/imu/adis16300_ring.c
>> +++ b/drivers/staging/iio/imu/adis16300_ring.c
>> @@ -134,11 +134,11 @@ 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 = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> -					    (u8 *)data,
>> -					    st->last_timestamp);
>> +	ring->access.store_to(ring,
>> +			(u8 *)data,
>> +			st->last_timestamp);
>>
>>   	iio_trigger_notify_done(st->indio_dev->trig);
>>   	kfree(data);
>> @@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16300_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -202,11 +188,24 @@ int adis16300_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 =&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_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_adc_0.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;
>> diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
>> index 9620cbe..a0b80e4 100644
>> --- a/drivers/staging/iio/imu/adis16350_ring.c
>> +++ b/drivers/staging/iio/imu/adis16350_ring.c
>> @@ -134,11 +134,11 @@ 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 = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> -					    (u8 *)data,
>> -					    st->last_timestamp);
>> +	ring->access.store_to(ring,
>> +			(u8 *)data,
>> +			st->last_timestamp);
>>
>>   	iio_trigger_notify_done(st->indio_dev->trig);
>>   	kfree(data);
>> @@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16350_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -204,11 +188,26 @@ int adis16350_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 =&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_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_adc_0.number);
>> +
>>   	ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16350_poll_func_th);
>>   	if (ret)
>>   		goto error_iio_sw_rb_free;
>> diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
>> index c8e2316..667f77b 100644
>> --- a/drivers/staging/iio/imu/adis16400_ring.c
>> +++ b/drivers/staging/iio/imu/adis16400_ring.c
>> @@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>>   	struct adis16400_state *st
>>   		= container_of(work_s, struct adis16400_state,
>>   			       work_trigger_to_ring);
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>
>>   	int i = 0;
>>   	s16 *data;
>> -	size_t datasize = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>
>>   	data = kmalloc(datasize , GFP_KERNEL);
>>   	if (data == NULL) {
>> @@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>> -			for (; i<  st->indio_dev->scan_count; i++)
>> +			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 (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>
>> -	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> -					    (u8 *)data,
>> -					    st->last_timestamp);
>> +	ring->access.store_to(ring,
>> +			(u8 *) data,
>> +			st->last_timestamp);
>>
>>   	iio_trigger_notify_done(st->indio_dev->trig);
>>   	kfree(data);
>> @@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
>>   	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);
>> -	/* Set default scan mode */
>> -
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>> -	iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>> -	indio_dev->scan_timestamp = true;
>> -
>> -	indio_dev->scan_el_attrs =&adis16400_scan_el_group;
>>
>>   	ring = iio_sw_rb_allocate(indio_dev);
>>   	if (!ring) {
>> @@ -214,11 +197,27 @@ 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;
>>   	ring->predisable =&iio_triggered_ring_predisable;
>>   	ring->owner = THIS_MODULE;
>>
>> +	/* Set default scan mode */
>> +	iio_scan_mask_set(ring, iio_scan_el_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_adc_0.number);
>> +
>>   	ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16400_poll_func_th);
>>   	if (ret)
>>   		goto error_iio_sw_rb_free;
>> diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
>> index dd4d87a..5c0e56a 100644
>> --- a/drivers/staging/iio/industrialio-core.c
>> +++ b/drivers/staging/iio/industrialio-core.c
>> @@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
>>   		goto error_ret;
>>   	}
>>
>> -	if (dev_info->scan_el_attrs) {
>> -		ret = sysfs_create_group(&dev_info->dev.kobj,
>> -					 dev_info->scan_el_attrs);
>> -		if (ret)
>> -			dev_err(&dev_info->dev,
>> -				"Failed to add sysfs scan els\n");
>> -	}
>> -
>>   error_ret:
>>   	return ret;
>>   }
>>
>>   static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
>>   {
>> -	if (dev_info->scan_el_attrs)
>> -		sysfs_remove_group(&dev_info->dev.kobj,
>> -				   dev_info->scan_el_attrs);
>> -
>>   	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
>>   }
>>
>> diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
>> index 610c2b6..148ca5c 100644
>> --- a/drivers/staging/iio/industrialio-ring.c
>> +++ b/drivers/staging/iio/industrialio-ring.c
>> @@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
>>   	if (ret)
>>   		goto error_free_ring_buffer_event_chrdev;
>>
>> +	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_event_chrdev;
>> +		}
>> +	}
>> +
>>   	return ret;
>>   error_free_ring_buffer_event_chrdev:
>>   	__iio_free_ring_buffer_event_chrdev(ring);
>> @@ -291,6 +301,10 @@ 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_free_ring_buffer_access_chrdev(ring);
>>   	__iio_free_ring_buffer_event_chrdev(ring);
>>   	device_del(&ring->dev);
>> @@ -468,7 +482,7 @@ ssize_t iio_scan_el_show(struct device *dev,
>>   	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>>   	struct iio_scan_el *this_el = to_iio_scan_el(attr);
>>
>> -	ret = iio_scan_mask_query(indio_dev, this_el->number);
>> +	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>>   	if (ret<  0)
>>   		return ret;
>>   	return sprintf(buf, "%d\n", ret);
>> @@ -491,19 +505,17 @@ ssize_t iio_scan_el_store(struct device *dev,
>>   		ret = -EBUSY;
>>   		goto error_ret;
>>   	}
>> -	ret = iio_scan_mask_query(indio_dev, this_el->number);
>> +	ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>>   	if (ret<  0)
>>   		goto error_ret;
>>   	if (!state&&  ret) {
>> -		ret = iio_scan_mask_clear(indio_dev, this_el->number);
>> +		ret = iio_scan_mask_clear(indio_dev->ring, this_el->number);
>>   		if (ret)
>>   			goto error_ret;
>> -		indio_dev->scan_count--;
>>   	} else if (state&&  !ret) {
>> -		ret = iio_scan_mask_set(indio_dev, this_el->number);
>> +		ret = iio_scan_mask_set(indio_dev->ring, this_el->number);
>>   		if (ret)
>>   			goto error_ret;
>> -		indio_dev->scan_count++;
>>   	}
>>   	if (this_el->set_state)
>>   		ret = this_el->set_state(this_el, indio_dev, state);
>> @@ -520,7 +532,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
>>   			    char *buf)
>>   {
>>   	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>> -	return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
>> +	return sprintf(buf, "%d\n", indio_dev->ring->scan_timestamp);
>>   }
>>   EXPORT_SYMBOL(iio_scan_el_ts_show);
>>
>> @@ -538,7 +550,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
>>   		ret = -EBUSY;
>>   		goto error_ret;
>>   	}
>> -	indio_dev->scan_timestamp = state;
>> +	indio_dev->ring->scan_timestamp = 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 ac017b1..6124353 100644
>> --- a/drivers/staging/iio/ring_generic.h
>> +++ b/drivers/staging/iio/ring_generic.h
>> @@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
>>    * @bytes_per_datum	[DEVICE] size of individual datum including timestamp
>>    * @bpe:		[DEVICE] size of individual channel value
>>    * @loopcount:		[INTERN] number of times the ring has looped
>> + * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
>> + *			control method is used
>> + * @scan_count:	[INTERN] the number of elements in the current scan mode
>> + * @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
>>    * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
>> @@ -124,6 +129,10 @@ struct iio_ring_buffer {
>>   	int				bytes_per_datum;
>>   	int				bpe;
>>   	int				loopcount;
>> +	struct attribute_group		*scan_el_attrs;
>> +	int				scan_count;
>> +	u32				scan_mask;
>> +	bool				scan_timestamp;
>>   	struct iio_handler		access_handler;
>>   	struct iio_event_interface	ev_int;
>>   	struct iio_shared_ev_pointer	shared_ev_pointer;
>> @@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
>>   				   iio_scan_el_ts_store),	\
>>   	}
>>
>> +/*
>> + * These are mainly provided to allow for a change of implementation if a device
>> + * has a large number of scan elements
>> + */
>> +#define IIO_MAX_SCAN_LENGTH 31
>> +
>> +/* note 0 used as error indicator as it doesn't make sense. */
>> +static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
>> +{
>> +	while (*av_masks) {
>> +		if (!(~*av_masks&  mask))
>> +			return *av_masks;
>> +		av_masks++;
>> +	}
>> +	return 0;
>> +}
>> +
>> +static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
>> +{
>> +	struct iio_dev *dev_info = ring->indio_dev;
>> +	u32 mask;
>> +
>> +	if (bit>  IIO_MAX_SCAN_LENGTH)
>> +		return -EINVAL;
>> +
>> +	if (!ring->scan_mask)
>> +		return 0;
>> +
>> +	if (dev_info->available_scan_masks)
>> +		mask = iio_scan_mask_match(dev_info->available_scan_masks,
>> +					ring->scan_mask);
>> +	else
>> +		mask = ring->scan_mask;
>> +
>> +	if (!mask)
>> +		return -EINVAL;
>> +
>> +	return !!(mask&  (1<<  bit));
>> +};
>> +
>> +static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
>> +{
>> +	struct iio_dev *dev_info = ring->indio_dev;
>> +	u32 mask;
>> +	u32 trialmask = ring->scan_mask | (1<<  bit);
>> +
>> +	if (bit>  IIO_MAX_SCAN_LENGTH)
>> +		return -EINVAL;
>> +	if (dev_info->available_scan_masks) {
>> +		mask = iio_scan_mask_match(dev_info->available_scan_masks,
>> +					trialmask);
>> +		if (!mask)
>> +			return -EINVAL;
>> +	}
>> +	ring->scan_mask = trialmask;
>> +	ring->scan_count++;
>> +
>> +	return 0;
>> +};
>> +
>> +static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
>> +{
>> +	if (bit>  IIO_MAX_SCAN_LENGTH)
>> +		return -EINVAL;
>> +	ring->scan_mask&= ~(1<<  bit);
>> +	ring->scan_count--;
>> +	return 0;
>> +};
>> +
>> +/**
>> + * iio_scan_mask_count_to_right() - how many scan elements occur before here
>> + * @dev_info: the iio_device whose scan mode we are querying
>> + * @bit: which number scan element is this
>> + **/
>> +static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
>> +						int bit)
>> +{
>> +	int count = 0;
>> +	int mask = (1<<  bit);
>> +	if (bit>  IIO_MAX_SCAN_LENGTH)
>> +		return -EINVAL;
>> +	while (mask) {
>> +		mask>>= 1;
>> +		if (mask&  ring->scan_mask)
>> +			count++;
>> +	}
>> +
>> +	return count;
>> +}
>> +
>> +
>>   static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
>>   {
>>   	put_device(&ring->dev);
>> diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
>> index 99efb6b..52624ac 100644
>> --- a/drivers/staging/iio/ring_sw.c
>> +++ b/drivers/staging/iio/ring_sw.c
>> @@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
>>
>>   int iio_sw_ring_preenable(struct iio_dev *indio_dev)
>>   {
>> +	struct iio_ring_buffer *ring = indio_dev->ring;
>>   	size_t size;
>>   	dev_dbg(&indio_dev->dev, "%s\n", __func__);
>>   	/* Check if there are any scan elements enabled, if not fail*/
>> -	if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
>> +	if (!(ring->scan_count || ring->scan_timestamp))
>>   		return -EINVAL;
>> -	if (indio_dev->scan_timestamp)
>> -		if (indio_dev->scan_count)
>> +	if (ring->scan_timestamp)
>> +		if (ring->scan_count)
>>   			/* Timestamp (aligned to s64) and data */
>> -			size = (((indio_dev->scan_count * indio_dev->ring->bpe)
>> +			size = (((ring->scan_count * ring->bpe)
>>   					+ sizeof(s64) - 1)
>>   				&  ~(sizeof(s64) - 1))
>>   				+ sizeof(s64);
>>   		else /* Timestamp only  */
>>   			size = sizeof(s64);
>>   	else /* Data only */
>> -		size = indio_dev->scan_count * indio_dev->ring->bpe;
>> -	indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
>> +		size = ring->scan_count * ring->bpe;
>> +	ring->access.set_bytes_per_datum(ring, size);
>>
>>   	return 0;
>>   }
>> @@ -462,9 +463,9 @@ 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);
>> +	struct iio_ring_buffer *ring = st->indio_dev->ring;
>>   	int len = 0;
>> -	size_t datasize = st->indio_dev
>> -		->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>> +	size_t datasize = ring->access.get_bytes_per_datum(ring);
>>   	char *data = kmalloc(datasize, GFP_KERNEL);
>>
>>   	if (data == NULL) {
>> @@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
>>   		return;
>>   	}
>>
>> -	if (st->indio_dev->scan_count)
>> +	if (ring->scan_count)
>>   		len = st->get_ring_element(st, data);
>>
>>   	  /* Guaranteed to be aligned with 8 byte boundary */
>> -	if (st->indio_dev->scan_timestamp)
>> +	if (ring->scan_timestamp)
>>   		*(s64 *)(((phys_addr_t)data + len
>>   				+ sizeof(s64) - 1)&  ~(sizeof(s64) - 1))
>>   			= st->last_timestamp;
>> -	  st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> -					(u8 *)data,
>> +	ring->access.store_to(ring,
>> +			(u8 *)data,
>>   			st->last_timestamp);
>>
>>   	iio_trigger_notify_done(st->indio_dev->trig);
>


-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* [PATCH 1/3] staging:iio update documentation
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
  2010-08-30 12:58             ` Jonathan Cameron
@ 2010-08-30 14:03             ` Manuel Stahl
  2010-08-30 14:23               ` Jonathan Cameron
  2010-08-30 14:03             ` [PATCH 2/3] staging:iio sync drivers with current ABI Manuel Stahl
  2010-08-30 14:03             ` [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation Manuel Stahl
  3 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 14:03 UTC (permalink / raw)
  To: linux-iio


Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
---
 drivers/staging/iio/Documentation/ring.txt        |    6 +-
 drivers/staging/iio/Documentation/sysfs-class-iio |   72 ++++++++++----------
 drivers/staging/iio/Documentation/userspace.txt   |   36 ++++++-----
 3 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index d2ca683..3696c36 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -47,10 +47,8 @@ request_update
   If parameters have changed that require reinitialization or configuration of
   the ring buffer this will trigger it.
 
-get_bpd, set_bpd
-  Get/set the number of bytes for a given reading (single element, not sample set)
-  The value of bps (bytes per set) is created from a combination of this and the
-  enabled scan elements.
+get_bytes_per_datum, set_bytes_per_datum
+  Get/set the number of bytes for a complete scan. (All samples + timestamp)
 
 get_length / set_length
   Get/set the number of sample sets that may be held by the buffer.
diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio
index 714b4c5..c137020 100644
--- a/drivers/staging/iio/Documentation/sysfs-class-iio
+++ b/drivers/staging/iio/Documentation/sysfs-class-iio
@@ -158,7 +158,7 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		Magnetic field along axis x, y or z (may be arbitrarily assigned)
 		channel m (not present if only one magnetometer at this orientation).
-		Data converted by application of offset then scale to Gauss
+		Data converted by application of offset then scale to Gauss.
 		Has all the equivalent modifiers as per in[m].
 
 What:		/sys/.../device[n]/device[n]:event[m]
@@ -212,39 +212,6 @@ Description:
 		The actual value of the threshold in raw device units obtained by
 		 reverse application of scale and offfset to the acceleration in m/s^2.
 
-What:		/sys/.../device[n]/scan_elements
-KernelVersion:	2.6.35
-Contact:	linux-iio@vger.kernel.org
-Description:
-		Directory containing interfaces for elements that will be captured
-		for a single triggered sample set in the buffer.
-
-What:		/sys/.../device[n]/scan_elements/[m]_accel_x0_en
-KernelVersion:	2.6.35
-Contact:	linux-iio@vger.kernel.org
-Description:
-		Scan element control for triggered data capture. m implies the
-		ordering within the buffer. Next the type is specified with
-		modifier and channel number as per the sysfs single channel
-		access above.
-
-What:		/sys/.../device[n]/scan_elements/accel[_x0]_precision
-KernelVersion:	2.6.35
-Contact:	linux-iio@vger.kernel.org
-Description:
-		Scan element precision within the buffer. Note that the
-		data alignment must restrictions must be read from within
-		buffer to work out full data alignment for data read
-		via buffer_access chrdev. _x0 dropped if shared across all
-		acceleration channels.
-
-What:		/sys/.../device[n]/scan_elements/accel[_x0]_shift
-KernelVersion:	2.6.35
-Contact:	linux-iio@vger.kernel.org
-Description:
-		A bit shift (to right) that must be applied prior to
-		extracting the bits specified by accel[_x0]_precision.
-
 What:		/sys/.../device[n]/device[n]:buffer:event/dev
 KernelVersion:	2.6.35
 Contact:	linux-iio@vger.kernel.org
@@ -270,8 +237,8 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		Number of scans contained by the buffer.
 
-What:		/sys/.../device[n]:buffer/bps
-KernelVersion:	2.6.35
+What:		/sys/.../device[n]:buffer/bytes_per_datum
+KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Bytes per scan.  Due to alignment fun, the scan may be larger
@@ -292,3 +259,36 @@ Description:
 		to the nearest power of 2 times this.  (may not be true in weird
 		hardware buffers that pack data well)
 
+What:		/sys/.../device[n]/buffer/scan_elements
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Directory containing interfaces for elements that will be captured
+		for a single triggered sample set in the buffer.
+
+What:		/sys/.../device[n]/buffer/scan_elements/[m]_accel_x0_en
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Scan element control for triggered data capture. m implies the
+		ordering within the buffer. Next the type is specified with
+		modifier and channel number as per the sysfs single channel
+		access above.
+
+What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_precision
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Scan element precision within the buffer. Note that the
+		data alignment must restrictions must be read from within
+		buffer to work out full data alignment for data read
+		via buffer_access chrdev. _x0 dropped if shared across all
+		acceleration channels.
+
+What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		A bit shift (to right) that must be applied prior to
+		extracting the bits specified by accel[_x0]_precision.
+
diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
index 4838818..8bba2fa 100644
--- a/drivers/staging/iio/Documentation/userspace.txt
+++ b/drivers/staging/iio/Documentation/userspace.txt
@@ -7,17 +7,14 @@ Typical sysfs entries (pruned for clarity)
 /sys/class/iio
   device0 - iio_dev related elements
     name - driver specific identifier (here lis3l02dq)
-    accel_x - polled (or from ring) raw readout of acceleration
-    accel_x_gain - hardware gain (calibration)
-    accel_x_offset - hardware offset (calibration)
-    available_sampling_frequency
+    accel_x_raw - polled (or from ring) raw readout of acceleration
+    accel_x_offset - offset to be applied to the raw reading
+    accel_x_scale - scale to be applied to the raw reading and offset
+    accel_x_calibbias - hardware offset (calibration)
+    accel_x_calibscale - hardware gain (calibration)
 
-    available_sampling_frequency - what options are there
+    sampling_frequency_available - what options are there
     sampling_frequency - control of internal sampling frequency
-    scan_elements - controls which channels will be stored in the ring buffer
-      scan_en_accel_x
-      scan_en_accel_y
-      scan_en_timestamp
     device - link to underlying hardware device
     uevent - udev related element
 
@@ -30,23 +27,28 @@ Typical sysfs entries (pruned for clarity)
       dev - major:minor for the chrdev (note major allocation dynamic)
     trigger - consumer attachement
       current_trigger - name based association with a trigger
-    ring_buffer0 - ring buffer interface
-      bps - byptes per sample (read only), dependant on scan element selection
+    device0:buffer0 - ring buffer interface
+      bytes_per_datum - byptes per complete datum (read only),
+                        dependant on scan element selection
       length - (rw) specificy length fo software ring buffer (typically ro in hw case)
-      ring_enable - turn the ring on. If its the first to be enabled attached to this
-                    trigger will also enable the trigger.
-      ring_access0
+      enable - turn the ring on. If its the first to be enabled attached to this
+               trigger will also enable the trigger.
+      device0:buffer0:access0
         dev - major:minor for ring buffer access chrdev
-      ring_event_line0
+      device0:buffer0:event0
         dev - major:minor for ring buffer event chrdev
+      scan_elements - controls which channels will be stored in the ring buffer
+        accel_x_en
+        accel_y_en
+        timestamp_en
 
   trigger0 - data ready trigger elements
     name - unqiue name of trigger
 
 Udev will create the following entries under /dev by default:
 
-ring_access0 - ring access chrdev
-ring_event0 - ring event chrdev
+device0:buffer0:access0 - ring access chrdev
+device0:buffer0:event0 - ring event chrdev
 event_line0 - general event chrdev.
 
 For the example code we assume the following rules have been used to ensure
-- 
1.7.0.6


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

* [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
  2010-08-30 12:58             ` Jonathan Cameron
  2010-08-30 14:03             ` [PATCH 1/3] staging:iio update documentation Manuel Stahl
@ 2010-08-30 14:03             ` Manuel Stahl
  2010-08-30 14:44               ` Jonathan Cameron
  2010-08-30 14:03             ` [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation Manuel Stahl
  3 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 14:03 UTC (permalink / raw)
  To: linux-iio


Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
---
 drivers/staging/iio/accel/accel.h          |   42 +++++++++++++++++++++---
 drivers/staging/iio/accel/adis16209_core.c |   26 +++++----------
 drivers/staging/iio/accel/adis16209_ring.c |   12 +++---
 drivers/staging/iio/accel/adis16220_core.c |   12 +++---
 drivers/staging/iio/accel/adis16240_core.c |   22 ++++++------
 drivers/staging/iio/accel/adis16240_ring.c |   12 +++---
 drivers/staging/iio/accel/inclinometer.h   |    2 +
 drivers/staging/iio/accel/lis3l02dq_core.c |    2 +-
 drivers/staging/iio/accel/sca3000_core.c   |    4 +-
 drivers/staging/iio/adc/adc.h              |    9 +++++
 drivers/staging/iio/gyro/adis16260_core.c  |   20 ++++++------
 drivers/staging/iio/gyro/adis16260_ring.c  |   12 +++---
 drivers/staging/iio/gyro/gyro.h            |   46 ++++++++++++++++++++++-----
 drivers/staging/iio/imu/adis16300_core.c   |   36 ++++++++++++---------
 drivers/staging/iio/imu/adis16300_ring.c   |   12 +++---
 drivers/staging/iio/imu/adis16350_core.c   |   44 ++++++++++++++++++--------
 drivers/staging/iio/imu/adis16350_ring.c   |   12 +++---
 drivers/staging/iio/imu/adis16400_core.c   |   47 +++++++++++++++-------------
 drivers/staging/iio/imu/adis16400_ring.c   |   12 +++---
 drivers/staging/iio/sysfs.h                |   17 ++++++++--
 20 files changed, 249 insertions(+), 152 deletions(-)

diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
index 1b6e37f..01e9302 100644
--- a/drivers/staging/iio/accel/accel.h
+++ b/drivers/staging/iio/accel/accel.h
@@ -14,14 +14,44 @@
 #define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_ACCEL_X_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(accel_x_gain, _mode, _show, _store, _addr)
+#define IIO_CONST_ATTR_ACCEL_SCALE(_string)		\
+	IIO_CONST_ATTR(accel_scale, _string)
 
-#define IIO_DEV_ATTR_ACCEL_Y_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(accel_y_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_ACCEL_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_scale, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_ACCEL_X_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_x_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_y_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_z_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_x_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_y_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_z_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_x_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_y_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_z_calibscale, _mode, _show, _store, _addr)
 
 #define IIO_DEV_ATTR_ACCEL(_show, _addr)			\
 	IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 6c6923f..bda497a 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -393,7 +393,7 @@ err_ret:
 
 static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned,
 		ADIS16209_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.30518");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.30518");
 static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned,
 		ADIS16209_AUX_ADC);
 static IIO_CONST_ATTR(in0_scale, "0.6105");
@@ -402,11 +402,11 @@ 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_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
 		adis16209_read_14bit_signed,
 		adis16209_write_16bit,
 		ADIS16209_YACCL_NULL);
@@ -416,26 +416,18 @@ 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_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_XACCL_NULL);
-static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_YACCL_NULL);
 static IIO_CONST_ATTR(incli_scale, "0.025");
 
 static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
 		       NULL, ADIS16209_ROT_OUT);
 
 static IIO_DEV_ATTR_TEMP(adis16209_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static IIO_CONST_ATTR_TEMP_OFFSET("25");
+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 IIO_CONST_ATTR_NAME("adis16209");
 
 static struct attribute *adis16209_event_attributes[] = {
 	NULL
@@ -457,13 +449,11 @@ static struct attribute *adis16209_attributes[] = {
 	&iio_const_attr_in0_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_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_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,
 	&iio_dev_attr_rot_raw.dev_attr.attr,
 	NULL
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 120bf91..3eb1d55 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -17,13 +17,13 @@
 #include "../trigger.h"
 #include "adis16209.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
 		     ADIS16209_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14),
 		     ADIS16209_XACCL_OUT, NULL);
 static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14),
 		     ADIS16209_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
 		     ADIS16209_AUX_ADC, NULL);
 static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12),
 		     ADIS16209_TEMP_OUT, NULL);
@@ -37,10 +37,10 @@ static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14),
 static IIO_SCAN_EL_TIMESTAMP(8);
 
 static struct attribute *adis16209_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_accel_x.dev_attr.attr,
 	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_scan_el_aux_adc.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_temp.dev_attr.attr,
 	&iio_scan_el_incli_x.dev_attr.attr,
 	&iio_scan_el_incli_y.dev_attr.attr,
@@ -177,12 +177,12 @@ 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_supply.number);
+	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_aux_adc.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);
 
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index bb7d765..edcf57d 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -487,7 +487,7 @@ static struct bin_attribute adc2_bin = {
 
 static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned,
 		ADIS16220_CAPT_SUPPLY);
-static IIO_CONST_ATTR(in_supply_scale, "0.0012207");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0012207");
 static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA);
 static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit,
 		NULL, ADIS16220_CAPT_PEAKA);
@@ -496,8 +496,8 @@ static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO,
 		adis16220_write_16bit,
 		ADIS16220_ACCL_NULL);
 static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static IIO_CONST_ATTR_TEMP_OFFSET("25");
+static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
 
 static IIO_DEV_ATTR_IN_RAW(0, adis16220_read_16bit, ADIS16220_CAPT_BUF1);
 static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2);
@@ -518,9 +518,9 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO,
 		adis16220_write_16bit,
 		ADIS16220_CAPT_PNTR);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("100200");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200");
 
-static IIO_CONST_ATTR(name, "adis16220");
+static IIO_CONST_ATTR_NAME("adis16220");
 
 static struct attribute *adis16220_attributes[] = {
 	&iio_dev_attr_in_supply_raw.dev_attr.attr,
@@ -533,7 +533,7 @@ static struct attribute *adis16220_attributes[] = {
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_const_attr_available_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
 	&iio_dev_attr_capture.dev_attr.attr,
 	&iio_dev_attr_capture_count.dev_attr.attr,
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 3e9531d..4583258 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -380,7 +380,7 @@ static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16240_read_10bit_unsigned,
 		ADIS16240_SUPPLY_OUT);
 static IIO_DEV_ATTR_IN_RAW(0, adis16240_read_10bit_signed,
 		ADIS16240_AUX_ADC);
-static IIO_CONST_ATTR(in_supply_scale, "0.00488");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00488");
 static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed,
 		ADIS16240_XACCL_OUT);
 static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO,
@@ -400,26 +400,26 @@ static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO,
 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_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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_CONST_ATTR_TEMP_SCALE("0.244");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("4096");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
 
-static IIO_CONST_ATTR(name, "adis16240");
+static IIO_CONST_ATTR_NAME("adis16240");
 
 static struct attribute *adis16240_event_attributes[] = {
 	NULL
@@ -434,18 +434,18 @@ static struct attribute *adis16240_attributes[] = {
 	&iio_const_attr_in_supply_scale.dev_attr.attr,
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_offset.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_offset.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_offset.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_available_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
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 581d0e5..9282372 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -17,7 +17,7 @@
 #include "../trigger.h"
 #include "adis16240.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
+static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
 		ADIS16240_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10),
 		ADIS16240_XACCL_OUT, NULL);
@@ -25,7 +25,7 @@ static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10),
 		ADIS16240_YACCL_OUT, NULL);
 static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10),
 		ADIS16240_ZACCL_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
+static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
 		ADIS16240_AUX_ADC, NULL);
 static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
 		ADIS16240_TEMP_OUT, NULL);
@@ -33,11 +33,11 @@ static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
 static IIO_SCAN_EL_TIMESTAMP(6);
 
 static struct attribute *adis16240_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_accel_x.dev_attr.attr,
 	&iio_scan_el_accel_y.dev_attr.attr,
 	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_scan_el_aux_adc.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_temp.dev_attr.attr,
 	&iio_scan_el_timestamp.dev_attr.attr,
 	NULL,
@@ -169,12 +169,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_supply.number);
+	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_aux_adc.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
 
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
 	if (ret)
diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h
index 5b49f83..faf73d7 100644
--- a/drivers/staging/iio/accel/inclinometer.h
+++ b/drivers/staging/iio/accel/inclinometer.h
@@ -21,3 +21,5 @@
 #define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \
 	IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr)
 
+#define IIO_CONST_ATTR_INCLI_SCALE(_string) \
+	IIO_CONST_ATTR(incli_scale, _string)
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 0ee9337..655f2b7 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -731,7 +731,7 @@ static struct attribute_group lis3l02dq_event_attribute_group = {
 	.attrs = lis3l02dq_event_attributes,
 };
 
-static IIO_CONST_ATTR(name, "lis3l02dq");
+static IIO_CONST_ATTR_NAME("lis3l02dq");
 static IIO_CONST_ATTR(accel_scale, "0.00958");
 
 static struct attribute *lis3l02dq_attributes[] = {
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index b78b6b6..0eb2c4c 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -721,8 +721,8 @@ error_ret:
 }
 static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp);
 
-static IIO_CONST_ATTR(temp_scale, "0.555556");
-static IIO_CONST_ATTR(temp_offset, "-214.6");
+static IIO_CONST_ATTR_TEMP_SCALE("0.555556");
+static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
 
 /**
  * sca3000_show_thresh() sysfs query of a threshold
diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h
index 7841e6a..6cb916e 100644
--- a/drivers/staging/iio/adc/adc.h
+++ b/drivers/staging/iio/adc/adc.h
@@ -27,5 +27,14 @@
 			      NULL,					\
 			      _addr)
 
+
+#define IIO_CONST_ATTR_IN_NAMED_OFFSET(_name, _string)			\
+	IIO_CONST_ATTR(in_##_name##_offset, _string)
+
+#define IIO_CONST_ATTR_IN_NAMED_SCALE(_name, _string)			\
+	IIO_CONST_ATTR(in_##_name##_scale, _string)
+
+
+
 #define IIO_EVENT_CODE_IN_HIGH_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a)
 #define IIO_EVENT_CODE_IN_LOW_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a + 32)
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 134dfaa..ac5378b 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -445,22 +445,22 @@ err_ret:
 static IIO_DEV_ATTR_IN_NAMED_RAW(supply,
 				adis16260_read_12bit_unsigned,
 				ADIS16260_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.0018315");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0018315");
 
 static IIO_DEV_ATTR_GYRO(adis16260_read_14bit_signed,
 		ADIS16260_GYRO_OUT);
-static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_GYRO_CALIBSCALE(S_IWUSR | S_IRUGO,
 		adis16260_read_14bit_signed,
 		adis16260_write_16bit,
 		ADIS16260_GYRO_SCALE);
-static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_GYRO_CALIBBIAS(S_IWUSR | S_IRUGO,
 		adis16260_read_12bit_signed,
 		adis16260_write_16bit,
 		ADIS16260_GYRO_OFF);
 
 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_CONST_ATTR_TEMP_OFFSET("25");
+static IIO_CONST_ATTR_TEMP_SCALE("0.1453");
 
 static IIO_DEV_ATTR_IN_RAW(0, adis16260_read_12bit_unsigned,
 		ADIS16260_AUX_ADC);
@@ -474,9 +474,9 @@ static IIO_DEV_ATTR_ANGL(adis16260_read_14bit_signed,
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("256 2048");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("256 2048");
 
-static IIO_CONST_ATTR(name, "adis16260");
+static IIO_CONST_ATTR_NAME("adis16260");
 
 static struct attribute *adis16260_event_attributes[] = {
 	NULL
@@ -490,8 +490,8 @@ static struct attribute *adis16260_attributes[] = {
 	&iio_dev_attr_in_supply_raw.dev_attr.attr,
 	&iio_const_attr_in_supply_scale.dev_attr.attr,
 	&iio_dev_attr_gyro_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_offset.dev_attr.attr,
+	&iio_dev_attr_gyro_calibscale.dev_attr.attr,
+	&iio_dev_attr_gyro_calibbias.dev_attr.attr,
 	&iio_dev_attr_angl_raw.dev_attr.attr,
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -499,7 +499,7 @@ static struct attribute *adis16260_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_const_attr_in0_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_available_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
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 0334860..659a672 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -17,11 +17,11 @@
 #include "../trigger.h"
 #include "adis16260.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in_supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
 		ADIS16260_SUPPLY_OUT, NULL);
 static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, IIO_SIGNED(14),
 		ADIS16260_GYRO_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(in0, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
 		ADIS16260_AUX_ADC, NULL);
 static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, IIO_UNSIGNED(12),
 		ADIS16260_TEMP_OUT, NULL);
@@ -31,9 +31,9 @@ static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, IIO_UNSIGNED(12),
 static IIO_SCAN_EL_TIMESTAMP(5);
 
 static struct attribute *adis16260_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_gyro.dev_attr.attr,
-	&iio_scan_el_aux_adc.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_temp.dev_attr.attr,
 	&iio_scan_el_angl.dev_attr.attr,
 	&iio_scan_el_timestamp.dev_attr.attr,
@@ -172,9 +172,9 @@ 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_supply.number);
+	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_aux_adc.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);
 
diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h
index f68edab..98b837b 100644
--- a/drivers/staging/iio/gyro/gyro.h
+++ b/drivers/staging/iio/gyro/gyro.h
@@ -3,6 +3,9 @@
 
 /* Gyroscope types of attribute */
 
+#define IIO_CONST_ATTR_GYRO_OFFSET(_string)	\
+	IIO_CONST_ATTR(gyro_offset, _string)
+
 #define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr)
 
@@ -15,18 +18,45 @@
 #define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_X_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(gyro_x_gain, _mode, _show, _store, _addr)
-
-#define IIO_DEV_ATTR_GYRO_Y_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(gyro_y_gain, _mode, _show, _store, _addr)
-
-#define IIO_DEV_ATTR_GYRO_Z_GAIN(_mode, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(gyro_z_gain, _mode, _show, _store, _addr)
+#define IIO_CONST_ATTR_GYRO_SCALE(_string)		\
+	IIO_CONST_ATTR(gyro_scale, _string)
 
 #define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr)		\
 	IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr)
 
+#define IIO_DEV_ATTR_GYRO_X_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_x_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_y_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
+
 #define IIO_DEV_ATTR_GYRO(_show, _addr)			\
 	IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
 
diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c
index f1950d5..168e8b3 100644
--- a/drivers/staging/iio/imu/adis16300_core.c
+++ b/drivers/staging/iio/imu/adis16300_core.c
@@ -503,28 +503,33 @@ err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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(supply, adis16300_read_14bit_unsigned,
 			   ADIS16300_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.00242");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00242");
 
 static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed,
 		ADIS16300_XGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s");
+static IIO_CONST_ATTR_GYRO_SCALE("0.05 deg/s");
 
 static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
 		ADIS16300_XACCL_OUT);
@@ -532,17 +537,17 @@ 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.0006 g");
+static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
 
 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.044 d");
+static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
 
 static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
-static IIO_CONST_ATTR(temp_offset, "198.16 K");
-static IIO_CONST_ATTR(temp_scale, "0.14 K");
+static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
+static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
 
 static IIO_DEV_ATTR_IN_RAW(0, adis16300_read_12bit_unsigned,
 		ADIS16300_AUX_ADC);
@@ -554,9 +559,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static IIO_CONST_ATTR(name, "adis16300");
+static IIO_CONST_ATTR_NAME("adis16300");
 
 static struct attribute *adis16300_event_attributes[] = {
 	NULL
@@ -567,9 +572,10 @@ static struct attribute_group adis16300_event_attribute_group = {
 };
 
 static struct attribute *adis16300_attributes[] = {
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_dev_attr_accel_z_offset.dev_attr.attr,
+	&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_in_supply_raw.dev_attr.attr,
 	&iio_const_attr_in_supply_scale.dev_attr.attr,
 	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -587,7 +593,7 @@ static struct attribute *adis16300_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_const_attr_in0_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_available_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
diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
index 742cad6..0e09051 100644
--- a/drivers/staging/iio/imu/adis16300_ring.c
+++ b/drivers/staging/iio/imu/adis16300_ring.c
@@ -17,7 +17,7 @@
 #include "../trigger.h"
 #include "adis16300.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
 		     ADIS16300_SUPPLY_OUT, NULL);
 
 static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -32,7 +32,7 @@ static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, IIO_SIGNED(14),
 
 static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_UNSIGNED(12),
 		     ADIS16300_TEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
 		     ADIS16300_AUX_ADC, NULL);
 
 static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X, IIO_SIGNED(12),
@@ -43,7 +43,7 @@ static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y, IIO_SIGNED(12),
 static IIO_SCAN_EL_TIMESTAMP(9);
 
 static struct attribute *adis16300_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_gyro_x.dev_attr.attr,
 	&iio_scan_el_temp.dev_attr.attr,
 	&iio_scan_el_accel_x.dev_attr.attr,
@@ -51,7 +51,7 @@ static struct attribute *adis16300_scan_el_attrs[] = {
 	&iio_scan_el_accel_z.dev_attr.attr,
 	&iio_scan_el_incli_x.dev_attr.attr,
 	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_scan_el_adc_0.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_timestamp.dev_attr.attr,
 	NULL,
 };
@@ -196,13 +196,13 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_in_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_adc_0.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);
 
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
index 1575b7b..d1f1015 100644
--- a/drivers/staging/iio/imu/adis16350_core.c
+++ b/drivers/staging/iio/imu/adis16350_core.c
@@ -475,24 +475,39 @@ err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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_OFFSET(S_IWUSR | S_IRUGO,
+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(supply, adis16350_read_12bit_unsigned,
 		ADIS16350_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.002418");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418");
 
 static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
 		ADIS16350_XGYRO_OUT);
@@ -500,7 +515,7 @@ 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.05");
+static IIO_CONST_ATTR_GYRO_SCALE("0.05");
 
 static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
 		ADIS16350_XACCL_OUT);
@@ -508,7 +523,7 @@ 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.00333");
+static IIO_CONST_ATTR_ACCEL_SCALE("0.00333");
 
 static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
 		NULL, ADIS16350_XTEMP_OUT);
@@ -516,7 +531,7 @@ 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.0005");
+static IIO_CONST_ATTR_TEMP_SCALE("0.0005");
 
 static IIO_DEV_ATTR_IN_RAW(0, adis16350_read_12bit_unsigned,
 		ADIS16350_AUX_ADC);
@@ -529,14 +544,17 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
 		adis16350_write_reset, 0);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static IIO_CONST_ATTR(name, "adis16350");
+static IIO_CONST_ATTR_NAME("adis16350");
 
 static struct attribute *adis16350_attributes[] = {
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_dev_attr_accel_z_offset.dev_attr.attr,
+	&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_in_supply_raw.dev_attr.attr,
 	&iio_const_attr_in_supply_scale.dev_attr.attr,
 	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -554,7 +572,7 @@ static struct attribute *adis16350_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_const_attr_in0_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_available_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
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
index a0b80e4..aefbae5 100644
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -17,7 +17,7 @@
 #include "../trigger.h"
 #include "adis16350.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in_supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
 		ADIS16350_SUPPLY_OUT, NULL);
 
 static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -41,13 +41,13 @@ static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12),
 static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12),
 		ADIS16350_ZTEMP_OUT, NULL);
 
-static IIO_SCAN_EL_C(adc_0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
 		ADIS16350_AUX_ADC, NULL);
 
 static IIO_SCAN_EL_TIMESTAMP(11);
 
 static struct attribute *adis16350_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_gyro_x.dev_attr.attr,
 	&iio_scan_el_gyro_y.dev_attr.attr,
 	&iio_scan_el_gyro_z.dev_attr.attr,
@@ -57,7 +57,7 @@ static struct attribute *adis16350_scan_el_attrs[] = {
 	&iio_scan_el_temp_x.dev_attr.attr,
 	&iio_scan_el_temp_y.dev_attr.attr,
 	&iio_scan_el_temp_z.dev_attr.attr,
-	&iio_scan_el_adc_0.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_timestamp.dev_attr.attr,
 	NULL,
 };
@@ -196,7 +196,7 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_in_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);
@@ -206,7 +206,7 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
 	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_adc_0.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
 
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
 	if (ret)
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 6013fee..1765fef 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -490,24 +490,24 @@ err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16400_read_12bit_signed,
-		adis16400_write_16bit,
-		ADIS16400_XACCL_OFF);
+#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 IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16400_read_12bit_signed,
-		adis16400_write_16bit,
-		ADIS16400_YACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_XGYRO_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_XGYRO_OFF);
+
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_XACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_XACCL_OFF);
 
-static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
-		adis16400_read_12bit_signed,
-		adis16400_write_16bit,
-		ADIS16400_ZACCL_OFF);
 
 static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16400_read_14bit_signed,
 		ADIS16400_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.002418");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418 V");
 
 static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed,
 		ADIS16400_XGYRO_OUT);
@@ -535,12 +535,12 @@ 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_CONST_ATTR_TEMP_OFFSET("198.16 K");
+static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
 
 static IIO_DEV_ATTR_IN_RAW(0, adis16400_read_12bit_unsigned,
 		ADIS16400_AUX_ADC);
-static IIO_CONST_ATTR(in0_scale, "0.000806");
+static IIO_CONST_ATTR(in0_scale, "0.000806 V");
 
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16400_read_frequency,
@@ -548,9 +548,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
 
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static IIO_CONST_ATTR(name, "adis16400");
+static IIO_CONST_ATTR_NAME("adis16400");
 
 static struct attribute *adis16400_event_attributes[] = {
 	NULL
@@ -561,9 +561,12 @@ static struct attribute_group adis16400_event_attribute_group = {
 };
 
 static struct attribute *adis16400_attributes[] = {
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_dev_attr_accel_z_offset.dev_attr.attr,
+	&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_in_supply_raw.dev_attr.attr,
 	&iio_const_attr_in_supply_scale.dev_attr.attr,
 	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -584,7 +587,7 @@ static struct attribute *adis16400_attributes[] = {
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_const_attr_in0_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_available_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
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 667f77b..de5ef5c 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -17,7 +17,7 @@
 #include "../trigger.h"
 #include "adis16400.h"
 
-static IIO_SCAN_EL_C(supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
 		     ADIS16400_SUPPLY_OUT, NULL);
 
 static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -43,13 +43,13 @@ static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, IIO_SIGNED(14),
 
 static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, IIO_SIGNED(12),
 		     ADIS16400_TEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
 		     ADIS16400_AUX_ADC, NULL);
 
 static IIO_SCAN_EL_TIMESTAMP(12);
 
 static struct attribute *adis16400_scan_el_attrs[] = {
-	&iio_scan_el_supply.dev_attr.attr,
+	&iio_scan_el_in_supply.dev_attr.attr,
 	&iio_scan_el_gyro_x.dev_attr.attr,
 	&iio_scan_el_gyro_y.dev_attr.attr,
 	&iio_scan_el_gyro_z.dev_attr.attr,
@@ -60,7 +60,7 @@ static struct attribute *adis16400_scan_el_attrs[] = {
 	&iio_scan_el_magn_y.dev_attr.attr,
 	&iio_scan_el_magn_z.dev_attr.attr,
 	&iio_scan_el_temp.dev_attr.attr,
-	&iio_scan_el_adc_0.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
 	&iio_scan_el_timestamp.dev_attr.attr,
 	NULL,
 };
@@ -205,7 +205,7 @@ 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_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_in_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);
@@ -216,7 +216,7 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 	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_adc_0.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
 
 	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
 	if (ret)
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 6083416..a4d4bb6 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -130,6 +130,13 @@ struct iio_const_attr {
 	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
 
 /**
+ * IIO_CONST_ATTR_NAME - constant identifier
+ * @_string: the name
+ **/
+#define IIO_CONST_ATTR_NAME(_string)				\
+	IIO_CONST_ATTR(name, _string)
+
+/**
  * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency
  * @_mode: sysfs file mode/permissions
  * @_show: output method for the attribute
@@ -156,10 +163,6 @@ struct iio_const_attr {
  *
  * Constant version
  **/
-/* Deprecated */
-#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string)			\
-	IIO_CONST_ATTR(available_sampling_frequency, _string)
-
 #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string)			\
 	IIO_CONST_ATTR(sampling_frequency_available, _string)
 
@@ -244,6 +247,12 @@ struct iio_const_attr {
 #define IIO_DEV_ATTR_TEMP_RAW(_show)			\
 	IIO_DEVICE_ATTR(temp_raw, S_IRUGO, _show, NULL, 0)
 
+#define IIO_CONST_ATTR_TEMP_OFFSET(_string)		\
+	IIO_CONST_ATTR(temp_offset, _string)
+
+#define IIO_CONST_ATTR_TEMP_SCALE(_string)		\
+	IIO_CONST_ATTR(temp_scale, _string)
+
 /**
  * IIO_EVENT_SH - generic shared event handler
  * @_name: event name
-- 
1.7.0.6


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

* [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
                               ` (2 preceding siblings ...)
  2010-08-30 14:03             ` [PATCH 2/3] staging:iio sync drivers with current ABI Manuel Stahl
@ 2010-08-30 14:03             ` Manuel Stahl
  2010-08-30 14:58               ` Jonathan Cameron
  3 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 14:03 UTC (permalink / raw)
  To: linux-iio


Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
---
 drivers/staging/iio/magnetometer/hmc5843.c |   32 ++++++++++++++--------------
 1 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 92f6c6f..66aab5a 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -95,15 +95,15 @@
 #define	CONF_NOT_USED				0x03
 #define	MEAS_CONF_MASK				0x03
 
-static const int regval_to_counts_per_mg[] = {
-	1620,
-	1300,
-	970,
-	780,
-	530,
-	460,
-	390,
-	280
+static const char *regval_to_scale[] = {
+	"0.0000006173",
+	"0.0000007692",
+	"0.0000010309",
+	"0.0000012821",
+	"0.0000018868",
+	"0.0000021739",
+	"0.0000025641",
+	"0.0000035714",
 };
 static const int regval_to_input_field_mg[] = {
 	700,
@@ -322,7 +322,7 @@ static IIO_DEVICE_ATTR(meas_conf,
  * 6		| 50
  * 7		| Not used
  */
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
 
 static s32 hmc5843_set_rate(struct i2c_client *client,
 				u8 rate)
@@ -459,17 +459,17 @@ static IIO_DEVICE_ATTR(magn_range,
 			set_range,
 			HMC5843_CONFIG_REG_B);
 
-static ssize_t show_gain(struct device *dev,
+static ssize_t show_scale(struct device *dev,
 			struct device_attribute *attr,
 			char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct hmc5843_data *data = indio_dev->dev_data;
-	return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
+	return strlen(strcpy(buf, regval_to_scale[data->range]));
 }
-static IIO_DEVICE_ATTR(magn_gain,
+static IIO_DEVICE_ATTR(magn_scale,
 			S_IRUGO,
-			show_gain,
+			show_scale,
 			NULL , 0);
 
 static struct attribute *hmc5843_attributes[] = {
@@ -477,11 +477,11 @@ static struct attribute *hmc5843_attributes[] = {
 	&iio_dev_attr_operating_mode.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_dev_attr_magn_range.dev_attr.attr,
-	&iio_dev_attr_magn_gain.dev_attr.attr,
+	&iio_dev_attr_magn_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_available_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL
 };
 
-- 
1.7.0.6


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

* Re: [PATCH 2/2] staging:iio move scan_elements into ring buffer
  2010-08-30 13:37               ` Manuel Stahl
@ 2010-08-30 14:09                 ` Jonathan Cameron
       [not found]                 ` <4C7BD886.3060109@cam.ac.uk>
  1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 14:09 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio, Song, Barry

On 08/30/10 14:37, Manuel Stahl wrote:
> Am 30.08.2010 14:58, schrieb Jonathan Cameron:
>> On 08/30/10 11:55, Manuel Stahl wrote:
>>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
>>
>> On more complex patches like this, could you verify which devices
>> you have tested against? Given the nature of that patch it
>> probably doesn't matter that much, but it's nice to save people
>> from wondering if they need to test on devices you have already
>> tried it with.
> 
> I have an sca3000 and an adis16405 to test with. The patch was made against v26.36-rc2 and compiled fine for all drivers in staging.
Cool.  Just add that detail to the patch description so it's there
for the records.
> 
>> This one certainly turned out to be more complex that I was
>> anticipating! Mostly movement of code so easy enough to
>> review.
>>
>> In one place as commented you made a change that obscured exactly
>> which bits your patch was changing. (see below).  I have nothing
>> against what you did, but would rather not have seen it in this
>> patch as it obscures what you are doing and that is never a good
>> idea! (in lis3l02dq_configure_ring).
> 
> I just wanted to have the same structure as for the adisXXXXX devices. Then maybe future changes can be done easier with find and replace.
That's fine.  The ideal would have been to have this as a really basic
prequel patch to the rest of the series.  The basic principle is to
keep a patch to a single purpose.  So patch one is to bring the driver
into line with the others in the tree (and arguably clean it up).
Patch two then makes the changes on top of that.  The easier things
are for reviewers, the faster you'll get a response!
> 
>> There is also a movement of available_scan_masks in the iio_dev
>> structure that is unexplained.  It doesn't matter in the slightest
>> but is an odd thing to do without reason.
> 
> Oh, this was an accident. I also moved available_scan_masks and realised afterwards that it's not buffer but device dependant.
Ah, easily done!  The only way to catch this sort of unnecessary change
is to do a reasonably close read of the resulting patch.
> 
>> Neither of the above matter, they are just things I picked up
>> on whilst reviewing.
> 
> The next patch will be a sync of docu and device ABI. Will again break most analog drivers, but should be doable by find and replace ;)
Excellent.
> 
>> Thanks for doing this!
>>
>> More than happy to add
>>
>> Signed-off-by: Jonathan Cameron<jic23@cam.ac.uk>
>>
>> Please forward to Greg KH (assuming no one shouts - might be worth
>> holding this one for a day or so given it effects a lot of drivers)
>>
>> Again, sorry to the Analog guys, this one is going to thoroughly break
>> you tree when it hits it.  Still better now than later when it effects
>> even more drivers.
>>
>> Note this also needs a patch updating the documentation.
>>
>>
>>> ---
>>>   drivers/staging/iio/accel/adis16209_ring.c |   41 ++++++------
>>>   drivers/staging/iio/accel/adis16240_ring.c |   33 +++++-----
>>>   drivers/staging/iio/accel/lis3l02dq_ring.c |   62 +++++++++--------
>>>   drivers/staging/iio/accel/sca3000_ring.c   |    2 +-
>>>   drivers/staging/iio/adc/max1363_core.c     |    1 -
>>>   drivers/staging/iio/adc/max1363_ring.c     |   18 +++--
>>>   drivers/staging/iio/gyro/adis16260_ring.c  |   31 ++++-----
>>>   drivers/staging/iio/iio.h                  |  102 +---------------------------
>>>   drivers/staging/iio/imu/adis16300_ring.c   |   43 ++++++------
>>>   drivers/staging/iio/imu/adis16350_ring.c   |   47 ++++++-------
>>>   drivers/staging/iio/imu/adis16400_ring.c   |   49 +++++++-------
>>>   drivers/staging/iio/industrialio-core.c    |   12 ---
>>>   drivers/staging/iio/industrialio-ring.c    |   28 ++++++--
>>>   drivers/staging/iio/ring_generic.h         |  100 +++++++++++++++++++++++++++
>>>   drivers/staging/iio/ring_sw.c              |   25 ++++---
>>>   15 files changed, 298 insertions(+), 296 deletions(-)
>>>
>>> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
>>> index d40b95f..120bf91 100644
>>> --- a/drivers/staging/iio/accel/adis16209_ring.c
>>> +++ b/drivers/staging/iio/accel/adis16209_ring.c
>>> @@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>>>       struct adis16209_state *st
>>>           = container_of(work_s, struct adis16209_state,
>>>                      work_trigger_to_ring);
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>
>>>       int i = 0;
>>>       s16 *data;
>>> -    size_t datasize = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> -                        (u8 *)data,
>>> -                        st->last_timestamp);
>>> +    ring->access.store_to(ring,
>>> +                  (u8 *)data,
>>> +                  st->last_timestamp);
>>>
>>>       iio_trigger_notify_done(st->indio_dev->trig);
>>>       kfree(data);
>>> @@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16209_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -182,11 +169,23 @@ 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;
>>>       ring->predisable =&iio_triggered_ring_predisable;
>>>       ring->owner = THIS_MODULE;
>>>
>>> +    /* Set default scan mode */
>>> +    iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.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,&adis16209_poll_func_th);
>>>       if (ret)
>>>           goto error_iio_sw_rb_free;
>>> diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
>>> index 462d452..581d0e5 100644
>>> --- a/drivers/staging/iio/accel/adis16240_ring.c
>>> +++ b/drivers/staging/iio/accel/adis16240_ring.c
>>> @@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>>>       struct adis16240_state *st
>>>           = container_of(work_s, struct adis16240_state,
>>>                   work_trigger_to_ring);
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>
>>>       int i = 0;
>>>       s16 *data;
>>> -    size_t datasize = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> +    ring->access.store_to(ring,
>>>               (u8 *)data,
>>>               st->last_timestamp);
>>>
>>> @@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16240_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -172,11 +161,21 @@ 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;
>>>       ring->predisable =&iio_triggered_ring_predisable;
>>>       ring->owner = THIS_MODULE;
>>>
>>> +    /* Set default scan mode */
>>> +    iio_scan_mask_set(ring, iio_scan_el_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_aux_adc.number);
>>> +
>>>       ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16240_poll_func_th);
>>>       if (ret)
>>>           goto error_iio_sw_rb_free;
>>> diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
>>> index 4c1b36a..a68a381 100644
>>> --- a/drivers/staging/iio/accel/lis3l02dq_ring.c
>>> +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
>>> @@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
>>>       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;
>>>       s16 *data;
>>>
>>> -    while (dev_info->scan_el_attrs->attrs[i]) {
>>> +    while (scan_el_attrs->attrs[i]) {
>>>           el = to_iio_scan_el((struct device_attribute *)
>>> -                    (dev_info->scan_el_attrs->attrs[i]));
>>> +                    (scan_el_attrs->attrs[i]));
>>>           /* label is in fact the address */
>>>           if (el->label == this_attr->address)
>>>               break;
>>>           i++;
>>>       }
>>> -    if (!dev_info->scan_el_attrs->attrs[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(dev_info, el->number);
>>> +    ret = iio_scan_mask_query(ring, el->number);
>>>       if (ret<  0)
>>>           goto error_ret;
>>>       if (ret) {
>>> -        data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
>>> +        data = kmalloc(ring->access.get_bytes_per_datum(ring),
>>>                      GFP_KERNEL);
>>>           if (data == NULL)
>>>               return -ENOMEM;
>>> -        ret = dev_info->ring->access.read_last(dev_info->ring,
>>> -                              (u8 *)data);
>>> +        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(dev_info, el->number);
>>> +    len = iio_scan_mask_count_to_right(ring, el->number);
>>>       if (len<  0) {
>>>           ret = len;
>>>           goto error_free_data;
>>> @@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
>>>    **/
>>>   static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>>>   {
>>> +    struct iio_ring_buffer *ring = st->help.indio_dev->ring;
>>>       struct spi_transfer *xfers;
>>>       struct spi_message msg;
>>>       int ret, i, j = 0;
>>>
>>> -    xfers = kzalloc((st->help.indio_dev->scan_count) * 2
>>> +    xfers = kzalloc((ring->scan_count) * 2
>>>               * sizeof(*xfers), GFP_KERNEL);
>>>       if (!xfers)
>>>           return -ENOMEM;
>>> @@ -223,7 +226,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++) {
>>> -        if (st->help.indio_dev->scan_mask&  (1<<  i)) {
>>> +        if (ring->scan_mask&  (1<<  i)) {
>>>               /* lower byte */
>>>               xfers[j].tx_buf = st->tx + 2*j;
>>>               st->tx[2*j] = read_all_tx_array[i*4];
>>> @@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
>>>        * values in alternate bytes
>>>        */
>>>       spi_message_init(&msg);
>>> -    for (j = 0; j<  st->help.indio_dev->scan_count * 2; j++)
>>> +    for (j = 0; j<  ring->scan_count * 2; j++)
>>>           spi_message_add_tail(&xfers[j],&msg);
>>>
>>>       ret = spi_sync(st->us,&msg);
>>> @@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
>>>       u8 *rx_array ;
>>>       s16 *data = (s16 *)buf;
>>>
>>> -    rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
>>> +    rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
>>>       if (rx_array == NULL)
>>>           return -ENOMEM;
>>>       ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
>>>       if (ret<  0)
>>>           return ret;
>>> -    for (i = 0; i<  h->indio_dev->scan_count; i++)
>>> +    for (i = 0; i<  h->indio_dev->ring->scan_count; i++)
>>>           data[i] = combine_8_to_16(rx_array[i*4+1],
>>>                       rx_array[i*4+3]);
>>>       kfree(rx_array);
>>> @@ -479,28 +482,29 @@ 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);
>>> -    /* Set default scan mode */
>>>       h->get_ring_element =&lis3l02dq_get_ring_element;
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&lis3l02dq_scan_el_group;
>>>
>>> -    indio_dev->ring = iio_sw_rb_allocate(indio_dev);
>>> -    if (!indio_dev->ring)
>> Personally I'd have done this directly into indio_dev->ring
>> as it would have reduced the lines changed count and kept
>> your changes more apparent.  Still doesn't really matter and
>> not worth respining the patch.
>>> +    ring = iio_sw_rb_allocate(indio_dev);
>>> +    if (!ring)
>>>           return -ENOMEM;
>>>
>>> +    indio_dev->ring = ring;
>>>       /* Effectively select the ring buffer implementation */
>>> -    iio_ring_sw_register_funcs(&indio_dev->ring->access);
>>> -    indio_dev->ring->bpe = 2;
>>> -    indio_dev->ring->preenable =&iio_sw_ring_preenable;
>>> -    indio_dev->ring->postenable =&iio_triggered_ring_postenable;
>>> -    indio_dev->ring->predisable =&iio_triggered_ring_predisable;
>>> -    indio_dev->ring->owner = THIS_MODULE;
>>> +    iio_ring_sw_register_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->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);
>>>
>>>       ret = iio_alloc_pollfunc(indio_dev, NULL,&lis3l02dq_poll_func_th);
>>>       if (ret)
>>> diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
>>> index eff5b9a..6d19d15 100644
>>> --- a/drivers/staging/iio/accel/sca3000_ring.c
>>> +++ b/drivers/staging/iio/accel/sca3000_ring.c
>>> @@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
>>>
>>>   int sca3000_configure_ring(struct iio_dev *indio_dev)
>>>   {
>>> -    indio_dev->scan_el_attrs =&sca3000_scan_el_group;
>>>       indio_dev->ring = sca3000_rb_allocate(indio_dev);
>>>       if (indio_dev->ring == NULL)
>>>           return -ENOMEM;
>>>       indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
>>>
>>> +    indio_dev->ring->scan_el_attrs =&sca3000_scan_el_group;
>>>       indio_dev->ring->access.rip_lots =&sca3000_rip_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;
>>> diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
>>> index 6435e50..1dc428f 100644
>>> --- a/drivers/staging/iio/adc/max1363_core.c
>>> +++ b/drivers/staging/iio/adc/max1363_core.c
>>> @@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
>>>       st->indio_dev->attrs = st->chip_info->dev_attrs;
>>>
>>>       /* Todo: this shouldn't be here. */
>>> -    st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
>>>       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/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
>>> index edac0ba..1d6ce54 100644
>>> --- a/drivers/staging/iio/adc/max1363_ring.c
>>> +++ b/drivers/staging/iio/adc/max1363_ring.c
>>> @@ -30,6 +30,7 @@
>>>   /* Todo: test this */
>>>   int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>>>   {
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>       unsigned long numvals;
>>>       int count = 0, ret;
>>>       u8 *ring_data;
>>> @@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
>>>           ret = -ENOMEM;
>>>           goto error_ret;
>>>       }
>>> -    ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
>>> -                        ring_data);
>>> +    ret = ring->access.read_last(ring, ring_data);
>>>       if (ret)
>>>           goto error_free_ring_data;
>>>       /* Need a count of channels prior to this one */
>>> @@ -77,6 +77,7 @@ error_ret:
>>>   static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>>   {
>>>       struct max1363_state *st = indio_dev->dev_data;
>>> +    struct iio_ring_buffer *ring = indio_dev->ring;
>>>       size_t d_size;
>>>       unsigned long numvals;
>>>
>>> @@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>>        * Need to figure out the current mode based upon the requested
>>>        * scan mask in iio_dev
>>>        */
>>> -    st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
>>> +    st->current_mode = max1363_match_mode(ring->scan_mask,
>>>                       st->chip_info);
>>>       if (!st->current_mode)
>>>           return -EINVAL;
>>> @@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
>>>       max1363_set_scan_mode(st);
>>>
>>>       numvals = hweight_long(st->current_mode->modemask);
>>> -    if (indio_dev->ring->access.set_bytes_per_datum) {
>>> +    if (ring->access.set_bytes_per_datum) {
>>>           if (st->chip_info->bits != 8)
>>>               d_size = numvals*2 + sizeof(s64);
>>>           else
>>>               d_size = numvals + sizeof(s64);
>>>           if (d_size % 8)
>>>               d_size += 8 - (d_size % 8);
>>> -        indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
>>> +        ring->access.set_bytes_per_datum(ring, d_size);
>>>       }
>>>
>>>       return 0;
>>> @@ -135,7 +136,7 @@ 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 = st->indio_dev;
>>> -    struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
>>> +    struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
>>>       s64 time_ns;
>>>       __u8 *rxbuf;
>>>       int b_sent;
>>> @@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
>>>
>>>       memcpy(rxbuf + d_size - sizeof(s64),&time_ns, sizeof(time_ns));
>>>
>>> -    indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
>>> +    indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
>>>   done:
>>>       kfree(rxbuf);
>>>       atomic_dec(&st->protect_ring);
>>> @@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
>>>           goto error_ret;
>>>       }
>>>       /* Effectively select the ring buffer implementation */
>>> -    iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
>>> +    iio_ring_sw_register_funcs(&indio_dev->ring->access);
>>>       ret = iio_alloc_pollfunc(indio_dev, NULL,&max1363_poll_func_th);
>>>       if (ret)
>>>           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;
>>> diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
>>> index 055d5e8..0334860 100644
>>> --- a/drivers/staging/iio/gyro/adis16260_ring.c
>>> +++ b/drivers/staging/iio/gyro/adis16260_ring.c
>>> @@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>>>       struct adis16260_state *st
>>>           = container_of(work_s, struct adis16260_state,
>>>                   work_trigger_to_ring);
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>
>>>       int i = 0;
>>>       s16 *data;
>>> -    size_t datasize = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> +    ring->access.store_to(ring,
>>>               (u8 *)data,
>>>               st->last_timestamp);
>>>
>>> @@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16260_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -174,11 +164,20 @@ 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;
>>>       ring->predisable =&iio_triggered_ring_predisable;
>>>       ring->owner = THIS_MODULE;
>>>
>>> +    /* Set default scan mode */
>>> +    iio_scan_mask_set(ring, iio_scan_el_supply.number);
>>> +    iio_scan_mask_set(ring, iio_scan_el_gyro.number);
>>> +    iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
>>> +    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)
>>>           goto error_iio_sw_rb_free;
>>> diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
>>> index 9d0ca12..3a4e8c3 100644
>>> --- a/drivers/staging/iio/iio.h
>>> +++ b/drivers/staging/iio/iio.h
>>> @@ -87,15 +87,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
>>>    * @event_attrs:    [DRIVER] event control attributes
>>>    * @event_conf_attrs:    [DRIVER] event configuration attributes
>>>    * @event_interfaces:    [INTERN] event chrdevs associated with interrupt lines
>>> + * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
>>>    * @ring:        [DRIVER] any ring buffer present
>>>    * @mlock:        [INTERN] lock used to prevent simultaneous device state
>>>    *            changes
>>> - * @scan_el_attrs:    [DRIVER] control of scan elements if that scan mode
>>> - *            control method is used
>>> - * @scan_count:    [INTERN] the number of elements in the current scan mode
>>> - * @scan_mask:        [INTERN] bitmask used in masking scan mode elements
>>> - * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
>>> - * @scan_timestamp:    [INTERN] does the scan mode include a timestamp
>>>    * @trig:        [INTERN] current device trigger (ring buffer modes)
>>>    * @pollfunc:        [DRIVER] function run on trigger being recieved
>>>    **/
>>> @@ -115,107 +110,14 @@ struct iio_dev {
>>>
>>>       struct iio_event_interface    *event_interfaces;
>>>
>> Why move this element?
>>> +    u32                *available_scan_masks;
>>>       struct iio_ring_buffer        *ring;
>>>       struct mutex            mlock;
>>>
>>> -    struct attribute_group        *scan_el_attrs;
>>> -    int                scan_count;
>>> -
>>> -    u32                scan_mask;
>>> -    u32                *available_scan_masks;
>>> -    bool                scan_timestamp;
>>>       struct iio_trigger        *trig;
>>>       struct iio_poll_func        *pollfunc;
>>>   };
>>>
>>> -/*
>>> - * These are mainly provided to allow for a change of implementation if a device
>>> - * has a large number of scan elements
>>> - */
>>> -#define IIO_MAX_SCAN_LENGTH 31
>>> -
>>> -/* note 0 used as error indicator as it doesn't make sense. */
>>> -static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
>>> -{
>>> -    while (*av_masks) {
>>> -        if (!(~*av_masks&  mask))
>>> -            return *av_masks;
>>> -        av_masks++;
>>> -    }
>>> -    return 0;
>>> -}
>>> -
>>> -static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
>>> -{
>>> -    u32 mask;
>>> -
>>> -    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> -        return -EINVAL;
>>> -
>>> -    if (!dev_info->scan_mask)
>>> -        return 0;
>>> -
>>> -    if (dev_info->available_scan_masks)
>>> -        mask = iio_scan_mask_match(dev_info->available_scan_masks,
>>> -                    dev_info->scan_mask);
>>> -    else
>>> -        mask = dev_info->scan_mask;
>>> -
>>> -    if (!mask)
>>> -        return -EINVAL;
>>> -
>>> -    return !!(mask&  (1<<  bit));
>>> -};
>>> -
>>> -static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
>>> -{
>>> -    u32 mask;
>>> -    u32 trialmask = dev_info->scan_mask | (1<<  bit);
>>> -
>>> -    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> -        return -EINVAL;
>>> -    if (dev_info->available_scan_masks) {
>>> -        mask = iio_scan_mask_match(dev_info->available_scan_masks,
>>> -                    trialmask);
>>> -        if (!mask)
>>> -            return -EINVAL;
>>> -    }
>>> -    dev_info->scan_mask = trialmask;
>>> -    dev_info->scan_count++;
>>> -
>>> -    return 0;
>>> -};
>>> -
>>> -static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
>>> -{
>>> -    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> -        return -EINVAL;
>>> -    dev_info->scan_mask&= ~(1<<  bit);
>>> -    dev_info->scan_count--;
>>> -    return 0;
>>> -};
>>> -
>>> -/**
>>> - * iio_scan_mask_count_to_right() - how many scan elements occur before here
>>> - * @dev_info: the iio_device whose scan mode we are querying
>>> - * @bit: which number scan element is this
>>> - **/
>>> -static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
>>> -                        int bit)
>>> -{
>>> -    int count = 0;
>>> -    int mask = (1<<  bit);
>>> -    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> -        return -EINVAL;
>>> -    while (mask) {
>>> -        mask>>= 1;
>>> -        if (mask&  dev_info->scan_mask)
>>> -            count++;
>>> -    }
>>> -
>>> -    return count;
>>> -}
>>> -
>>>   /**
>>>    * iio_device_register() - register a device with the IIO subsystem
>>>    * @dev_info:        Device structure filled by the device driver
>>> diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
>>> index 854183c..742cad6 100644
>>> --- a/drivers/staging/iio/imu/adis16300_ring.c
>>> +++ b/drivers/staging/iio/imu/adis16300_ring.c
>>> @@ -134,11 +134,11 @@ 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 = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> -                        (u8 *)data,
>>> -                        st->last_timestamp);
>>> +    ring->access.store_to(ring,
>>> +            (u8 *)data,
>>> +            st->last_timestamp);
>>>
>>>       iio_trigger_notify_done(st->indio_dev->trig);
>>>       kfree(data);
>>> @@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16300_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -202,11 +188,24 @@ int adis16300_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 =&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_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_adc_0.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;
>>> diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
>>> index 9620cbe..a0b80e4 100644
>>> --- a/drivers/staging/iio/imu/adis16350_ring.c
>>> +++ b/drivers/staging/iio/imu/adis16350_ring.c
>>> @@ -134,11 +134,11 @@ 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 = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> -                        (u8 *)data,
>>> -                        st->last_timestamp);
>>> +    ring->access.store_to(ring,
>>> +            (u8 *)data,
>>> +            st->last_timestamp);
>>>
>>>       iio_trigger_notify_done(st->indio_dev->trig);
>>>       kfree(data);
>>> @@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16350_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -204,11 +188,26 @@ int adis16350_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 =&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_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_adc_0.number);
>>> +
>>>       ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16350_poll_func_th);
>>>       if (ret)
>>>           goto error_iio_sw_rb_free;
>>> diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
>>> index c8e2316..667f77b 100644
>>> --- a/drivers/staging/iio/imu/adis16400_ring.c
>>> +++ b/drivers/staging/iio/imu/adis16400_ring.c
>>> @@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>>>       struct adis16400_state *st
>>>           = container_of(work_s, struct adis16400_state,
>>>                      work_trigger_to_ring);
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>
>>>       int i = 0;
>>>       s16 *data;
>>> -    size_t datasize = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>
>>>       data = kmalloc(datasize , GFP_KERNEL);
>>>       if (data == NULL) {
>>> @@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx)>= 0)
>>> -            for (; i<  st->indio_dev->scan_count; i++)
>>> +            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 (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>>>
>>> -    st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> -                        (u8 *)data,
>>> -                        st->last_timestamp);
>>> +    ring->access.store_to(ring,
>>> +            (u8 *) data,
>>> +            st->last_timestamp);
>>>
>>>       iio_trigger_notify_done(st->indio_dev->trig);
>>>       kfree(data);
>>> @@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
>>>       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);
>>> -    /* Set default scan mode */
>>> -
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
>>> -    iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
>>> -    indio_dev->scan_timestamp = true;
>>> -
>>> -    indio_dev->scan_el_attrs =&adis16400_scan_el_group;
>>>
>>>       ring = iio_sw_rb_allocate(indio_dev);
>>>       if (!ring) {
>>> @@ -214,11 +197,27 @@ 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;
>>>       ring->predisable =&iio_triggered_ring_predisable;
>>>       ring->owner = THIS_MODULE;
>>>
>>> +    /* Set default scan mode */
>>> +    iio_scan_mask_set(ring, iio_scan_el_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_adc_0.number);
>>> +
>>>       ret = iio_alloc_pollfunc(indio_dev, NULL,&adis16400_poll_func_th);
>>>       if (ret)
>>>           goto error_iio_sw_rb_free;
>>> diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
>>> index dd4d87a..5c0e56a 100644
>>> --- a/drivers/staging/iio/industrialio-core.c
>>> +++ b/drivers/staging/iio/industrialio-core.c
>>> @@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
>>>           goto error_ret;
>>>       }
>>>
>>> -    if (dev_info->scan_el_attrs) {
>>> -        ret = sysfs_create_group(&dev_info->dev.kobj,
>>> -                     dev_info->scan_el_attrs);
>>> -        if (ret)
>>> -            dev_err(&dev_info->dev,
>>> -                "Failed to add sysfs scan els\n");
>>> -    }
>>> -
>>>   error_ret:
>>>       return ret;
>>>   }
>>>
>>>   static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
>>>   {
>>> -    if (dev_info->scan_el_attrs)
>>> -        sysfs_remove_group(&dev_info->dev.kobj,
>>> -                   dev_info->scan_el_attrs);
>>> -
>>>       sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
>>>   }
>>>
>>> diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
>>> index 610c2b6..148ca5c 100644
>>> --- a/drivers/staging/iio/industrialio-ring.c
>>> +++ b/drivers/staging/iio/industrialio-ring.c
>>> @@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
>>>       if (ret)
>>>           goto error_free_ring_buffer_event_chrdev;
>>>
>>> +    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_event_chrdev;
>>> +        }
>>> +    }
>>> +
>>>       return ret;
>>>   error_free_ring_buffer_event_chrdev:
>>>       __iio_free_ring_buffer_event_chrdev(ring);
>>> @@ -291,6 +301,10 @@ 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_free_ring_buffer_access_chrdev(ring);
>>>       __iio_free_ring_buffer_event_chrdev(ring);
>>>       device_del(&ring->dev);
>>> @@ -468,7 +482,7 @@ ssize_t iio_scan_el_show(struct device *dev,
>>>       struct iio_dev *indio_dev = dev_get_drvdata(dev);
>>>       struct iio_scan_el *this_el = to_iio_scan_el(attr);
>>>
>>> -    ret = iio_scan_mask_query(indio_dev, this_el->number);
>>> +    ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>>>       if (ret<  0)
>>>           return ret;
>>>       return sprintf(buf, "%d\n", ret);
>>> @@ -491,19 +505,17 @@ ssize_t iio_scan_el_store(struct device *dev,
>>>           ret = -EBUSY;
>>>           goto error_ret;
>>>       }
>>> -    ret = iio_scan_mask_query(indio_dev, this_el->number);
>>> +    ret = iio_scan_mask_query(indio_dev->ring, this_el->number);
>>>       if (ret<  0)
>>>           goto error_ret;
>>>       if (!state&&  ret) {
>>> -        ret = iio_scan_mask_clear(indio_dev, this_el->number);
>>> +        ret = iio_scan_mask_clear(indio_dev->ring, this_el->number);
>>>           if (ret)
>>>               goto error_ret;
>>> -        indio_dev->scan_count--;
>>>       } else if (state&&  !ret) {
>>> -        ret = iio_scan_mask_set(indio_dev, this_el->number);
>>> +        ret = iio_scan_mask_set(indio_dev->ring, this_el->number);
>>>           if (ret)
>>>               goto error_ret;
>>> -        indio_dev->scan_count++;
>>>       }
>>>       if (this_el->set_state)
>>>           ret = this_el->set_state(this_el, indio_dev, state);
>>> @@ -520,7 +532,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
>>>                   char *buf)
>>>   {
>>>       struct iio_dev *indio_dev = dev_get_drvdata(dev);
>>> -    return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
>>> +    return sprintf(buf, "%d\n", indio_dev->ring->scan_timestamp);
>>>   }
>>>   EXPORT_SYMBOL(iio_scan_el_ts_show);
>>>
>>> @@ -538,7 +550,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
>>>           ret = -EBUSY;
>>>           goto error_ret;
>>>       }
>>> -    indio_dev->scan_timestamp = state;
>>> +    indio_dev->ring->scan_timestamp = 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 ac017b1..6124353 100644
>>> --- a/drivers/staging/iio/ring_generic.h
>>> +++ b/drivers/staging/iio/ring_generic.h
>>> @@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
>>>    * @bytes_per_datum    [DEVICE] size of individual datum including timestamp
>>>    * @bpe:        [DEVICE] size of individual channel value
>>>    * @loopcount:        [INTERN] number of times the ring has looped
>>> + * @scan_el_attrs:    [DRIVER] control of scan elements if that scan mode
>>> + *            control method is used
>>> + * @scan_count:    [INTERN] the number of elements in the current scan mode
>>> + * @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
>>>    * @shared_ev_pointer:    [INTERN] the shared event pointer to allow escalation of
>>> @@ -124,6 +129,10 @@ struct iio_ring_buffer {
>>>       int                bytes_per_datum;
>>>       int                bpe;
>>>       int                loopcount;
>>> +    struct attribute_group        *scan_el_attrs;
>>> +    int                scan_count;
>>> +    u32                scan_mask;
>>> +    bool                scan_timestamp;
>>>       struct iio_handler        access_handler;
>>>       struct iio_event_interface    ev_int;
>>>       struct iio_shared_ev_pointer    shared_ev_pointer;
>>> @@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
>>>                      iio_scan_el_ts_store),    \
>>>       }
>>>
>>> +/*
>>> + * These are mainly provided to allow for a change of implementation if a device
>>> + * has a large number of scan elements
>>> + */
>>> +#define IIO_MAX_SCAN_LENGTH 31
>>> +
>>> +/* note 0 used as error indicator as it doesn't make sense. */
>>> +static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
>>> +{
>>> +    while (*av_masks) {
>>> +        if (!(~*av_masks&  mask))
>>> +            return *av_masks;
>>> +        av_masks++;
>>> +    }
>>> +    return 0;
>>> +}
>>> +
>>> +static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
>>> +{
>>> +    struct iio_dev *dev_info = ring->indio_dev;
>>> +    u32 mask;
>>> +
>>> +    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> +        return -EINVAL;
>>> +
>>> +    if (!ring->scan_mask)
>>> +        return 0;
>>> +
>>> +    if (dev_info->available_scan_masks)
>>> +        mask = iio_scan_mask_match(dev_info->available_scan_masks,
>>> +                    ring->scan_mask);
>>> +    else
>>> +        mask = ring->scan_mask;
>>> +
>>> +    if (!mask)
>>> +        return -EINVAL;
>>> +
>>> +    return !!(mask&  (1<<  bit));
>>> +};
>>> +
>>> +static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
>>> +{
>>> +    struct iio_dev *dev_info = ring->indio_dev;
>>> +    u32 mask;
>>> +    u32 trialmask = ring->scan_mask | (1<<  bit);
>>> +
>>> +    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> +        return -EINVAL;
>>> +    if (dev_info->available_scan_masks) {
>>> +        mask = iio_scan_mask_match(dev_info->available_scan_masks,
>>> +                    trialmask);
>>> +        if (!mask)
>>> +            return -EINVAL;
>>> +    }
>>> +    ring->scan_mask = trialmask;
>>> +    ring->scan_count++;
>>> +
>>> +    return 0;
>>> +};
>>> +
>>> +static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
>>> +{
>>> +    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> +        return -EINVAL;
>>> +    ring->scan_mask&= ~(1<<  bit);
>>> +    ring->scan_count--;
>>> +    return 0;
>>> +};
>>> +
>>> +/**
>>> + * iio_scan_mask_count_to_right() - how many scan elements occur before here
>>> + * @dev_info: the iio_device whose scan mode we are querying
>>> + * @bit: which number scan element is this
>>> + **/
>>> +static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
>>> +                        int bit)
>>> +{
>>> +    int count = 0;
>>> +    int mask = (1<<  bit);
>>> +    if (bit>  IIO_MAX_SCAN_LENGTH)
>>> +        return -EINVAL;
>>> +    while (mask) {
>>> +        mask>>= 1;
>>> +        if (mask&  ring->scan_mask)
>>> +            count++;
>>> +    }
>>> +
>>> +    return count;
>>> +}
>>> +
>>> +
>>>   static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
>>>   {
>>>       put_device(&ring->dev);
>>> diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
>>> index 99efb6b..52624ac 100644
>>> --- a/drivers/staging/iio/ring_sw.c
>>> +++ b/drivers/staging/iio/ring_sw.c
>>> @@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
>>>
>>>   int iio_sw_ring_preenable(struct iio_dev *indio_dev)
>>>   {
>>> +    struct iio_ring_buffer *ring = indio_dev->ring;
>>>       size_t size;
>>>       dev_dbg(&indio_dev->dev, "%s\n", __func__);
>>>       /* Check if there are any scan elements enabled, if not fail*/
>>> -    if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
>>> +    if (!(ring->scan_count || ring->scan_timestamp))
>>>           return -EINVAL;
>>> -    if (indio_dev->scan_timestamp)
>>> -        if (indio_dev->scan_count)
>>> +    if (ring->scan_timestamp)
>>> +        if (ring->scan_count)
>>>               /* Timestamp (aligned to s64) and data */
>>> -            size = (((indio_dev->scan_count * indio_dev->ring->bpe)
>>> +            size = (((ring->scan_count * ring->bpe)
>>>                       + sizeof(s64) - 1)
>>>                   &  ~(sizeof(s64) - 1))
>>>                   + sizeof(s64);
>>>           else /* Timestamp only  */
>>>               size = sizeof(s64);
>>>       else /* Data only */
>>> -        size = indio_dev->scan_count * indio_dev->ring->bpe;
>>> -    indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
>>> +        size = ring->scan_count * ring->bpe;
>>> +    ring->access.set_bytes_per_datum(ring, size);
>>>
>>>       return 0;
>>>   }
>>> @@ -462,9 +463,9 @@ 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);
>>> +    struct iio_ring_buffer *ring = st->indio_dev->ring;
>>>       int len = 0;
>>> -    size_t datasize = st->indio_dev
>>> -        ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
>>> +    size_t datasize = ring->access.get_bytes_per_datum(ring);
>>>       char *data = kmalloc(datasize, GFP_KERNEL);
>>>
>>>       if (data == NULL) {
>>> @@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
>>>           return;
>>>       }
>>>
>>> -    if (st->indio_dev->scan_count)
>>> +    if (ring->scan_count)
>>>           len = st->get_ring_element(st, data);
>>>
>>>         /* Guaranteed to be aligned with 8 byte boundary */
>>> -    if (st->indio_dev->scan_timestamp)
>>> +    if (ring->scan_timestamp)
>>>           *(s64 *)(((phys_addr_t)data + len
>>>                   + sizeof(s64) - 1)&  ~(sizeof(s64) - 1))
>>>               = st->last_timestamp;
>>> -      st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>>> -                    (u8 *)data,
>>> +    ring->access.store_to(ring,
>>> +            (u8 *)data,
>>>               st->last_timestamp);
>>>
>>>       iio_trigger_notify_done(st->indio_dev->trig);
>>
> 
> 


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

* Re: [PATCH 1/3] staging:iio update documentation
  2010-08-30 14:03             ` [PATCH 1/3] staging:iio update documentation Manuel Stahl
@ 2010-08-30 14:23               ` Jonathan Cameron
  2010-08-30 14:24                 ` Manuel Stahl
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 14:23 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

On 08/30/10 15:03, Manuel Stahl wrote:

Hi Manuel,

Couple of comments inline.

Most relate to stuff that was wrong in the original text.
Feel free to leave these for me to clean up at a later
date if you prefer.  If so add my signed off and send
to Greg KH.
> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/Documentation/ring.txt        |    6 +-
>  drivers/staging/iio/Documentation/sysfs-class-iio |   72 ++++++++++----------
>  drivers/staging/iio/Documentation/userspace.txt   |   36 ++++++-----
>  3 files changed, 57 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
> index d2ca683..3696c36 100644
> --- a/drivers/staging/iio/Documentation/ring.txt
> +++ b/drivers/staging/iio/Documentation/ring.txt
> @@ -47,10 +47,8 @@ request_update
>    If parameters have changed that require reinitialization or configuration of
>    the ring buffer this will trigger it.
>  
> -get_bpd, set_bpd
> -  Get/set the number of bytes for a given reading (single element, not sample set)
> -  The value of bps (bytes per set) is created from a combination of this and the
> -  enabled scan elements.
> +get_bytes_per_datum, set_bytes_per_datum
> +  Get/set the number of bytes for a complete scan. (All samples + timestamp)
Hohum. That original comment doesn't look at all accurate...
>  
>  get_length / set_length
>    Get/set the number of sample sets that may be held by the buffer.
> diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio
> index 714b4c5..c137020 100644
> --- a/drivers/staging/iio/Documentation/sysfs-class-iio
> +++ b/drivers/staging/iio/Documentation/sysfs-class-iio
> @@ -158,7 +158,7 @@ Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Magnetic field along axis x, y or z (may be arbitrarily assigned)
>  		channel m (not present if only one magnetometer at this orientation).
> -		Data converted by application of offset then scale to Gauss
> +		Data converted by application of offset then scale to Gauss.
good catch.
>  		Has all the equivalent modifiers as per in[m].
>  
>  What:		/sys/.../device[n]/device[n]:event[m]
> @@ -212,39 +212,6 @@ Description:
>  		The actual value of the threshold in raw device units obtained by
>  		 reverse application of scale and offfset to the acceleration in m/s^2.
>  
> -What:		/sys/.../device[n]/scan_elements
> -KernelVersion:	2.6.35
> -Contact:	linux-iio@vger.kernel.org
> -Description:
> -		Directory containing interfaces for elements that will be captured
> -		for a single triggered sample set in the buffer.
> -
> -What:		/sys/.../device[n]/scan_elements/[m]_accel_x0_en
> -KernelVersion:	2.6.35
> -Contact:	linux-iio@vger.kernel.org
> -Description:
> -		Scan element control for triggered data capture. m implies the
> -		ordering within the buffer. Next the type is specified with
> -		modifier and channel number as per the sysfs single channel
> -		access above.
> -
> -What:		/sys/.../device[n]/scan_elements/accel[_x0]_precision
> -KernelVersion:	2.6.35
> -Contact:	linux-iio@vger.kernel.org
> -Description:
> -		Scan element precision within the buffer. Note that the
> -		data alignment must restrictions must be read from within
> -		buffer to work out full data alignment for data read
> -		via buffer_access chrdev. _x0 dropped if shared across all
> -		acceleration channels.
> -
> -What:		/sys/.../device[n]/scan_elements/accel[_x0]_shift
> -KernelVersion:	2.6.35
> -Contact:	linux-iio@vger.kernel.org
> -Description:
> -		A bit shift (to right) that must be applied prior to
> -		extracting the bits specified by accel[_x0]_precision.
> -
>  What:		/sys/.../device[n]/device[n]:buffer:event/dev
>  KernelVersion:	2.6.35
>  Contact:	linux-iio@vger.kernel.org
> @@ -270,8 +237,8 @@ Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Number of scans contained by the buffer.
>  
> -What:		/sys/.../device[n]:buffer/bps
> -KernelVersion:	2.6.35
> +What:		/sys/.../device[n]:buffer/bytes_per_datum
> +KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Bytes per scan.  Due to alignment fun, the scan may be larger
> @@ -292,3 +259,36 @@ Description:
>  		to the nearest power of 2 times this.  (may not be true in weird
>  		hardware buffers that pack data well)
>  
> +What:		/sys/.../device[n]/buffer/scan_elements
Is this not /sys/.../device[n]/buffer[m]/scan_elements? I think we allow
for multiple buffers per device.
> +KernelVersion:	2.6.37
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Directory containing interfaces for elements that will be captured
> +		for a single triggered sample set in the buffer.
> +
> +What:		/sys/.../device[n]/buffer/scan_elements/[m]_accel_x0_en
This needs some brackets... [_x0]  
> +KernelVersion:	2.6.37
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Scan element control for triggered data capture. m implies the
> +		ordering within the buffer. Next the type is specified with
> +		modifier and channel number as per the sysfs single channel
> +		access above.
> +
Obviously the next two will get eaten up by your suggestion of 'type' the other
day, but best to keep the documentation matching what is actually in place so
I'm glad to see you updated them.
> +What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_precision
> +KernelVersion:	2.6.37
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Scan element precision within the buffer. Note that the
> +		data alignment must restrictions must be read from within
> +		buffer to work out full data alignment for data read
> +		via buffer_access chrdev. _x0 dropped if shared across all
> +		acceleration channels.
> +
> +What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift
> +KernelVersion:	2.6.37
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		A bit shift (to right) that must be applied prior to
> +		extracting the bits specified by accel[_x0]_precision.
> +
> diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
> index 4838818..8bba2fa 100644
> --- a/drivers/staging/iio/Documentation/userspace.txt
> +++ b/drivers/staging/iio/Documentation/userspace.txt
> @@ -7,17 +7,14 @@ Typical sysfs entries (pruned for clarity)
>  /sys/class/iio
>    device0 - iio_dev related elements
>      name - driver specific identifier (here lis3l02dq)
> -    accel_x - polled (or from ring) raw readout of acceleration
> -    accel_x_gain - hardware gain (calibration)
> -    accel_x_offset - hardware offset (calibration)
> -    available_sampling_frequency
> +    accel_x_raw - polled (or from ring) raw readout of acceleration
> +    accel_x_offset - offset to be applied to the raw reading
> +    accel_x_scale - scale to be applied to the raw reading and offset
> +    accel_x_calibbias - hardware offset (calibration)
> +    accel_x_calibscale - hardware gain (calibration)
youch, Hadn't realised how out of date some of this has gotten. 

Actually we can probably drop most of this file.  It just replicates
the abi documentation (and predates it). Shall I do that once
your changes have merged, or do you want to loose everything down
to the Udev will create line?  Perhaps add something saying the sysfs
stuff is documented in the abi file?

>  
> -    available_sampling_frequency - what options are there
> +    sampling_frequency_available - what options are there
>      sampling_frequency - control of internal sampling frequency
> -    scan_elements - controls which channels will be stored in the ring buffer
> -      scan_en_accel_x
> -      scan_en_accel_y
> -      scan_en_timestamp
>      device - link to underlying hardware device
>      uevent - udev related element
>  
> @@ -30,23 +27,28 @@ Typical sysfs entries (pruned for clarity)
>        dev - major:minor for the chrdev (note major allocation dynamic)
>      trigger - consumer attachement
>        current_trigger - name based association with a trigger
> -    ring_buffer0 - ring buffer interface
> -      bps - byptes per sample (read only), dependant on scan element selection
> +    device0:buffer0 - ring buffer interface
> +      bytes_per_datum - byptes per complete datum (read only),
> +                        dependant on scan element selection
>        length - (rw) specificy length fo software ring buffer (typically ro in hw case)
> -      ring_enable - turn the ring on. If its the first to be enabled attached to this
> -                    trigger will also enable the trigger.
> -      ring_access0
> +      enable - turn the ring on. If its the first to be enabled attached to this
> +               trigger will also enable the trigger.
> +      device0:buffer0:access0
>          dev - major:minor for ring buffer access chrdev
> -      ring_event_line0
> +      device0:buffer0:event0
>          dev - major:minor for ring buffer event chrdev
> +      scan_elements - controls which channels will be stored in the ring buffer
> +        accel_x_en
> +        accel_y_en
> +        timestamp_en
>  
>    trigger0 - data ready trigger elements
>      name - unqiue name of trigger
>  
>  Udev will create the following entries under /dev by default:
>  
> -ring_access0 - ring access chrdev
> -ring_event0 - ring event chrdev
> +device0:buffer0:access0 - ring access chrdev
> +device0:buffer0:event0 - ring event chrdev
>  event_line0 - general event chrdev.
>  
>  For the example code we assume the following rules have been used to ensure


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

* Re: [PATCH 1/3] staging:iio update documentation
  2010-08-30 14:23               ` Jonathan Cameron
@ 2010-08-30 14:24                 ` Manuel Stahl
  2010-08-30 14:49                   ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 14:24 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 10641 bytes --]

Am 30.08.2010 16:23, schrieb Jonathan Cameron:
> On 08/30/10 15:03, Manuel Stahl wrote:
>
> Hi Manuel,
>
> Couple of comments inline.
>
> Most relate to stuff that was wrong in the original text.
> Feel free to leave these for me to clean up at a later
> date if you prefer.  If so add my signed off and send
> to Greg KH.
>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
> Signed-off-by: Jonathan Cameron<jic23@cam.ac.uk>
>> ---
>>   drivers/staging/iio/Documentation/ring.txt        |    6 +-
>>   drivers/staging/iio/Documentation/sysfs-class-iio |   72 ++++++++++----------
>>   drivers/staging/iio/Documentation/userspace.txt   |   36 ++++++-----
>>   3 files changed, 57 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
>> index d2ca683..3696c36 100644
>> --- a/drivers/staging/iio/Documentation/ring.txt
>> +++ b/drivers/staging/iio/Documentation/ring.txt
>> @@ -47,10 +47,8 @@ request_update
>>     If parameters have changed that require reinitialization or configuration of
>>     the ring buffer this will trigger it.
>>
>> -get_bpd, set_bpd
>> -  Get/set the number of bytes for a given reading (single element, not sample set)
>> -  The value of bps (bytes per set) is created from a combination of this and the
>> -  enabled scan elements.
>> +get_bytes_per_datum, set_bytes_per_datum
>> +  Get/set the number of bytes for a complete scan. (All samples + timestamp)
> Hohum. That original comment doesn't look at all accurate...
>>
>>   get_length / set_length
>>     Get/set the number of sample sets that may be held by the buffer.
>> diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio
>> index 714b4c5..c137020 100644
>> --- a/drivers/staging/iio/Documentation/sysfs-class-iio
>> +++ b/drivers/staging/iio/Documentation/sysfs-class-iio
>> @@ -158,7 +158,7 @@ Contact:	linux-iio@vger.kernel.org
>>   Description:
>>   		Magnetic field along axis x, y or z (may be arbitrarily assigned)
>>   		channel m (not present if only one magnetometer at this orientation).
>> -		Data converted by application of offset then scale to Gauss
>> +		Data converted by application of offset then scale to Gauss.
> good catch.
>>   		Has all the equivalent modifiers as per in[m].
>>
>>   What:		/sys/.../device[n]/device[n]:event[m]
>> @@ -212,39 +212,6 @@ Description:
>>   		The actual value of the threshold in raw device units obtained by
>>   		 reverse application of scale and offfset to the acceleration in m/s^2.
>>
>> -What:		/sys/.../device[n]/scan_elements
>> -KernelVersion:	2.6.35
>> -Contact:	linux-iio@vger.kernel.org
>> -Description:
>> -		Directory containing interfaces for elements that will be captured
>> -		for a single triggered sample set in the buffer.
>> -
>> -What:		/sys/.../device[n]/scan_elements/[m]_accel_x0_en
>> -KernelVersion:	2.6.35
>> -Contact:	linux-iio@vger.kernel.org
>> -Description:
>> -		Scan element control for triggered data capture. m implies the
>> -		ordering within the buffer. Next the type is specified with
>> -		modifier and channel number as per the sysfs single channel
>> -		access above.
>> -
>> -What:		/sys/.../device[n]/scan_elements/accel[_x0]_precision
>> -KernelVersion:	2.6.35
>> -Contact:	linux-iio@vger.kernel.org
>> -Description:
>> -		Scan element precision within the buffer. Note that the
>> -		data alignment must restrictions must be read from within
>> -		buffer to work out full data alignment for data read
>> -		via buffer_access chrdev. _x0 dropped if shared across all
>> -		acceleration channels.
>> -
>> -What:		/sys/.../device[n]/scan_elements/accel[_x0]_shift
>> -KernelVersion:	2.6.35
>> -Contact:	linux-iio@vger.kernel.org
>> -Description:
>> -		A bit shift (to right) that must be applied prior to
>> -		extracting the bits specified by accel[_x0]_precision.
>> -
>>   What:		/sys/.../device[n]/device[n]:buffer:event/dev
>>   KernelVersion:	2.6.35
>>   Contact:	linux-iio@vger.kernel.org
>> @@ -270,8 +237,8 @@ Contact:	linux-iio@vger.kernel.org
>>   Description:
>>   		Number of scans contained by the buffer.
>>
>> -What:		/sys/.../device[n]:buffer/bps
>> -KernelVersion:	2.6.35
>> +What:		/sys/.../device[n]:buffer/bytes_per_datum
>> +KernelVersion:	2.6.37
>>   Contact:	linux-iio@vger.kernel.org
>>   Description:
>>   		Bytes per scan.  Due to alignment fun, the scan may be larger
>> @@ -292,3 +259,36 @@ Description:
>>   		to the nearest power of 2 times this.  (may not be true in weird
>>   		hardware buffers that pack data well)
>>
>> +What:		/sys/.../device[n]/buffer/scan_elements
> Is this not /sys/.../device[n]/buffer[m]/scan_elements? I think we allow
> for multiple buffers per device.
>> +KernelVersion:	2.6.37
>> +Contact:	linux-iio@vger.kernel.org
>> +Description:
>> +		Directory containing interfaces for elements that will be captured
>> +		for a single triggered sample set in the buffer.
>> +
>> +What:		/sys/.../device[n]/buffer/scan_elements/[m]_accel_x0_en
> This needs some brackets... [_x0]

Depends on what we accord for the next version, there should be a patch 
removing the [m] and creating all the new files.

>> +KernelVersion:	2.6.37
>> +Contact:	linux-iio@vger.kernel.org
>> +Description:
>> +		Scan element control for triggered data capture. m implies the
>> +		ordering within the buffer. Next the type is specified with
>> +		modifier and channel number as per the sysfs single channel
>> +		access above.
>> +
> Obviously the next two will get eaten up by your suggestion of 'type' the other
> day, but best to keep the documentation matching what is actually in place so
> I'm glad to see you updated them.
>> +What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_precision
>> +KernelVersion:	2.6.37
>> +Contact:	linux-iio@vger.kernel.org
>> +Description:
>> +		Scan element precision within the buffer. Note that the
>> +		data alignment must restrictions must be read from within
>> +		buffer to work out full data alignment for data read
>> +		via buffer_access chrdev. _x0 dropped if shared across all
>> +		acceleration channels.
>> +
>> +What:		/sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift
>> +KernelVersion:	2.6.37
>> +Contact:	linux-iio@vger.kernel.org
>> +Description:
>> +		A bit shift (to right) that must be applied prior to
>> +		extracting the bits specified by accel[_x0]_precision.
>> +
>> diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
>> index 4838818..8bba2fa 100644
>> --- a/drivers/staging/iio/Documentation/userspace.txt
>> +++ b/drivers/staging/iio/Documentation/userspace.txt
>> @@ -7,17 +7,14 @@ Typical sysfs entries (pruned for clarity)
>>   /sys/class/iio
>>     device0 - iio_dev related elements
>>       name - driver specific identifier (here lis3l02dq)
>> -    accel_x - polled (or from ring) raw readout of acceleration
>> -    accel_x_gain - hardware gain (calibration)
>> -    accel_x_offset - hardware offset (calibration)
>> -    available_sampling_frequency
>> +    accel_x_raw - polled (or from ring) raw readout of acceleration
>> +    accel_x_offset - offset to be applied to the raw reading
>> +    accel_x_scale - scale to be applied to the raw reading and offset
>> +    accel_x_calibbias - hardware offset (calibration)
>> +    accel_x_calibscale - hardware gain (calibration)
> youch, Hadn't realised how out of date some of this has gotten.
>
> Actually we can probably drop most of this file.  It just replicates
> the abi documentation (and predates it). Shall I do that once
> your changes have merged, or do you want to loose everything down
> to the Udev will create line?  Perhaps add something saying the sysfs
> stuff is documented in the abi file?

Would be great if you do another docu review patch afterwards.

>
>>
>> -    available_sampling_frequency - what options are there
>> +    sampling_frequency_available - what options are there
>>       sampling_frequency - control of internal sampling frequency
>> -    scan_elements - controls which channels will be stored in the ring buffer
>> -      scan_en_accel_x
>> -      scan_en_accel_y
>> -      scan_en_timestamp
>>       device - link to underlying hardware device
>>       uevent - udev related element
>>
>> @@ -30,23 +27,28 @@ Typical sysfs entries (pruned for clarity)
>>         dev - major:minor for the chrdev (note major allocation dynamic)
>>       trigger - consumer attachement
>>         current_trigger - name based association with a trigger
>> -    ring_buffer0 - ring buffer interface
>> -      bps - byptes per sample (read only), dependant on scan element selection
>> +    device0:buffer0 - ring buffer interface
>> +      bytes_per_datum - byptes per complete datum (read only),
>> +                        dependant on scan element selection
>>         length - (rw) specificy length fo software ring buffer (typically ro in hw case)
>> -      ring_enable - turn the ring on. If its the first to be enabled attached to this
>> -                    trigger will also enable the trigger.
>> -      ring_access0
>> +      enable - turn the ring on. If its the first to be enabled attached to this
>> +               trigger will also enable the trigger.
>> +      device0:buffer0:access0
>>           dev - major:minor for ring buffer access chrdev
>> -      ring_event_line0
>> +      device0:buffer0:event0
>>           dev - major:minor for ring buffer event chrdev
>> +      scan_elements - controls which channels will be stored in the ring buffer
>> +        accel_x_en
>> +        accel_y_en
>> +        timestamp_en
>>
>>     trigger0 - data ready trigger elements
>>       name - unqiue name of trigger
>>
>>   Udev will create the following entries under /dev by default:
>>
>> -ring_access0 - ring access chrdev
>> -ring_event0 - ring event chrdev
>> +device0:buffer0:access0 - ring access chrdev
>> +device0:buffer0:event0 - ring event chrdev
>>   event_line0 - general event chrdev.
>>
>>   For the example code we assume the following rules have been used to ensure
>

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 161 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 14:03             ` [PATCH 2/3] staging:iio sync drivers with current ABI Manuel Stahl
@ 2010-08-30 14:44               ` Jonathan Cameron
  2010-08-30 15:00                 ` Manuel Stahl
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 14:44 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

On 08/30/10 15:03, Manuel Stahl wrote:

Youch, I hadn't registered just how far away this lot were from the abi.
Thanks for doing this.

I sometimes wonder if it would be better to loose all the macros and move
over to abi doc based enforcement (like hwmon does).  What do people think?
As can be seen in this patch, it makes very little difference in the length of
code.  Disadvantage is that it does add a review burden.

Let's merge this fix anyway and consider whether to loose some of the macros
at a later date.

Quite a bit of this fixes naming of parameter that weren't correct under the
previous abi.  Clearly we (meaning mainly me :) ) need to review drivers
much more closely for abi breakage.

An excellent patch.  Thank you very much for doing this.

One minor white space introduction that I'd like you to clean up before
sending on.


> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>

> ---
>  drivers/staging/iio/accel/accel.h          |   42 +++++++++++++++++++++---
>  drivers/staging/iio/accel/adis16209_core.c |   26 +++++----------
>  drivers/staging/iio/accel/adis16209_ring.c |   12 +++---
>  drivers/staging/iio/accel/adis16220_core.c |   12 +++---
>  drivers/staging/iio/accel/adis16240_core.c |   22 ++++++------
>  drivers/staging/iio/accel/adis16240_ring.c |   12 +++---
>  drivers/staging/iio/accel/inclinometer.h   |    2 +
>  drivers/staging/iio/accel/lis3l02dq_core.c |    2 +-
>  drivers/staging/iio/accel/sca3000_core.c   |    4 +-
>  drivers/staging/iio/adc/adc.h              |    9 +++++
>  drivers/staging/iio/gyro/adis16260_core.c  |   20 ++++++------
>  drivers/staging/iio/gyro/adis16260_ring.c  |   12 +++---
>  drivers/staging/iio/gyro/gyro.h            |   46 ++++++++++++++++++++++-----
>  drivers/staging/iio/imu/adis16300_core.c   |   36 ++++++++++++---------
>  drivers/staging/iio/imu/adis16300_ring.c   |   12 +++---
>  drivers/staging/iio/imu/adis16350_core.c   |   44 ++++++++++++++++++--------
>  drivers/staging/iio/imu/adis16350_ring.c   |   12 +++---
>  drivers/staging/iio/imu/adis16400_core.c   |   47 +++++++++++++++-------------
>  drivers/staging/iio/imu/adis16400_ring.c   |   12 +++---
>  drivers/staging/iio/sysfs.h                |   17 ++++++++--
>  20 files changed, 249 insertions(+), 152 deletions(-)


> 
> diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
> index 1b6e37f..01e9302 100644
> --- a/drivers/staging/iio/accel/accel.h
> +++ b/drivers/staging/iio/accel/accel.h
> @@ -14,14 +14,44 @@
>  #define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr)	\
>  	IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr)
>  
> -#define IIO_DEV_ATTR_ACCEL_X_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(accel_x_gain, _mode, _show, _store, _addr)
> +#define IIO_CONST_ATTR_ACCEL_SCALE(_string)		\
> +	IIO_CONST_ATTR(accel_scale, _string)
>  
> -#define IIO_DEV_ATTR_ACCEL_Y_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(accel_y_gain, _mode, _show, _store, _addr)
> +#define IIO_DEV_ATTR_ACCEL_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_scale, _mode, _show, _store, _addr)
>  
> -#define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr)
> +#define IIO_DEV_ATTR_ACCEL_X_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_x_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Y_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_y_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Z_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_z_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_x_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_y_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_z_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_calibscale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_X_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_x_calibscale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Y_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_y_calibscale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_ACCEL_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(accel_z_calibscale, _mode, _show, _store, _addr)
>  
>  #define IIO_DEV_ATTR_ACCEL(_show, _addr)			\
>  	IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr)
> diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
> index 6c6923f..bda497a 100644
> --- a/drivers/staging/iio/accel/adis16209_core.c
> +++ b/drivers/staging/iio/accel/adis16209_core.c
> @@ -393,7 +393,7 @@ err_ret:
>  
>  static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned,
>  		ADIS16209_SUPPLY_OUT);
> -static IIO_CONST_ATTR(in_supply_scale, "0.30518");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.30518");
Here is an example of just how silly it can get...

>  static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned,
>  		ADIS16209_AUX_ADC);
>  static IIO_CONST_ATTR(in0_scale, "0.6105");
> @@ -402,11 +402,11 @@ 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_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
>  		adis16209_read_14bit_signed,
>  		adis16209_write_16bit,
>  		ADIS16209_YACCL_NULL);
> @@ -416,26 +416,18 @@ 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_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
> -		adis16209_read_14bit_signed,
> -		adis16209_write_16bit,
> -		ADIS16209_XACCL_NULL);
> -static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
> -		adis16209_read_14bit_signed,
> -		adis16209_write_16bit,
> -		ADIS16209_YACCL_NULL);
>  static IIO_CONST_ATTR(incli_scale, "0.025");
>  
>  static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
>  		       NULL, ADIS16209_ROT_OUT);
>  
>  static IIO_DEV_ATTR_TEMP(adis16209_read_temp);
> -static IIO_CONST_ATTR(temp_offset, "25");
> -static IIO_CONST_ATTR(temp_scale, "-0.47");
> +static IIO_CONST_ATTR_TEMP_OFFSET("25");
> +static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
Again. Do we really need these macros?
>  
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
>  
> -static IIO_CONST_ATTR(name, "adis16209");
> +static IIO_CONST_ATTR_NAME("adis16209");
>  
>  static struct attribute *adis16209_event_attributes[] = {
>  	NULL
> @@ -457,13 +449,11 @@ static struct attribute *adis16209_attributes[] = {
>  	&iio_const_attr_in0_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_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_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,
>  	&iio_dev_attr_rot_raw.dev_attr.attr,
>  	NULL
> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
> index 120bf91..3eb1d55 100644
> --- a/drivers/staging/iio/accel/adis16209_ring.c
> +++ b/drivers/staging/iio/accel/adis16209_ring.c
> @@ -17,13 +17,13 @@
>  #include "../trigger.h"
>  #include "adis16209.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
> +static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
>  		     ADIS16209_SUPPLY_OUT, NULL);
good spot.  Should have caught that one the first time round...

>  static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14),
>  		     ADIS16209_XACCL_OUT, NULL);
>  static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14),
>  		     ADIS16209_YACCL_OUT, NULL);
> -static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
> +static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
>  		     ADIS16209_AUX_ADC, NULL);
>  static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12),
>  		     ADIS16209_TEMP_OUT, NULL);
> @@ -37,10 +37,10 @@ static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14),
>  static IIO_SCAN_EL_TIMESTAMP(8);
>  
>  static struct attribute *adis16209_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_accel_x.dev_attr.attr,
>  	&iio_scan_el_accel_y.dev_attr.attr,
> -	&iio_scan_el_aux_adc.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_temp.dev_attr.attr,
>  	&iio_scan_el_incli_x.dev_attr.attr,
>  	&iio_scan_el_incli_y.dev_attr.attr,
> @@ -177,12 +177,12 @@ 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_supply.number);
> +	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_aux_adc.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);
>  
> diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
> index bb7d765..edcf57d 100644
> --- a/drivers/staging/iio/accel/adis16220_core.c
> +++ b/drivers/staging/iio/accel/adis16220_core.c
> @@ -487,7 +487,7 @@ static struct bin_attribute adc2_bin = {
>  
>  static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned,
>  		ADIS16220_CAPT_SUPPLY);
> -static IIO_CONST_ATTR(in_supply_scale, "0.0012207");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0012207");
>  static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA);
>  static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit,
>  		NULL, ADIS16220_CAPT_PEAKA);
> @@ -496,8 +496,8 @@ static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO,
>  		adis16220_write_16bit,
>  		ADIS16220_ACCL_NULL);
>  static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned);
> -static IIO_CONST_ATTR(temp_offset, "25");
> -static IIO_CONST_ATTR(temp_scale, "-0.47");
> +static IIO_CONST_ATTR_TEMP_OFFSET("25");
> +static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
>  
>  static IIO_DEV_ATTR_IN_RAW(0, adis16220_read_16bit, ADIS16220_CAPT_BUF1);
>  static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2);
> @@ -518,9 +518,9 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO,
>  		adis16220_write_16bit,
>  		ADIS16220_CAPT_PNTR);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("100200");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200");
>  
> -static IIO_CONST_ATTR(name, "adis16220");
> +static IIO_CONST_ATTR_NAME("adis16220");
>  
>  static struct attribute *adis16220_attributes[] = {
>  	&iio_dev_attr_in_supply_raw.dev_attr.attr,
> @@ -533,7 +533,7 @@ static struct attribute *adis16220_attributes[] = {
>  	&iio_dev_attr_in1_raw.dev_attr.attr,
>  	&iio_const_attr_temp_offset.dev_attr.attr,
>  	&iio_const_attr_temp_scale.dev_attr.attr,
> -	&iio_const_attr_available_sampling_frequency.dev_attr.attr,
> +	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
>  	&iio_dev_attr_reset.dev_attr.attr,
>  	&iio_dev_attr_capture.dev_attr.attr,
>  	&iio_dev_attr_capture_count.dev_attr.attr,
> diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
> index 3e9531d..4583258 100644
> --- a/drivers/staging/iio/accel/adis16240_core.c
> +++ b/drivers/staging/iio/accel/adis16240_core.c
> @@ -380,7 +380,7 @@ static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16240_read_10bit_unsigned,
>  		ADIS16240_SUPPLY_OUT);
>  static IIO_DEV_ATTR_IN_RAW(0, adis16240_read_10bit_signed,
>  		ADIS16240_AUX_ADC);
> -static IIO_CONST_ATTR(in_supply_scale, "0.00488");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00488");
>  static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed,
>  		ADIS16240_XACCL_OUT);
>  static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO,
> @@ -400,26 +400,26 @@ static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO,
>  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_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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_CONST_ATTR_TEMP_SCALE("0.244");
>  
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("4096");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
>  
> -static IIO_CONST_ATTR(name, "adis16240");
> +static IIO_CONST_ATTR_NAME("adis16240");
>  
>  static struct attribute *adis16240_event_attributes[] = {
>  	NULL
> @@ -434,18 +434,18 @@ static struct attribute *adis16240_attributes[] = {
>  	&iio_const_attr_in_supply_scale.dev_attr.attr,
>  	&iio_dev_attr_in0_raw.dev_attr.attr,
>  	&iio_dev_attr_accel_x_raw.dev_attr.attr,
> -	&iio_dev_attr_accel_x_offset.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_offset.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_offset.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_available_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
> diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
> index 581d0e5..9282372 100644
> --- a/drivers/staging/iio/accel/adis16240_ring.c
> +++ b/drivers/staging/iio/accel/adis16240_ring.c
> @@ -17,7 +17,7 @@
>  #include "../trigger.h"
>  #include "adis16240.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
> +static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
>  		ADIS16240_SUPPLY_OUT, NULL);
>  static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10),
>  		ADIS16240_XACCL_OUT, NULL);
> @@ -25,7 +25,7 @@ static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10),
>  		ADIS16240_YACCL_OUT, NULL);
>  static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10),
>  		ADIS16240_ZACCL_OUT, NULL);
> -static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
> +static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
>  		ADIS16240_AUX_ADC, NULL);
>  static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
>  		ADIS16240_TEMP_OUT, NULL);
> @@ -33,11 +33,11 @@ static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
>  static IIO_SCAN_EL_TIMESTAMP(6);
>  
>  static struct attribute *adis16240_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_accel_x.dev_attr.attr,
>  	&iio_scan_el_accel_y.dev_attr.attr,
>  	&iio_scan_el_accel_z.dev_attr.attr,
> -	&iio_scan_el_aux_adc.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_temp.dev_attr.attr,
>  	&iio_scan_el_timestamp.dev_attr.attr,
>  	NULL,
> @@ -169,12 +169,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_supply.number);
> +	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_aux_adc.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in0.number);
>  
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
>  	if (ret)
> diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h
> index 5b49f83..faf73d7 100644
> --- a/drivers/staging/iio/accel/inclinometer.h
> +++ b/drivers/staging/iio/accel/inclinometer.h
> @@ -21,3 +21,5 @@
>  #define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \
>  	IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr)
>  
> +#define IIO_CONST_ATTR_INCLI_SCALE(_string) \
> +	IIO_CONST_ATTR(incli_scale, _string)
> diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
> index 0ee9337..655f2b7 100644
> --- a/drivers/staging/iio/accel/lis3l02dq_core.c
> +++ b/drivers/staging/iio/accel/lis3l02dq_core.c
> @@ -731,7 +731,7 @@ static struct attribute_group lis3l02dq_event_attribute_group = {
>  	.attrs = lis3l02dq_event_attributes,
>  };
>  
> -static IIO_CONST_ATTR(name, "lis3l02dq");
> +static IIO_CONST_ATTR_NAME("lis3l02dq");
>  static IIO_CONST_ATTR(accel_scale, "0.00958");
>  
>  static struct attribute *lis3l02dq_attributes[] = {
> diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
> index b78b6b6..0eb2c4c 100644
> --- a/drivers/staging/iio/accel/sca3000_core.c
> +++ b/drivers/staging/iio/accel/sca3000_core.c
> @@ -721,8 +721,8 @@ error_ret:
>  }
>  static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp);
>  
> -static IIO_CONST_ATTR(temp_scale, "0.555556");
> -static IIO_CONST_ATTR(temp_offset, "-214.6");
> +static IIO_CONST_ATTR_TEMP_SCALE("0.555556");
> +static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
>  
>  /**
>   * sca3000_show_thresh() sysfs query of a threshold
> diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h
> index 7841e6a..6cb916e 100644
> --- a/drivers/staging/iio/adc/adc.h
> +++ b/drivers/staging/iio/adc/adc.h
> @@ -27,5 +27,14 @@
>  			      NULL,					\
>  			      _addr)
>  
> +
> +#define IIO_CONST_ATTR_IN_NAMED_OFFSET(_name, _string)			\
> +	IIO_CONST_ATTR(in_##_name##_offset, _string)
> +
> +#define IIO_CONST_ATTR_IN_NAMED_SCALE(_name, _string)			\
> +	IIO_CONST_ATTR(in_##_name##_scale, _string)
A lot of white space here.  Could you cut it down to one line please.,
> +
> +
> +
>  #define IIO_EVENT_CODE_IN_HIGH_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a)
>  #define IIO_EVENT_CODE_IN_LOW_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a + 32)
> diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
> index 134dfaa..ac5378b 100644
> --- a/drivers/staging/iio/gyro/adis16260_core.c
> +++ b/drivers/staging/iio/gyro/adis16260_core.c
> @@ -445,22 +445,22 @@ err_ret:
>  static IIO_DEV_ATTR_IN_NAMED_RAW(supply,
>  				adis16260_read_12bit_unsigned,
>  				ADIS16260_SUPPLY_OUT);
> -static IIO_CONST_ATTR(in_supply_scale, "0.0018315");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0018315");
>  
>  static IIO_DEV_ATTR_GYRO(adis16260_read_14bit_signed,
>  		ADIS16260_GYRO_OUT);
> -static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO,
> +static IIO_DEV_ATTR_GYRO_CALIBSCALE(S_IWUSR | S_IRUGO,
>  		adis16260_read_14bit_signed,
>  		adis16260_write_16bit,
>  		ADIS16260_GYRO_SCALE);
> -static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO,
> +static IIO_DEV_ATTR_GYRO_CALIBBIAS(S_IWUSR | S_IRUGO,
>  		adis16260_read_12bit_signed,
>  		adis16260_write_16bit,
>  		ADIS16260_GYRO_OFF);
>  
>  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_CONST_ATTR_TEMP_OFFSET("25");
> +static IIO_CONST_ATTR_TEMP_SCALE("0.1453");
>  
>  static IIO_DEV_ATTR_IN_RAW(0, adis16260_read_12bit_unsigned,
>  		ADIS16260_AUX_ADC);
> @@ -474,9 +474,9 @@ static IIO_DEV_ATTR_ANGL(adis16260_read_14bit_signed,
>  
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("256 2048");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("256 2048");
>  
> -static IIO_CONST_ATTR(name, "adis16260");
> +static IIO_CONST_ATTR_NAME("adis16260");
>  
>  static struct attribute *adis16260_event_attributes[] = {
>  	NULL
> @@ -490,8 +490,8 @@ static struct attribute *adis16260_attributes[] = {
>  	&iio_dev_attr_in_supply_raw.dev_attr.attr,
>  	&iio_const_attr_in_supply_scale.dev_attr.attr,
>  	&iio_dev_attr_gyro_raw.dev_attr.attr,
> -	&iio_dev_attr_gyro_scale.dev_attr.attr,
> -	&iio_dev_attr_gyro_offset.dev_attr.attr,
ouch.  I definitely need to start checking this stuff more carefully
in driver submissions.
> +	&iio_dev_attr_gyro_calibscale.dev_attr.attr,
> +	&iio_dev_attr_gyro_calibbias.dev_attr.attr,
>  	&iio_dev_attr_angl_raw.dev_attr.attr,
>  	&iio_dev_attr_temp_raw.dev_attr.attr,
>  	&iio_const_attr_temp_offset.dev_attr.attr,
> @@ -499,7 +499,7 @@ static struct attribute *adis16260_attributes[] = {
>  	&iio_dev_attr_in0_raw.dev_attr.attr,
>  	&iio_const_attr_in0_scale.dev_attr.attr,
>  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> -	&iio_const_attr_available_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
> diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
> index 0334860..659a672 100644
> --- a/drivers/staging/iio/gyro/adis16260_ring.c
> +++ b/drivers/staging/iio/gyro/adis16260_ring.c
> @@ -17,11 +17,11 @@
>  #include "../trigger.h"
>  #include "adis16260.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
> +static IIO_SCAN_EL_C(in_supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
>  		ADIS16260_SUPPLY_OUT, NULL);
>  static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, IIO_SIGNED(14),
>  		ADIS16260_GYRO_OUT, NULL);
> -static IIO_SCAN_EL_C(aux_adc, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
> +static IIO_SCAN_EL_C(in0, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
>  		ADIS16260_AUX_ADC, NULL);
>  static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, IIO_UNSIGNED(12),
>  		ADIS16260_TEMP_OUT, NULL);
> @@ -31,9 +31,9 @@ static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, IIO_UNSIGNED(12),
>  static IIO_SCAN_EL_TIMESTAMP(5);
>  
>  static struct attribute *adis16260_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_gyro.dev_attr.attr,
> -	&iio_scan_el_aux_adc.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_temp.dev_attr.attr,
>  	&iio_scan_el_angl.dev_attr.attr,
>  	&iio_scan_el_timestamp.dev_attr.attr,
> @@ -172,9 +172,9 @@ 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_supply.number);
> +	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_aux_adc.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);
>  
> diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h
> index f68edab..98b837b 100644
> --- a/drivers/staging/iio/gyro/gyro.h
> +++ b/drivers/staging/iio/gyro/gyro.h
> @@ -3,6 +3,9 @@
>  
>  /* Gyroscope types of attribute */
>  
> +#define IIO_CONST_ATTR_GYRO_OFFSET(_string)	\
> +	IIO_CONST_ATTR(gyro_offset, _string)
> +
>  #define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr)	\
>  	IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr)
>  
> @@ -15,18 +18,45 @@
>  #define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr)	\
>  	IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr)
>  
> -#define IIO_DEV_ATTR_GYRO_X_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(gyro_x_gain, _mode, _show, _store, _addr)
> -
> -#define IIO_DEV_ATTR_GYRO_Y_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(gyro_y_gain, _mode, _show, _store, _addr)
> -
> -#define IIO_DEV_ATTR_GYRO_Z_GAIN(_mode, _show, _store, _addr)		\
> -	IIO_DEVICE_ATTR(gyro_z_gain, _mode, _show, _store, _addr)
> +#define IIO_CONST_ATTR_GYRO_SCALE(_string)		\
> +	IIO_CONST_ATTR(gyro_scale, _string)
>  
>  #define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr)		\
>  	IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr)
>  
> +#define IIO_DEV_ATTR_GYRO_X_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_x_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Y_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_y_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr)
> +
> +#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
> +	IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
> +
>  #define IIO_DEV_ATTR_GYRO(_show, _addr)			\
>  	IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
>  
> diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c
> index f1950d5..168e8b3 100644
> --- a/drivers/staging/iio/imu/adis16300_core.c
> +++ b/drivers/staging/iio/imu/adis16300_core.c
> @@ -503,28 +503,33 @@ err_ret:
>  	return ret;
>  }
>  
> -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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(supply, adis16300_read_14bit_unsigned,
>  			   ADIS16300_SUPPLY_OUT);
> -static IIO_CONST_ATTR(in_supply_scale, "0.00242");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00242");
>  
>  static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed,
>  		ADIS16300_XGYRO_OUT);
> -static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s");
> +static IIO_CONST_ATTR_GYRO_SCALE("0.05 deg/s");
>  
>  static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
>  		ADIS16300_XACCL_OUT);
> @@ -532,17 +537,17 @@ 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.0006 g");
> +static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
Abi says that units should be m/s^2.  Also we shouldn't have units
in the attributes.   I've been meaning to clear them out.  They
just make userspace code more complex for no gain.
>  
>  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.044 d");
> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>  
>  static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
These need to be suitable for conversion to milli degrees C to match
hwmon.
>  
>  static IIO_DEV_ATTR_IN_RAW(0, adis16300_read_12bit_unsigned,
>  		ADIS16300_AUX_ADC);
> @@ -554,9 +559,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
>  
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
>  
> -static IIO_CONST_ATTR(name, "adis16300");
> +static IIO_CONST_ATTR_NAME("adis16300");
>  
>  static struct attribute *adis16300_event_attributes[] = {
>  	NULL
> @@ -567,9 +572,10 @@ static struct attribute_group adis16300_event_attribute_group = {
>  };
>  
>  static struct attribute *adis16300_attributes[] = {
> -	&iio_dev_attr_accel_x_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_y_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_z_offset.dev_attr.attr,
> +	&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_in_supply_raw.dev_attr.attr,
>  	&iio_const_attr_in_supply_scale.dev_attr.attr,
>  	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
> @@ -587,7 +593,7 @@ static struct attribute *adis16300_attributes[] = {
>  	&iio_dev_attr_in0_raw.dev_attr.attr,
>  	&iio_const_attr_in0_scale.dev_attr.attr,
>  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> -	&iio_const_attr_available_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
> diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
> index 742cad6..0e09051 100644
> --- a/drivers/staging/iio/imu/adis16300_ring.c
> +++ b/drivers/staging/iio/imu/adis16300_ring.c
> @@ -17,7 +17,7 @@
>  #include "../trigger.h"
>  #include "adis16300.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
> +static IIO_SCAN_EL_C(in_supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
>  		     ADIS16300_SUPPLY_OUT, NULL);
>  
>  static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, IIO_SIGNED(14),
> @@ -32,7 +32,7 @@ static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, IIO_SIGNED(14),
>  
>  static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_UNSIGNED(12),
>  		     ADIS16300_TEMP_OUT, NULL);
> -static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
> +static IIO_SCAN_EL_C(in0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
>  		     ADIS16300_AUX_ADC, NULL);
>  
>  static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X, IIO_SIGNED(12),
> @@ -43,7 +43,7 @@ static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y, IIO_SIGNED(12),
>  static IIO_SCAN_EL_TIMESTAMP(9);
>  
>  static struct attribute *adis16300_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_gyro_x.dev_attr.attr,
>  	&iio_scan_el_temp.dev_attr.attr,
>  	&iio_scan_el_accel_x.dev_attr.attr,
> @@ -51,7 +51,7 @@ static struct attribute *adis16300_scan_el_attrs[] = {
>  	&iio_scan_el_accel_z.dev_attr.attr,
>  	&iio_scan_el_incli_x.dev_attr.attr,
>  	&iio_scan_el_incli_y.dev_attr.attr,
> -	&iio_scan_el_adc_0.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_timestamp.dev_attr.attr,
>  	NULL,
>  };
> @@ -196,13 +196,13 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
>  	ring->owner = THIS_MODULE;
>  
>  	/* Set default scan mode */
> -	iio_scan_mask_set(ring, iio_scan_el_supply.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in_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_adc_0.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);
>  
> diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
> index 1575b7b..d1f1015 100644
> --- a/drivers/staging/iio/imu/adis16350_core.c
> +++ b/drivers/staging/iio/imu/adis16350_core.c
> @@ -475,24 +475,39 @@ err_ret:
>  	return ret;
>  }
>  
> -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
> +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);
> +
Good point.  I never even noticed these weren't present in the
driver.


> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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_OFFSET(S_IWUSR | S_IRUGO,
> +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(supply, adis16350_read_12bit_unsigned,
>  		ADIS16350_SUPPLY_OUT);
> -static IIO_CONST_ATTR(in_supply_scale, "0.002418");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418");
>  
>  static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
>  		ADIS16350_XGYRO_OUT);
> @@ -500,7 +515,7 @@ 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.05");
> +static IIO_CONST_ATTR_GYRO_SCALE("0.05");
>  
>  static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
>  		ADIS16350_XACCL_OUT);
> @@ -508,7 +523,7 @@ 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.00333");
> +static IIO_CONST_ATTR_ACCEL_SCALE("0.00333");
>  
>  static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
>  		NULL, ADIS16350_XTEMP_OUT);
> @@ -516,7 +531,7 @@ 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.0005");
> +static IIO_CONST_ATTR_TEMP_SCALE("0.0005");
>  
>  static IIO_DEV_ATTR_IN_RAW(0, adis16350_read_12bit_unsigned,
>  		ADIS16350_AUX_ADC);
> @@ -529,14 +544,17 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
>  		adis16350_write_reset, 0);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
>  
> -static IIO_CONST_ATTR(name, "adis16350");
> +static IIO_CONST_ATTR_NAME("adis16350");
>  
>  static struct attribute *adis16350_attributes[] = {
> -	&iio_dev_attr_accel_x_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_y_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_z_offset.dev_attr.attr,
> +	&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_in_supply_raw.dev_attr.attr,
>  	&iio_const_attr_in_supply_scale.dev_attr.attr,
>  	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
> @@ -554,7 +572,7 @@ static struct attribute *adis16350_attributes[] = {
>  	&iio_dev_attr_in0_raw.dev_attr.attr,
>  	&iio_const_attr_in0_scale.dev_attr.attr,
>  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> -	&iio_const_attr_available_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
> diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
> index a0b80e4..aefbae5 100644
> --- a/drivers/staging/iio/imu/adis16350_ring.c
> +++ b/drivers/staging/iio/imu/adis16350_ring.c
> @@ -17,7 +17,7 @@
>  #include "../trigger.h"
>  #include "adis16350.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
> +static IIO_SCAN_EL_C(in_supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
>  		ADIS16350_SUPPLY_OUT, NULL);
>  
>  static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14),
> @@ -41,13 +41,13 @@ static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12),
>  static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12),
>  		ADIS16350_ZTEMP_OUT, NULL);
>  
> -static IIO_SCAN_EL_C(adc_0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
> +static IIO_SCAN_EL_C(in0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
>  		ADIS16350_AUX_ADC, NULL);
>  
>  static IIO_SCAN_EL_TIMESTAMP(11);
>  
>  static struct attribute *adis16350_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_gyro_x.dev_attr.attr,
>  	&iio_scan_el_gyro_y.dev_attr.attr,
>  	&iio_scan_el_gyro_z.dev_attr.attr,
> @@ -57,7 +57,7 @@ static struct attribute *adis16350_scan_el_attrs[] = {
>  	&iio_scan_el_temp_x.dev_attr.attr,
>  	&iio_scan_el_temp_y.dev_attr.attr,
>  	&iio_scan_el_temp_z.dev_attr.attr,
> -	&iio_scan_el_adc_0.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_timestamp.dev_attr.attr,
>  	NULL,
>  };
> @@ -196,7 +196,7 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
>  	ring->owner = THIS_MODULE;
>  
>  	/* Set default scan mode */
> -	iio_scan_mask_set(ring, iio_scan_el_supply.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in_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);
> @@ -206,7 +206,7 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
>  	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_adc_0.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in0.number);
>  
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
>  	if (ret)
> diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
> index 6013fee..1765fef 100644
> --- a/drivers/staging/iio/imu/adis16400_core.c
> +++ b/drivers/staging/iio/imu/adis16400_core.c
> @@ -490,24 +490,24 @@ err_ret:
>  	return ret;
>  }
>  
> -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
> -		adis16400_read_12bit_signed,
> -		adis16400_write_16bit,
> -		ADIS16400_XACCL_OFF);
> +#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 IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
> -		adis16400_read_12bit_signed,
> -		adis16400_write_16bit,
> -		ADIS16400_YACCL_OFF);
> +static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF);
> +static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_XGYRO_OFF);
> +static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_XGYRO_OFF);
> +
> +static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF);
> +static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_XACCL_OFF);
> +static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_XACCL_OFF);
>  
> -static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
> -		adis16400_read_12bit_signed,
> -		adis16400_write_16bit,
> -		ADIS16400_ZACCL_OFF);
>  
>  static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16400_read_14bit_signed,
>  		ADIS16400_SUPPLY_OUT);
> -static IIO_CONST_ATTR(in_supply_scale, "0.002418");
> +static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418 V");
>  
>  static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed,
>  		ADIS16400_XGYRO_OUT);
> @@ -535,12 +535,12 @@ 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_CONST_ATTR_TEMP_OFFSET("198.16 K");
> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>  
>  static IIO_DEV_ATTR_IN_RAW(0, adis16400_read_12bit_unsigned,
>  		ADIS16400_AUX_ADC);
> -static IIO_CONST_ATTR(in0_scale, "0.000806");
> +static IIO_CONST_ATTR(in0_scale, "0.000806 V");
>  
>  static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
>  		adis16400_read_frequency,
> @@ -548,9 +548,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
>  
>  static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
>  
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
>  
> -static IIO_CONST_ATTR(name, "adis16400");
> +static IIO_CONST_ATTR_NAME("adis16400");
>  
>  static struct attribute *adis16400_event_attributes[] = {
>  	NULL
> @@ -561,9 +561,12 @@ static struct attribute_group adis16400_event_attribute_group = {
>  };
>  
>  static struct attribute *adis16400_attributes[] = {
> -	&iio_dev_attr_accel_x_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_y_offset.dev_attr.attr,
> -	&iio_dev_attr_accel_z_offset.dev_attr.attr,
> +	&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_in_supply_raw.dev_attr.attr,
>  	&iio_const_attr_in_supply_scale.dev_attr.attr,
>  	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
> @@ -584,7 +587,7 @@ static struct attribute *adis16400_attributes[] = {
>  	&iio_dev_attr_in0_raw.dev_attr.attr,
>  	&iio_const_attr_in0_scale.dev_attr.attr,
>  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> -	&iio_const_attr_available_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
> diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
> index 667f77b..de5ef5c 100644
> --- a/drivers/staging/iio/imu/adis16400_ring.c
> +++ b/drivers/staging/iio/imu/adis16400_ring.c
> @@ -17,7 +17,7 @@
>  #include "../trigger.h"
>  #include "adis16400.h"
>  
> -static IIO_SCAN_EL_C(supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
> +static IIO_SCAN_EL_C(in_supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
>  		     ADIS16400_SUPPLY_OUT, NULL);
>  
>  static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, IIO_SIGNED(14),
> @@ -43,13 +43,13 @@ static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, IIO_SIGNED(14),
>  
>  static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, IIO_SIGNED(12),
>  		     ADIS16400_TEMP_OUT, NULL);
> -static IIO_SCAN_EL_C(adc_0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
> +static IIO_SCAN_EL_C(in0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
>  		     ADIS16400_AUX_ADC, NULL);
>  
>  static IIO_SCAN_EL_TIMESTAMP(12);
>  
>  static struct attribute *adis16400_scan_el_attrs[] = {
> -	&iio_scan_el_supply.dev_attr.attr,
> +	&iio_scan_el_in_supply.dev_attr.attr,
>  	&iio_scan_el_gyro_x.dev_attr.attr,
>  	&iio_scan_el_gyro_y.dev_attr.attr,
>  	&iio_scan_el_gyro_z.dev_attr.attr,
> @@ -60,7 +60,7 @@ static struct attribute *adis16400_scan_el_attrs[] = {
>  	&iio_scan_el_magn_y.dev_attr.attr,
>  	&iio_scan_el_magn_z.dev_attr.attr,
>  	&iio_scan_el_temp.dev_attr.attr,
> -	&iio_scan_el_adc_0.dev_attr.attr,
> +	&iio_scan_el_in0.dev_attr.attr,
>  	&iio_scan_el_timestamp.dev_attr.attr,
>  	NULL,
>  };
> @@ -205,7 +205,7 @@ 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_supply.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in_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);
> @@ -216,7 +216,7 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
>  	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_adc_0.number);
> +	iio_scan_mask_set(ring, iio_scan_el_in0.number);
>  
>  	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
>  	if (ret)
> diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
> index 6083416..a4d4bb6 100644
> --- a/drivers/staging/iio/sysfs.h
> +++ b/drivers/staging/iio/sysfs.h
> @@ -130,6 +130,13 @@ struct iio_const_attr {
>  	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
>  
>  /**
> + * IIO_CONST_ATTR_NAME - constant identifier
> + * @_string: the name
> + **/
> +#define IIO_CONST_ATTR_NAME(_string)				\
> +	IIO_CONST_ATTR(name, _string)
> +
> +/**
>   * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency
>   * @_mode: sysfs file mode/permissions
>   * @_show: output method for the attribute
> @@ -156,10 +163,6 @@ struct iio_const_attr {
>   *
>   * Constant version
>   **/
> -/* Deprecated */
> -#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string)			\
> -	IIO_CONST_ATTR(available_sampling_frequency, _string)
> -
>  #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string)			\
>  	IIO_CONST_ATTR(sampling_frequency_available, _string)
>  
> @@ -244,6 +247,12 @@ struct iio_const_attr {
>  #define IIO_DEV_ATTR_TEMP_RAW(_show)			\
>  	IIO_DEVICE_ATTR(temp_raw, S_IRUGO, _show, NULL, 0)
>  
> +#define IIO_CONST_ATTR_TEMP_OFFSET(_string)		\
> +	IIO_CONST_ATTR(temp_offset, _string)
> +
> +#define IIO_CONST_ATTR_TEMP_SCALE(_string)		\
> +	IIO_CONST_ATTR(temp_scale, _string)
> +
>  /**
>   * IIO_EVENT_SH - generic shared event handler
>   * @_name: event name


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

* Re: [PATCH 1/3] staging:iio update documentation
  2010-08-30 14:24                 ` Manuel Stahl
@ 2010-08-30 14:49                   ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 14:49 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

Hi Manel
>>>
>>> +What:        /sys/.../device[n]/buffer/scan_elements
>> Is this not /sys/.../device[n]/buffer[m]/scan_elements? I think we allow
>> for multiple buffers per device.
>>> +KernelVersion:    2.6.37
>>> +Contact:    linux-iio@vger.kernel.org
>>> +Description:
>>> +        Directory containing interfaces for elements that will be captured
>>> +        for a single triggered sample set in the buffer.
>>> +
>>> +What:        /sys/.../device[n]/buffer/scan_elements/[m]_accel_x0_en
>> This needs some brackets... [_x0]
> 
> Depends on what we accord for the next version, there should be a patch removing the [m] and creating all the new files.

As I said in the other discussion.  That m (or direct equivalent) is vital.  Otherwise userspace has no way of knowing
the parameter ordering in what comes out of the buffer.  As things stand I haven't yet seen
any reason (beyond ls putting them in a nice order) for changing that element of the interface.

The brackets issue here is completely separate.  We have always allowed single dimension accelerometers
to not specify a direction.  And there are dual parallel accelerometer chips out there hence the need for
the optional number. 
> 
>>> +KernelVersion:    2.6.37
>>> +Contact:    linux-iio@vger.kernel.org
>>> +Description:
>>> +        Scan element control for triggered data capture. m implies the
>>> +        ordering within the buffer. Next the type is specified with
>>> +        modifier and channel number as per the sysfs single channel
>>> +        access above.
>>> +
>> Obviously the next two will get eaten up by your suggestion of 'type' the other
>> day, but best to keep the documentation matching what is actually in place so
>> I'm glad to see you updated them.
>>> +What:        /sys/.../device[n]/buffer/scan_elements/accel[_x0]_precision
>>> +KernelVersion:    2.6.37
>>> +Contact:    linux-iio@vger.kernel.org
>>> +Description:
>>> +        Scan element precision within the buffer. Note that the
>>> +        data alignment must restrictions must be read from within
>>> +        buffer to work out full data alignment for data read
>>> +        via buffer_access chrdev. _x0 dropped if shared across all
>>> +        acceleration channels.
>>> +
>>> +What:        /sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift
>>> +KernelVersion:    2.6.37
>>> +Contact:    linux-iio@vger.kernel.org
>>> +Description:
>>> +        A bit shift (to right) that must be applied prior to
>>> +        extracting the bits specified by accel[_x0]_precision.
>>> +
>>> diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
>>> index 4838818..8bba2fa 100644
>>> --- a/drivers/staging/iio/Documentation/userspace.txt
>>> +++ b/drivers/staging/iio/Documentation/userspace.txt
>>> @@ -7,17 +7,14 @@ Typical sysfs entries (pruned for clarity)
>>>   /sys/class/iio
>>>     device0 - iio_dev related elements
>>>       name - driver specific identifier (here lis3l02dq)
>>> -    accel_x - polled (or from ring) raw readout of acceleration
>>> -    accel_x_gain - hardware gain (calibration)
>>> -    accel_x_offset - hardware offset (calibration)
>>> -    available_sampling_frequency
>>> +    accel_x_raw - polled (or from ring) raw readout of acceleration
>>> +    accel_x_offset - offset to be applied to the raw reading
>>> +    accel_x_scale - scale to be applied to the raw reading and offset
>>> +    accel_x_calibbias - hardware offset (calibration)
>>> +    accel_x_calibscale - hardware gain (calibration)
>> youch, Hadn't realised how out of date some of this has gotten.
>>
>> Actually we can probably drop most of this file.  It just replicates
>> the abi documentation (and predates it). Shall I do that once
>> your changes have merged, or do you want to loose everything down
>> to the Udev will create line?  Perhaps add something saying the sysfs
>> stuff is documented in the abi file?
> 
> Would be great if you do another docu review patch afterwards.

Cool, will do.  Then send this patch on as is with my 

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

Perhaps naming it staging:iio partial documentation update

just to stop anyone pointing out that the documentation isn't perfect
after your patch!

Jonathan

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

* Re: [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation
  2010-08-30 14:03             ` [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation Manuel Stahl
@ 2010-08-30 14:58               ` Jonathan Cameron
  2010-08-31 12:16                 ` Datta, Shubhrajyoti
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 14:58 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio, Shubhrajyoti Datta

This one would benefit from an ack from Shubhrajyoti Datta (cc'd)

It's his driver and whilst to my eye this looks fine it would
be good to have his input on the scale numbers.

If he doesn't reply for a bit send it on anyway ;)  (as it is
fairly trivial)

I actually promised to fix this myself in the original review
but I'm happy you beat me to it ;)

One issue inline...  Fix that and feel free to add my sign-off.

Thanks,

Jonathan

On 08/30/10 15:03, Manuel Stahl wrote:
> Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>

> ---
>  drivers/staging/iio/magnetometer/hmc5843.c |   32 ++++++++++++++--------------
>  1 files changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
> index 92f6c6f..66aab5a 100644
> --- a/drivers/staging/iio/magnetometer/hmc5843.c
> +++ b/drivers/staging/iio/magnetometer/hmc5843.c
> @@ -95,15 +95,15 @@
>  #define	CONF_NOT_USED				0x03
>  #define	MEAS_CONF_MASK				0x03
>  
> -static const int regval_to_counts_per_mg[] = {
> -	1620,
> -	1300,
> -	970,
> -	780,
> -	530,
> -	460,
> -	390,
> -	280
> +static const char *regval_to_scale[] = {
> +	"0.0000006173",
> +	"0.0000007692",
> +	"0.0000010309",
> +	"0.0000012821",
> +	"0.0000018868",
> +	"0.0000021739",
> +	"0.0000025641",
> +	"0.0000035714",
>  };
>  static const int regval_to_input_field_mg[] = {
>  	700,
> @@ -322,7 +322,7 @@ static IIO_DEVICE_ATTR(meas_conf,
>   * 6		| 50
>   * 7		| Not used
>   */
> -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
>  
>  static s32 hmc5843_set_rate(struct i2c_client *client,
>  				u8 rate)
> @@ -459,17 +459,17 @@ static IIO_DEVICE_ATTR(magn_range,
>  			set_range,
>  			HMC5843_CONFIG_REG_B);
>  
> -static ssize_t show_gain(struct device *dev,
> +static ssize_t show_scale(struct device *dev,
>  			struct device_attribute *attr,
>  			char *buf)
>  {
>  	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct hmc5843_data *data = indio_dev->dev_data;
> -	return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
> +	return strlen(strcpy(buf, regval_to_scale[data->range]));

That leaves us without a trailing "\n".  Makes for messy use of cat ;)
Probably easier to use

return sprintf(buf, "%s\n", regval_to_scale[data->range]);
>  }
> -static IIO_DEVICE_ATTR(magn_gain,
> +static IIO_DEVICE_ATTR(magn_scale,
>  			S_IRUGO,
> -			show_gain,
> +			show_scale,
>  			NULL , 0);
>  
>  static struct attribute *hmc5843_attributes[] = {
> @@ -477,11 +477,11 @@ static struct attribute *hmc5843_attributes[] = {
>  	&iio_dev_attr_operating_mode.dev_attr.attr,
>  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
>  	&iio_dev_attr_magn_range.dev_attr.attr,
> -	&iio_dev_attr_magn_gain.dev_attr.attr,
> +	&iio_dev_attr_magn_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_available_sampling_frequency.dev_attr.attr,
> +	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
>  	NULL
>  };
>  


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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 14:44               ` Jonathan Cameron
@ 2010-08-30 15:00                 ` Manuel Stahl
  2010-08-30 15:42                   ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 15:00 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 3375 bytes --]

Am 30.08.2010 16:44, schrieb Jonathan Cameron:
> On 08/30/10 15:03, Manuel Stahl wrote:
>
> Youch, I hadn't registered just how far away this lot were from the abi.
> Thanks for doing this.
>
> I sometimes wonder if it would be better to loose all the macros and move
> over to abi doc based enforcement (like hwmon does).  What do people think?
> As can be seen in this patch, it makes very little difference in the length of
> code.  Disadvantage is that it does add a review burden.

I think we should keep the macros. Then we can simply search for 
IIO_DEVICE_ATTR and IIO_CONST_ATTR in the drivers, as these are 
suspicious for declaring proprietary attributes. When the well known 
macros change they produce compile errors. Also good for finding broken 
drivers.

> Let's merge this fix anyway and consider whether to loose some of the macros
> at a later date.
>
> Quite a bit of this fixes naming of parameter that weren't correct under the
> previous abi.  Clearly we (meaning mainly me :) ) need to review drivers
> much more closely for abi breakage.

As I said before, some macros are suspicious and we can search for them.
i.e. IIO_DEV_ATTR_ACCEL_X_OFFSET and IIO_DEV_ATTR_ACCEL_X_SCALE should 
be rarely used as they're constant for most devices.

> An excellent patch.  Thank you very much for doing this.
>
> One minor white space introduction that I'd like you to clean up before
> sending on.
>
>
>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
> Signed-off-by: Jonathan Cameron<jic23@cam.ac.uk>
>


>>   static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
>>   		ADIS16300_XACCL_OUT);
>> @@ -532,17 +537,17 @@ 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.0006 g");
>> +static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
> Abi says that units should be m/s^2.  Also we shouldn't have units
> in the attributes.   I've been meaning to clear them out.  They
> just make userspace code more complex for no gain.

Ups, you're right with m/s^2, nevertheless is worth an extra patch. 
Sure, the units don't need to be there, but parsing is the same with or 
without (scanf just ignores the chars).

>>   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.044 d");
>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>
>>   static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
> These need to be suitable for conversion to milli degrees C to match
> hwmon.
I think scientific devices should stick to SI units.

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 15:00                 ` Manuel Stahl
@ 2010-08-30 15:42                   ` Jonathan Cameron
  2010-08-30 15:48                     ` Manuel Stahl
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 15:42 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

On 08/30/10 16:00, Manuel Stahl wrote:
> Am 30.08.2010 16:44, schrieb Jonathan Cameron:
>> On 08/30/10 15:03, Manuel Stahl wrote:
>>
>> Youch, I hadn't registered just how far away this lot were from the abi.
>> Thanks for doing this.
>>
>> I sometimes wonder if it would be better to loose all the macros and move
>> over to abi doc based enforcement (like hwmon does).  What do people think?
>> As can be seen in this patch, it makes very little difference in the length of
>> code.  Disadvantage is that it does add a review burden.
> 
> I think we should keep the macros. Then we can simply search for
> IIO_DEVICE_ATTR and IIO_CONST_ATTR in the drivers, as these are
> suspicious for declaring proprietary attributes. When the well known
> macros change they produce compile errors. Also good for finding
> broken drivers.
A good point.  As a general rule, lets say we don't introduce new ones into the
headers until either:

1) There are two drivers using them and they are something we are sure will stay in drivers
   (I'm still unconvinced by the reset attribute in many of Analog's drivers)
2) They are obviously general elements.  e.g. when we had the first magnetometer we
   introduced the magn parameters.  Let has also start being militant about the necessity to
   also document any new ones.  Either the first user updates the docs or someone else has
   to within a few days... I'll do them when I think pestering people about it will delay
   an otherwise good driver.
> 
>> Let's merge this fix anyway and consider whether to loose some of the macros
>> at a later date.
>>
>> Quite a bit of this fixes naming of parameter that weren't correct under the
>> previous abi.  Clearly we (meaning mainly me :) ) need to review drivers
>> much more closely for abi breakage.
> 
> As I said before, some macros are suspicious and we can search for them.
> i.e. IIO_DEV_ATTR_ACCEL_X_OFFSET and IIO_DEV_ATTR_ACCEL_X_SCALE should be rarely used as they're constant for most devices.
There are actually numerous multirange accelerometers.  It is mere coincidence that
we don't have any in tree yet but I take your point.
> 
>> An excellent patch.  Thank you very much for doing this.
>>
>> One minor white space introduction that I'd like you to clean up before
>> sending on.
>>
>>
>>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
>> Signed-off-by: Jonathan Cameron<jic23@cam.ac.uk>
>>
> 
> 
>>>   static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
>>>           ADIS16300_XACCL_OUT);
>>> @@ -532,17 +537,17 @@ 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.0006 g");
>>> +static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
>> Abi says that units should be m/s^2.  Also we shouldn't have units
>> in the attributes.   I've been meaning to clear them out.  They
>> just make userspace code more complex for no gain.
> 
> Ups, you're right with m/s^2, nevertheless is worth an extra patch. Sure, the units don't need to be there, but parsing is the same with or without (scanf just ignores the chars).
Cool.  Can I leave this one to you?
> 
>>>   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.044 d");
>>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>>
>>>   static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
>>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>> These need to be suitable for conversion to milli degrees C to match
>> hwmon.
> I think scientific devices should stick to SI units.
I'd normally agree, but hwmon beat us in defining the interface and I
agree with Greg and Andrew Morton that the kernel is gaining too many
incompatible interfaces.  Hence for temp we follow them.  Same ought
to be true for in[m] and current measurements.  Guess I'll do an audit
of this sometime soon and make sure they are all the same.

Jonathan

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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 15:42                   ` Jonathan Cameron
@ 2010-08-30 15:48                     ` Manuel Stahl
  2010-08-30 16:07                       ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 15:48 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 4402 bytes --]

Am 30.08.2010 17:42, schrieb Jonathan Cameron:
> On 08/30/10 16:00, Manuel Stahl wrote:
>> Am 30.08.2010 16:44, schrieb Jonathan Cameron:
>>> On 08/30/10 15:03, Manuel Stahl wrote:
>>>
>>> Youch, I hadn't registered just how far away this lot were from the abi.
>>> Thanks for doing this.
>>>
>>> I sometimes wonder if it would be better to loose all the macros and move
>>> over to abi doc based enforcement (like hwmon does).  What do people think?
>>> As can be seen in this patch, it makes very little difference in the length of
>>> code.  Disadvantage is that it does add a review burden.
>>
>> I think we should keep the macros. Then we can simply search for
>> IIO_DEVICE_ATTR and IIO_CONST_ATTR in the drivers, as these are
>> suspicious for declaring proprietary attributes. When the well known
>> macros change they produce compile errors. Also good for finding
>> broken drivers.
> A good point.  As a general rule, lets say we don't introduce new ones into the
> headers until either:
>
> 1) There are two drivers using them and they are something we are sure will stay in drivers
>     (I'm still unconvinced by the reset attribute in many of Analog's drivers)

I think this is the case for supply, so we could add a macro for this one.

> 2) They are obviously general elements.  e.g. when we had the first magnetometer we
>     introduced the magn parameters.  Let has also start being militant about the necessity to
>     also document any new ones.  Either the first user updates the docs or someone else has
>     to within a few days... I'll do them when I think pestering people about it will delay
>     an otherwise good driver.

Good point.


>>>>    static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
>>>>            ADIS16300_XACCL_OUT);
>>>> @@ -532,17 +537,17 @@ 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.0006 g");
>>>> +static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
>>> Abi says that units should be m/s^2.  Also we shouldn't have units
>>> in the attributes.   I've been meaning to clear them out.  They
>>> just make userspace code more complex for no gain.
>>
>> Ups, you're right with m/s^2, nevertheless is worth an extra patch. Sure, the units don't need to be there, but parsing is the same with or without (scanf just ignores the chars).
> Cool.  Can I leave this one to you?

Ok, guess I also introduced the mess here.

>>>>    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.044 d");
>>>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>>>
>>>>    static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
>>>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>>>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>>>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>>>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>>> These need to be suitable for conversion to milli degrees C to match
>>> hwmon.
>> I think scientific devices should stick to SI units.
> I'd normally agree, but hwmon beat us in defining the interface and I
> agree with Greg and Andrew Morton that the kernel is gaining too many
> incompatible interfaces.  Hence for temp we follow them.  Same ought
> to be true for in[m] and current measurements.  Guess I'll do an audit
> of this sometime soon and make sure they are all the same.

We already have a major difference here, that is we allow floating point 
values as output. Also we have no _input postfix, which, I agree, should 
be compatible if it was there. Hwmon is tuned to fixed point values, but 
that it too limited for the range of devices we want to address with 
IIO. They simply don't care if they loose some bit of precision.

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 15:48                     ` Manuel Stahl
@ 2010-08-30 16:07                       ` Jonathan Cameron
  2010-08-30 16:28                         ` Manuel Stahl
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 16:07 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

On 08/30/10 16:48, Manuel Stahl wrote:
> Am 30.08.2010 17:42, schrieb Jonathan Cameron:
>> On 08/30/10 16:00, Manuel Stahl wrote:
>>> Am 30.08.2010 16:44, schrieb Jonathan Cameron:
>>>> On 08/30/10 15:03, Manuel Stahl wrote:
>>>>
>>>> Youch, I hadn't registered just how far away this lot were from the abi.
>>>> Thanks for doing this.
>>>>
>>>> I sometimes wonder if it would be better to loose all the macros and move
>>>> over to abi doc based enforcement (like hwmon does).  What do people think?
>>>> As can be seen in this patch, it makes very little difference in the length of
>>>> code.  Disadvantage is that it does add a review burden.
>>>
>>> I think we should keep the macros. Then we can simply search for
>>> IIO_DEVICE_ATTR and IIO_CONST_ATTR in the drivers, as these are
>>> suspicious for declaring proprietary attributes. When the well known
>>> macros change they produce compile errors. Also good for finding
>>> broken drivers.
>> A good point.  As a general rule, lets say we don't introduce new ones into the
>> headers until either:
>>
>> 1) There are two drivers using them and they are something we are sure will stay in drivers
>>     (I'm still unconvinced by the reset attribute in many of Analog's drivers)
> 
> I think this is the case for supply, so we could add a macro for this one.
Indeed, that one is clearly a common case.
> 
>> 2) They are obviously general elements.  e.g. when we had the first magnetometer we
>>     introduced the magn parameters.  Let has also start being militant about the necessity to
>>     also document any new ones.  Either the first user updates the docs or someone else has
>>     to within a few days... I'll do them when I think pestering people about it will delay
>>     an otherwise good driver.
> 
> Good point.
> 
> 
>>>>>    static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
>>>>>            ADIS16300_XACCL_OUT);
>>>>> @@ -532,17 +537,17 @@ 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.0006 g");
>>>>> +static IIO_CONST_ATTR_ACCEL_SCALE("0.0006 g");
>>>> Abi says that units should be m/s^2.  Also we shouldn't have units
>>>> in the attributes.   I've been meaning to clear them out.  They
>>>> just make userspace code more complex for no gain.
>>>
>>> Ups, you're right with m/s^2, nevertheless is worth an extra patch. Sure, the units don't need to be there, but parsing is the same with or without (scanf just ignores the chars).
>> Cool.  Can I leave this one to you?
> 
> Ok, guess I also introduced the mess here.
Thanks ;)  There are others sculling about, but an audit ought to
pick them up.
> 
>>>>>    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.044 d");
>>>>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>>>>
>>>>>    static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
>>>>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>>>>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>>>>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>>>>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>>>> These need to be suitable for conversion to milli degrees C to match
>>>> hwmon.
>>> I think scientific devices should stick to SI units.
>> I'd normally agree, but hwmon beat us in defining the interface and I
>> agree with Greg and Andrew Morton that the kernel is gaining too many
>> incompatible interfaces.  Hence for temp we follow them.  Same ought
>> to be true for in[m] and current measurements.  Guess I'll do an audit
>> of this sometime soon and make sure they are all the same.
> 
> We already have a major difference here, that is we allow floating
> point values as output. Also we have no _input postfix, which, I
> agree, should be compatible if it was there. Hwmon is tuned to fixed
> point values, but that it too limited for the range of devices we
> want to address with IIO. They simply don't care if they loose some
> bit of precision.
We do allow _input.  Only one user at the moment though.  illuminance0_input
in the tsl2563 driver.  The intent was always to extend their interface
but not to break comparability if we can easily avoid it.  I should probably
document the fact we allow this. It's useful for slow devices with non linear
mappings between their raw values and the measurement. (very common in light
sensors).  Things will get more 'interesting' when we have a fast device
with a non linear mapping.  We'll figure that out what to do about that
if / when some has such a device.

I agree that fixed point is overly limiting for our purposes. However, by
simply allowing ours to use floating point userspace can accommodate either.
Afterall in most cases a floating point read of an integer string will give
the right (or very close to it) result.

Basically my intent (supported by others in the abi discussions) is to match and extend
hwmon wherever possible.  I'm actively advocating this approach elsewhere in the
kernel as well.

Jonathan

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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 16:07                       ` Jonathan Cameron
@ 2010-08-30 16:28                         ` Manuel Stahl
  2010-08-30 16:43                           ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 16:28 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

[-- Attachment #1: Type: text/plain, Size: 3517 bytes --]

Am 30.08.2010 18:07, schrieb Jonathan Cameron:
> On 08/30/10 16:48, Manuel Stahl wrote:
>> Am 30.08.2010 17:42, schrieb Jonathan Cameron:
>>> On 08/30/10 16:00, Manuel Stahl wrote:
>>>> Am 30.08.2010 16:44, schrieb Jonathan Cameron:
>>>>> On 08/30/10 15:03, Manuel Stahl wrote:
>>>>>>     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.044 d");
>>>>>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>>>>>
>>>>>>     static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
>>>>>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>>>>>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>>>>>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>>>>>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>>>>> These need to be suitable for conversion to milli degrees C to match
>>>>> hwmon.
>>>> I think scientific devices should stick to SI units.
>>> I'd normally agree, but hwmon beat us in defining the interface and I
>>> agree with Greg and Andrew Morton that the kernel is gaining too many
>>> incompatible interfaces.  Hence for temp we follow them.  Same ought
>>> to be true for in[m] and current measurements.  Guess I'll do an audit
>>> of this sometime soon and make sure they are all the same.
>>
>> We already have a major difference here, that is we allow floating
>> point values as output. Also we have no _input postfix, which, I
>> agree, should be compatible if it was there. Hwmon is tuned to fixed
>> point values, but that it too limited for the range of devices we
>> want to address with IIO. They simply don't care if they loose some
>> bit of precision.
> We do allow _input.  Only one user at the moment though.  illuminance0_input
> in the tsl2563 driver.  The intent was always to extend their interface
> but not to break comparability if we can easily avoid it.  I should probably
> document the fact we allow this. It's useful for slow devices with non linear
> mappings between their raw values and the measurement. (very common in light
> sensors).  Things will get more 'interesting' when we have a fast device
> with a non linear mapping.  We'll figure that out what to do about that
> if / when some has such a device.
>
> I agree that fixed point is overly limiting for our purposes. However, by
> simply allowing ours to use floating point userspace can accommodate either.
> Afterall in most cases a floating point read of an integer string will give
> the right (or very close to it) result.
>
> Basically my intent (supported by others in the abi discussions) is to match and extend
> hwmon wherever possible.  I'm actively advocating this approach elsewhere in the
> kernel as well.

As I said, I have no doubt that *_input files must be compatible (mV, 
m°C), but the combination of _raw, _offset and _scale can result in SI 
units as you have to do floating point math anyway.
While doing the cleanup here, I found that we have rad/s for gyros and 
deg for inclinometeres. Should be unified somehow.

Cheers,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 170 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* Re: [PATCH 2/2] staging:iio move scan_elements into ring buffer
       [not found]                 ` <4C7BD886.3060109@cam.ac.uk>
@ 2010-08-30 16:31                   ` Manuel Stahl
  2010-08-30 16:48                     ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Manuel Stahl @ 2010-08-30 16:31 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1579 bytes --]

Am 30.08.2010 18:12, schrieb Jonathan Cameron:
> On 08/30/10 14:37, Manuel Stahl wrote:
>> Am 30.08.2010 14:58, schrieb Jonathan Cameron:
>>> On 08/30/10 11:55, Manuel Stahl wrote:
>>>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
>>>
>>> On more complex patches like this, could you verify which devices
>>> you have tested against? Given the nature of that patch it
>>> probably doesn't matter that much, but it's nice to save people
>>> from wondering if they need to test on devices you have already
>>> tried it with.
>>
>> I have an sca3000 and an adis16405 to test with. The patch was made against v26.36-rc2 and compiled fine for all drivers in staging.
> Glad you have an sca3000.  My test board is currently broken so I've just
> been crossing my fingers that I hadn't broken the driver with recent code
> changes!  Have you had any problems with the adis16405?  I'm currently getting
> seg faults with an adis16350 that I can't seem to track down.  I'm waiting
> for Barry to answer a few queries on that one...

I know where the segfaults come from: iio_scan_el_show, etc.
I forgot to cast to a buffer instead of a iio_dev.

For sca3000 I have some problems with the ring buffer. The event doesn't 
get triggered.

Regards,
-- 
Dipl.-Inf. Manuel Stahl
Fraunhofer-Institut für Integrierte Schaltungen IIS
- Leistungsoptimierte Systeme -
Nordostpark 93                Telefon  +49 (0)911/58061-6419
90411 Nürnberg                Fax      +49 (0)911/58061-6398
http://www.iis.fraunhofer.de  manuel.stahl@iis.fraunhofer.de

[-- Attachment #2: manuel_stahl.vcf --]
[-- Type: text/x-vcard, Size: 161 bytes --]

begin:vcard
fn:Manuel Stahl
n:Stahl;Manuel
email;internet:manuel.stahl@iis.fraunhofer.de
tel;work:+49 911 58061-6419
x-mozilla-html:FALSE
version:2.1
end:vcard


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

* Re: [PATCH 2/3] staging:iio sync drivers with current ABI
  2010-08-30 16:28                         ` Manuel Stahl
@ 2010-08-30 16:43                           ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 16:43 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio

On 08/30/10 17:28, Manuel Stahl wrote:
> Am 30.08.2010 18:07, schrieb Jonathan Cameron:
>> On 08/30/10 16:48, Manuel Stahl wrote:
>>> Am 30.08.2010 17:42, schrieb Jonathan Cameron:
>>>> On 08/30/10 16:00, Manuel Stahl wrote:
>>>>> Am 30.08.2010 16:44, schrieb Jonathan Cameron:
>>>>>> On 08/30/10 15:03, Manuel Stahl wrote:
>>>>>>>     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.044 d");
>>>>>>> +static IIO_CONST_ATTR_INCLI_SCALE("0.044 deg");
>>>>>>>
>>>>>>>     static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned)=
;
>>>>>>> -static IIO_CONST_ATTR(temp_offset, "198.16 K");
>>>>>>> -static IIO_CONST_ATTR(temp_scale, "0.14 K");
>>>>>>> +static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
>>>>>>> +static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
>>>>>> These need to be suitable for conversion to milli degrees C to m=
atch
>>>>>> hwmon.
>>>>> I think scientific devices should stick to SI units.
>>>> I'd normally agree, but hwmon beat us in defining the interface an=
d I
>>>> agree with Greg and Andrew Morton that the kernel is gaining too m=
any
>>>> incompatible interfaces.  Hence for temp we follow them.  Same oug=
ht
>>>> to be true for in[m] and current measurements.  Guess I'll do an a=
udit
>>>> of this sometime soon and make sure they are all the same.
>>>
>>> We already have a major difference here, that is we allow floating
>>> point values as output. Also we have no _input postfix, which, I
>>> agree, should be compatible if it was there. Hwmon is tuned to fixe=
d
>>> point values, but that it too limited for the range of devices we
>>> want to address with IIO. They simply don't care if they loose some
>>> bit of precision.
>> We do allow _input.  Only one user at the moment though.  illuminanc=
e0_input
>> in the tsl2563 driver.  The intent was always to extend their interf=
ace
>> but not to break comparability if we can easily avoid it.  I should =
probably
>> document the fact we allow this. It's useful for slow devices with n=
on linear
>> mappings between their raw values and the measurement. (very common =
in light
>> sensors).  Things will get more 'interesting' when we have a fast de=
vice
>> with a non linear mapping.  We'll figure that out what to do about t=
hat
>> if / when some has such a device.
>>
>> I agree that fixed point is overly limiting for our purposes. Howeve=
r, by
>> simply allowing ours to use floating point userspace can accommodate=
 either.
>> Afterall in most cases a floating point read of an integer string wi=
ll give
>> the right (or very close to it) result.
>>
>> Basically my intent (supported by others in the abi discussions) is =
to match and extend
>> hwmon wherever possible.  I'm actively advocating this approach else=
where in the
>> kernel as well.
>=20
> As I said, I have no doubt that *_input files must be compatible (mV,
> m=B0C), but the combination of _raw, _offset and _scale can result in
> SI units as you have to do floating point math anyway.
I still think matching their multiplier (e.g. milli volts etc) is going=
 to
be a better idea on the long run.  Other than being marginally annoying=
 in
that we aren't going to do this for other unit types, I don't think it =
matters
to us...  I've seen a few people agitating on lm-sensors for a higher a=
ccuracy
option there.  If they need it then I'd argue for our raw and multiplie=
r approach.
To be cynical, along with it being a good idea in my view, the reason f=
or
matching units is to avoid conflict with those we need to eventually co=
nvince
in order to move out of staging.  It's just good politics.

> While doing
> the cleanup here, I found that we have rad/s for gyros and deg for
> inclinometeres. Should be unified somehow

Agreed.  Which one shall we go for?
Having googled to confirm. Radians are accepted as closest derived SI u=
nit...
http://physics.nist.gov/cuu/Units/units.html
Got to love a m/m argument...

So I think rad/s.

Jonathan


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

* Re: [PATCH 2/2] staging:iio move scan_elements into ring buffer
  2010-08-30 16:31                   ` Manuel Stahl
@ 2010-08-30 16:48                     ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-08-30 16:48 UTC (permalink / raw)
  To: Manuel Stahl; +Cc: linux-iio@vger.kernel.org

On 08/30/10 17:31, Manuel Stahl wrote:
> Am 30.08.2010 18:12, schrieb Jonathan Cameron:
>> On 08/30/10 14:37, Manuel Stahl wrote:
>>> Am 30.08.2010 14:58, schrieb Jonathan Cameron:
>>>> On 08/30/10 11:55, Manuel Stahl wrote:
>>>>> Signed-off-by: Manuel Stahl<manuel.stahl@iis.fraunhofer.de>
>>>>
>>>> On more complex patches like this, could you verify which devices
>>>> you have tested against? Given the nature of that patch it
>>>> probably doesn't matter that much, but it's nice to save people
>>>> from wondering if they need to test on devices you have already
>>>> tried it with.
>>>
>>> I have an sca3000 and an adis16405 to test with. The patch was made against v26.36-rc2 and compiled fine for all drivers in staging.
>> Glad you have an sca3000.  My test board is currently broken so I've just
>> been crossing my fingers that I hadn't broken the driver with recent code
>> changes!  Have you had any problems with the adis16405?  I'm currently getting
>> seg faults with an adis16350 that I can't seem to track down.  I'm waiting
>> for Barry to answer a few queries on that one...
> 
> I know where the segfaults come from: iio_scan_el_show, etc.
> I forgot to cast to a buffer instead of a iio_dev.
Nope, the problem was pre todays patches, though obviously please fix
that one ;)  That kit is at home so I'll give it another poke this evening.
> 
> For sca3000 I have some problems with the ring buffer. The event doesn't get triggered.
Guess I should fix my board and take another look at that driver.

Jonathan


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

* RE: [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation
  2010-08-30 14:58               ` Jonathan Cameron
@ 2010-08-31 12:16                 ` Datta, Shubhrajyoti
  0 siblings, 0 replies; 28+ messages in thread
From: Datta, Shubhrajyoti @ 2010-08-31 12:16 UTC (permalink / raw)
  To: Jonathan Cameron, Manuel Stahl; +Cc: linux-iio@vger.kernel.org



> -----Original Message-----
> From: Jonathan Cameron [mailto:jic23@cam.ac.uk]
> Sent: Monday, August 30, 2010 8:28 PM
> To: Manuel Stahl
> Cc: linux-iio@vger.kernel.org; Datta, Shubhrajyoti
> Subject: Re: [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with
> documentation
>=20
> This one would benefit from an ack from Shubhrajyoti Datta (cc'd)
>=20
Looks good to me feel free to add my appreciations/ack
Thanks for the patch.
> It's his driver and whilst to my eye this looks fine it would
> be good to have his input on the scale numbers.
>=20
> If he doesn't reply for a bit send it on anyway ;)  (as it is
> fairly trivial)
>=20
> I actually promised to fix this myself in the original review
> but I'm happy you beat me to it ;)
>=20
> One issue inline...  Fix that and feel free to add my sign-off.
>=20
> Thanks,
>=20
> Jonathan
>=20
> On 08/30/10 15:03, Manuel Stahl wrote:
> > Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
>=20
> > ---
> >  drivers/staging/iio/magnetometer/hmc5843.c |   32 ++++++++++++++------=
-
> -------
> >  1 files changed, 16 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/staging/iio/magnetometer/hmc5843.c
> b/drivers/staging/iio/magnetometer/hmc5843.c
> > index 92f6c6f..66aab5a 100644
> > --- a/drivers/staging/iio/magnetometer/hmc5843.c
> > +++ b/drivers/staging/iio/magnetometer/hmc5843.c
> > @@ -95,15 +95,15 @@
> >  #define	CONF_NOT_USED				0x03
> >  #define	MEAS_CONF_MASK				0x03
> >
> > -static const int regval_to_counts_per_mg[] =3D {
> > -	1620,
> > -	1300,
> > -	970,
> > -	780,
> > -	530,
> > -	460,
> > -	390,
> > -	280
> > +static const char *regval_to_scale[] =3D {
> > +	"0.0000006173",
> > +	"0.0000007692",
> > +	"0.0000010309",
> > +	"0.0000012821",
> > +	"0.0000018868",
> > +	"0.0000021739",
> > +	"0.0000025641",
> > +	"0.0000035714",
> >  };
> >  static const int regval_to_input_field_mg[] =3D {
> >  	700,
> > @@ -322,7 +322,7 @@ static IIO_DEVICE_ATTR(meas_conf,
> >   * 6		| 50
> >   * 7		| Not used
> >   */
> > -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
> > +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
> >
> >  static s32 hmc5843_set_rate(struct i2c_client *client,
> >  				u8 rate)
> > @@ -459,17 +459,17 @@ static IIO_DEVICE_ATTR(magn_range,
> >  			set_range,
> >  			HMC5843_CONFIG_REG_B);
> >
> > -static ssize_t show_gain(struct device *dev,
> > +static ssize_t show_scale(struct device *dev,
> >  			struct device_attribute *attr,
> >  			char *buf)
> >  {
> >  	struct iio_dev *indio_dev =3D dev_get_drvdata(dev);
> >  	struct hmc5843_data *data =3D indio_dev->dev_data;
> > -	return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
> > +	return strlen(strcpy(buf, regval_to_scale[data->range]));
>=20
> That leaves us without a trailing "\n".  Makes for messy use of cat ;)
> Probably easier to use
>=20
> return sprintf(buf, "%s\n", regval_to_scale[data->range]);
> >  }
> > -static IIO_DEVICE_ATTR(magn_gain,
> > +static IIO_DEVICE_ATTR(magn_scale,
> >  			S_IRUGO,
> > -			show_gain,
> > +			show_scale,
> >  			NULL , 0);
> >
> >  static struct attribute *hmc5843_attributes[] =3D {
> > @@ -477,11 +477,11 @@ static struct attribute *hmc5843_attributes[] =3D=
 {
> >  	&iio_dev_attr_operating_mode.dev_attr.attr,
> >  	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> >  	&iio_dev_attr_magn_range.dev_attr.attr,
> > -	&iio_dev_attr_magn_gain.dev_attr.attr,
> > +	&iio_dev_attr_magn_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_available_sampling_frequency.dev_attr.attr,
> > +	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
> >  	NULL
> >  };
> >

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

* Re: [IIO] Cleanup userspace
  2010-08-27 15:09         ` Jonathan Cameron
  2010-08-30 10:55           ` [PATCH 1/2] staging:iio rename ring attributes Manuel Stahl
  2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
@ 2010-09-04 17:26           ` Jonathan Cameron
  2 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2010-09-04 17:26 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Manuel Stahl, linux-iio@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org

On 08/27/10 16:09, Jonathan Cameron wrote:
> ...
>>>
>>> Agreed. These ought to be in there and will be needed
>>>
>>>> To be compatible with future extensions we could have:
>>>>    |- /sys/bus/iio/ii0/buffer0/scan_elements/
>>>>       |- accel_x:en    (0 or 1)
>>>>       |- accel_x:type  (i.e. s14/16, see *)
>>>>       |- accel_x:index
>>>>
>>>
>>>> * s14/16 means signed 14 bits, stored in 16 bits, right aligned. If
>>>> it's left aligned we can just modify the scale attribute and give the
>>>> 16 bit interpretation in <channel>:raw.
>>> That is quite a neat way of doing it though I'm not sure 'type' is the
>>> ideal name.  My immediate thought is that type would be 'acceleration'!
>>> We definitely want this on list.  We'd also want to drop the precision
>>> attribute as that will just confuse things.
>>
>> I'm open for any other name.
> Lets see if anyone else has a suggestion...

actually, having thought about it a bit more (and as no one else chipped in)
I'm happy to go with type as you suggested. It's a nice clear interface.
It should be obvious to anyone looking at the value that it is about the size
of the element (even if they don't immediately follow the /16 bit).
Perhaps we should run this past lkml to see if anyone has a suggestion?

Manuel, it's your idea so you get to write the email ;)

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

end of thread, other threads:[~2010-09-04 17:26 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-27  8:57 [IIO] Cleanup userspace Manuel Stahl
     [not found] ` <4C77AC01.3090204@cam.ac.uk>
     [not found]   ` <4C77B68B.4060805@iis.fraunhofer.de>
2010-08-27 14:24     ` Jonathan Cameron
2010-08-27 14:31       ` Manuel Stahl
2010-08-27 15:09         ` Jonathan Cameron
2010-08-30 10:55           ` [PATCH 1/2] staging:iio rename ring attributes Manuel Stahl
2010-08-30 12:28             ` Jonathan Cameron
2010-08-30 10:55           ` [PATCH 2/2] staging:iio move scan_elements into ring buffer Manuel Stahl
2010-08-30 12:58             ` Jonathan Cameron
2010-08-30 13:37               ` Manuel Stahl
2010-08-30 14:09                 ` Jonathan Cameron
     [not found]                 ` <4C7BD886.3060109@cam.ac.uk>
2010-08-30 16:31                   ` Manuel Stahl
2010-08-30 16:48                     ` Jonathan Cameron
2010-08-30 14:03             ` [PATCH 1/3] staging:iio update documentation Manuel Stahl
2010-08-30 14:23               ` Jonathan Cameron
2010-08-30 14:24                 ` Manuel Stahl
2010-08-30 14:49                   ` Jonathan Cameron
2010-08-30 14:03             ` [PATCH 2/3] staging:iio sync drivers with current ABI Manuel Stahl
2010-08-30 14:44               ` Jonathan Cameron
2010-08-30 15:00                 ` Manuel Stahl
2010-08-30 15:42                   ` Jonathan Cameron
2010-08-30 15:48                     ` Manuel Stahl
2010-08-30 16:07                       ` Jonathan Cameron
2010-08-30 16:28                         ` Manuel Stahl
2010-08-30 16:43                           ` Jonathan Cameron
2010-08-30 14:03             ` [PATCH 3/3] staging:iio:hmc5843 change ABI to comply with documentation Manuel Stahl
2010-08-30 14:58               ` Jonathan Cameron
2010-08-31 12:16                 ` Datta, Shubhrajyoti
2010-09-04 17:26           ` [IIO] Cleanup userspace Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox