From 853418d845952555823cf14979ce29bce63d9cfe Mon Sep 17 00:00:00 2001 From: wangyq13 Date: Wed, 12 Aug 2020 18:18:20 +0800 Subject: [PATCH] input: ilitek_0flash_mmi: add usb charger detection ilitek_0flash_mmi: Add usb charger detection function. Enabled by kernel dtsi. NO_PROP_NEEDED: Change-Id: I2c8349444032e28badee766236adaefb35f04b85 Signed-off-by: wangyq13 Reviewed-on: https://gerrit.mot.com/1720309 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Jun Weng Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- .../touchscreen/ilitek_0flash_mmi/ilitek.c | 7 ++ .../touchscreen/ilitek_0flash_mmi/ilitek.h | 6 ++ .../ilitek_0flash_mmi/ilitek_qcom.c | 102 ++++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.c b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.c index e963a1db49e5..122e5823875b 100644 --- a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.c +++ b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.c @@ -519,6 +519,8 @@ int ili_fw_upgrade_handler(void *data) } atomic_set(&ilits->fw_stat, END); + if(ilits->charger_detection_enable && ilits->boot && (ilits->charger_notify_wq != NULL)) + queue_work(ilits->charger_notify_wq, &ilits->charger_notify_work); return ret; } @@ -1035,6 +1037,11 @@ void ili_dev_remove(void) if (ilits->ws) wakeup_source_unregister(ilits->ws); + if (ilits->charger_notif.notifier_call) + power_supply_unreg_notifier(&ilits->charger_notif); + if (ilits->charger_notify_wq) + destroy_workqueue(ilits->charger_notify_wq); + kfree(ilits->tr_buf); kfree(ilits->gcoord); ili_interface_dev_exit(ilits); diff --git a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.h b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.h index 9a0a2cc590f2..193443f57b7a 100644 --- a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.h +++ b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek.h @@ -778,6 +778,11 @@ struct ilitek_ts_data { struct regulator *vdd; struct regulator *vcc; + struct notifier_block charger_notif; + struct workqueue_struct *charger_notify_wq; + struct work_struct charger_notify_work; + int usb_plug_status; + #ifdef CONFIG_FB struct notifier_block notifier_fb; #else @@ -826,6 +831,7 @@ struct ilitek_ts_data { int irq_num; int irq_gpio; int irq_tirgger_type; + bool charger_detection_enable; int tp_rst; int tp_int; int wait_int_timeout; diff --git a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek_qcom.c b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek_qcom.c index 78caf1dd98dd..418043e073b8 100644 --- a/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek_qcom.c +++ b/drivers/input/touchscreen/ilitek_0flash_mmi/ilitek_qcom.c @@ -807,6 +807,14 @@ static int ilitek_plat_gpio_register(void) ilits->report_gesture_key = 0; } #endif + ilits->charger_detection_enable = of_property_read_bool(dev_node, "ilitek,usb_charger"); + if (!ilits->charger_detection_enable) { + ILI_ERR("error reading ilitek,usb_charger. ilits->charger_detection_enable = %d\n", + ilits->charger_detection_enable); + } else { + ILI_INFO("ilitek,usb_charger = %d\n", ilits->charger_detection_enable); + } + ilits->tp_int = of_get_named_gpio_flags(dev_node, DTS_INT_GPIO, 0, &flag); ilits->tp_rst = of_get_named_gpio_flags(dev_node, DTS_RESET_GPIO, 0, &flag); @@ -850,6 +858,93 @@ out: return ret; } +static int ilitek_charger_notifier_callback(struct notifier_block *nb, + unsigned long val, void *v) +{ + int ret = 0; + struct power_supply *psy = NULL; + union power_supply_propval prop; + + if(ilits->fw_update_stat != FW_UPDATE_PASS) + return 0; + + psy= power_supply_get_by_name("usb"); + if (!psy) { + ILI_ERR("Couldn't get usbpsy\n"); + return -EINVAL; + } + if (!strcmp(psy->desc->name, "usb")) { + if (psy && val == POWER_SUPPLY_PROP_STATUS) { + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, &prop); + if (ret < 0) { + ILI_ERR("Couldn't get POWER_SUPPLY_PROP_ONLINE rc=%d\n", ret); + return ret; + } else { + if(prop.intval != ilits->usb_plug_status) { + ILI_INFO("usb_plug_status =%d\n", prop.intval); + ilits->usb_plug_status = prop.intval; + if(ilits->charger_detection_enable && !ilits->tp_suspend && + (ilits->charger_notify_wq != NULL)) + queue_work(ilits->charger_notify_wq, &ilits->charger_notify_work); + } + } + } + } + return 0; +} + +static void ilitek_charger_notify_work(struct work_struct *work) +{ + int ret = 0; + + if (NULL == work) { + ILI_ERR("%s: parameter work are null!\n", __func__); + return; + } + ILI_INFO("enter ilitek_charger_notify_work\n"); + + mutex_lock(&ilits->touch_mutex); + ret = ili_ic_func_ctrl("plug", !ilits->usb_plug_status);// plug in + if(ret<0) { + ILI_ERR("Write plug in failed\n"); + } + mutex_unlock(&ilits->touch_mutex); +} + +void ilitek_plat_charger_init(void) +{ + int ret = 0; + struct power_supply *psy = NULL; + union power_supply_propval prop; + + ilits->charger_notify_wq = create_singlethread_workqueue("ili_charger_wq"); + if (!ilits->charger_notify_wq) { + ILI_ERR("allocate charger_notify_wq failed\n"); + return; + } + INIT_WORK(&ilits->charger_notify_work, ilitek_charger_notify_work); + ilits->charger_notif.notifier_call = ilitek_charger_notifier_callback; + ret = power_supply_reg_notifier(&ilits->charger_notif); + if (ret < 0) + ILI_ERR("power_supply_reg_notifier failed\n"); + + /* if power supply supplier registered brfore TP + * ps_notify_callback will not receive PSY_EVENT_PROP_ADDED + * event, and will cause miss to set TP into charger state. + * So check PS state in probe. + */ + psy = power_supply_get_by_name("usb"); + if (psy) { + ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, &prop); + if (ret < 0) { + ILI_ERR("Couldn't get POWER_SUPPLY_PROP_ONLINE rc=%d\n", ret); + } else { + ilits->usb_plug_status = prop.intval; + ILI_INFO("boot check usb_plug_status = %d\n", prop.intval); + } + } +} + static int ilitek_plat_probe(void) { #ifdef ILI_SENSOR_EN @@ -864,12 +959,19 @@ static int ilitek_plat_probe(void) if (ilitek_plat_gpio_register() < 0) ILI_ERR("Register gpio failed\n"); + if (ilits->charger_detection_enable) + ilitek_plat_charger_init(); + if (ili_tddi_init() < 0) { ILI_ERR("ILITEK Driver probe failed\n"); if(gpio_is_valid(ilits->tp_int)) gpio_free(ilits->tp_int); if(gpio_is_valid(ilits->tp_rst)) gpio_free(ilits->tp_rst); + if (ilits->charger_notif.notifier_call) + power_supply_unreg_notifier(&ilits->charger_notif); + if (ilits->charger_notify_wq) + destroy_workqueue(ilits->charger_notify_wq); return -ENODEV; }