All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-06 20:47 ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, Ezequiel Garcia

This series add the support for an ADC IP block from Cosmic Circuits.
The patchset is based on v3.19-rc3.

As agreed with Rob, this series drops the vendor prefix in the
adc-reserved-channels DT property. This property is generic enough to
be used in other drivers (at91 is a potential candidate).

A follow-up patch can use the property in at91 and add it to the
IIO generic bindings.

Changes from v6:

  * Dropped the vendor prefix in the adc-reserved-channels property,
    as suggested by Rob.
  * Added Andrew's Reviewed-by tags. Andrew reviewed v3, and the driver
    changed little since then.
    http://www.spinics.net/lists/linux-iio/msg15630.html.

Changes from v5:

  * Fixed CC10001_ADC_CH_MASK macro definition, to separate the channel
    number from the channel map, as noted by Hartmut.
  * Return the real error code in devm_regulator_get failure.

Changes from v4:

  * Added a compile-time dependency on REGULATOR and HAVE_CLK.
  * Replaced the silly XOR operation for a proper mask out of the
    available channels.

Changes from v3:

  * Fixed a few style nitpicks as per Hartmut's feedback.
  * Used GENMASK() to build the channel mask, which fixes a very nasty
    bug. Also found by Hartmut.

Changes from v2:

  * Changed a devicetree property from adc-available-channels to
    adc-reserved-channels, so it can be made optional.
  * Renamed the driver from cc_10001_xxx to cc10001_xxx so it's consistent
    with the rest of the kernel style.
  * Some more minor cosmetic fixes.

Changes from v1:

  * Removed unneeded header includes.
  * Changed all the names and macros prefix: s/CC_10001_/CC10001_.
  * Used .update_scan_mode callback to preallocate the buffer.
  * Used indio_dev for the struct iio_dev.
  * Only read the regulator voltage when needed.
  * Fixed probe() error handling.
  * Used for_each_set_bit() instead of open-coding it.
  * Name the power-down register as _POWER_UP, to make the code
    less silly.
  * Error out when no valid sample can be read (i.e. when end-of-conversion
    poll times out).
  * ... plus some assorted code cleaning based on the feedback.

Ezequiel Garcia (1):
  DT: Add a vendor prefix for Cosmic Circuits

Phani Movva (2):
  iio: adc: Cosmic Circuits 10001 ADC driver
  DT: iio: adc: Add CC_10001 binding documentation

 .../devicetree/bindings/iio/adc/cc10001_adc.txt    |  22 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 drivers/iio/adc/Kconfig                            |  11 +
 drivers/iio/adc/Makefile                           |   1 +
 drivers/iio/adc/cc10001_adc.c                      | 423 +++++++++++++++++++++
 5 files changed, 458 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
 create mode 100644 drivers/iio/adc/cc10001_adc.c

-- 
2.2.1

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

