static irqreturn_t msm_ts_irq(int irq, void *dev_id) { struct msm_ts *ts = dev_id; struct msm_ts_platform_data *pdata = ts->pdata; uint32_t tssc_avg12, tssc_avg34, tssc_status, tssc_ctl; int x, y, z1, z2; int was_down; int down; tssc_ctl = tssc_readl(ts, TSSC_CTL); tssc_status = tssc_readl(ts, TSSC_STATUS); tssc_avg12 = tssc_readl(ts, TSSC_AVG_12); tssc_avg34 = tssc_readl(ts, TSSC_AVG_34); setup_next_sample(ts); x = tssc_avg12 & 0xffff; y = tssc_avg12 >> 16; z1 = tssc_avg34 & 0xffff; z2 = tssc_avg34 >> 16; if (pdata->inv_x) x = pdata->inv_x - x; if (pdata->inv_y) y = pdata->inv_y - y; if (x < 0) x = 0; if (y < 0) y = 0; down = !(tssc_ctl & TSSC_CTL_PENUP_IRQ); was_down = ts->ts_down; ts->ts_down = down; if (down && !(tssc_ctl & TSSC_CTL_DATA_FLAG)) return IRQ_HANDLED; if (msm_tsdebug & 2) printk("%s: down=%d, x=%d, y=%d, z1=%d, z2=%d, status %x\n", __func__, down, x, y, z1, z2, tssc_status); if (!was_down && down) { struct ts_virt_key *vkey = NULL; if (pdata->vkeys_y && (y > pdata->virt_y_start)) vkey = find_virt_key(ts, pdata->vkeys_y, x); if (!vkey && ts->pdata->vkeys_x && (x > pdata->virt_x_start)) vkey = find_virt_key(ts, pdata->vkeys_x, y); if (vkey) { WARN_ON(ts->vkey_down != NULL); if(msm_tsdebug) printk("%s: virtual key down %d\n", __func__, vkey->key); ts->vkey_down = vkey; input_report_key(ts->input_dev, vkey->key, 1); input_sync(ts->input_dev); return IRQ_HANDLED; } } else if (ts->vkey_down != NULL) { if (!down) { if(msm_tsdebug) printk("%s: virtual key up %d\n", __func__, ts->vkey_down->key); input_report_key(ts->input_dev, ts->vkey_down->key, 0); input_sync(ts->input_dev); ts->vkey_down = NULL; } return IRQ_HANDLED; } if (down) { input_report_abs(ts->input_dev, ABS_X, x); input_report_abs(ts->input_dev, ABS_Y, y); input_report_abs(ts->input_dev, ABS_PRESSURE, z1); } input_report_key(ts->input_dev, BTN_TOUCH, down); input_sync(ts->input_dev); return IRQ_HANDLED; }
static irqreturn_t msm_ts_irq(int irq, void *dev_id) { struct msm_ts *ts = dev_id; struct msm_ts_platform_data *pdata = ts->pdata; uint32_t tmp, num_op, num_samp; uint32_t tssc_avg12, tssc_avg34, tssc_status, tssc_ctl; int x, y, z1, z2; int was_down; int down; tssc_ctl = tssc_readl(ts, TSSC_CTL); tssc_status = tssc_readl(ts, TSSC_STATUS); tssc_avg12 = tssc_readl(ts, TSSC_AVG_12); tssc_avg34 = tssc_readl(ts, TSSC_AVG_34); tssc_writel(ts, s_sampling_int, TSSC_SAMPLING_INT); setup_next_sample(ts); #if defined(CONFIG_MACH_MSM7X27_SWIFT) y = tssc_avg12 & 0xffff; x = tssc_avg12 >> 16; z1 = 255; z2 = 0; #else /* original */ x = tssc_avg12 & 0xffff; y = tssc_avg12 >> 16; z1 = tssc_avg34 & 0xffff; z2 = tssc_avg34 >> 16; #endif /* invert the inputs if necessary */ if (pdata->inv_x) x = pdata->inv_x - x; if (pdata->inv_y) y = pdata->inv_y - y; if (x < 0) x = 0; if (y < 0) y = 0; down = !(tssc_ctl & TSSC_CTL_PENUP_IRQ); was_down = ts->ts_down; ts->ts_down = down; /* no valid data */ if (down && !(tssc_ctl & TSSC_CTL_DATA_FLAG)) return IRQ_HANDLED; if (msm_tsdebug & 2) printk("%s: down=%d, x=%d, y=%d, z1=%d, z2=%d, status %x\n", __func__, down, x, y, z1, z2, tssc_status); if (!was_down && down) { struct ts_virt_key *vkey = NULL; if (pdata->vkeys_y && (y > pdata->virt_y_start)) vkey = find_virt_key(ts, pdata->vkeys_y, x); if (!vkey && ts->pdata->vkeys_x && (x > pdata->virt_x_start)) vkey = find_virt_key(ts, pdata->vkeys_x, y); if (vkey) { WARN_ON(ts->vkey_down != NULL); if (msm_tsdebug) printk(KERN_INFO "%s: virtual key down %d\n", __func__, vkey->key); ts->vkey_down = vkey; input_report_key(ts->input_dev, vkey->key, 1); input_sync(ts->input_dev); return IRQ_HANDLED; } } else if (ts->vkey_down != NULL) { if (!down) { if (msm_tsdebug) printk(KERN_INFO "%s: virtual key up %d\n", __func__, ts->vkey_down->key); input_report_key(ts->input_dev, ts->vkey_down->key, 0); input_sync(ts->input_dev); ts->vkey_down = NULL; } if (y > 650) mod_timer(&ts->timer, jiffies + msecs_to_jiffies(s_penup_time)); return IRQ_HANDLED; } if (down) { if ((check_count(ts, x, y) != false) && (ts_check_region(ts, x, y) != false)) { input_report_abs(ts->input_dev, ABS_X, x); input_report_abs(ts->input_dev, ABS_Y, y); input_report_abs(ts->input_dev, ABS_PRESSURE, z1); input_report_key(ts->input_dev, BTN_TOUCH, down); input_sync(ts->input_dev); } mod_timer(&ts->timer, jiffies + msecs_to_jiffies(TS_PENUP_TIMEOUT_MS)); } else { input_report_key(ts->input_dev, BTN_TOUCH, down); input_sync(ts->input_dev); } ts->count = down; touch_press = down; if (down == 0) ts->count1 = down; return IRQ_HANDLED; }