static int ucb1x00_ts_open(struct input_dev *idev) { struct ucb1x00_ts *ts = input_get_drvdata(idev); int ret = 0; BUG_ON(ts->rtask); init_waitqueue_head(&ts->irq_wait); ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts); if (ret < 0) goto out; /* * If we do this at all, we should allow the user to * measure and read the X and Y resistance at any time. */ ucb1x00_adc_enable(ts->ucb); ts->x_res = ucb1x00_ts_read_xres(ts); ts->y_res = ucb1x00_ts_read_yres(ts); ucb1x00_adc_disable(ts->ucb); ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd"); if (!IS_ERR(ts->rtask)) { ret = 0; } else { ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts); ts->rtask = NULL; ret = -EFAULT; } out: return ret; }
/* * Initialisation. */ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) { struct ucb1x00_ts *ts; struct input_dev *idev; int err; ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); idev = input_allocate_device(); if (!ts || !idev) { err = -ENOMEM; goto fail; } ts->ucb = dev->ucb; ts->idev = idev; ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; idev->name = "Touchscreen panel"; idev->id.product = ts->ucb->id; idev->open = ucb1x00_ts_open; idev->close = ucb1x00_ts_close; idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_drvdata(idev, ts); ucb1x00_adc_enable(ts->ucb); ts->x_res = ucb1x00_ts_read_xres(ts); ts->y_res = ucb1x00_ts_read_yres(ts); ucb1x00_adc_disable(ts->ucb); input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); err = input_register_device(idev); if (err) goto fail; dev->priv = ts; return 0; fail: input_free_device(idev); kfree(ts); return err; }