* [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-06 20:47 ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak,
	Ezequiel Garcia

This series add the support for an ADC IP block from Cosmic Circuits.
The patchset is based on v3.19-rc3.

As agreed with Rob, this series drops the vendor prefix in the
adc-reserved-channels DT property. This property is generic enough to
be used in other drivers (at91 is a potential candidate).

A follow-up patch can use the property in at91 and add it to the
IIO generic bindings.

Changes from v6:

  * Dropped the vendor prefix in the adc-reserved-channels property,
    as suggested by Rob.
  * Added Andrew's Reviewed-by tags. Andrew reviewed v3, and the driver
    changed little since then.
    http://www.spinics.net/lists/linux-iio/msg15630.html.

Changes from v5:

  * Fixed CC10001_ADC_CH_MASK macro definition, to separate the channel
    number from the channel map, as noted by Hartmut.
  * Return the real error code in devm_regulator_get failure.

Changes from v4:

  * Added a compile-time dependency on REGULATOR and HAVE_CLK.
  * Replaced the silly XOR operation for a proper mask out of the
    available channels.

Changes from v3:

  * Fixed a few style nitpicks as per Hartmut's feedback.
  * Used GENMASK() to build the channel mask, which fixes a very nasty
    bug. Also found by Hartmut.

Changes from v2:

  * Changed a devicetree property from adc-available-channels to
    adc-reserved-channels, so it can be made optional.
  * Renamed the driver from cc_10001_xxx to cc10001_xxx so it's consistent
    with the rest of the kernel style.
  * Some more minor cosmetic fixes.

Changes from v1:

  * Removed unneeded header includes.
  * Changed all the names and macros prefix: s/CC_10001_/CC10001_.
  * Used .update_scan_mode callback to preallocate the buffer.
  * Used indio_dev for the struct iio_dev.
  * Only read the regulator voltage when needed.
  * Fixed probe() error handling.
  * Used for_each_set_bit() instead of open-coding it.
  * Name the power-down register as _POWER_UP, to make the code
    less silly.
  * Error out when no valid sample can be read (i.e. when end-of-conversion
    poll times out).
  * ... plus some assorted code cleaning based on the feedback.

Ezequiel Garcia (1):
  DT: Add a vendor prefix for Cosmic Circuits

Phani Movva (2):
  iio: adc: Cosmic Circuits 10001 ADC driver
  DT: iio: adc: Add CC_10001 binding documentation

 .../devicetree/bindings/iio/adc/cc10001_adc.txt    |  22 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 drivers/iio/adc/Kconfig                            |  11 +
 drivers/iio/adc/Makefile                           |   1 +
 drivers/iio/adc/cc10001_adc.c                      | 423 +++++++++++++++++++++
 5 files changed, 458 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
 create mode 100644 drivers/iio/adc/cc10001_adc.c

-- 
2.2.1

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

* [PATCH v7 1/3] iio: adc: Cosmic Circuits 10001 ADC driver
  2015-01-06 20:47 ` Ezequiel Garcia
@ 2015-01-06 20:47     ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, Phani Movva, Naidu Tellapati,
	Ezequiel Garcia

From: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>

This commit adds support for Cosmic Circuits 10001 10-bit ADC device.

Reviewed-by: Andrew Bresticker <abrestic-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Signed-off-by: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Naidu Tellapati <Naidu.Tellapati-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
[ezequiel: code style cleaning]
Signed-off-by: Ezequiel Garcia <ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
---
 drivers/iio/adc/Kconfig       |  11 ++
 drivers/iio/adc/Makefile      |   1 +
 drivers/iio/adc/cc10001_adc.c | 423 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 435 insertions(+)
 create mode 100644 drivers/iio/adc/cc10001_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 0f79e47..9cb8543 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -135,6 +135,17 @@ config AXP288_ADC
 	  device. Depending on platform configuration, this general purpose ADC can
 	  be used for sampling sensors such as thermal resistors.
 
+config CC10001_ADC
+	tristate "Cosmic Circuits 10001 ADC driver"
+	depends on HAS_IOMEM || HAVE_CLK || REGULATOR
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to build support for Cosmic Circuits 10001 ADC.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called cc10001_adc.
+
 config EXYNOS_ADC
 	tristate "Exynos ADC driver support"
 	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 701fdb7..ce60fe9 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
+obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1027) += max1027.o
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
new file mode 100644
index 0000000..47f638b
--- /dev/null
+++ b/drivers/iio/adc/cc10001_adc.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2014-2015 Imagination Technologies Ltd.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <linux/iio/buffer.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_buffer.h>
+
+/* Registers */
+#define CC10001_ADC_CONFIG		0x00
+#define CC10001_ADC_START_CONV		BIT(4)
+#define CC10001_ADC_MODE_SINGLE_CONV	BIT(5)
+
+#define CC10001_ADC_DDATA_OUT		0x04
+#define CC10001_ADC_EOC			0x08
+#define CC10001_ADC_EOC_SET		BIT(0)
+
+#define CC10001_ADC_CHSEL_SAMPLED	0x0c
+#define CC10001_ADC_POWER_UP		0x10
+#define CC10001_ADC_POWER_UP_SET	BIT(0)
+#define CC10001_ADC_DEBUG		0x14
+#define CC10001_ADC_DATA_COUNT		0x20
+
+#define CC10001_ADC_DATA_MASK		GENMASK(9, 0)
+#define CC10001_ADC_NUM_CHANNELS	8
+#define CC10001_ADC_CH_MASK		GENMASK(2, 0)
+
+#define CC10001_INVALID_SAMPLED		0xffff
+#define CC10001_MAX_POLL_COUNT		20
+
+/*
+ * As per device specification, wait six clock cycles after power-up to
+ * activate START. Since adding two more clock cycles delay does not
+ * impact the performance too much, we are adding two additional cycles delay
+ * intentionally here.
+ */
+#define	CC10001_WAIT_CYCLES		8
+
+struct cc10001_adc_device {
+	void __iomem *reg_base;
+	struct clk *adc_clk;
+	struct regulator *reg;
+	u16 *buf;
+
+	struct mutex lock;
+	unsigned long channel_map;
+	unsigned int start_delay_ns;
+	unsigned int eoc_delay_ns;
+};
+
+static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
+					 u32 reg, u32 val)
+{
+	writel(val, adc_dev->reg_base + reg);
+}
+
+static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
+				       u32 reg)
+{
+	return readl(adc_dev->reg_base + reg);
+}
+
+static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
+			      unsigned int channel)
+{
+	u32 val;
+
+	/* Channel selection and mode of operation */
+	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+
+	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
+	val = val | CC10001_ADC_START_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+}
+
+static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
+				 unsigned int channel,
+				 unsigned int delay)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int poll_count = 0;
+
+	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
+			CC10001_ADC_EOC_SET)) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	poll_count = 0;
+	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
+			CC10001_ADC_CH_MASK) != channel) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	/* Read the 10 bit output register */
+	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
+			       CC10001_ADC_DATA_MASK;
+}
+
+static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
+{
+	struct cc10001_adc_device *adc_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev;
+	unsigned int delay_ns;
+	unsigned int channel;
+	bool sample_invalid;
+	u16 *data;
+	int i;
+
+	indio_dev = pf->indio_dev;
+	adc_dev = iio_priv(indio_dev);
+	data = adc_dev->buf;
+
+	mutex_lock(&adc_dev->lock);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	i = 0;
+	sample_invalid = false;
+	for_each_set_bit(channel, indio_dev->active_scan_mask,
+				  indio_dev->masklength) {
+
+		cc10001_adc_start(adc_dev, channel);
+
+		data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
+		if (data[i] == CC10001_INVALID_SAMPLED) {
+			dev_warn(&indio_dev->dev,
+				 "invalid sample on channel %d\n", channel);
+			sample_invalid = true;
+			goto done;
+		}
+		i++;
+	}
+
+done:
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	mutex_unlock(&adc_dev->lock);
+
+	if (!sample_invalid)
+		iio_push_to_buffers_with_timestamp(indio_dev, data,
+						   iio_get_time_ns());
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
+					struct iio_chan_spec const *chan)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int delay_ns;
+	u16 val;
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	cc10001_adc_start(adc_dev, chan->channel);
+
+	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	return val;
+}
+
+static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
+				 struct iio_chan_spec const *chan,
+				 int *val, int *val2, long mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+		mutex_lock(&adc_dev->lock);
+		*val = cc10001_adc_read_raw_voltage(indio_dev, chan);
+		mutex_unlock(&adc_dev->lock);
+
+		if (*val == CC10001_INVALID_SAMPLED)
+			return -EIO;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		ret = regulator_get_voltage(adc_dev->reg);
+		if (ret)
+			return ret;
+
+		*val = ret / 1000;
+		*val2 = chan->scan_type.realbits;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
+				    const unsigned long *scan_mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	kfree(adc_dev->buf);
+	adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	if (!adc_dev->buf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const struct iio_info cc10001_adc_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &cc10001_adc_read_raw,
+	.update_scan_mode = &cc10001_update_scan_mode,
+};
+
+static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	struct iio_chan_spec *chan_array, *timestamp;
+	unsigned int bit, idx = 0;
+
+	indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
+						CC10001_ADC_NUM_CHANNELS);
+
+	chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
+				  sizeof(struct iio_chan_spec),
+				  GFP_KERNEL);
+	if (!chan_array)
+		return -ENOMEM;
+
+	for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
+		struct iio_chan_spec *chan = &chan_array[idx];
+
+		chan->type = IIO_VOLTAGE;
+		chan->indexed = 1;
+		chan->channel = bit;
+		chan->scan_index = idx;
+		chan->scan_type.sign = 'u';
+		chan->scan_type.realbits = 10;
+		chan->scan_type.storagebits = 16;
+		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
+		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+		idx++;
+	}
+
+	timestamp = &chan_array[idx];
+	timestamp->type = IIO_TIMESTAMP;
+	timestamp->channel = -1;
+	timestamp->scan_index = idx;
+	timestamp->scan_type.sign = 's';
+	timestamp->scan_type.realbits = 64;
+	timestamp->scan_type.storagebits = 64;
+
+	indio_dev->channels = chan_array;
+
+	return 0;
+}
+
+static int cc10001_adc_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct cc10001_adc_device *adc_dev;
+	unsigned long adc_clk_rate;
+	struct resource *res;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	adc_dev = iio_priv(indio_dev);
+
+	adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
+	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
+		adc_dev->channel_map &= ~ret;
+
+	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
+	if (IS_ERR(adc_dev->reg))
+		return PTR_ERR(adc_dev->reg);
+
+	ret = regulator_enable(adc_dev->reg);
+	if (ret)
+		return ret;
+
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->name = dev_name(&pdev->dev);
+	indio_dev->info = &cc10001_adc_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(adc_dev->reg_base)) {
+		ret = PTR_ERR(adc_dev->reg_base);
+		goto err_disable_reg;
+	}
+
+	adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
+	if (IS_ERR(adc_dev->adc_clk)) {
+		dev_err(&pdev->dev, "failed to get the clock\n");
+		ret = PTR_ERR(adc_dev->adc_clk);
+		goto err_disable_reg;
+	}
+
+	ret = clk_prepare_enable(adc_dev->adc_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable the clock\n");
+		goto err_disable_reg;
+	}
+
+	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
+	if (!adc_clk_rate) {
+		ret = -EINVAL;
+		dev_err(&pdev->dev, "null clock rate!\n");
+		goto err_disable_clk;
+	}
+
+	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
+	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
+
+	/* Setup the ADC channels available on the device */
+	ret = cc10001_adc_channel_init(indio_dev);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	mutex_init(&adc_dev->lock);
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+					 &cc10001_adc_trigger_h, NULL);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto err_cleanup_buffer;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	return 0;
+
+err_cleanup_buffer:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_disable_clk:
+	clk_disable_unprepare(adc_dev->adc_clk);
+err_disable_reg:
+	regulator_disable(adc_dev->reg);
+	return ret;
+}
+
+static int cc10001_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	clk_disable_unprepare(adc_dev->adc_clk);
+	regulator_disable(adc_dev->reg);
+
+	return 0;
+}
+
+static const struct of_device_id cc10001_adc_dt_ids[] = {
+	{ .compatible = "cosmic,10001-adc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
+
+static struct platform_driver cc10001_adc_driver = {
+	.driver = {
+		.name   = "cc10001-adc",
+		.of_match_table = cc10001_adc_dt_ids,
+	},
+	.probe	= cc10001_adc_probe,
+	.remove	= cc10001_adc_remove,
+};
+module_platform_driver(cc10001_adc_driver);
+
+MODULE_AUTHOR("Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.2.1

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

* [PATCH v7 1/3] iio: adc: Cosmic Circuits 10001 ADC driver
@ 2015-01-06 20:47     ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak,
	Phani Movva, Naidu Tellapati, Ezequiel Garcia

From: Phani Movva <Phani.Movva@imgtec.com>

This commit adds support for Cosmic Circuits 10001 10-bit ADC device.

Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
Signed-off-by: Phani Movva <Phani.Movva@imgtec.com>
Signed-off-by: Naidu Tellapati <Naidu.Tellapati@imgtec.com>
[ezequiel: code style cleaning]
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
---
 drivers/iio/adc/Kconfig       |  11 ++
 drivers/iio/adc/Makefile      |   1 +
 drivers/iio/adc/cc10001_adc.c | 423 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 435 insertions(+)
 create mode 100644 drivers/iio/adc/cc10001_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 0f79e47..9cb8543 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -135,6 +135,17 @@ config AXP288_ADC
 	  device. Depending on platform configuration, this general purpose ADC can
 	  be used for sampling sensors such as thermal resistors.
 
+config CC10001_ADC
+	tristate "Cosmic Circuits 10001 ADC driver"
+	depends on HAS_IOMEM || HAVE_CLK || REGULATOR
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to build support for Cosmic Circuits 10001 ADC.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called cc10001_adc.
+
 config EXYNOS_ADC
 	tristate "Exynos ADC driver support"
 	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 701fdb7..ce60fe9 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
+obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1027) += max1027.o
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
new file mode 100644
index 0000000..47f638b
--- /dev/null
+++ b/drivers/iio/adc/cc10001_adc.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2014-2015 Imagination Technologies Ltd.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <linux/iio/buffer.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_buffer.h>
+
+/* Registers */
+#define CC10001_ADC_CONFIG		0x00
+#define CC10001_ADC_START_CONV		BIT(4)
+#define CC10001_ADC_MODE_SINGLE_CONV	BIT(5)
+
+#define CC10001_ADC_DDATA_OUT		0x04
+#define CC10001_ADC_EOC			0x08
+#define CC10001_ADC_EOC_SET		BIT(0)
+
+#define CC10001_ADC_CHSEL_SAMPLED	0x0c
+#define CC10001_ADC_POWER_UP		0x10
+#define CC10001_ADC_POWER_UP_SET	BIT(0)
+#define CC10001_ADC_DEBUG		0x14
+#define CC10001_ADC_DATA_COUNT		0x20
+
+#define CC10001_ADC_DATA_MASK		GENMASK(9, 0)
+#define CC10001_ADC_NUM_CHANNELS	8
+#define CC10001_ADC_CH_MASK		GENMASK(2, 0)
+
+#define CC10001_INVALID_SAMPLED		0xffff
+#define CC10001_MAX_POLL_COUNT		20
+
+/*
+ * As per device specification, wait six clock cycles after power-up to
+ * activate START. Since adding two more clock cycles delay does not
+ * impact the performance too much, we are adding two additional cycles delay
+ * intentionally here.
+ */
+#define	CC10001_WAIT_CYCLES		8
+
+struct cc10001_adc_device {
+	void __iomem *reg_base;
+	struct clk *adc_clk;
+	struct regulator *reg;
+	u16 *buf;
+
+	struct mutex lock;
+	unsigned long channel_map;
+	unsigned int start_delay_ns;
+	unsigned int eoc_delay_ns;
+};
+
+static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
+					 u32 reg, u32 val)
+{
+	writel(val, adc_dev->reg_base + reg);
+}
+
+static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
+				       u32 reg)
+{
+	return readl(adc_dev->reg_base + reg);
+}
+
+static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
+			      unsigned int channel)
+{
+	u32 val;
+
+	/* Channel selection and mode of operation */
+	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+
+	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
+	val = val | CC10001_ADC_START_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+}
+
+static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
+				 unsigned int channel,
+				 unsigned int delay)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int poll_count = 0;
+
+	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
+			CC10001_ADC_EOC_SET)) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	poll_count = 0;
+	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
+			CC10001_ADC_CH_MASK) != channel) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	/* Read the 10 bit output register */
+	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
+			       CC10001_ADC_DATA_MASK;
+}
+
+static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
+{
+	struct cc10001_adc_device *adc_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev;
+	unsigned int delay_ns;
+	unsigned int channel;
+	bool sample_invalid;
+	u16 *data;
+	int i;
+
+	indio_dev = pf->indio_dev;
+	adc_dev = iio_priv(indio_dev);
+	data = adc_dev->buf;
+
+	mutex_lock(&adc_dev->lock);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	i = 0;
+	sample_invalid = false;
+	for_each_set_bit(channel, indio_dev->active_scan_mask,
+				  indio_dev->masklength) {
+
+		cc10001_adc_start(adc_dev, channel);
+
+		data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
+		if (data[i] == CC10001_INVALID_SAMPLED) {
+			dev_warn(&indio_dev->dev,
+				 "invalid sample on channel %d\n", channel);
+			sample_invalid = true;
+			goto done;
+		}
+		i++;
+	}
+
+done:
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	mutex_unlock(&adc_dev->lock);
+
+	if (!sample_invalid)
+		iio_push_to_buffers_with_timestamp(indio_dev, data,
+						   iio_get_time_ns());
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
+					struct iio_chan_spec const *chan)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int delay_ns;
+	u16 val;
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	cc10001_adc_start(adc_dev, chan->channel);
+
+	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	return val;
+}
+
+static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
+				 struct iio_chan_spec const *chan,
+				 int *val, int *val2, long mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+		mutex_lock(&adc_dev->lock);
+		*val = cc10001_adc_read_raw_voltage(indio_dev, chan);
+		mutex_unlock(&adc_dev->lock);
+
+		if (*val == CC10001_INVALID_SAMPLED)
+			return -EIO;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		ret = regulator_get_voltage(adc_dev->reg);
+		if (ret)
+			return ret;
+
+		*val = ret / 1000;
+		*val2 = chan->scan_type.realbits;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
+				    const unsigned long *scan_mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	kfree(adc_dev->buf);
+	adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	if (!adc_dev->buf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const struct iio_info cc10001_adc_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &cc10001_adc_read_raw,
+	.update_scan_mode = &cc10001_update_scan_mode,
+};
+
+static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	struct iio_chan_spec *chan_array, *timestamp;
+	unsigned int bit, idx = 0;
+
+	indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
+						CC10001_ADC_NUM_CHANNELS);
+
+	chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
+				  sizeof(struct iio_chan_spec),
+				  GFP_KERNEL);
+	if (!chan_array)
+		return -ENOMEM;
+
+	for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
+		struct iio_chan_spec *chan = &chan_array[idx];
+
+		chan->type = IIO_VOLTAGE;
+		chan->indexed = 1;
+		chan->channel = bit;
+		chan->scan_index = idx;
+		chan->scan_type.sign = 'u';
+		chan->scan_type.realbits = 10;
+		chan->scan_type.storagebits = 16;
+		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
+		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+		idx++;
+	}
+
+	timestamp = &chan_array[idx];
+	timestamp->type = IIO_TIMESTAMP;
+	timestamp->channel = -1;
+	timestamp->scan_index = idx;
+	timestamp->scan_type.sign = 's';
+	timestamp->scan_type.realbits = 64;
+	timestamp->scan_type.storagebits = 64;
+
+	indio_dev->channels = chan_array;
+
+	return 0;
+}
+
+static int cc10001_adc_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct cc10001_adc_device *adc_dev;
+	unsigned long adc_clk_rate;
+	struct resource *res;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	adc_dev = iio_priv(indio_dev);
+
+	adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
+	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
+		adc_dev->channel_map &= ~ret;
+
+	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
+	if (IS_ERR(adc_dev->reg))
+		return PTR_ERR(adc_dev->reg);
+
+	ret = regulator_enable(adc_dev->reg);
+	if (ret)
+		return ret;
+
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->name = dev_name(&pdev->dev);
+	indio_dev->info = &cc10001_adc_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(adc_dev->reg_base)) {
+		ret = PTR_ERR(adc_dev->reg_base);
+		goto err_disable_reg;
+	}
+
+	adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
+	if (IS_ERR(adc_dev->adc_clk)) {
+		dev_err(&pdev->dev, "failed to get the clock\n");
+		ret = PTR_ERR(adc_dev->adc_clk);
+		goto err_disable_reg;
+	}
+
+	ret = clk_prepare_enable(adc_dev->adc_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable the clock\n");
+		goto err_disable_reg;
+	}
+
+	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
+	if (!adc_clk_rate) {
+		ret = -EINVAL;
+		dev_err(&pdev->dev, "null clock rate!\n");
+		goto err_disable_clk;
+	}
+
+	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
+	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
+
+	/* Setup the ADC channels available on the device */
+	ret = cc10001_adc_channel_init(indio_dev);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	mutex_init(&adc_dev->lock);
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+					 &cc10001_adc_trigger_h, NULL);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto err_cleanup_buffer;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	return 0;
+
+err_cleanup_buffer:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_disable_clk:
+	clk_disable_unprepare(adc_dev->adc_clk);
+err_disable_reg:
+	regulator_disable(adc_dev->reg);
+	return ret;
+}
+
+static int cc10001_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	clk_disable_unprepare(adc_dev->adc_clk);
+	regulator_disable(adc_dev->reg);
+
+	return 0;
+}
+
+static const struct of_device_id cc10001_adc_dt_ids[] = {
+	{ .compatible = "cosmic,10001-adc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
+
+static struct platform_driver cc10001_adc_driver = {
+	.driver = {
+		.name   = "cc10001-adc",
+		.of_match_table = cc10001_adc_dt_ids,
+	},
+	.probe	= cc10001_adc_probe,
+	.remove	= cc10001_adc_remove,
+};
+module_platform_driver(cc10001_adc_driver);
+
+MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>");
+MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.2.1

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

* [PATCH v7 2/3] DT: iio: adc: Add CC_10001 binding documentation
  2015-01-06 20:47 ` Ezequiel Garcia
@ 2015-01-06 20:47     ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, Phani Movva, Naidu Tellapati,
	Ezequiel Garcia

From: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>

Add the devicetree binding document for Cosmic Circuits 10001 ADC device.

Reviewed-by: Andrew Bresticker <abrestic-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Naidu Tellapati <Naidu.Tellapati-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
---
 .../devicetree/bindings/iio/adc/cc10001_adc.txt    | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
new file mode 100644
index 0000000..904f76d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
@@ -0,0 +1,22 @@
+* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC)
+
+Required properties:
+  - compatible: Should be "cosmic,10001-adc"
+  - reg: Should contain adc registers location and length.
+  - clock-names: Should contain "adc".
+  - clocks: Should contain a clock specifier for each entry in clock-names
+  - vref-supply: The regulator supply ADC reference voltage.
+
+Optional properties:
+  - adc-reserved-channels: Bitmask of reserved channels,
+    i.e. channels that cannot be used by the OS.
+
+Example:
+adc: adc@18101600 {
+	compatible = "cosmic,10001-adc";
+	reg = <0x18101600 0x24>;
+	adc-reserved-channels = <0x2>;
+	clocks = <&adc_clk>;
+	clock-names = "adc";
+	vref-supply = <&reg_1v8>;
+};
-- 
2.2.1

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

