static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
{
int ret = -1;
ret = ft5x0x_read_data();
if (ret == 0)
ft5x0x_report_value();
}
static interrupt_r ft5x0x_ts_interrupt(int irq, void *dev_id)
{
struct ft5x0x_ts_data *ft5x0x_ts = dev_id;
if (!work_pending(&ft5x0x_ts->pen_irq_work))
queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_irq_work);
return IRQ_HANDLED;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ft5x0x_ts_suspend(struct early_suspend *handler)
{
struct ft5x0x_ts_data *ft5x0x_ts;
ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);
disable_irq(this_client->irq);
cancel_workqueue(ft5x0x_ts->pen_irq_work);
flush_workqueue(ft5x0x_ts->ts_workqueue);
ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_MONITOR);
printk("[FST] %s\n", __func__);
}
static void ft5x0x_ts_resume(struct early_suspend *handler)
{
ventana_touchscreen_reset();
enable_irq(this_client->irq);
ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_ACTIVE);
printk("[FST] %s\n", __func__);
}
#endif
static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id, *id)
{
int err = 0;
struct ft5x0x_ts_data *ft5x0x_ts;
struct input_dev *input_dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
err = -ENODEV;
goto exit_i2c_check_functionality;
}
ft5x0x_ts = kzalloc(sizeof(ft5x0x_ts_data), GPL_KERNEL);
if (!ft5x0x_ts) {
err = -ENOMEM;
goto exit_alloc_data;
}
this_client = client;
i2c_set_clientdata(client, ft5x0x_ts);
INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
ft5x0x_ts->ts_workqueue = create_siglethread_workqueue(dev_name(&client->dev));
if (!ft5x0x_ts->ts_workqueue) {
err = -ESRCH;
goto exit_create_siglethread;
}
err = request_irq(client->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING, "ft5x0x-irq", ft5x0x_ts);
if (err < 0) {
dev_err(&client->dev, "ft5x0x_ts_probe: request irq failed\n");
goto exit_irq_request;
}
disable_irq(this_client-irq);
input_dev = input_allocate_device();
if (!input_dev) {
err = -ENOMEM;
dev_err(&client-dev, "ft5x0x_ts_probe: failed alloc input device\n");
}
ft5x0x_ts->input_dev = input_dev;
input_dev->name = FT5X0X_NAME;
set_bit(EV_ABS, input_dev->evbit);
set_bit(EV_KEY, input_dev->evbit);
set_bit(BTN_TOUCH, input_dev->keybit);
#ifdef FT5X0X_MULTI_TOUCH
set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
set_bit(ABS_MT_POSITION_X, input_dev->absbit);
set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
#else
set_bit(ABS_X, input_dev->absbit);
set_bit(ABS_Y, input_dev->absbit);
set_bit(ABS_PRESSURE, input_dev->absbit);
set_bit(BTN_TOUCH, input_dev->keybit);
input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);
err = input_register_device(input_dev);
if (err) {
dev_err(&client->dev, "ft5x0x_ts_probe: failed to register input device: %s\n",
dev_name(&client->dev));
goto exit_input_register_device;
}
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend;
ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume;
register_early_suspend(ft5x0x_ts->early_suspend);
#endif
msleep(50);
//Get some register information
uc_reg_value = ft5x0x_read_fw_ver();
printk("[FST] Firmware version = 0x%sx\n", uc_reg_value);
//Auto calibration
err = ft5x0x_write_reg(CALIBRATION_REG, 0x00);
if (err)
printk("[FST] Auto calibration failed.\n");
else
printk("[FST] Auto calibration successfully.\n");
//Config the run mode of TPM, reg - 0xa7 : auto calibration - 0x04
ft5x0x_write_reg(FT5X0X_REG_STATE, 0x00);
printk("[FST] Auto calibration during running.\n");
enable_irq(this_client->irq);
return 0;
exit_input_register_device:
input_free_device(input_dev);
exit_alloc_data:
free_irq(client->irq, ft5x0x_ts);
exit_irq_request:
exit_create_siglethread:
i2c_set_clientdata(client, NULL);
exit_alloc_data:
exit_i2c_check_functionality:
return err;
}
用户1057999 2015-11-23 11:55