linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zubair Lutfullah <zubair.lutfullah@gmail.com>
To: jic23@cam.ac.uk
Cc: linux-iio@vger.kernel.org, gregkh@linuxfoundation.org,
	linux-kernel@vger.kernel.org, koen@dominion.thruhere.net,
	zubair.lutfullah@gmail.com
Subject: [PATCH 05/21] iio: input: am335x_adc: Add continuous mode to adc
Date: Wed, 17 Jul 2013 18:26:34 +0100	[thread overview]
Message-ID: <1374082010-28095-6-git-send-email-zubair.lutfullah@gmail.com> (raw)
In-Reply-To: <1374082010-28095-1-git-send-email-zubair.lutfullah@gmail.com>

Main patch. Adds continuous sampling support for the driver

The IRQs are changed in the TSC drivers as they are shared with
the ADC IRQ lines.

This patch is based on work in the 3.2 tree by TI
Original Author is Patil Rachna

Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
---
 drivers/iio/adc/ti_am335x_adc.c           |  386 ++++++++++++++++++++++++-----
 drivers/input/touchscreen/ti_am335x_tsc.c |    9 +-
 drivers/mfd/ti_am335x_tscadc.c            |   12 +-
 include/linux/mfd/ti_am335x_tscadc.h      |   12 +
 4 files changed, 351 insertions(+), 68 deletions(-)

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 8a63203..1f6e800 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -29,11 +29,25 @@
 #include <linux/math64.h>
 #include <linux/mfd/ti_am335x_tscadc.h>
 
+#include <linux/stat.h>
+
+#include <linux/sched.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/sysfs.h>
+#include <linux/delay.h>
+
 struct tiadc_device {
 	struct ti_tscadc_dev *mfd_tscadc;
 	int channels;
 	u8 channel_line[8];
 	u8 channel_step[8];
+	struct work_struct      poll_work;
+	wait_queue_head_t       wq_data_avail;
+	int                     irq;
+	bool                    is_continuous_mode;
+        u16                     *buffer;
 };
 
 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -56,7 +70,7 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
 	return step_en;
 }
 