* [PATCH v7 2/3] DT: iio: adc: Add CC_10001 binding documentation
@ 2015-01-06 20:47     ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak,
	Phani Movva, Naidu Tellapati, Ezequiel Garcia

From: Phani Movva <Phani.Movva@imgtec.com>

Add the devicetree binding document for Cosmic Circuits 10001 ADC device.

Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Phani Movva <Phani.Movva@imgtec.com>
Signed-off-by: Naidu Tellapati <Naidu.Tellapati@imgtec.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
---
 .../devicetree/bindings/iio/adc/cc10001_adc.txt    | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
new file mode 100644
index 0000000..904f76d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
@@ -0,0 +1,22 @@
+* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC)
+
+Required properties:
+  - compatible: Should be "cosmic,10001-adc"
+  - reg: Should contain adc registers location and length.
+  - clock-names: Should contain "adc".
+  - clocks: Should contain a clock specifier for each entry in clock-names
+  - vref-supply: The regulator supply ADC reference voltage.
+
+Optional properties:
+  - adc-reserved-channels: Bitmask of reserved channels,
+    i.e. channels that cannot be used by the OS.
+
+Example:
+adc: adc@18101600 {
+	compatible = "cosmic,10001-adc";
+	reg = <0x18101600 0x24>;
+	adc-reserved-channels = <0x2>;
+	clocks = <&adc_clk>;
+	clock-names = "adc";
+	vref-supply = <&reg_1v8>;
+};
-- 
2.2.1

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

