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 x = 0, y = 0; unsigned int z1, z2, z; unsigned int fsm; status = titsc_readl(ts_dev, REG_IRQSTATUS); if (status & IRQENB_FIFO0THRES) { titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); if (ts_dev->pen_down && z1 != 0 && z2 != 0) { /* * Calculate pressure using formula * Resistance(touch) = x plate resistance * * x postion/4096 * ((z2 / z1) - 1) */ z = z1 - z2; z *= x; z *= ts_dev->x_plate_resistance; z /= z2; z = (z + 2047) >> 12; if (z <= MAX_12BIT) { input_report_abs(input_dev, ABS_X, x); input_report_abs(input_dev, ABS_Y, y); input_report_abs(input_dev, ABS_PRESSURE, z); input_report_key(input_dev, BTN_TOUCH, 1); input_sync(input_dev); } }
static irqreturn_t titsc_irq(int irq, void *dev) { struct titsc *ts_dev = dev; struct input_dev *input_dev = ts_dev->input; unsigned int fsm, status, irqclr = 0; unsigned int x = 0, y = 0; unsigned int z1, z2, z; status = titsc_readl(ts_dev, REG_RAWIRQSTATUS); if (status & IRQENB_HW_PEN) { ts_dev->pen_down = true; irqclr |= IRQENB_HW_PEN; pm_stay_awake(ts_dev->mfd_tscadc->dev); } if (status & IRQENB_PENUP) { fsm = titsc_readl(ts_dev, REG_ADCFSM); if (fsm == ADCFSM_STEPID) { ts_dev->pen_down = false; input_report_key(input_dev, BTN_TOUCH, 0); input_report_abs(input_dev, ABS_PRESSURE, 0); input_sync(input_dev); pm_relax(ts_dev->mfd_tscadc->dev); } else { ts_dev->pen_down = true; } irqclr |= IRQENB_PENUP; } if (status & IRQENB_EOS) irqclr |= IRQENB_EOS; /* * ADC and touchscreen share the IRQ line. * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only */ if (status & IRQENB_FIFO0THRES) { titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); if (ts_dev->pen_down && z1 != 0 && z2 != 0) { /* * Calculate pressure using formula * Resistance(touch) = x plate resistance * * x postion/4096 * ((z2 / z1) - 1) */ z = z1 - z2; z *= x; z *= ts_dev->x_plate_resistance; z /= z2; z = (z + 2047) >> 12; if (z <= MAX_12BIT) { input_report_abs(input_dev, ABS_X, x); input_report_abs(input_dev, ABS_Y, y); input_report_abs(input_dev, ABS_PRESSURE, z); input_report_key(input_dev, BTN_TOUCH, 1); input_sync(input_dev); } }