-static void tiadc_step_config(struct tiadc_device *adc_dev)
+static void tiadc_step_config(struct tiadc_device *adc_dev,bool mode)
 {
 	unsigned int stepconfig;
 	int i, steps;
@@ -72,7 +86,11 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
 	 */
 
 	steps = TOTAL_STEPS - adc_dev->channels;
-	stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+	if (mode == 0)
+            stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+	else
+			stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
+			| STEPCONFIG_MODE_SWCNT;
 
 	for (i = 0; i < adc_dev->channels; i++) {
 		int chan;
@@ -88,6 +106,226 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
 
 }
 
+static ssize_t tiadc_show_mode(struct device *dev,
+                struct device_attribute *attr, char *buf)
+{
+        struct iio_dev *indio_dev = dev_get_drvdata(dev);
+        struct tiadc_device *adc_dev = iio_priv(indio_dev);
+        unsigned int tmp;
+
+        tmp = tiadc_readl(adc_dev, REG_STEPCONFIG(TOTAL_STEPS));
+        tmp &= STEPCONFIG_MODE(1);
+
+        if (tmp == 0x00)
+                return sprintf(buf, "oneshot\n");
+        else if (tmp == 0x01)
+                return sprintf(buf, "continuous\n");
+        else
+                return sprintf(buf, "Operation mode unknown\n");
+}
+
+static ssize_t tiadc_set_mode(struct device *dev,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+        struct iio_dev *indio_dev = dev_get_drvdata(dev);
+        struct tiadc_device *adc_dev = iio_priv(indio_dev);
+        unsigned config;
+
+        config = tiadc_readl(adc_dev, REG_CTRL);
+        config &= ~(CNTRLREG_TSCSSENB);
+        tiadc_writel(adc_dev, REG_CTRL, config);
+
+	if (!strncmp(buf, "oneshot", 7))
+               adc_dev->is_continuous_mode = false;
+        else if (!strncmp(buf, "continuous", 10))
+                adc_dev->is_continuous_mode = true;
+        else {
+                dev_err(dev, "Operational mode unknown\n");
+                return -EINVAL;
+        }
+ 
+	tiadc_step_config(adc_dev, adc_dev->is_continuous_mode);
+
+        config = tiadc_readl(adc_dev, REG_CTRL);
+        tiadc_writel(adc_dev, REG_CTRL,
+                        (config | CNTRLREG_TSCSSENB));
+        return count;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, tiadc_show_mode,
+                tiadc_set_mode, 0);
+
+static struct attribute *tiadc_attributes[] = {
+        &iio_dev_attr_mode.dev_attr.attr,
+        NULL,
+};
+
+static const struct attribute_group tiadc_attribute_group = {
+        .attrs = tiadc_attributes,
+};
+
+static irqreturn_t tiadc_irq(int irq, void *private)
+{
+        struct iio_dev *idev = private;
+        struct tiadc_device *adc_dev = iio_priv(idev);
+	unsigned int status, config;
+
+        status = tiadc_readl(adc_dev, REG_IRQSTATUS);
+        if (status & IRQENB_FIFO1THRES) {
+                tiadc_writel(adc_dev, REG_IRQCLR,
+                                IRQENB_FIFO1THRES);
+
+                if (iio_buffer_enabled(idev)) {
+                        if (!work_pending(&adc_dev->poll_work))
+                                schedule_work(&adc_dev->poll_work);
+                } else {
+                        wake_up_interruptible(&adc_dev->wq_data_avail);
+                }
+                tiadc_writel(adc_dev, REG_IRQSTATUS,
+                                (status | IRQENB_FIFO1THRES));
+                return IRQ_HANDLED;
+        } else if ((status &  IRQENB_FIFO1OVRRUN) ||
+                        (status &  IRQENB_FIFO1UNDRFLW)) {
+                config = tiadc_readl(adc_dev,  REG_CTRL);
+                config &= ~( CNTRLREG_TSCSSENB);
+                tiadc_writel(adc_dev,  REG_CTRL, config);
+ 
+                if (status &  IRQENB_FIFO1UNDRFLW)
+                        tiadc_writel(adc_dev,  REG_IRQSTATUS,
+                        (status |  IRQENB_FIFO1UNDRFLW));
+                else
+                        tiadc_writel(adc_dev,  REG_IRQSTATUS,
+                                (status |  IRQENB_FIFO1OVRRUN));
+ 
+                tiadc_writel(adc_dev,  REG_CTRL,
+                        (config |  CNTRLREG_TSCSSENB));
+                return IRQ_HANDLED;        
+	} else {
+                return IRQ_NONE;
+        }
+}
+
+static void tiadc_poll_handler(struct work_struct *work_s)
+{
+        struct tiadc_device *adc_dev =
+                container_of(work_s, struct tiadc_device, poll_work);
+        struct iio_dev *idev = iio_priv_to_dev(adc_dev);
+        struct iio_buffer *buffer = idev->buffer;
+        unsigned int fifo1count, readx1, status;
+        int i;
+        u32 *iBuf;
+
+        fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+        iBuf = kmalloc((fifo1count + 1) * sizeof(u32), GFP_KERNEL);
+        if (iBuf == NULL)
+                return;
+        /*
+         * Wait for ADC sequencer to settle down.
+         * There could be a scenario where in we
+         * try to read data from ADC before
+         * it is available.
+         */
+        udelay(500);
+
+        for (i = 0; i < fifo1count; i++) {
+                readx1 = tiadc_readl(adc_dev, REG_FIFO1);
+                readx1 &= FIFOREAD_DATA_MASK;
+                iBuf[i] = readx1;
+        }
+
+        buffer->access->store_to(buffer, (u8 *) iBuf);
+        status = tiadc_readl(adc_dev, REG_IRQENABLE);
+        tiadc_writel(adc_dev, REG_IRQENABLE,
+                        (status | IRQENB_FIFO1THRES));
+
+        kfree(iBuf);
+}
+
+static int tiadc_buffer_preenable(struct iio_dev *idev)
+{
+        struct iio_buffer *buffer = idev->buffer;
+
+        buffer->access->set_bytes_per_datum(buffer, 16);
+        return 0;
+}
+
+static int tiadc_buffer_postenable(struct iio_dev *idev)
+{
+        struct tiadc_device *adc_dev = iio_priv(idev);
+        struct iio_buffer *buffer = idev->buffer;
+        unsigned int enb, status, fifo1count;
+        int stepnum, i;
+        u8 bit;
+
+        if (!adc_dev->is_continuous_mode) {
+                printk("Data cannot be read continuously in one shot mode\n");
+                return -EINVAL;
+        } else {
+                status = tiadc_readl(adc_dev, REG_IRQENABLE);
+                tiadc_writel(adc_dev, REG_IRQENABLE,
+                                (status | IRQENB_FIFO1THRES)|
+                                 IRQENB_FIFO1OVRRUN |
+                                 IRQENB_FIFO1UNDRFLW);
+
+                fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+                for (i = 0; i < fifo1count; i++)
+                        tiadc_readl(adc_dev, REG_FIFO1);
+
+                tiadc_writel(adc_dev, REG_SE, 0x00);
+                for_each_set_bit(bit, buffer->scan_mask,
+                                adc_dev->channels) {
+                        struct iio_chan_spec const *chan = idev->channels + bit;
+                        /*
+                         * There are a total of 16 steps available
+                         * that are shared between ADC and touchscreen.
+                         * We start configuring from step 16 to 0 incase of
+                         * ADC. Hence the relation between input channel
+                         * and step for ADC would be as below.
+                         */
+                        stepnum = chan->channel + 9;
+                        enb = tiadc_readl(adc_dev, REG_SE);
+                        enb |= (1 << stepnum);
+                        tiadc_writel(adc_dev, REG_SE, enb);
+                }
+                return 0;
+        }
+}
+
+static int tiadc_buffer_postdisable(struct iio_dev *idev)
+{
+        struct tiadc_device *adc_dev = iio_priv(idev);
+  
+	tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
+                                IRQENB_FIFO1OVRRUN |
+                                IRQENB_FIFO1UNDRFLW));
+        tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB_TC);
+        return 0;
+}
+
+static const struct iio_buffer_setup_ops tiadc_buffer_setup_ops = {
+        .preenable = &tiadc_buffer_preenable,
+        .postenable = &tiadc_buffer_postenable,
+        .postdisable = &tiadc_buffer_postdisable,
+};
+
+static int tiadc_config_sw_ring(struct iio_dev *idev)
+{
+        struct tiadc_device *adc_dev = iio_priv(idev);
+      //int ret;
+
+        idev->buffer = iio_kfifo_allocate(idev);
+        if (!idev->buffer)
+                return(-ENOMEM);
+
+ //     idev->buffer->access = &ring_sw_access_funcs;
+        idev->setup_ops = &tiadc_buffer_setup_ops;
+
+        INIT_WORK(&adc_dev->poll_work, &tiadc_poll_handler);
+
+        idev->modes |= INDIO_BUFFER_HARDWARE;
+        return 0;
+}
+
 static const char * const chan_name_ain[] = {
 	"AIN0",
 	"AIN1",
@@ -121,6 +359,7 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
 		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 						BIT(IIO_CHAN_INFO_SCALE);
 		chan->datasheet_name = chan_name_ain[chan->channel];
+		chan->scan_index = i;
 		chan->scan_type.sign = 'u';
 		chan->scan_type.realbits = 12;
 		chan->scan_type.storagebits = 32;
@@ -148,68 +387,76 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
 	u32 step_en;
 	unsigned long timeout = jiffies + usecs_to_jiffies
 				(IDLE_TIMEOUT * adc_dev->channels);
-	step_en = get_adc_step_mask(adc_dev);
-	am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
- 
-	/* Wait for ADC sequencer to complete sampling */
-	while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
-		if (time_after(jiffies, timeout))
-			return -EAGAIN;
-		}
-	map_val = chan->channel + TOTAL_CHANNELS;
 