* [PATCH v7 3/3] DT: Add a vendor prefix for Cosmic Circuits
  2015-01-06 20:47 ` Ezequiel Garcia
@ 2015-01-06 20:47     ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, Ezequiel Garcia

Reviewed-by: Andrew Bresticker <abrestic-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
---
 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 b1df0ad..014770f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -36,6 +36,7 @@ chunghwa	Chunghwa Picture Tubes Ltd.
 cirrus	Cirrus Logic, Inc.
 cnm	Chips&Media, Inc.
 cortina	Cortina Systems, Inc.
+cosmic	Cosmic Circuits
 crystalfontz	Crystalfontz America, Inc.
 dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom	DAVICOM Semiconductor, Inc.
-- 
2.2.1

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

* [PATCH v7 3/3] DT: Add a vendor prefix for Cosmic Circuits
@ 2015-01-06 20:47     ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-06 20:47 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak,
	Ezequiel Garcia

Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
---
 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 b1df0ad..014770f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -36,6 +36,7 @@ chunghwa	Chunghwa Picture Tubes Ltd.
 cirrus	Cirrus Logic, Inc.
 cnm	Chips&Media, Inc.
 cortina	Cortina Systems, Inc.
+cosmic	Cosmic Circuits
 crystalfontz	Crystalfontz America, Inc.
 dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom	DAVICOM Semiconductor, Inc.
-- 
2.2.1

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-06 20:47 ` Ezequiel Garcia
@ 2015-01-10 14:15     ` Jonathan Cameron
  -1 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-10 14:15 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ

On 06/01/15 20:47, Ezequiel Garcia wrote:
> This series add the support for an ADC IP block from Cosmic Circuits.
> The patchset is based on v3.19-rc3.
> 
> As agreed with Rob, this series drops the vendor prefix in the
> adc-reserved-channels DT property. This property is generic enough to
> be used in other drivers (at91 is a potential candidate).
> 
> A follow-up patch can use the property in at91 and add it to the
> IIO generic bindings.
I'm happy - will let this sit for a little while to let Harmut say
if wants to take another look (or give a reviewed-by or similar).

Thanks all,

Jonathan
> 
> Changes from v6:
> 
>   * Dropped the vendor prefix in the adc-reserved-channels property,
>     as suggested by Rob.
>   * Added Andrew's Reviewed-by tags. Andrew reviewed v3, and the driver
>     changed little since then.
>     http://www.spinics.net/lists/linux-iio/msg15630.html.
> 
> Changes from v5:
> 
>   * Fixed CC10001_ADC_CH_MASK macro definition, to separate the channel
>     number from the channel map, as noted by Hartmut.
>   * Return the real error code in devm_regulator_get failure.
> 
> Changes from v4:
> 
>   * Added a compile-time dependency on REGULATOR and HAVE_CLK.
>   * Replaced the silly XOR operation for a proper mask out of the
>     available channels.
> 
> Changes from v3:
> 
>   * Fixed a few style nitpicks as per Hartmut's feedback.
>   * Used GENMASK() to build the channel mask, which fixes a very nasty
>     bug. Also found by Hartmut.
> 
> Changes from v2:
> 
>   * Changed a devicetree property from adc-available-channels to
>     adc-reserved-channels, so it can be made optional.
>   * Renamed the driver from cc_10001_xxx to cc10001_xxx so it's consistent
>     with the rest of the kernel style.
>   * Some more minor cosmetic fixes.
> 
> Changes from v1:
> 
>   * Removed unneeded header includes.
>   * Changed all the names and macros prefix: s/CC_10001_/CC10001_.
>   * Used .update_scan_mode callback to preallocate the buffer.
>   * Used indio_dev for the struct iio_dev.
>   * Only read the regulator voltage when needed.
>   * Fixed probe() error handling.
>   * Used for_each_set_bit() instead of open-coding it.
>   * Name the power-down register as _POWER_UP, to make the code
>     less silly.
>   * Error out when no valid sample can be read (i.e. when end-of-conversion
>     poll times out).
>   * ... plus some assorted code cleaning based on the feedback.
> 
> Ezequiel Garcia (1):
>   DT: Add a vendor prefix for Cosmic Circuits
> 
> Phani Movva (2):
>   iio: adc: Cosmic Circuits 10001 ADC driver
>   DT: iio: adc: Add CC_10001 binding documentation
> 
>  .../devicetree/bindings/iio/adc/cc10001_adc.txt    |  22 ++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  drivers/iio/adc/Kconfig                            |  11 +
>  drivers/iio/adc/Makefile                           |   1 +
>  drivers/iio/adc/cc10001_adc.c                      | 423 +++++++++++++++++++++
>  5 files changed, 458 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
>  create mode 100644 drivers/iio/adc/cc10001_adc.c
> 

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-10 14:15     ` Jonathan Cameron
  0 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-10 14:15 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak

On 06/01/15 20:47, Ezequiel Garcia wrote:
> This series add the support for an ADC IP block from Cosmic Circuits.
> The patchset is based on v3.19-rc3.
> 
> As agreed with Rob, this series drops the vendor prefix in the
> adc-reserved-channels DT property. This property is generic enough to
> be used in other drivers (at91 is a potential candidate).
> 
> A follow-up patch can use the property in at91 and add it to the
> IIO generic bindings.
I'm happy - will let this sit for a little while to let Harmut say
if wants to take another look (or give a reviewed-by or similar).

Thanks all,

Jonathan
> 
> Changes from v6:
> 
>   * Dropped the vendor prefix in the adc-reserved-channels property,
>     as suggested by Rob.
>   * Added Andrew's Reviewed-by tags. Andrew reviewed v3, and the driver
>     changed little since then.
>     http://www.spinics.net/lists/linux-iio/msg15630.html.
> 
> Changes from v5:
> 
>   * Fixed CC10001_ADC_CH_MASK macro definition, to separate the channel
>     number from the channel map, as noted by Hartmut.
>   * Return the real error code in devm_regulator_get failure.
> 
> Changes from v4:
> 
>   * Added a compile-time dependency on REGULATOR and HAVE_CLK.
>   * Replaced the silly XOR operation for a proper mask out of the
>     available channels.
> 
> Changes from v3:
> 
>   * Fixed a few style nitpicks as per Hartmut's feedback.
>   * Used GENMASK() to build the channel mask, which fixes a very nasty
>     bug. Also found by Hartmut.
> 
> Changes from v2:
> 
>   * Changed a devicetree property from adc-available-channels to
>     adc-reserved-channels, so it can be made optional.
>   * Renamed the driver from cc_10001_xxx to cc10001_xxx so it's consistent
>     with the rest of the kernel style.
>   * Some more minor cosmetic fixes.
> 
> Changes from v1:
> 
>   * Removed unneeded header includes.
>   * Changed all the names and macros prefix: s/CC_10001_/CC10001_.
>   * Used .update_scan_mode callback to preallocate the buffer.
>   * Used indio_dev for the struct iio_dev.
>   * Only read the regulator voltage when needed.
>   * Fixed probe() error handling.
>   * Used for_each_set_bit() instead of open-coding it.
>   * Name the power-down register as _POWER_UP, to make the code
>     less silly.
>   * Error out when no valid sample can be read (i.e. when end-of-conversion
>     poll times out).
>   * ... plus some assorted code cleaning based on the feedback.
> 
> Ezequiel Garcia (1):
>   DT: Add a vendor prefix for Cosmic Circuits
> 
> Phani Movva (2):
>   iio: adc: Cosmic Circuits 10001 ADC driver
>   DT: iio: adc: Add CC_10001 binding documentation
> 
>  .../devicetree/bindings/iio/adc/cc10001_adc.txt    |  22 ++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  drivers/iio/adc/Kconfig                            |  11 +
>  drivers/iio/adc/Makefile                           |   1 +
>  drivers/iio/adc/cc10001_adc.c                      | 423 +++++++++++++++++++++
>  5 files changed, 458 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
>  create mode 100644 drivers/iio/adc/cc10001_adc.c
> 


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

* Re: [PATCH v7 1/3] iio: adc: Cosmic Circuits 10001 ADC driver
  2015-01-06 20:47     ` Ezequiel Garcia
@ 2015-01-10 20:22         ` Hartmut Knaack
  -1 siblings, 0 replies; 24+ messages in thread
From: Hartmut Knaack @ 2015-01-10 20:22 UTC (permalink / raw)
  To: Ezequiel Garcia, Jonathan Cameron, James Hartley,
	Andrew Bresticker, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Mark.Rutland-5wv7dgnIgG8
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, Phani Movva, Naidu Tellapati

