diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c index 12618452be52..5460576db453 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c @@ -386,6 +386,69 @@ static ssize_t gesture_store(struct device *dev, return size; } static DEVICE_ATTR(gesture, (S_IWUSR | S_IWGRP | S_IRUGO), gesture_show, gesture_store); + +/* + * cli_gesture value used to indicate which gesture mode type is enabled + */ +static ssize_t cli_gesture_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%02x\n", touch_cdev->pdata.cli_supported_gesture_type); +} + +static ssize_t cli_gesture_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + unsigned int value = 0; + int err = 0; + + mutex_lock(&touch_cdev->extif_mutex); + err = sscanf(buf, "%d", &value); + if (err < 0) { + dev_err(dev, "CLI Failed to convert value\n"); + return -EINVAL; + } + switch (value) { + case 0x10: + dev_info(dev, "%s: CLI zero tap disable\n", __func__); + touch_cdev->cli_gesture_mode_type &= 0xFE; + break; + case 0x11: + dev_info(dev, "%s: CLI zero tap enable\n", __func__); + touch_cdev->cli_gesture_mode_type |= 0x01; + break; + case 0x20: + dev_info(dev, "%s: CLI single tap disable\n", __func__); + touch_cdev->cli_gesture_mode_type &= 0xFD; + break; + case 0x21: + dev_info(dev, "%s: CLI single tap enable\n", __func__); + touch_cdev->cli_gesture_mode_type |= 0x02; + break; + case 0x30: + dev_info(dev, "%s: CLI double tap disable\n", __func__); + touch_cdev->cli_gesture_mode_type &= 0xFB; + break; + case 0x31: + dev_info(dev, "%s: CLI double tap enable\n", __func__); + touch_cdev->cli_gesture_mode_type |= 0x04; + break; + default: + dev_info(dev, "%s: CLI unsupport gesture mode type\n", __func__); + ; + } + mutex_unlock(&touch_cdev->extif_mutex); + dev_info(dev, "%s: cli_gesture_mode_type = 0x%02x \n", __func__, + touch_cdev->cli_gesture_mode_type); + + return size; +} + +static DEVICE_ATTR(cli_gesture, (S_IRUGO | S_IWUSR | S_IWGRP), + cli_gesture_show, cli_gesture_store); #endif static struct attribute *sysfs_class_attrs[] = { @@ -419,6 +482,7 @@ static struct attribute *sysfs_class_attrs[] = { #endif #ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL &dev_attr_gesture.attr, + &dev_attr_cli_gesture.attr, #endif NULL, }; @@ -856,6 +920,15 @@ int ts_mmi_dev_register(struct device *parent, } } + if (touch_cdev->pdata.cli_gestures_enabled) { + ret = ts_mmi_cli_gesture_init(touch_cdev); + if (ret < 0) { + dev_err(DEV_TS, "%s: Register CLI gesture failed. %d\n", + __func__, ret); + goto GESTURE_INIT_FAILED; + } + } + if (touch_cdev->pdata.palm_enabled) { ret = ts_mmi_palm_init(touch_cdev); if (ret < 0) { @@ -923,6 +996,8 @@ void ts_mmi_dev_unregister(struct device *parent) } if (touch_cdev->pdata.gestures_enabled) ts_mmi_gesture_remove(touch_cdev); + if (touch_cdev->pdata.cli_gestures_enabled) + ts_mmi_cli_gesture_remove(touch_cdev); if (touch_cdev->pdata.palm_enabled) ts_mmi_palm_remove(touch_cdev); ts_mmi_notifiers_unregister(touch_cdev); diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c index 373404e66fd6..609d292eb6df 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c @@ -79,6 +79,7 @@ struct ts_mmi_touch_events_data { static struct ts_mmi_sensor_platform_data *sensor_pdata; static struct ts_mmi_sensor_platform_data *palm_sensor_pdata; static struct ts_mmi_touch_events_data *events_data; +static struct ts_mmi_sensor_platform_data *cli_sensor_pdata; #ifdef TS_MMI_TOUCH_GESTURE_LOG_EVENT static inline void ts_mmi_touch_log_event(struct touch_event_with_time_data *dst, const struct touch_event_data *src) @@ -437,6 +438,26 @@ static struct sensors_classdev __maybe_unused sensors_touch_cdev = { .sensors_poll_delay = NULL, }; +static struct sensors_classdev __maybe_unused cli_sensors_touch_cdev = { + .name = "s-dt-gesture", + .vendor = "Motorola", + .version = 1, + .type = SENSOR_TYPE_MOTO_DOUBLE_TAP, + .max_range = "5.0", + .resolution = "5.0", + .sensor_power = "1", + .min_delay = 0, + .max_delay = 0, + /* WAKE_UP & SPECIAL_REPORT */ + .flags = 1 | 6, + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 200, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, +}; + static struct sensors_classdev __maybe_unused palm_sensors_touch_cdev = { .name = "palm-gesture", .vendor = "Motorola", @@ -557,6 +578,81 @@ int ts_mmi_gesture_remove(struct ts_mmi_dev *touch_cdev) return 0; } +int ts_mmi_cli_gesture_init(struct ts_mmi_dev *touch_cdev) +{ + struct input_dev *sensor_input_dev; + int err; + + sensor_input_dev = input_allocate_device(); + if (!sensor_input_dev) { + dev_err(DEV_TS, "%s: Failed to allocate input device", __func__); + goto exit; + } + + cli_sensor_pdata = devm_kzalloc(&sensor_input_dev->dev, + sizeof(struct ts_mmi_sensor_platform_data), GFP_KERNEL); + if (!cli_sensor_pdata) { + dev_err(DEV_TS, "%s: Failed to allocate memory", __func__); + goto free_sensor_input_dev; + } + + __set_bit(EV_KEY, sensor_input_dev->evbit); + __set_bit(KEY_F1, sensor_input_dev->keybit); + __set_bit(KEY_F2, sensor_input_dev->keybit); + __set_bit(KEY_F3, sensor_input_dev->keybit); + __set_bit(KEY_F4, sensor_input_dev->keybit); + __set_bit(EV_ABS, sensor_input_dev->evbit); + __set_bit(EV_SYN, sensor_input_dev->evbit); + /* TODO: fill in real screen resolution */ + input_set_abs_params(sensor_input_dev, ABS_X, 0, 4096, 0, 0); + input_set_abs_params(sensor_input_dev, ABS_Y, 0, 4096, 0, 0); + + sensor_input_dev->name = "s-double-tap"; + cli_sensor_pdata->input_sensor_dev = sensor_input_dev; + + err = input_register_device(sensor_input_dev); + if (err) { + dev_err(DEV_TS, "%s: Unable to register device, err=%d", __func__, err); + goto free_sensor_pdata; + } + + cli_sensor_pdata->ps_cdev = cli_sensors_touch_cdev; + cli_sensor_pdata->ps_cdev.sensors_enable = ts_mmi_sensor_set_enable; + cli_sensor_pdata->touch_cdev = touch_cdev; + + err = sensors_classdev_register(&sensor_input_dev->dev, + &cli_sensor_pdata->ps_cdev); + if (err) + goto unregister_sensor_input_device; + + /* export report gesture function to vendor */ + touch_cdev->mdata->exports.report_gesture = ts_mmi_gesture_handler; + + return 0; + +unregister_sensor_input_device: + input_unregister_device(sensor_input_dev); + sensor_input_dev = NULL; +free_sensor_pdata: + if (sensor_input_dev && cli_sensor_pdata) + devm_kfree(&sensor_input_dev->dev, cli_sensor_pdata); +free_sensor_input_dev: + if (sensor_input_dev) + input_free_device(sensor_input_dev); +exit: + return 1; +} + +int ts_mmi_cli_gesture_remove(struct ts_mmi_dev *touch_cdev) +{ + sensors_classdev_unregister(&cli_sensor_pdata->ps_cdev); + input_unregister_device(cli_sensor_pdata->input_sensor_dev); + devm_kfree(&cli_sensor_pdata->input_sensor_dev->dev, cli_sensor_pdata); + cli_sensor_pdata = NULL; + + return 0; +} + int ts_mmi_palm_init(struct ts_mmi_dev *touch_cdev) { struct input_dev *sensor_input_dev; diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c index 48ecf857a93d..e4dc701af170 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c @@ -59,7 +59,7 @@ static int ts_mmi_panel_off(struct ts_mmi_dev *touch_cdev) { atomic_set(&touch_cdev->resume_should_stop, 1); TRY_TO_CALL(pre_suspend); - if (touch_cdev->pdata.gestures_enabled) { + if (touch_cdev->pdata.gestures_enabled || touch_cdev->pdata.cli_gestures_enabled) { #ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL if(touch_cdev->gesture_mode_type != 0) { if(touch_cdev->gesture_mode_type & 0x01) { @@ -78,6 +78,26 @@ static int ts_mmi_panel_off(struct ts_mmi_dev *touch_cdev) { dev_info(DEV_MMI, "%s: notify touch driver to switch gesture mode\n", __func__); TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_SWITCH); + touch_cdev->pm_mode = TS_MMI_PM_GESTURE; + } + //CLI touch + if (touch_cdev->cli_gesture_mode_type != 0) { + if(touch_cdev->cli_gesture_mode_type & 0x01) { + dev_info(DEV_MMI, "%s: CLI try to enter zero Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_CLI_ZERO); + } + if(touch_cdev->cli_gesture_mode_type & 0x02) { + dev_info(DEV_MMI, "%s: CLI try to enter single Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_CLI_SINGLE); + } + if(touch_cdev->cli_gesture_mode_type & 0x04) { + dev_info(DEV_MMI, "%s: CLI try to enter double Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_CLI_DOUBLE); + } + + dev_info(DEV_MMI, "%s: notify touch driver to switch CLI gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_SWITCH); + touch_cdev->pm_mode = TS_MMI_PM_GESTURE; } #else diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c index 9164b879b0b9..528ea5e73ceb 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c @@ -90,6 +90,11 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev, ppdata->gestures_enabled = true; } + if (of_property_read_bool(of_node, "mmi,cli-enable-gestures")) { + dev_info(DEV_TS, "%s: using enable cli gestures\n", __func__); + ppdata->cli_gestures_enabled = true; + } + if (of_property_read_bool(of_node, "mmi,enable-palm")) { dev_info(DEV_TS, "%s: using enable palm\n", __func__); ppdata->palm_enabled = true; @@ -160,6 +165,10 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev, if (!of_property_read_u32(of_node, "mmi,supported_gesture_type", &ppdata->supported_gesture_type)) dev_info(DEV_TS, "%s: supported_gesture_type property %02x\n", __func__, ppdata->supported_gesture_type); + + if (!of_property_read_u32(of_node, "mmi,cli_supported_gesture_type", &ppdata->cli_supported_gesture_type)) + dev_info(DEV_TS, "%s: cli_supported_gesture_type property %02x\n", + __func__, ppdata->cli_supported_gesture_type); #endif chosen = of_find_node_by_name(NULL, "chosen"); diff --git a/include/linux/touchscreen_mmi.h b/include/linux/touchscreen_mmi.h index cebb9fe7275e..9f6b77cc7f2f 100644 --- a/include/linux/touchscreen_mmi.h +++ b/include/linux/touchscreen_mmi.h @@ -291,6 +291,9 @@ enum ts_mmi_pm_mode { TS_MMI_PM_GESTURE_DOUBLE, TS_MMI_PM_GESTURE_ZERO, TS_MMI_PM_GESTURE_SWITCH, + TS_MMI_PM_GESTURE_CLI_SINGLE, + TS_MMI_PM_GESTURE_CLI_DOUBLE, + TS_MMI_PM_GESTURE_CLI_ZERO }; enum ts_mmi_panel_event { @@ -409,6 +412,7 @@ struct ts_mmi_dev_pdata { bool usb_detection; bool update_refresh_rate; bool gestures_enabled; + bool cli_gestures_enabled; bool palm_enabled; bool fw_load_resume; bool suppression_ctrl; @@ -428,6 +432,7 @@ struct ts_mmi_dev_pdata { const char *bound_display; #ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL int supported_gesture_type; + int cli_supported_gesture_type; #endif }; @@ -455,6 +460,7 @@ struct ts_mmi_dev { int forcereflash; #ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL unsigned char gesture_mode_type; + unsigned char cli_gesture_mode_type; #endif int panel_status; struct ts_mmi_dev_pdata pdata; @@ -566,6 +572,8 @@ extern void ts_mmi_dev_unregister(struct device *parent); extern int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev, struct device_node *of_node); extern int ts_mmi_gesture_init(struct ts_mmi_dev *data); extern int ts_mmi_gesture_remove(struct ts_mmi_dev *data); +extern int ts_mmi_cli_gesture_init(struct ts_mmi_dev *data); +extern int ts_mmi_cli_gesture_remove(struct ts_mmi_dev *data); extern int ts_mmi_palm_init(struct ts_mmi_dev *data); extern int ts_mmi_palm_remove(struct ts_mmi_dev *data); #ifdef TS_MMI_TOUCH_EDGE_GESTURE