-	/*
-	 * When the sub-system is first enabled,
-	 * the sequencer will always start with the
-	 * lowest step (1) and continue until step (16).
-	 * For ex: If we have enabled 4 ADC channels and
-	 * currently use only 1 out of them, the
-	 * sequencer still configures all the 4 steps,
-	 * leading to 3 unwanted data.
-	 * Hence we need to flush out this data.
-	 */
-
-	for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
-		if (chan->channel == adc_dev->channel_line[i]) {
-			step = adc_dev->channel_step[i];
-			break;
+       if (adc_dev->is_continuous_mode) {
+               printk("One shot mode not enabled\n");
+               return -EINVAL;
+       } else {
+
+		step_en = get_adc_step_mask(adc_dev);
+		am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+	 
+		/* Wait for ADC sequencer to complete sampling */
+		while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
+			if (time_after(jiffies, timeout))
+				return -EAGAIN;
+			}
+		map_val = chan->channel + TOTAL_CHANNELS;
+
+		/*
+		 * When the sub-system is first enabled,
+		 * the sequencer will always start with the
+		 * lowest step (1) and continue until step (16).
+		 * For ex: If we have enabled 4 ADC channels and
+		 * currently use only 1 out of them, the
+		 * sequencer still configures all the 4 steps,
+		 * leading to 3 unwanted data.
+		 * Hence we need to flush out this data.
+		 */
+
+		for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
+			if (chan->channel == adc_dev->channel_line[i]) {
+				step = adc_dev->channel_step[i];
+				break;
+			}
 		}
