/* must be called with mutex held */ static void tsc2005_disable(struct tsc2005 *ts) { if (ts->disable_depth++ != 0) return; disable_irq(ts->spi->irq); if (ts->esd_timeout) del_timer_sync(&ts->esd_timer); del_timer_sync(&ts->penup_timer); tsc2005_stop_scan(ts); }
/* Must be called with mutex held */ static void tsc2005_disable(struct tsc2005 *ts) { if (ts->disable_depth++ != 0) return; disable_irq(ts->spi->irq); if (ts->esd_timeout) del_timer(&ts->esd_timer); /* wait until penup timer expire normally */ do { msleep(4); } while (ts->sample_sent); tsc2005_stop_scan(ts); }
static int __devinit tsc2005_ts_init(struct tsc2005 *ts, struct tsc2005_platform_data *pdata) { struct input_dev *idev; int r; int x_max, y_max; init_timer(&ts->penup_timer); setup_timer(&ts->penup_timer, tsc2005_ts_penup_timer_handler, (unsigned long)ts); spin_lock_init(&ts->lock); mutex_init(&ts->mutex); ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; ts->hw_avg_max = pdata->ts_hw_avg; ts->stab_time = pdata->ts_stab_time; x_max = pdata->ts_x_max ? : 4096; ts->fudge_x = pdata->ts_x_fudge ? : 4; y_max = pdata->ts_y_max ? : 4096; ts->fudge_y = pdata->ts_y_fudge ? : 8; ts->p_max = pdata->ts_pressure_max ? : MAX_12BIT; ts->touch_pressure = pdata->ts_touch_pressure ? : ts->p_max; ts->fudge_p = pdata->ts_pressure_fudge ? : 2; ts->set_reset = pdata->set_reset; if (prescale) { x_max = x_size; y_max = y_size; } idev = input_allocate_device(); if (idev == NULL) { r = -ENOMEM; goto err1; } idev->name = "TSC2005 touchscreen"; snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts", ts->spi->dev.bus_id); idev->phys = ts->phys; idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); idev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE); idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ts->idev = idev; tsc2005_ts_setup_spi_xfer(ts); input_set_abs_params(idev, ABS_X, 0, x_max, ts->fudge_x, 0); input_set_abs_params(idev, ABS_Y, 0, y_max, ts->fudge_y, 0); input_set_abs_params(idev, ABS_PRESSURE, 0, ts->p_max, ts->fudge_p, 0); tsc2005_start_scan(ts); r = request_irq(ts->spi->irq, tsc2005_ts_irq_handler, (((TSC2005_CFR2_INITVALUE & TSC2005_CFR2_IRQ_MASK) == TSC2005_CFR2_IRQ_PENDAV) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING) | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "tsc2005", ts); if (r < 0) { dev_err(&ts->spi->dev, "unable to get DAV IRQ"); goto err2; } set_irq_wake(ts->spi->irq, 1); r = input_register_device(idev); if (r < 0) { dev_err(&ts->spi->dev, "can't register touchscreen device\n"); goto err3; } /* We can tolerate these failing */ r = device_create_file(&ts->spi->dev, &dev_attr_ts_ctrl_selftest); if (r < 0) dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n", dev_attr_ts_ctrl_selftest.attr.name, r); r = device_create_file(&ts->spi->dev, &dev_attr_pen_down); if (r < 0) dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n", dev_attr_pen_down.attr.name, r); r = device_create_file(&ts->spi->dev, &dev_attr_disable_ts); if (r < 0) dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n", dev_attr_disable_ts.attr.name, r); /* Finally, configure and start the optional EDD watchdog. */ ts->esd_timeout = pdata->esd_timeout; if (ts->esd_timeout && ts->set_reset) { unsigned long wdj; setup_timer(&ts->esd_timer, tsc2005_esd_timer_handler, (unsigned long)ts); INIT_WORK(&ts->esd_work, tsc2005_rst_handler); wdj = msecs_to_jiffies(ts->esd_timeout); ts->esd_timer.expires = round_jiffies(jiffies+wdj); add_timer(&ts->esd_timer); } return 0; err3: free_irq(ts->spi->irq, ts); err2: tsc2005_stop_scan(ts); input_free_device(idev); err1: return r; }