Ezequiel Garcia schrieb am 06.01.2015 um 21:47:
> From: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> 
> This commit adds support for Cosmic Circuits 10001 10-bit ADC device.
> 
> Reviewed-by: Andrew Bresticker <abrestic-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> Signed-off-by: Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Naidu Tellapati <Naidu.Tellapati-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> [ezequiel: code style cleaning]
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Acked-by: Hartmut Knaack <knaack.h-Mmb7MZpHnFY@public.gmane.org>
> ---
>  drivers/iio/adc/Kconfig       |  11 ++
>  drivers/iio/adc/Makefile      |   1 +
>  drivers/iio/adc/cc10001_adc.c | 423 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 435 insertions(+)
>  create mode 100644 drivers/iio/adc/cc10001_adc.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 0f79e47..9cb8543 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -135,6 +135,17 @@ config AXP288_ADC
>  	  device. Depending on platform configuration, this general purpose ADC can
>  	  be used for sampling sensors such as thermal resistors.
>  
> +config CC10001_ADC
> +	tristate "Cosmic Circuits 10001 ADC driver"
> +	depends on HAS_IOMEM || HAVE_CLK || REGULATOR
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	help
> +	  Say yes here to build support for Cosmic Circuits 10001 ADC.
> +
> +	  This driver can also be built as a module. If so, the module will be
> +	  called cc10001_adc.
> +
>  config EXYNOS_ADC
>  	tristate "Exynos ADC driver support"
>  	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 701fdb7..ce60fe9 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
>  obj-$(CONFIG_AD799X) += ad799x.o
>  obj-$(CONFIG_AT91_ADC) += at91_adc.o
>  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
> +obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
>  obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
>  obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
>  obj-$(CONFIG_MAX1027) += max1027.o
> diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
> new file mode 100644
> index 0000000..47f638b
> --- /dev/null
> +++ b/drivers/iio/adc/cc10001_adc.c
> @@ -0,0 +1,423 @@
> +/*
> + * Copyright (c) 2014-2015 Imagination Technologies Ltd.
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +
> +#include <linux/iio/buffer.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_buffer.h>
> +
> +/* Registers */
> +#define CC10001_ADC_CONFIG		0x00
> +#define CC10001_ADC_START_CONV		BIT(4)
> +#define CC10001_ADC_MODE_SINGLE_CONV	BIT(5)
> +
> +#define CC10001_ADC_DDATA_OUT		0x04
> +#define CC10001_ADC_EOC			0x08
> +#define CC10001_ADC_EOC_SET		BIT(0)
> +
> +#define CC10001_ADC_CHSEL_SAMPLED	0x0c
> +#define CC10001_ADC_POWER_UP		0x10
> +#define CC10001_ADC_POWER_UP_SET	BIT(0)
> +#define CC10001_ADC_DEBUG		0x14
> +#define CC10001_ADC_DATA_COUNT		0x20
> +
> +#define CC10001_ADC_DATA_MASK		GENMASK(9, 0)
> +#define CC10001_ADC_NUM_CHANNELS	8
> +#define CC10001_ADC_CH_MASK		GENMASK(2, 0)
> +
> +#define CC10001_INVALID_SAMPLED		0xffff
> +#define CC10001_MAX_POLL_COUNT		20
> +
> +/*
> + * As per device specification, wait six clock cycles after power-up to
> + * activate START. Since adding two more clock cycles delay does not
> + * impact the performance too much, we are adding two additional cycles delay
> + * intentionally here.
> + */
> +#define	CC10001_WAIT_CYCLES		8
> +
> +struct cc10001_adc_device {
> +	void __iomem *reg_base;
> +	struct clk *adc_clk;
> +	struct regulator *reg;
> +	u16 *buf;
> +
> +	struct mutex lock;
> +	unsigned long channel_map;
> +	unsigned int start_delay_ns;
> +	unsigned int eoc_delay_ns;
> +};
> +
> +static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
> +					 u32 reg, u32 val)
> +{
> +	writel(val, adc_dev->reg_base + reg);
> +}
> +
> +static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
> +				       u32 reg)
> +{
> +	return readl(adc_dev->reg_base + reg);
> +}
> +
> +static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
> +			      unsigned int channel)
> +{
> +	u32 val;
> +
> +	/* Channel selection and mode of operation */
> +	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
> +
> +	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
> +	val = val | CC10001_ADC_START_CONV;
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
> +}
> +
> +static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
> +				 unsigned int channel,
> +				 unsigned int delay)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	unsigned int poll_count = 0;
> +
> +	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
> +			CC10001_ADC_EOC_SET)) {
> +
> +		ndelay(delay);
> +		if (poll_count++ == CC10001_MAX_POLL_COUNT)
> +			return CC10001_INVALID_SAMPLED;
> +	}
> +
> +	poll_count = 0;
> +	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
> +			CC10001_ADC_CH_MASK) != channel) {
> +
> +		ndelay(delay);
> +		if (poll_count++ == CC10001_MAX_POLL_COUNT)
> +			return CC10001_INVALID_SAMPLED;
> +	}
> +
> +	/* Read the 10 bit output register */
> +	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
> +			       CC10001_ADC_DATA_MASK;
> +}
> +
> +static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
> +{
> +	struct cc10001_adc_device *adc_dev;
> +	struct iio_poll_func *pf = p;
> +	struct iio_dev *indio_dev;
> +	unsigned int delay_ns;
> +	unsigned int channel;
> +	bool sample_invalid;
> +	u16 *data;
> +	int i;
> +
> +	indio_dev = pf->indio_dev;
> +	adc_dev = iio_priv(indio_dev);
> +	data = adc_dev->buf;
> +
> +	mutex_lock(&adc_dev->lock);
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
> +			      CC10001_ADC_POWER_UP_SET);
> +
> +	/* Wait for 8 (6+2) clock cycles before activating START */
> +	ndelay(adc_dev->start_delay_ns);
> +
> +	/* Calculate delay step for eoc and sampled data */
> +	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
> +
> +	i = 0;
> +	sample_invalid = false;
> +	for_each_set_bit(channel, indio_dev->active_scan_mask,
> +				  indio_dev->masklength) {
> +
> +		cc10001_adc_start(adc_dev, channel);
> +
> +		data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
> +		if (data[i] == CC10001_INVALID_SAMPLED) {
> +			dev_warn(&indio_dev->dev,
> +				 "invalid sample on channel %d\n", channel);
> +			sample_invalid = true;
> +			goto done;
> +		}
> +		i++;
> +	}
> +
> +done:
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
> +
> +	mutex_unlock(&adc_dev->lock);
> +
> +	if (!sample_invalid)
> +		iio_push_to_buffers_with_timestamp(indio_dev, data,
> +						   iio_get_time_ns());
> +	iio_trigger_notify_done(indio_dev->trig);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
> +					struct iio_chan_spec const *chan)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	unsigned int delay_ns;
> +	u16 val;
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
> +			      CC10001_ADC_POWER_UP_SET);
> +
> +	/* Wait for 8 (6+2) clock cycles before activating START */
> +	ndelay(adc_dev->start_delay_ns);
> +
> +	/* Calculate delay step for eoc and sampled data */
> +	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
> +
> +	cc10001_adc_start(adc_dev, chan->channel);
> +
> +	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
> +
> +	return val;
> +}
> +
> +static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
> +				 struct iio_chan_spec const *chan,
> +				 int *val, int *val2, long mask)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		if (iio_buffer_enabled(indio_dev))
> +			return -EBUSY;
> +		mutex_lock(&adc_dev->lock);
> +		*val = cc10001_adc_read_raw_voltage(indio_dev, chan);
> +		mutex_unlock(&adc_dev->lock);
> +
> +		if (*val == CC10001_INVALID_SAMPLED)
> +			return -EIO;
> +		return IIO_VAL_INT;
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		ret = regulator_get_voltage(adc_dev->reg);
> +		if (ret)
> +			return ret;
> +
> +		*val = ret / 1000;
> +		*val2 = chan->scan_type.realbits;
> +		return IIO_VAL_FRACTIONAL_LOG2;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
> +				    const unsigned long *scan_mask)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +
> +	kfree(adc_dev->buf);
> +	adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
> +	if (!adc_dev->buf)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const struct iio_info cc10001_adc_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = &cc10001_adc_read_raw,
> +	.update_scan_mode = &cc10001_update_scan_mode,
> +};
> +
> +static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	struct iio_chan_spec *chan_array, *timestamp;
> +	unsigned int bit, idx = 0;
> +
> +	indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
> +						CC10001_ADC_NUM_CHANNELS);
> +
> +	chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
> +				  sizeof(struct iio_chan_spec),
> +				  GFP_KERNEL);
> +	if (!chan_array)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
> +		struct iio_chan_spec *chan = &chan_array[idx];
> +
> +		chan->type = IIO_VOLTAGE;
> +		chan->indexed = 1;
> +		chan->channel = bit;
> +		chan->scan_index = idx;
> +		chan->scan_type.sign = 'u';
> +		chan->scan_type.realbits = 10;
> +		chan->scan_type.storagebits = 16;
> +		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
> +		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
> +		idx++;
> +	}
> +
> +	timestamp = &chan_array[idx];
> +	timestamp->type = IIO_TIMESTAMP;
> +	timestamp->channel = -1;
> +	timestamp->scan_index = idx;
> +	timestamp->scan_type.sign = 's';
> +	timestamp->scan_type.realbits = 64;
> +	timestamp->scan_type.storagebits = 64;
> +
> +	indio_dev->channels = chan_array;
> +
> +	return 0;
> +}
> +
> +static int cc10001_adc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct cc10001_adc_device *adc_dev;
> +	unsigned long adc_clk_rate;
> +	struct resource *res;
> +	struct iio_dev *indio_dev;
> +	int ret;
> +
> +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
> +	if (indio_dev == NULL)
> +		return -ENOMEM;
> +
> +	adc_dev = iio_priv(indio_dev);
> +
> +	adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
> +	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
> +		adc_dev->channel_map &= ~ret;
> +
> +	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
> +	if (IS_ERR(adc_dev->reg))
> +		return PTR_ERR(adc_dev->reg);
> +
> +	ret = regulator_enable(adc_dev->reg);
> +	if (ret)
> +		return ret;
> +
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->name = dev_name(&pdev->dev);
> +	indio_dev->info = &cc10001_adc_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(adc_dev->reg_base)) {
> +		ret = PTR_ERR(adc_dev->reg_base);
> +		goto err_disable_reg;
> +	}
> +
> +	adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
> +	if (IS_ERR(adc_dev->adc_clk)) {
> +		dev_err(&pdev->dev, "failed to get the clock\n");
> +		ret = PTR_ERR(adc_dev->adc_clk);
> +		goto err_disable_reg;
> +	}
> +
> +	ret = clk_prepare_enable(adc_dev->adc_clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to enable the clock\n");
> +		goto err_disable_reg;
> +	}
> +
> +	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
> +	if (!adc_clk_rate) {
> +		ret = -EINVAL;
> +		dev_err(&pdev->dev, "null clock rate!\n");
> +		goto err_disable_clk;
> +	}
> +
> +	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
> +	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
> +
> +	/* Setup the ADC channels available on the device */
> +	ret = cc10001_adc_channel_init(indio_dev);
> +	if (ret < 0)
> +		goto err_disable_clk;
> +
> +	mutex_init(&adc_dev->lock);
> +
> +	ret = iio_triggered_buffer_setup(indio_dev, NULL,
> +					 &cc10001_adc_trigger_h, NULL);
> +	if (ret < 0)
> +		goto err_disable_clk;
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret < 0)
> +		goto err_cleanup_buffer;
> +
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	return 0;
> +
> +err_cleanup_buffer:
> +	iio_triggered_buffer_cleanup(indio_dev);
> +err_disable_clk:
> +	clk_disable_unprepare(adc_dev->adc_clk);
> +err_disable_reg:
> +	regulator_disable(adc_dev->reg);
> +	return ret;
> +}
> +
> +static int cc10001_adc_remove(struct platform_device *pdev)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +
> +	iio_device_unregister(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
> +	clk_disable_unprepare(adc_dev->adc_clk);
> +	regulator_disable(adc_dev->reg);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id cc10001_adc_dt_ids[] = {
> +	{ .compatible = "cosmic,10001-adc", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
> +
> +static struct platform_driver cc10001_adc_driver = {
> +	.driver = {
> +		.name   = "cc10001-adc",
> +		.of_match_table = cc10001_adc_dt_ids,
> +	},
> +	.probe	= cc10001_adc_probe,
> +	.remove	= cc10001_adc_remove,
> +};
> +module_platform_driver(cc10001_adc_driver);
> +
> +MODULE_AUTHOR("Phani Movva <Phani.Movva-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>");
> +MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
> +MODULE_LICENSE("GPL v2");
> 

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

* Re: [PATCH v7 1/3] iio: adc: Cosmic Circuits 10001 ADC driver
@ 2015-01-10 20:22         ` Hartmut Knaack
  0 siblings, 0 replies; 24+ messages in thread
From: Hartmut Knaack @ 2015-01-10 20:22 UTC (permalink / raw)
  To: Ezequiel Garcia, Jonathan Cameron, James Hartley,
	Andrew Bresticker, robh+dt, Mark.Rutland
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak,
	Phani Movva, Naidu Tellapati

Ezequiel Garcia schrieb am 06.01.2015 um 21:47:
> From: Phani Movva <Phani.Movva@imgtec.com>
> 
> This commit adds support for Cosmic Circuits 10001 10-bit ADC device.
> 
> Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
> Signed-off-by: Phani Movva <Phani.Movva@imgtec.com>
> Signed-off-by: Naidu Tellapati <Naidu.Tellapati@imgtec.com>
> [ezequiel: code style cleaning]
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
Acked-by: Hartmut Knaack <knaack.h@gmx.de>
> ---
>  drivers/iio/adc/Kconfig       |  11 ++
>  drivers/iio/adc/Makefile      |   1 +
>  drivers/iio/adc/cc10001_adc.c | 423 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 435 insertions(+)
>  create mode 100644 drivers/iio/adc/cc10001_adc.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 0f79e47..9cb8543 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -135,6 +135,17 @@ config AXP288_ADC
>  	  device. Depending on platform configuration, this general purpose ADC can
>  	  be used for sampling sensors such as thermal resistors.
>  
> +config CC10001_ADC
> +	tristate "Cosmic Circuits 10001 ADC driver"
> +	depends on HAS_IOMEM || HAVE_CLK || REGULATOR
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	help
> +	  Say yes here to build support for Cosmic Circuits 10001 ADC.
> +
> +	  This driver can also be built as a module. If so, the module will be
> +	  called cc10001_adc.
> +
>  config EXYNOS_ADC
>  	tristate "Exynos ADC driver support"
>  	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 701fdb7..ce60fe9 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
>  obj-$(CONFIG_AD799X) += ad799x.o
>  obj-$(CONFIG_AT91_ADC) += at91_adc.o
>  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
> +obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
>  obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
>  obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
>  obj-$(CONFIG_MAX1027) += max1027.o
> diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
> new file mode 100644
> index 0000000..47f638b
> --- /dev/null
> +++ b/drivers/iio/adc/cc10001_adc.c
> @@ -0,0 +1,423 @@
> +/*
> + * Copyright (c) 2014-2015 Imagination Technologies Ltd.
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +
> +#include <linux/iio/buffer.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_buffer.h>
> +
> +/* Registers */
> +#define CC10001_ADC_CONFIG		0x00
> +#define CC10001_ADC_START_CONV		BIT(4)
> +#define CC10001_ADC_MODE_SINGLE_CONV	BIT(5)
> +
> +#define CC10001_ADC_DDATA_OUT		0x04
> +#define CC10001_ADC_EOC			0x08
> +#define CC10001_ADC_EOC_SET		BIT(0)
> +
> +#define CC10001_ADC_CHSEL_SAMPLED	0x0c
> +#define CC10001_ADC_POWER_UP		0x10
> +#define CC10001_ADC_POWER_UP_SET	BIT(0)
> +#define CC10001_ADC_DEBUG		0x14
> +#define CC10001_ADC_DATA_COUNT		0x20
> +
> +#define CC10001_ADC_DATA_MASK		GENMASK(9, 0)
> +#define CC10001_ADC_NUM_CHANNELS	8
> +#define CC10001_ADC_CH_MASK		GENMASK(2, 0)
> +
> +#define CC10001_INVALID_SAMPLED		0xffff
> +#define CC10001_MAX_POLL_COUNT		20
> +
> +/*
> + * As per device specification, wait six clock cycles after power-up to
> + * activate START. Since adding two more clock cycles delay does not
> + * impact the performance too much, we are adding two additional cycles delay
> + * intentionally here.
> + */
> +#define	CC10001_WAIT_CYCLES		8
> +
> +struct cc10001_adc_device {
> +	void __iomem *reg_base;
> +	struct clk *adc_clk;
> +	struct regulator *reg;
> +	u16 *buf;
> +
> +	struct mutex lock;
> +	unsigned long channel_map;
> +	unsigned int start_delay_ns;
> +	unsigned int eoc_delay_ns;
> +};
> +
> +static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
> +					 u32 reg, u32 val)
> +{
> +	writel(val, adc_dev->reg_base + reg);
> +}
> +
> +static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
> +				       u32 reg)
> +{
> +	return readl(adc_dev->reg_base + reg);
> +}
> +
> +static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
> +			      unsigned int channel)
> +{
> +	u32 val;
> +
> +	/* Channel selection and mode of operation */
> +	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
> +
> +	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
> +	val = val | CC10001_ADC_START_CONV;
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
> +}
> +
> +static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
> +				 unsigned int channel,
> +				 unsigned int delay)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	unsigned int poll_count = 0;
> +
> +	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
> +			CC10001_ADC_EOC_SET)) {
> +
> +		ndelay(delay);
> +		if (poll_count++ == CC10001_MAX_POLL_COUNT)
> +			return CC10001_INVALID_SAMPLED;
> +	}
> +
> +	poll_count = 0;
> +	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
> +			CC10001_ADC_CH_MASK) != channel) {
> +
> +		ndelay(delay);
> +		if (poll_count++ == CC10001_MAX_POLL_COUNT)
> +			return CC10001_INVALID_SAMPLED;
> +	}
> +
> +	/* Read the 10 bit output register */
> +	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
> +			       CC10001_ADC_DATA_MASK;
> +}
> +
> +static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
> +{
> +	struct cc10001_adc_device *adc_dev;
> +	struct iio_poll_func *pf = p;
> +	struct iio_dev *indio_dev;
> +	unsigned int delay_ns;
> +	unsigned int channel;
> +	bool sample_invalid;
> +	u16 *data;
> +	int i;
> +
> +	indio_dev = pf->indio_dev;
> +	adc_dev = iio_priv(indio_dev);
> +	data = adc_dev->buf;
> +
> +	mutex_lock(&adc_dev->lock);
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
> +			      CC10001_ADC_POWER_UP_SET);
> +
> +	/* Wait for 8 (6+2) clock cycles before activating START */
> +	ndelay(adc_dev->start_delay_ns);
> +
> +	/* Calculate delay step for eoc and sampled data */
> +	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
> +
> +	i = 0;
> +	sample_invalid = false;
> +	for_each_set_bit(channel, indio_dev->active_scan_mask,
> +				  indio_dev->masklength) {
> +
> +		cc10001_adc_start(adc_dev, channel);
> +
> +		data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
> +		if (data[i] == CC10001_INVALID_SAMPLED) {
> +			dev_warn(&indio_dev->dev,
> +				 "invalid sample on channel %d\n", channel);
> +			sample_invalid = true;
> +			goto done;
> +		}
> +		i++;
> +	}
> +
> +done:
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
> +
> +	mutex_unlock(&adc_dev->lock);
> +
> +	if (!sample_invalid)
> +		iio_push_to_buffers_with_timestamp(indio_dev, data,
> +						   iio_get_time_ns());
> +	iio_trigger_notify_done(indio_dev->trig);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
> +					struct iio_chan_spec const *chan)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	unsigned int delay_ns;
> +	u16 val;
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
> +			      CC10001_ADC_POWER_UP_SET);
> +
> +	/* Wait for 8 (6+2) clock cycles before activating START */
> +	ndelay(adc_dev->start_delay_ns);
> +
> +	/* Calculate delay step for eoc and sampled data */
> +	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
> +
> +	cc10001_adc_start(adc_dev, chan->channel);
> +
> +	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
> +
> +	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
> +
> +	return val;
> +}
> +
> +static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
> +				 struct iio_chan_spec const *chan,
> +				 int *val, int *val2, long mask)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		if (iio_buffer_enabled(indio_dev))
> +			return -EBUSY;
> +		mutex_lock(&adc_dev->lock);
> +		*val = cc10001_adc_read_raw_voltage(indio_dev, chan);
> +		mutex_unlock(&adc_dev->lock);
> +
> +		if (*val == CC10001_INVALID_SAMPLED)
> +			return -EIO;
> +		return IIO_VAL_INT;
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		ret = regulator_get_voltage(adc_dev->reg);
> +		if (ret)
> +			return ret;
> +
> +		*val = ret / 1000;
> +		*val2 = chan->scan_type.realbits;
> +		return IIO_VAL_FRACTIONAL_LOG2;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
> +				    const unsigned long *scan_mask)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +
> +	kfree(adc_dev->buf);
> +	adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
> +	if (!adc_dev->buf)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const struct iio_info cc10001_adc_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = &cc10001_adc_read_raw,
> +	.update_scan_mode = &cc10001_update_scan_mode,
> +};
> +
> +static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
> +{
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +	struct iio_chan_spec *chan_array, *timestamp;
> +	unsigned int bit, idx = 0;
> +
> +	indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
> +						CC10001_ADC_NUM_CHANNELS);
> +
> +	chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
> +				  sizeof(struct iio_chan_spec),
> +				  GFP_KERNEL);
> +	if (!chan_array)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
> +		struct iio_chan_spec *chan = &chan_array[idx];
> +
> +		chan->type = IIO_VOLTAGE;
> +		chan->indexed = 1;
> +		chan->channel = bit;
> +		chan->scan_index = idx;
> +		chan->scan_type.sign = 'u';
> +		chan->scan_type.realbits = 10;
> +		chan->scan_type.storagebits = 16;
> +		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
> +		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
> +		idx++;
> +	}
> +
> +	timestamp = &chan_array[idx];
> +	timestamp->type = IIO_TIMESTAMP;
> +	timestamp->channel = -1;
> +	timestamp->scan_index = idx;
> +	timestamp->scan_type.sign = 's';
> +	timestamp->scan_type.realbits = 64;
> +	timestamp->scan_type.storagebits = 64;
> +
> +	indio_dev->channels = chan_array;
> +
> +	return 0;
> +}
> +
> +static int cc10001_adc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct cc10001_adc_device *adc_dev;
> +	unsigned long adc_clk_rate;
> +	struct resource *res;
> +	struct iio_dev *indio_dev;
> +	int ret;
> +
> +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
> +	if (indio_dev == NULL)
> +		return -ENOMEM;
> +
> +	adc_dev = iio_priv(indio_dev);
> +
> +	adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
> +	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
> +		adc_dev->channel_map &= ~ret;
> +
> +	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
> +	if (IS_ERR(adc_dev->reg))
> +		return PTR_ERR(adc_dev->reg);
> +
> +	ret = regulator_enable(adc_dev->reg);
> +	if (ret)
> +		return ret;
> +
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->name = dev_name(&pdev->dev);
> +	indio_dev->info = &cc10001_adc_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(adc_dev->reg_base)) {
> +		ret = PTR_ERR(adc_dev->reg_base);
> +		goto err_disable_reg;
> +	}
> +
> +	adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
> +	if (IS_ERR(adc_dev->adc_clk)) {
> +		dev_err(&pdev->dev, "failed to get the clock\n");
> +		ret = PTR_ERR(adc_dev->adc_clk);
> +		goto err_disable_reg;
> +	}
> +
> +	ret = clk_prepare_enable(adc_dev->adc_clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to enable the clock\n");
> +		goto err_disable_reg;
> +	}
> +
> +	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
> +	if (!adc_clk_rate) {
> +		ret = -EINVAL;
> +		dev_err(&pdev->dev, "null clock rate!\n");
> +		goto err_disable_clk;
> +	}
> +
> +	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
> +	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
> +
> +	/* Setup the ADC channels available on the device */
> +	ret = cc10001_adc_channel_init(indio_dev);
> +	if (ret < 0)
> +		goto err_disable_clk;
> +
> +	mutex_init(&adc_dev->lock);
> +
> +	ret = iio_triggered_buffer_setup(indio_dev, NULL,
> +					 &cc10001_adc_trigger_h, NULL);
> +	if (ret < 0)
> +		goto err_disable_clk;
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret < 0)
> +		goto err_cleanup_buffer;
> +
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	return 0;
> +
> +err_cleanup_buffer:
> +	iio_triggered_buffer_cleanup(indio_dev);
> +err_disable_clk:
> +	clk_disable_unprepare(adc_dev->adc_clk);
> +err_disable_reg:
> +	regulator_disable(adc_dev->reg);
> +	return ret;
> +}
> +
> +static int cc10001_adc_remove(struct platform_device *pdev)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
> +
> +	iio_device_unregister(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
> +	clk_disable_unprepare(adc_dev->adc_clk);
> +	regulator_disable(adc_dev->reg);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id cc10001_adc_dt_ids[] = {
> +	{ .compatible = "cosmic,10001-adc", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
> +
> +static struct platform_driver cc10001_adc_driver = {
> +	.driver = {
> +		.name   = "cc10001-adc",
> +		.of_match_table = cc10001_adc_dt_ids,
> +	},
> +	.probe	= cc10001_adc_probe,
> +	.remove	= cc10001_adc_remove,
> +};
> +module_platform_driver(cc10001_adc_driver);
> +
> +MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>");
> +MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
> +MODULE_LICENSE("GPL v2");
> 


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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-10 14:15     ` Jonathan Cameron
@ 2015-01-20 10:54         ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-20 10:54 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ



On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
> On 06/01/15 20:47, Ezequiel Garcia wrote:
>> This series add the support for an ADC IP block from Cosmic Circuits.
>> The patchset is based on v3.19-rc3.
>>
>> As agreed with Rob, this series drops the vendor prefix in the
>> adc-reserved-channels DT property. This property is generic enough to
>> be used in other drivers (at91 is a potential candidate).
>>
>> A follow-up patch can use the property in at91 and add it to the
>> IIO generic bindings.
> I'm happy - will let this sit for a little while to let Harmut say
> if wants to take another look (or give a reviewed-by or similar).
> 

Hi Jonathan,

As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
than later, so we don't miss next window.

Thanks a lot!
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-20 10:54         ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-20 10:54 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak



On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
> On 06/01/15 20:47, Ezequiel Garcia wrote:
>> This series add the support for an ADC IP block from Cosmic Circuits.
>> The patchset is based on v3.19-rc3.
>>
>> As agreed with Rob, this series drops the vendor prefix in the
>> adc-reserved-channels DT property. This property is generic enough to
>> be used in other drivers (at91 is a potential candidate).
>>
>> A follow-up patch can use the property in at91 and add it to the
>> IIO generic bindings.
> I'm happy - will let this sit for a little while to let Harmut say
> if wants to take another look (or give a reviewed-by or similar).
> 

Hi Jonathan,

As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
than later, so we don't miss next window.

Thanks a lot!
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-20 20:37             ` Jonathan Cameron
@ 2015-01-20 20:36                 ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-20 20:36 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ



On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
> On 20/01/15 10:54, Ezequiel Garcia wrote:
>>
>>
>> On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
>>> On 06/01/15 20:47, Ezequiel Garcia wrote:
>>>> This series add the support for an ADC IP block from Cosmic Circuits.
>>>> The patchset is based on v3.19-rc3.
>>>>
>>>> As agreed with Rob, this series drops the vendor prefix in the
>>>> adc-reserved-channels DT property. This property is generic enough to
>>>> be used in other drivers (at91 is a potential candidate).
>>>>
>>>> A follow-up patch can use the property in at91 and add it to the
>>>> IIO generic bindings.
>>> I'm happy - will let this sit for a little while to let Harmut say
>>> if wants to take another look (or give a reviewed-by or similar).
>>>
>>
>> Hi Jonathan,
>>
>> As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
>> than later, so we don't miss next window.
>>
>> Thanks a lot!
>>
> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
> hasn't yet picked up my last pull request.  In the mean time I've applied
> it to the branch that will get rebased once he's taken that and pushed it
> out as testing.
> 

OK, thanks a lot for the heads up.

Cheers,
-- 
Ezequiel
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-20 20:36                 ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-20 20:36 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak



On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
> On 20/01/15 10:54, Ezequiel Garcia wrote:
>>
>>
>> On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
>>> On 06/01/15 20:47, Ezequiel Garcia wrote:
>>>> This series add the support for an ADC IP block from Cosmic Circuits.
>>>> The patchset is based on v3.19-rc3.
>>>>
>>>> As agreed with Rob, this series drops the vendor prefix in the
>>>> adc-reserved-channels DT property. This property is generic enough to
>>>> be used in other drivers (at91 is a potential candidate).
>>>>
>>>> A follow-up patch can use the property in at91 and add it to the
>>>> IIO generic bindings.
>>> I'm happy - will let this sit for a little while to let Harmut say
>>> if wants to take another look (or give a reviewed-by or similar).
>>>
>>
>> Hi Jonathan,
>>
>> As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
>> than later, so we don't miss next window.
>>
>> Thanks a lot!
>>
> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
> hasn't yet picked up my last pull request.  In the mean time I've applied
> it to the branch that will get rebased once he's taken that and pushed it
> out as testing.
> 

OK, thanks a lot for the heads up.

Cheers,
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-20 10:54         ` Ezequiel Garcia
@ 2015-01-20 20:37             ` Jonathan Cameron
  -1 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-20 20:37 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ

On 20/01/15 10:54, Ezequiel Garcia wrote:
> 
> 
> On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
>> On 06/01/15 20:47, Ezequiel Garcia wrote:
>>> This series add the support for an ADC IP block from Cosmic Circuits.
>>> The patchset is based on v3.19-rc3.
>>>
>>> As agreed with Rob, this series drops the vendor prefix in the
>>> adc-reserved-channels DT property. This property is generic enough to
>>> be used in other drivers (at91 is a potential candidate).
>>>
>>> A follow-up patch can use the property in at91 and add it to the
>>> IIO generic bindings.
>> I'm happy - will let this sit for a little while to let Harmut say
>> if wants to take another look (or give a reviewed-by or similar).
>>
> 
> Hi Jonathan,
> 
> As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
> than later, so we don't miss next window.
> 
> Thanks a lot!
> 
Hi, I'm afraid that I'm a little stalled on sending it on because Greg
hasn't yet picked up my last pull request.  In the mean time I've applied
it to the branch that will get rebased once he's taken that and pushed it
out as testing.

Jonathan

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-20 20:37             ` Jonathan Cameron
  0 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-20 20:37 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak

On 20/01/15 10:54, Ezequiel Garcia wrote:
> 
> 
> On 01/10/2015 11:15 AM, Jonathan Cameron wrote:
>> On 06/01/15 20:47, Ezequiel Garcia wrote:
>>> This series add the support for an ADC IP block from Cosmic Circuits.
>>> The patchset is based on v3.19-rc3.
>>>
>>> As agreed with Rob, this series drops the vendor prefix in the
>>> adc-reserved-channels DT property. This property is generic enough to
>>> be used in other drivers (at91 is a potential candidate).
>>>
>>> A follow-up patch can use the property in at91 and add it to the
>>> IIO generic bindings.
>> I'm happy - will let this sit for a little while to let Harmut say
>> if wants to take another look (or give a reviewed-by or similar).
>>
> 
> Hi Jonathan,
> 
> As Harmut gave a Reviewed-by, I'm wondering if you can pick this sooner
> than later, so we don't miss next window.
> 
> Thanks a lot!
> 
Hi, I'm afraid that I'm a little stalled on sending it on because Greg
hasn't yet picked up my last pull request.  In the mean time I've applied
it to the branch that will get rebased once he's taken that and pushed it
out as testing.

Jonathan

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-20 20:37             ` Jonathan Cameron
@ 2015-01-29 16:29                 ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-29 16:29 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ

Hi Jonathan,

On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
[..]
>
> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
> hasn't yet picked up my last pull request.  In the mean time I've applied
> it to the branch that will get rebased once he's taken that and pushed it
> out as testing.
> 

I can't find your second pull anywhere. Any chance we can get this
driver in v3.20?

Also, I can't find the driver anywhere in your testing branch here:

https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/

Seems like patches 2 and 3 are there, but not patch 1/3 of the series:
"iio: adc: Cosmic Circuits 10001 ADC driver".

Please let me know if you need anything at all from me!

Thanks a lot,
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-29 16:29                 ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-29 16:29 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak

Hi Jonathan,

On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
[..]
>
> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
> hasn't yet picked up my last pull request.  In the mean time I've applied
> it to the branch that will get rebased once he's taken that and pushed it
> out as testing.
> 

I can't find your second pull anywhere. Any chance we can get this
driver in v3.20?

Also, I can't find the driver anywhere in your testing branch here:

https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/

Seems like patches 2 and 3 are there, but not patch 1/3 of the series:
"iio: adc: Cosmic Circuits 10001 ADC driver".

Please let me know if you need anything at all from me!

Thanks a lot,
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-29 16:29                 ` Ezequiel Garcia
@ 2015-01-29 18:12                     ` Jonathan Cameron
  -1 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-29 18:12 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ

On 29/01/15 16:29, Ezequiel Garcia wrote:
> Hi Jonathan,
> 
> On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
> [..]
>>
>> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
>> hasn't yet picked up my last pull request.  In the mean time I've applied
>> it to the branch that will get rebased once he's taken that and pushed it
>> out as testing.
>>
> 
> I can't find your second pull anywhere. Any chance we can get this
> driver in v3.20?
I've not sent it yet. Had a bit of a backlog of review to catch up with.
+ in theory should be fine for a pull in the next day or two...
> 
> Also, I can't find the driver anywhere in your testing branch here:
> 
> https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/
> 
> Seems like patches 2 and 3 are there, but not patch 1/3 of the series:
> "iio: adc: Cosmic Circuits 10001 ADC driver".
you are quite right.  I have no idea how that happened.  Anyhow, 
it's there now.


> 
> Please let me know if you need anything at all from me!
> 
> Thanks a lot,
> 

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

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-29 18:12                     ` Jonathan Cameron
  0 siblings, 0 replies; 24+ messages in thread
From: Jonathan Cameron @ 2015-01-29 18:12 UTC (permalink / raw)
  To: Ezequiel Garcia, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak

On 29/01/15 16:29, Ezequiel Garcia wrote:
> Hi Jonathan,
> 
> On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
> [..]
>>
>> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
>> hasn't yet picked up my last pull request.  In the mean time I've applied
>> it to the branch that will get rebased once he's taken that and pushed it
>> out as testing.
>>
> 
> I can't find your second pull anywhere. Any chance we can get this
> driver in v3.20?
I've not sent it yet. Had a bit of a backlog of review to catch up with.
+ in theory should be fine for a pull in the next day or two...
> 
> Also, I can't find the driver anywhere in your testing branch here:
> 
> https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/
> 
> Seems like patches 2 and 3 are there, but not patch 1/3 of the series:
> "iio: adc: Cosmic Circuits 10001 ADC driver".
you are quite right.  I have no idea how that happened.  Anyhow, 
it's there now.


> 
> Please let me know if you need anything at all from me!
> 
> Thanks a lot,
> 


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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
  2015-01-29 18:12                     ` Jonathan Cameron
@ 2015-01-29 18:24                         ` Ezequiel Garcia
  -1 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-29 18:24 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark.Rutland-5wv7dgnIgG8,
	knaack.h-Mmb7MZpHnFY
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel.Moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ



On 01/29/2015 03:12 PM, Jonathan Cameron wrote:
> On 29/01/15 16:29, Ezequiel Garcia wrote:
>> Hi Jonathan,
>>
>> On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
>> [..]
>>>
>>> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
>>> hasn't yet picked up my last pull request.  In the mean time I've applied
>>> it to the branch that will get rebased once he's taken that and pushed it
>>> out as testing.
>>>
>>
>> I can't find your second pull anywhere. Any chance we can get this
>> driver in v3.20?
> I've not sent it yet. Had a bit of a backlog of review to catch up with.
> + in theory should be fine for a pull in the next day or two...

Great, thanks!
-- 
Ezequiel

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

* Re: [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support
@ 2015-01-29 18:24                         ` Ezequiel Garcia
  0 siblings, 0 replies; 24+ messages in thread
From: Ezequiel Garcia @ 2015-01-29 18:24 UTC (permalink / raw)
  To: Jonathan Cameron, James Hartley, Andrew Bresticker, robh+dt,
	Mark.Rutland, knaack.h
  Cc: linux-iio, devicetree, Pawel.Moll, ijc+devicetree, galak



On 01/29/2015 03:12 PM, Jonathan Cameron wrote:
> On 29/01/15 16:29, Ezequiel Garcia wrote:
>> Hi Jonathan,
>>
>> On 01/20/2015 05:37 PM, Jonathan Cameron wrote:
>> [..]
>>>
>>> Hi, I'm afraid that I'm a little stalled on sending it on because Greg
>>> hasn't yet picked up my last pull request.  In the mean time I've applied
>>> it to the branch that will get rebased once he's taken that and pushed it
>>> out as testing.
>>>
>>
>> I can't find your second pull anywhere. Any chance we can get this
>> driver in v3.20?
> I've not sent it yet. Had a bit of a backlog of review to catch up with.
> + in theory should be fine for a pull in the next day or two...

Great, thanks!
-- 
Ezequiel

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

end of thread, other threads:[~2015-01-29 18:24 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-06 20:47 [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support Ezequiel Garcia
2015-01-06 20:47 ` Ezequiel Garcia
     [not found] ` <1420577257-10846-1-git-send-email-ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
2015-01-06 20:47   ` [PATCH v7 1/3] iio: adc: Cosmic Circuits 10001 ADC driver Ezequiel Garcia
2015-01-06 20:47     ` Ezequiel Garcia
     [not found]     ` <1420577257-10846-2-git-send-email-ezequiel.garcia-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
2015-01-10 20:22       ` Hartmut Knaack
2015-01-10 20:22         ` Hartmut Knaack
2015-01-06 20:47   ` [PATCH v7 2/3] DT: iio: adc: Add CC_10001 binding documentation Ezequiel Garcia
2015-01-06 20:47     ` Ezequiel Garcia
2015-01-06 20:47   ` [PATCH v7 3/3] DT: Add a vendor prefix for Cosmic Circuits Ezequiel Garcia
2015-01-06 20:47     ` Ezequiel Garcia
2015-01-10 14:15   ` [PATCH v7 0/3] iio: Add Cosmic Circuits ADC support Jonathan Cameron
2015-01-10 14:15     ` Jonathan Cameron
     [not found]     ` <54B133FE.1020808-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2015-01-20 10:54       ` Ezequiel Garcia
2015-01-20 10:54         ` Ezequiel Garcia
     [not found]         ` <54BE33FB.6020800-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
2015-01-20 20:37           ` Jonathan Cameron
2015-01-20 20:37             ` Jonathan Cameron
     [not found]             ` <54BEBC80.1090608-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2015-01-20 20:36               ` Ezequiel Garcia
2015-01-20 20:36                 ` Ezequiel Garcia
2015-01-29 16:29               ` Ezequiel Garcia
2015-01-29 16:29                 ` Ezequiel Garcia
     [not found]                 ` <54CA5FCC.5090801-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
2015-01-29 18:12                   ` Jonathan Cameron
2015-01-29 18:12                     ` Jonathan Cameron
     [not found]                     ` <54CA77FB.9030403-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2015-01-29 18:24                       ` Ezequiel Garcia
2015-01-29 18:24                         ` Ezequiel Garcia

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.