-	}
-	if (WARN_ON_ONCE(step == UINT_MAX))
-		return -EINVAL;
-
-	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
-	for (i = 0; i < fifo1count; i++) {
-		read = tiadc_readl(adc_dev, REG_FIFO1);
-		stepid = read & FIFOREAD_CHNLID_MASK;
-		stepid = stepid >> 0x10;
-
-		if (stepid == map_val) {
-			read = read & FIFOREAD_DATA_MASK;
-			found = true;
-			*val = read;
+		if (WARN_ON_ONCE(step == UINT_MAX))
+			return -EINVAL;
+
+		fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+		for (i = 0; i < fifo1count; i++) {
+			read = tiadc_readl(adc_dev, REG_FIFO1);
+			stepid = read & FIFOREAD_CHNLID_MASK;
+			stepid = stepid >> 0x10;
+
+			if (stepid == map_val) {
+				read = read & FIFOREAD_DATA_MASK;
+				found = true;
+				*val = read;
+			}
 		}
-	}
 
-	switch (mask){
-		case IIO_CHAN_INFO_RAW : /*Do nothing. Above code works fine.*/
-					break;
-		case IIO_CHAN_INFO_SCALE : {
-			/*12 Bit adc. Scale value for 1800mV AVDD. Ideally
-			AVDD should come from DT.*/
-			*val = div_u64( (u64)(*val) * 1800 , 4096);
-			break;
+		switch (mask){
+			case IIO_CHAN_INFO_RAW : /*Do nothing. Above code works fine.*/
+						break;
+			case IIO_CHAN_INFO_SCALE : {
+				/*12 Bit adc. Scale value for 1800mV AVDD. Ideally
+				AVDD should come from DT.*/
+				*val = div_u64( (u64)(*val) * 1800 , 4096);
+				break;
+			}
+			default: break;
 		}
-		default: break;
-	}
 
-	if (found == false)
-		return -EBUSY;
-	return IIO_VAL_INT;
+		if (found == false)
+			return -EBUSY;
+		return IIO_VAL_INT;
+	}
 }
 
 static const struct iio_info tiadc_info = {
 	.read_raw = &tiadc_read_raw,
+	.attrs = &tiadc_attribute_group,
 };
 
 static int tiadc_probe(struct platform_device *pdev)
@@ -243,17 +490,37 @@ static int tiadc_probe(struct platform_device *pdev)
 		channels++;
 	}
 	adc_dev->channels = channels;
+	adc_dev->irq = adc_dev->mfd_tscadc->irq;
 
 	indio_dev->dev.parent = &pdev->dev;
 	indio_dev->name = dev_name(&pdev->dev);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &tiadc_info;
 
-	tiadc_step_config(adc_dev);
+	/* by default driver comes up with oneshot mode */
+	tiadc_step_config(adc_dev, adc_dev->is_continuous_mode);
+
+	/* program FIFO threshold to value minus 1 */
+	tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
 
 	err = tiadc_channel_init(indio_dev, adc_dev->channels);
 	if (err < 0)
 		goto err_free_device;
