static int cyttsp5_input_register_device(struct input_dev *input, int max_slots) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) input_mt_init_slots(input, max_slots, 0); #else input_mt_init_slots(input, max_slots); #endif return input_register_device(input); }
static int touch_init(void) { int rc; input_dev = input_allocate_device(); if (!input_dev) { pr_info("input_dev alloc fail\n"); return -ENOMEM; } input_dev->name = "touch"; __set_bit(EV_KEY, input_dev->evbit); __set_bit(EV_ABS, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); input_mt_init_slots(input_dev, 5); input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 720, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 1280, 0, 0); input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0); rc = input_register_device(input_dev); if (rc) { pr_info("input_register_device fail\n"); return -EINVAL; } return 0; }
/* setup which logical events to report */ static void setup_events_to_report(struct input_dev *input_dev, const struct bcm5974_config *cfg) { __set_bit(EV_ABS, input_dev->evbit); /* for synaptics only */ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); /* finger touch area */ set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); /* finger approach area */ set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); /* finger orientation */ set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); /* finger position */ set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_LEFT, input_dev->keybit); if (cfg->caps & HAS_INTEGRATED_BUTTON) __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); input_mt_init_slots(input_dev, MAX_FINGERS, INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); }
/** * pimhyp3_request_input_dev - Allocate, populate and register the input device * @ts: our pimhyp3_ts_data pointer * Must be called during probe */ static int pimhyp3_request_input_dev(struct pimhyp3_ts_data *ts) { int error; ts->input_dev = devm_input_allocate_device(&ts->client->dev); if (!ts->input_dev) { dev_err(&ts->client->dev, "Failed to allocate input device."); return -ENOMEM; } /* Set up device parameters */ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); ts->input_dev->name = "Cypress Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; ts->input_dev->id.product = ts->id; ts->input_dev->id.version = ts->version; error = input_register_device(ts->input_dev); if (error) { dev_err(&ts->client->dev, "Failed to register input device: %d", error); return error; } return 0; }
static int silead_ts_request_input_dev(struct silead_ts_data *data) { struct device *dev = &data->client->dev; int error; data->input = devm_input_allocate_device(dev); if (!data->input) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } input_set_abs_params(data->input, ABS_MT_POSITION_X, 0, 4095, 0, 0); input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0); touchscreen_parse_properties(data->input, true, &data->prop); input_mt_init_slots(data->input, data->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); if (device_property_read_bool(dev, "silead,home-button")) input_set_capability(data->input, EV_KEY, KEY_LEFTMETA); data->input->name = SILEAD_TS_NAME; data->input->phys = "input/ts"; data->input->id.bustype = BUS_I2C; error = input_register_device(data->input); if (error) { dev_err(dev, "Failed to register input device: %d\n", error); return error; } return 0; }
static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct input_dev *input = hi->input; switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: switch (usage->hid) { case HID_GD_X: field->logical_maximum = 32760; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_X); set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE); /* touchscreen emulation */ set_abs(input, ABS_X, field, SN_MOVE); return 1; case HID_GD_Y: field->logical_maximum = 32760; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_Y); set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE); /* touchscreen emulation */ set_abs(input, ABS_Y, field, SN_MOVE); return 1; } return 0; case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_TIPSWITCH: /* touchscreen emulation */ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(input, EV_KEY, BTN_TOUCH); return 1; case HID_DG_INRANGE: case HID_DG_CONFIDENCE: case HID_DG_CONTACTCOUNT: case HID_DG_CONTACTMAX: return -1; case HID_DG_CONTACTID: input_mt_init_slots(input, MAX_SLOTS); return 1; case HID_DG_TIPPRESSURE: field->logical_minimum = 0; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_PRESSURE); set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE); /* touchscreen emulation */ set_abs(input, ABS_PRESSURE, field, SN_PRESSURE); return 1; } return 0; } /* ignore others (from other reports we won't get anyway) */ return -1; }
static int cyttsp4_input_register_device(struct input_dev *input, int max_slots) { input_set_abs_params(input, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0); input_mt_init_slots(input, max_slots); return input_register_device(input); }
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { if (wacom_wac->features->device_type == BTN_TOOL_FINGER) { input_dev->absbit[BIT_WORD(ABS_MISC)] &= ~BIT_MASK(ABS_MISC); input_mt_init_slots(input_dev, 2); input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wacom_wac->features->x_max, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wacom_wac->features->y_max, 0, 0); } }
static int prepare_tsc_input_device(uint16_t ind, struct usf_type *usf_info, struct us_input_info_type *input_info, const char *name) { struct input_dev *in_dev = allocate_dev(ind, name); if (in_dev == NULL) return -ENOMEM; usf_info->input_ifs[ind] = in_dev; #ifdef SKY_ULTRASOUNDPEN_FEATURE set_bit(CAMERA_KEY, in_dev->keybit); set_bit(CAPTURE_KEY, in_dev->keybit); #endif in_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); in_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(in_dev, ABS_X, input_info->tsc_x_dim[MIN_IND], input_info->tsc_x_dim[MAX_IND], 0, 0); input_set_abs_params(in_dev, ABS_Y, input_info->tsc_y_dim[MIN_IND], input_info->tsc_y_dim[MAX_IND], 0, 0); input_set_abs_params(in_dev, ABS_DISTANCE, input_info->tsc_z_dim[MIN_IND], input_info->tsc_z_dim[MAX_IND], 0, 0); input_set_abs_params(in_dev, ABS_PRESSURE, input_info->tsc_pressure[MIN_IND], input_info->tsc_pressure[MAX_IND], 0, 0); input_set_abs_params(in_dev, ABS_TILT_X, input_info->tsc_x_tilt[MIN_IND], input_info->tsc_x_tilt[MAX_IND], 0, 0); input_set_abs_params(in_dev, ABS_TILT_Y, input_info->tsc_y_tilt[MIN_IND], input_info->tsc_y_tilt[MAX_IND], 0, 0); input_mt_init_slots(in_dev, NUM_TRK_ID); return 0; }
static int __init vinput_multi_tc_init(void) { int err; vinput_multi_tc_dev = input_allocate_device(); if (!vinput_multi_tc_dev) return -ENOMEM; vinput_multi_tc_dev->name = "qwerty"; vinput_multi_tc_dev->id.product = 0; vinput_multi_tc_dev->id.version = 0x0100; set_bit(EV_SYN, vinput_multi_tc_dev->evbit); set_bit(EV_KEY, vinput_multi_tc_dev->evbit); set_bit(EV_ABS, vinput_multi_tc_dev->evbit); set_bit(BTN_TOUCH, vinput_multi_tc_dev->keybit); input_mt_init_slots(vinput_multi_tc_dev, MAX_FINGER_NUM); input_set_abs_params(vinput_multi_tc_dev, ABS_X, 0, 1280, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_Y, 0, 720, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_PRESSURE, 0, 255, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_MT_POSITION_X, 0, 1280, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_MT_POSITION_Y, 0, 720, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(vinput_multi_tc_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0); err = input_register_device(vinput_multi_tc_dev); if (err) { input_free_device(vinput_multi_tc_dev); return err; } return 0; }
static int silead_ts_request_input_dev(struct silead_ts_data *data) { struct device *dev = &data->client->dev; int ret; data->input_dev = devm_input_allocate_device(dev); if (!data->input_dev) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } data->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_set_abs_params(data->input_dev, ABS_MT_POSITION_X, 0, data->x_max, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_POSITION_Y, 0, data->y_max, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0); input_mt_init_slots(data->input_dev, data->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); data->input_dev->name = SILEAD_TS_NAME; data->input_dev->phys = "input/ts"; data->input_dev->id.bustype = BUS_I2C; ret = input_register_device(data->input_dev); if (ret) { dev_err(dev, "Failed to register input device: %d\n", ret); return ret; } return 0; }
/** * goodix_request_input_dev - Allocate, populate and register the input device * * @ts: our goodix_ts_data pointer * * Must be called during probe */ static int goodix_request_input_dev(struct goodix_ts_data *ts) { int error; ts->input_dev = devm_input_allocate_device(&ts->client->dev); if (!ts->input_dev) { dev_err(&ts->client->dev, "Failed to allocate input device."); return -ENOMEM; } ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); ts->input_dev->name = "Goodix Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; ts->input_dev->id.product = 0x1001; ts->input_dev->id.version = 10427; error = input_register_device(ts->input_dev); if (error) { dev_err(&ts->client->dev, "Failed to register input device: %d", error); return error; } return 0; }
static int __devinit ist30xx_probe(struct i2c_client * client, const struct i2c_device_id * id) { int ret; struct ist30xx_data *data; struct input_dev *input_dev; #if 0 /* [email protected] */ struct touch_platform_data *ts_pdata; // struct ist30xx_ts_device *dev; ts_pdata = client->dev.platform_data; // dev = &ist30xx_ts_dev; /* [email protected] */ #endif tsp_info("\n%s(), the i2c addr=0x%x \n", __func__, client->addr); /* dev->power = ts_pdata->power; dev->num_irq = ts_pdata->irq; dev->sda_gpio = ts_pdata->sda; dev->scl_gpio = ts_pdata->scl;*/ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { tsp_debug("failed to i2c functionality check"); ret = -ENODEV; goto err_check_functionality_failed; } data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->client = client; if(client->dev.of_node) { data->pdata = devm_kzalloc(&client->dev, sizeof(struct ist30xx_tsi_platform_data), GFP_KERNEL); if(!data->pdata) { tsp_debug("failed to allocate platform_data"); return -ENOMEM; } ret = ist30xx_parse_dt(&client->dev, data->pdata); if(ret) { tsp_debug("device tree parsing failed"); return ret; } } else { data->pdata = client->dev.platform_data; } ret = ist30xx_regulator_configure(data, true); if (ret < 0) { tsp_debug("Failed to configure regulators"); } ret = ist30xx_ldo_power_on(data, true); if (ret < 0) { tsp_debug("Failed to power on"); } input_dev = input_allocate_device(); if (!input_dev) { ret = -ENOMEM; tsp_err("%s(), input_allocate_device failed (%d)\n", __func__, ret); goto err_alloc_dev; } #if 0 DMSG("[ TSP ] irq : %d, scl : %d, sda : %d\n", client->irq, ts_pdata->scl, ts_pdata->sda); #endif data->num_fingers = IST30XX_MAX_MT_FINGERS; data->num_keys = IST30XX_MAX_MT_FINGERS; data->irq_enabled = 1; data->client = client; data->input_dev = input_dev; #if 0 /* [email protected] */ data->power = ts_pdata->power; /* [email protected] */ #endif i2c_set_clientdata(client, data); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) input_mt_init_slots(input_dev, IST30XX_MAX_MT_FINGERS); #endif input_dev->name = "ist30xx_ts_input"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; set_bit(EV_ABS, input_dev->evbit); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) set_bit(INPUT_PROP_DIRECT, input_dev->propbit); #endif input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, IST30XX_MAX_X, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, IST30XX_MAX_Y, 0, 0); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, IST30XX_MAX_W, 0, 0); #else input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, IST30XX_MAX_Z, 0, 0); input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, IST30XX_MAX_W, 0, 0); #endif #if IST30XX_USE_KEY { int i; set_bit(EV_KEY, input_dev->evbit); set_bit(EV_SYN, input_dev->evbit); for (i = 1; i < ARRAY_SIZE(ist30xx_key_code); i++) set_bit(ist30xx_key_code[i], input_dev->keybit); } #endif input_set_drvdata(input_dev, data); ret = input_register_device(input_dev); if (ret) { input_free_device(input_dev); goto err_reg_dev; } #if defined(CONFIG_FB) data->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&data->fb_notif); if(ret) tsp_debug("Unable to register fb_notifier \n"); else tsp_debug("Register fb_notifier \n"); #elif defined(CONFIG_HAS_EARLYSUSPEND) data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = ist30xx_early_suspend; data->early_suspend.resume = ist30xx_late_resume; register_early_suspend(&data->early_suspend); #endif ts_data = data; ret = ist30xx_init_system(); if (ret) { dev_err(&client->dev, "chip initialization failed\n"); goto err_init_drv; } ret = ist30xx_init_update_sysfs(); if (ret) goto err_init_drv; #if IST30XX_DEBUG ret = ist30xx_init_misc_sysfs(); if (ret) goto err_init_drv; #endif # if IST30XX_FACTORY_TEST ret = ist30xx_init_factory_sysfs(); if (ret) goto err_init_drv; #endif #if IST30XX_TRACKING_MODE ret = ist30xx_init_tracking_sysfs(); if (ret) goto err_init_drv; #endif ret = request_threaded_irq(client->irq, NULL, ist30xx_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "ist30xx_ts", data); if (ret) goto err_irq; ist30xx_disable_irq(data); #if IST30XX_INTERNAL_BIN # if IST30XX_UPDATE_BY_WORKQUEUE INIT_DELAYED_WORK(&work_fw_update, fw_update_func); schedule_delayed_work(&work_fw_update, IST30XX_UPDATE_DELAY); # else ret = ist30xx_auto_bin_update(data); if (ret < 0) goto err_irq; # endif #endif // IST30XX_INTERNAL_BIN ret = ist30xx_get_info(data); tsp_info("Get info: %s\n", (ret == 0 ? "success" : "fail")); INIT_DELAYED_WORK(&work_reset_check, reset_work_func); #if IRQ_THREAD_WORK_QUEUE INIT_WORK(&work_irq_thread, irq_thread_func); #endif #if IST30XX_DETECT_TA ist30xx_ta_status = 0; #endif #if IST30XX_EVENT_MODE init_timer(&idle_timer); idle_timer.function = timer_handler; idle_timer.expires = jiffies_64 + (EVENT_TIMER_INTERVAL); mod_timer(&idle_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); ktime_get_ts(&t_event); #endif ist30xx_initialized = 1; return 0; err_irq: ist30xx_disable_irq(data); free_irq(client->irq, data); err_init_drv: #if IST30XX_EVENT_MODE get_event_mode = false; #endif tsp_err("Error, ist30xx init driver\n"); // ist30xx_power_off(); ist30xx_ts_off(); input_unregister_device(input_dev); return 0; err_reg_dev: err_alloc_dev: tsp_err("Error, ist30xx mem free\n"); kfree(data); err_check_functionality_failed: return 0; }
static int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ct36x_ts_info *ts = NULL; struct device *dev = &client->dev; int err = -1; if (dev == NULL) { printk(KERN_ERR "%s(): dev not registered!\n", __func__); goto ERR_HW_INIT; } /* Check I2C Functionality */ err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); if ( !err ) { dev_err(dev, "Check I2C Functionality Failed.\n"); goto ERR_I2C_CHK; } ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); if (ts == NULL) { printk(KERN_ERR "%s(): Not registered at I2C!\n", __func__); goto ERR_HW_INIT; } ts->ready = 0; // Device is not ready /* Init Hardware */ err = ct36x_ts_hw_init(ts); if ( err ) { dev_err(dev, "Platform HW Init Failed.\n"); goto ERR_HW_INIT; } /* HW Reset when Firmware request and update. */ ct36x_ts_hw_reset(ts); #if (CT36X_TS_CHIP_SEL == CT360_CHIP_VER) // Set I2C scon to 0x0f2f --> read version ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x0F; ts->data.buf[2] = 0x2A; #elif (CT36X_TS_CHIP_SEL == CT36X_CHIP_VER) // Set I2C scon to 0x3fff --> read version ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x3F; ts->data.buf[2] = 0xFF; #endif ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(10); ts->data.buf[0] = 0x00; ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // do read version ct36x_ts_reg_read(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); dev_info(dev, "FW Version read: 0x%x \n", ts->data.buf[0]); #if defined(CONFIG_CT360_CHIP_UPDATE_SUPPORT) { char fw_ver_upd = Binary_Data[CT36X_TS_FW_VER_OFFSET]; dev_info(dev, "FW Version write: 0x%x \n", fw_ver_upd); if ( fw_ver_upd != ts->data.buf[0] ) { dev_info(dev, "Running bootloader ... \n"); err = ct36x_ts_bootloader(client); dev_info(dev, "Bootloader done, %s \n", err ? "Failed" : "OK"); } } #else dev_info(dev, "Bootloader support disabled, trying without...\n"); #endif // register early suspend #ifdef CONFIG_HAS_EARLYSUSPEND #if (CT36X_TS_HAS_EARLYSUSPEND) ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = ct36x_early_suspend; ts->early_suspend.resume = ct36x_early_resume; register_early_suspend(&ts->early_suspend); #endif #endif // allocate input device ts->input = input_allocate_device(); if ( !ts->input ) { dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME); err = -ENOMEM; goto ERR_INPUT_ALLOC; } __set_bit(EV_ABS, ts->input->evbit); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) __set_bit(INPUT_PROP_DIRECT, ts->input->propbit); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) input_mt_init_slots(ts->input, CT36X_TS_POINT_NUM); #endif input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0); input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); ts->input->name = DRIVER_NAME; ts->input->id.bustype = BUS_I2C; // register input device err = input_register_device(ts->input); if ( err ) { dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME); goto ERR_INPUT_REGIS; } /* ct36x_zx */ ts->ts_workqueue = create_singlethread_workqueue(CT36X_TS_WQ); if (!ts->ts_workqueue) { err = -ESRCH; printk(KERN_ERR "create_workqueue falled!\n"); goto ERR_TS_WQ; } // work INIT_WORK(&ts->event_work, ct36x_ts_workfunc); // Init irq ts->irq = gpio_to_irq(CT36X_TS_IRQ_PIN); //err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts); err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING, DRIVER_NAME, ts); /* ct36x_zx */ if ( err ) { dev_err(dev, "Unable to request irq.\n"); goto ERR_IRQ_REQEST; } // ESD timer #if (CT36X_TS_ESD_TIMER_INTERVAL) setup_timer(&ts->timer, ct36x_ts_timer, ts); ts->timer.expires = jiffies + HZ * CT36X_TS_ESD_TIMER_INTERVAL; add_timer(&ts->timer); ts->timer_on = 1; dev_info(dev, "ESD timer, %s \n", ts->timer_on ? "On" : "Off"); #endif /* Add another reset and then state we are ready */ ct36x_ts_hw_reset(ts); ts->ready = 1; // Device is ready return 0; ERR_TS_WQ: ERR_IRQ_REQEST: ERR_INPUT_REGIS: input_free_device(ts->input); ERR_INPUT_ALLOC: ERR_I2C_CHK: #ifdef CONFIG_HAS_EARLYSUSPEND #if (CT36X_TS_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif #endif ERR_HW_INIT: ct36x_ts_hw_exit(ts); return err; }
static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; int retry=0; struct gt818_ts_data *ts; struct gt818_platform_data *pdata; dev_info(&client->dev,"Install touch driver.\n"); printk("gt818: Install touch driver.\n"); //Check I2C function if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n"); ret = -ENODEV; goto err_check_functionality_failed; } ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } i2c_connect_client = client; //used by Guitar_Update pdata = client->dev.platform_data; ts->client = client; i2c_set_clientdata(client, ts); //init int and reset ports ret = gpio_request(pdata->gpio_pendown, "TS_INT"); //Request IO if (ret){ dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)pdata->gpio_pendown, ret); goto err_gpio_request_failed; } rk29_mux_api_set(pdata->pendown_iomux_name, pdata->pendown_iomux_mode); gpio_direction_input(pdata->gpio_pendown); gpio_pull_updown(pdata->gpio_pendown, 0); ret = gpio_request(pdata->gpio_reset, "gt818_resetPin"); if(ret){ dev_err(&client->dev, "failed to request resetPin GPIO%d\n", pdata->gpio_reset); goto err_gpio_request_failed; } rk29_mux_api_set(pdata->resetpin_iomux_name, pdata->resetpin_iomux_mode); #if 1 for(retry = 0; retry < 4; retry++) { gpio_pull_updown(pdata->gpio_reset, 1); gpio_direction_output(pdata->gpio_reset, 0); msleep(1); //delay at least 1ms gpio_direction_input(pdata->gpio_reset); gpio_pull_updown(pdata->gpio_reset, 0); msleep(25); //delay at least 20ms ret = i2c_pre_cmd(ts); if (ret > 0) break; msleep(50); } if(ret <= 0) { dev_err(&client->dev, "Warnning: I2C communication might be ERROR!\n"); goto err_i2c_failed; } #endif for(retry = 0; retry < 3; retry++) { ret = goodix_init_panel(ts); dev_info(&client->dev,"the config ret is :%d\n", ret); msleep(20); if(ret < 0) //Initiall failed continue; else break; } if(ret < 0) { ts->bad_data = 1; goto err_init_godix_ts; } goodix_read_version(ts); INIT_WORK(&ts->work, goodix_ts_work_func); //init work_struct ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { ret = -ENOMEM; dev_dbg(&client->dev,"goodix_ts_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } //ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; //ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); //ts->input_dev->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) | // BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR); // for android #ifdef HAVE_TOUCH_KEY for(retry = 0; retry < MAX_KEY_NUM; retry++) { input_set_capability(ts->input_dev, EV_KEY, gt818_key_array[retry]); } #endif snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); snprintf(ts->name, sizeof(ts->name), "gt818-touchscreen"); ts->input_dev->name = "gt818_ts";//ts->name; ts->input_dev->phys = ts->phys; ts->input_dev->dev.parent = &client->dev; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0xDEAD; ts->input_dev->id.product = 0xBEEF; ts->input_dev->id.version = 10427; //screen firmware version __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); __set_bit(EV_ABS, ts->input_dev->evbit); #ifdef GOODIX_MULTI_TOUCH input_mt_init_slots(ts->input_dev, MAX_FINGER_NUM); //input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_WIDTH, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_HEIGHT, 0, 0); //input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER_NUM, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); #else input_set_abs_params(ts->input_dev, ABS_X, 0, SCREEN_MAX_HEIGHT, 0, 0); input_set_abs_params(ts->input_dev, ABS_Y, 0, SCREEN_MAX_WIDTH, 0, 0); input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0); #endif ret = input_register_device(ts->input_dev); if (ret) { dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name); goto err_input_register_device_failed; } ts->bad_data = 0; // 16finger_list.length = 0; client->irq = gpio_to_irq(pdata->gpio_pendown); //If not defined in client if (client->irq) { #if INT_TRIGGER==0 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_RISING #elif INT_TRIGGER==1 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_FALLING #elif INT_TRIGGER==2 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_LOW #elif INT_TRIGGER==3 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_HIGH #endif ret = request_irq(client->irq, goodix_ts_irq_handler, GT801_PLUS_IRQ_TYPE, client->name, ts); if (ret != 0) { dev_err(&client->dev,"Cannot allocate ts INT!ERRNO:%d\n", ret); gpio_direction_input(pdata->gpio_pendown); gpio_free(pdata->gpio_pendown); goto err_gpio_request_failed; } else { disable_irq(client->irq); ts->use_irq = 1; dev_dbg(&client->dev,"Reques EIRQ %d succesd on GPIO:%d\n", client->irq, pdata->gpio_pendown); } } err_gpio_request_failed: ts->power = goodix_ts_power; #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = goodix_ts_early_suspend; ts->early_suspend.resume = goodix_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif dev_info(&client->dev,"Start %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); if (ts->use_irq) { enable_irq(client->irq); } else { hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ts->timer.function = goodix_ts_timer_func; hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); } i2c_end_cmd(ts); return 0; err_init_godix_ts: i2c_end_cmd(ts); if(ts->use_irq) { ts->use_irq = 0; free_irq(client->irq,ts); gpio_direction_input(pdata->gpio_pendown); gpio_free(pdata->gpio_pendown); } else hrtimer_cancel(&ts->timer); err_input_register_device_failed: input_free_device(ts->input_dev); err_input_dev_alloc_failed: i2c_set_clientdata(client, NULL); err_i2c_failed: kfree(ts); err_alloc_data_failed: err_check_functionality_failed: return ret; }
static int cyttsp4_input_register_device(struct input_dev *input, int max_tchs) { /* max num slots equals max touches + 1 for hover */ input_mt_init_slots(input, max_tchs + 1); return input_register_device(input); }
static int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0, i; struct ct36x_data *ts = NULL; struct ct36x_platform_data *pdata = client->dev.platform_data; if(!pdata){ dev_err(&client->dev, "no platform data\n"); return -EINVAL; }; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); return -ENODEV; } ts = kzalloc(sizeof(struct ct36x_data), GFP_KERNEL); if(!ts){ dev_err(&client->dev, "No memory for ct36x"); return -ENOMEM; } ts->model = pdata->model; ts->x_max = pdata->x_max; ts->y_max = pdata->y_max; ts->rst_io = pdata->rst_io; ts->irq_io = pdata->irq_io; for(i = 0; i < 4; i++) ts->orientation[i] = pdata->orientation[i]; ts->client = client; ts->dev = &client->dev; i2c_set_clientdata(client, ts); ret = ct36x_set_ops(ts, pdata->model); if(ret < 0){ dev_err(ts->dev, "Failed to set ct36x ops\n"); goto err_ct36x_set_ops; } if(ts->ops->init){ ret = ts->ops->init(ts); if(ret < 0){ dev_err(ts->dev, "Failed to init ct36x chip\n"); goto err_input_allocate_device; } } ret = ct36x_chip_get_ver(ts); if(ret < 0){ dev_warn(ts->dev, "CT363 TOUCHSCREEN is no exist\n"); goto err_input_allocate_device; } printk("CT363 ver=[%x]\n", ret); ts->input = input_allocate_device(); if(!ts->input){ ret = -ENODEV; dev_err(ts->dev, "Failed to allocate input device\n"); goto err_input_allocate_device; } ts->input->name = CT36X_NAME; ts->input->dev.parent = &client->dev; set_bit(EV_ABS, ts->input->evbit); set_bit(INPUT_PROP_DIRECT, ts->input->propbit); input_mt_init_slots(ts->input, ts->point_num); input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); ret = input_register_device(ts->input); if(ret < 0){ dev_err(ts->dev, "Failed to register input device\n"); goto err_input_register_devcie; } #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = ct36x_ts_early_suspend; ts->early_suspend.resume = ct36x_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif ts->irq = gpio_to_irq(ts->irq_io.gpio); ret = request_threaded_irq(ts->irq, NULL, ct36x_irq_handler, IRQF_TRIGGER_FALLING|IRQF_ONESHOT, CT36X_NAME, ts); if(ret < 0){ dev_err(ts->dev, "Failed to request threaded irq\n"); goto err_request_threaded_irq; } dev_info(ts->dev, "CT363 Successfully initialized\n"); return 0; err_request_threaded_irq: unregister_early_suspend(&ts->early_suspend); input_unregister_device(ts->input); err_input_register_devcie: input_free_device(ts->input); err_input_allocate_device: if(ts->ops->deinit) ts->ops->deinit(ts); err_ct36x_init_chip: err_ct36x_set_ops: i2c_set_clientdata(client, NULL); kfree(ts); return ret; }
static int pixcir_i2c_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { const struct pixcir_ts_platform_data *pdata = dev_get_platdata(&client->dev); struct device *dev = &client->dev; struct device_node *np = dev->of_node; struct pixcir_i2c_ts_data *tsdata; struct input_dev *input; int error; if (np && !pdata) { pdata = pixcir_parse_dt(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } if (!pdata) { dev_err(&client->dev, "platform data not defined\n"); return -EINVAL; } if (!gpio_is_valid(pdata->gpio_attb)) { dev_err(dev, "Invalid gpio_attb in pdata\n"); return -EINVAL; } if (!pdata->chip.max_fingers) { dev_err(dev, "Invalid max_fingers in pdata\n"); return -EINVAL; } tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL); if (!tsdata) return -ENOMEM; input = devm_input_allocate_device(dev); if (!input) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } tsdata->client = client; tsdata->input = input; tsdata->pdata = pdata; input->name = client->name; input->id.bustype = BUS_I2C; input->open = pixcir_input_open; input->close = pixcir_input_close; input->dev.parent = &client->dev; __set_bit(EV_KEY, input->evbit); __set_bit(EV_ABS, input->evbit); __set_bit(BTN_TOUCH, input->keybit); input_set_abs_params(input, ABS_X, 0, pdata->x_max, 0, 0); input_set_abs_params(input, ABS_Y, 0, pdata->y_max, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); tsdata->max_fingers = tsdata->pdata->chip.max_fingers; if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) { tsdata->max_fingers = PIXCIR_MAX_SLOTS; dev_info(dev, "Limiting maximum fingers to %d\n", tsdata->max_fingers); } error = input_mt_init_slots(input, tsdata->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); if (error) { dev_err(dev, "Error initializing Multi-Touch slots\n"); return error; } input_set_drvdata(input, tsdata); error = devm_gpio_request_one(dev, pdata->gpio_attb, GPIOF_DIR_IN, "pixcir_i2c_attb"); if (error) { dev_err(dev, "Failed to request ATTB gpio\n"); return error; } error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, tsdata); if (error) { dev_err(dev, "failed to request irq %d\n", client->irq); return error; } /* Always be in IDLE mode to save power, device supports auto wake */ error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE); if (error) { dev_err(dev, "Failed to set IDLE mode\n"); return error; } /* Stop device till opened */ error = pixcir_stop(tsdata); if (error) return error; error = input_register_device(input); if (error) return error; i2c_set_clientdata(client, tsdata); device_init_wakeup(&client->dev, 1); return 0; }
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = td->mtclass; __s32 quirks = cls->quirks; /* Only map fields from TouchScreen or TouchPad collections. * We need to ignore fields that belong to other collections * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); else if (field->application == HID_DG_TOUCHPAD) set_bit(INPUT_PROP_POINTER, hi->input->propbit); else return 0; switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: switch (usage->hid) { case HID_GD_X: if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) field->logical_maximum = 32760; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_X); set_abs(hi->input, ABS_MT_POSITION_X, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_X, field, cls->sn_move); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_GD_Y: if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) field->logical_maximum = 32760; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_Y); set_abs(hi->input, ABS_MT_POSITION_Y, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_Y, field, cls->sn_move); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; } return 0; case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_INRANGE: if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_CONFIDENCE: if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_TIPSWITCH: hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_CONTACTID: if (!td->maxcontacts) td->maxcontacts = MT_DEFAULT_MAXCONTACT; input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; td->last_field_index = field->index; td->last_mt_collection = usage->collection_index; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR); set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, cls->sn_width); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, cls->sn_height); input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_TIPPRESSURE: if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) field->logical_minimum = 0; hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_PRESSURE); set_abs(hi->input, ABS_MT_PRESSURE, field, cls->sn_pressure); /* touchscreen emulation */ set_abs(hi->input, ABS_PRESSURE, field, cls->sn_pressure); if (td->last_mt_collection == usage->collection_index) { td->last_slot_field = usage->hid; td->last_field_index = field->index; } return 1; case HID_DG_CONTACTCOUNT: if (td->last_mt_collection == usage->collection_index) td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ if (td->last_mt_collection == usage->collection_index) td->last_field_index = field->index; return -1; } /* let hid-input decide for the others */ return 0; case 0xff000000: /* we do not want to map these: no input-oriented meaning */ return -1; } return 0; }
static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count) { struct uinput_user_dev *user_dev; struct input_dev *dev; int i; int retval; if (count != sizeof(struct uinput_user_dev)) return -EINVAL; if (!udev->dev) { retval = uinput_allocate_device(udev); if (retval) return retval; } dev = udev->dev; user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev)); if (IS_ERR(user_dev)) return PTR_ERR(user_dev); udev->ff_effects_max = user_dev->ff_effects_max; /* Ensure name is filled in */ if (!user_dev->name[0]) { retval = -EINVAL; goto exit; } kfree(dev->name); dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE, GFP_KERNEL); if (!dev->name) { retval = -ENOMEM; goto exit; } dev->id.bustype = user_dev->id.bustype; dev->id.vendor = user_dev->id.vendor; dev->id.product = user_dev->id.product; dev->id.version = user_dev->id.version; for (i = 0; i < ABS_CNT; i++) { input_abs_set_max(dev, i, user_dev->absmax[i]); input_abs_set_min(dev, i, user_dev->absmin[i]); input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]); input_abs_set_flat(dev, i, user_dev->absflat[i]); } /* check if absmin/absmax/absfuzz/absflat are filled as * told in Documentation/input/input-programming.txt */ if (test_bit(EV_ABS, dev->evbit)) { retval = uinput_validate_absbits(dev); if (retval < 0) goto exit; if (test_bit(ABS_MT_SLOT, dev->absbit)) { int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; input_mt_init_slots(dev, nslot, 0); } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { input_set_events_per_packet(dev, 60); } } udev->state = UIST_SETUP_COMPLETE; retval = count; exit: kfree(user_dev); return retval; }
static int sis_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct sis_ts_data *ts; struct input_dev *input; int error; ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; ts->client = client; ts->attn_gpio = devm_gpiod_get_optional(&client->dev, "attn", GPIOD_IN); if (IS_ERR(ts->attn_gpio)) { error = PTR_ERR(ts->attn_gpio); if (error != -EPROBE_DEFER) dev_err(&client->dev, "Failed to get attention GPIO: %d\n", error); return error; } ts->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); if (error != -EPROBE_DEFER) dev_err(&client->dev, "Failed to get reset GPIO: %d\n", error); return error; } sis_ts_reset(ts); ts->input = input = devm_input_allocate_device(&client->dev); if (!input) { dev_err(&client->dev, "Failed to allocate input device\n"); return -ENOMEM; } input->name = "SiS Touchscreen"; input->id.bustype = BUS_I2C; input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0); input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, SIS_AREA_LENGTH_LONGER, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, SIS_AREA_LENGTH_SHORT, 0, 0); error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT); if (error) { dev_err(&client->dev, "Failed to initialize MT slots: %d\n", error); return error; } error = devm_request_threaded_irq(&client->dev, client->irq, NULL, sis_ts_irq_handler, IRQF_ONESHOT, client->name, ts); if (error) { dev_err(&client->dev, "Failed to request IRQ: %d\n", error); return error; } error = input_register_device(ts->input); if (error) { dev_err(&client->dev, "Failed to register input device: %d\n", error); return error; } return 0; }
static int cyttsp5_input_register_device(struct input_dev *input, int max_slots) { input_mt_init_slots(input, max_slots, 0); return input_register_device(input); }
static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count) { struct uinput_user_dev *user_dev; struct input_dev *dev; char *name; int size; int retval; if (count != sizeof(struct uinput_user_dev)) return -EINVAL; if (!udev->dev) { retval = uinput_allocate_device(udev); if (retval) return retval; } dev = udev->dev; user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); if (!user_dev) return -ENOMEM; if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) { retval = -EFAULT; goto exit; } udev->ff_effects_max = user_dev->ff_effects_max; size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; if (!size) { retval = -EINVAL; goto exit; } kfree(dev->name); dev->name = name = kmalloc(size, GFP_KERNEL); if (!name) { retval = -ENOMEM; goto exit; } strlcpy(name, user_dev->name, size); dev->id.bustype = user_dev->id.bustype; dev->id.vendor = user_dev->id.vendor; dev->id.product = user_dev->id.product; dev->id.version = user_dev->id.version; size = sizeof(int) * ABS_CNT; memcpy(dev->absmax, user_dev->absmax, size); memcpy(dev->absmin, user_dev->absmin, size); memcpy(dev->absfuzz, user_dev->absfuzz, size); memcpy(dev->absflat, user_dev->absflat, size); /* check if absmin/absmax/absfuzz/absflat are filled as * told in Documentation/input/input-programming.txt */ if (test_bit(EV_ABS, dev->evbit)) { retval = uinput_validate_absbits(dev); if (retval < 0) goto exit; if (test_bit(ABS_MT_SLOT, dev->absbit)) { int nslot = 2; //input_abs_get_max(dev, ABS_MT_SLOT) + 1; input_mt_init_slots(dev, nslot); } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { input_set_events_per_packet(dev, 60); } } udev->state = UIST_SETUP_COMPLETE; retval = count; exit: kfree(user_dev); return retval; }
int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = -1; int binchksum; int updcnt; struct ct36x_ts_info *ts; struct device *dev; if ( CT36X_TS_CORE_DEBUG ) printk(">>>>> %s() called <<<<< \n", __FUNCTION__); dev = &client->dev; #ifdef CONFIG_OF if (ts_com->owner != NULL) return -ENODEV; memset(ts_com, 0 ,sizeof(struct touch_pdata)); ts_com = (struct touch_pdata*)client->dev.platform_data; printk("ts_com->owner = %s\n", ts_com->owner); ct36x_platform_get_cfg(&ct36x_ts); ct36x_ts.client = client; i2c_set_clientdata(client, &ct36x_ts); ts_com->hardware_reset = ct36x_hw_reset; ts_com->read_version = ct36x_read_version; ts_com->upgrade_touch = ct36x_upgrade_touch; #else struct ct36x_platform_data *pdata; pdata = dev->platform_data; if ( pdata ) { ct36x_ts.i2c_address = client->addr; ct36x_ts.irq = pdata->irq; ct36x_ts.rst = pdata->rst; ct36x_ts.ss = pdata->ss; ct36x_platform_get_cfg(&ct36x_ts); ct36x_ts.client = client; i2c_set_clientdata(client, &ct36x_ts); } else { printk("No platform data for device %s.\n", DRIVER_NAME); } plat_data = dev->platform_data; #endif ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); /* Create Proc Entry File */ //ts->proc_entry = create_proc_entry(DRIVER_NAME, 0666/*S_IFREG | S_IRUGO | S_IWUSR*/, NULL); ts->proc_entry = proc_create(DRIVER_NAME, 0666/*S_IFREG | S_IRUGO | S_IWUSR*/, NULL, &ct36x_ts_fops); if ( ts->proc_entry == NULL ) { dev_err(dev, "Failed creating proc dir entry file.\n"); } //else { //ts->proc_entry->proc_fops = &ct36x_ts_fops; //} /* register early suspend */ #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = ct36x_early_suspend; ts->early_suspend.resume = ct36x_early_resume; register_early_suspend(&ts->early_suspend); #endif /* Check I2C Functionality */ err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); if ( !err ) { dev_err(dev, "Check I2C Functionality Failed.\n"); goto ERR_I2C_CHK; } /* Request platform resources (gpio/interrupt pins) */ err = ct36x_platform_get_resource(ts); if ( err ) { dev_err(dev, "Unable to request platform resource for device %s.\n", DRIVER_NAME); goto ERR_PLAT_RSC; } /* Hardware reset */ #ifdef CONFIG_OF ct36x_platform_hw_reset(ts); #else ct36x_platform_hw_reset(pdata); #endif updcnt = 5; while (updcnt--) { if (ct36x_test_read(client, client->addr, (char *)&binchksum, 1) == 1) break; } if (updcnt <= 0) { printk("ct36x touch not exit!\n"); goto ERR_PLAT_RSC; } binchksum = 0; #ifdef LATE_UPGRADE ts_com->upgrade_task = kthread_run(ct36x_late_upgrade, NULL, "ct36x_late_upgrade"); if (!ts_com->upgrade_task) printk("%s creat upgrade process failed\n", __func__); else printk("%s creat upgrade process sucessful\n", __func__); #else // Get binary Checksum binchksum = ct36x_chip_get_binchksum(ts->data.buf); if ( CT36X_TS_CORE_DEBUG ) printk("Bin checksum: 0x%x\n", binchksum); // Get firmware Checksum fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf); if ( CT36X_TS_CORE_DEBUG ) printk("Fw checksum: 0x%x\n", fwchksum); //while(1){} updcnt = 2; while ( binchksum != fwchksum && updcnt--) { /* Update Firmware */ ct36x_chip_go_bootloader(client, ts->data.buf); /* Hardware reset */ #ifdef CONFIG_OF ct36x_platform_hw_reset(&ct36x_ts); #else ct36x_platform_hw_reset(plat_data); #endif // Get firmware Checksum fwchksum = ct36x_chip_get_fwchksum(client, ts->data.buf); if ( CT36X_TS_CORE_DEBUG ) printk("Fw checksum: 0x%x\n", fwchksum); } #if defined(CONFIG_TOUCHSCREEN_CT36X_CHIP_CT365) ct36x_check_trim(ct36x_ts.client); #endif printk("Fw update %s. 0x%x, 0x%x\n", binchksum != fwchksum ? "Failed" : "Success", binchksum, fwchksum); /* Hardware reset */ #ifdef CONFIG_OF ct36x_platform_hw_reset(&ct36x_ts); #else ct36x_platform_hw_reset(plat_data); #endif #endif /* allocate input device */ ts->input = input_allocate_device(); if ( !ts->input ) { dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME); err = -ENOMEM; goto ERR_INPUT_ALLOC; } /* config input device */ __set_bit(EV_SYN, ts->input->evbit); __set_bit(EV_KEY, ts->input->evbit); __set_bit(EV_ABS, ts->input->evbit); __set_bit(INPUT_PROP_DIRECT, ts->input->propbit); input_mt_init_slots(ts->input, CT36X_TS_POINT_NUM, 0); //input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0); //input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0); #ifdef CONFIG_OF if (ts_com->pol & 4) swap(ts_com->xres, ts_com->yres); input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts_com->xres, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts_com->yres, 0, 0); #else input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, plat_data->x_max, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, plat_data->y_max, 0, 0); #endif input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); ts->input->name = DRIVER_NAME; ts->input->id.bustype = BUS_I2C; /* register input device */ err = input_register_device(ts->input); if ( err ) { dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME); goto ERR_INPUT_REGIS; } /* Create work queue */ INIT_WORK(&ts->event_work, ct36x_ts_workfunc); ts->workqueue = create_singlethread_workqueue(dev_name(&client->dev)); /* Init irq */ //gpio_set_status(GPIO_FT_IRQ, gpio_status_in); //gpio_irq_set(170, GPIO_IRQ(FT_IRQ-INT_GPIO_0, GPIO_IRQ_FALLING)); //err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts); #ifndef CONFIG_OF if (pdata->init_gpio) { pdata->init_gpio(); } #endif err = request_irq(ts->irq, ct36x_ts_irq, IRQF_DISABLED, DRIVER_NAME, ts); #ifdef LATE_UPGRADE disable_irq(ts->irq); #endif if ( err ) { dev_err(dev, "Unable to request irq for device %s.\n", DRIVER_NAME); goto ERR_IRQ_REQ; } /* Set device is ready */ ts->state = CT36X_STATE_NORMAL; /* power denoisy*/ //ct36x_chip_set_adapter_on(client, ts->data.buf); //ct36x_chip_set_adapter_off(client, ts->data.buf); //ct36x_ts_adapter(0); create_init(client->dev, ts_com); printk("%s: over\n",__func__); return 0; ERR_IRQ_REQ: destroy_workqueue(ts->workqueue); ERR_INPUT_REGIS: input_free_device(ts->input); ERR_INPUT_ALLOC: ERR_PLAT_RSC: ct36x_platform_put_resource(ts); ERR_I2C_CHK: #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&ts->early_suspend); #endif remove_proc_entry(DRIVER_NAME, NULL); ts_com->owner = NULL; return err; }
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = &td->mtclass; int code; /* Only map fields from TouchScreen or TouchPad collections. * We need to ignore fields that belong to other collections * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); else if (field->application != HID_DG_TOUCHPAD) return 0; /* In case of an indirect device (touchpad), we need to add * specific BTN_TOOL_* to be handled by the synaptics xorg * driver. * We also consider that touchscreens providing buttons are touchpads. */ if (field->application == HID_DG_TOUCHPAD || (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || cls->is_indirect) { set_bit(INPUT_PROP_POINTER, hi->input->propbit); set_bit(BTN_TOOL_FINGER, hi->input->keybit); set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); } /* eGalax devices provide a Digitizer.Stylus input which overrides * the correct Digitizers.Finger X/Y ranges. * Let's just ignore this input. */ if (field->physical == HID_DG_STYLUS) return -1; /* Only map fields from TouchScreen or TouchPad collections. * We need to ignore fields that belong to other collections * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); else if (field->application == HID_DG_TOUCHPAD) set_bit(INPUT_PROP_POINTER, hi->input->propbit); else return 0; switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: switch (usage->hid) { case HID_GD_X: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_X); set_abs(hi->input, ABS_MT_POSITION_X, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_X, field, cls->sn_move); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_GD_Y: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_Y); set_abs(hi->input, ABS_MT_POSITION_Y, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_Y, field, cls->sn_move); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; } return 0; case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_INRANGE: mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_CONFIDENCE: mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_TIPSWITCH: hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_CONTACTID: if (!td->maxcontacts) td->maxcontacts = MT_DEFAULT_MAXCONTACT; input_mt_init_slots(hi->input, td->maxcontacts); mt_store_field(usage, td, hi); td->last_field_index = field->index; td->touches_by_report++; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR); set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, cls->sn_width); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, cls->sn_height); input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_TIPPRESSURE: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_PRESSURE); set_abs(hi->input, ABS_MT_PRESSURE, field, cls->sn_pressure); /* touchscreen emulation */ set_abs(hi->input, ABS_PRESSURE, field, cls->sn_pressure); mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ td->last_field_index = field->index; return -1; } case HID_DG_TOUCH: /* Legacy devices use TIPSWITCH and not TOUCH. * Let's just ignore this field. */ return -1; /* let hid-input decide for the others */ return 0; case HID_UP_BUTTON: code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); hid_map_usage(hi, usage, bit, max, EV_KEY, code); input_set_capability(hi->input, EV_KEY, code); return 1; case 0xff000000: /* we do not want to map these: no input-oriented meaning */ return -1; } return 0; }
static int pm_connect(struct serio *serio, struct serio_driver *drv) { struct pm *pm; struct input_dev *input_dev; int max_x, max_y; int err; pm = kzalloc(sizeof(struct pm), GFP_KERNEL); input_dev = input_allocate_device(); if (!pm || !input_dev) { err = -ENOMEM; goto fail1; } pm->serio = serio; pm->dev = input_dev; snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); pm->maxcontacts = 1; input_dev->name = "PenMount Serial TouchScreen"; input_dev->phys = pm->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_PENMOUNT; input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); switch (serio->id.id) { default: case 0: pm->packetsize = 5; pm->parse_packet = pm_parse_9000; input_dev->id.product = 0x9000; max_x = max_y = 0x3ff; break; case 1: pm->packetsize = 6; pm->parse_packet = pm_parse_6000; input_dev->id.product = 0x6000; max_x = max_y = 0x3ff; break; case 2: pm->packetsize = 6; pm->parse_packet = pm_parse_3000; input_dev->id.product = 0x3000; max_x = max_y = 0x7ff; pm->maxcontacts = PM_3000_MTSLOT; break; case 3: pm->packetsize = 6; pm->parse_packet = pm_parse_6250; input_dev->id.product = 0x6250; max_x = max_y = 0x3ff; pm->maxcontacts = PM_6250_MTSLOT; break; } input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0); input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0); if (pm->maxcontacts > 1) { input_mt_init_slots(pm->dev, pm->maxcontacts); input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, max_x, 0, 0); input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0); } serio_set_drvdata(serio, pm); err = serio_open(serio, drv); if (err) goto fail2; err = input_register_device(pm->dev); if (err) goto fail3; return 0; fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(pm); return err; }
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = td->mtclass; switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: switch (usage->hid) { case HID_GD_X: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_X); set_abs(hi->input, ABS_MT_POSITION_X, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_X, field, cls->sn_move); td->last_slot_field = usage->hid; return 1; case HID_GD_Y: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_POSITION_Y); set_abs(hi->input, ABS_MT_POSITION_Y, field, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_Y, field, cls->sn_move); td->last_slot_field = usage->hid; return 1; } return 0; case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_INRANGE: td->last_slot_field = usage->hid; return 1; case HID_DG_CONFIDENCE: td->last_slot_field = usage->hid; return 1; case HID_DG_TIPSWITCH: hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH); td->last_slot_field = usage->hid; return 1; case HID_DG_CONTACTID: input_mt_init_slots(hi->input, td->mtclass->maxcontacts); td->last_slot_field = usage->hid; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR); td->last_slot_field = usage->hid; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); field->logical_maximum = 1; field->logical_minimum = 0; set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); td->last_slot_field = usage->hid; return 1; case HID_DG_TIPPRESSURE: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_PRESSURE); set_abs(hi->input, ABS_MT_PRESSURE, field, cls->sn_pressure); /* touchscreen emulation */ set_abs(hi->input, ABS_PRESSURE, field, cls->sn_pressure); td->last_slot_field = usage->hid; return 1; case HID_DG_CONTACTCOUNT: td->last_field_index = field->report->maxfield - 1; return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ return -1; } /* let hid-input decide for the others */ return 0; case 0xff000000: /* we do not want to map these: no input-oriented meaning */ return -1; } return 0; }
static int cyttsp4_input_register_device(struct input_dev *input, int max_tchs) { /* max num slots equals max touches + 1 for hover */ input_mt_init_slots(input, max_tchs + 1);//modified by linghai interim because of the input-mt.c change return input_register_device(input); }
/******************************************************* 功能: 触摸屏探测函数 在注册驱动时调用(要求存在对应的client); 用于IO,中断等资源申请;设备注册;触摸屏初始化等工作 参数: client:待驱动的设备结构体 id:设备ID return: 执行结果码,0表示正常执行 ********************************************************/ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct goodix_ts_data *ts; int ret = 0; int retry=0; int ret1 = -1; //int count=0; struct goodix_i2c_rmi_platform_data *pdata = client->dev.platform_data; if (!pdata) { // gModify.Add dev_err(&client->dev, "platform data is required!\n"); return -EINVAL; } int INT_PORT = pdata ->gpio_irq; int SHUTDOWN_PORT = pdata->gpio_shutdown; if (!SHUTDOWN_PORT || !INT_PORT) { ret = -1; printk(KERN_ALERT "goodix platform data error\n"); goto err_check_functionality_failed ; } dev_dbg(&client->dev,"Install touchscreen driver for guitar.\n"); //Check I2C function ret=i2c_write_bytes(client,pdata->config_info,pdata->config_info_len); if (ret < 0){ printk("I2C transfer error in panel init"); goto error_i2c_transfer; } msleep(1); ret = gpio_request(SHUTDOWN_PORT, "TS_SHUTDOWN"); //Request IO if (ret < 0) { printk(KERN_ALERT "Failed to request GPIO:%d, ERRNO:%d\n",(int)SHUTDOWN_PORT,ret); goto err_check_functionality_failed; } gpio_direction_output(SHUTDOWN_PORT, 0); //Touchscreen is waiting to wakeup ret = gpio_get_value(SHUTDOWN_PORT); if (ret) { printk(KERN_ALERT "Cannot set touchscreen to work.\n"); goto err_check_functionality_failed; } //waite guitar start if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "System need I2C function.\n"); ret = -ENODEV; goto err_check_functionality_failed; } i2c_connect_client = client; //used by Guitar Updating. /* gModify.unCmmt msleep(16); for(retry=0; retry < 5; retry++) { ret =i2c_write_bytes(client, NULL, 0); //Test i2c. if (ret > 0) break; } if(ret < 0) { dev_err(&client->dev, "Warnning: I2C connection might be something wrong!\n"); //ret = -ENOSYS; //goto err_i2c_failed; } */ // gpio_set_value(SHUTDOWN_PORT, 1); //suspend ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } INIT_WORK(&ts->work, goodix_ts_work_func); ts->client = client; i2c_set_clientdata(client, ts); ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { ret = -ENOMEM; dev_dbg(&client->dev," In File:%s Function:%s Failed to allocate input device\n", __FILE__, __func__); goto err_input_dev_alloc_failed; } #if 0 ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ts->input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); // for android //#ifdef GOODIX_MULTI_TOUCH //used by android 1.x for multi-touch, not realized //ts->input_dev->absbit[0]=BIT(ABS_HAT0X) |BIT(ABS_HAT0Y); //ts->input_dev->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); //#endif input_set_abs_params(ts->input_dev, ABS_X, 0, pdata->xmax, 0, 0); input_set_abs_params(ts->input_dev, ABS_Y, 0, pdata->ymax, 0, 0); input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0); #endif #ifdef GOODIX_MULTI_TOUCH ts->input_dev->name = "Goodix TouchScreen of Guitar"; ts->input_dev->phys = "I2C"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0EEF; ts->input_dev->id.product = 0x0020; //hkw add // input_set_capability(ts->input_dev, EV_KEY, EV_KEY); input_set_capability(ts->input_dev, EV_KEY, KEY_BACK); input_set_capability(ts->input_dev, EV_KEY, KEY_HOMEPAGE); input_set_capability(ts->input_dev, EV_KEY, KEY_MENU); __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); __set_bit(EV_ABS, ts->input_dev->evbit); input_mt_init_slots(ts->input_dev, MAX_FINGER_NUM); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, pdata->xmax, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, pdata->ymax, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); #endif finger_list.length = 0; ret = input_register_device(ts->input_dev); if (ret) { dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name); goto err_input_register_device_failed; } gpio_set_value(SHUTDOWN_PORT, 0); msleep(10); /* ret1=goodix_init_panel(ts); if(ret1 < 0) goto err_init_godix_ts; */ // goodix_read_version(ts); msleep(500); ts->init_finished = 0; ts->use_irq = 0; ts->retry=0; ts->bad_data = 0; if (client->irq) { ret = gpio_request(INT_PORT, "TS_INT"); //Request IO if (ret < 0) { dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)INT_PORT,ret); goto err_gpio_request_failed; } /* set input mode */ gpio_direction_input(INT_PORT); //gpio_enable_edge_int(gpio_to_idx(INT_PORT), // gModify.unCmmt // pdata->irq_edge, client->irq - INT_GPIO_0); ret = request_irq(gpio_to_irq(client->irq), goodix_ts_irq_handler, IRQF_TRIGGER_FALLING, client->name, ts); if (ret != 0) { dev_err(&client->dev,"Can't allocate touchscreen's interrupt!ERRNO:%d\n", ret); gpio_free( INT_PORT); goto err_gpio_request_failed; } else { // disable_irq(client->irq); ts->use_irq = 1; dev_info(&client->dev,"Requestt EIRQ %d succesd on GPIO:%d\n",client->irq,INT_PORT); } } err_gpio_request_failed: if (!ts->use_irq) { hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ts->timer.function = goodix_ts_timer_func; hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); } #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = goodix_ts_early_suspend; ts->early_suspend.resume = goodix_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif dev_info(&client->dev,"Start %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "Interrupt" : "Polling\n"); return 0; err_init_godix_ts: if(ts->use_irq) free_irq(client->irq,ts); gpio_request(INT_PORT,"TS_INT"); gpio_free(INT_PORT); err_input_register_device_failed: input_free_device(ts->input_dev); err_input_dev_alloc_failed: i2c_set_clientdata(client, NULL); kfree(ts); err_i2c_failed: gpio_direction_input(SHUTDOWN_PORT); gpio_free(SHUTDOWN_PORT); error_i2c_transfer: err_alloc_data_failed: err_check_functionality_failed: return ret; }
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct gsl_ts_data *ts; const struct firmware *fw = NULL; unsigned long irqflags; int error; bool acpipower; dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "%s: i2c check functionality error\n", __func__); error = -ENXIO; goto release; } if (client->irq <= 0) { dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__); error = -ENODEV; goto release; } ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL); if (!ts) { error = -ENOMEM; goto release; } ts->client = client; i2c_set_clientdata(client, ts); if (gsl_fw_name != NULL) { strncpy(ts->fw_name, gsl_fw_name, sizeof(ts->fw_name)); } else { strncpy(ts->fw_name, GSL_FW_NAME_DEFAULT, sizeof(ts->fw_name)); } error = request_firmware(&fw, ts->fw_name, &ts->client->dev); if (error < 0) { dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error); goto release; } error = gsl_ts_init(ts, fw); if (error < 0) { dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error); goto release; } ts->input = devm_input_allocate_device(&client->dev); if (!ts->input) { dev_err(&client->dev, "%s: failed to allocate input device\n", __func__); error = -ENOMEM; goto release; } ts->input->name = "Silead GSLx680 Touchscreen"; ts->input->id.bustype = BUS_I2C; ts->input->phys = "input/ts"; input_set_capability(ts->input, EV_ABS, ABS_X); input_set_capability(ts->input, EV_ABS, ABS_Y); input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone); input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); input_set_drvdata(ts->input, ts); error = input_register_device(ts->input); if (error) { dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error); goto release; } /* Try to use ACPI power methods first */ acpipower = false; #ifdef CONFIG_ACPI if (ACPI_COMPANION(&client->dev)) { /* Wake the device up with a power on reset */ if (acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3)) { dev_warn(&client->dev, "%s: failed to wake up device through ACPI: %d, using GPIO controls instead\n", __func__, error); } else { acpipower = true; } } #endif /* Not available, use GPIO settings from DSDT/DT instead */ if (!acpipower) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0); #else ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0, GPIOD_OUT_LOW); #endif if (IS_ERR(ts->gpio)) { dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__); error = PTR_ERR(ts->gpio); goto release; } #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) error = gpiod_direction_output(ts->gpio, 0); if (error < 0) { dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__); goto release; } #endif } else { ts->gpio = NULL; } /* Enable power */ gsl_ts_power(client, false); /* Execute the controller startup sequence */ error = gsl_ts_reset_chip(client); if (error < 0) { dev_err(&client->dev, "%s: chip reset failed\n", __func__); goto release; } error = gsl_ts_write_fw(ts, fw); if (error < 0) { dev_err(&client->dev, "%s: firmware transfer failed\n", __func__); goto release; } error = gsl_ts_startup_chip(client); if (error < 0) { dev_err(&client->dev, "%s: chip startup failed\n", __func__); goto release; } /* * Systems using device tree should set up interrupt via DTS, * the rest will use the default falling edge interrupts. */ irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; /* Set up interrupt handler - do we still need to account for shared interrupts? */ error = devm_request_threaded_irq( &client->dev, client->irq, NULL, gsl_ts_irq, irqflags | IRQF_ONESHOT, client->name, ts ); if (error) { dev_err(&client->dev, "%s: failed to register interrupt\n", __func__); goto release; } /* * Systems using device tree should set up wakeup via DTS, * the rest will configure device as wakeup source by default. */ if (!client->dev.of_node) { device_init_wakeup(&client->dev, true); } ts->state = GSL_TS_GREEN; release: if (fw) { release_firmware(fw); } if (error < 0) { return error; } return 0; }