diff --git a/drivers/input/touchscreen/nova_0flash_mmi/Android.mk b/drivers/input/touchscreen/nova_0flash_mmi/Android.mk index 4d7536a1a96e..5fdb2c717d7b 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/Android.mk +++ b/drivers/input/touchscreen/nova_0flash_mmi/Android.mk @@ -15,6 +15,17 @@ ifneq ($(BOARD_USES_PANEL_NOTIFICATIONS),) KERNEL_CFLAGS += CONFIG_INPUT_NOVA_PANEL_NOTIFICATIONS=y endif +ifneq ($(BOARD_USES_PEN_NOTIFIER),) + KERNEL_CFLAGS += CONFIG_INPUT_NOVA_0FLASH_MMI_PEN_NOTIFIER=y +endif + +ifneq ($(BOARD_USES_STYLUS_PALM),) + KERNEL_CFLAGS += CONFIG_INPUT_NOVA_0FLASH_MMI_STYLUS_PALM=y +endif + +ifneq ($(BOARD_USES_STYLUS_PALM_RANGE),) + KERNEL_CFLAGS += CONFIG_INPUT_NOVA_0FLASH_MMI_STYLUS_PALM_RANGE=y +endif include $(CLEAR_VARS) LOCAL_MODULE := nova_0flash_mmi.ko LOCAL_MODULE_TAGS := optional diff --git a/drivers/input/touchscreen/nova_0flash_mmi/Kbuild b/drivers/input/touchscreen/nova_0flash_mmi/Kbuild index c80094bee12a..99fe5c9a653b 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/Kbuild +++ b/drivers/input/touchscreen/nova_0flash_mmi/Kbuild @@ -1,7 +1,7 @@ # add -Wall to try to catch everything we can. EXTRA_CFLAGS += -Wall -EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \ - -I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/nova_0flash_mmi +EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \ + -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/input/touchscreen/nova_0flash_mmi ifeq ($(filter m y, $(CONFIG_TOUCHSCREEN_NT36xxx_HOSTDL_SPI)),) obj-m := nova_0flash_mmi.o @@ -13,6 +13,16 @@ ifneq ($(filter m y,$(CONFIG_INPUT_NOVA_PANEL_NOTIFICATIONS)),) EXTRA_CFLAGS += -DNVT_CONFIG_PANEL_NOTIFICATIONS endif +ifneq ($(filter m y,$(CONFIG_INPUT_NOVA_0FLASH_MMI_STYLUS_PALM)),) + EXTRA_CFLAGS += -DPALM_GESTURE +endif +ifneq ($(filter m y,$(CONFIG_INPUT_NOVA_0FLASH_MMI_STYLUS_PALM_RANGE)),) + EXTRA_CFLAGS += -DPALM_GESTURE_RANGE +endif +ifneq ($(filter m y,$(CONFIG_INPUT_NOVA_0FLASH_MMI_PEN_NOTIFIER)),) + KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../../../misc/pen/Module.symvers + EXTRA_CFLAGS += -DNOVATECH_PEN_NOTIFIER +endif nova_0flash_mmi-objs += nt36xxx.o nova_0flash_mmi-objs += nt36xxx_ext_proc.o nova_0flash_mmi-objs += nt36xxx_fw_update.o diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c index 19114c98f4d1..d17b046e4b27 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c @@ -27,6 +27,14 @@ #include #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) +#include +#include +#include +#include +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef CONFIG_DRM_MSM #include @@ -36,7 +44,7 @@ #elif defined(CONFIG_HAS_EARLYSUSPEND) #include #endif - +#endif //end version code >= 5.4.0 #include "nt36xxx.h" #if NVT_TOUCH_ESD_PROTECT #include @@ -103,11 +111,26 @@ extern void nvt_mp_proc_deinit(void); struct nvt_ts_data *ts; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) +static struct drm_panel *active_panel; +#endif +#endif + #if BOOT_UPDATE_FIRMWARE static struct workqueue_struct *nvt_fwu_wq; extern void Boot_Update_Firmware(struct work_struct *work); #endif +#ifdef NOVATECH_PEN_NOTIFIER +int nvt_mcu_pen_detect_set(uint8_t pen_detect); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) +static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data); +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef _MSM_DRM_NOTIFY_H_ static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data); @@ -122,6 +145,7 @@ static void nvt_ts_late_resume(struct early_suspend *h); #ifdef NVT_CONFIG_PANEL_NOTIFICATIONS static int nvt_panel_notifier_callback(struct notifier_block *self, unsigned long event, void *data); #endif +#endif //end version code >= 5.4.0 uint32_t ENG_RST_ADDR = 0x7FFF80; uint32_t SWRST_N8_ADDR = 0; //read from dtsi @@ -131,6 +155,9 @@ 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; +char *nvt_boot_firmware_name = NULL; +char *nvt_mp_firmware_name = NULL; + #if TOUCH_KEY_NUM > 0 const uint16_t touch_key_array[TOUCH_KEY_NUM] = { KEY_BACK, @@ -1105,6 +1132,34 @@ static int nvt_get_dt_def_coords(struct device *dev, char *name) return rc; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) +static int nova_check_dt(struct device_node *np) +{ + int i; + int count; + struct device_node *node; + struct drm_panel *panel; + + count = of_count_phandle_with_args(np, "panel", NULL); + if (count <= 0) + return 0; + + for (i = 0; i < count; i++) { + node = of_parse_phandle(np, "panel", i); + panel = of_drm_find_panel(node); + of_node_put(node); + if (!IS_ERR(panel)) { + active_panel = panel; + return 0; + } + } + + return -ENODEV; +} +#endif +#endif + static int32_t nvt_parse_dt(struct device *dev) { struct device_node *np = dev->of_node; @@ -1125,6 +1180,29 @@ static int32_t nvt_parse_dt(struct device *dev) NVT_LOG("SWRST_N8_ADDR=0x%06X\n", SWRST_N8_ADDR); } + ret = of_property_read_string(np, "novatek,panel-supplier", + &ts->panel_supplier); + if (ret < 0) { + NVT_LOG("Unable to read panel supplier\n"); + } else { + NVT_LOG("panel supplier is %s", (char *)ts->panel_supplier); + nvt_boot_firmware_name = kzalloc(NVT_FILE_NAME_LENGTH, GFP_KERNEL); + if (!nvt_boot_firmware_name) { + NVT_LOG("%s: alloc nvt_boot_firmware_name failed\n", __func__); + goto nvt_boot_firmware_name_alloc_failed; + } + nvt_mp_firmware_name = kzalloc(NVT_FILE_NAME_LENGTH, GFP_KERNEL); + if (!nvt_boot_firmware_name) { + NVT_LOG("%s: alloc nvt_boot_firmware_name failed\n", __func__); + goto nvt_mp_firmware_name_alloc_failed; + } + snprintf(nvt_boot_firmware_name, NVT_FILE_NAME_LENGTH, "%s_novatek_ts_fw.bin", + ts->panel_supplier); + snprintf(nvt_mp_firmware_name, NVT_FILE_NAME_LENGTH, "%s_novatek_ts_mp.bin", + ts->panel_supplier); + } + NVT_LOG("boot firmware %s, mp firmware %s", nvt_boot_firmware_name, nvt_mp_firmware_name); + ret = nvt_get_dt_def_coords(dev, "novatek,def-max-resolution"); if (ret) { ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; @@ -1169,6 +1247,13 @@ static int32_t nvt_parse_dt(struct device *dev) } else { ts->report_gesture_key = 0; } + + return ret; + +nvt_mp_firmware_name_alloc_failed: + kfree(nvt_boot_firmware_name); + nvt_boot_firmware_name = NULL; +nvt_boot_firmware_name_alloc_failed: return ret; } #else @@ -1277,7 +1362,10 @@ static void nvt_esd_check_func(struct work_struct *work) mutex_lock(&ts->lock); NVT_ERR("do ESD recovery, timer = %d, retry = %d\n", timer, esd_retry); /* do esd recovery, reload fw */ - nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + if(nvt_boot_firmware_name) + nvt_update_firmware(nvt_boot_firmware_name); + else + nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); mutex_unlock(&ts->lock); /* update interrupt timer */ irq_timer = jiffies; @@ -1348,7 +1436,17 @@ static int32_t nvt_ts_point_data_checksum(uint8_t *buf, uint8_t length) } #endif /* POINT_DATA_CHECKSUM */ +#define FINGER_ENTER 0x01 +#define FINGER_MOVING 0x02 +#ifdef PALM_GESTURE +#define PALM_TOUCH 0x05 +#define POINT_DATA_LEN 120 +#define MINOR_DATA_OFFSET 70 +#define ORIENT_DATA_OFFSET 110 +#else #define POINT_DATA_LEN 65 +#endif + /******************************************************* Description: Novatek touchscreen work function. @@ -1363,7 +1461,11 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) uint32_t position = 0; uint32_t input_x = 0; uint32_t input_y = 0; - uint32_t input_w = 0; + uint32_t input_major = 0; +#ifdef PALM_GESTURE + uint32_t input_minor = 0; + int32_t input_orient = 0; +#endif uint32_t input_p = 0; uint8_t input_id = 0; #if MT_PROTOCOL_B @@ -1396,10 +1498,13 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) #if NVT_TOUCH_WDT_RECOVERY /* ESD protect by WDT */ - if (nvt_wdt_fw_recovery(point_data)) { - NVT_ERR("Recover for fw reset, %02X\n", point_data[1]); - nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); - goto XFER_ERROR; + if (nvt_wdt_fw_recovery(point_data)) { + NVT_ERR("Recover for fw reset, %02X\n", point_data[1]); + if(nvt_boot_firmware_name) + nvt_update_firmware(nvt_boot_firmware_name); + else + nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + goto XFER_ERROR; } #endif /* #if NVT_TOUCH_WDT_RECOVERY */ @@ -1436,8 +1541,13 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) input_id = (uint8_t)(point_data[position + 0] >> 3); if ((input_id == 0) || (input_id > ts->max_touch_num)) continue; - - if (((point_data[position] & 0x07) == 0x01) || ((point_data[position] & 0x07) == 0x02)) { //finger down (enter & moving) +#ifdef PALM_GESTURE + if (((point_data[position] & 0x07) == FINGER_ENTER) + || ((point_data[position] & 0x07) == FINGER_MOVING) + || ((point_data[position] & 0x07) == PALM_TOUCH)) { //finger down (enter & moving) or palm +#else + if (((point_data[position] & 0x07) == FINGER_ENTER) || ((point_data[position] & 0x07) == FINGER_MOVING)) { //finger down (enter & moving) +#endif #if NVT_TOUCH_ESD_PROTECT /* update interrupt timer */ irq_timer = jiffies; @@ -1448,15 +1558,43 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) continue; if ((input_x > ts->abs_x_max) || (input_y > ts->abs_y_max)) continue; - input_w = (uint32_t)(point_data[position + 4]); - if (input_w == 0) - input_w = 1; - if (i < 2) { - input_p = (uint32_t)(point_data[position + 5]) + (uint32_t)(point_data[i + 63] << 8); - if (input_p > TOUCH_FORCE_NUM) - input_p = TOUCH_FORCE_NUM; - } else { + +#ifdef PALM_GESTURE_RANGE + if((point_data[position] & 0x07) == PALM_TOUCH) { //palm + input_minor = (uint32_t)(point_data[1 + MINOR_DATA_OFFSET + i]); + if (input_minor == 0) + input_minor = 1; + + input_orient = (int8_t)(point_data[1 + ORIENT_DATA_OFFSET + i]); + } +#endif + input_major = (uint32_t)(point_data[position + 4]); + if (input_major == 0) + input_major = 1; + +#ifdef PALM_GESTURE + if ((point_data[position] & 0x07) == PALM_TOUCH) { //palm input_p = (uint32_t)(point_data[position + 5]); + if(input_p == 255) + input_p = PALM_HANG; + else if (input_p == 254) + input_p = PALM_HAND_HOLDE; + +#ifdef PALM_GESTURE_RANGE + //dimension-to-pixel + input_minor = input_minor * TOUCH_DEFAULT_MAX_WIDTH / PANEL_REAL_WIDTH * 100; + input_major = input_major * TOUCH_DEFAULT_MAX_HEIGHT / PANEL_REAL_HEIGHT * 100; +#endif + } else +#endif + { + if (i < 2) { + input_p = (uint32_t)(point_data[position + 5]) + (uint32_t)(point_data[i + 63] << 8); + if (input_p > TOUCH_FORCE_NUM) + input_p = TOUCH_FORCE_NUM; + } else { + input_p = (uint32_t)(point_data[position + 5]); + } } if (input_p == 0) input_p = 1; @@ -1470,11 +1608,28 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) input_report_key(ts->input_dev, BTN_TOUCH, 1); #endif /* MT_PROTOCOL_B */ - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p); - +#ifdef PALM_GESTURE + if((point_data[position] & 0x07) == PALM_TOUCH) { //palm + dev_dbg(&ts->client->dev, "id=%d, pressure=%d, (%d,%d), major=%d, minor=%d, orient=%d\n", + input_id, input_p, input_x, input_y, input_major, input_minor, input_orient); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_major); +#ifdef PALM_GESTURE_RANGE + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, input_minor); + input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, input_orient); +#endif + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p); + } else +#endif + { + dev_dbg(&ts->client->dev, "id=%d, pressure=%d, (%d,%d), major=%d\n", + input_id, input_p, input_x, input_y, input_major); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_major); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p); + } #if MT_PROTOCOL_B #else /* MT_PROTOCOL_B */ input_mt_sync(ts->input_dev); @@ -1488,6 +1643,10 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) for (i = 0; i < ts->max_touch_num; i++) { if (press_id[i] != 1) { input_mt_slot(ts->input_dev, i); +#ifdef PALM_GESTURE_RANGE + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, 0); + input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, 0); +#endif input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); @@ -1688,6 +1847,14 @@ int nvt_sensor_remove(struct nvt_ts_data *data) data->sensor_pdata = NULL; data->wakeable = false; data->should_enable_gesture = false; + if (!nvt_boot_firmware_name) { + kfree(nvt_boot_firmware_name); + nvt_boot_firmware_name = NULL; + } + if (!nvt_mp_firmware_name) { + kfree(nvt_mp_firmware_name); + nvt_mp_firmware_name = NULL; + } return 0; } #endif @@ -1728,10 +1895,55 @@ static ssize_t ic_ver_show(struct device *dev, "Config ID: ", ts->nvt_pid ? ts->nvt_pid : ts->config_id); } +#ifdef PALM_GESTURE +static ssize_t nvt_palm_settings_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d", ts->palm_enabled); +} + +static ssize_t nvt_palm_settings_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + +{ + int value; + int err = 0; + + if (count > 2) + return -EINVAL; + + if (sscanf(buf, "%d", &value) != 1) + return -EINVAL; + + err = count; + + switch (value) { + case 0: + ts->palm_enabled = false; + break; + case 1: + ts->palm_enabled = true; + break; + default: + err = -EINVAL; + ts->palm_enabled = false; + NVT_ERR("Invalid Value! %d\n", value); + break; + } + + nvt_palm_set(ts->palm_enabled); + + return err; +} +#endif + static struct device_attribute touchscreen_attributes[] = { __ATTR_RO(path), __ATTR_RO(vendor), __ATTR_RO(ic_ver), +#ifdef PALM_GESTURE + __ATTR(palm_settings, S_IRUGO | S_IWUSR | S_IWGRP, nvt_palm_settings_show, nvt_palm_settings_store), +#endif __ATTR_NULL }; @@ -1771,7 +1983,11 @@ int32_t nvt_fw_class_init(bool create) ts_class_dev = device_create(touchscreen_class, NULL, MKDEV(INPUT_MAJOR, minor), +#ifdef PALM_GESTURE + ts, NVT_PRIMARY_NAME); +#else ts, NVT_SPI_NAME); +#endif if (IS_ERR(ts_class_dev)) { error = PTR_ERR(ts_class_dev); ts_class_dev = NULL; @@ -1787,7 +2003,11 @@ int32_t nvt_fw_class_init(bool create) if (error) goto device_destroy; else +#ifdef PALM_GESTURE + NVT_LOG("create /sys/class/touchscreen/%s Succeeded!\n", NVT_PRIMARY_NAME); +#else NVT_LOG("create /sys/class/touchscreen/%s Succeeded!\n", NVT_SPI_NAME); +#endif } else { if (!touchscreen_class || !ts_class_dev) return -ENODEV; @@ -1812,7 +2032,30 @@ device_destroy: return -ENODEV; } +#ifdef NOVATECH_PEN_NOTIFIER +static int pen_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + int ret = 0; + NVT_LOG("Received event(%lu) for pen detection\n", event); + if (event == PEN_DETECTION_INSERT) + ts->nvt_pen_detect_flag = PEN_DETECTION_INSERT; + else if (event == PEN_DETECTION_PULL) + ts->nvt_pen_detect_flag = PEN_DETECTION_PULL; + + if (!bTouchIsAwake || !ts->fw_ready_flag) { + NVT_LOG("touch in suspend or no firmware, so store."); + } else { + ret = nvt_mcu_pen_detect_set(ts->nvt_pen_detect_flag); + if (ret < 0) { + NVT_ERR("write pen state fail"); + } + } + + return 0; +} +#endif /******************************************************* Description: @@ -1830,6 +2073,15 @@ static int32_t nvt_ts_probe(struct spi_device *client) #ifdef NVT_SENSOR_EN static bool initialized_sensor; #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) + struct device_node *dp = client->dev.of_node; + + ret = nova_check_dt(dp); + if (ret == -EPROBE_DEFER) { + NVT_LOG("panel error\n"); + return ret; + } +#endif NVT_LOG("start\n"); @@ -1952,8 +2204,13 @@ static int32_t nvt_ts_probe(struct spi_device *client) input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, TOUCH_FORCE_NUM, 0, 0); //pressure = TOUCH_FORCE_NUM #if TOUCH_MAX_FINGER_NUM > 1 +#ifdef PALM_GESTURE_RANGE + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, TOUCH_DEFAULT_MAX_HEIGHT, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MINOR, 0, TOUCH_DEFAULT_MAX_HEIGHT, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_ORIENTATION, TOUCH_ORIENTATION_MIN, TOUCH_ORIENTATION_MAX, 0, 0); +#else input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); //area = 255 - +#endif input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); #if MT_PROTOCOL_B @@ -1975,6 +2232,10 @@ static int32_t nvt_ts_probe(struct spi_device *client) } #endif +#ifdef PALM_GESTURE + ts->palm_enabled = false; +#endif + sprintf(ts->phys, "input/ts"); ts->input_dev->name = NVT_TS_NAME; ts->input_dev->phys = ts->phys; @@ -2125,6 +2386,28 @@ static int32_t nvt_ts_probe(struct spi_device *client) } #endif +#ifdef NOVATECH_PEN_NOTIFIER + ts->fw_ready_flag = false; + ts->nvt_pen_detect_flag = PEN_DETECTION_INSERT; + ts->pen_notif.notifier_call = pen_notifier_callback; + ret = pen_detection_register_client(&ts->pen_notif); + if (ret) { + NVT_ERR("[PEN]Unable to register pen_notifier: %d\n", ret); + goto err_register_pen_notif_failed; + } +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) + ts->drm_notif.notifier_call = nvt_drm_notifier_callback; + if (active_panel && + drm_panel_notifier_register(active_panel, + &ts->drm_notif) < 0) { + NVT_LOG("register notifier failed!\n"); + goto err_register_drm_notif_failed; + } +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef _MSM_DRM_NOTIFY_H_ ts->drm_notif.notifier_call = nvt_drm_notifier_callback; @@ -2161,6 +2444,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) goto err_register_early_suspend_failed; } #endif +#endif //end version code >= 5.4.0 ret = nvt_fw_class_init(true); if (ret) { @@ -2175,6 +2459,15 @@ static int32_t nvt_ts_probe(struct spi_device *client) return 0; err_create_touchscreen_class_failed: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) + if (active_panel) { + drm_panel_notifier_unregister(active_panel, &ts->drm_notif); + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); + } +err_register_drm_notif_failed: +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef _MSM_DRM_NOTIFY_H_ if (msm_drm_unregister_client(&ts->drm_notif)) @@ -2189,6 +2482,12 @@ err_register_fb_notif_failed: unregister_early_suspend(&ts->early_suspend); err_register_early_suspend_failed: #endif +#endif //end version code >= 5.4.0 +#ifdef NOVATECH_PEN_NOTIFIER + if (pen_detection_unregister_client(&ts->pen_notif)) + NVT_ERR("Error occurred while unregistering pen_notifier.\n"); +err_register_pen_notif_failed: +#endif #if NVT_TOUCH_MP nvt_mp_proc_deinit(); err_mp_proc_init_failed: @@ -2272,6 +2571,15 @@ static int32_t nvt_ts_remove(struct spi_device *client) NVT_LOG("Removing driver...\n"); nvt_fw_class_init(false); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) + if (active_panel) { + drm_panel_notifier_unregister(active_panel, &ts->drm_notif); + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); + } +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef _MSM_DRM_NOTIFY_H_ if (msm_drm_unregister_client(&ts->drm_notif)) @@ -2288,6 +2596,11 @@ static int32_t nvt_ts_remove(struct spi_device *client) if (unregister_panel_notifier(&ts->panel_notif)) NVT_ERR("Error occurred while unregistering panel_notifier.\n"); #endif +#endif //end version code >= 5.4.0 +#ifdef NOVATECH_PEN_NOTIFIER + if (pen_detection_unregister_client(&ts->pen_notif)) + NVT_ERR("Error occurred while unregistering pen_notifier.\n"); +#endif #if NVT_TOUCH_MP nvt_mp_proc_deinit(); @@ -2358,6 +2671,14 @@ static void nvt_ts_shutdown(struct spi_device *client) nvt_irq_enable(false); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) + if (active_panel) { + drm_panel_notifier_unregister(active_panel, &ts->drm_notif); + NVT_ERR("Error occurred while unregistering drm_notifier.\n"); + } +#endif +#else //vension code < 5.4.0 #if defined(CONFIG_FB) #ifdef _MSM_DRM_NOTIFY_H_ if (msm_drm_unregister_client(&ts->drm_notif)) @@ -2374,7 +2695,7 @@ static void nvt_ts_shutdown(struct spi_device *client) if (unregister_panel_notifier(&ts->panel_notif)) NVT_ERR("Error occurred while unregistering panel_notifier.\n"); #endif - +#endif //end version code >= 5.4.0 #if NVT_TOUCH_MP nvt_mp_proc_deinit(); #endif @@ -2491,6 +2812,10 @@ static int32_t nvt_ts_suspend(struct device *dev) #if MT_PROTOCOL_B for (i = 0; i < ts->max_touch_num; i++) { input_mt_slot(ts->input_dev, i); +#ifdef PALM_GESTURE_RANGE + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, 0); + input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, 0); +#endif input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); @@ -2586,6 +2911,48 @@ static int32_t nvt_ts_resume(struct device *dev) return 0; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) +static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +{ + struct msm_drm_notifier *evdata = data; + int *blank; + struct nvt_ts_data *ts = + container_of(self, struct nvt_ts_data, drm_notif); + + if (!evdata) + return 0; + + if (!(event == MSM_DRM_EARLY_EVENT_BLANK || + event == MSM_DRM_EVENT_BLANK)) { + NVT_LOG("event(%lu) do not need process\n", event); + return 0; + } + + blank = evdata->data; + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + if (event == MSM_DRM_EARLY_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_POWERDOWN) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + nvt_ts_suspend(&ts->client->dev); +#ifdef NVT_SENSOR_EN + if (ts->should_enable_gesture) { + NVT_LOG("double tap gesture suspend\n"); + return 1; + } +#endif + } + } else if (event == MSM_DRM_EVENT_BLANK) { + if (*blank == MSM_DRM_BLANK_UNBLANK) { + NVT_LOG("event=%lu, *blank=%d\n", event, *blank); + nvt_ts_resume(&ts->client->dev); + } + } + + return 0; +} +#endif +#else //vension code < 5.4.0 #ifdef NVT_CONFIG_PANEL_NOTIFICATIONS static int nvt_panel_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { @@ -2704,6 +3071,7 @@ static void nvt_ts_late_resume(struct early_suspend *h) nvt_ts_resume(ts->client); } #endif +#endif //version code >= 5.4.0 static const struct spi_device_id nvt_ts_id[] = { { NVT_SPI_NAME, 0 }, diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h index bc81ae521efe..660919a9927f 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h @@ -23,6 +23,9 @@ #include #include #include +#include +#include + #ifdef NVT_SENSOR_EN #include #endif @@ -30,6 +33,9 @@ #ifdef NVT_CONFIG_PANEL_NOTIFICATIONS #include #endif +#ifdef NOVATECH_PEN_NOTIFIER +#include +#endif #ifdef CONFIG_HAS_EARLYSUSPEND #include @@ -63,6 +69,7 @@ //---SPI driver info.--- #define NVT_SPI_NAME "NVT-ts" +#define NVT_PRIMARY_NAME "primary" #if NVT_DEBUG #define NVT_LOG(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) @@ -85,6 +92,16 @@ extern const uint16_t touch_key_array[TOUCH_KEY_NUM]; #endif #define TOUCH_FORCE_NUM 1000 +#ifdef PALM_GESTURE +#define PALM_HAND_HOLDE 900 +#define PALM_HANG 1000 +#ifdef PALM_GESTURE_RANGE +#define TOUCH_ORIENTATION_MIN 0 +#define TOUCH_ORIENTATION_MAX 90 +#define PANEL_REAL_WIDTH 7096 +#define PANEL_REAL_HEIGHT 15768 +#endif +#endif /* Enable only when module have tp reset pin and connected to host */ #define NVT_TOUCH_SUPPORT_HW_RST 0 @@ -107,7 +124,7 @@ extern const uint16_t gesture_key_array[]; #define MP_UPDATE_FIRMWARE_NAME "novatek_ts_mp.bin" #define POINT_DATA_CHECKSUM 1 #define POINT_DATA_CHECKSUM_LEN 65 - +#define NVT_FILE_NAME_LENGTH 128 //---ESD Protect.--- #define NVT_TOUCH_ESD_PROTECT 0 #define NVT_TOUCH_ESD_CHECK_PERIOD 1500 /* ms */ @@ -148,18 +165,7 @@ struct nvt_ts_data { struct delayed_work nvt_fwu_work; uint16_t addr; int8_t phys[32]; -#if defined(CONFIG_FB) -#ifdef _MSM_DRM_NOTIFY_H_ - struct notifier_block drm_notif; -#else - struct notifier_block fb_notif; -#endif -#elif defined(CONFIG_HAS_EARLYSUSPEND) - struct early_suspend early_suspend; -#endif -#ifdef NVT_CONFIG_PANEL_NOTIFICATIONS - struct notifier_block panel_notif; -#endif + uint8_t fw_ver; uint8_t x_num; uint8_t y_num; @@ -181,6 +187,7 @@ struct nvt_ts_data { uint8_t *xbuf; struct mutex xbuf_lock; bool irq_enabled; + const char *panel_supplier; #ifdef CONFIG_MTK_SPI struct mt_chip_conf spi_ctrl; #endif @@ -194,14 +201,40 @@ struct nvt_ts_data { bool wakeable; bool should_enable_gesture; bool gesture_enabled; +#ifdef NOVATECH_PEN_NOTIFIER + bool fw_ready_flag; + int nvt_pen_detect_flag; + struct notifier_block pen_notif; +#endif enum display_state screen_state; struct mutex state_mutex; struct nvt_sensor_platform_data *sensor_pdata; +#endif +#ifdef PALM_GESTURE + bool palm_enabled; #endif char product_id[10]; uint8_t fw_type; uint32_t build_id; uint32_t config_id; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +#if defined(CONFIG_DRM) + struct notifier_block drm_notif; +#endif +#else //vension code < 5.4.0 +#if defined(CONFIG_FB) +#ifdef _MSM_DRM_NOTIFY_H_ + struct notifier_block drm_notif; +#else + struct notifier_block fb_notif; +#endif +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif +#ifdef NVT_CONFIG_PANEL_NOTIFICATIONS + struct notifier_block panel_notif; +#endif +#endif //version code >= 5.4.0 }; #if NVT_TOUCH_PROC @@ -241,6 +274,9 @@ typedef enum { //---extern structures--- extern struct nvt_ts_data *ts; +extern char *nvt_boot_firmware_name; +extern char *nvt_mp_firmware_name; + //---extern functions--- int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len); int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len); @@ -261,5 +297,10 @@ int32_t nvt_write_addr(uint32_t addr, uint8_t data); #if NVT_TOUCH_ESD_PROTECT extern void nvt_esd_check_enable(uint8_t enable); #endif /* #if NVT_TOUCH_ESD_PROTECT */ - +#ifdef NOVATECH_PEN_NOTIFIER +extern int nvt_mcu_pen_detect_set(uint8_t pen_detect); +#endif +#ifdef PALM_GESTURE +extern int nvt_palm_set(bool enabled); +#endif #endif /* _LINUX_NVT_TOUCH_H */ diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_ext_proc.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_ext_proc.c index 44f379b56616..f70918cc414f 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_ext_proc.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_ext_proc.c @@ -39,6 +39,16 @@ #define XDATA_SECTOR_SIZE 256 +#define ENABLE_PASSIVE_PEN_MODE_CMD 0x73 +#define DISABLE_PASSIVE_PEN_MODE_CMD 0x74 +#define ENABLE_PALM_GESTURE_MODE_CMD 0x75 +#define DISABLE_PALM_GESTURE_MODE_CMD 0x76 + +#define ENABLE_DOZE_MODE_CMD 0xB7 +#define DISABLE_DOZE_MODE_CMD 0xB8 + +static uint8_t monitor_control_status = 1; + static uint8_t xdata_tmp[2048] = {0}; static int32_t xdata[2048] = {0}; @@ -562,10 +572,16 @@ static ssize_t nvt_fwupdate_read(struct file *file, char __user *buff, size_t co switch (fwtype) { case FWTYPE_Normal: - nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + if(nvt_boot_firmware_name) + nvt_update_firmware(nvt_boot_firmware_name); + else + nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); break; case FWTYPE_MP: - nvt_update_firmware(MP_UPDATE_FIRMWARE_NAME); + if(nvt_mp_firmware_name) + nvt_update_firmware(nvt_mp_firmware_name); + else + nvt_update_firmware(MP_UPDATE_FIRMWARE_NAME); break; default: NVT_ERR("fwtype error\n"); @@ -586,61 +602,85 @@ static const struct file_operations nvt_fwupdate_fops = { .read = nvt_fwupdate_read, }; -uint8_t status = 1; -#define ENABLE_MONITOR 1 -#define DISABLE_MONITOR 0 -#define ENABLE_DOZE_MODE_CMD 0xB7 -#define DISABLE_DOZE_MODE_CMD 0xB8 -int32_t nvt_monitor_control(uint8_t status) +int32_t nvt_cmd_store(uint8_t u8Cmd) { - uint8_t buf[8] = {0}; + int i, retry = 5; + uint8_t buf[3] = {0}; int32_t ret = 0; - NVT_LOG("set monitor control: %d\n", status); + if (mutex_lock_interruptible(&ts->lock)) { + return -ERESTARTSYS; + } //---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_monitor_control_out; + mutex_unlock(&ts->lock); + return ret; } - if (status == ENABLE_MONITOR) { + for (i = 0; i < retry; i++) { + //---set cmd status--- buf[0] = EVENT_MAP_HOST_CMD; - buf[1] = ENABLE_DOZE_MODE_CMD; - ret = CTP_SPI_WRITE(ts->client, buf, 2); - if (ret < 0) { - NVT_ERR("Write enable doze mode command fail!\n"); - goto nvt_monitor_control_out; - } else { - NVT_LOG("set enable doze mode cmd succeeded\n"); - } - } else if (status == DISABLE_MONITOR) { + buf[1] = u8Cmd; + CTP_SPI_WRITE(ts->client, buf, 2); + msleep(20); + + //---read cmd status--- buf[0] = EVENT_MAP_HOST_CMD; - buf[1] = DISABLE_DOZE_MODE_CMD; - ret = CTP_SPI_WRITE(ts->client, buf, 2); - if (ret < 0) { - NVT_ERR("Write disable doze mode command fail!\n"); - goto nvt_monitor_control_out; - } else { - NVT_LOG("set disable doze mode cmd succeeded\n"); - } + buf[1] = 0xFF; + CTP_SPI_READ(ts->client, buf, 2); + if (buf[1] == 0x00) + break; + } + + if (unlikely(i == retry)) { + NVT_LOG("send Cmd 0x%02X failed, buf[1]=0x%02X\n", u8Cmd, buf[1]); + ret = -1; } else { - NVT_ERR("Invalid monitor_control parameter!\n"); - ret = -EINVAL; + NVT_LOG("send Cmd 0x%02X success, tried %d times\n", u8Cmd, i); } - nvt_monitor_control_out: + mutex_unlock(&ts->lock); return ret; } +#ifdef NOVATECH_PEN_NOTIFIER +int nvt_mcu_pen_detect_set(uint8_t pen_detect) { + int ret = 0; + + if (pen_detect == PEN_DETECTION_PULL) { + ret = nvt_cmd_store(ENABLE_PASSIVE_PEN_MODE_CMD); + } else if (pen_detect == PEN_DETECTION_INSERT) { + ret = nvt_cmd_store(DISABLE_PASSIVE_PEN_MODE_CMD); + } + + return ret; +} +#endif + +#ifdef PALM_GESTURE +int nvt_palm_set(bool enabled) { + int ret = 0; + + if (enabled) { + ret = nvt_cmd_store(ENABLE_PALM_GESTURE_MODE_CMD); + } else if (!enabled) { + ret = nvt_cmd_store(DISABLE_PALM_GESTURE_MODE_CMD); + } + + return ret; +} +#endif + static int nvt_monitor_control_show(struct seq_file *sfile, void *v) { - if(status == ENABLE_MONITOR) + if(monitor_control_status == 1) seq_printf(sfile, "Enable Doze MODE!\n"); - else if (status == DISABLE_MONITOR) + else if (monitor_control_status == 0) seq_printf(sfile, "Disable Doze MODE!\n"); else seq_printf(sfile, "UNKNOW MODE!\n"); @@ -670,8 +710,17 @@ static ssize_t nvt_monitor_control_store(struct file *file, const char *buffer, return -EINVAL; } - status = input; - nvt_monitor_control(status); + monitor_control_status = input; + NVT_LOG("set monitor control: %d\n", monitor_control_status); + + if (monitor_control_status == 1) { + nvt_cmd_store(ENABLE_DOZE_MODE_CMD); + } else if (monitor_control_status == 0) { + nvt_cmd_store(DISABLE_DOZE_MODE_CMD); + } else { + NVT_ERR("Invalid parameter %d!\n", monitor_control_status); + } + kfree(str); return count; diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_fw_update.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_fw_update.c index 5e5b68c1b1f2..fbf0b7ff1ce0 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_fw_update.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_fw_update.c @@ -34,7 +34,7 @@ #define NVT_DUMP_PARTITION_LEN (1024) #define NVT_DUMP_PARTITION_PATH "/data/local/tmp" -struct timeval start, end; +struct TIME_TYPE start, end; const struct firmware *fw_entry = NULL; static size_t fw_need_write_size = 0; static uint8_t *fwbuf = NULL; @@ -402,7 +402,11 @@ static int32_t nvt_read_ram_and_save_file(uint32_t addr, uint16_t len, char *nam CTP_SPI_READ(ts->client, fbufp, len+1); /* Write to file */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) + ret = kernel_write(fp, (char __user *)fbufp+1, len, &file_offset); +#else ret = vfs_write(fp, (char __user *)fbufp+1, len, &file_offset); +#endif if (ret != len) { NVT_ERR("write file failed\n"); goto open_file_fail; @@ -803,7 +807,7 @@ static int32_t nvt_download_firmware_hw_crc(void) uint8_t retry = 0; int32_t ret = 0; - do_gettimeofday(&start); + GET_TIME_OF_DAY(&start); while (1) { /* bootloader reset to reset MCU */ @@ -852,7 +856,7 @@ fail: } } - do_gettimeofday(&end); + GET_TIME_OF_DAY(&end); return ret; } @@ -870,7 +874,7 @@ static int32_t nvt_download_firmware(void) uint8_t retry = 0; int32_t ret = 0; - do_gettimeofday(&start); + GET_TIME_OF_DAY(&start); while (1) { /* @@ -931,7 +935,7 @@ fail: } } - do_gettimeofday(&end); + GET_TIME_OF_DAY(&end); return ret; } @@ -971,8 +975,13 @@ int32_t nvt_update_firmware(char *firmware_name) goto download_fail; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) + NVT_LOG("Update firmware success! <%lld us>\n", + (end.tv_sec - start.tv_sec)*1000000L + (end.tv_nsec - start.tv_nsec)/1000); +#else NVT_LOG("Update firmware success! <%ld us>\n", (end.tv_sec - start.tv_sec)*1000000L + (end.tv_usec - start.tv_usec)); +#endif /* Get FW Info */ ret = nvt_get_fw_info(); @@ -1002,16 +1011,33 @@ return: *******************************************************/ void Boot_Update_Firmware(struct work_struct *work) { + int32_t ret = 0; + mutex_lock(&ts->lock); - if (nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME)) { + + if(nvt_boot_firmware_name) + ret = nvt_update_firmware(nvt_boot_firmware_name); + else + ret = nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + if (ret) { NVT_ERR("download firmware failed, ignore check fw state\n"); } else { nvt_check_fw_reset_state(RESET_STATE_REK); } + + mutex_unlock(&ts->lock); + if (ts->charger_detection) { queue_work(ts->charger_detection->nvt_charger_notify_wq, &ts->charger_detection->charger_notify_work); } - mutex_unlock(&ts->lock); +#ifdef NOVATECH_PEN_NOTIFIER + if(!ts->fw_ready_flag) + ts->fw_ready_flag = true; + nvt_mcu_pen_detect_set(ts->nvt_pen_detect_flag); +#endif +#ifdef PALM_GESTURE + nvt_palm_set(ts->palm_enabled); +#endif } #endif /* BOOT_UPDATE_FIRMWARE */ diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mp_ctrlram.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mp_ctrlram.c index ade4d293f147..67fd1886cd92 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mp_ctrlram.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mp_ctrlram.c @@ -414,7 +414,11 @@ static int32_t nvt_save_rawdata_to_csv(int32_t *rawdata, uint8_t x_ch, uint8_t y output_len = y_ch * x_ch * 7 + y_ch * 2; #endif /* #if TOUCH_KEY_NUM > 0 */ pos = offset; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) + write_ret = kernel_write(fp, (char __user *)fbufp, output_len, &pos); +#else write_ret = vfs_write(fp, (char __user *)fbufp, output_len, &pos); +#endif if (write_ret <= 0) { NVT_ERR("write %s failed\n", file_path); set_fs(org_fs); @@ -1216,7 +1220,10 @@ static int32_t nvt_selftest_open(struct inode *inode, struct file *file) #endif /* #if NVT_TOUCH_ESD_PROTECT */ //---Download MP FW--- - nvt_update_firmware(MP_UPDATE_FIRMWARE_NAME); + if(nvt_mp_firmware_name) + nvt_update_firmware(nvt_mp_firmware_name); + else + nvt_update_firmware(MP_UPDATE_FIRMWARE_NAME); if (nvt_get_fw_info()) { mutex_unlock(&ts->lock); @@ -1240,7 +1247,10 @@ static int32_t nvt_selftest_open(struct inode *inode, struct file *file) if (nvt_mp_parse_dt(np, mpcriteria)) { //---Download Normal FW--- - nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + if(nvt_boot_firmware_name) + nvt_update_firmware(nvt_boot_firmware_name); + else + nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); mutex_unlock(&ts->lock); NVT_ERR("mp parse device tree failed!\n"); return -EINVAL; @@ -1343,7 +1353,10 @@ static int32_t nvt_selftest_open(struct inode *inode, struct file *file) } //---Download Normal FW--- - nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); + if(nvt_boot_firmware_name) + nvt_update_firmware(nvt_boot_firmware_name); + else + nvt_update_firmware(BOOT_UPDATE_FIRMWARE_NAME); mutex_unlock(&ts->lock);