+    init_waitqueue_head(&adc_dev->wq_data_avail);
+
+    err = request_irq(adc_dev->irq, tiadc_irq, IRQF_SHARED,
+            indio_dev->name, indio_dev);
+    if (err)
+            goto err_free_irq;
+
+    err = tiadc_config_sw_ring(indio_dev);
+    if (err < 0)
+            goto err_unregister;
+ 
+    err = iio_buffer_register(indio_dev,
+                    indio_dev->channels, indio_dev->num_channels);
+    if (err < 0)
+            goto err_unregister;
 
 	err = iio_device_register(indio_dev);
 	if (err)
@@ -263,6 +530,10 @@ static int tiadc_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_unregister:
+
+err_free_irq:
+   free_irq(adc_dev->irq, indio_dev);
 err_free_channels:
 	tiadc_channels_remove(indio_dev);
 err_free_device:
@@ -313,13 +584,14 @@ static int tiadc_resume(struct device *dev)
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
 	unsigned int restore;
 
+    tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
+    tiadc_step_config(adc_dev, adc_dev->is_continuous_mode);
+
 	/* Make sure ADC is powered up */
 	restore = tiadc_readl(adc_dev, REG_CTRL);
 	restore &= ~(CNTRLREG_POWERDOWN);
 	tiadc_writel(adc_dev, REG_CTRL, restore);
 
-	tiadc_step_config(adc_dev);
-
 	return 0;
 }
 
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index cf56cae..4bf2ee6 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -263,11 +263,14 @@ static irqreturn_t titsc_irq(int irq, void *dev)
  
         /*
          * ADC and touchscreen share the IRQ line.
-         * FIFO1 threshold interrupt is used by ADC,
+         * FIFO1 threshold, FIFO1 Overrun and FIFO1 underflow
+         * interrupts are used by ADC,
          * hence return from touchscreen IRQ handler if FIFO1
-         * threshold interrupt occurred.
+         * related interrupts occurred.
          */
-        if (status & IRQENB_FIFO1THRES)
+       if ((status & IRQENB_FIFO1THRES) ||
+                       (status & IRQENB_FIFO1OVRRUN) ||
+                       (status & IRQENB_FIFO1UNDRFLW))
                 return IRQ_NONE;
         else if (status & IRQENB_FIFO0THRES) {
 		titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index d72001c..fdbd0d5 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -282,6 +282,8 @@ static int tscadc_suspend(struct device *dev)
 	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
 
 	tscadc_writel(tscadc_dev, REG_SE, 0x00);
+        tscadc_dev->irqstat = tscadc_readl(tscadc_dev, REG_IRQENABLE);
+        tscadc_dev->ctrl = tscadc_readl(tscadc_dev, REG_CTRL);
 	pm_runtime_put_sync(dev);
 
 	return 0;
@@ -290,22 +292,16 @@ static int tscadc_suspend(struct device *dev)
 static int tscadc_resume(struct device *dev)
 {
 	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
-	unsigned int restore, ctrl;
 
 	pm_runtime_get_sync(dev);
 
 	/* context restore */
-	ctrl = CNTRLREG_STEPCONFIGWRT |	CNTRLREG_STEPID;
-	if (tscadc_dev->tsc_cell != -1)
-		ctrl |= CNTRLREG_TSCENB | CNTRLREG_4WIRE;
-	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
+	tscadc_writel(tscadc_dev, REG_IRQENABLE, tscadc_dev->irqstat);
 
 	if (tscadc_dev->tsc_cell != -1)
 		tscadc_idle_config(tscadc_dev);
 	am335x_tsc_se_update(tscadc_dev);
-	restore = tscadc_readl(tscadc_dev, REG_CTRL);
-	tscadc_writel(tscadc_dev, REG_CTRL,
-			(restore | CNTRLREG_TSCSSENB));
+        tscadc_writel(tscadc_dev, REG_CTRL, tscadc_dev->ctrl);
 
 	return 0;
 }
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index db1791b..f436918 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -46,17 +46,23 @@
 /* Step Enable */
 #define STEPENB_MASK		(0x1FFFF << 0)
 #define STEPENB(val)		((val) << 0)
+#define ENB(val)                        (1 << (val))
+#define STPENB_STEPENB          STEPENB(0x1FFFF)
+#define STPENB_STEPENB_TC       STEPENB(0x1FFF)
 
 /* IRQ enable */
 #define IRQENB_HW_PEN		BIT(0)
 #define IRQENB_FIFO0THRES	BIT(2)
 #define IRQENB_FIFO1THRES	BIT(5)
 #define IRQENB_PENUP		BIT(9)
+#define IRQENB_FIFO1OVRRUN       BIT(6)
+#define IRQENB_FIFO1UNDRFLW      BIT(7)
 
 /* Step Configuration */
 #define STEPCONFIG_MODE_MASK	(3 << 0)
 #define STEPCONFIG_MODE(val)	((val) << 0)
 #define STEPCONFIG_MODE_HWSYNC	STEPCONFIG_MODE(2)
+#define STEPCONFIG_MODE_SWCNT   STEPCONFIG_MODE(1)
 #define STEPCONFIG_AVG_MASK	(7 << 2)
 #define STEPCONFIG_AVG(val)	((val) << 2)
 #define STEPCONFIG_AVG_16	STEPCONFIG_AVG(4)
@@ -124,6 +130,7 @@
 #define	MAX_CLK_DIV		7
 #define TOTAL_STEPS		16
 #define TOTAL_CHANNELS		8
+#define FIFO1_THRESHOLD                        19
 
 /*
 * ADC runs at 3MHz, and it takes
@@ -153,6 +160,11 @@ struct ti_tscadc_dev {
 
 	/* adc device */
 	struct adc_device *adc;
+
+    /* Context save */
+    unsigned int irqstat;
+    unsigned int ctrl;
+
 };
 
 static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
