diff --git a/drivers/input/touchscreen/focaltech_0flash_mmi/Android.mk b/drivers/input/touchscreen/focaltech_0flash_mmi/Android.mk index a8b703831add..f4a2244e17d0 100644 --- a/drivers/input/touchscreen/focaltech_0flash_mmi/Android.mk +++ b/drivers/input/touchscreen/focaltech_0flash_mmi/Android.mk @@ -15,6 +15,10 @@ ifneq ($(BOARD_USES_TOUCH_PALM),) KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_ENABLE_PALM=y endif +ifneq ($(BOARD_USES_PEN_NOTIFIER),) + KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_PEN_NOTIFIER=y +endif + include $(CLEAR_VARS) LOCAL_MODULE := focaltech_0flash_mmi.ko LOCAL_MODULE_TAGS := optional diff --git a/drivers/input/touchscreen/focaltech_0flash_mmi/Kbuild b/drivers/input/touchscreen/focaltech_0flash_mmi/Kbuild index 28f36621c81f..8cb1f728ecf2 100644 --- a/drivers/input/touchscreen/focaltech_0flash_mmi/Kbuild +++ b/drivers/input/touchscreen/focaltech_0flash_mmi/Kbuild @@ -40,3 +40,7 @@ endif ifneq ($(filter m y,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_ENABLE_PALM)),) EXTRA_CFLAGS += -DFOCALTECH_PALM_SENSOR_EN endif +ifneq ($(filter m y,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_PEN_NOTIFIER)),) + KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../../../misc/pen/Module.symvers + EXTRA_CFLAGS += -DFOCALTECH_PEN_NOTIFIER +endif diff --git a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_common.h b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_common.h index 71720beef82e..2f281b43c81e 100755 --- a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_common.h +++ b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_common.h @@ -96,6 +96,7 @@ #define FTS_REG_IDE_PARA_STATUS 0xB6 #define FTS_REG_GLOVE_MODE_EN 0xC0 #define FTS_REG_COVER_MODE_EN 0xC1 +#define FTS_REG_PEN_DETECTION 0xC2 #define FTS_REG_CHARGER_MODE_EN 0x8B #define FTS_REG_GESTURE_EN 0xD0 #define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3 diff --git a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.c b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.c index 83a5c6e10710..643d70a16988 100755 --- a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.c +++ b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.c @@ -38,6 +38,9 @@ #include #include +#ifdef FOCALTECH_PEN_NOTIFIER +#include +#endif #ifdef CONFIG_DRM #include #elif defined(CONFIG_FB) @@ -93,6 +96,9 @@ static struct sensors_classdev __maybe_unused palm_sensors_touch_cdev = { /***************************************************************************** * Static function prototypes *****************************************************************************/ +#ifdef FOCALTECH_PEN_NOTIFIER +static int fts_mcu_pen_detect_set(uint8_t pen_detect); +#endif static int fts_ts_suspend(struct device *dev); static int fts_ts_resume(struct device *dev); @@ -151,6 +157,9 @@ void fts_tp_state_recovery(struct fts_ts_data *ts_data) #endif #if FTS_GESTURE_EN fts_gesture_recovery(ts_data); +#endif +#ifdef FOCALTECH_PEN_NOTIFIER + fts_mcu_pen_detect_set(ts_data->fts_pen_detect_flag); #endif FTS_FUNC_EXIT(); } @@ -807,6 +816,48 @@ void fts_cable_detect_func(bool force_renew) } #endif +#ifdef FOCALTECH_PEN_NOTIFIER +static int fts_mcu_pen_detect_set(uint8_t pen_detect) +{ + uint8_t write_data = 0; + uint8_t read_data = 0; + uint8_t retry_cnt = 0; + int ret = 0; + + do{ + if (pen_detect == PEN_DETECTION_INSERT) { + write_data= 0x01; + ret = fts_write_reg(FTS_REG_PEN_DETECTION, write_data); + if (ret < 0) { + FTS_ERROR("set register PEN IN fail, ret=%d", ret); + return ret; + } + FTS_INFO("%s: PEN detect status IN!\n", __func__); + } else if (pen_detect == PEN_DETECTION_PULL) { + write_data= 0x00; + ret = fts_write_reg(FTS_REG_PEN_DETECTION, write_data); + if (ret < 0) { + FTS_ERROR("set register PEN OUT fail, ret=%d", ret); + return ret; + } + FTS_INFO("%s: PEN detect status OUT!\n", __func__); + } + + ret = fts_read_reg(FTS_REG_PEN_DETECTION, &read_data); + if (ret < 0) + FTS_ERROR("read 8b register fail, ret=%d", ret); + retry_cnt++; + }while((write_data != read_data) && retry_cnt < FTS_REG_RETRY_TIMES); + + if (retry_cnt >= FTS_REG_RETRY_TIMES) { + FTS_ERROR("write pen status fail"); + return -EIO; + } + + return 0; +} +#endif + static void fts_irq_read_report(void) { int ret = 0; @@ -1568,6 +1619,34 @@ static void fts_resume_work(struct work_struct *work) } #endif +#ifdef FOCALTECH_PEN_NOTIFIER +static int pen_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + int ret = 0; + + struct fts_ts_data *ts_data = + container_of(self, struct fts_ts_data, pen_notif); + FTS_INFO("Received event(%lu) for pen detection\n", event); + + if (event == PEN_DETECTION_INSERT) + ts_data->fts_pen_detect_flag = PEN_DETECTION_INSERT; + else if (event == PEN_DETECTION_PULL) + ts_data->fts_pen_detect_flag = PEN_DETECTION_PULL; + + if ((fts_data->suspended) || (!fts_data->fw_is_running)) { + FTS_INFO("touch in suspend or no firmware, so store."); + } else { + ret = fts_mcu_pen_detect_set(ts_data->fts_pen_detect_flag); + if (ret < 0) { + FTS_ERROR("write pen state fail"); + } + } + + return 0; +} +#endif + #ifdef CONFIG_DRM int drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) @@ -1857,6 +1936,15 @@ static int fts_ts_probe_entry(struct fts_ts_data *ts_data) FTS_ERROR("init fw upgrade fail"); } +#ifdef FOCALTECH_PEN_NOTIFIER + ts_data->fts_pen_detect_flag = PEN_DETECTION_PULL; + ts_data->pen_notif.notifier_call = pen_notifier_callback; + ret = pen_detection_register_client(&ts_data->pen_notif); + if (ret) { + FTS_ERROR("[PEN]Unable to register pen_notifier: %d\n", ret); + } +#endif + #ifdef CONFIG_DRM if (ts_data->ts_workqueue) { INIT_WORK(&ts_data->resume_work, fts_resume_work); @@ -1975,7 +2063,10 @@ static int fts_ts_remove_entry(struct fts_ts_data *ts_data) if (ts_data->ts_workqueue) destroy_workqueue(ts_data->ts_workqueue); - +#ifdef FOCALTECH_PEN_NOTIFIER + if (pen_detection_unregister_client(&ts_data->pen_notif)) + FTS_ERROR("Error occurred while unregistering pen_notifier.\n"); +#endif #ifdef CONFIG_DRM if (msm_drm_unregister_client(&ts_data->fb_notif)) FTS_ERROR("Error occurred while unregistering fb_notifier.\n"); diff --git a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.h b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.h index 447555bfd85c..5f23d9d320e4 100755 --- a/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.h +++ b/drivers/input/touchscreen/focaltech_0flash_mmi/focaltech_core.h @@ -223,7 +223,10 @@ struct fts_ts_data { struct pinctrl_state *pins_suspend; struct pinctrl_state *pins_release; #endif - +#ifdef FOCALTECH_PEN_NOTIFIER + int fts_pen_detect_flag; + struct notifier_block pen_notif; +#endif #if defined(CONFIG_FB) || defined(CONFIG_DRM) struct notifier_block fb_notif; #elif defined(CONFIG_HAS_EARLYSUSPEND)