RE: [PATCH] staging: iio: adc: Enable driver support for ad799x AD converters

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jonathan Cameron wrote on 2010-10-01:
> On 10/01/10 16:07, Hennerich, Michael wrote:
>> Jonathan Cameron wrote on 2010-10-01:
>>> Hi Michael,
>>>
>>> I was pretty much happy with this last time round. Couple of comments
>>> inline. The new line missing in the Makefile is probably the only one
>>> that I'd advocate doing pre merge.
>>>
>>> The precision attrs have gone away to be replaced by the more
>>> informative type attributes in the scan_elements directory.  This can
>>> trivially be done as an additional patch post merge.
>>>
>>> There are some subtle changes to the event naming (post discussion on
>>> lkml) but I'll just do this driver alongside the others in the patch
>>> set implementing those changes. This is the first driver providing
>>> hyst so that attribute will also need documenting. Again that should
>>> happen post merge.
>>>
>>> I think we can also take advantage of some of the helper functions
>>> that are now in place for buffer registration (came out of Barry's
>>> work), but that can definitely happen at a later date.
>>>
>>> So in summary I'm happy to see this merge right now.  The sooner the
>>> better as far as I'm concerned
>>
>> Hi Jonathan,
>>
>> We have a few more iio drivers in our repository. Over the next couple
>> of weeks I'm trying to get them out. Excellent.
>>
>>> because I would like it to go in before
>>> the event clean up series currently sat in my tree. That way I can
>>> update this one at the same time.
>>
>> Oops - this patch was already against your tree:
>> http://git.kernel.org/?p=linux/kernel/git/jic23/iio_temp.git
>>
>> Need to check if it works on Greg's staging.
> Ah. Shouldn't be too bad.  That's what I get for putting temporary trees
> up - that one only exists for testing the adis16260 and adis16350 driver
> changes.

Well - it looks bad.
It basically errors on everything I changed in order to make it work on your temp tree.
I'll send Greg my original version...

drivers/staging/iio/adc/ad799x_ring.c: In function 'ad799x_single_channel_from_ring':
drivers/staging/iio/adc/ad799x_ring.c:35: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_ring.c:39: error: 'struct iio_ring_buffer' has no member named 'scan_count'
drivers/staging/iio/adc/ad799x_ring.c:53: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_ring.c: In function 'ad799x_ring_preenable':
drivers/staging/iio/adc/ad799x_ring.c:85: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_ring.c:87: error: 'struct iio_ring_buffer' has no member named 'scan_count'
drivers/staging/iio/adc/ad799x_ring.c:89: error: 'struct iio_ring_access_funcs' has no member named 'set_bytes_per_datum'
drivers/staging/iio/adc/ad799x_ring.c:93: error: 'struct iio_ring_access_funcs' has no member named 'set_bytes_per_datum'
drivers/staging/iio/adc/ad799x_ring.c: In function 'ad799x_poll_bh_to_ring':
drivers/staging/iio/adc/ad799x_ring.c:136: error: 'struct iio_ring_buffer' has no member named 'scan_count'
drivers/staging/iio/adc/ad799x_ring.c:163: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_ring.c:169: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_ring.c: In function 'ad799x_register_ring_funcs_and_init':
drivers/staging/iio/adc/ad799x_ring.c:225: error: 'struct iio_ring_buffer' has no member named 'scan_el_attrs'
  LD      drivers/staging/iio/light/built-in.o
drivers/staging/iio/adc/ad799x_core.c: In function 'ad799x_scan_el_set_state':
drivers/staging/iio/adc/ad799x_core.c:108: error: 'struct iio_ring_buffer' has no member named 'scan_mask'
drivers/staging/iio/adc/ad799x_core.c:117:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c: At top level:
drivers/staging/iio/adc/ad799x_core.c:117: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:118:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:118: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:119:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:119: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:120:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:120: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:121:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:121: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:122:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:122: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:123:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:123: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c:124:1: error: macro "IIO_SCAN_EL_C" requires 5 arguments, but only 4 given
drivers/staging/iio/adc/ad799x_core.c:124: warning: type defaults to 'int' in declaration of 'IIO_SCAN_EL_C'
drivers/staging/iio/adc/ad799x_core.c: In function 'ad799x_interrupt_bh':
drivers/staging/iio/adc/ad799x_core.c:391: warning: suggest parentheses around + or - inside shift
drivers/staging/iio/adc/ad799x_core.c:392: warning: right shift count >= width of type
drivers/staging/iio/adc/ad799x_core.c:392: warning: suggest parentheses around + or - inside shift
drivers/staging/iio/adc/ad799x_core.c: At top level:
drivers/staging/iio/adc/ad799x_core.c:469: error: 'iio_scan_el_in0' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:470: error: 'iio_const_attr_in0_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:471: error: 'iio_scan_el_in1' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:472: error: 'iio_const_attr_in1_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:473: error: 'iio_scan_el_in2' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:474: error: 'iio_const_attr_in2_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:475: error: 'iio_scan_el_in3' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:476: error: 'iio_const_attr_in3_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:499: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:499: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:499: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:499: error: (near initialization for 'ad7992_scan_el_attrs[0]')
drivers/staging/iio/adc/ad799x_core.c:500: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:500: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:500: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:500: error: (near initialization for 'ad7992_scan_el_attrs[1]')
drivers/staging/iio/adc/ad799x_core.c:501: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:501: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:501: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:501: error: (near initialization for 'ad7992_scan_el_attrs[2]')
drivers/staging/iio/adc/ad799x_core.c:502: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:502: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:502: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:502: error: (near initialization for 'ad7992_scan_el_attrs[3]')
drivers/staging/iio/adc/ad799x_core.c:531: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:531: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:531: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:531: error: (near initialization for 'ad7997_8_scan_el_attrs[0]')
drivers/staging/iio/adc/ad799x_core.c:532: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:532: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:532: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:532: error: (near initialization for 'ad7997_8_scan_el_attrs[1]')
drivers/staging/iio/adc/ad799x_core.c:533: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:533: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:533: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:533: error: (near initialization for 'ad7997_8_scan_el_attrs[2]')
drivers/staging/iio/adc/ad799x_core.c:534: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:534: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:534: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:534: error: (near initialization for 'ad7997_8_scan_el_attrs[3]')
drivers/staging/iio/adc/ad799x_core.c:535: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:535: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:535: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:535: error: (near initialization for 'ad7997_8_scan_el_attrs[4]')
drivers/staging/iio/adc/ad799x_core.c:536: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:536: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:536: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:536: error: (near initialization for 'ad7997_8_scan_el_attrs[5]')
drivers/staging/iio/adc/ad799x_core.c:537: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:537: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:537: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:537: error: (near initialization for 'ad7997_8_scan_el_attrs[6]')
drivers/staging/iio/adc/ad799x_core.c:538: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:538: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:538: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:538: error: (near initialization for 'ad7997_8_scan_el_attrs[7]')
drivers/staging/iio/adc/ad799x_core.c:539: error: 'iio_scan_el_in4' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:539: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:539: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:539: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:539: error: (near initialization for 'ad7997_8_scan_el_attrs[8]')
drivers/staging/iio/adc/ad799x_core.c:540: error: 'iio_const_attr_in4_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:540: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:540: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:540: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:540: error: (near initialization for 'ad7997_8_scan_el_attrs[9]')
drivers/staging/iio/adc/ad799x_core.c:541: error: 'iio_scan_el_in5' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:541: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:541: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:541: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:541: error: (near initialization for 'ad7997_8_scan_el_attrs[10]')
drivers/staging/iio/adc/ad799x_core.c:542: error: 'iio_const_attr_in5_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:542: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:542: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:542: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:542: error: (near initialization for 'ad7997_8_scan_el_attrs[11]')
drivers/staging/iio/adc/ad799x_core.c:543: error: 'iio_scan_el_in6' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:543: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:543: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:543: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:543: error: (near initialization for 'ad7997_8_scan_el_attrs[12]')
drivers/staging/iio/adc/ad799x_core.c:544: error: 'iio_const_attr_in6_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:544: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:544: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:544: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:544: error: (near initialization for 'ad7997_8_scan_el_attrs[13]')
drivers/staging/iio/adc/ad799x_core.c:545: error: 'iio_scan_el_in7' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:545: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:545: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:545: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:545: error: (near initialization for 'ad7997_8_scan_el_attrs[14]')
drivers/staging/iio/adc/ad799x_core.c:546: error: 'iio_const_attr_in7_index' undeclared here (not in a function)
drivers/staging/iio/adc/ad799x_core.c:546: error: request for member 'dev_attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:546: error: request for member 'attr' in something not a structure or union
drivers/staging/iio/adc/ad799x_core.c:546: error: initializer element is not constant
drivers/staging/iio/adc/ad799x_core.c:546: error: (near initialization for 'ad7997_8_scan_el_attrs[15]')


>
>> ...It's time to get out of staging
> Couple of big bits that I think will need doing before we are ready
> to run that gauntlet. Now its mainly stuff around the buffer code.
>
>>
>>> Acked-by: Jonathan Cameron <jic23@xxxxxxxxx>
>>>
>>> Please send on to Greg KH <greg@xxxxxxxxx> for him to merge.
>>>
>>> Thanks,
>>>
>>> Jonathan
>>>
>>>> Driver for ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997
>>>> and
>>>> ad7998 multichannel ADC.
>>>>
>>>> Signed-off-by: Michael Hennerich <michael.hennerich@xxxxxxxxxx>
>>>> ---
>>>>  drivers/staging/iio/adc/Kconfig       |   20 +
>>>>  drivers/staging/iio/adc/Makefile      |    4 +
>>>>  drivers/staging/iio/adc/ad799x.h      |  157 ++++++
>>>>  drivers/staging/iio/adc/ad799x_core.c |  918
>>>> +++++++++++++++++++++++++++++++++
>>>> drivers/staging/iio/adc/ad799x_ring.c |  246 +++++++++
>>>>  5 files changed, 1345 insertions(+), 0 deletions(-)  create mode
>>>> 100644 drivers/staging/iio/adc/ad799x.h  create mode 100644
>>>> drivers/staging/iio/adc/ad799x_core.c
>>>>  create mode 100644 drivers/staging/iio/adc/ad799x_ring.c
>>>> diff --git a/drivers/staging/iio/adc/Kconfig
>>>> b/drivers/staging/iio/adc/Kconfig index 0835fbc..3ea4da8 100644
>>>> --- a/drivers/staging/iio/adc/Kconfig
>>>> +++ b/drivers/staging/iio/adc/Kconfig
>>>> @@ -26,3 +26,23 @@ config MAX1363_RING_BUFFER
>>>>      help
>>>>        Say yes here to include ring buffer support in the MAX1363
>>>>        ADC driver.
>>>> +
>>>> +config AD799X
>>>> +    tristate "Analog Devices AD799x ADC driver"
>>> I'll express my usual anti comment on driver names with wild cards,
>>> but as there are hardly any numbers left in the range it is probably
>>> fine here.
>>>> +    depends on I2C +    select IIO_TRIGGER if IIO_RING_BUFFER +
>>>> select AD799X_RING_BUFFER +    help +      Say yes here to build
>>>> support for Analog Devices: +      ad7991, ad7995, ad7999, ad7992,
>>>> ad7993, ad7994, ad7997, ad7998 +      i2c analog to digital
>>>> convertors (ADC). Provides direct access +      via sysfs. + +config
>>>> AD799X_RING_BUFFER +    bool "Analog Devices AD799x: use ring buffer"
>>>> +    depends on AD799X +    select IIO_RING_BUFFER +    select
>>>> IIO_SW_RING +    help +      Say yes here to include ring buffer
>>>> support in the AD799X +      ADC driver. diff --git
>>>> a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
>>>> index 688510f..f4aa63a 100644 --- a/drivers/staging/iio/adc/Makefile
>>>> +++ b/drivers/staging/iio/adc/Makefile @@ -6,3 +6,7 @@ max1363-y :=
>>>> max1363_core.o  max1363-y += max1363_ring.o
>>>>
>>>>  obj-$(CONFIG_MAX1363) += max1363.o
>>>> + +ad799x-y := ad799x_core.o +ad799x-$(CONFIG_AD799X_RING_BUFFER) +=
>>>> ad799x_ring.o +obj-$(CONFIG_AD799X) += ad799x.o Please add a new line
>>>> after this. \ No newline at end of file diff --git
>>>> a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
>>>> new file mode 100644 index 0000000..73f3ec5 --- /dev/null +++
>>>> b/drivers/staging/iio/adc/ad799x.h @@ -0,0 +1,157 @@ +/* + *
>>>> Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + *
>>>> Copyright (C) 2008-2010 Jonathan Cameron + * + * This program is free
>>>> software; you can redistribute it and/or +modify + * it under the
>>>> terms of the GNU General Public License version 2 +as + * published
>>>> by the Free Software Foundation. + * + * ad799x.h + */ + +#ifndef
>>>> _AD799X_H_ +#define _AD799X_H_ + +#define AD799X_CHANNEL_SHIFT
>>>>            4 + +/* + * AD7991, AD7995 and AD7999 defines  */ +
>>>> +#define AD7991_REF_SEL 0x08 +#define AD7991_FLTR
>>>>      0x04 +#define AD7991_BIT_TRIAL_DELAY                    0x02
>>>> +#define AD7991_SAMPLE_DELAY                  0x01 + +/* + * AD7992,
>>>> AD7993, AD7994, AD7997 and AD7998 defines  */ + +#define AD7998_FLTR
>>>> 0x08 +#define AD7998_ALERT_EN                              0x04
>>>> +#define AD7998_BUSY_ALERT                 0x02 +#define
>>>> AD7998_BUSY_ALERT_POL                        0x01 + +#define
>>>> AD7998_CONV_RES_REG                     0x0 +#define
>>>> AD7998_ALERT_STAT_REG                       0x1 +#define
>>>> AD7998_CONF_REG                            0x2 +#define
>>>> AD7998_CYCLE_TMR_REG                        0x3 +#define
>>>> AD7998_DATALOW_CH1_REG                       0x4 +#define
>>>> AD7998_DATAHIGH_CH1_REG                    0x5 +#define
>>>> AD7998_HYST_CH1_REG                 0x6 +#define
>>>> AD7998_DATALOW_CH2_REG                       0x7 +#define
>>>> AD7998_DATAHIGH_CH2_REG                    0x8 +#define
>>>> AD7998_HYST_CH2_REG                 0x9 +#define
>>>> AD7998_DATALOW_CH3_REG                       0xA +#define
>>>> AD7998_DATAHIGH_CH3_REG                    0xB +#define
>>>> AD7998_HYST_CH3_REG                 0xC +#define
>>>> AD7998_DATALOW_CH4_REG                       0xD +#define
>>>> AD7998_DATAHIGH_CH4_REG                    0xE +#define
>>>> AD7998_HYST_CH4_REG                 0xF + +#define AD7998_CYC_MASK
>>>>                       0x7 +#define AD7998_CYC_DIS
>>>>          0x0 +#define AD7998_CYC_TCONF_32                        0x1
>>>> +#define AD7998_CYC_TCONF_64                 0x2 +#define
>>>> AD7998_CYC_TCONF_128                       0x3 +#define
>>>> AD7998_CYC_TCONF_256                        0x4 +#define
>>>> AD7998_CYC_TCONF_512                       0x5 +#define
>>>> AD7998_CYC_TCONF_1024                       0x6 +#define
>>>> AD7998_CYC_TCONF_2048                        0x7 + +#define
>>>> AD7998_ALERT_STAT_CLEAR                  0xFF + +/* + * AD7997 and
>>>> AD7997 defines + */ + +#define AD7997_8_READ_SINGLE
>>>> 0x80 +#define AD7997_8_READ_SEQUENCE                    0x70 + +enum
>>>> { +    ad7991, +       ad7995, +       ad7999, + ad7992, +
>>>> ad7993, +       ad7994, +    ad7997, +       ad7998 +}; + +struct
>>>> ad799x_state; + +/** + * struct ad799x_chip_info - chip specifc
>>>> information + * @num_inputs: number of physical inputs on chip + *
>>>> @bits:           accuracy of the adc in bits + * @int_vref_mv:
>>>> the internal reference voltage + * @monitor_mode:       whether the
>>>> chip supports monitor interrupts + * @default_config:    device
>>>> default configuration + * @dev_attrs:                pointer to the
>>>> device attribute group + * @scan_attrs:               pointer to the
>>>> scan element attribute group + * @event_attrs:        pointer to the
>>>> monitor event attribute group + * @ad799x_set_scan_mode: function
>>>> pointer to the device specific +mode function + + */ +struct
>>>> ad799x_chip_info { + u8 num_inputs; +    u8
>>>>    bits; + u16 int_vref_mv; +  bool
>>>> monitor_mode; +    u16                             default_config; +
>>>>      struct attribute_group          *dev_attrs; +   struct
>>>> attribute_group              *scan_attrs; +  struct attribute_group
>>>> *event_attrs; +    int (*ad799x_set_scan_mode)     (struct
>>>> ad799x_state *st, + unsigned mask); +}; + +struct ad799x_state { +
>>>>     struct iio_dev *indio_dev; +    struct i2c_client
>>>> *client; +      const struct ad799x_chip_info     *chip_info; +
>>>> struct work_struct poll_work; +    struct work_struct
>>>> work_thresh; +  atomic_t protect_ring; + struct iio_trigger
>>>> *trig; +        struct regulator *reg; + s64
>>>>    last_timestamp; +    u16                             int_vref_mv;
>>>> +  unsigned id; +   char                            *name; +    u16
>>>>                           config; +}; + +/* + * TODO: struct
>>>> ad799x_platform_data needs to go into +inlude/linux/iio Typo in
>>>> comment. + */ + +struct ad799x_platform_data { +     u16 vref_mv; +};
>>>> + +int ad799x_set_scan_mode(struct ad799x_state *st, unsigned mask);
>>>> + +#ifdef CONFIG_AD799X_RING_BUFFER +int
>>>> ad799x_single_channel_from_ring(struct ad799x_state *st, long +mask);
>>>> int ad799x_register_ring_funcs_and_init(struct iio_dev +*indio_dev);
>>>> void ad799x_ring_cleanup(struct iio_dev *indio_dev); +#else /*
>>>> CONFIG_AD799X_RING_BUFFER */ int
>>>> +ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
>>>> { +    return -EINVAL; +} + + +static inline int
>>>> +ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) { +
>>>>  return 0; +} + +static inline void ad799x_ring_cleanup(struct
>>>> iio_dev *indio_dev) { } +#endif /* CONFIG_AD799X_RING_BUFFER */
>>>> #endif /* _AD799X_H_ */ diff --git
>>>> a/drivers/staging/iio/adc/ad799x_core.c
>>>> b/drivers/staging/iio/adc/ad799x_core.c new file mode 100644 index
>>>> 0000000..772c664 --- /dev/null +++
>>>> b/drivers/staging/iio/adc/ad799x_core.c @@ -0,0 +1,918 @@ +/* + *
>>>> iio/adc/ad799x.c + * Copyright (C) 2010 Michael Hennerich, Analog
>>>> Devices Inc. + * + * based on iio/adc/max1363 + * Copyright (C)
>>>> 2008-2010 Jonathan Cameron + * + * based on
>>>> linux/drivers/i2c/chips/max123x + * Copyright (C) 2002-2004 Stefan
>>>> Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.c + *
>>>> Copyright (C) 2000 Russell King + * + * This program is free
>>>> software; you can redistribute it and/or +modify + * it under the
>>>> terms of the GNU General Public License version 2 +as + * published
>>>> by the Free Software Foundation. + * + * ad799x.c + * + * Support for
>>>> ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, +ad7997, + * ad7998
>>>> and similar chips. + * + */ + +#include <linux/interrupt.h> +#include
>>>> <linux/workqueue.h> +#include <linux/device.h> +#include
>>>> <linux/kernel.h> +#include <linux/sysfs.h> +#include <linux/list.h>
>>>> +#include <linux/i2c.h> +#include <linux/regulator/consumer.h>
>>>> #include <linux/slab.h> +#include <linux/types.h> #include
>>>> <linux/err.h> + +#include "../iio.h" +#include "../sysfs.h" +
>>>> +#include "../ring_generic.h" +#include "adc.h" +#include "ad799x.h"
>>>> + +/* + * ad799x register access by I2C + */ +static int
>>>> ad799x_i2c_read16(struct ad799x_state *st, u8 reg, u16 +*data) { +
>>>> struct i2c_client *client = st->client; +        int ret = 0; + +
>>>>    ret = i2c_smbus_read_word_data(client, reg); +      if (ret < 0) {
>>>> +                dev_err(&client->dev, "I2C read error\n"); +
>>>>    return ret; +   } + +   *data = swab16((u16)ret); + + return 0; +}
>>>> + +static int ad799x_i2c_read8(struct ad799x_state *st, u8 reg, u8
>>>> +*data) { +  struct i2c_client *client = st->client; +       int ret
>>>> = 0; + +    ret = i2c_smbus_read_word_data(client, reg); +  if (ret <
>>>> 0) { +            dev_err(&client->dev, "I2C read error\n"); + return
>>>> ret; +   } + +    *data = ret; + +        return 0; +} + +static int
>>>> ad799x_i2c_write16(struct ad799x_state *st, u8 reg, u16 +data) { +
>>>>  struct i2c_client *client = st->client; +        int ret = 0; + +
>>>>     ret = i2c_smbus_write_word_data(client, reg, swab16(data)); +
>>>>    if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + +
>>>>   return ret; +} + +static int ad799x_i2c_write8(struct ad799x_state
>>>> *st, u8 reg, u8 +data) { +      struct i2c_client *client =
>>>> st->client; +        int ret = 0; + +        ret =
>>>> i2c_smbus_write_byte_data(client, reg, data); +        if (ret < 0) +
>>>>          dev_err(&client->dev, "I2C write error\n"); + +       return
>>>> ret; +} + +static int ad799x_scan_el_set_state(struct iio_scan_el
>>>> *scan_el, + struct iio_dev *indio_dev, +
>>>>   bool state) +{ + struct ad799x_state *st = indio_dev->dev_data; +
>>>>  return ad799x_set_scan_mode(st, st->indio_dev->ring->scan_mask); } +
>>>> +/* Here we claim all are 16 bits. This currently does no harm and
>>>> +saves + * us a lot of scan element listings */ + +#define
>>>> AD799X_SCAN_EL(number) \ +     IIO_SCAN_EL_C(in##number, number, 0,
>>>> ad799x_scan_el_set_state); + +static AD799X_SCAN_EL(0); +static
>>>> AD799X_SCAN_EL(1); +static AD799X_SCAN_EL(2); +static
>>>> AD799X_SCAN_EL(3); +static AD799X_SCAN_EL(4); +static
>>>> AD799X_SCAN_EL(5); +static AD799X_SCAN_EL(6); +static
>>>> AD799X_SCAN_EL(7); + +static ssize_t ad799x_show_precision(struct
>>>> device *dev, +                               struct device_attribute
>>>> *attr, +                                char *buf) +{ +    struct
>>>> iio_dev *dev_info = dev_get_drvdata(dev); +      struct ad799x_state
>>>> *st = iio_dev_get_devdata(dev_info); +  return sprintf(buf, "%d\n",
>>>> st->chip_info->bits); } + +static IIO_DEVICE_ATTR(in_precision,
>>>> S_IRUGO, ad799x_show_precision, +                   NULL, 0); +
>>>> +static int ad7991_5_9_set_scan_mode(struct ad799x_state *st,
>>>> unsigned +mask) { +    return i2c_smbus_write_byte(st->client, +
>>>>          st- config | (mask << AD799X_CHANNEL_SHIFT)); } + +static
>>>> int ad7992_3_4_set_scan_mode(struct ad799x_state *st, unsigned +mask)
>>>> { +        return ad799x_i2c_write8(st, AD7998_CONF_REG, +
>>>> st->config | (mask << AD799X_CHANNEL_SHIFT)); } + +static int
>>>> ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned +mask) { +
>>>> return ad799x_i2c_write16(st, AD7998_CONF_REG, + st->config | (mask
>>>> << AD799X_CHANNEL_SHIFT)); } + +int ad799x_set_scan_mode(struct
>>>> ad799x_state *st, unsigned mask) { + int ret; + +    if
>>>> (st->chip_info->ad799x_set_scan_mode != NULL) { +            ret =
>>>> st->chip_info->ad799x_set_scan_mode(st, mask); +             return
>>>> (ret > 0) ? 0 : ret; +     } + +   return 0; +} + +static ssize_t
>>>> ad799x_read_single_channel(struct device *dev, + struct
>>>> device_attribute *attr, +                               char *buf) +{
>>>> +      struct iio_dev *dev_info = dev_get_drvdata(dev); +  struct
>>>> ad799x_state *st = iio_dev_get_devdata(dev_info); +     struct
>>>> iio_dev_attr *this_attr = to_iio_dev_attr(attr); +     int ret = 0,
>>>> len = 0; + u32 data ; + u16 rxbuf[1]; +  u8 cmd; +       long mask; +
>>>> +  mutex_lock(&dev_info- mlock); +    mask = 1 << this_attr->address;
>>>> +       /* If ring buffer capture is occuring, query the buffer */ +
>>>>     if (iio_ring_enabled(dev_info)) { +            data =
>>>> ad799x_single_channel_from_ring(st, mask); + if (data < 0) { +
>>>>             ret = data; +                   goto
> error_ret; +               } +     } else { +              switch (st-
>> id)
>>>> { +          case ad7991: +          case ad7995: +          case
>>>> ad7999: +                  cmd = st->config | (mask <<
>>>> AD799X_CHANNEL_SHIFT); +                  break; + case ad7992: +
>>>>      case ad7993: +            case ad7994: +                  cmd =
>>>> mask << AD799X_CHANNEL_SHIFT; +                    break; +
>>>>      case ad7997: + case ad7998: +                  cmd =
>>>> (this_attr->address << + AD799X_CHANNEL_SHIFT) |
>>>> AD7997_8_READ_SINGLE; +                      break; +
> default: +                      cmd = 0; + +            } +
> ret
>>>> = ad799x_i2c_read16(st, cmd, rxbuf); +               if (ret < 0) +
>>>> goto error_ret; + +               data = rxbuf[0] & 0xFFF; +      } +
>>>> + /* Pretty print the result */ +  len = sprintf(buf, "%u\n", data);
>>>> + +error_ret: +    mutex_unlock(&dev_info->mlock); +       return ret
>>>> ? ret : len; +} + +static ssize_t ad799x_read_frequency(struct device
>>>> *dev, + struct device_attribute *attr, +
>>>>       char *buf) +{ + struct iio_dev *dev_info =
>>>> dev_get_drvdata(dev); +    struct ad799x_state *st =
>>>> iio_dev_get_devdata(dev_info); + +   int ret, len = 0; +     u8 val;
>>>> +       ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &val); +  if
>>>> (ret) + return ret; + +     val &= AD7998_CYC_MASK; + +     switch
>>>> (val) { + case AD7998_CYC_DIS: +            len = sprintf(buf,
>>>> "0\n"); + break; +        case AD7998_CYC_TCONF_32: +
>>>> len = sprintf(buf, "15625\n"); +                break; +        case
>>>> AD7998_CYC_TCONF_64: +               len = sprintf(buf, "7812\n"); +
>>>>        break; +        case AD7998_CYC_TCONF_128: +              len
>>>> = sprintf(buf, "3906\n"); +         break; +        case
>>>> AD7998_CYC_TCONF_256: +              len = sprintf(buf, "1953\n"); +
>>>>        break; +        case AD7998_CYC_TCONF_512: +              len
>>>> = sprintf(buf, "976\n"); + break; +        case
>>>> AD7998_CYC_TCONF_1024: +             len = sprintf(buf, "488\n"); +
>>>> break; +        case AD7998_CYC_TCONF_2048: +             len =
>>>> sprintf(buf, "244\n"); + break; +        } +    return len; +} +
>>>> +static ssize_t ad799x_write_frequency(struct device *dev, +
>>>>                              struct
> device_attribute *attr, +                                        const
> char *buf,
>>>> +                                     size_t len) +{ +       struct
>>>> iio_dev *dev_info = dev_get_drvdata(dev); +      struct ad799x_state
>>>> *st = iio_dev_get_devdata(dev_info); + +   long val; +     int ret; +
>>>> u8 t; + +       ret = strict_strtol(buf, 10, &val); +    if (ret) +
>>>>            return ret; + +    mutex_lock(&dev_info->mlock); + ret =
>>>> ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &t); + if (ret) +
>>>>     goto error_ret_mutex; + /* Wipe the bits clean */ +     t &=
>>>> ~AD7998_CYC_MASK; + +      switch (val) { +    case 15625: +
>>>>  t |= AD7998_CYC_TCONF_32; + break; +        case 7812: +
>>>> t |= AD7998_CYC_TCONF_64; +            break; +        case 3906: + t
>>>> |= AD7998_CYC_TCONF_128; +              break; +        case 1953: +
>>>> t |= AD7998_CYC_TCONF_256; +              break; +        case 976: +
>>>> t |= AD7998_CYC_TCONF_512; +              break; +        case 488: +
>>>> t |= AD7998_CYC_TCONF_1024; +             break; +        case 244: +
>>>> t |= AD7998_CYC_TCONF_2048; +             break; +        case  0: +
>>>> t |= AD7998_CYC_DIS; +            break; +        default: +
>>>>     ret = -EINVAL; +                goto error_ret_mutex; + } + +
>>>> ret = ad799x_i2c_write8(st, AD7998_CYCLE_TMR_REG, t); +
>>>> +error_ret_mutex: +  mutex_unlock(&dev_info->mlock); + +     return
>>>> ret ? ret : len; +} + + +static ssize_t
>>>> ad799x_read_channel_config(struct device *dev, +
>>>>                  struct
> device_attribute *attr, +                                        char
> *buf) +{
>>>> +    struct iio_dev *dev_info = dev_get_drvdata(dev); +      struct
>>>> ad799x_state *st = iio_dev_get_devdata(dev_info); +  struct
>>>> iio_event_attr *this_attr = to_iio_event_attr(attr); + +     int ret;
>>>> +      u16 val; +       ret = ad799x_i2c_read16(st, this_attr->mask,
>>>> &val); + if (ret) +            return ret; + + return sprintf(buf,
>>>> "%d\n", val); +} + +static ssize_t ad799x_write_channel_config(struct
>>>> device *dev, + struct device_attribute *attr, +
>>>>               const char *buf, +
>>>> size_t len) +{ +    struct iio_dev *dev_info = dev_get_drvdata(dev);
>>>> +      struct ad799x_state *st = iio_dev_get_devdata(dev_info); +
>>>> struct iio_event_attr *this_attr = to_iio_event_attr(attr); + +
>>>> long val; +    int ret; + +    ret = strict_strtol(buf, 10, &val); +
>>>>  if (ret) +              return ret; + +
>>>> mutex_lock(&dev_info->mlock); + ret = ad799x_i2c_write16(st,
>>>> this_attr->mask, val); +     mutex_unlock(&dev_info->mlock); + +
>>>> return ret ? ret : len; +} + +static void ad799x_interrupt_bh(struct
>>>> work_struct *work_s) { + struct ad799x_state *st =
>>>> container_of(work_s, + struct ad799x_state, work_thresh); +        u8
>>>> status; +    int i; + + if (ad799x_i2c_read8(st,
>>>> AD7998_ALERT_STAT_REG, &status)) + goto err_out; + +  if (!status) +
>>>>         goto err_out; + + ad799x_i2c_write8(st,
>>>> AD7998_ALERT_STAT_REG, +AD7998_ALERT_STAT_CLEAR); + +        for (i =
>>>> 0; i < 8; i++) { +          if (status & (1 << i)) +
>>>> iio_push_event(st->indio_dev, 0, +                         i & 0x1 ?
>>>> + IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) : +
>>>>  IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1), +
>>>> st->last_timestamp); +    } + +err_out: +
>>>> enable_irq(st->client->irq); +} + +static int ad799x_interrupt(struct
>>>> iio_dev *dev_info, +         int index, + s64 timestamp, +
>>>> int no_test) +{ +       struct ad799x_state *st = dev_info->dev_data;
>>>> + +      st->last_timestamp = timestamp; +
>>>> schedule_work(&st->work_thresh); +      return 0; +} +
>>>> +IIO_EVENT_SH(ad799x, &ad799x_interrupt); + +/* Direct read
>>>> attribtues */ +static IIO_DEV_ATTR_IN_RAW(0,
>>>> ad799x_read_single_channel, 0); +static IIO_DEV_ATTR_IN_RAW(1,
>>>> ad799x_read_single_channel, 1); +static IIO_DEV_ATTR_IN_RAW(2,
>>>> ad799x_read_single_channel, 2); +static IIO_DEV_ATTR_IN_RAW(3,
>>>> ad799x_read_single_channel, 3); +static IIO_DEV_ATTR_IN_RAW(4,
>>>> ad799x_read_single_channel, 4); +static IIO_DEV_ATTR_IN_RAW(5,
>>>> ad799x_read_single_channel, 5); +static IIO_DEV_ATTR_IN_RAW(6,
>>>> ad799x_read_single_channel, 6); +static IIO_DEV_ATTR_IN_RAW(7,
>>>> ad799x_read_single_channel, 7); + +static ssize_t
>>>> ad799x_show_scale(struct device *dev, + struct device_attribute
>>>> *attr, +                            char *buf) +{ + /* Driver
>>>> currently only support internal vref */ +   struct iio_dev *dev_info
>>>> = dev_get_drvdata(dev); +      struct ad799x_state *st =
>>>> iio_dev_get_devdata(dev_info); +     /* Corresponds to Vref /
>>>> 2^(bits) */ + +    if ((1 << (st->chip_info->bits + 1)) +      >
>>>> st->int_vref_mv) +            return sprintf(buf, "0.5\n"); + else +
>>>>         return sprintf(buf, "%d\n", +
>>>> st->int_vref_mv >> st->chip_info->bits); } + +static
>>>> IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, +0); +
>>>> +static ssize_t ad799x_show_name(struct device *dev, + struct
>>>> device_attribute *attr, +                             char *buf) +{ +
>>>>        struct iio_dev *dev_info = dev_get_drvdata(dev); +    struct
>>>> ad799x_state *st = iio_dev_get_devdata(dev_info); +     return
>>>> sprintf(buf, "%s\n", st->client->name); } + +static
>>>> IIO_DEVICE_ATTR(name, S_IRUGO, ad799x_show_name, NULL, 0); + +static
>>>> struct attribute *ad7991_5_9_3_4_device_attrs[] = { +
>>>> &iio_dev_attr_in0_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in1_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in2_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in3_raw.dev_attr.attr, +
>>>> &iio_dev_attr_name.dev_attr.attr, +
>>>> &iio_dev_attr_in_scale.dev_attr.attr, + NULL +}; + +static struct
>>>> attribute_group ad7991_5_9_3_4_dev_attr_group = { +  .attrs =
>>>> ad7991_5_9_3_4_device_attrs, }; + +static struct attribute
>>>> *ad7991_5_9_3_4_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr,
>>>> +    &iio_const_attr_in0_index.dev_attr.attr, +
>>>> &iio_scan_el_in1.dev_attr.attr, +
>>>> &iio_const_attr_in1_index.dev_attr.attr, +
>>>> &iio_scan_el_in2.dev_attr.attr, +
>>>> &iio_const_attr_in2_index.dev_attr.attr, +
>>>> &iio_scan_el_in3.dev_attr.attr, +
>>>> &iio_const_attr_in3_index.dev_attr.attr,
>>> The precision attribute has been replaced by the _type attributes in
>>> the scan_elements directory as they give all the information in one
>>> consice form.  Lets do that change as an additional patch post merge
>>> though.
>>>
>>>> +    &iio_dev_attr_in_precision.dev_attr.attr, +    NULL, +}; +
>>>> +static struct attribute_group ad7991_5_9_3_4_scan_el_group = { +
>>>> .name = "scan_elements", +    .attrs = ad7991_5_9_3_4_scan_el_attrs,
>>>> }; + +static struct attribute *ad7992_device_attrs[] = { +
>>>> &iio_dev_attr_in0_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in1_raw.dev_attr.attr, +
>>>> &iio_dev_attr_name.dev_attr.attr, +
>>>> &iio_dev_attr_in_scale.dev_attr.attr, +    NULL +}; + +static struct
>>>> attribute_group ad7992_dev_attr_group = { +    .attrs =
>>>> ad7992_device_attrs, +}; + +static struct attribute
>>>> *ad7992_scan_el_attrs[] = { +    &iio_scan_el_in0.dev_attr.attr, +
>>>> &iio_const_attr_in0_index.dev_attr.attr, +
>>>> &iio_scan_el_in1.dev_attr.attr, +
>>>> &iio_const_attr_in1_index.dev_attr.attr, +
>>>> &iio_dev_attr_in_precision.dev_attr.attr, +    NULL, +}; + +static
>>>> struct attribute_group ad7992_scan_el_group = { +    .name =
>>>> "scan_elements", +    .attrs = ad7992_scan_el_attrs, +}; + +static
>>>> struct attribute *ad7997_8_device_attrs[] = { +
>>>> &iio_dev_attr_in0_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in1_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in2_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in3_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in4_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in5_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in6_raw.dev_attr.attr, +
>>>> &iio_dev_attr_in7_raw.dev_attr.attr, +
>>>> &iio_dev_attr_name.dev_attr.attr, +
>>>> &iio_dev_attr_in_scale.dev_attr.attr, +    NULL +}; + +static struct
>>>> attribute_group ad7997_8_dev_attr_group = { +    .attrs =
>>>> ad7997_8_device_attrs, +}; + +static struct attribute
>>>> *ad7997_8_scan_el_attrs[] = { +    &iio_scan_el_in0.dev_attr.attr, +
>>>>   &iio_const_attr_in0_index.dev_attr.attr, +
>>>> &iio_scan_el_in1.dev_attr.attr, +
>>>> &iio_const_attr_in1_index.dev_attr.attr, +
>>>> &iio_scan_el_in2.dev_attr.attr, +
>>>> &iio_const_attr_in2_index.dev_attr.attr, +
>>>> &iio_scan_el_in3.dev_attr.attr, +
>>>> &iio_const_attr_in3_index.dev_attr.attr, +
>>>> &iio_scan_el_in4.dev_attr.attr, +
>>>> &iio_const_attr_in4_index.dev_attr.attr, +
>>>> &iio_scan_el_in5.dev_attr.attr, +
>>>> &iio_const_attr_in5_index.dev_attr.attr, +
>>>> &iio_scan_el_in6.dev_attr.attr, +
>>>> &iio_const_attr_in6_index.dev_attr.attr, +
>>>> &iio_scan_el_in7.dev_attr.attr, +
>>>> &iio_const_attr_in7_index.dev_attr.attr, +
>>>> &iio_dev_attr_in_precision.dev_attr.attr, +    NULL, +}; + +static
>>>> struct attribute_group ad7997_8_scan_el_group = { +    .name =
>>>> "scan_elements", +    .attrs = ad7997_8_scan_el_attrs, +}; +
>>>> +IIO_EVENT_ATTR_SH(in0_thresh_low_value, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_DATALOW_CH1_REG); + +IIO_EVENT_ATTR_SH(in0_thresh_high_value,
>>>> +              iio_event_ad799x, +
>>>> ad799x_read_channel_config, +
>>>> ad799x_write_channel_config, +              AD7998_DATAHIGH_CH1_REG);
>>>> + +IIO_EVENT_ATTR_SH(in0_thresh_both_hyst_raw, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_HYST_CH1_REG); + +IIO_EVENT_ATTR_SH(in1_thresh_low_value, +
>>>>           iio_event_ad799x, +
>>>> ad799x_read_channel_config, +
>>>> ad799x_write_channel_config, +              AD7998_DATALOW_CH2_REG);
>>>> + +IIO_EVENT_ATTR_SH(in1_thresh_high_value, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_DATAHIGH_CH2_REG); +
>>>> +IIO_EVENT_ATTR_SH(in1_thresh_both_hyst_raw, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_HYST_CH2_REG); + +IIO_EVENT_ATTR_SH(in2_thresh_low_value, +
>>>>           iio_event_ad799x, +
>>>> ad799x_read_channel_config, +
>>>> ad799x_write_channel_config, +              AD7998_DATALOW_CH3_REG);
>>>> + +IIO_EVENT_ATTR_SH(in2_thresh_high_value, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_DATAHIGH_CH3_REG); +
>>>> +IIO_EVENT_ATTR_SH(in2_thresh_both_hyst_raw, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_HYST_CH3_REG); + +IIO_EVENT_ATTR_SH(in3_thresh_low_value, +
>>>>           iio_event_ad799x, +
>>>> ad799x_read_channel_config, +
>>>> ad799x_write_channel_config, +              AD7998_DATALOW_CH4_REG);
>>>> + +IIO_EVENT_ATTR_SH(in3_thresh_high_value, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_DATAHIGH_CH4_REG); +
>>>> +IIO_EVENT_ATTR_SH(in3_thresh_both_hyst_raw, +
>>>> iio_event_ad799x, +              ad799x_read_channel_config, +
>>>>       ad799x_write_channel_config, +
>>>> AD7998_HYST_CH4_REG); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR |
>>>> S_IRUGO, +                          ad799x_read_frequency, +
>>>>                 ad799x_write_frequency); +static
>>>> IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 +244
>>>> 0"); + +static struct attribute *ad7993_4_7_8_event_attributes[] = {
>>>> +    &iio_event_attr_in0_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in0_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_event_attr_in2_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in2_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in2_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_event_attr_in3_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in3_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in3_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_dev_attr_sampling_frequency.dev_attr.attr, +
>>>> &iio_const_attr_sampling_frequency_available.dev_attr.attr, +
>>>> NULL, +}; + +static struct attribute_group
>>>> ad7993_4_7_8_event_attrs_group = { +    .attrs =
>>>> ad7993_4_7_8_event_attributes, }; + +static struct attribute
>>>> *ad7992_event_attributes[] = { +
>>>> &iio_event_attr_in0_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in0_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_low_value.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_high_value.dev_attr.attr, +
>>>> &iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr, +
>>>> &iio_dev_attr_sampling_frequency.dev_attr.attr, +
>>>> &iio_const_attr_sampling_frequency_available.dev_attr.attr, +
>>>> NULL, +}; + +static struct attribute_group ad7992_event_attrs_group =
>>>> { +    .attrs = ad7992_event_attributes, +}; + +static const struct
>>>> ad799x_chip_info ad799x_chip_info_tbl[] = { +    [ad7991] = { +
>>>>      .num_inputs = 4, +            .bits = 12, +
>>>> .int_vref_mv = 4096, +            .dev_attrs =
>>>> &ad7991_5_9_3_4_dev_attr_group, +            .scan_attrs =
>>>> &ad7991_5_9_3_4_scan_el_group, +            .ad799x_set_scan_mode =
>>>> ad7991_5_9_set_scan_mode, +    }, +    [ad7995] = { +
>>>> .num_inputs = 4, +            .bits = 10, +            .int_vref_mv =
>>>> 1024, +            .dev_attrs = &ad7991_5_9_3_4_dev_attr_group, +
>>>>        .scan_attrs = &ad7991_5_9_3_4_scan_el_group, +
>>>> .ad799x_set_scan_mode = ad7991_5_9_set_scan_mode, +    }, +
>>>> [ad7999] = { +            .num_inputs = 4, +            .bits = 10, +
>>>>            .int_vref_mv = 1024, +            .dev_attrs =
>>>> &ad7991_5_9_3_4_dev_attr_group, +            .scan_attrs =
>>>> &ad7991_5_9_3_4_scan_el_group, +            .ad799x_set_scan_mode =
>>>> ad7991_5_9_set_scan_mode, +    }, +    [ad7992] = { +
>>>> .num_inputs = 2, +            .bits = 12, +            .int_vref_mv =
>>>> 4096, +            .monitor_mode = true, +            .default_config
>>>> = AD7998_ALERT_EN, +            .dev_attrs = &ad7992_dev_attr_group,
>>>> +            .scan_attrs = &ad7992_scan_el_group, +
>>>> .event_attrs = &ad7992_event_attrs_group, +
>>>> .ad799x_set_scan_mode = ad7992_3_4_set_scan_mode, +    }, +
>>>> [ad7993] = { +            .num_inputs = 4, +            .bits = 10, +
>>>>            .int_vref_mv = 1024, +            .monitor_mode = true, +
>>>>           .default_config = AD7998_ALERT_EN, +            .dev_attrs
>>>> = &ad7991_5_9_3_4_dev_attr_group, +            .scan_attrs =
>>>> &ad7991_5_9_3_4_scan_el_group, +            .event_attrs =
>>>> &ad7993_4_7_8_event_attrs_group, +            .ad799x_set_scan_mode =
>>>> ad7992_3_4_set_scan_mode, +    }, +    [ad7994] = { +
>>>> .num_inputs = 4, +            .bits = 12, +            .int_vref_mv =
>>>> 4096, +            .monitor_mode = true, +            .default_config
>>>> = AD7998_ALERT_EN, +            .dev_attrs =
>>>> &ad7991_5_9_3_4_dev_attr_group, +            .scan_attrs =
>>>> &ad7991_5_9_3_4_scan_el_group, +            .event_attrs =
>>>> &ad7993_4_7_8_event_attrs_group, +            .ad799x_set_scan_mode =
>>>> ad7992_3_4_set_scan_mode, +    }, +    [ad7997] = { +
>>>> .num_inputs = 8, +            .bits = 10, +            .int_vref_mv =
>>>> 1024, +            .monitor_mode = true, +            .default_config
>>>> = AD7998_ALERT_EN, +            .dev_attrs =
>>>> &ad7997_8_dev_attr_group, +            .scan_attrs =
>>>> &ad7997_8_scan_el_group, +            .event_attrs =
>>>> &ad7993_4_7_8_event_attrs_group, +            .ad799x_set_scan_mode =
>>>> ad7997_8_set_scan_mode, +    }, +    [ad7998] = { +
>>>> .num_inputs = 8, +            .bits = 12, +            .int_vref_mv =
>>>> 4096, +            .monitor_mode = true, +            .default_config
>>>> = AD7998_ALERT_EN, +            .dev_attrs =
>>>> &ad7997_8_dev_attr_group, +            .scan_attrs =
>>>> &ad7997_8_scan_el_group, +            .event_attrs =
>>>> &ad7993_4_7_8_event_attrs_group, +            .ad799x_set_scan_mode =
>>>> ad7997_8_set_scan_mode, +    }, +}; + +static int __devinit
>>>> ad799x_probe(struct i2c_client *client, +
>>>>   const struct i2c_device_id *id) { +    int ret, regdone = 0; +
>>>> struct ad799x_platform_data *pdata = client- dev.platform_data; +
>>>> struct ad799x_state *st = kzalloc(sizeof(*st), GFP_KERNEL); +    if
>>>> (st == NULL) { +            ret = -ENOMEM; +            goto
>>>> error_ret; +    } + +    /* this is only used for device removal
>>>> purposes */ +    i2c_set_clientdata(client, st); + +
>>>> atomic_set(&st->protect_ring, 0); +    st->id = id->driver_data; +
>>>> st->chip_info = &ad799x_chip_info_tbl[st->id]; +    st->config =
>>>> st->chip_info->default_config; + +    /* TODO: Add pdata options for
>>>> filtering and bit delay */
>>> We also need to add userspace attributes to cover filtering for these
>>> devices.  However, that is definitely a discussion for another day!
>>>> + +  if (pdata) +            st->int_vref_mv = pdata->vref_mv; + else
>>>> +            st->int_vref_mv = st->chip_info->int_vref_mv; + +
>>>> st->reg = regulator_get(&client->dev, "vcc"); +        if
>>>> (!IS_ERR(st->reg)) { +               ret = regulator_enable(st->reg);
>>>> +         if (ret) + goto error_put_reg; +   } +    st->client =
>>>> client; + +        st->indio_dev = iio_allocate_device(); +        if
>>>> (st->indio_dev == NULL) { +          ret = -ENOMEM; + goto
>>>> error_disable_reg; +    } + +   /* Estabilish that the iio_dev is a
>>>> child of the i2c device */ +    st->indio_dev->dev.parent =
>>>> &client->dev; +     st->indio_dev- attrs = st->chip_info->dev_attrs;
>>>> +  st->indio_dev->event_attrs = st->chip_info->event_attrs; + +
>>>> st->indio_dev->dev_data = (void *)(st); +
>>>> st->indio_dev->driver_module = THIS_MODULE; +   st->indio_dev- modes
>>>> = INDIO_DIRECT_MODE; + st->indio_dev->num_interrupt_lines = 1; + +
>>>> ret = ad799x_set_scan_mode(st, 0); +       if (ret) +
>>>> goto error_free_device; + +    ret =
>>>> ad799x_register_ring_funcs_and_init(st->indio_dev); + if (ret) +
>>>>       goto error_free_device; + +     ret =
>>>> iio_device_register(st->indio_dev); +        if (ret) + goto
>>>> error_cleanup_ring; +        regdone = 1; + +        ret =
>>>> iio_ring_buffer_register(st->indio_dev->ring, 0); +  if (ret) + goto
>>>> error_cleanup_ring; + +      if (client->irq > 0 &&
>>>> st->chip_info->monitor_mode) { +             INIT_WORK(&st-
>>>> work_thresh, ad799x_interrupt_bh); + +            ret =
>>>> iio_register_interrupt_line(client->irq, + st->indio_dev, +
>>>>                      0, +
>>>> IRQF_TRIGGER_FALLING, + client->name); +                if (ret) +
>>>>                   goto error_cleanup_ring; + +              /* +
>>>>        * The event handler list element refer to iio_event_ad799x. +
>>>>               * All event attributes bind to the same event handler.
>>>> +            * So, only register event handler once. + */ +
>>>>  iio_add_event_to_list(&iio_event_ad799x, +
>>>>  &st->indio_dev->interrupts[0]- ev_list); +      } + +   return 0;
>>>> +error_cleanup_ring: +       ad799x_ring_cleanup(st->indio_dev);
>>>> +error_free_device: +        if (!regdone) +
>>>> iio_free_device(st->indio_dev); +    else +
>>>> iio_device_unregister(st->indio_dev); +error_disable_reg: +    if
>>>> (!IS_ERR(st->reg)) +         regulator_disable(st->reg);
>>>> +error_put_reg: +    if (!IS_ERR(st->reg)) +
>>>> regulator_put(st->reg); + kfree(st); +error_ret: +        return ret;
>>>> +} + +static __devexit int ad799x_remove(struct i2c_client *client) {
>>>> + struct ad799x_state *st = i2c_get_clientdata(client); +
>>>> struct iio_dev *indio_dev = st->indio_dev; + +   if (client->irq > 0
>>>> && st->chip_info- monitor_mode) +
>>>> iio_unregister_interrupt_line(indio_dev, 0); + +
>>>> iio_ring_buffer_unregister(indio_dev->ring); +
>>>> ad799x_ring_cleanup(indio_dev); + iio_device_unregister(indio_dev); +
>>>>    if (!IS_ERR(st->reg)) { +               regulator_disable(st-
>>>> reg); +            regulator_put(st->reg); +       } +     kfree(st);
>>>> + + return 0; +} + +static const struct i2c_device_id ad799x_id[] = {
>>>> + { "ad7991", ad7991 }, + { "ad7995", ad7995 }, +        { "ad7999",
>>>> ad7999 }, + { "ad7992", ad7992 }, + { "ad7993", ad7993 }, +        {
>>>> "ad7994", ad7994 }, + { "ad7997", ad7997 }, + { "ad7998", ad7998 }, +
>>>>        {} +}; + +MODULE_DEVICE_TABLE(i2c, ad799x_id); + +static
>>>> struct i2c_driver ad799x_driver = { +        .driver = { + .name =
>>>> "ad799x", +  }, +    .probe = ad799x_probe, +        .remove =
>>>> __devexit_p(ad799x_remove), +        .id_table = ad799x_id, +}; +
>>>> +static __init int ad799x_init(void) { +     return
>>>> i2c_add_driver(&ad799x_driver); } + +static __exit void
>>>> ad799x_exit(void) { +    i2c_del_driver(&ad799x_driver); +} +
>>>> +MODULE_AUTHOR("Michael Hennerich
>>>> +<hennerich@xxxxxxxxxxxxxxxxxxxx>"); +MODULE_DESCRIPTION("Analog
>>>> Devices AD799x ADC"); +MODULE_LICENSE("GPL v2");
>>>> MODULE_ALIAS("i2c:ad799x"); + +module_init(ad799x_init);
>>>> +module_exit(ad799x_exit); diff --git
>>>> a/drivers/staging/iio/adc/ad799x_ring.c
>>>> b/drivers/staging/iio/adc/ad799x_ring.c new file mode 100644 index
>>>> 0000000..0f2041a --- /dev/null +++
>>>> b/drivers/staging/iio/adc/ad799x_ring.c @@ -0,0 +1,246 @@ +/* + *
>>>> Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + *
>>>> Copyright (C) 2008-2010 Jonathan Cameron + * + * This program is free
>>>> software; you can redistribute it and/or +modify + * it under the
>>>> terms of the GNU General Public License version 2 +as + * published
>>>> by the Free Software Foundation. + * + * ad799x_ring.c + */ +
>>>> +#include <linux/interrupt.h> +#include <linux/workqueue.h> +#include
>>>> <linux/device.h> +#include <linux/slab.h> +#include <linux/kernel.h>
>>>> +#include <linux/sysfs.h> +#include <linux/list.h> +#include
>>>> <linux/i2c.h> +#include <linux/bitops.h> + +#include "../iio.h"
>>>> +#include "../ring_generic.h" +#include "../ring_sw.h" +#include
>>>> "../trigger.h" +#include "../sysfs.h" + +#include "ad799x.h" + +int
>>>> ad799x_single_channel_from_ring(struct ad799x_state *st, long +mask)
>>>> { +    unsigned long numvals; +        int count = 0, ret; +   u16
>>>> *ring_data; +       if (!(st->indio_dev->ring->scan_mask & mask)) { +
>>>>               ret = -EBUSY; +         goto error_ret; + } +
>>>> numvals = st->indio_dev->ring->scan_count; + +    ring_data =
>>>> kmalloc(numvals*2, GFP_KERNEL); +   if (ring_data == NULL) { +
>>>>   ret = -ENOMEM; +                goto error_ret; + } +     ret =
>>>> st->indio_dev->ring->access.read_last(st->indio_dev->ring, + (u8 *)
>>>> ring_data); +     if (ret) +              goto error_free_ring_data;
>>>> +    /* Need a count of channels prior to this one */ +     mask >>=
>>>> 1; +   while (mask) { +            if (mask &
>>>> st->indio_dev->ring->scan_mask) + count++; +              mask >>= 1;
>>>> + } + +   ret = be16_to_cpu(ring_data[count]) & 0xFFF; +
>>>> +error_free_ring_data: +     kfree(ring_data); +error_ret: + return
>>>> ret; +} + +/** + * ad799x_ring_preenable() setup the parameters of
>>>> the ring before +enabling + * + * The complex nature of the setting
>>>> of the nuber of bytes per +datum is due + * to this driver currently
>>>> ensuring that the timestamp is stored +at an 8 + * byte boundary. +
>>>> **/ +static int ad799x_ring_preenable(struct iio_dev *indio_dev) { +
>>>> struct ad799x_state *st = indio_dev->dev_data; +    size_t d_size; +
>>>> unsigned long numvals; + +    /* +     * Need to figure out the
>>>> current mode based upon the requested +  * scan mask in iio_dev +
>>>>    */ + + if (st->id == ad7997 || st->id == ad7998) +
>>>> ad799x_set_scan_mode(st, st->indio_dev->ring->scan_mask); + + numvals
>>>> = st->indio_dev->ring->scan_count; + + if
>>>> (indio_dev->ring->access.set_bytes_per_datum) { +            d_size =
>>>> numvals*2 + 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); + } + +
>>>> return 0; +} + +/** + * ad799x_poll_func_th() th of trigger launched
>>>> polling to ring +buffer + * + * As sampling only occurs on i2c comms
>>>> occuring, leave +timestamping until + * then.  Some triggers will
>>>> generate their own time stamp. +Currently + * there is no way of
>>>> notifying them when no one cares. + **/ +static void
>>>> ad799x_poll_func_th(struct iio_dev *indio_dev, s64 +time) { +
>>>> struct ad799x_state *st = indio_dev->dev_data; + +
>>>> schedule_work(&st->poll_work); + + return; +} +/** + *
>>>> ad799x_poll_bh_to_ring() bh of trigger launched polling to ring
>>>> buffer + * @work_s:     the work struct through which this was
>>>> scheduled + * + * Currently there is no option in this driver to
>>>> disable the +saving of + * timestamps within the ring. + * I think
>>>> the one copy of this at a time was to avoid problems if +the + *
>>>> trigger was set far too high and the reads then locked up the
>>>> computer. + **/ +static void ad799x_poll_bh_to_ring(struct
>>>> work_struct *work_s) { +    struct ad799x_state *st =
>>>> container_of(work_s, struct ad799x_state, +
>>>>                    poll_work); + struct iio_dev *indio_dev =
>>>> st->indio_dev; +    struct iio_sw_ring_buffer *ring =
>>>> iio_to_sw_ring(indio_dev- ring); +    s64 time_ns; +  __u8 *rxbuf; +
>>>> int b_sent; +   size_t d_size; +        u8 cmd; + +  unsigned long
>>>> numvals = st->indio_dev->ring->scan_count; + + /* Ensure the
>>>> timestamp is 8 byte aligned */ +  d_size = numvals*2 + sizeof(s64); +
>>>> +     if (d_size % sizeof(s64)) +             d_size += sizeof(s64) -
>>>> (d_size % sizeof(s64)); + +  /* Ensure only one copy of this function
>>>> running at a time */ +       if (atomic_inc_return(&st- protect_ring)
>>>> > 1) +            return; + +     /* Monitor mode prevents reading.
>>>> Whilst not currently implemented +         * might as well have this
>>>> test in here in the meantime as it does +  * no harm. +    */ +   if
>>>> (numvals == 0) + return; + +     rxbuf = kmalloc(d_size,
>>>> GFP_KERNEL); +  if (rxbuf == NULL) + return; + +    switch (st->id) {
>>>> +     case ad7991: +  case ad7995: +  case ad7999: +          cmd =
>>>> st->config | (st->indio_dev->ring->scan_mask << +
>>>> AD799X_CHANNEL_SHIFT); +                break; +        case ad7992:
>>>> +  case ad7993: +    case ad7994: +          cmd =
>>>> (st->indio_dev->ring->scan_mask << +
>>>> AD799X_CHANNEL_SHIFT) | AD7998_CONV_RES_REG; + break; +        case
>>>> ad7997: +    case ad7998: +          cmd = AD7997_8_READ_SEQUENCE |
>>>> AD7998_CONV_RES_REG; +               break; +        default: + cmd =
>>>> 0; +      } + +   b_sent = i2c_smbus_read_i2c_block_data(st->client,
>>>> +                  cmd, numvals*2, rxbuf); +    if (b_sent < 0) +
>>>>           goto done; + +  time_ns = iio_get_time_ns(); + +
>>>> memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + +
>>>>   indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
>>>> +done: +    kfree(rxbuf); + atomic_dec(&st->protect_ring); +} + +
>>>> +int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) {
>>>> +    struct ad799x_state *st = indio_dev->dev_data; +        int ret
>>>> = 0; + +    indio_dev->ring = iio_sw_rb_allocate(indio_dev); +
>>>> if (!indio_dev->ring) { +               ret = -ENOMEM; + goto
>>>> error_ret; +       } +     /* Effectively select the ring buffer
>>>> implementation */ +
>>>> iio_ring_sw_register_funcs(&st->indio_dev->ring->access); +
>>>> indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc),
>>>> GFP_KERNEL); +       if (indio_dev->pollfunc == NULL) { + ret =
>>>> -ENOMEM; +            goto error_deallocate_sw_rb; +  } +     /*
>>>> Configure the polling function called on trigger interrupts */ +
>>>> indio_dev->pollfunc- poll_func_main = &ad799x_poll_func_th; +
>>>> indio_dev->pollfunc->private_data = indio_dev; + +  /* Ring buffer
>>>> functions - here trigger setup related */ + +
>>>> indio_dev->ring->preenable = &ad799x_ring_preenable; +
>>>> indio_dev->ring->postenable = &iio_triggered_ring_postenable; +
>>>> indio_dev->ring->predisable = &iio_triggered_ring_predisable; + +
>>>> INIT_WORK(&st->poll_work, &ad799x_poll_bh_to_ring); + +
>>>> indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs; + + /*
>>>> Flag that polled ring buffering is possible */ +     indio_dev- modes
>>>> |= INDIO_RING_TRIGGERED; +      return 0; +error_deallocate_sw_rb: +
>>>>   iio_sw_rb_free(indio_dev->ring); +error_ret: +  return ret; +} +
>>>> +void ad799x_ring_cleanup(struct iio_dev *indio_dev) { +   /* ensure
>>>> that the trigger has been detached */ +       if (indio_dev->trig) {
>>>> +            iio_put_trigger(indio_dev->trig); +
>>>> iio_trigger_dettach_poll_func(indio_dev->trig, +
>>>> indio_dev->pollfunc); +      } +     kfree(indio_dev->pollfunc); +
>>>> iio_sw_rb_free(indio_dev->ring); +}
>>
>> Greetings,
>> Michael
>>
>> Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
>> Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 4036
>> Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
>>
>>

Greetings,
Michael

Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 4036
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif


--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux