nova_0flash_mmi: notify firmware when usb connected

TP:
When USB connected, notify this info to firmware.
This will help firmware to handle ghost touch issue.

Change-Id: I86ac9a721eb6fdca3cb3a9c38d1b55290f6b8175
Signed-off-by: haojl2 <haojl2@motorola.com>
Reviewed-on: https://gerrit.mot.com/1448175
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Jun Weng <wengjun1@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
haojl2 2019-09-27 12:43:55 +08:00 • committed by Yeqing Wang
commit 1b609ecc23
3 changed files with 213 additions and 0 deletions

View file

@ -24,6 +24,7 @@
#include <linux/input/mt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/power_supply.h>
#if defined(CONFIG_FB)
#ifdef CONFIG_DRM_MSM
@ -109,6 +110,10 @@ static void nvt_ts_late_resume(struct early_suspend *h);
uint32_t ENG_RST_ADDR = 0x7FFF80;
uint32_t SWRST_N8_ADDR = 0; //read from dtsi
uint32_t SPI_RD_FAST_ADDR = 0; //read from dtsi
static int charger_notifier_callback(struct notifier_block *nb, unsigned long val, void *v);
static int nvt_set_charger(uint8_t charger_on_off);
static void nvt_charger_notify_work(struct work_struct *work);
static int usb_detect_flag = 0;
#if TOUCH_KEY_NUM > 0
const uint16_t touch_key_array[TOUCH_KEY_NUM] = {
@ -1110,6 +1115,12 @@ static int32_t nvt_parse_dt(struct device *dev)
} else {
NVT_LOG("SPI_RD_FAST_ADDR=0x%06X\n", SPI_RD_FAST_ADDR);
}
if (of_property_read_bool(np, "novatek,usb_charger")) {
NVT_LOG("novatek,usb_charger set");
ts->charger_detection_enable = 1;
} else {
ts->charger_detection_enable = 0;
}
return ret;
}
@ -1940,6 +1951,59 @@ static int32_t nvt_ts_probe(struct spi_device *client)
}
#endif
if (ts->charger_detection_enable) {
ts->charger_detection = kzalloc(sizeof(struct usb_charger_detection), GFP_KERNEL);
if (ts->charger_detection == NULL) {
NVT_ERR("failed to allocated memory for usb_charger_detection\n");
goto err_charger_detection_alloc_failed;
}
}
if (ts->charger_detection) {
struct power_supply *psy = NULL;
union power_supply_propval prop = {0};
NVT_LOG("charger_detection on");
ts->charger_detection->usb_connected = 0;
ts->charger_detection->nvt_charger_notify_wq = create_singlethread_workqueue("nvt_charger_wq");
if (!ts->charger_detection->nvt_charger_notify_wq) {
NVT_ERR("allocate nvt_charger_notify_wq failed\n");
goto err_charger_notify_wq_failed;
}
INIT_WORK(&ts->charger_detection->charger_notify_work, nvt_charger_notify_work);
ts->charger_detection->charger_notif.notifier_call = charger_notifier_callback;
ret = power_supply_reg_notifier(&ts->charger_detection->charger_notif);
if (ret) {
NVT_ERR("Unable to register charger_notifier:%d\n", ret);
goto err_register_charger_notify_failed;
}
/* 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) {
NVT_ERR("Couldn't get POWER_SUPPLY_PROP_ONLINE rc=%d\n", ret);
goto err_register_charger_notify_failed;
} else {
usb_detect_flag = prop.intval;
if (usb_detect_flag != ts->charger_detection->usb_connected) {
if (USB_DETECT_IN == usb_detect_flag) {
ts->charger_detection->usb_connected = USB_DETECT_IN;
} else {
ts->charger_detection->usb_connected = USB_DETECT_OUT;
}
nvt_set_charger(ts->charger_detection->usb_connected);
}
}
}
}
#if BOOT_UPDATE_FIRMWARE
nvt_fwu_wq = alloc_workqueue("nvt_fwu_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
if (!nvt_fwu_wq) {
@ -2075,6 +2139,16 @@ err_create_nvt_fwu_wq_failed:
#if WAKEUP_GESTURE
device_init_wakeup(&ts->input_dev->dev, 0);
#endif
err_register_charger_notify_failed:
if (ts->charger_detection) {
if (ts->charger_detection->charger_notif.notifier_call)
power_supply_unreg_notifier(&ts->charger_detection->charger_notif);
destroy_workqueue(ts->charger_detection->nvt_charger_notify_wq);
ts->charger_detection->nvt_charger_notify_wq = NULL;
kfree(ts->charger_detection);
}
err_charger_detection_alloc_failed:
err_charger_notify_wq_failed:
free_irq(client->irq, ts);
err_int_request_failed:
input_unregister_device(ts->input_dev);
@ -2132,6 +2206,12 @@ static int32_t nvt_ts_remove(struct spi_device *client)
#endif
#if NVT_TOUCH_PROC
nvt_flash_proc_deinit();
if (ts->charger_detection) {
if (ts->charger_detection->charger_notif.notifier_call)
power_supply_unreg_notifier(&ts->charger_detection->charger_notif);
destroy_workqueue(ts->charger_detection->nvt_charger_notify_wq);
kfree(ts->charger_detection);
}
#endif
#if NVT_TOUCH_ESD_PROTECT
@ -2380,6 +2460,10 @@ static int32_t nvt_ts_resume(struct device *dev)
msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
#endif /* #if NVT_TOUCH_ESD_PROTECT */
if (ts->charger_detection) {
queue_work(ts->charger_detection->nvt_charger_notify_wq, &ts->charger_detection->charger_notify_work);
}
#if WAKEUP_GESTURE
#ifdef NVT_SENSOR_EN
if (ts->wakeable) {
@ -2495,6 +2579,117 @@ static const struct spi_device_id nvt_ts_id[] = {
{ }
};
static int nvt_set_charger(uint8_t charger_on_off)
{
uint8_t buf[8] = {0};
int32_t ret = 0;
NVT_LOG("set charger: %d\n", charger_on_off);
msleep(20);
//---set xdata index to EVENT BUF ADDR---
ret = nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HOST_CMD);
if (ret < 0) {
NVT_ERR("Set event buffer index fail!\n");
goto nvt_set_charger_out;
}
if (charger_on_off == USB_DETECT_IN) {
buf[0] = EVENT_MAP_HOST_CMD;
buf[1] = CMD_CHARGER_ON;
ret = CTP_SPI_WRITE(ts->client, buf, 2);
if (ret < 0) {
NVT_ERR("Write set charger command fail!\n");
goto nvt_set_charger_out;
} else {
NVT_LOG("set charger on cmd succeeded\n");
}
} else if (charger_on_off == USB_DETECT_OUT) {
buf[0] = EVENT_MAP_HOST_CMD;
buf[1] = CMD_CHARGER_OFF;
ret = CTP_SPI_WRITE(ts->client, buf, 2);
if (ret < 0) {
NVT_ERR("Write set charger command fail!\n");
goto nvt_set_charger_out;
} else {
NVT_LOG("set charger off cmd succeeded\n");
}
} else {
NVT_ERR("Invalid charger parameter!\n");
ret = -EINVAL;
}
nvt_set_charger_out:
return ret;
}
static void nvt_charger_notify_work(struct work_struct *work)
{
if (NULL == work) {
NVT_ERR("%s: parameter work are null!\n", __func__);
return;
}
NVT_LOG("enter\n");
if (USB_DETECT_IN == usb_detect_flag) {
if (mutex_lock_interruptible(&ts->lock)) {
NVT_ERR("Failed to lock in mutex_lock_interruptible(&ts->lock).\n");
return;
}
nvt_set_charger(USB_DETECT_IN);
mutex_unlock(&ts->lock);
} else if (USB_DETECT_OUT == usb_detect_flag) {
if (mutex_lock_interruptible(&ts->lock)) {
NVT_ERR("Failed to lock in mutex_lock_interruptible(&ts->lock).\n");
return;
}
nvt_set_charger(USB_DETECT_OUT);
mutex_unlock(&ts->lock);
}else{
NVT_LOG("Charger flag:%d not currently required!\n",usb_detect_flag);
}
}
static int charger_notifier_callback(struct notifier_block *nb,
unsigned long val, void *v)
{
int ret = 0;
struct power_supply *psy = NULL;
struct usb_charger_detection *charger_detection =
container_of(nb, struct usb_charger_detection, charger_notif);
union power_supply_propval prop;
psy= power_supply_get_by_name("usb");
if (!psy){
return -EINVAL;
NVT_ERR("Couldn't get usbpsy\n");
}
if (!strcmp(psy->desc->name, "usb")){
if (psy && charger_detection && val == POWER_SUPPLY_PROP_STATUS) {
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT,&prop);
if (ret < 0) {
NVT_ERR("Couldn't get POWER_SUPPLY_PROP_ONLINE rc=%d\n", ret);
return ret;
}else{
usb_detect_flag = prop.intval;
if(usb_detect_flag != charger_detection->usb_connected) {
if (USB_DETECT_IN == usb_detect_flag) {
charger_detection->usb_connected = USB_DETECT_IN;
}else{
charger_detection->usb_connected = USB_DETECT_OUT;
}
if (bTouchIsAwake){
queue_work(charger_detection->nvt_charger_notify_wq,
&charger_detection->charger_notify_work);
}
}
}
}
}
return 0;
}
#ifdef CONFIG_OF
static struct of_device_id nvt_match_table[] = {
{ .compatible = "novatek,NVT-ts-spi",},

View file

@ -123,6 +123,19 @@ struct nvt_sensor_platform_data {
};
#endif
/* charger detect */
#define USB_DETECT_IN 1
#define USB_DETECT_OUT 0
#define CMD_CHARGER_ON (0x53)
#define CMD_CHARGER_OFF (0x51)
struct usb_charger_detection {
struct notifier_block charger_notif;
uint8_t usb_connected;
struct workqueue_struct *nvt_charger_notify_wq;
struct work_struct charger_notify_work;
};
struct nvt_ts_data {
struct spi_device *client;
struct input_dev *input_dev;
@ -162,6 +175,8 @@ struct nvt_ts_data {
#ifdef CONFIG_MTK_SPI
struct mt_chip_conf spi_ctrl;
#endif
uint32_t charger_detection_enable;
struct usb_charger_detection *charger_detection;
#ifdef CONFIG_SPI_MT65XX
struct mtk_chip_config spi_ctrl;
#endif

View file

@ -1008,6 +1008,9 @@ void Boot_Update_Firmware(struct work_struct *work)
} else {
nvt_check_fw_reset_state(RESET_STATE_REK);
}
if (ts->charger_detection) {
queue_work(ts->charger_detection->nvt_charger_notify_wq, &ts->charger_detection->charger_notify_work);
}
mutex_unlock(&ts->lock);
}