static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) { u32 tmp, rv[4], xs[4], ys[4]; int idx; struct lpc32xx_tsc *tsc = dev_id; struct input_dev *input = tsc->dev; tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { /* FIFO overflow - throw away samples */ lpc32xx_fifo_clear(tsc); return IRQ_HANDLED; } /* * Gather and normalize 4 samples. Pen-up events may have less * than 4 samples, but its ok to pop 4 and let the last sample * pen status check drop the samples. */ idx = 0; while (idx < 4 && !(tsc_readl(tsc, LPC32XX_TSC_STAT) & LPC32XX_TSC_STAT_FIFO_EMPTY)) { tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); rv[idx] = tmp; idx++; } /* Data is only valid if pen is still down in last sample */ if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { /* Use average of 2nd and 3rd sample for position */ input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); input_report_key(input, BTN_TOUCH, 1); } else { input_report_key(input, BTN_TOUCH, 0); } input_sync(input); return IRQ_HANDLED; }
static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) { u32 tmp, rv[4], xs[4], ys[4]; int idx; struct lpc32xx_tsc *tsc = dev_id; struct input_dev *input = tsc->dev; tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { lpc32xx_fifo_clear(tsc); return IRQ_HANDLED; } idx = 0; while (idx < 4 && !(tsc_readl(tsc, LPC32XX_TSC_STAT) & LPC32XX_TSC_STAT_FIFO_EMPTY)) { tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); rv[idx] = tmp; idx++; } if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); input_report_key(input, BTN_TOUCH, 1); } else { input_report_key(input, BTN_TOUCH, 0); } input_sync(input); return IRQ_HANDLED; }