-- 
1.7.9.5


  parent reply	other threads:[~2013-07-17 17:27 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-17 17:26 [PATCH 00/21] iio: TI-am335x-adc continuous mode Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 01/21] MFD: ti_tscadc: disable TSC control Zubair Lutfullah
2013-07-17 17:34   ` Greg KH
2013-07-17 17:26 ` [PATCH 02/21] IIO: ADC: ti_adc: Fix 1st sample read Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 03/21] iio: ti_am335x_adc: Added iio_voltageX_scale Zubair Lutfullah
2013-07-17 17:36   ` Greg KH
2013-07-17 17:26 ` [PATCH 04/21] input: ti_tsc: Enable shared IRQ for TSC Zubair Lutfullah
2013-07-17 17:26 ` Zubair Lutfullah [this message]
2013-07-17 17:38   ` [PATCH 05/21] iio: input: am335x_adc: Add continuous mode to adc Greg KH
     [not found]     ` <CAExKytyQ23VXMVyRX9OHEQ8HZT5tFhKHSjhaH_-G_O1BVL91-A@mail.gmail.com>
2013-07-17 18:09       ` Greg KH
2013-07-18  8:08   ` Felipe Balbi
2013-07-17 17:26 ` [PATCH 06/21] MFD: ti_tscadc: ADC Clock check not required Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 07/21] iio: TI-am335x-adc: Cleanup Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 08/21] IIO: ti_adc: Handle set to clear IRQENABLE register properly Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 09/21] IIO: ti_adc: Handle set to clear IRQSTATUS " Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 10/21] IIO: ti_adc: Handle overrun before threshold event Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 11/21] iio: ti_adc: Avoid double " Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 12/21] IIO: ti_adc: Also clear threshold event when clearing overrun event Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 13/21] IO: ti_adc: Reset and clear overrun status before capture Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 14/21] IIO: ti_adc: Properly handle out of memory situation Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 15/21] IIO: ti_adc: Print error and handle short FIFO events Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 16/21] IIO: ti_adc: Fix allocation count of FIFO buffer Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 17/21] Revert "IIO: ti_adc: Correct wrong samples received on 1st read in continuous mode" Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 18/21] IIO: ti_adc: Fix capture operation during resume Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 19/21] iio: ti_amss5x adc Fix check_patch.pl issues Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 20/21] input: ti_am335x_tsc.c fix checkpatch.pl issues Zubair Lutfullah
2013-07-17 17:26 ` [PATCH 21/21] mfd: ti_am335x_tscadc.c " Zubair Lutfullah

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1374082010-28095-6-git-send-email-zubair.lutfullah@gmail.com \
    --to=zubair.lutfullah@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jic23@cam.ac.uk \
    --cc=koen@dominion.thruhere.net \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).