mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
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:
parent
ac8b973dac
commit
1b609ecc23
3 changed files with 213 additions and 0 deletions
|
|
@ -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",},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue