* [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector
@ 2015-08-20 19:37 Vladimir Barinov
2015-08-20 19:37 ` [PATCH v4 1/4] iio: Support triggered events Vladimir Barinov
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Vladimir Barinov @ 2015-08-20 19:37 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel,
linux-iio, devicetree, cory.tusar
Hello,
This adds the folowing:
- Support triggered events
- Add Holt vendor prefix
- Holt threshold detector driver for HI-8435 chip
- Document HI-8435 DT bindings
PDF file can be found here:
http://www.holtic.com/products/3081-hi-8435.aspx
Vladimir Barinov (4):
[1/4] iio: Support triggered events
[2/4] dt: Add vendor prefix 'holt'
[3/4] iio: adc: hi8435: Holt HI-8435 threshold detector
[4/4] dt: Document Holt HI-8435 bindings
---
This patchset is against the 'kernel/git/jic23/iio.git' repo, 'togreg' branch.
Documentation/ABI/testing/sysfs-bus-iio | 1
Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 | 39 +
Documentation/devicetree/bindings/iio/adc/hi8435.txt | 21
Documentation/devicetree/bindings/vendor-prefixes.txt | 1
drivers/iio/Kconfig | 6
drivers/iio/Makefile | 1
drivers/iio/adc/Kconfig | 11
drivers/iio/adc/Makefile | 1
drivers/iio/adc/hi8435.c | 535 ++++++++++++++++++
drivers/iio/industrialio-core.c | 4
drivers/iio/industrialio-trigger.c | 12
drivers/iio/industrialio-triggered-event.c | 68 ++
include/linux/iio/iio.h | 3
include/linux/iio/triggered_event.h | 11
14 files changed, 710 insertions(+), 4 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435
create mode 100644 Documentation/devicetree/bindings/iio/adc/hi8435.txt
create mode 100644 drivers/iio/adc/hi8435.c
create mode 100644 drivers/iio/industrialio-triggered-event.c
create mode 100644 include/linux/iio/triggered_event.h
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v4 1/4] iio: Support triggered events 2015-08-20 19:37 [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector Vladimir Barinov @ 2015-08-20 19:37 ` Vladimir Barinov 2015-08-20 19:43 ` Vladimir Barinov 2015-08-20 19:38 ` [PATCH v4 2/4] dt: Add vendor prefix 'holt' Vladimir Barinov ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Vladimir Barinov @ 2015-08-20 19:37 UTC (permalink / raw) To: Jonathan Cameron Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar Support triggered events. This is useful for chips that don't have their own interrupt sources. It allows to use generic/standalone iio triggers for those drivers. Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- Changes in version 2: - initially added Changes in version 3: - fixed grammar in patch description - changed license header to match "GNU Public License v2 or later" Changes in version 4: - added pollfunc_event to separate triggering buffer and event interfaces. This allows runnig both from the same trigger - removed 'currentmode' for triggered buffer since useless - renamed parameters of iio_triggered_event_setup drivers/iio/Kconfig | 6 +++ drivers/iio/Makefile | 1 + drivers/iio/industrialio-core.c | 4 +- drivers/iio/industrialio-trigger.c | 12 +++++- drivers/iio/industrialio-triggered-event.c | 68 ++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 3 ++ include/linux/iio/triggered_event.h | 11 +++++ 7 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 drivers/iio/industrialio-triggered-event.c create mode 100644 include/linux/iio/triggered_event.h diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 4011eff..8fcc92f 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -58,6 +58,12 @@ config IIO_CONSUMERS_PER_TRIGGER This value controls the maximum number of consumers that a given trigger may handle. Default is 2. +config IIO_TRIGGERED_EVENT + tristate + select IIO_TRIGGER + help + Provides helper functions for setting up triggered events. + source "drivers/iio/accel/Kconfig" source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 698afc2..40dc13e 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -9,6 +9,7 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o +obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += accel/ diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b3fcc2c..2c3b6a1 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -962,7 +962,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); @@ -1241,7 +1241,7 @@ int iio_device_register(struct iio_dev *indio_dev) "Failed to register event set\n"); goto error_free_sysfs; } - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) iio_device_register_trigger_consumer(indio_dev); if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 570606c..ae2806a 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -366,10 +366,18 @@ static ssize_t iio_trigger_write_current(struct device *dev, indio_dev->trig = trig; - if (oldtrig) + if (oldtrig) { + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) + iio_trigger_detach_poll_func(oldtrig, + indio_dev->pollfunc_event); iio_trigger_put(oldtrig); - if (indio_dev->trig) + } + if (indio_dev->trig) { iio_trigger_get(indio_dev->trig); + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) + iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc_event); + } return len; } diff --git a/drivers/iio/industrialio-triggered-event.c b/drivers/iio/industrialio-triggered-event.c new file mode 100644 index 0000000..8cc254f --- /dev/null +++ b/drivers/iio/industrialio-triggered-event.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/export.h> +#include <linux/module.h> +#include <linux/iio/iio.h> +#include <linux/iio/triggered_event.h> +#include <linux/iio/trigger_consumer.h> + +/** + * iio_triggered_event_setup() - Setup pollfunc_event for triggered event + * @indio_dev: IIO device structure + * @h: Function which will be used as pollfunc_event top half + * @thread: Function which will be used as pollfunc_event bottom half + * + * This function combines some common tasks which will normally be performed + * when setting up a triggered event. It will allocate the pollfunc_event and + * set mode to use it for triggered event. + * + * Before calling this function the indio_dev structure should already be + * completely initialized, but not yet registered. In practice this means that + * this function should be called right before iio_device_register(). + * + * To free the resources allocated by this function call + * iio_triggered_event_cleanup(). + */ +int iio_triggered_event_setup(struct iio_dev *indio_dev, + irqreturn_t (*h)(int irq, void *p), + irqreturn_t (*thread)(int irq, void *p)) +{ + indio_dev->pollfunc_event = iio_alloc_pollfunc(h, + thread, + IRQF_ONESHOT, + indio_dev, + "%s_consumer%d", + indio_dev->name, + indio_dev->id); + if (indio_dev->pollfunc_event == NULL) + return -ENOMEM; + + /* Flag that events polling is possible */ + indio_dev->modes |= INDIO_EVENT_TRIGGERED; + + return 0; +} +EXPORT_SYMBOL(iio_triggered_event_setup); + +/** + * iio_triggered_event_cleanup() - Free resources allocated by iio_triggered_event_setup() + * @indio_dev: IIO device structure + */ +void iio_triggered_event_cleanup(struct iio_dev *indio_dev) +{ + indio_dev->modes &= ~INDIO_EVENT_TRIGGERED; + iio_dealloc_pollfunc(indio_dev->pollfunc_event); +} +EXPORT_SYMBOL(iio_triggered_event_cleanup); + +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_DESCRIPTION("IIO helper functions for setting up triggered events"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 7bb7f67..19c94c9 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -294,6 +294,7 @@ static inline s64 iio_get_time_ns(void) #define INDIO_BUFFER_TRIGGERED 0x02 #define INDIO_BUFFER_SOFTWARE 0x04 #define INDIO_BUFFER_HARDWARE 0x08 +#define INDIO_EVENT_TRIGGERED 0x10 #define INDIO_ALL_BUFFER_MODES \ (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | INDIO_BUFFER_SOFTWARE) @@ -457,6 +458,7 @@ struct iio_buffer_setup_ops { * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) * @pollfunc: [DRIVER] function run on trigger being received + * @pollfunc_event: [DRIVER] function run on events trigger being received * @channels: [DRIVER] channel specification structure table * @num_channels: [DRIVER] number of channels specified in @channels. * @channel_attr_list: [INTERN] keep track of automatically created channel @@ -495,6 +497,7 @@ struct iio_dev { unsigned scan_index_timestamp; struct iio_trigger *trig; struct iio_poll_func *pollfunc; + struct iio_poll_func *pollfunc_event; struct iio_chan_spec const *channels; int num_channels; diff --git a/include/linux/iio/triggered_event.h b/include/linux/iio/triggered_event.h new file mode 100644 index 0000000..8fe8537 --- /dev/null +++ b/include/linux/iio/triggered_event.h @@ -0,0 +1,11 @@ +#ifndef _LINUX_IIO_TRIGGERED_EVENT_H_ +#define _LINUX_IIO_TRIGGERED_EVENT_H_ + +#include <linux/interrupt.h> + +int iio_triggered_event_setup(struct iio_dev *indio_dev, + irqreturn_t (*h)(int irq, void *p), + irqreturn_t (*thread)(int irq, void *p)); +void iio_triggered_event_cleanup(struct iio_dev *indio_dev); + +#endif -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/4] iio: Support triggered events 2015-08-20 19:37 ` [PATCH v4 1/4] iio: Support triggered events Vladimir Barinov @ 2015-08-20 19:43 ` Vladimir Barinov 2015-08-27 19:50 ` Jonathan Cameron 0 siblings, 1 reply; 11+ messages in thread From: Vladimir Barinov @ 2015-08-20 19:43 UTC (permalink / raw) To: Jonathan Cameron Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar Verified event and buffer polling works concurrently on the same trigger with hi-8435. The buffer interface part for hi-8435 was not sent. On 20.08.2015 22:37, Vladimir Barinov wrote: > Support triggered events. > > This is useful for chips that don't have their own interrupt sources. > It allows to use generic/standalone iio triggers for those drivers. > > Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> > --- > Changes in version 2: > - initially added > Changes in version 3: > - fixed grammar in patch description > - changed license header to match "GNU Public License v2 or later" > Changes in version 4: > - added pollfunc_event to separate triggering buffer and event > interfaces. This allows runnig both from the same trigger > - removed 'currentmode' for triggered buffer since useless > - renamed parameters of iio_triggered_event_setup > > drivers/iio/Kconfig | 6 +++ > drivers/iio/Makefile | 1 + > drivers/iio/industrialio-core.c | 4 +- > drivers/iio/industrialio-trigger.c | 12 +++++- > drivers/iio/industrialio-triggered-event.c | 68 ++++++++++++++++++++++++++++++ > include/linux/iio/iio.h | 3 ++ > include/linux/iio/triggered_event.h | 11 +++++ > 7 files changed, 101 insertions(+), 4 deletions(-) > create mode 100644 drivers/iio/industrialio-triggered-event.c > create mode 100644 include/linux/iio/triggered_event.h > > diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig > index 4011eff..8fcc92f 100644 > --- a/drivers/iio/Kconfig > +++ b/drivers/iio/Kconfig > @@ -58,6 +58,12 @@ config IIO_CONSUMERS_PER_TRIGGER > This value controls the maximum number of consumers that a > given trigger may handle. Default is 2. > > +config IIO_TRIGGERED_EVENT > + tristate > + select IIO_TRIGGER > + help > + Provides helper functions for setting up triggered events. > + > source "drivers/iio/accel/Kconfig" > source "drivers/iio/adc/Kconfig" > source "drivers/iio/amplifiers/Kconfig" > diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile > index 698afc2..40dc13e 100644 > --- a/drivers/iio/Makefile > +++ b/drivers/iio/Makefile > @@ -9,6 +9,7 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o > industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o > > obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o > +obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o > obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o > > obj-y += accel/ > diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c > index b3fcc2c..2c3b6a1 100644 > --- a/drivers/iio/industrialio-core.c > +++ b/drivers/iio/industrialio-core.c > @@ -962,7 +962,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) > static void iio_dev_release(struct device *device) > { > struct iio_dev *indio_dev = dev_to_iio_dev(device); > - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) > + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) > iio_device_unregister_trigger_consumer(indio_dev); > iio_device_unregister_eventset(indio_dev); > iio_device_unregister_sysfs(indio_dev); > @@ -1241,7 +1241,7 @@ int iio_device_register(struct iio_dev *indio_dev) > "Failed to register event set\n"); > goto error_free_sysfs; > } > - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) > + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) > iio_device_register_trigger_consumer(indio_dev); > > if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && > diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c > index 570606c..ae2806a 100644 > --- a/drivers/iio/industrialio-trigger.c > +++ b/drivers/iio/industrialio-trigger.c > @@ -366,10 +366,18 @@ static ssize_t iio_trigger_write_current(struct device *dev, > > indio_dev->trig = trig; > > - if (oldtrig) > + if (oldtrig) { > + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) > + iio_trigger_detach_poll_func(oldtrig, > + indio_dev->pollfunc_event); > iio_trigger_put(oldtrig); > - if (indio_dev->trig) > + } > + if (indio_dev->trig) { > iio_trigger_get(indio_dev->trig); > + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) > + iio_trigger_attach_poll_func(indio_dev->trig, > + indio_dev->pollfunc_event); > + } > > return len; > } > diff --git a/drivers/iio/industrialio-triggered-event.c b/drivers/iio/industrialio-triggered-event.c > new file mode 100644 > index 0000000..8cc254f > --- /dev/null > +++ b/drivers/iio/industrialio-triggered-event.c > @@ -0,0 +1,68 @@ > +/* > + * Copyright (C) 2015 Cogent Embedded, Inc. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + */ > + > +#include <linux/kernel.h> > +#include <linux/export.h> > +#include <linux/module.h> > +#include <linux/iio/iio.h> > +#include <linux/iio/triggered_event.h> > +#include <linux/iio/trigger_consumer.h> > + > +/** > + * iio_triggered_event_setup() - Setup pollfunc_event for triggered event > + * @indio_dev: IIO device structure > + * @h: Function which will be used as pollfunc_event top half > + * @thread: Function which will be used as pollfunc_event bottom half > + * > + * This function combines some common tasks which will normally be performed > + * when setting up a triggered event. It will allocate the pollfunc_event and > + * set mode to use it for triggered event. > + * > + * Before calling this function the indio_dev structure should already be > + * completely initialized, but not yet registered. In practice this means that > + * this function should be called right before iio_device_register(). > + * > + * To free the resources allocated by this function call > + * iio_triggered_event_cleanup(). > + */ > +int iio_triggered_event_setup(struct iio_dev *indio_dev, > + irqreturn_t (*h)(int irq, void *p), > + irqreturn_t (*thread)(int irq, void *p)) > +{ > + indio_dev->pollfunc_event = iio_alloc_pollfunc(h, > + thread, > + IRQF_ONESHOT, > + indio_dev, > + "%s_consumer%d", > + indio_dev->name, > + indio_dev->id); > + if (indio_dev->pollfunc_event == NULL) > + return -ENOMEM; > + > + /* Flag that events polling is possible */ > + indio_dev->modes |= INDIO_EVENT_TRIGGERED; > + > + return 0; > +} > +EXPORT_SYMBOL(iio_triggered_event_setup); > + > +/** > + * iio_triggered_event_cleanup() - Free resources allocated by iio_triggered_event_setup() > + * @indio_dev: IIO device structure > + */ > +void iio_triggered_event_cleanup(struct iio_dev *indio_dev) > +{ > + indio_dev->modes &= ~INDIO_EVENT_TRIGGERED; > + iio_dealloc_pollfunc(indio_dev->pollfunc_event); > +} > +EXPORT_SYMBOL(iio_triggered_event_cleanup); > + > +MODULE_AUTHOR("Vladimir Barinov"); > +MODULE_DESCRIPTION("IIO helper functions for setting up triggered events"); > +MODULE_LICENSE("GPL"); > diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h > index 7bb7f67..19c94c9 100644 > --- a/include/linux/iio/iio.h > +++ b/include/linux/iio/iio.h > @@ -294,6 +294,7 @@ static inline s64 iio_get_time_ns(void) > #define INDIO_BUFFER_TRIGGERED 0x02 > #define INDIO_BUFFER_SOFTWARE 0x04 > #define INDIO_BUFFER_HARDWARE 0x08 > +#define INDIO_EVENT_TRIGGERED 0x10 > > #define INDIO_ALL_BUFFER_MODES \ > (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | INDIO_BUFFER_SOFTWARE) > @@ -457,6 +458,7 @@ struct iio_buffer_setup_ops { > * @scan_index_timestamp:[INTERN] cache of the index to the timestamp > * @trig: [INTERN] current device trigger (buffer modes) > * @pollfunc: [DRIVER] function run on trigger being received > + * @pollfunc_event: [DRIVER] function run on events trigger being received > * @channels: [DRIVER] channel specification structure table > * @num_channels: [DRIVER] number of channels specified in @channels. > * @channel_attr_list: [INTERN] keep track of automatically created channel > @@ -495,6 +497,7 @@ struct iio_dev { > unsigned scan_index_timestamp; > struct iio_trigger *trig; > struct iio_poll_func *pollfunc; > + struct iio_poll_func *pollfunc_event; > > struct iio_chan_spec const *channels; > int num_channels; > diff --git a/include/linux/iio/triggered_event.h b/include/linux/iio/triggered_event.h > new file mode 100644 > index 0000000..8fe8537 > --- /dev/null > +++ b/include/linux/iio/triggered_event.h > @@ -0,0 +1,11 @@ > +#ifndef _LINUX_IIO_TRIGGERED_EVENT_H_ > +#define _LINUX_IIO_TRIGGERED_EVENT_H_ > + > +#include <linux/interrupt.h> > + > +int iio_triggered_event_setup(struct iio_dev *indio_dev, > + irqreturn_t (*h)(int irq, void *p), > + irqreturn_t (*thread)(int irq, void *p)); > +void iio_triggered_event_cleanup(struct iio_dev *indio_dev); > + > +#endif ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/4] iio: Support triggered events 2015-08-20 19:43 ` Vladimir Barinov @ 2015-08-27 19:50 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2015-08-27 19:50 UTC (permalink / raw) To: Vladimir Barinov Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar On 20/08/15 20:43, Vladimir Barinov wrote: > Verified event and buffer polling works concurrently on the same trigger with hi-8435. > The buffer interface part for hi-8435 was not sent. > > On 20.08.2015 22:37, Vladimir Barinov wrote: >> Support triggered events. >> >> This is useful for chips that don't have their own interrupt sources. >> It allows to use generic/standalone iio triggers for those drivers. >> >> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> Applied with a certain amount of fuzz (the buffers have moved out into their own directory). Jonathan >> --- >> Changes in version 2: >> - initially added >> Changes in version 3: >> - fixed grammar in patch description >> - changed license header to match "GNU Public License v2 or later" >> Changes in version 4: >> - added pollfunc_event to separate triggering buffer and event >> interfaces. This allows runnig both from the same trigger >> - removed 'currentmode' for triggered buffer since useless >> - renamed parameters of iio_triggered_event_setup >> >> drivers/iio/Kconfig | 6 +++ >> drivers/iio/Makefile | 1 + >> drivers/iio/industrialio-core.c | 4 +- >> drivers/iio/industrialio-trigger.c | 12 +++++- >> drivers/iio/industrialio-triggered-event.c | 68 ++++++++++++++++++++++++++++++ >> include/linux/iio/iio.h | 3 ++ >> include/linux/iio/triggered_event.h | 11 +++++ >> 7 files changed, 101 insertions(+), 4 deletions(-) >> create mode 100644 drivers/iio/industrialio-triggered-event.c >> create mode 100644 include/linux/iio/triggered_event.h >> >> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig >> index 4011eff..8fcc92f 100644 >> --- a/drivers/iio/Kconfig >> +++ b/drivers/iio/Kconfig >> @@ -58,6 +58,12 @@ config IIO_CONSUMERS_PER_TRIGGER >> This value controls the maximum number of consumers that a >> given trigger may handle. Default is 2. >> +config IIO_TRIGGERED_EVENT >> + tristate >> + select IIO_TRIGGER >> + help >> + Provides helper functions for setting up triggered events. >> + >> source "drivers/iio/accel/Kconfig" >> source "drivers/iio/adc/Kconfig" >> source "drivers/iio/amplifiers/Kconfig" >> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile >> index 698afc2..40dc13e 100644 >> --- a/drivers/iio/Makefile >> +++ b/drivers/iio/Makefile >> @@ -9,6 +9,7 @@ industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o >> industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o >> obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o >> +obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o >> obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o >> obj-y += accel/ >> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c >> index b3fcc2c..2c3b6a1 100644 >> --- a/drivers/iio/industrialio-core.c >> +++ b/drivers/iio/industrialio-core.c >> @@ -962,7 +962,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) >> static void iio_dev_release(struct device *device) >> { >> struct iio_dev *indio_dev = dev_to_iio_dev(device); >> - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) >> + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) >> iio_device_unregister_trigger_consumer(indio_dev); >> iio_device_unregister_eventset(indio_dev); >> iio_device_unregister_sysfs(indio_dev); >> @@ -1241,7 +1241,7 @@ int iio_device_register(struct iio_dev *indio_dev) >> "Failed to register event set\n"); >> goto error_free_sysfs; >> } >> - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) >> + if (indio_dev->modes & (INDIO_BUFFER_TRIGGERED | INDIO_EVENT_TRIGGERED)) >> iio_device_register_trigger_consumer(indio_dev); >> if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && >> diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c >> index 570606c..ae2806a 100644 >> --- a/drivers/iio/industrialio-trigger.c >> +++ b/drivers/iio/industrialio-trigger.c >> @@ -366,10 +366,18 @@ static ssize_t iio_trigger_write_current(struct device *dev, >> indio_dev->trig = trig; >> - if (oldtrig) >> + if (oldtrig) { >> + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) >> + iio_trigger_detach_poll_func(oldtrig, >> + indio_dev->pollfunc_event); >> iio_trigger_put(oldtrig); >> - if (indio_dev->trig) >> + } >> + if (indio_dev->trig) { >> iio_trigger_get(indio_dev->trig); >> + if (indio_dev->modes & INDIO_EVENT_TRIGGERED) >> + iio_trigger_attach_poll_func(indio_dev->trig, >> + indio_dev->pollfunc_event); >> + } >> return len; >> } >> diff --git a/drivers/iio/industrialio-triggered-event.c b/drivers/iio/industrialio-triggered-event.c >> new file mode 100644 >> index 0000000..8cc254f >> --- /dev/null >> +++ b/drivers/iio/industrialio-triggered-event.c >> @@ -0,0 +1,68 @@ >> +/* >> + * Copyright (C) 2015 Cogent Embedded, Inc. >> + * >> + * This program is free software; you can redistribute it and/or modify it >> + * under the terms of the GNU General Public License as published by the >> + * Free Software Foundation; either version 2 of the License, or (at your >> + * option) any later version. >> + */ >> + >> +#include <linux/kernel.h> >> +#include <linux/export.h> >> +#include <linux/module.h> >> +#include <linux/iio/iio.h> >> +#include <linux/iio/triggered_event.h> >> +#include <linux/iio/trigger_consumer.h> >> + >> +/** >> + * iio_triggered_event_setup() - Setup pollfunc_event for triggered event >> + * @indio_dev: IIO device structure >> + * @h: Function which will be used as pollfunc_event top half >> + * @thread: Function which will be used as pollfunc_event bottom half >> + * >> + * This function combines some common tasks which will normally be performed >> + * when setting up a triggered event. It will allocate the pollfunc_event and >> + * set mode to use it for triggered event. >> + * >> + * Before calling this function the indio_dev structure should already be >> + * completely initialized, but not yet registered. In practice this means that >> + * this function should be called right before iio_device_register(). >> + * >> + * To free the resources allocated by this function call >> + * iio_triggered_event_cleanup(). >> + */ >> +int iio_triggered_event_setup(struct iio_dev *indio_dev, >> + irqreturn_t (*h)(int irq, void *p), >> + irqreturn_t (*thread)(int irq, void *p)) >> +{ >> + indio_dev->pollfunc_event = iio_alloc_pollfunc(h, >> + thread, >> + IRQF_ONESHOT, >> + indio_dev, >> + "%s_consumer%d", >> + indio_dev->name, >> + indio_dev->id); >> + if (indio_dev->pollfunc_event == NULL) >> + return -ENOMEM; >> + >> + /* Flag that events polling is possible */ >> + indio_dev->modes |= INDIO_EVENT_TRIGGERED; >> + >> + return 0; >> +} >> +EXPORT_SYMBOL(iio_triggered_event_setup); >> + >> +/** >> + * iio_triggered_event_cleanup() - Free resources allocated by iio_triggered_event_setup() >> + * @indio_dev: IIO device structure >> + */ >> +void iio_triggered_event_cleanup(struct iio_dev *indio_dev) >> +{ >> + indio_dev->modes &= ~INDIO_EVENT_TRIGGERED; >> + iio_dealloc_pollfunc(indio_dev->pollfunc_event); >> +} >> +EXPORT_SYMBOL(iio_triggered_event_cleanup); >> + >> +MODULE_AUTHOR("Vladimir Barinov"); >> +MODULE_DESCRIPTION("IIO helper functions for setting up triggered events"); >> +MODULE_LICENSE("GPL"); >> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h >> index 7bb7f67..19c94c9 100644 >> --- a/include/linux/iio/iio.h >> +++ b/include/linux/iio/iio.h >> @@ -294,6 +294,7 @@ static inline s64 iio_get_time_ns(void) >> #define INDIO_BUFFER_TRIGGERED 0x02 >> #define INDIO_BUFFER_SOFTWARE 0x04 >> #define INDIO_BUFFER_HARDWARE 0x08 >> +#define INDIO_EVENT_TRIGGERED 0x10 >> #define INDIO_ALL_BUFFER_MODES \ >> (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | INDIO_BUFFER_SOFTWARE) >> @@ -457,6 +458,7 @@ struct iio_buffer_setup_ops { >> * @scan_index_timestamp:[INTERN] cache of the index to the timestamp >> * @trig: [INTERN] current device trigger (buffer modes) >> * @pollfunc: [DRIVER] function run on trigger being received >> + * @pollfunc_event: [DRIVER] function run on events trigger being received >> * @channels: [DRIVER] channel specification structure table >> * @num_channels: [DRIVER] number of channels specified in @channels. >> * @channel_attr_list: [INTERN] keep track of automatically created channel >> @@ -495,6 +497,7 @@ struct iio_dev { >> unsigned scan_index_timestamp; >> struct iio_trigger *trig; >> struct iio_poll_func *pollfunc; >> + struct iio_poll_func *pollfunc_event; >> struct iio_chan_spec const *channels; >> int num_channels; >> diff --git a/include/linux/iio/triggered_event.h b/include/linux/iio/triggered_event.h >> new file mode 100644 >> index 0000000..8fe8537 >> --- /dev/null >> +++ b/include/linux/iio/triggered_event.h >> @@ -0,0 +1,11 @@ >> +#ifndef _LINUX_IIO_TRIGGERED_EVENT_H_ >> +#define _LINUX_IIO_TRIGGERED_EVENT_H_ >> + >> +#include <linux/interrupt.h> >> + >> +int iio_triggered_event_setup(struct iio_dev *indio_dev, >> + irqreturn_t (*h)(int irq, void *p), >> + irqreturn_t (*thread)(int irq, void *p)); >> +void iio_triggered_event_cleanup(struct iio_dev *indio_dev); >> + >> +#endif > > -- > To unsubscribe from this list: send the line "unsubscribe linux-iio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 2/4] dt: Add vendor prefix 'holt' 2015-08-20 19:37 [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector Vladimir Barinov 2015-08-20 19:37 ` [PATCH v4 1/4] iio: Support triggered events Vladimir Barinov @ 2015-08-20 19:38 ` Vladimir Barinov 2015-08-23 22:32 ` Rob Herring 2015-08-20 19:38 ` [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector Vladimir Barinov 2015-08-20 19:38 ` [PATCH v4 4/4] dt: Document Holt HI-8435 bindings Vladimir Barinov 3 siblings, 1 reply; 11+ messages in thread From: Vladimir Barinov @ 2015-08-20 19:38 UTC (permalink / raw) To: Jonathan Cameron Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar Add Holt Integrated Circuits, Inc. to the list of device tree vendor prefixes Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- Changes in version 2: - none Changes in version 3: - none Changes in version 4: - none Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index d444757..bc64cc9 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -99,6 +99,7 @@ himax Himax Technologies, Inc. hisilicon Hisilicon Limited. hit Hitachi Ltd. hitex Hitex Development Tools +holt Holt Integrated Circuits, Inc. honeywell Honeywell hp Hewlett Packard i2se I2SE GmbH -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/4] dt: Add vendor prefix 'holt' 2015-08-20 19:38 ` [PATCH v4 2/4] dt: Add vendor prefix 'holt' Vladimir Barinov @ 2015-08-23 22:32 ` Rob Herring 2015-08-27 19:51 ` Jonathan Cameron 0 siblings, 1 reply; 11+ messages in thread From: Rob Herring @ 2015-08-23 22:32 UTC (permalink / raw) To: Vladimir Barinov Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, Cory Tusar On Thu, Aug 20, 2015 at 2:38 PM, Vladimir Barinov <vladimir.barinov@cogentembedded.com> wrote: > Add Holt Integrated Circuits, Inc. to the list of device tree vendor > prefixes > > Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> Acked-by: Rob Herring <robh@kernel.org> > --- > Changes in version 2: > - none > Changes in version 3: > - none > Changes in version 4: > - none > > Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt > index d444757..bc64cc9 100644 > --- a/Documentation/devicetree/bindings/vendor-prefixes.txt > +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt > @@ -99,6 +99,7 @@ himax Himax Technologies, Inc. > hisilicon Hisilicon Limited. > hit Hitachi Ltd. > hitex Hitex Development Tools > +holt Holt Integrated Circuits, Inc. > honeywell Honeywell > hp Hewlett Packard > i2se I2SE GmbH > -- > 1.9.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/4] dt: Add vendor prefix 'holt' 2015-08-23 22:32 ` Rob Herring @ 2015-08-27 19:51 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2015-08-27 19:51 UTC (permalink / raw) To: Rob Herring, Vladimir Barinov Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, Cory Tusar On 23/08/15 23:32, Rob Herring wrote: > On Thu, Aug 20, 2015 at 2:38 PM, Vladimir Barinov > <vladimir.barinov@cogentembedded.com> wrote: >> Add Holt Integrated Circuits, Inc. to the list of device tree vendor >> prefixes >> >> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> > > Acked-by: Rob Herring <robh@kernel.org> Applied to the togreg branch of iio.git. Thanks, Jonathan > >> --- >> Changes in version 2: >> - none >> Changes in version 3: >> - none >> Changes in version 4: >> - none >> >> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt >> index d444757..bc64cc9 100644 >> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt >> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt >> @@ -99,6 +99,7 @@ himax Himax Technologies, Inc. >> hisilicon Hisilicon Limited. >> hit Hitachi Ltd. >> hitex Hitex Development Tools >> +holt Holt Integrated Circuits, Inc. >> honeywell Honeywell >> hp Hewlett Packard >> i2se I2SE GmbH >> -- >> 1.9.1 >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-iio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector 2015-08-20 19:37 [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector Vladimir Barinov 2015-08-20 19:37 ` [PATCH v4 1/4] iio: Support triggered events Vladimir Barinov 2015-08-20 19:38 ` [PATCH v4 2/4] dt: Add vendor prefix 'holt' Vladimir Barinov @ 2015-08-20 19:38 ` Vladimir Barinov 2015-08-27 20:09 ` Jonathan Cameron 2015-08-20 19:38 ` [PATCH v4 4/4] dt: Document Holt HI-8435 bindings Vladimir Barinov 3 siblings, 1 reply; 11+ messages in thread From: Vladimir Barinov @ 2015-08-20 19:38 UTC (permalink / raw) To: Jonathan Cameron Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar Add Holt threshold detector driver for HI-8435 chip Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- Changes in version 2: - Added file sysfs-bus-iio-adc-hi8435 - Changed naming from "discrete ADC" to "threshold detector" - Replaced swab16p/swab32p with be16_to_cpup/be32_to_cpup - Made *_show and *_store functions static - moved out from iio buffers to iio events - removed hi8436/hi8437 chips from the driver - moved from debounce_soft_delay/enable to debounce_interval via IIO_CHAN_INFO_DEBOUNCE_TIME - added name extention "comparator" - moved threshold/hysteresis setup via generic iio event sysfs - added software mask/unmask channel events - added programming sensor outputs while in test mode via IIO_CHAN_INFO_RAW - added channels .ext_info for programming sensing mode Changes in version 3: - fixed typos - moved <linux/interrupt.h> to match alphabetic order - fixed missed */event/* prefix in the ABI description - added missed colon in sysfs-bus-iio-adc-hi8435 file after "What" - moved in_voltageY_comparator_thresh_either_en and debounce_time to sysfs-bus-iio file - added error checking for hi8435_write[b|w] Changes in version 4: - removed software debounce logic - fixed typo in comment s/threshold/thresholds - removed test_enable sysfs entry - removed *_raw entries - removed extended_name - switched to GPIO descriptor API - added comment describing the need of thresholds initialization - added debugfs_reg_access Documentation/ABI/testing/sysfs-bus-iio | 1 + Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 | 39 ++ drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/hi8435.c | 535 +++++++++++++++++++++ 5 files changed, 587 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 create mode 100644 drivers/iio/adc/hi8435.c diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 42d360f..20312a0 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -581,6 +581,7 @@ What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en What: /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en What: /sys/.../iio:deviceX/events/in_voltageY_thresh_falling_en +What: /sys/.../iio:deviceX/events/in_voltageY_thresh_either_en What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en KernelVersion: 2.6.37 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 b/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 new file mode 100644 index 0000000..e3f1943 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 @@ -0,0 +1,39 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_sensing_mode +Date: August 2015 +KernelVersion: 4.2.0 +Contact: source@cogentembedded.com +Description: + Program sensor type for threshold detector inputs. + Could be either "GND-Open" or "Supply-Open" mode. Y is a + threshold detector input channel. Channels 0..7, 8..15, 16..23 + and 24..31 has common sensor types. + +What: /sys/bus/iio/devices/iio:deviceX/events/in_voltageY_thresh_falling_value +Date: August 2015 +KernelVersion: 4.2.0 +Contact: source@cogentembedded.com +Description: + Channel Y low voltage threshold. If sensor input voltage goes lower then + this value then the threshold falling event is pushed. + Depending on in_voltageY_sensing_mode the low voltage threshold + is separately set for "GND-Open" and "Supply-Open" modes. + Channels 0..31 have common low threshold values, but could have different + sensing_modes. + The low voltage threshold range is between 2..21V. + Hysteresis between low and high thresholds can not be lower then 2 and + can not be odd. + +What: /sys/bus/iio/devices/iio:deviceX/events/in_voltageY_thresh_rising_value +Date: August 2015 +KernelVersion: 4.2.0 +Contact: source@cogentembedded.com +Description: + Channel Y high voltage threshold. If sensor input voltage goes higher then + this value then the threshold rising event is pushed. + Depending on in_voltageY_sensing_mode the high voltage threshold + is separately set for "GND-Open" and "Supply-Open" modes. + Channels 0..31 have common high threshold values, but could have different + sensing_modes. + The high voltage threshold range is between 3..22V. + Hysteresis between low and high thresholds can not be lower then 2 and + can not be odd. diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 50c103d..dc4ca6e 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -183,6 +183,17 @@ config EXYNOS_ADC To compile this driver as a module, choose M here: the module will be called exynos_adc. +config HI8435 + tristate "Holt Integrated Circuits HI-8435 threshold detector" + select IIO_TRIGGERED_EVENT + depends on SPI + help + If you say yes here you get support for Holt Integrated Circuits + HI-8435 chip. + + This driver can also be built as a module. If so, the module will be + called hi8435. + config LP8788_ADC tristate "LP8788 ADC driver" depends on MFD_LP8788 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index a096210..00f367aa 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o +obj-$(CONFIG_HI8435) += hi8435.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX1363) += max1363.o diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c new file mode 100644 index 0000000..2b413d6 --- /dev/null +++ b/drivers/iio/adc/hi8435.c @@ -0,0 +1,535 @@ +/* + * Holt Integrated Circuits HI-8435 threshold detector driver + * + * Copyright (C) 2015 Zodiac Inflight Innovations + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/delay.h> +#include <linux/iio/events.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_event.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/spi/spi.h> + +#define DRV_NAME "hi8435" + +/* Register offsets for HI-8435 */ +#define HI8435_CTRL_REG 0x02 +#define HI8435_PSEN_REG 0x04 +#define HI8435_TMDATA_REG 0x1E +#define HI8435_GOCENHYS_REG 0x3A +#define HI8435_SOCENHYS_REG 0x3C +#define HI8435_SO7_0_REG 0x10 +#define HI8435_SO15_8_REG 0x12 +#define HI8435_SO23_16_REG 0x14 +#define HI8435_SO31_24_REG 0x16 +#define HI8435_SO31_0_REG 0x78 + +#define HI8435_WRITE_OPCODE 0x00 +#define HI8435_READ_OPCODE 0x80 + +/* CTRL register bits */ +#define HI8435_CTRL_TEST 0x01 +#define HI8435_CTRL_SRST 0x02 + +struct hi8435_priv { + struct spi_device *spi; + struct mutex lock; + + unsigned long event_scan_mask; /* soft mask/unmask channels events */ + unsigned int event_prev_val; + + unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */ + unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */ + u8 reg_buffer[4] ____cacheline_aligned; +}; + +static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val) +{ + reg |= HI8435_READ_OPCODE; + return spi_write_then_read(priv->spi, ®, 1, val, 1); +} + +static int hi8435_readw(struct hi8435_priv *priv, u8 reg, u16 *val) +{ + int ret; + + reg |= HI8435_READ_OPCODE; + ret = spi_write_then_read(priv->spi, ®, 1, val, 2); + *val = be16_to_cpup(val); + + return ret; +} + +static int hi8435_readl(struct hi8435_priv *priv, u8 reg, u32 *val) +{ + int ret; + + reg |= HI8435_READ_OPCODE; + ret = spi_write_then_read(priv->spi, ®, 1, val, 4); + *val = be32_to_cpup(val); + + return ret; +} + +static int hi8435_writeb(struct hi8435_priv *priv, u8 reg, u8 val) +{ + priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE; + priv->reg_buffer[1] = val; + + return spi_write(priv->spi, priv->reg_buffer, 2); +} + +static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val) +{ + priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE; + priv->reg_buffer[1] = (val >> 8) & 0xff; + priv->reg_buffer[2] = val & 0xff; + + return spi_write(priv->spi, priv->reg_buffer, 3); +} + +static int hi8435_read_event_config(struct iio_dev *idev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct hi8435_priv *priv = iio_priv(idev); + + return !!(priv->event_scan_mask & BIT(chan->channel)); +} + +static int hi8435_write_event_config(struct iio_dev *idev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, int state) +{ + struct hi8435_priv *priv = iio_priv(idev); + + priv->event_scan_mask &= ~BIT(chan->channel); + if (state) + priv->event_scan_mask |= BIT(chan->channel); + + return 0; +} + +static int hi8435_read_event_value(struct iio_dev *idev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct hi8435_priv *priv = iio_priv(idev); + int ret; + u8 mode, psen; + u16 reg; + + ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen); + if (ret < 0) + return ret; + + /* Supply-Open or GND-Open sensing mode */ + mode = !!(psen & BIT(chan->channel / 8)); + + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : + HI8435_GOCENHYS_REG, ®); + if (ret < 0) + return ret; + + if (dir == IIO_EV_DIR_FALLING) + *val = ((reg & 0xff) - (reg >> 8)) / 2; + + if (dir == IIO_EV_DIR_RISING) + *val = ((reg & 0xff) + (reg >> 8)) / 2; + + return IIO_VAL_INT; +} + +static int hi8435_write_event_value(struct iio_dev *idev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct hi8435_priv *priv = iio_priv(idev); + int ret; + u8 mode, psen; + u16 reg; + + ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen); + if (ret < 0) + return ret; + + /* Supply-Open or GND-Open sensing mode */ + mode = !!(psen & BIT(chan->channel / 8)); + + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : + HI8435_GOCENHYS_REG, ®); + if (ret < 0) + return ret; + + if (dir == IIO_EV_DIR_FALLING) { + /* falling threshold range 2..21V, hysteresis minimum 2V */ + if (val < 2 || val > 21 || (val + 2) > priv->threshold_hi[mode]) + return -EINVAL; + + if (val == priv->threshold_lo[mode]) + return 0; + + priv->threshold_lo[mode] = val; + + /* hysteresis must not be odd */ + if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2) + priv->threshold_hi[mode]--; + } + + if (dir == IIO_EV_DIR_RISING) { + /* rising threshold range 3..22V, hysteresis minimum 2V */ + if (val < 3 || val > 22 || val < (priv->threshold_lo[mode] + 2)) + return -EINVAL; + + if (val == priv->threshold_hi[mode]) + return 0; + + priv->threshold_hi[mode] = val; + + /* hysteresis must not be odd */ + if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2) + priv->threshold_lo[mode]++; + } + + /* program thresholds */ + mutex_lock(&priv->lock); + + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : + HI8435_GOCENHYS_REG, ®); + if (ret < 0) { + mutex_unlock(&priv->lock); + return ret; + } + + /* hysteresis */ + reg = priv->threshold_hi[mode] - priv->threshold_lo[mode]; + reg <<= 8; + /* threshold center */ + reg |= (priv->threshold_hi[mode] + priv->threshold_lo[mode]); + + ret = hi8435_writew(priv, mode ? HI8435_SOCENHYS_REG : + HI8435_GOCENHYS_REG, reg); + + mutex_unlock(&priv->lock); + + return ret; +} + +static int hi8435_debugfs_reg_access(struct iio_dev *idev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct hi8435_priv *priv = iio_priv(idev); + int ret; + u8 val; + + if (readval != NULL) { + ret = hi8435_readb(priv, reg, &val); + *readval = val; + } else { + val = (u8)writeval; + ret = hi8435_writeb(priv, reg, val); + } + + return ret; +} + +static const struct iio_event_spec hi8435_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + }, +}; + +static int hi8435_get_sensing_mode(struct iio_dev *idev, + const struct iio_chan_spec *chan) +{ + struct hi8435_priv *priv = iio_priv(idev); + int ret; + u8 reg; + + ret = hi8435_readb(priv, HI8435_PSEN_REG, ®); + if (ret < 0) + return ret; + + return !!(reg & BIT(chan->channel / 8)); +} + +static int hi8435_set_sensing_mode(struct iio_dev *idev, + const struct iio_chan_spec *chan, + unsigned int mode) +{ + struct hi8435_priv *priv = iio_priv(idev); + int ret; + u8 reg; + + mutex_lock(&priv->lock); + + ret = hi8435_readb(priv, HI8435_PSEN_REG, ®); + if (ret < 0) { + mutex_unlock(&priv->lock); + return ret; + } + + reg &= ~BIT(chan->channel / 8); + if (mode) + reg |= BIT(chan->channel / 8); + + ret = hi8435_writeb(priv, HI8435_PSEN_REG, reg); + + mutex_unlock(&priv->lock); + + return ret; +} + +static const char * const hi8435_sensing_modes[] = { "GND-Open", + "Supply-Open" }; + +static const struct iio_enum hi8435_sensing_mode = { + .items = hi8435_sensing_modes, + .num_items = ARRAY_SIZE(hi8435_sensing_modes), + .get = hi8435_get_sensing_mode, + .set = hi8435_set_sensing_mode, +}; + +static const struct iio_chan_spec_ext_info hi8435_ext_info[] = { + IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode), + {}, +}; + +#define HI8435_VOLTAGE_CHANNEL(num) \ +{ \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .event_spec = hi8435_events, \ + .num_event_specs = ARRAY_SIZE(hi8435_events), \ + .ext_info = hi8435_ext_info, \ +} + +static const struct iio_chan_spec hi8435_channels[] = { + HI8435_VOLTAGE_CHANNEL(0), + HI8435_VOLTAGE_CHANNEL(1), + HI8435_VOLTAGE_CHANNEL(2), + HI8435_VOLTAGE_CHANNEL(3), + HI8435_VOLTAGE_CHANNEL(4), + HI8435_VOLTAGE_CHANNEL(5), + HI8435_VOLTAGE_CHANNEL(6), + HI8435_VOLTAGE_CHANNEL(7), + HI8435_VOLTAGE_CHANNEL(8), + HI8435_VOLTAGE_CHANNEL(9), + HI8435_VOLTAGE_CHANNEL(10), + HI8435_VOLTAGE_CHANNEL(11), + HI8435_VOLTAGE_CHANNEL(12), + HI8435_VOLTAGE_CHANNEL(13), + HI8435_VOLTAGE_CHANNEL(14), + HI8435_VOLTAGE_CHANNEL(15), + HI8435_VOLTAGE_CHANNEL(16), + HI8435_VOLTAGE_CHANNEL(17), + HI8435_VOLTAGE_CHANNEL(18), + HI8435_VOLTAGE_CHANNEL(19), + HI8435_VOLTAGE_CHANNEL(20), + HI8435_VOLTAGE_CHANNEL(21), + HI8435_VOLTAGE_CHANNEL(22), + HI8435_VOLTAGE_CHANNEL(23), + HI8435_VOLTAGE_CHANNEL(24), + HI8435_VOLTAGE_CHANNEL(25), + HI8435_VOLTAGE_CHANNEL(26), + HI8435_VOLTAGE_CHANNEL(27), + HI8435_VOLTAGE_CHANNEL(28), + HI8435_VOLTAGE_CHANNEL(29), + HI8435_VOLTAGE_CHANNEL(30), + HI8435_VOLTAGE_CHANNEL(31), + IIO_CHAN_SOFT_TIMESTAMP(32), +}; + +static const struct iio_info hi8435_info = { + .driver_module = THIS_MODULE, + .read_event_config = &hi8435_read_event_config, + .write_event_config = hi8435_write_event_config, + .read_event_value = &hi8435_read_event_value, + .write_event_value = &hi8435_write_event_value, + .debugfs_reg_access = &hi8435_debugfs_reg_access, +}; + +static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val) +{ + struct hi8435_priv *priv = iio_priv(idev); + enum iio_event_direction dir; + unsigned int i; + unsigned int status = priv->event_prev_val ^ val; + + if (!status) + return; + + for_each_set_bit(i, &priv->event_scan_mask, 32) { + if (!(status & BIT(i))) + continue; + + dir = val & BIT(i) ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING; + + iio_push_event(idev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, + IIO_EV_TYPE_THRESH, dir), + iio_get_time_ns()); + } + + priv->event_prev_val = val; +} + +static irqreturn_t hi8435_trigger_handler(int irq, void *private) +{ + struct iio_poll_func *pf = private; + struct iio_dev *idev = pf->indio_dev; + struct hi8435_priv *priv = iio_priv(idev); + u32 val; + int ret; + + ret = hi8435_readl(priv, HI8435_SO31_0_REG, &val); + if (ret < 0) + goto err_read; + + hi8435_iio_push_event(idev, val); + +err_read: + iio_trigger_notify_done(idev->trig); + + return IRQ_HANDLED; +} + +static int hi8435_probe(struct spi_device *spi) +{ + struct iio_dev *idev; + struct hi8435_priv *priv; + struct gpio_desc *reset_gpio; + int ret; + + idev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); + if (!idev) + return -ENOMEM; + + priv = iio_priv(idev); + priv->spi = spi; + + reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) { + /* chip s/w reset if h/w reset failed */ + hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST); + hi8435_writeb(priv, HI8435_CTRL_REG, 0); + } else { + udelay(5); + gpiod_set_value(reset_gpio, 1); + } + + spi_set_drvdata(spi, idev); + mutex_init(&priv->lock); + + idev->dev.parent = &spi->dev; + idev->name = spi_get_device_id(spi)->name; + idev->modes = INDIO_DIRECT_MODE; + idev->info = &hi8435_info; + idev->channels = hi8435_channels; + idev->num_channels = ARRAY_SIZE(hi8435_channels); + + /* unmask all events */ + priv->event_scan_mask = ~(0); + /* + * There is a restriction in the chip - the hysteresis can not be odd. + * If the hysteresis is set to odd value then chip gets into lock state + * and not functional anymore. + * After chip reset the thresholds are in undefined state, so we need to + * initialize thresholds to some initial values and then prevent + * userspace setting odd hysteresis. + * + * Set threshold low voltage to 2V, threshold high voltage to 4V + * for both GND-Open and Supply-Open sensing modes. + */ + priv->threshold_lo[0] = priv->threshold_lo[1] = 2; + priv->threshold_hi[0] = priv->threshold_hi[1] = 4; + hi8435_writew(priv, HI8435_GOCENHYS_REG, 0x206); + hi8435_writew(priv, HI8435_SOCENHYS_REG, 0x206); + + ret = iio_triggered_event_setup(idev, NULL, hi8435_trigger_handler); + if (ret) + return ret; + + ret = iio_device_register(idev); + if (ret < 0) { + dev_err(&spi->dev, "unable to register device\n"); + goto unregister_triggered_event; + } + + return 0; + +unregister_triggered_event: + iio_triggered_event_cleanup(idev); + return ret; +} + +static int hi8435_remove(struct spi_device *spi) +{ + struct iio_dev *idev = spi_get_drvdata(spi); + + iio_device_unregister(idev); + iio_triggered_event_cleanup(idev); + + return 0; +} + +static const struct of_device_id hi8435_dt_ids[] = { + { .compatible = "holt,hi8435" }, + {}, +}; +MODULE_DEVICE_TABLE(of, hi8435_dt_ids); + +static const struct spi_device_id hi8435_id[] = { + { "hi8435", 0}, + { } +}; +MODULE_DEVICE_TABLE(spi, hi8435_id); + +static struct spi_driver hi8435_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = of_match_ptr(hi8435_dt_ids), + }, + .probe = hi8435_probe, + .remove = hi8435_remove, + .id_table = hi8435_id, +}; +module_spi_driver(hi8435_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vladimir Barinov"); +MODULE_DESCRIPTION("HI-8435 threshold detector"); -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector 2015-08-20 19:38 ` [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector Vladimir Barinov @ 2015-08-27 20:09 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2015-08-27 20:09 UTC (permalink / raw) To: Vladimir Barinov Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar On 20/08/15 20:38, Vladimir Barinov wrote: > Add Holt threshold detector driver for HI-8435 chip > > Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> A few little bits and bobs below but basically there. Jonathan > --- > Changes in version 2: > - Added file sysfs-bus-iio-adc-hi8435 > - Changed naming from "discrete ADC" to "threshold detector" > - Replaced swab16p/swab32p with be16_to_cpup/be32_to_cpup > - Made *_show and *_store functions static > - moved out from iio buffers to iio events > - removed hi8436/hi8437 chips from the driver > - moved from debounce_soft_delay/enable to debounce_interval via > IIO_CHAN_INFO_DEBOUNCE_TIME > - added name extention "comparator" > - moved threshold/hysteresis setup via generic iio event sysfs > - added software mask/unmask channel events > - added programming sensor outputs while in test mode via > IIO_CHAN_INFO_RAW > - added channels .ext_info for programming sensing mode > Changes in version 3: > - fixed typos > - moved <linux/interrupt.h> to match alphabetic order > - fixed missed */event/* prefix in the ABI description > - added missed colon in sysfs-bus-iio-adc-hi8435 file after "What" > - moved in_voltageY_comparator_thresh_either_en and debounce_time > to sysfs-bus-iio file > - added error checking for hi8435_write[b|w] > Changes in version 4: > - removed software debounce logic > - fixed typo in comment s/threshold/thresholds > - removed test_enable sysfs entry > - removed *_raw entries > - removed extended_name > - switched to GPIO descriptor API > - added comment describing the need of thresholds initialization > - added debugfs_reg_access > > Documentation/ABI/testing/sysfs-bus-iio | 1 + > Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 | 39 ++ > drivers/iio/adc/Kconfig | 11 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/hi8435.c | 535 +++++++++++++++++++++ > 5 files changed, 587 insertions(+) > create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 > create mode 100644 drivers/iio/adc/hi8435.c > > diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio > index 42d360f..20312a0 100644 > --- a/Documentation/ABI/testing/sysfs-bus-iio > +++ b/Documentation/ABI/testing/sysfs-bus-iio > @@ -581,6 +581,7 @@ What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en > What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en > What: /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en > What: /sys/.../iio:deviceX/events/in_voltageY_thresh_falling_en > +What: /sys/.../iio:deviceX/events/in_voltageY_thresh_either_en > What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en > What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en > KernelVersion: 2.6.37 > diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 b/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 > new file mode 100644 > index 0000000..e3f1943 > --- /dev/null > +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-hi8435 > @@ -0,0 +1,39 @@ > +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_sensing_mode > +Date: August 2015 > +KernelVersion: 4.2.0 > +Contact: source@cogentembedded.com > +Description: > + Program sensor type for threshold detector inputs. > + Could be either "GND-Open" or "Supply-Open" mode. Y is a > + threshold detector input channel. Channels 0..7, 8..15, 16..23 > + and 24..31 has common sensor types. > + > +What: /sys/bus/iio/devices/iio:deviceX/events/in_voltageY_thresh_falling_value > +Date: August 2015 > +KernelVersion: 4.2.0 > +Contact: source@cogentembedded.com > +Description: > + Channel Y low voltage threshold. If sensor input voltage goes lower then > + this value then the threshold falling event is pushed. > + Depending on in_voltageY_sensing_mode the low voltage threshold > + is separately set for "GND-Open" and "Supply-Open" modes. > + Channels 0..31 have common low threshold values, but could have different > + sensing_modes. > + The low voltage threshold range is between 2..21V. > + Hysteresis between low and high thresholds can not be lower then 2 and > + can not be odd. Should note that what happens if it is set to odd. > + > +What: /sys/bus/iio/devices/iio:deviceX/events/in_voltageY_thresh_rising_value > +Date: August 2015 > +KernelVersion: 4.2.0 > +Contact: source@cogentembedded.com > +Description: > + Channel Y high voltage threshold. If sensor input voltage goes higher then > + this value then the threshold rising event is pushed. > + Depending on in_voltageY_sensing_mode the high voltage threshold > + is separately set for "GND-Open" and "Supply-Open" modes. > + Channels 0..31 have common high threshold values, but could have different > + sensing_modes. > + The high voltage threshold range is between 3..22V. > + Hysteresis between low and high thresholds can not be lower then 2 and > + can not be odd. > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 50c103d..dc4ca6e 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -183,6 +183,17 @@ config EXYNOS_ADC > To compile this driver as a module, choose M here: the module will be > called exynos_adc. > > +config HI8435 > + tristate "Holt Integrated Circuits HI-8435 threshold detector" > + select IIO_TRIGGERED_EVENT > + depends on SPI > + help > + If you say yes here you get support for Holt Integrated Circuits > + HI-8435 chip. > + > + This driver can also be built as a module. If so, the module will be > + called hi8435. > + > config LP8788_ADC > tristate "LP8788 ADC driver" > depends on MFD_LP8788 > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index a096210..00f367aa 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -19,6 +19,7 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o > obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o > obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o > obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o I'm a little dubious about this being in ADC but lets leave it there for now as it's easier to move later. > +obj-$(CONFIG_HI8435) += hi8435.o > obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o > obj-$(CONFIG_MAX1027) += max1027.o > obj-$(CONFIG_MAX1363) += max1363.o > diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c > new file mode 100644 > index 0000000..2b413d6 > --- /dev/null > +++ b/drivers/iio/adc/hi8435.c > @@ -0,0 +1,535 @@ > +/* > + * Holt Integrated Circuits HI-8435 threshold detector driver > + * > + * Copyright (C) 2015 Zodiac Inflight Innovations > + * Copyright (C) 2015 Cogent Embedded, Inc. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. > + */ > + > +#include <linux/delay.h> > +#include <linux/iio/events.h> > +#include <linux/iio/iio.h> > +#include <linux/iio/sysfs.h> > +#include <linux/iio/trigger.h> > +#include <linux/iio/trigger_consumer.h> > +#include <linux/iio/triggered_event.h> > +#include <linux/interrupt.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_device.h> > +#include <linux/of_gpio.h> > +#include <linux/spi/spi.h> > + > +#define DRV_NAME "hi8435" > + > +/* Register offsets for HI-8435 */ > +#define HI8435_CTRL_REG 0x02 > +#define HI8435_PSEN_REG 0x04 > +#define HI8435_TMDATA_REG 0x1E > +#define HI8435_GOCENHYS_REG 0x3A > +#define HI8435_SOCENHYS_REG 0x3C > +#define HI8435_SO7_0_REG 0x10 > +#define HI8435_SO15_8_REG 0x12 > +#define HI8435_SO23_16_REG 0x14 > +#define HI8435_SO31_24_REG 0x16 > +#define HI8435_SO31_0_REG 0x78 > + > +#define HI8435_WRITE_OPCODE 0x00 > +#define HI8435_READ_OPCODE 0x80 > + > +/* CTRL register bits */ > +#define HI8435_CTRL_TEST 0x01 > +#define HI8435_CTRL_SRST 0x02 > + > +struct hi8435_priv { > + struct spi_device *spi; > + struct mutex lock; > + > + unsigned long event_scan_mask; /* soft mask/unmask channels events */ > + unsigned int event_prev_val; > + > + unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */ > + unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */ Small point, but I can't find any use of the 4th element in the buffer? Whilst it makes no practical difference it is a little odd! > + u8 reg_buffer[4] ____cacheline_aligned; > +}; > + > +static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val) > +{ > + reg |= HI8435_READ_OPCODE; > + return spi_write_then_read(priv->spi, ®, 1, val, 1); > +} > + > +static int hi8435_readw(struct hi8435_priv *priv, u8 reg, u16 *val) > +{ > + int ret; > + > + reg |= HI8435_READ_OPCODE; > + ret = spi_write_then_read(priv->spi, ®, 1, val, 2); > + *val = be16_to_cpup(val); > + > + return ret; > +} > + > +static int hi8435_readl(struct hi8435_priv *priv, u8 reg, u32 *val) > +{ > + int ret; > + > + reg |= HI8435_READ_OPCODE; > + ret = spi_write_then_read(priv->spi, ®, 1, val, 4); > + *val = be32_to_cpup(val); > + > + return ret; > +} > + > +static int hi8435_writeb(struct hi8435_priv *priv, u8 reg, u8 val) > +{ > + priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE; > + priv->reg_buffer[1] = val; > + > + return spi_write(priv->spi, priv->reg_buffer, 2); > +} > + > +static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val) > +{ > + priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE; > + priv->reg_buffer[1] = (val >> 8) & 0xff; > + priv->reg_buffer[2] = val & 0xff; > + > + return spi_write(priv->spi, priv->reg_buffer, 3); > +} > + > +static int hi8435_read_event_config(struct iio_dev *idev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + > + return !!(priv->event_scan_mask & BIT(chan->channel)); > +} > + > +static int hi8435_write_event_config(struct iio_dev *idev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, int state) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + > + priv->event_scan_mask &= ~BIT(chan->channel); > + if (state) > + priv->event_scan_mask |= BIT(chan->channel); > + > + return 0; > +} > + > +static int hi8435_read_event_value(struct iio_dev *idev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int *val, int *val2) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + int ret; > + u8 mode, psen; > + u16 reg; > + > + ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen); > + if (ret < 0) > + return ret; > + > + /* Supply-Open or GND-Open sensing mode */ > + mode = !!(psen & BIT(chan->channel / 8)); > + > + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : > + HI8435_GOCENHYS_REG, ®); > + if (ret < 0) > + return ret; > + > + if (dir == IIO_EV_DIR_FALLING) > + *val = ((reg & 0xff) - (reg >> 8)) / 2; > + else if? > + if (dir == IIO_EV_DIR_RISING) > + *val = ((reg & 0xff) + (reg >> 8)) / 2; > + > + return IIO_VAL_INT; > +} > + > +static int hi8435_write_event_value(struct iio_dev *idev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int val, int val2) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + int ret; > + u8 mode, psen; > + u16 reg; > + > + ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen); > + if (ret < 0) > + return ret; > + > + /* Supply-Open or GND-Open sensing mode */ > + mode = !!(psen & BIT(chan->channel / 8)); > + > + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : > + HI8435_GOCENHYS_REG, ®); > + if (ret < 0) > + return ret; > + > + if (dir == IIO_EV_DIR_FALLING) { > + /* falling threshold range 2..21V, hysteresis minimum 2V */ > + if (val < 2 || val > 21 || (val + 2) > priv->threshold_hi[mode]) > + return -EINVAL; > + > + if (val == priv->threshold_lo[mode]) > + return 0; > + > + priv->threshold_lo[mode] = val; > + > + /* hysteresis must not be odd */ > + if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2) > + priv->threshold_hi[mode]--; Document this detail (that the threshold is reduced under these circumstances) > + } > + else if? > + if (dir == IIO_EV_DIR_RISING) { > + /* rising threshold range 3..22V, hysteresis minimum 2V */ > + if (val < 3 || val > 22 || val < (priv->threshold_lo[mode] + 2)) > + return -EINVAL; > + > + if (val == priv->threshold_hi[mode]) > + return 0; > + > + priv->threshold_hi[mode] = val; > + > + /* hysteresis must not be odd */ > + if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2) > + priv->threshold_lo[mode]++; > + } > + > + /* program thresholds */ > + mutex_lock(&priv->lock); > + > + ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG : > + HI8435_GOCENHYS_REG, ®); > + if (ret < 0) { > + mutex_unlock(&priv->lock); > + return ret; > + } > + > + /* hysteresis */ > + reg = priv->threshold_hi[mode] - priv->threshold_lo[mode]; > + reg <<= 8; > + /* threshold center */ > + reg |= (priv->threshold_hi[mode] + priv->threshold_lo[mode]); > + > + ret = hi8435_writew(priv, mode ? HI8435_SOCENHYS_REG : > + HI8435_GOCENHYS_REG, reg); > + > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static int hi8435_debugfs_reg_access(struct iio_dev *idev, > + unsigned reg, unsigned writeval, > + unsigned *readval) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + int ret; > + u8 val; > + > + if (readval != NULL) { > + ret = hi8435_readb(priv, reg, &val); > + *readval = val; > + } else { > + val = (u8)writeval; > + ret = hi8435_writeb(priv, reg, val); > + } > + > + return ret; > +} > + > +static const struct iio_event_spec hi8435_events[] = { > + { > + .type = IIO_EV_TYPE_THRESH, > + .dir = IIO_EV_DIR_RISING, > + .mask_separate = BIT(IIO_EV_INFO_VALUE), > + }, { > + .type = IIO_EV_TYPE_THRESH, > + .dir = IIO_EV_DIR_FALLING, > + .mask_separate = BIT(IIO_EV_INFO_VALUE), > + }, { > + .type = IIO_EV_TYPE_THRESH, > + .dir = IIO_EV_DIR_EITHER, > + .mask_separate = BIT(IIO_EV_INFO_ENABLE), > + }, > +}; > + > +static int hi8435_get_sensing_mode(struct iio_dev *idev, > + const struct iio_chan_spec *chan) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + int ret; > + u8 reg; > + > + ret = hi8435_readb(priv, HI8435_PSEN_REG, ®); > + if (ret < 0) > + return ret; > + > + return !!(reg & BIT(chan->channel / 8)); > +} > + > +static int hi8435_set_sensing_mode(struct iio_dev *idev, > + const struct iio_chan_spec *chan, > + unsigned int mode) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + int ret; > + u8 reg; > + > + mutex_lock(&priv->lock); > + > + ret = hi8435_readb(priv, HI8435_PSEN_REG, ®); > + if (ret < 0) { > + mutex_unlock(&priv->lock); > + return ret; > + } > + > + reg &= ~BIT(chan->channel / 8); > + if (mode) > + reg |= BIT(chan->channel / 8); > + > + ret = hi8435_writeb(priv, HI8435_PSEN_REG, reg); > + > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static const char * const hi8435_sensing_modes[] = { "GND-Open", > + "Supply-Open" }; + > +static const struct iio_enum hi8435_sensing_mode = { > + .items = hi8435_sensing_modes, > + .num_items = ARRAY_SIZE(hi8435_sensing_modes), > + .get = hi8435_get_sensing_mode, > + .set = hi8435_set_sensing_mode, > +}; > + > +static const struct iio_chan_spec_ext_info hi8435_ext_info[] = { > + IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode), > + {}, > +}; > + > +#define HI8435_VOLTAGE_CHANNEL(num) \ > +{ \ > + .type = IIO_VOLTAGE, \ > + .indexed = 1, \ > + .channel = num, \ > + .event_spec = hi8435_events, \ > + .num_event_specs = ARRAY_SIZE(hi8435_events), \ > + .ext_info = hi8435_ext_info, \ > +} > + > +static const struct iio_chan_spec hi8435_channels[] = { > + HI8435_VOLTAGE_CHANNEL(0), > + HI8435_VOLTAGE_CHANNEL(1), > + HI8435_VOLTAGE_CHANNEL(2), > + HI8435_VOLTAGE_CHANNEL(3), > + HI8435_VOLTAGE_CHANNEL(4), > + HI8435_VOLTAGE_CHANNEL(5), > + HI8435_VOLTAGE_CHANNEL(6), > + HI8435_VOLTAGE_CHANNEL(7), > + HI8435_VOLTAGE_CHANNEL(8), > + HI8435_VOLTAGE_CHANNEL(9), > + HI8435_VOLTAGE_CHANNEL(10), > + HI8435_VOLTAGE_CHANNEL(11), > + HI8435_VOLTAGE_CHANNEL(12), > + HI8435_VOLTAGE_CHANNEL(13), > + HI8435_VOLTAGE_CHANNEL(14), > + HI8435_VOLTAGE_CHANNEL(15), > + HI8435_VOLTAGE_CHANNEL(16), > + HI8435_VOLTAGE_CHANNEL(17), > + HI8435_VOLTAGE_CHANNEL(18), > + HI8435_VOLTAGE_CHANNEL(19), > + HI8435_VOLTAGE_CHANNEL(20), > + HI8435_VOLTAGE_CHANNEL(21), > + HI8435_VOLTAGE_CHANNEL(22), > + HI8435_VOLTAGE_CHANNEL(23), > + HI8435_VOLTAGE_CHANNEL(24), > + HI8435_VOLTAGE_CHANNEL(25), > + HI8435_VOLTAGE_CHANNEL(26), > + HI8435_VOLTAGE_CHANNEL(27), > + HI8435_VOLTAGE_CHANNEL(28), > + HI8435_VOLTAGE_CHANNEL(29), > + HI8435_VOLTAGE_CHANNEL(30), > + HI8435_VOLTAGE_CHANNEL(31), > + IIO_CHAN_SOFT_TIMESTAMP(32), > +}; > + > +static const struct iio_info hi8435_info = { > + .driver_module = THIS_MODULE, > + .read_event_config = &hi8435_read_event_config, > + .write_event_config = hi8435_write_event_config, > + .read_event_value = &hi8435_read_event_value, > + .write_event_value = &hi8435_write_event_value, > + .debugfs_reg_access = &hi8435_debugfs_reg_access, > +}; > + > +static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val) > +{ > + struct hi8435_priv *priv = iio_priv(idev); > + enum iio_event_direction dir; > + unsigned int i; > + unsigned int status = priv->event_prev_val ^ val; > + > + if (!status) > + return; > + > + for_each_set_bit(i, &priv->event_scan_mask, 32) { > + if (!(status & BIT(i))) > + continue; > + I'd have been tempted to do an if / else with the iio_push_event instead of having this temporary visit. > + dir = val & BIT(i) ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING; > + > + iio_push_event(idev, > + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, > + IIO_EV_TYPE_THRESH, dir), > + iio_get_time_ns()); > + } > + > + priv->event_prev_val = val; > +} > + > +static irqreturn_t hi8435_trigger_handler(int irq, void *private) > +{ > + struct iio_poll_func *pf = private; > + struct iio_dev *idev = pf->indio_dev; > + struct hi8435_priv *priv = iio_priv(idev); > + u32 val; > + int ret; > + > + ret = hi8435_readl(priv, HI8435_SO31_0_REG, &val); > + if (ret < 0) > + goto err_read; > + > + hi8435_iio_push_event(idev, val); > + > +err_read: > + iio_trigger_notify_done(idev->trig); > + > + return IRQ_HANDLED; > +} > + > +static int hi8435_probe(struct spi_device *spi) > +{ > + struct iio_dev *idev; > + struct hi8435_priv *priv; > + struct gpio_desc *reset_gpio; > + int ret; > + > + idev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); > + if (!idev) > + return -ENOMEM; > + > + priv = iio_priv(idev); > + priv->spi = spi; > + > + reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW); > + if (IS_ERR(reset_gpio)) { > + /* chip s/w reset if h/w reset failed */ > + hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST); > + hi8435_writeb(priv, HI8435_CTRL_REG, 0); > + } else { > + udelay(5); > + gpiod_set_value(reset_gpio, 1); > + } > + > + spi_set_drvdata(spi, idev); > + mutex_init(&priv->lock); > + > + idev->dev.parent = &spi->dev; > + idev->name = spi_get_device_id(spi)->name; > + idev->modes = INDIO_DIRECT_MODE; > + idev->info = &hi8435_info; > + idev->channels = hi8435_channels; > + idev->num_channels = ARRAY_SIZE(hi8435_channels); > + > + /* unmask all events */ > + priv->event_scan_mask = ~(0); > + /* > + * There is a restriction in the chip - the hysteresis can not be odd. > + * If the hysteresis is set to odd value then chip gets into lock state > + * and not functional anymore. > + * After chip reset the thresholds are in undefined state, so we need to > + * initialize thresholds to some initial values and then prevent > + * userspace setting odd hysteresis. > + * > + * Set threshold low voltage to 2V, threshold high voltage to 4V > + * for both GND-Open and Supply-Open sensing modes. > + */ > + priv->threshold_lo[0] = priv->threshold_lo[1] = 2; > + priv->threshold_hi[0] = priv->threshold_hi[1] = 4; > + hi8435_writew(priv, HI8435_GOCENHYS_REG, 0x206); > + hi8435_writew(priv, HI8435_SOCENHYS_REG, 0x206); > + > + ret = iio_triggered_event_setup(idev, NULL, hi8435_trigger_handler); > + if (ret) > + return ret; > + > + ret = iio_device_register(idev); > + if (ret < 0) { > + dev_err(&spi->dev, "unable to register device\n"); > + goto unregister_triggered_event; > + } > + > + return 0; > + > +unregister_triggered_event: > + iio_triggered_event_cleanup(idev); > + return ret; > +} > + > +static int hi8435_remove(struct spi_device *spi) > +{ > + struct iio_dev *idev = spi_get_drvdata(spi); > + > + iio_device_unregister(idev); > + iio_triggered_event_cleanup(idev); > + > + return 0; > +} > + > +static const struct of_device_id hi8435_dt_ids[] = { > + { .compatible = "holt,hi8435" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, hi8435_dt_ids); > + > +static const struct spi_device_id hi8435_id[] = { > + { "hi8435", 0}, > + { } > +}; > +MODULE_DEVICE_TABLE(spi, hi8435_id); > + > +static struct spi_driver hi8435_driver = { > + .driver = { > + .name = DRV_NAME, > + .of_match_table = of_match_ptr(hi8435_dt_ids), > + }, > + .probe = hi8435_probe, > + .remove = hi8435_remove, > + .id_table = hi8435_id, > +}; > +module_spi_driver(hi8435_driver); > + > +MODULE_LICENSE("GPL"); > +MODULE_AUTHOR("Vladimir Barinov"); > +MODULE_DESCRIPTION("HI-8435 threshold detector"); > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 4/4] dt: Document Holt HI-8435 bindings 2015-08-20 19:37 [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector Vladimir Barinov ` (2 preceding siblings ...) 2015-08-20 19:38 ` [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector Vladimir Barinov @ 2015-08-20 19:38 ` Vladimir Barinov 2015-08-27 20:11 ` Jonathan Cameron 3 siblings, 1 reply; 11+ messages in thread From: Vladimir Barinov @ 2015-08-20 19:38 UTC (permalink / raw) To: Jonathan Cameron Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar These bindings can be used to register Holt HI-8435 threshold detector Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- Changes in version 2: - renamed file name hi-843x.txt to hi8435.txt - removed hi-8436,hi-8436,hi-8437 - removed holt,debounce-soft field - renamed holt,debounc-soft-delay to holt,debounce-interval - renamed mr-gpio to reset-gpios Changes in version 3: - none Changes in version 4: - removed debounce_interval property - removed reset-gpios to use GPIO descriptor API .../devicetree/bindings/iio/adc/hi8435.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/hi8435.txt diff --git a/Documentation/devicetree/bindings/iio/adc/hi8435.txt b/Documentation/devicetree/bindings/iio/adc/hi8435.txt new file mode 100644 index 0000000..3b0348c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/hi8435.txt @@ -0,0 +1,21 @@ +Holt Integrated Circuits HI-8435 threshold detector bindings + +Required properties: + - compatible: should be "holt,hi8435" + - reg: spi chip select number for the device + +Recommended properties: + - spi-max-frequency: definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Optional properties: + - gpios: GPIO used for controlling the reset pin + +Example: +sensor@0 { + compatible = "holt,hi8435"; + reg = <0>; + gpios = <&gpio6 1 0>; + + spi-max-frequency = <1000000>; +}; -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 4/4] dt: Document Holt HI-8435 bindings 2015-08-20 19:38 ` [PATCH v4 4/4] dt: Document Holt HI-8435 bindings Vladimir Barinov @ 2015-08-27 20:11 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2015-08-27 20:11 UTC (permalink / raw) To: Vladimir Barinov Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-kernel, linux-iio, devicetree, cory.tusar On 20/08/15 20:38, Vladimir Barinov wrote: > These bindings can be used to register Holt HI-8435 threshold detector > > Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> This is fine and trivial enough that I am not going to need a device tree ack (not that I'd complain if one showed up :) Will pick it up with the driver.. > --- > Changes in version 2: > - renamed file name hi-843x.txt to hi8435.txt > - removed hi-8436,hi-8436,hi-8437 > - removed holt,debounce-soft field > - renamed holt,debounc-soft-delay to holt,debounce-interval > - renamed mr-gpio to reset-gpios > Changes in version 3: > - none > Changes in version 4: > - removed debounce_interval property > - removed reset-gpios to use GPIO descriptor API > > .../devicetree/bindings/iio/adc/hi8435.txt | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > create mode 100644 Documentation/devicetree/bindings/iio/adc/hi8435.txt > > diff --git a/Documentation/devicetree/bindings/iio/adc/hi8435.txt b/Documentation/devicetree/bindings/iio/adc/hi8435.txt > new file mode 100644 > index 0000000..3b0348c > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/hi8435.txt > @@ -0,0 +1,21 @@ > +Holt Integrated Circuits HI-8435 threshold detector bindings > + > +Required properties: > + - compatible: should be "holt,hi8435" > + - reg: spi chip select number for the device > + > +Recommended properties: > + - spi-max-frequency: definition as per > + Documentation/devicetree/bindings/spi/spi-bus.txt > + > +Optional properties: > + - gpios: GPIO used for controlling the reset pin > + > +Example: > +sensor@0 { > + compatible = "holt,hi8435"; > + reg = <0>; > + gpios = <&gpio6 1 0>; > + > + spi-max-frequency = <1000000>; > +}; > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-08-27 20:11 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-08-20 19:37 [PATCH v4 0/4] iio: adc: hi8435: Add Holt HI-8435 threshold detector Vladimir Barinov 2015-08-20 19:37 ` [PATCH v4 1/4] iio: Support triggered events Vladimir Barinov 2015-08-20 19:43 ` Vladimir Barinov 2015-08-27 19:50 ` Jonathan Cameron 2015-08-20 19:38 ` [PATCH v4 2/4] dt: Add vendor prefix 'holt' Vladimir Barinov 2015-08-23 22:32 ` Rob Herring 2015-08-27 19:51 ` Jonathan Cameron 2015-08-20 19:38 ` [PATCH v4 3/4] iio: adc: hi8435: Holt HI-8435 threshold detector Vladimir Barinov 2015-08-27 20:09 ` Jonathan Cameron 2015-08-20 19:38 ` [PATCH v4 4/4] dt: Document Holt HI-8435 bindings Vladimir Barinov 2015-08-27 20:11 ` Jonathan Cameron
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).