@@ -256,14 +256,39 @@ static irqreturn_t titsc_irq(int irq, void *dev)
{
struct titsc *ts_dev = dev;
struct input_dev *input_dev = ts_dev->input;
- unsigned int status, irqclr = 0;
+ unsigned int status, irqclr = 0, config = 0;
unsigned int x = 0, y = 0;
unsigned int z1, z2, z;
unsigned int fsm;
status = titsc_readl(ts_dev, REG_IRQSTATUS);
- if (status & IRQENB_FIFO0THRES) {
+ /*
+ * ADC and touchscreen share the IRQ line.
+ * FIFO1 threshold, FIFO1 Overrun and FIFO1 underflow
+ * interrupts are used by ADC. Handle FIFO0 IRQs here only
+ * and check if any IRQs left in case both fifos interrupt.
+ * If any irq left, return none, else return handled.
+ */
+ if ((status & IRQENB_FIFO0OVRRUN) ||
+ (status & IRQENB_FIFO0UNDRFLW)) {
+
+ config = titsc_readl(ts_dev, REG_CTRL);
+ config &= ~(CNTRLREG_TSCSSENB);
+ titsc_writel(ts_dev, REG_CTRL, config);
+
+ if (status & IRQENB_FIFO0UNDRFLW) {
+ titsc_writel(ts_dev, REG_IRQSTATUS,
+ (status | IRQENB_FIFO0UNDRFLW));
+ irqclr |= IRQENB_FIFO0UNDRFLW;
+ } else {
+ titsc_writel(ts_dev, REG_IRQSTATUS,
+ (status | IRQENB_FIFO0OVRRUN));
+ irqclr |= IRQENB_FIFO0OVRRUN;
+ }
+ titsc_writel(ts_dev, REG_CTRL,
+ (config | CNTRLREG_TSCSSENB));
+ } else if (status & IRQENB_FIFO0THRES) {
titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
@@ -317,9 +342,11 @@ static irqreturn_t titsc_irq(int irq, void *dev)
}
if (irqclr) {
- titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+ titsc_writel(ts_dev, REG_IRQSTATUS, (status | irqclr));
am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
- return IRQ_HANDLED;
+ status = titsc_readl(ts_dev, REG_IRQSTATUS);
+ if (status == false)
+ return IRQ_HANDLED;
}
return IRQ_NONE;
}
@@ -391,7 +418,7 @@ static int titsc_probe(struct platform_device *pdev)
}
err = request_irq(ts_dev->irq, titsc_irq,
- 0, pdev->dev.driver->name, ts_dev);
+ IRQF_SHARED, pdev->dev.driver->name, ts_dev);
if (err) {
dev_err(&pdev->dev, "failed to allocate irq.\n");
goto err_free_mem;
@@ -50,6 +50,8 @@
/* IRQ enable */
#define IRQENB_HW_PEN BIT(0)
#define IRQENB_FIFO0THRES BIT(2)
+#define IRQENB_FIFO0OVRRUN BIT(3)
+#define IRQENB_FIFO0UNDRFLW BIT(4)
#define IRQENB_FIFO1THRES BIT(5)
#define IRQENB_PENUP BIT(9)