From: "Mårten Lindahl" <marten.lindahl-VrBV9hrLPhE@public.gmane.org>
To: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: "Peter Meerwald-Stadler"
<pmeerw-jW+XmwGofnusTnJN9+BGXg@public.gmane.org>,
"Mårten Lindahl" <martenli-VrBV9hrLPhE@public.gmane.org>,
lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org,
linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] iio: adc: add driver for the ti-adc084s021 chip
Date: Sun, 30 Apr 2017 14:38:34 +0200 [thread overview]
Message-ID: <1493555914.2883.29.camel@axis.com> (raw)
In-Reply-To: <5dec6eec-c214-c14d-8dc9-ff298854fc1c-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
On Sun, 2017-04-23 at 20:13 +0100, Jonathan Cameron wrote:
> On 21/04/17 21:19, Peter Meerwald-Stadler wrote:
> >
> >> From: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>
> >
> > comments below
> A few more from me. Laptop battery gone flat so not so thorough on top few lines!
>
> Jonathan
Hi Jonathan! Thanks for the comments! Please see my reply below.
Thanks,
Mårten
> >
> >> This adds support for the Texas Instruments ADC084S021 ADC chip.
> >>
> >> Signed-off-by: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>
> >> ---
> >> .../devicetree/bindings/iio/adc/ti-adc084s021.txt | 25 ++
> >> drivers/iio/adc/Kconfig | 12 +
> >> drivers/iio/adc/Makefile | 1 +
> >> drivers/iio/adc/ti-adc084s021.c | 342 +++++++++++++++++++++
> >> 4 files changed, 380 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
> >> create mode 100644 drivers/iio/adc/ti-adc084s021.c
> >>
> >> diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
> >> new file mode 100644
> >> index 0000000..921eb46
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
> >> @@ -0,0 +1,25 @@
> >> +* Texas Instruments' ADC084S021
> >> +
> >> +Required properties:
> >> + - compatible : Must be "ti,adc084s021"
> >> + - reg : SPI chip select number for the device
> >> + - vref-supply : The regulator supply for ADC reference voltage
> >> + - spi-max-frequency : Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt
> >> +
> >> +Optional properties:
> >> + - spi-cpol : SPI inverse clock polarity, as per spi-bus bindings
> >> + - spi-cpha : SPI shifted clock phase (CPHA), as per spi-bus bindings
> >> + - spi-cs-high : SPI chip select active high, as per spi-bus bindings
> >> +
> >> +
> >> +Example:
> >> +adc@0 {
> >> + compatible = "ti,adc084s021";
> >> + reg = <0>;
> >> + vref-supply = <&adc_vref>;
> >> + spi-cpol;
> >> + spi-cpha;
> >> + spi-cs-high;
> >> + spi-max-frequency = <16000000>;
> >> + pl022,com-mode = <0x2>; /* DMA */
> >
> > what is this?
> >
> >> +};
> >> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> >> index dedae7a..13141e5 100644
> >> --- a/drivers/iio/adc/Kconfig
> >> +++ b/drivers/iio/adc/Kconfig
> >> @@ -560,6 +560,18 @@ config TI_ADC0832
> >> This driver can also be built as a module. If so, the module will be
> >> called ti-adc0832.
> >>
> >> +config TI_ADC084S021
> >> + tristate "Texas Instruments ADC084S021"
> >> + depends on SPI
> >> + select IIO_BUFFER
> >> + select IIO_TRIGGERED_BUFFER
> >> + help
> >> + If you say yes here you get support for Texas Instruments ADC084S021
> >> + chips.
> >> +
> >> + This driver can also be built as a module. If so, the module will be
> >> + called ti-adc084s021.
> >> +
> >> config TI_ADC12138
> >> tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
> >> depends on SPI
> >> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> >> index d001262..b1a6158 100644
> >> --- a/drivers/iio/adc/Makefile
> >> +++ b/drivers/iio/adc/Makefile
> >> @@ -51,6 +51,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
> >> obj-$(CONFIG_STM32_ADC) += stm32-adc.o
> >> obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
> >> obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
> >> +obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
> >> obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
> >> obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
> >> obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
> >> diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
> >> new file mode 100644
> >> index 0000000..4f33b91
> >> --- /dev/null
> >> +++ b/drivers/iio/adc/ti-adc084s021.c
> >> @@ -0,0 +1,342 @@
> >> +/**
> >> + * Copyright (C) 2017 Axis Communications AB
> >> + *
> >> + * Driver for Texas Instruments' ADC084S021 ADC chip.
> >> + * Datasheets can be found here:
> >> + * http://www.ti.com/lit/ds/symlink/adc084s021.pdf
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> + */
> >> +
> >> +#include <linux/err.h>
> >> +#include <linux/spi/spi.h>
> >> +#include <linux/module.h>
> >> +#include <linux/interrupt.h>
> >> +#include <linux/iio/iio.h>
> >> +#include <linux/iio/buffer.h>
> >> +#include <linux/iio/events.h>
> >> +#include <linux/iio/triggered_buffer.h>
> >> +#include <linux/iio/trigger_consumer.h>
> >> +#include <linux/regulator/consumer.h>
> >> +
> >> +#define MODULE_NAME "adc084s021"
> >> +#define DRIVER_VERSION "1.0"
> >
> > is only used once at the very end...
> >
> >> +#define ADC_RESOLUTION 8
> Put it inline...
Fixed in v2.
> >> +#define ADC_N_CHANNELS 4
> Belongs inline. No additional info provided by having it here.
Fixed in v2.
> >
> > we want a consistent prefix, such as ADC084S021_
> >
> >> +
> >> +struct adc084s021_configuration {
> >> + const struct iio_chan_spec *channels;
> >> + u8 num_channels;
> >
> > no need for u8, perhaps unsigned?
> >
> >> +};
> >> +
> >> +struct adc084s021 {
> >> + struct spi_device *spi;
> >> + struct spi_message message;
> >> + struct spi_transfer spi_trans[2];
> >> + struct regulator *reg;
> >> + struct mutex lock;
> >> + /*
> >> + * DMA (thus cache coherency maintenance) requires the
> >> + * transfer buffers to live in their own cache lines.
> >> + */
> >> + union {
> >> + u8 tx_buf[2];
> >> + u8 rx_buf[2];
> >> + } ____cacheline_aligned;
> >> + u8 cur_adc_values[ADC_N_CHANNELS];
> >> +};
> >> +
> >> +/**
> >> + * Event triggered when value changes on a channel
> >> + */
> >> +static const struct iio_event_spec adc084s021_event = {
> >> + .type = IIO_EV_TYPE_CHANGE,
> >> + .dir = IIO_EV_DIR_NONE,
> >> +};
> Not the intent of that type of event at all.
I removed using events in v2.
> >> +
> >> +/**
> >> + * Channel specification
> >> + */
> >> +#define ADC084S021_VOLTAGE_CHANNEL(num) \
> >> + { \
> >> + .type = IIO_VOLTAGE, \
> >> + .channel = (num), \
> >> + .address = (num << 3), \
> >
> > parenthesis should be around (num)
> >
> >> + .indexed = 1, \
> >> + .scan_index = num, \
> >
> > parenthesis?
> >
> >> + .scan_type = { \
> >> + .sign = 'u', \
> >> + .realbits = 8, \
> >> + .storagebits = 32, \
> >> + .shift = 24 - ((num << 3)), \
> >
> > no need for (( )) around the expression, parenthesis should be around num
> >
> > the shift doesn't make sense, you are shifting in
> >
> > adc084s021_adc_conversion() already and return just 8 bits (so storagebits
> > should be 8)?
> >
> > you could/should use realbits = 8, storagebits = 16, shift = 4 and
> > endianness = IIO_BE if I read Figure 1 of the datasheet correctly
> >
> >> + }, \
> >> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> >
> > likely this is missing _SCALE
> > IIO expects data to be returned in millivolt, see
> > Documentation/ABI/testing/sysfs-bus-iio
> >
> >> + .event_spec = &adc084s021_event, \
> >> + .num_event_specs = 1, \
> >
> > ARRAY_SIZE(&adc084s021_event) to be extensible?
> >
> >> + }
> >> +
> >> +static const struct iio_chan_spec adc084s021_channels[] = {
> >> + ADC084S021_VOLTAGE_CHANNEL(0),
> >> + ADC084S021_VOLTAGE_CHANNEL(1),
> >> + ADC084S021_VOLTAGE_CHANNEL(2),
> >> + ADC084S021_VOLTAGE_CHANNEL(3),
> >> + IIO_CHAN_SOFT_TIMESTAMP(4),
> >> +};
> >> +
> >> +static const struct adc084s021_configuration adc084s021_config[] = {
> >> + { adc084s021_channels, ARRAY_SIZE(adc084s021_channels) },
> >
> > for just one configuration, this is not really needed; so you plan/forsee
> > more chips being added soonish?
> >
> >> +};
> >> +
> >> +/**
> >> + * Read an ADC channel and return its value.
> >> + *
> >> + * @adc: The ADC SPI data.
> >> + * @channel: The IIO channel data structure.
> >> + */
> >> +static int adc084s021_adc_conversion(struct adc084s021 *adc,
> >> + struct iio_chan_spec const *channel)
> >> +{
> >> + u16 value;
> >
> > value should be u8, but is not really needed
> >
> >> + int ret;
> >> +
> >> + mutex_lock(&adc->lock);
> >> + adc->tx_buf[0] = channel->address;
> >> +
> >> + /* Do the transfer */
> >> + ret = spi_sync(adc->spi, &adc->message);
> >> +
> >
> > no newline here please
> >
> >> + if (ret < 0) {
> >> + mutex_unlock(&adc->lock);
> >> + return ret;
> >> + }
> >> +
> >> + value = (adc->rx_buf[0] << 4) | (adc->rx_buf[1] >> 4);
> >
> > I recommend using __be16 for rx_buf and
> > ret = (be16_to_cpu(adc->rx_buf) >> 4) & 0xff;
> >
> >> + mutex_unlock(&adc->lock);
> >> +
> >> + dev_dbg(&adc->spi->dev, "value 0x%02X on channel %d\n",
> >> + value, channel->channel);
> >> + return value;
> >> +}
> >> +
> >> +/**
> >> + * Make a readout of requested IIO channel info.
> >
> > no need to document this, it is found in every IIO driver...
> >
> >> + *
> >> + * @indio_dev: The industrial I/O device.
> >> + * @channel: The IIO channel data structure.
> >> + * @val: First element of value (integer).
> >> + * @val2: Second element of value (fractional).
> >> + * @mask: The info_mask to read.
> >> + */
> >> +static int adc084s021_read_raw(struct iio_dev *indio_dev,
> >> + struct iio_chan_spec const *channel, int *val,
> >> + int *val2, long mask)
> >> +{
> >> + struct adc084s021 *adc = iio_priv(indio_dev);
> >> + int retval;
> >
> > how about using ret everywhere?
> Agreed.
Fixed in v2.
> >
> >> +
> >> + switch (mask) {
> >> + case IIO_CHAN_INFO_RAW:
> >
> > probably want iio_device_claim_direct_mode() so to not interfere with
> > buffered accessBorderline case as all you will do is queue up additional spi transfers.
> At least after you have dropped the unusual events stuff.
>
> Arguably this will mean sysfs reads could make the buffered data flow
> less deterministic though so maybe on claiming direct mode (which
> prevents it running concurrently with buffered capture.
Fixed in v2. And no events anymore.
> >
> >> + retval = adc084s021_adc_conversion(adc, channel);
> >> + if (retval < 0)
> >> + return retval;
> >> +
> >> + *val = retval;
> >> + return IIO_VAL_INT;
> >> +
> >> + default:
> >> + return -EINVAL;
> >> + }
> >> +}
> >> +
> >> +/**
> >> + * Read enabled ADC channels and push data to the buffer.
> >> + *
> >> + * @irq: The interrupt number (not used).
> >> + * @pollfunc: Pointer to the poll func.
> >> + */
> >> +static irqreturn_t adc084s021_trigger_handler(int irq, void *pollfunc)
> >> +{
> >> + struct iio_poll_func *pf = pollfunc;
> >> + struct iio_dev *indio_dev = pf->indio_dev;
> >> + struct adc084s021 *adc = iio_priv(indio_dev);
> >> + u8 *data;
> >> + s64 timestamp;
> >> + int value, scan_index;
> >> +
> >> + data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
> >
> > pre-allocate buffer with maximum size statically; allocation is
> > potentially expensive; don't forget space for the timestamp and padding...
> >
> >> + if (!data) {
> >> + iio_trigger_notify_done(indio_dev->trig);
> >> + return IRQ_NONE;
> >> + }
> >> +
> >> + timestamp = iio_get_time_ns(indio_dev);
> >> +
> >> + for_each_set_bit(scan_index, indio_dev->active_scan_mask,
> >> + indio_dev->masklength) {
> >> + const struct iio_chan_spec *channel =
> >> + &indio_dev->channels[scan_index];
> >> + value = adc084s021_adc_conversion(adc, channel);
> >
> > lock is taken and released for each channel, probably want to do it just
> > once?
> >
> >> + data[scan_index] = value;
> >> +
> >> + /*
> >> + * Compare read data to previous read. If it differs send
> >> + * event notification for affected channel.
> >> + */
> >> + if (adc->cur_adc_values[scan_index] != (u8)value) {
> >
> > cur_adc_values is not initialized (probably set to 0);
> > so on first read, should the notification be sent?
> ? This is 'unusual' to say the least. Why the events given the data
> is available via the buffer. If you really want to do this stuff, it
> ought to be in userspace.
>
> Are you trying to emulate the filtering input does?
I removed the check for previous value and sending events in v2.
> >
> >> + adc->cur_adc_values[scan_index] = (u8)value;
> >> + iio_push_event(indio_dev,
> >> + IIO_EVENT_CODE(IIO_VOLTAGE, 0,
> >> + IIO_NO_MOD, IIO_EV_DIR_NONE,
> >> + IIO_EV_TYPE_CHANGE,
> >> + channel->channel, 0, 0),
> >> + timestamp);
> >> + dev_dbg(&indio_dev->dev,
> >> + "new value on ch%d: 0x%02X (ts %llu)\n",
> >> + channel->channel, value, timestamp);
> >> + }
> >> + }
> >> +
> >> + iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
> >> + iio_trigger_notify_done(indio_dev->trig);
> >> + kfree(data);
> blank line here please.
Fixed in v2.
> >> + return IRQ_HANDLED;
> >> +}
> >> +
> >> +static const struct iio_info adc084s021_info = {
> >> + .read_raw = adc084s021_read_raw,
> >> + .driver_module = THIS_MODULE,
> >> +};
> >> +
> >> +/**
> >> + * Create and register ADC IIO device for SPI.
> >
> > comment is rather pointless
> >
> >> + */
> >> +static int adc084s021_probe(struct spi_device *spi)
> >> +{
> >> + struct iio_dev *indio_dev;
> >> + struct adc084s021 *adc;
> >> + int config = spi_get_device_id(spi)->driver_data;
> >> + int retval;
> >
> > ret maybe
> >
> >> +
> >> + /* Allocate an Industrial I/O device */
> >
> > obviously...
> :) Yeah, clear out any comments that don't tell us much.
Fixed in v2.
> >
> >> + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
> >> + if (!indio_dev) {
> >> + dev_err(&spi->dev, "Failed to allocate IIO device\n");
> >> + return -ENOMEM;
> >> + }
> >> +
> >> + adc = iio_priv(indio_dev);
> >> + adc->spi = spi;
> >> + spi->bits_per_word = ADC_RESOLUTION;
> This surprised me somewhat as I was expecting an odd value for this
> (and was going to ask if standard power of 2 options would work).
> If it had been inline, this would have required slightly less review
> time which I always like (particularly when crammed into an airline seat!)
Yes, I am using inline value in v2.
> >> +
> >> + /* Update the SPI device with config and connect the iio dev */
> >> + retval = spi_setup(spi);
> >> + if (retval) {
> >> + dev_err(&spi->dev, "Failed to update SPI device\n");
> >> + return retval;
> >> + }
> >> + spi_set_drvdata(spi, indio_dev);
> >> +
> >> + /* Initiate the Industrial I/O device */
> :>> + indio_dev->dev.parent = &spi->dev;
> >> + indio_dev->dev.of_node = spi->dev.of_node;
> >> + indio_dev->name = spi_get_device_id(spi)->name;
> >> + indio_dev->modes = INDIO_DIRECT_MODE;
> >> + indio_dev->info = &adc084s021_info;
> >> + indio_dev->channels = adc084s021_config[config].channels;
> >> + indio_dev->num_channels = adc084s021_config[config].num_channels;
> >
> > could do it directly as long there is just one configuration
> That would certainly be preferable unless V2 is going to show up
> with multiple options!
Fixed. No more options supported in v2.
> >
> >> +
> >> + /* Create SPI transfer for channel reads */
> >> + adc->spi_trans[0].tx_buf = &adc->tx_buf[0];
> >> + adc->spi_trans[0].len = 2;
> >> + adc->spi_trans[0].speed_hz = spi->max_speed_hz;
> >> + adc->spi_trans[0].bits_per_word = spi->bits_per_word;
> >> + adc->spi_trans[1].rx_buf = &adc->rx_buf[0];
> >> + adc->spi_trans[1].len = 2;
> >> + adc->spi_trans[1].speed_hz = spi->max_speed_hz;
> >> + adc->spi_trans[1].bits_per_word = spi->bits_per_word;
> >> +
> >> + /* Setup SPI message for channel reads */
> >> + spi_message_init(&adc->message);
> >> + spi_message_add_tail(&adc->spi_trans[0], &adc->message);
> >> + spi_message_add_tail(&adc->spi_trans[1], &adc->message);
> spi_init_with_transfers to save a bit of boilerplate.
Fixed in v2.
> >> +
> >> + adc->reg = devm_regulator_get(&spi->dev, "vref");
> >> + if (IS_ERR(adc->reg))
> >> + return PTR_ERR(adc->reg);
> >> +
> >> + retval = regulator_enable(adc->reg);
> >> + if (retval < 0)
> >> + return retval;
> Given we either have slow sysfs accesses or know we have buffered
> access on going. Have you considered enabling and disabling
> the regulator dynamically? The fact that this often makes sense is
> why Mark and co from the regulators side of things haven't provided
> a devm_regulator_enable... You would need a preenable and postdisable
> to make sure it was on for buffered access.
Yes, I am using preenable and postdisable functions for regulator in v2.
> >> +
> >> + mutex_init(&adc->lock);
> >> +
> >> + /* Setup triggered buffer with pollfunction */
> >> + retval = iio_triggered_buffer_setup(indio_dev, NULL,
> >
> > devm_()
> I disagree. It would change the ordering wrt to the regulator_enable.
> Now, obviously it won't actually matter, but it will make the code
> less obviously correct and for the small burden of extra unwind
> code I'd keep using the non devm version.
I did not change this in v2. So I kept the non devm_ functions.
> >
> >> + adc084s021_trigger_handler, NULL);
> >> + if (retval) {
> >> + dev_err(&spi->dev, "Failed to setup triggered buffer\n");
> >> + goto buffer_setup_failed;
> >> + }
> >> +
> >> + retval = iio_device_register(indio_dev);
> >> + if (retval) {
> >> + dev_err(&spi->dev, "Failed to register IIO device\n");
> Hmm. If we were to flesh out some error messages for the few
> cases where there is no info provided in iio_device_register we could
> probably clean out a fair bit of boiler plate reporting in drivers.
> Ah well, one for the future!
If you insist I will remove it :)
> >> + goto device_register_failed;
> >> + }
> >> +
> >> + dev_info(&spi->dev, "probed!\n");
> >
> > no logging please, just outputs clutter
> >
> >> + return 0;
> >> +
> >> +device_register_failed:
> >> + iio_triggered_buffer_cleanup(indio_dev);
> >> +buffer_setup_failed:
> >> + regulator_disable(adc->reg);
> >> + return retval;
> >> +}
> >> +
> >> +/**
> >> + * Unregister ADC IIO device for SPI.
> >> + */
> >> +static int adc084s021_remove(struct spi_device *spi)
> >> +{
> >> + struct iio_dev *indio_dev = spi_get_drvdata(spi);
> >> + struct adc084s021 *adc = iio_priv(indio_dev);
> >> +
> >> + iio_device_unregister(indio_dev);
> >> + iio_triggered_buffer_cleanup(indio_dev);
> >> + regulator_disable(adc->reg);
> blank line here preferred (slightly!)
Fixed in v2.
> >> + return 0;
> >> +}
> >> +
> >> +static const struct of_device_id adc084s021_of_match[] = {
> >> + { .compatible = "ti,adc084s021", },
> >> + {},
> >> +};
> >> +
> >> +MODULE_DEVICE_TABLE(of, adc084s021_of_match);
> >> +
> >> +static const struct spi_device_id adc084s021_id[] = {
> >> + { MODULE_NAME, 0},
> >> + {}
> >> +};
> >> +
> >> +MODULE_DEVICE_TABLE(spi, adc084s021_id);
> >> +
> >> +static struct spi_driver adc084s021_driver = {
> >> + .driver = {
> >> + .name = MODULE_NAME,
> >> + .of_match_table = of_match_ptr(adc084s021_of_match),
> >> + },
> >> + .probe = adc084s021_probe,
> >> + .remove = adc084s021_remove,
> >> + .id_table = adc084s021_id,
> >> +};
> >> +
> Convention often says to not bother with a blank line here or before
> the MODULE_DEVICE_TABLE above. Gives a visual indication that these macros
> are being passed the structures.
> (really minor point!)
Fixed in v2.
> >> +module_spi_driver(adc084s021_driver);
> >> +
> >> +MODULE_AUTHOR("Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>");
> >> +MODULE_DESCRIPTION("Texas Instruments ADC084S021");
> >> +MODULE_LICENSE("GPL v2");
> >> +MODULE_VERSION(DRIVER_VERSION);
> >>
> >
>
next prev parent reply other threads:[~2017-04-30 12:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-21 14:58 [PATCH] iio: adc: add driver for the ti-adc084s021 chip Mårten Lindahl
[not found] ` <1492786703-5149-1-git-send-email-marten.lindahl-VrBV9hrLPhE@public.gmane.org>
2017-04-21 20:19 ` Peter Meerwald-Stadler
[not found] ` <alpine.DEB.2.20.1704212149070.2470-M0QeDd4q1oXQbIPoIc8EuQ@public.gmane.org>
2017-04-23 19:13 ` Jonathan Cameron
[not found] ` <5dec6eec-c214-c14d-8dc9-ff298854fc1c-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-04-27 10:15 ` Mårten Lindahl
[not found] ` <1493288121.21359.33.camel-VrBV9hrLPhE@public.gmane.org>
2017-04-30 15:13 ` Jonathan Cameron
2017-04-30 12:38 ` Mårten Lindahl [this message]
2017-04-30 12:24 ` Mårten Lindahl
2017-04-28 13:52 ` Rob Herring
2017-04-30 12:42 ` Mårten Lindahl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1493555914.2883.29.camel@axis.com \
--to=marten.lindahl-vrbv9hrlphe@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org \
--cc=linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
--cc=martenli-VrBV9hrLPhE@public.gmane.org \
--cc=pmeerw-jW+XmwGofnusTnJN9+BGXg@public.gmane.org \
--cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).