From 57ce0ce446d8c4626b4ea01005a1173da36f095c Mon Sep 17 00:00:00 2001
From: Joel A Fernandes <joelagnel@ti.com>
Date: Mon, 28 Nov 2011 20:55:25 -0600
Subject: [PATCH 8/9] tscadc: Trigger through sysfs

Signed-off-by: Joel A Fernandes <joelagnel@ti.com>
---
 drivers/input/touchscreen/ti_tscadc.c |   61 ++++++++++++++++++++++++++++++---
 include/linux/input/ti_tscadc.h       |    1 +
 2 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/ti_tscadc.c b/drivers/input/touchscreen/ti_tscadc.c
index 638feb9..0126219 100644
--- a/drivers/input/touchscreen/ti_tscadc.c
+++ b/drivers/input/touchscreen/ti_tscadc.c
@@ -26,6 +26,17 @@
 #include <linux/io.h>
 #include <linux/input/ti_tscadc.h>
 #include <linux/delay.h>
+#include <linux/device.h>
+
+size_t do_adc_sample(struct kobject *, struct attribute *, char *);
+static DEVICE_ATTR(ain1, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain2, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain3, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain4, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain5, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain6, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain7, S_IRUGO, do_adc_sample, NULL);
+static DEVICE_ATTR(ain8, S_IRUGO, do_adc_sample, NULL);
 
 /* Memory mapped registers here have incorrect offsets!
  * Correct after referring TRM */
@@ -144,12 +155,12 @@ static void tsc_adc_step_config(struct tscadc *ts_dev, int channel)
 	stepconfig = TSCADC_STEPCONFIG_MODE_SWONESHOT |
 		TSCADC_STEPCONFIG_2SAMPLES_AVG |
 		((channel-1) << 19);
-
+	
 	delay = TSCADC_STEPCONFIG_SAMPLEDLY | TSCADC_STEPCONFIG_OPENDLY;
 
 	tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG(10), stepconfig);
 	tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY(10), delay);
-
+	
 	/* Get the ball rolling, this will trigger the FSM to step through
  	 * as soon as TSC_ADC_SS is turned on */
 	tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_GENERAL);
@@ -199,7 +210,7 @@ static irqreturn_t tsc_adc_interrupt(int irq, void *dev)
 		irqclr |= TSCADC_IRQENB_FIFO1THRES;
 	}
 
-	mdelay(500);
+	// mdelay(500);
 
 	tscadc_writel(ts_dev, TSCADC_REG_IRQSTATUS, irqclr);
 
@@ -207,7 +218,7 @@ static irqreturn_t tsc_adc_interrupt(int irq, void *dev)
 	tscadc_writel(ts_dev, TSCADC_REG_IRQEOI, 0x0);
 
 	/* Turn on Step 1 again */
-	tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_GENERAL);
+	// tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_GENERAL);
 	return IRQ_HANDLED;
 }
 
@@ -461,6 +472,34 @@ static irqreturn_t tsc_interrupt(int irq, void *dev)
 * The functions for inserting/removing driver as a module.
 */
 
+size_t do_adc_sample(struct kobject *kobj, struct attribute *attr, char *buf) {
+	struct platform_device *pdev;
+	struct device *dev;
+	struct tscadc *ts_dev;
+	int channel_num;
+
+	pdev = (struct platform_device *)container_of(kobj, struct device, kobj);
+	dev = &pdev->dev;
+
+	ts_dev = dev_get_drvdata(dev);
+
+	if(strncmp(attr->name, "ain", 3)) {
+		printk("Invalid ain num\n");
+		return -EINVAL;
+	}
+
+	channel_num = attr->name[3] - 0x30;
+	if(channel_num > 8 || channel_num < 1) {
+		printk("Invalid channel_num=%d\n", channel_num);
+		return -EINVAL;
+	}
+
+	tsc_adc_step_config(ts_dev, channel_num);
+
+	memcpy(buf, attr->name, strlen(attr->name)+1);
+	return strlen(attr->name);
+}
+
 static	int __devinit tscadc_probe(struct platform_device *pdev)
 {
 	struct tscadc			*ts_dev;
@@ -472,6 +511,18 @@ static	int __devinit tscadc_probe(struct platform_device *pdev)
 	struct resource			*res;
 	struct clk			*tsc_ick;
 
+	printk("dev addr = %p\n", &pdev->dev);
+	printk("pdev addr = %p\n", pdev);
+
+	device_create_file(&pdev->dev, &dev_attr_ain1);
+	device_create_file(&pdev->dev, &dev_attr_ain2);
+	device_create_file(&pdev->dev, &dev_attr_ain3);
+	device_create_file(&pdev->dev, &dev_attr_ain4);
+	device_create_file(&pdev->dev, &dev_attr_ain5);
+	device_create_file(&pdev->dev, &dev_attr_ain6);
+	device_create_file(&pdev->dev, &dev_attr_ain7);
+	device_create_file(&pdev->dev, &dev_attr_ain8);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "no memory resource defined.\n");
@@ -595,7 +646,6 @@ static	int __devinit tscadc_probe(struct platform_device *pdev)
 			goto err_fail;
 	}
 	else {
-		tsc_adc_step_config(ts_dev, 8);
 		tscadc_writel(ts_dev, TSCADC_REG_FIFO0THR, 0);
 		irqenable = TSCADC_IRQENB_FIFO0THRES;
 	}
@@ -604,6 +654,7 @@ static	int __devinit tscadc_probe(struct platform_device *pdev)
 	ctrl |= TSCADC_CNTRLREG_TSCSSENB;
 	tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);	/* Turn on TSC_ADC */
 
+	dev_set_drvdata(&pdev->dev, ts_dev);
 	return 0;
 
 err_fail:
diff --git a/include/linux/input/ti_tscadc.h b/include/linux/input/ti_tscadc.h
index 850cd4b..fc239c6 100644
--- a/include/linux/input/ti_tscadc.h
+++ b/include/linux/input/ti_tscadc.h
@@ -13,6 +13,7 @@
  *			0.
  * @x_plate_resistance:	X plate resistance.
  */
+#include <linux/device.h>
 
 #define TI_TSCADC_TSCMODE 0
 #define TI_TSCADC_GENMODE 1
-- 
1.7.2.5

