diff --git a/config/kernel/linux-sm8250-current.config b/config/kernel/linux-sm8250-current.config index 80fff20f48b9..6fe1d0c60fbd 100644 --- a/config/kernel/linux-sm8250-current.config +++ b/config/kernel/linux-sm8250-current.config @@ -1,4 +1,4 @@ -# Armbian defconfig generated with 6.12 +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -74,6 +74,8 @@ CONFIG_ACPI_APEI=y CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_BLK_DEV_THROTTLING=y @@ -283,7 +285,6 @@ CONFIG_QRTR_SMD=m CONFIG_QRTR_TUN=m CONFIG_CGROUP_NET_PRIO=y CONFIG_BPF_STREAM_PARSER=y -CONFIG_CAN=m CONFIG_BT=m CONFIG_BT_HIDP=m # CONFIG_BT_DEBUGFS is not set @@ -291,7 +292,9 @@ CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_QCA=y CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y CONFIG_RFKILL=m CONFIG_RFKILL_INPUT=y @@ -358,6 +361,7 @@ CONFIG_NVME_HWMON=y CONFIG_QCOM_FASTRPC=m CONFIG_SRAM=y CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_NTSYNC=m CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m CONFIG_UACCE=m @@ -484,22 +488,13 @@ CONFIG_PHYLIB=y CONFIG_AQUANTIA_PHY=y CONFIG_AT803X_PHY=y CONFIG_VITESSE_PHY=y -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB=m -CONFIG_CAN_ETAS_ES58X=m -CONFIG_CAN_F81604=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -CONFIG_CAN_MCBA_USB=m -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_THUNDER=y CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m +CONFIG_PPP=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m @@ -534,6 +529,7 @@ CONFIG_USB_NET_AQC111=m # CONFIG_WLAN_VENDOR_ADMTEK is not set CONFIG_ATH11K=m CONFIG_ATH11K_PCI=m +CONFIG_ATH12K=m # CONFIG_WLAN_VENDOR_ATMEL is not set # CONFIG_WLAN_VENDOR_BROADCOM is not set # CONFIG_WLAN_VENDOR_INTEL is not set @@ -619,8 +615,9 @@ CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y -CONFIG_CHARGER_QCOM_SMB5=m -CONFIG_BATTERY_QCOM_FG=m +CONFIG_CHARGER_BQ25970=y +CONFIG_CHARGER_QCOM_SMB5=y +CONFIG_BATTERY_QCOM_FG=y CONFIG_SENSORS_ARM_SCMI=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m @@ -665,6 +662,7 @@ CONFIG_REGULATOR_PCA9450=y CONFIG_REGULATOR_PF8X00=y CONFIG_REGULATOR_PFUZE100=y CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_QCOM_REFGEN=y CONFIG_REGULATOR_QCOM_RPMH=y CONFIG_REGULATOR_QCOM_SMD_RPM=y CONFIG_REGULATOR_QCOM_SPMI=y @@ -740,15 +738,15 @@ CONFIG_HID_CYPRESS=y CONFIG_HID_EZKEY=y CONFIG_HID_ITE=y CONFIG_HID_KENSINGTON=y -CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH=m CONFIG_HID_REDRAGON=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y CONFIG_HID_MULTITOUCH=m CONFIG_HID_NINTENDO=m -CONFIG_USB_HIDDEV=y CONFIG_I2C_HID_ACPI=m CONFIG_I2C_HID_OF=m +CONFIG_USB_HIDDEV=y CONFIG_USB_CONN_GPIO=m CONFIG_USB=y CONFIG_USB_OTG=y @@ -759,6 +757,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=m CONFIG_USB_STORAGE=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_DWC3=y @@ -804,13 +803,15 @@ CONFIG_TYPEC_MUX_FSA4480=m CONFIG_TYPEC_MUX_GPIO_SBU=m CONFIG_TYPEC_MUX_NB7VPQ904M=m CONFIG_TYPEC_DP_ALTMODE=m -CONFIG_MMC=y +CONFIG_MMC=m CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_ARMMMCI=m # CONFIG_MMC_STM32_SDMMC is not set -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_SDHCI_MSM=m +CONFIG_MMC_USHC=m CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_HWMON=y @@ -818,6 +819,7 @@ CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_QCOM=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=y CONFIG_LEDS_CLASS_MULTICOLOR=y CONFIG_LEDS_HTR3212=m CONFIG_LEDS_LM3692X=m @@ -825,18 +827,19 @@ CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y -CONFIG_LEDS_USER=y -CONFIG_LEDS_GROUP_MULTICOLOR=y -CONFIG_LEDS_PWM_MULTICOLOR=y -CONFIG_LEDS_QCOM_LPG=y +CONFIG_LEDS_USER=m +CONFIG_LEDS_GROUP_MULTICOLOR=m +CONFIG_LEDS_PWM_MULTICOLOR=m +CONFIG_LEDS_QCOM_FLASH=m +CONFIG_LEDS_QCOM_LPG=m CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_DISK=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_ACTIVITY=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_PANIC=y -CONFIG_LEDS_TRIGGER_NETDEV=y +CONFIG_LEDS_TRIGGER_NETDEV=m CONFIG_EDAC=y CONFIG_EDAC_GHES=y CONFIG_RTC_CLASS=y diff --git a/config/sources/families/sm8250.conf b/config/sources/families/sm8250.conf index 814bf8794383..ebd5a81cda77 100644 --- a/config/sources/families/sm8250.conf +++ b/config/sources/families/sm8250.conf @@ -16,14 +16,13 @@ enable_extension "image-output-abl" case $BRANCH in current) - declare -g KERNEL_MAJOR_MINOR="6.12" # Major and minor versions of this kernel. - declare -g KERNELBRANCH='branch:linux-6.12.y' + declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel. + declare -g KERNELBRANCH='branch:linux-6.18.y' declare -g -i KERNEL_GIT_CACHE_TTL=120 # 2 minutes; this is a high-traffic repo ;; edge) - declare -g KERNEL_MAJOR_MINOR="6.14" # Major and minor versions of this kernel. - declare -g KERNELBRANCH='branch:linux-6.14.y' + declare -g KERNEL_MAJOR_MINOR="6.19" # Major and minor versions of this kernel. declare -g -i KERNEL_GIT_CACHE_TTL=120 # 2 minutes; this is a high-traffic repo ;; diff --git a/patch/kernel/archive/sm8250-6.18/0000.patching_config.yaml b/patch/kernel/archive/sm8250-6.18/0000.patching_config.yaml new file mode 100644 index 000000000000..ec326af9e477 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0000.patching_config.yaml @@ -0,0 +1,29 @@ +config: # This is file 'patch/kernel/archive/sm8250-6.18/0000.patching_config.yaml' + + # Just some info stuff; not used by the patching scripts + name: sm8250-6.18 + kind: kernel + type: mainline # or: vendor + branch: linux-6.18.y + last-known-good-tag: v6.18.3 + maintainers: + - { github: rpardini, name: Ricardo Pardini, email: ricardo@pardini.net, armbian-forum: rpardini } + + # .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones. + # This is meant to provide a way to "add a board DTS" without having to null-patch them in. + dts-directories: + - { source: "dt", target: "arch/arm64/boot/dts/qcom" } + + # the Makefile in each of these directories will be magically patched to include the dts files copied + # or patched-in; overlay subdir will be included "-y" if it exists. + # No more Makefile patching needed, yay! + auto-patch-dt-makefile: + - { directory: "arch/arm64/boot/dts/qcom", config-var: "CONFIG_ARCH_QCOM" } + + # configuration for when applying patches to git / auto-rewriting patches (development cycle helpers) + patches-to-git: + do-not-commit-files: + - "MAINTAINERS" # constant churn, drop them. sorry. + do-not-commit-regexes: # Python-style regexes + - "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now + diff --git a/patch/kernel/archive/sm8250-6.18/0001-drm-Add-drm-notifier-support.patch b/patch/kernel/archive/sm8250-6.18/0001-drm-Add-drm-notifier-support.patch new file mode 100644 index 000000000000..9efdd2649775 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0001-drm-Add-drm-notifier-support.patch @@ -0,0 +1,138 @@ +From 56330cd8650e8b60b836727156a94a67485a3c67 Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Thu, 4 Aug 2022 13:26:53 +0800 +Subject: [PATCH 01/62] drm: Add drm notifier support + +Signed-off-by: Jiali Chen +--- + drivers/gpu/drm/Makefile | 3 +- + drivers/gpu/drm/drm_notifier.c | 58 ++++++++++++++++++++++++++++++++++ + include/drm/drm_notifier.h | 37 ++++++++++++++++++++++ + 3 files changed, 97 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/drm_notifier.c + create mode 100644 include/drm/drm_notifier.h + +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 4dafbdc8f86a..9b2434daa24f 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -72,7 +72,8 @@ drm-y := \ + drm_vblank.o \ + drm_vblank_work.o \ + drm_vma_manager.o \ +- drm_writeback.o ++ drm_writeback.o \ ++ drm_notifier.o + drm-$(CONFIG_DRM_CLIENT) += \ + drm_client.o \ + drm_client_event.o \ +diff --git a/drivers/gpu/drm/drm_notifier.c b/drivers/gpu/drm/drm_notifier.c +new file mode 100644 +index 000000000000..0b90d02d8692 +--- /dev/null ++++ b/drivers/gpu/drm/drm_notifier.c +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2019, The Linux Foundation. All rights reserved. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++ ++static BLOCKING_NOTIFIER_HEAD(mi_drm_notifier_list); ++ ++/** ++ * mi_drm_register_client - register a client notifier ++ * @nb: notifier block to callback on events ++ * ++ * This function registers a notifier callback function ++ * to msm_drm_notifier_list, which would be called when ++ * received unblank/power down event. ++ */ ++int mi_drm_register_client(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&mi_drm_notifier_list, nb); ++} ++EXPORT_SYMBOL(mi_drm_register_client); ++ ++/** ++ * mi_drm_unregister_client - unregister a client notifier ++ * @nb: notifier block to callback on events ++ * ++ * This function unregisters the callback function from ++ * msm_drm_notifier_list. ++ */ ++int mi_drm_unregister_client(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&mi_drm_notifier_list, nb); ++} ++EXPORT_SYMBOL(mi_drm_unregister_client); ++ ++/** ++ * mi_drm_notifier_call_chain - notify clients of drm_events ++ * @val: event MSM_DRM_EARLY_EVENT_BLANK or MSM_DRM_EVENT_BLANK ++ * @v: notifier data, inculde display id and display blank ++ * event(unblank or power down). ++ */ ++int mi_drm_notifier_call_chain(unsigned long val, void *v) ++{ ++ return blocking_notifier_call_chain(&mi_drm_notifier_list, val, v); ++} ++EXPORT_SYMBOL(mi_drm_notifier_call_chain); +diff --git a/include/drm/drm_notifier.h b/include/drm/drm_notifier.h +new file mode 100644 +index 000000000000..fd0e976559b8 +--- /dev/null ++++ b/include/drm/drm_notifier.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2019, The Linux Foundation. All rights reserved. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _DRM_NOTIFIER_H_ ++#define _DRM_NOTIFIER_H_ ++ ++#include ++ ++/* A hardware display blank change occurred */ ++#define MI_DRM_EVENT_BLANK 0x01 ++/* A hardware display blank early change occurred */ ++#define MI_DRM_EARLY_EVENT_BLANK 0x02 ++ ++enum drm_notifier_data { ++ /* panel: power on */ ++ MI_DRM_BLANK_UNBLANK, ++ /* panel: power down */ ++ MI_DRM_BLANK_POWERDOWN, ++}; ++ ++int mi_drm_register_client(struct notifier_block *nb); ++int mi_drm_unregister_client(struct notifier_block *nb); ++int mi_drm_notifier_call_chain(unsigned long val, void *v); ++ ++#endif /* _DRM_NOTIFIER_H */ +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0002-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch b/patch/kernel/archive/sm8250-6.18/0002-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch new file mode 100644 index 000000000000..a5d219d77814 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0002-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch @@ -0,0 +1,57 @@ +From dcde7e9d08a5a3a3f9096d73caefeae3ae16f88f Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Mon, 17 Oct 2022 08:02:58 +0800 +Subject: [PATCH 02/62] drm: dsi: emit panel turn on/off signal to touchscreen + +Signed-off-by: Jiali Chen +--- + drivers/gpu/drm/msm/dsi/dsi_manager.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c +index ca400924d4ee..168a254feecc 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c +@@ -7,6 +7,7 @@ + + #include "msm_kms.h" + #include "dsi.h" ++#include "drm/drm_notifier.h" + + #define DSI_CLOCK_MASTER DSI_0 + #define DSI_CLOCK_SLAVE DSI_1 +@@ -283,6 +284,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) + struct mipi_dsi_host *host = msm_dsi->host; + bool is_bonded_dsi = IS_BONDED_DSI(); + int ret; ++ enum drm_notifier_data notifier_data; + + DBG("id=%d", id); + +@@ -296,6 +298,9 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) + return; + } + ++ notifier_data = MI_DRM_BLANK_UNBLANK; ++ mi_drm_notifier_call_chain(MI_DRM_EVENT_BLANK, ¬ifier_data); ++ + ret = msm_dsi_host_enable(host); + if (ret) { + pr_err("%s: enable host %d failed, %d\n", __func__, id, ret); +@@ -339,9 +344,13 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) + struct mipi_dsi_host *host = msm_dsi->host; + bool is_bonded_dsi = IS_BONDED_DSI(); + int ret; ++ enum drm_notifier_data notifier_data; + + DBG("id=%d", id); + ++ notifier_data = MI_DRM_BLANK_POWERDOWN; ++ mi_drm_notifier_call_chain(MI_DRM_EARLY_EVENT_BLANK, ¬ifier_data); ++ + /* + * Do nothing with the host if it is slave-DSI in case of bonded DSI. + * It is safe to call dsi_mgr_phy_disable() here because a single PHY +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0003-Input-Add-nt36523-touchscreen-driver.patch b/patch/kernel/archive/sm8250-6.18/0003-Input-Add-nt36523-touchscreen-driver.patch new file mode 100644 index 000000000000..f1c085873c6c --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0003-Input-Add-nt36523-touchscreen-driver.patch @@ -0,0 +1,3502 @@ +From 38ff5e332200a9cf67a73952d3df55d7b72e8c1d Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Thu, 4 Aug 2022 13:26:26 +0800 +Subject: [PATCH 03/62] Input: Add nt36523 touchscreen driver + +Signed-off-by: Jiali Chen +--- + drivers/input/touchscreen/Kconfig | 2 + + drivers/input/touchscreen/Makefile | 1 + + drivers/input/touchscreen/nt36523/Kconfig | 11 + + drivers/input/touchscreen/nt36523/Makefile | 8 + + drivers/input/touchscreen/nt36523/nt36xxx.c | 1910 +++++++++++++++++ + drivers/input/touchscreen/nt36523/nt36xxx.h | 242 +++ + .../touchscreen/nt36523/nt36xxx_fw_update.c | 857 ++++++++ + .../touchscreen/nt36523/nt36xxx_mem_map.h | 390 ++++ + 8 files changed, 3421 insertions(+) + create mode 100644 drivers/input/touchscreen/nt36523/Kconfig + create mode 100644 drivers/input/touchscreen/nt36523/Makefile + create mode 100644 drivers/input/touchscreen/nt36523/nt36xxx.c + create mode 100644 drivers/input/touchscreen/nt36523/nt36xxx.h + create mode 100644 drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c + create mode 100644 drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h + +diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig +index 196905162945..0ed83e356c3e 100644 +--- a/drivers/input/touchscreen/Kconfig ++++ b/drivers/input/touchscreen/Kconfig +@@ -12,6 +12,8 @@ menuconfig INPUT_TOUCHSCREEN + + if INPUT_TOUCHSCREEN + ++source "drivers/input/touchscreen/nt36523/Kconfig" ++ + config TOUCHSCREEN_88PM860X + tristate "Marvell 88PM860x touchscreen" + depends on MFD_88PM860X +diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile +index 97a025c6a377..636b2a3e6b13 100644 +--- a/drivers/input/touchscreen/Makefile ++++ b/drivers/input/touchscreen/Makefile +@@ -118,3 +118,4 @@ obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o + obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o + obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o + obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o ++obj-$(CONFIG_TOUCHSCREEN_NT36523_SPI) += nt36523/ +diff --git a/drivers/input/touchscreen/nt36523/Kconfig b/drivers/input/touchscreen/nt36523/Kconfig +new file mode 100644 +index 000000000000..5f4ef5abfd6a +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/Kconfig +@@ -0,0 +1,11 @@ ++# ++# Novatek NT36523 touchscreen driver configuration ++# ++config TOUCHSCREEN_NT36523_SPI ++ tristate "Novatek NT36523 no flash SPI driver" ++ default n ++ help ++ Say Y here if you have a Novatek NT36523 no flash touchscreen connected ++ to your system by SPI bus. ++ ++ If unsure, say N. +diff --git a/drivers/input/touchscreen/nt36523/Makefile b/drivers/input/touchscreen/nt36523/Makefile +new file mode 100644 +index 000000000000..d16afc8f127f +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/Makefile +@@ -0,0 +1,8 @@ ++# ++# Makefile for the Novatek NT36523 touchscreen driver. ++# ++ ++# Each configuration option enables a list of files. ++obj-$(CONFIG_TOUCHSCREEN_NT36523_SPI) += nt36523_ts.o ++nt36523_ts-y := nt36xxx.o \ ++ nt36xxx_fw_update.o +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c +new file mode 100644 +index 000000000000..63c584f681d7 +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.c +@@ -0,0 +1,1910 @@ ++/* ++ * Copyright (C) 2010 - 2018 Novatek, Inc. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * $Revision: 73033 $ ++ * $Date: 2020-11-26 10:09:14 +0800 (週四, 26 十一月 2020) $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_DRM ++#include ++#endif ++ ++#include "nt36xxx.h" ++ ++#if NVT_TOUCH_ESD_PROTECT ++#include ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++#if NVT_TOUCH_ESD_PROTECT ++static struct delayed_work nvt_esd_check_work; ++static struct workqueue_struct *nvt_esd_check_wq; ++static unsigned long irq_timer = 0; ++uint8_t esd_check = false; ++uint8_t esd_retry = 0; ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++struct nvt_ts_data *ts; ++ ++#if BOOT_UPDATE_FIRMWARE ++static struct workqueue_struct *nvt_fwu_wq; ++extern void Boot_Update_Firmware(struct work_struct *work); ++#endif ++ ++#ifdef CONFIG_DRM ++static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data); ++#endif ++ ++static int32_t nvt_ts_suspend(struct device *dev); ++static int32_t nvt_ts_resume(struct device *dev); ++ ++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 ++ ++#if TOUCH_KEY_NUM > 0 ++const uint16_t touch_key_array[TOUCH_KEY_NUM] = { ++ KEY_BACK, ++ KEY_HOME, ++ KEY_MENU ++}; ++#endif ++ ++static uint8_t bTouchIsAwake = 0; ++ ++/******************************************************* ++Description: ++ Novatek touchscreen irq enable/disable function. ++ ++return: ++ n.a. ++*******************************************************/ ++static void nvt_irq_enable(bool enable) ++{ ++ if (enable) { ++ if (!ts->irq_enabled) { ++ enable_irq(ts->client->irq); ++ ts->irq_enabled = true; ++ } ++ } else { ++ if (ts->irq_enabled) { ++ disable_irq(ts->client->irq); ++ ts->irq_enabled = false; ++ } ++ } ++} ++ ++static inline int32_t spi_read_write(struct spi_device *client, uint8_t *buf, size_t len , NVT_SPI_RW rw) ++{ ++ struct spi_message m; ++ struct spi_transfer t = { ++ .len = len, ++ }; ++ ++ memset(ts->xbuf, 0, len + DUMMY_BYTES); ++ memcpy(ts->xbuf, buf, len); ++ ++ switch (rw) { ++ case NVTREAD: ++ t.tx_buf = ts->xbuf; ++ t.rx_buf = ts->rbuf; ++ t.len = (len + DUMMY_BYTES); ++ break; ++ ++ case NVTWRITE: ++ t.tx_buf = ts->xbuf; ++ break; ++ } ++ ++ spi_message_init(&m); ++ spi_message_add_tail(&t, &m); ++ return spi_sync(client, &m); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen spi read function. ++ ++return: ++ Executive outcomes. 2---succeed. -5---I/O error ++*******************************************************/ ++int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len) ++{ ++ int32_t ret = -1; ++ int32_t retries = 0; ++ ++ mutex_lock(&ts->xbuf_lock); ++ ++ buf[0] = SPI_READ_MASK(buf[0]); ++ ++ while (retries < 5) { ++ ret = spi_read_write(client, buf, len, NVTREAD); ++ if (ret == 0) break; ++ retries++; ++ } ++ ++ if (unlikely(retries == 5)) { ++ NVT_ERR("read error, ret=%d\n", ret); ++ ret = -EIO; ++ } else { ++ memcpy((buf+1), (ts->rbuf+2), (len-1)); ++ } ++ ++ mutex_unlock(&ts->xbuf_lock); ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen spi write function. ++ ++return: ++ Executive outcomes. 1---succeed. -5---I/O error ++*******************************************************/ ++int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len) ++{ ++ int32_t ret = -1; ++ int32_t retries = 0; ++ ++ mutex_lock(&ts->xbuf_lock); ++ ++ buf[0] = SPI_WRITE_MASK(buf[0]); ++ ++ while (retries < 5) { ++ ret = spi_read_write(client, buf, len, NVTWRITE); ++ if (ret == 0) break; ++ retries++; ++ } ++ ++ if (unlikely(retries == 5)) { ++ NVT_ERR("error, ret=%d\n", ret); ++ ret = -EIO; ++ } ++ ++ mutex_unlock(&ts->xbuf_lock); ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen set index/page/addr address. ++ ++return: ++ Executive outcomes. 0---succeed. -5---access fail. ++*******************************************************/ ++int32_t nvt_set_page(uint32_t addr) ++{ ++ uint8_t buf[4] = {0}; ++ ++ buf[0] = 0xFF; //set index/page/addr command ++ buf[1] = (addr >> 15) & 0xFF; ++ buf[2] = (addr >> 7) & 0xFF; ++ ++ return CTP_SPI_WRITE(ts->client, buf, 3); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen write data to specify address. ++ ++return: ++ Executive outcomes. 0---succeed. -5---access fail. ++*******************************************************/ ++int32_t nvt_write_addr(uint32_t addr, uint8_t data) ++{ ++ int32_t ret = 0; ++ uint8_t buf[4] = {0}; ++ ++ //---set xdata index--- ++ buf[0] = 0xFF; //set index/page/addr command ++ buf[1] = (addr >> 15) & 0xFF; ++ buf[2] = (addr >> 7) & 0xFF; ++ ret = CTP_SPI_WRITE(ts->client, buf, 3); ++ if (ret) { ++ NVT_ERR("set page 0x%06X failed, ret = %d\n", addr, ret); ++ return ret; ++ } ++ ++ //---write data to index--- ++ buf[0] = addr & (0x7F); ++ buf[1] = data; ++ ret = CTP_SPI_WRITE(ts->client, buf, 2); ++ if (ret) { ++ NVT_ERR("write data to 0x%06X failed, ret = %d\n", addr, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen enable hw bld crc function. ++ ++return: ++ N/A. ++*******************************************************/ ++void nvt_bld_crc_enable(void) ++{ ++ uint8_t buf[4] = {0}; ++ ++ //---set xdata index to BLD_CRC_EN_ADDR--- ++ nvt_set_page(ts->mmap->BLD_CRC_EN_ADDR); ++ ++ //---read data from index--- ++ buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); ++ buf[1] = 0xFF; ++ CTP_SPI_READ(ts->client, buf, 2); ++ ++ //---write data to index--- ++ buf[0] = ts->mmap->BLD_CRC_EN_ADDR & (0x7F); ++ buf[1] = buf[1] | (0x01 << 7); ++ CTP_SPI_WRITE(ts->client, buf, 2); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen clear status & enable fw crc function. ++ ++return: ++ N/A. ++*******************************************************/ ++void nvt_fw_crc_enable(void) ++{ ++ uint8_t buf[4] = {0}; ++ ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR); ++ ++ //---clear fw reset status--- ++ buf[0] = EVENT_MAP_RESET_COMPLETE & (0x7F); ++ buf[1] = 0x00; ++ CTP_SPI_WRITE(ts->client, buf, 2); ++ ++ //---enable fw crc--- ++ buf[0] = EVENT_MAP_HOST_CMD & (0x7F); ++ buf[1] = 0xAE; //enable fw crc command ++ CTP_SPI_WRITE(ts->client, buf, 2); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen set boot ready function. ++ ++return: ++ N/A. ++*******************************************************/ ++void nvt_boot_ready(void) ++{ ++ //---write BOOT_RDY status cmds--- ++ nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 1); ++ ++ mdelay(5); ++ ++ if (!ts->hw_crc) { ++ //---write BOOT_RDY status cmds--- ++ nvt_write_addr(ts->mmap->BOOT_RDY_ADDR, 0); ++ ++ //---write POR_CD cmds--- ++ nvt_write_addr(ts->mmap->POR_CD_ADDR, 0xA0); ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen enable auto copy mode function. ++ ++return: ++ N/A. ++*******************************************************/ ++void nvt_tx_auto_copy_mode(void) ++{ ++ //---write TX_AUTO_COPY_EN cmds--- ++ nvt_write_addr(ts->mmap->TX_AUTO_COPY_EN, 0x69); ++ ++ NVT_ERR("tx auto copy mode enable\n"); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen check spi dma tx info function. ++ ++return: ++ N/A. ++*******************************************************/ ++int32_t nvt_check_spi_dma_tx_info(void) ++{ ++ uint8_t buf[8] = {0}; ++ int32_t i = 0; ++ const int32_t retry = 200; ++ ++ for (i = 0; i < retry; i++) { ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->SPI_DMA_TX_INFO); ++ ++ //---read fw status--- ++ buf[0] = ts->mmap->SPI_DMA_TX_INFO & 0x7F; ++ buf[1] = 0xFF; ++ CTP_SPI_READ(ts->client, buf, 2); ++ ++ if (buf[1] == 0x00) ++ break; ++ ++ usleep_range(1000, 1000); ++ } ++ ++ if (i >= retry) { ++ NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); ++ return -1; ++ } else { ++ return 0; ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen eng reset cmd ++ function. ++ ++return: ++ n.a. ++*******************************************************/ ++void nvt_eng_reset(void) ++{ ++ //---eng reset cmds to ENG_RST_ADDR--- ++ nvt_write_addr(ENG_RST_ADDR, 0x5A); ++ ++ mdelay(1); //wait tMCU_Idle2TP_REX_Hi after TP_RST ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen reset MCU ++ function. ++ ++return: ++ n.a. ++*******************************************************/ ++void nvt_sw_reset(void) ++{ ++ //---software reset cmds to SWRST_N8_ADDR--- ++ nvt_write_addr(SWRST_N8_ADDR, 0x55); ++ ++ msleep(10); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen reset MCU then into idle mode ++ function. ++ ++return: ++ n.a. ++*******************************************************/ ++void nvt_sw_reset_idle(void) ++{ ++ //---MCU idle cmds to SWRST_N8_ADDR--- ++ nvt_write_addr(SWRST_N8_ADDR, 0xAA); ++ ++ msleep(15); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen reset MCU (boot) function. ++ ++return: ++ n.a. ++*******************************************************/ ++void nvt_bootloader_reset(void) ++{ ++ //---reset cmds to SWRST_N8_ADDR--- ++ nvt_write_addr(SWRST_N8_ADDR, 0x69); ++ ++ mdelay(5); //wait tBRST2FR after Bootload RST ++ ++ if (SPI_RD_FAST_ADDR) { ++ /* disable SPI_RD_FAST */ ++ nvt_write_addr(SPI_RD_FAST_ADDR, 0x00); ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen clear FW status function. ++ ++return: ++ Executive outcomes. 0---succeed. -1---fail. ++*******************************************************/ ++int32_t nvt_clear_fw_status(void) ++{ ++ uint8_t buf[8] = {0}; ++ int32_t i = 0; ++ const int32_t retry = 20; ++ ++ for (i = 0; i < retry; i++) { ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); ++ ++ //---clear fw status--- ++ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; ++ buf[1] = 0x00; ++ CTP_SPI_WRITE(ts->client, buf, 2); ++ ++ //---read fw status--- ++ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; ++ buf[1] = 0xFF; ++ CTP_SPI_READ(ts->client, buf, 2); ++ ++ if (buf[1] == 0x00) ++ break; ++ ++ usleep_range(10000, 10000); ++ } ++ ++ if (i >= retry) { ++ NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); ++ return -1; ++ } else { ++ return 0; ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen check FW status function. ++ ++return: ++ Executive outcomes. 0---succeed. -1---failed. ++*******************************************************/ ++int32_t nvt_check_fw_status(void) ++{ ++ uint8_t buf[8] = {0}; ++ int32_t i = 0; ++ const int32_t retry = 50; ++ ++ for (i = 0; i < retry; i++) { ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE); ++ ++ //---read fw status--- ++ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE; ++ buf[1] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 2); ++ ++ if ((buf[1] & 0xF0) == 0xA0) ++ break; ++ ++ usleep_range(10000, 10000); ++ } ++ ++ if (i >= retry) { ++ NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]); ++ return -1; ++ } else { ++ return 0; ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen check FW reset state function. ++ ++return: ++ Executive outcomes. 0---succeed. -1---failed. ++*******************************************************/ ++int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state) ++{ ++ uint8_t buf[8] = {0}; ++ int32_t ret = 0; ++ int32_t retry = 0; ++ int32_t retry_max = (check_reset_state == RESET_STATE_INIT) ? 10 : 50; ++ ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_RESET_COMPLETE); ++ ++ while (1) { ++ //---read reset state--- ++ buf[0] = EVENT_MAP_RESET_COMPLETE; ++ buf[1] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 6); ++ ++ if ((buf[1] >= check_reset_state) && (buf[1] <= RESET_STATE_MAX)) { ++ ret = 0; ++ break; ++ } ++ ++ retry++; ++ if(unlikely(retry > retry_max)) { ++ NVT_ERR("error, retry=%d, buf[1]=0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", ++ retry, buf[1], buf[2], buf[3], buf[4], buf[5]); ++ ret = -1; ++ break; ++ } ++ ++ usleep_range(10000, 10000); ++ } ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen get novatek project id information ++ function. ++ ++return: ++ Executive outcomes. 0---success. -1---fail. ++*******************************************************/ ++int32_t nvt_read_pid(void) ++{ ++ uint8_t buf[4] = {0}; ++ int32_t ret = 0; ++ ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_PROJECTID); ++ ++ //---read project id--- ++ buf[0] = EVENT_MAP_PROJECTID; ++ buf[1] = 0x00; ++ buf[2] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 3); ++ ++ ts->nvt_pid = (buf[2] << 8) + buf[1]; ++ ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR); ++ ++ NVT_LOG("PID=%04X\n", ts->nvt_pid); ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen get firmware related information ++ function. ++ ++return: ++ Executive outcomes. 0---success. -1---fail. ++*******************************************************/ ++int32_t nvt_get_fw_info(void) ++{ ++ uint8_t buf[64] = {0}; ++ uint32_t retry_count = 0; ++ int32_t ret = 0; ++ ++info_retry: ++ //---set xdata index to EVENT BUF ADDR--- ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_FWINFO); ++ ++ //---read fw info--- ++ buf[0] = EVENT_MAP_FWINFO; ++ CTP_SPI_READ(ts->client, buf, 39); ++ ts->fw_ver = buf[1]; ++ ts->x_num = buf[3]; ++ ts->y_num = buf[4]; ++ ts->abs_x_max = (uint16_t)((buf[5] << 8) | buf[6]); ++ ts->abs_y_max = (uint16_t)((buf[7] << 8) | buf[8]); ++ ts->max_button_num = buf[11]; ++ ts->cascade = buf[34] & 0x01; ++ if (ts->pen_support) { ++ ts->x_gang_num = buf[37]; ++ ts->y_gang_num = buf[38]; ++ } ++ ++ //---clear x_num, y_num if fw info is broken--- ++ if ((buf[1] + buf[2]) != 0xFF) { ++ NVT_ERR("FW info is broken! fw_ver=0x%02X, ~fw_ver=0x%02X\n", buf[1], buf[2]); ++ ts->fw_ver = 0; ++ ts->x_num = 18; ++ ts->y_num = 32; ++ ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; ++ ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; ++ ts->max_button_num = TOUCH_KEY_NUM; ++ ++ if(retry_count < 3) { ++ retry_count++; ++ NVT_ERR("retry_count=%d\n", retry_count); ++ goto info_retry; ++ } else { ++ NVT_ERR("Set default fw_ver=%d, x_num=%d, y_num=%d, " ++ "abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n", ++ ts->fw_ver, ts->x_num, ts->y_num, ++ ts->abs_x_max, ts->abs_y_max, ts->max_button_num); ++ ret = -1; ++ } ++ } else { ++ ret = 0; ++ } ++ ++ NVT_LOG("fw_ver = 0x%02X, fw_type = 0x%02X, x_num=%d, y_num=%d\n", ts->fw_ver, buf[14], ts->x_num, ts->y_num); ++ ++ //---Get Novatek PID--- ++ nvt_read_pid(); ++ ++ return ret; ++} ++ ++static void release_pen_event(void) { ++ if (ts && ts->pen_input_dev) { ++ input_report_abs(ts->pen_input_dev, ABS_X, 0); ++ input_report_abs(ts->pen_input_dev, ABS_Y, 0); ++ input_report_abs(ts->pen_input_dev, ABS_PRESSURE, 0); ++ input_report_abs(ts->pen_input_dev, ABS_TILT_X, 0); ++ input_report_abs(ts->pen_input_dev, ABS_TILT_Y, 0); ++ input_report_abs(ts->pen_input_dev, ABS_DISTANCE, 0); ++ input_report_key(ts->pen_input_dev, BTN_TOUCH, 0); ++ input_report_key(ts->pen_input_dev, BTN_TOOL_PEN, 0); ++ input_report_key(ts->pen_input_dev, BTN_STYLUS, 0); ++ input_report_key(ts->pen_input_dev, BTN_STYLUS2, 0); ++ input_sync(ts->pen_input_dev); ++ } ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen parse device tree function. ++ ++return: ++ n.a. ++*******************************************************/ ++#ifdef CONFIG_OF ++static int32_t nvt_parse_dt(struct device *dev) ++{ ++ struct device_node *np = dev->of_node; ++ int32_t ret = 0; ++ ++#if NVT_TOUCH_SUPPORT_HW_RST ++ ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, &ts->reset_flags); ++ NVT_LOG("novatek,reset-gpio=%d\n", ts->reset_gpio); ++#endif ++ ts->irq_gpio = of_get_named_gpio(np, "novatek,irq-gpio", 0); ++ NVT_LOG("novatek,irq-gpio=%d\n", ts->irq_gpio); ++ ++ ts->pen_support = of_property_read_bool(np, "novatek,pen-support"); ++ NVT_LOG("novatek,pen-support=%d\n", ts->pen_support); ++ ++ ts->wgp_stylus = of_property_read_bool(np, "novatek,wgp-stylus"); ++ NVT_LOG("novatek,wgp-stylus=%d\n", ts->wgp_stylus); ++ ++ ret = of_property_read_u32(np, "novatek,swrst-n8-addr", &SWRST_N8_ADDR); ++ if (ret) { ++ NVT_ERR("error reading novatek,swrst-n8-addr. ret=%d\n", ret); ++ return ret; ++ } else { ++ NVT_LOG("SWRST_N8_ADDR=0x%06X\n", SWRST_N8_ADDR); ++ } ++ ++ ret = of_property_read_u32(np, "novatek,spi-rd-fast-addr", &SPI_RD_FAST_ADDR); ++ if (ret) { ++ NVT_LOG("not support novatek,spi-rd-fast-addr\n"); ++ SPI_RD_FAST_ADDR = 0; ++ ret = 0; ++ } else { ++ NVT_LOG("SPI_RD_FAST_ADDR=0x%06X\n", SPI_RD_FAST_ADDR); ++ } ++ ++ ret = of_property_read_string(np, "firmware-name", &ts->fw_name); ++ if (ret) { ++ NVT_LOG("Unable to get touchscreen firmware name\n"); ++ ts->fw_name = DEFAULT_BOOT_UPDATE_FIRMWARE_NAME; ++ } ++ ++ ret = of_property_read_u32(np, "spi-max-frequency", &ts->spi_max_freq); ++ if (ret) { ++ NVT_LOG("Unable to get spi freq\n"); ++ return ret; ++ } else { ++ NVT_LOG("spi-max-frequency: %u\n", ts->spi_max_freq); ++ } ++ ++ return ret; ++} ++#else ++static int32_t nvt_parse_dt(struct device *dev) ++{ ++#if NVT_TOUCH_SUPPORT_HW_RST ++ ts->reset_gpio = NVTTOUCH_RST_PIN; ++#endif ++ ts->irq_gpio = NVTTOUCH_INT_PIN; ++ return 0; ++} ++#endif ++ ++/******************************************************* ++Description: ++ Novatek touchscreen config and request gpio ++ ++return: ++ Executive outcomes. 0---succeed. not 0---failed. ++*******************************************************/ ++static int nvt_gpio_config(struct nvt_ts_data *ts) ++{ ++ int32_t ret = 0; ++ ++#if NVT_TOUCH_SUPPORT_HW_RST ++ /* request RST-pin (Output/High) */ ++ if (gpio_is_valid(ts->reset_gpio)) { ++ ret = gpio_request_one(ts->reset_gpio, GPIOF_OUT_INIT_LOW, "NVT-tp-rst"); ++ if (ret) { ++ NVT_ERR("Failed to request NVT-tp-rst GPIO\n"); ++ goto err_request_reset_gpio; ++ } ++ } ++#endif ++ ++ /* request INT-pin (Input) */ ++ if (gpio_is_valid(ts->irq_gpio)) { ++ ret = gpio_request_one(ts->irq_gpio, GPIOF_IN, "NVT-int"); ++ if (ret) { ++ NVT_ERR("Failed to request NVT-int GPIO\n"); ++ goto err_request_irq_gpio; ++ } ++ } ++ ++ return ret; ++ ++err_request_irq_gpio: ++#if NVT_TOUCH_SUPPORT_HW_RST ++ gpio_free(ts->reset_gpio); ++err_request_reset_gpio: ++#endif ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen deconfig gpio ++ ++return: ++ n.a. ++*******************************************************/ ++static void nvt_gpio_deconfig(struct nvt_ts_data *ts) ++{ ++ if (gpio_is_valid(ts->irq_gpio)) ++ gpio_free(ts->irq_gpio); ++#if NVT_TOUCH_SUPPORT_HW_RST ++ if (gpio_is_valid(ts->reset_gpio)) ++ gpio_free(ts->reset_gpio); ++#endif ++} ++ ++static uint8_t nvt_fw_recovery(uint8_t *point_data) ++{ ++ uint8_t i = 0; ++ uint8_t detected = true; ++ ++ /* check pattern */ ++ for (i=1 ; i<7 ; i++) { ++ if (point_data[i] != 0x77) { ++ detected = false; ++ break; ++ } ++ } ++ ++ return detected; ++} ++ ++void nvt_set_dbgfw_status(bool enable) ++{ ++ ts->fw_debug = enable; ++} ++ ++bool nvt_get_dbgfw_status(void) ++{ ++ return ts->fw_debug; ++} ++ ++#if NVT_TOUCH_ESD_PROTECT ++void nvt_esd_check_enable(uint8_t enable) ++{ ++ /* update interrupt timer */ ++ irq_timer = jiffies; ++ /* clear esd_retry counter, if protect function is enabled */ ++ esd_retry = enable ? 0 : esd_retry; ++ /* enable/disable esd check flag */ ++ esd_check = enable; ++} ++ ++static void nvt_esd_check_func(struct work_struct *work) ++{ ++ unsigned int timer = jiffies_to_msecs(jiffies - irq_timer); ++ ++ //NVT_LOG("esd_check = %d (retry %d)\n", esd_check, esd_retry); //DEBUG ++ ++ if ((timer > NVT_TOUCH_ESD_CHECK_PERIOD) && esd_check) { ++ 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(ts->fw_name); ++ mutex_unlock(&ts->lock); ++ /* update interrupt timer */ ++ irq_timer = jiffies; ++ /* update esd_retry counter */ ++ esd_retry++; ++ } ++ ++ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, ++ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); ++} ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++#if NVT_TOUCH_WDT_RECOVERY ++static uint8_t recovery_cnt = 0; ++static uint8_t nvt_wdt_fw_recovery(uint8_t *point_data) ++{ ++ uint32_t recovery_cnt_max = 10; ++ uint8_t recovery_enable = false; ++ uint8_t i = 0; ++ ++ recovery_cnt++; ++ ++ /* check pattern */ ++ for (i=1 ; i<7 ; i++) { ++ if ((point_data[i] != 0xFD) && (point_data[i] != 0xFE)) { ++ recovery_cnt = 0; ++ break; ++ } ++ } ++ ++ if (recovery_cnt > recovery_cnt_max){ ++ recovery_enable = true; ++ recovery_cnt = 0; ++ } ++ ++ return recovery_enable; ++} ++#endif /* #if NVT_TOUCH_WDT_RECOVERY */ ++ ++#define PEN_DATA_LEN 14 ++#define FW_HISTORY_SIZE 128 ++static uint32_t nvt_dump_fw_history(void) ++{ ++ int32_t ret = 0; ++ uint8_t buf[FW_HISTORY_SIZE + 1 + DUMMY_BYTES] = {0}; ++ int32_t i = 0; ++ char *tmp_dump = NULL; ++ int32_t line_cnt = 0; ++ ++ if (ts->mmap->FW_HISTORY_ADDR == 0) { ++ NVT_ERR("FW_HISTORY_ADDR not available!\n"); ++ ret = -1; ++ goto exit_nvt_dump_fw_history; ++ } ++ nvt_set_page(ts->mmap->FW_HISTORY_ADDR); ++ buf[0] = ts->mmap->FW_HISTORY_ADDR & 0xFF; ++ CTP_SPI_READ(ts->client, buf, FW_HISTORY_SIZE + 1); ++ if (ret) { ++ NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); ++ ret = -1; ++ goto exit_nvt_dump_fw_history; ++ } ++ ++ tmp_dump = (char *)kzalloc(FW_HISTORY_SIZE * 4, GFP_KERNEL); ++ for (i = 0; i < FW_HISTORY_SIZE; i++) { ++ sprintf(tmp_dump + i * 3 + line_cnt, "%02X ", buf[1 + i]); ++ if ((i + 1) % 16 == 0) { ++ sprintf(tmp_dump + i * 3 + line_cnt + 3, "%c", '\n'); ++ line_cnt++; ++ } ++ } ++ NVT_LOG("%s", tmp_dump); ++ ++exit_nvt_dump_fw_history: ++ if (tmp_dump) { ++ kfree(tmp_dump); ++ tmp_dump = NULL; ++ } ++ nvt_set_page(ts->mmap->EVENT_BUF_ADDR); ++ ++ return ret; ++} ++ ++#define POINT_DATA_LEN 65 ++/******************************************************* ++Description: ++ Novatek touchscreen work function. ++ ++return: ++ n.a. ++*******************************************************/ ++static irqreturn_t nvt_ts_work_func(int irq, void *data) ++{ ++ int32_t ret = -1; ++ uint8_t point_data[POINT_DATA_LEN + PEN_DATA_LEN + 1 + DUMMY_BYTES] = {0}; ++ uint32_t position = 0; ++ uint32_t input_x = 0; ++ uint32_t input_y = 0; ++ uint32_t input_w = 0; ++ uint32_t input_p = 0; ++ uint8_t input_id = 0; ++#if MT_PROTOCOL_B ++ uint8_t press_id[TOUCH_MAX_FINGER_NUM] = {0}; ++#endif /* MT_PROTOCOL_B */ ++ int32_t i = 0; ++ int32_t finger_cnt = 0; ++ uint8_t pen_format_id = 0; ++ uint32_t pen_x = 0; ++ uint32_t pen_y = 0; ++ uint32_t pen_pressure = 0; ++ uint32_t pen_distance = 0; ++ int8_t pen_tilt_x = 0; ++ int8_t pen_tilt_y = 0; ++ uint32_t pen_btn1 = 0; ++ uint32_t pen_btn2 = 0; ++ uint32_t pen_battery = 0; ++ ++ mutex_lock(&ts->lock); ++ ++ if (ts->dev_pm_suspend) { ++ ret = wait_for_completion_timeout(&ts->dev_pm_suspend_completion, msecs_to_jiffies(500)); ++ if (!ret) { ++ NVT_ERR("system(spi) can't finished resuming procedure, skip it\n"); ++ goto XFER_ERROR; ++ } ++ } ++ ++ if (ts->pen_support) ++ ret = CTP_SPI_READ(ts->client, point_data, POINT_DATA_LEN + PEN_DATA_LEN + 1); ++ else ++ ret = CTP_SPI_READ(ts->client, point_data, POINT_DATA_LEN + 1); ++ if (ret < 0) { ++ NVT_ERR("CTP_SPI_READ failed.(%d)\n", ret); ++ goto XFER_ERROR; ++ } ++ ++ /*--- dump SPI buf --- ++ for (i = 0; i < 10; i++) { ++ NVT_LOG("%02X %02X %02X %02X %02X %02X \n", ++ point_data[1+i*6], point_data[2+i*6], point_data[3+i*6], point_data[4+i*6], point_data[5+i*6], point_data[6+i*6]); ++ } ++ */ ++ ++#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]); ++ if (point_data[1] == 0xFD) { ++ NVT_ERR("Dump FW history:\n"); ++ nvt_dump_fw_history(); ++ } ++ nvt_update_firmware(ts->fw_name); ++ goto XFER_ERROR; ++ } ++#endif /* #if NVT_TOUCH_WDT_RECOVERY */ ++ ++ /* ESD protect by FW handshake */ ++ if (nvt_fw_recovery(point_data)) { ++#if NVT_TOUCH_ESD_PROTECT ++ nvt_esd_check_enable(true); ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ goto XFER_ERROR; ++ } ++ ++ finger_cnt = 0; ++ ++ for (i = 0; i < ts->max_touch_num; i++) { ++ position = 1 + 6 * i; ++ 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) ++#if NVT_TOUCH_ESD_PROTECT ++ /* update interrupt timer */ ++ irq_timer = jiffies; ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ input_x = (uint32_t)(point_data[position + 1] << 4) + (uint32_t) (point_data[position + 3] >> 4); ++ input_y = (uint32_t)(point_data[position + 2] << 4) + (uint32_t) (point_data[position + 3] & 0x0F); ++ if ((input_x < 0) || (input_y < 0)) ++ 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 { ++ input_p = (uint32_t)(point_data[position + 5]); ++ } ++ if (input_p == 0) ++ input_p = 1; ++ ++#if MT_PROTOCOL_B ++ press_id[input_id - 1] = 1; ++ input_mt_slot(ts->input_dev, input_id - 1); ++ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); ++#else /* MT_PROTOCOL_B */ ++ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, input_id - 1); ++ 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); ++ ++#if MT_PROTOCOL_B ++#else /* MT_PROTOCOL_B */ ++ input_mt_sync(ts->input_dev); ++#endif /* MT_PROTOCOL_B */ ++ ++ finger_cnt++; ++ } ++ } ++ ++#if MT_PROTOCOL_B ++ for (i = 0; i < ts->max_touch_num; i++) { ++ if (press_id[i] != 1) { ++ input_mt_slot(ts->input_dev, i); ++ 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); ++ } ++ } ++ input_report_key(ts->input_dev, BTN_TOUCH, (finger_cnt > 0)); ++#else /* MT_PROTOCOL_B */ ++ if (finger_cnt == 0) { ++ input_report_key(ts->input_dev, BTN_TOUCH, 0); ++ input_mt_sync(ts->input_dev); ++ } ++#endif /* MT_PROTOCOL_B */ ++ ++#if TOUCH_KEY_NUM > 0 ++ if (point_data[61] == 0xF8) { ++#if NVT_TOUCH_ESD_PROTECT ++ /* update interrupt timer */ ++ irq_timer = jiffies; ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ for (i = 0; i < ts->max_button_num; i++) { ++ input_report_key(ts->input_dev, touch_key_array[i], ((point_data[62] >> i) & 0x01)); ++ } ++ } else { ++ for (i = 0; i < ts->max_button_num; i++) { ++ input_report_key(ts->input_dev, touch_key_array[i], 0); ++ } ++ } ++#endif ++ ++ input_sync(ts->input_dev); ++ ++ if (ts->pen_support && ts->pen_input_dev_enable && !(ts->pen_is_charge)) { ++/* ++ //--- dump pen buf --- ++ printk("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", ++ point_data[66], point_data[67], point_data[68], point_data[69], point_data[70], ++ point_data[71], point_data[72], point_data[73], point_data[74], point_data[75], ++ point_data[76], point_data[77], point_data[78], point_data[79]); ++*/ ++ // parse and handle pen report ++ pen_format_id = point_data[66]; ++ if (pen_format_id != 0xFF) { ++ if (pen_format_id == 0x01) { ++ // report pen data ++ pen_x = (uint32_t)(point_data[67] << 8) + (uint32_t)(point_data[68]); ++ pen_y = (uint32_t)(point_data[69] << 8) + (uint32_t)(point_data[70]); ++ if (pen_x >= ts->abs_x_max * 2 - 1) { ++ pen_x -= 1; ++ } ++ if (pen_y >= ts->abs_y_max * 2 - 1) { ++ pen_y -= 1; ++ } ++ pen_pressure = (uint32_t)(point_data[71] << 8) + (uint32_t)(point_data[72]); ++ pen_tilt_x = (int32_t)point_data[73]; ++ pen_tilt_y = (int32_t)point_data[74]; ++ pen_distance = (uint32_t)(point_data[75] << 8) + (uint32_t)(point_data[76]); ++ pen_btn1 = (uint32_t)(point_data[77] & 0x01); ++ pen_btn2 = (uint32_t)((point_data[77] >> 1) & 0x01); ++ pen_battery = (uint32_t)point_data[78]; ++// printk("x=%d,y=%d,p=%d,tx=%d,ty=%d,d=%d,b1=%d,b2=%d,bat=%d\n", pen_x, pen_y, pen_pressure, ++// pen_tilt_x, pen_tilt_y, pen_distance, pen_btn1, pen_btn2, pen_battery); ++ ++ input_report_abs(ts->pen_input_dev, ABS_X, pen_x); ++ input_report_abs(ts->pen_input_dev, ABS_Y, pen_y); ++ input_report_abs(ts->pen_input_dev, ABS_PRESSURE, pen_pressure); ++ input_report_key(ts->pen_input_dev, BTN_TOUCH, !!pen_pressure); ++ input_report_abs(ts->pen_input_dev, ABS_TILT_X, pen_tilt_x); ++ input_report_abs(ts->pen_input_dev, ABS_TILT_Y, pen_tilt_y); ++ input_report_abs(ts->pen_input_dev, ABS_DISTANCE, pen_distance); ++ input_report_key(ts->pen_input_dev, BTN_TOOL_PEN, !!pen_distance || !!pen_pressure); ++ input_report_key(ts->pen_input_dev, BTN_STYLUS, pen_btn1); ++ input_report_key(ts->pen_input_dev, BTN_STYLUS2, pen_btn2); ++ input_sync(ts->pen_input_dev); ++ // TBD: pen battery event report ++ // NVT_LOG("pen_battery=%d\n", pen_battery); ++ } else if (pen_format_id == 0xF0) { ++ // report Pen ID ++ } else { ++ NVT_ERR("Unknown pen format id!\n"); ++ goto XFER_ERROR; ++ } ++ } else { // pen_format_id = 0xFF, i.e. no pen present ++ release_pen_event(); ++ } ++ } /* if (ts->pen_support) */ ++ ++XFER_ERROR: ++ ++ mutex_unlock(&ts->lock); ++ return IRQ_HANDLED; ++} ++ ++ ++/******************************************************* ++Description: ++ Novatek touchscreen check chip version trim function. ++ ++return: ++ Executive outcomes. 0---NVT IC. -1---not NVT IC. ++*******************************************************/ ++static int8_t nvt_ts_check_chip_ver_trim(uint32_t chip_ver_trim_addr) ++{ ++ ++ ts->mmap = &NT36523_memory_map; ++ ts->carrier_system = NT36523_hw_info.carrier_system; ++ ts->hw_crc = NT36523_hw_info.hw_crc; ++ return 0; ++} ++ ++static void nvt_suspend_work(struct work_struct *work) ++{ ++ struct nvt_ts_data *ts_core = container_of(work, struct nvt_ts_data, suspend_work); ++ nvt_ts_suspend(&ts_core->client->dev); ++} ++ ++static void nvt_resume_work(struct work_struct *work) ++{ ++ struct nvt_ts_data *ts_core = container_of(work, struct nvt_ts_data, resume_work); ++ nvt_ts_resume(&ts_core->client->dev); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen driver probe function. ++ ++return: ++ Executive outcomes. 0---succeed. negative---failed ++*******************************************************/ ++static int32_t nvt_ts_probe(struct spi_device *client) ++{ ++ int32_t ret = 0; ++#if (TOUCH_KEY_NUM > 0) ++ int32_t retry = 0; ++#endif ++ ++ NVT_LOG("probe start\n"); ++ ++ ts = kzalloc(sizeof(struct nvt_ts_data), GFP_KERNEL); ++ if (ts == NULL) { ++ NVT_ERR("failed to allocated memory for nvt ts data\n"); ++ return -ENOMEM; ++ } ++ ++ ts->xbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN+1+DUMMY_BYTES), GFP_KERNEL); ++ if(ts->xbuf == NULL) { ++ NVT_ERR("kzalloc for xbuf failed!\n"); ++ ret = -ENOMEM; ++ goto err_malloc_xbuf; ++ } ++ ++ ts->rbuf = (uint8_t *)kzalloc(NVT_READ_LEN, GFP_KERNEL); ++ if(ts->rbuf == NULL) { ++ NVT_ERR("kzalloc for rbuf failed!\n"); ++ ret = -ENOMEM; ++ goto err_malloc_rbuf; ++ } ++ ++ ts->client = client; ++ spi_set_drvdata(client, ts); ++ ++ //---prepare for spi parameter--- ++ if (ts->client->controller->flags & SPI_CONTROLLER_HALF_DUPLEX) { ++ NVT_ERR("Full duplex not supported by master\n"); ++ ret = -EIO; ++ goto err_ckeck_full_duplex; ++ } ++ ts->client->bits_per_word = 8; ++ ts->client->mode = SPI_MODE_0; ++ ++ ret = spi_setup(ts->client); ++ if (ret < 0) { ++ NVT_ERR("Failed to perform SPI setup\n"); ++ goto err_spi_setup; ++ } ++ ++#ifdef CONFIG_MTK_SPI ++ /* old usage of MTK spi API */ ++ memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mt_chip_conf)); ++ ts->client->controller_data = (void *)&ts->spi_ctrl; ++#endif ++ ++#ifdef CONFIG_SPI_MT65XX ++ /* new usage of MTK spi API */ ++ memcpy(&ts->spi_ctrl, &spi_ctrdata, sizeof(struct mtk_chip_config)); ++ ts->client->controller_data = (void *)&ts->spi_ctrl; ++#endif ++ ++ NVT_LOG("mode=%d, max_speed_hz=%d\n", ts->client->mode, ts->client->max_speed_hz); ++ ++ //---parse dts--- ++ ret = nvt_parse_dt(&client->dev); ++ if (ret) { ++ NVT_ERR("parse dt error\n"); ++ goto err_spi_setup; ++ } ++ ++ //---request and config GPIOs--- ++ ret = nvt_gpio_config(ts); ++ if (ret) { ++ NVT_ERR("gpio config error!\n"); ++ goto err_gpio_config_failed; ++ } ++ ++ mutex_init(&ts->lock); ++ mutex_init(&ts->xbuf_lock); ++ ++ //---eng reset before TP_RESX high ++ nvt_eng_reset(); ++ ++#if NVT_TOUCH_SUPPORT_HW_RST ++ gpio_set_value(ts->reset_gpio, 1); ++#endif ++ ++ // need 10ms delay after POR(power on reset) ++ msleep(10); ++ ++ //---check chip version trim--- ++ ret = nvt_ts_check_chip_ver_trim(CHIP_VER_TRIM_ADDR); ++ if (ret) { ++ NVT_LOG("try to check from old chip ver trim address\n"); ++ ret = nvt_ts_check_chip_ver_trim(CHIP_VER_TRIM_OLD_ADDR); ++ if (ret) { ++ NVT_ERR("chip is not identified\n"); ++ ret = -EINVAL; ++ goto err_chipvertrim_failed; ++ } ++ } ++ ++ ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; ++ ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; ++ ++ //---allocate input device--- ++ ts->input_dev = input_allocate_device(); ++ if (ts->input_dev == NULL) { ++ NVT_ERR("allocate input device failed\n"); ++ ret = -ENOMEM; ++ goto err_input_dev_alloc_failed; ++ } ++ ++ ts->max_touch_num = TOUCH_MAX_FINGER_NUM; ++ ++#if TOUCH_KEY_NUM > 0 ++ ts->max_button_num = TOUCH_KEY_NUM; ++#endif ++ ++ ts->int_trigger_type = INT_TRIGGER_TYPE; ++ ++ //---set input device info.--- ++ ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ts->input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); ++ ++ ts->db_wakeup = 0; ++ ts->fw_ver = 0; ++ ts->x_num = 32; ++ ts->y_num = 50; ++ ts->x_gang_num = 4; ++ ts->y_gang_num = 6; ++ ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH; ++ ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT; ++ ts->max_button_num = TOUCH_KEY_NUM; ++ NVT_LOG("Set default fw_ver=%d, x_num=%d, y_num=%d, " ++ "abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n", ++ ts->fw_ver, ts->x_num, ts->y_num, ++ ts->abs_x_max, ts->abs_y_max, ts->max_button_num); ++ ++#if MT_PROTOCOL_B ++ input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0); ++#endif ++ ++ 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 ++ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); //area = 255 ++ ++ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max - 1, 0, 0); ++ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max - 1, 0, 0); ++#if MT_PROTOCOL_B ++ // no need to set ABS_MT_TRACKING_ID, input_mt_init_slots() already set it ++#else ++ input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, ts->max_touch_num, 0, 0); ++#endif //MT_PROTOCOL_B ++#endif //TOUCH_MAX_FINGER_NUM > 1 ++ ++#if TOUCH_KEY_NUM > 0 ++ for (retry = 0; retry < ts->max_button_num; retry++) { ++ input_set_capability(ts->input_dev, EV_KEY, touch_key_array[retry]); ++ } ++#endif ++ ++ sprintf(ts->phys, "input/ts"); ++ ts->input_dev->name = NVT_TS_NAME; ++ ts->input_dev->phys = ts->phys; ++ ts->input_dev->id.bustype = BUS_SPI; ++ ++ //---register input device--- ++ ret = input_register_device(ts->input_dev); ++ if (ret) { ++ NVT_ERR("register input device (%s) failed. ret=%d\n", ts->input_dev->name, ret); ++ goto err_input_register_device_failed; ++ } ++ ++ if (ts->pen_support) { ++ //---allocate pen input device--- ++ ts->pen_input_dev = input_allocate_device(); ++ if (ts->pen_input_dev == NULL) { ++ NVT_ERR("allocate pen input device failed\n"); ++ ret = -ENOMEM; ++ goto err_pen_input_dev_alloc_failed; ++ } ++ ++ //---set pen input device info.--- ++ ts->pen_input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ ts->pen_input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ts->pen_input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN); ++ //ts->pen_input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER); ++ ts->pen_input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS); ++ ts->pen_input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2); ++ ts->pen_input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); ++ ++ if (ts->wgp_stylus) { ++ input_set_abs_params(ts->pen_input_dev, ABS_X, 0, ts->abs_x_max * 2 - 1, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, ts->abs_y_max * 2 - 1, 0, 0); ++ } else { ++ input_set_abs_params(ts->pen_input_dev, ABS_X, 0, ts->abs_x_max - 1, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, ts->abs_y_max - 1, 0, 0); ++ } ++ ++ input_set_abs_params(ts->pen_input_dev, ABS_PRESSURE, 0, PEN_PRESSURE_MAX, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_DISTANCE, 0, PEN_DISTANCE_MAX, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_TILT_X, PEN_TILT_MIN, PEN_TILT_MAX, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_TILT_Y, PEN_TILT_MIN, PEN_TILT_MAX, 0, 0); ++ ++ sprintf(ts->pen_phys, "input/pen"); ++ ts->pen_input_dev->name = NVT_PEN_NAME; ++ ts->pen_input_dev->phys = ts->pen_phys; ++ ts->pen_input_dev->id.bustype = BUS_SPI; ++ ++ //---register pen input device--- ++ ret = input_register_device(ts->pen_input_dev); ++ if (ret) { ++ NVT_ERR("register pen input device (%s) failed. ret=%d\n", ts->pen_input_dev->name, ret); ++ goto err_pen_input_register_device_failed; ++ } ++ } /* if (ts->pen_support) */ ++ ++ //---set int-pin & request irq--- ++ client->irq = gpio_to_irq(ts->irq_gpio); ++ if (client->irq) { ++ NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type); ++ ts->irq_enabled = true; ++ ret = request_threaded_irq(client->irq, NULL, nvt_ts_work_func, ++ ts->int_trigger_type | IRQF_ONESHOT, NVT_SPI_NAME, ts); ++ if (ret != 0) { ++ NVT_ERR("request irq failed. ret=%d\n", ret); ++ goto err_int_request_failed; ++ } else { ++ nvt_irq_enable(false); ++ NVT_LOG("request irq %d succeed\n", client->irq); ++ } ++ } ++ ++ ts->pen_is_charge = false; ++ ++ ts->lkdown_readed =false; ++ pm_stay_awake(&client->dev); ++ ++ ts->ic_state = NVT_IC_INIT; ++ ts->dev_pm_suspend = false; ++ ts->gesture_command_delayed = -1; ++ init_completion(&ts->dev_pm_suspend_completion); ++ ts->fw_debug = false; ++ ++#ifdef CONFIG_FACTORY_BUILD ++ ts->pen_input_dev_enable = 1; ++#else ++ ts->pen_input_dev_enable = 0; ++#endif ++ ++#if BOOT_UPDATE_FIRMWARE ++ nvt_fwu_wq = alloc_workqueue("nvt_fwu_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); ++ if (!nvt_fwu_wq) { ++ NVT_ERR("nvt_fwu_wq create workqueue failed\n"); ++ ret = -ENOMEM; ++ goto err_create_nvt_fwu_wq_failed; ++ } ++ INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware); ++ // please make sure boot update start after display reset(RESX) sequence ++ queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(14000)); ++#endif ++ ++ NVT_LOG("NVT_TOUCH_ESD_PROTECT is %d\n", NVT_TOUCH_ESD_PROTECT); ++#if NVT_TOUCH_ESD_PROTECT ++ INIT_DELAYED_WORK(&nvt_esd_check_work, nvt_esd_check_func); ++ nvt_esd_check_wq = alloc_workqueue("nvt_esd_check_wq", WQ_MEM_RECLAIM, 1); ++ if (!nvt_esd_check_wq) { ++ NVT_ERR("nvt_esd_check_wq create workqueue failed\n"); ++ ret = -ENOMEM; ++ goto err_create_nvt_esd_check_wq_failed; ++ } ++ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, ++ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++ ts->event_wq = alloc_workqueue("nvt-event-queue", ++ WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); ++ if (!ts->event_wq) { ++ NVT_ERR("Can not create work thread for suspend/resume!!"); ++ ret = -ENOMEM; ++ goto err_alloc_work_thread_failed; ++ } ++ INIT_WORK(&ts->resume_work, nvt_resume_work); ++ INIT_WORK(&ts->suspend_work, nvt_suspend_work); ++ ++#ifdef CONFIG_DRM ++ ts->drm_notif.notifier_call = nvt_drm_notifier_callback; ++ ret = mi_drm_register_client(&ts->drm_notif); ++ if(ret) { ++ NVT_ERR("register drm_notifier failed. ret=%d\n", ret); ++ goto err_register_drm_notif_failed; ++ } ++#endif ++ ++ bTouchIsAwake = 1; ++ NVT_LOG("end\n"); ++ ++ nvt_irq_enable(true); ++ ++ return 0; ++ ++#ifdef CONFIG_DRM ++ if (mi_drm_unregister_client(&ts->drm_notif)) ++ NVT_ERR("Error occurred while unregistering drm_notifier.\n"); ++err_register_drm_notif_failed: ++#endif ++ ++err_alloc_work_thread_failed: ++ ++#if NVT_TOUCH_ESD_PROTECT ++ if (nvt_esd_check_wq) { ++ cancel_delayed_work_sync(&nvt_esd_check_work); ++ destroy_workqueue(nvt_esd_check_wq); ++ nvt_esd_check_wq = NULL; ++ } ++err_create_nvt_esd_check_wq_failed: ++#endif ++#if BOOT_UPDATE_FIRMWARE ++ if (nvt_fwu_wq) { ++ cancel_delayed_work_sync(&ts->nvt_fwu_work); ++ destroy_workqueue(nvt_fwu_wq); ++ nvt_fwu_wq = NULL; ++ } ++err_create_nvt_fwu_wq_failed: ++ ++#endif ++ free_irq(client->irq, ts); ++err_int_request_failed: ++ if (ts->pen_support) { ++ input_unregister_device(ts->pen_input_dev); ++ ts->pen_input_dev = NULL; ++ } ++err_pen_input_register_device_failed: ++ if (ts->pen_support) { ++ if (ts->pen_input_dev) { ++ input_free_device(ts->pen_input_dev); ++ ts->pen_input_dev = NULL; ++ } ++ } ++err_pen_input_dev_alloc_failed: ++ input_unregister_device(ts->input_dev); ++ ts->input_dev = NULL; ++err_input_register_device_failed: ++ if (ts->input_dev) { ++ input_free_device(ts->input_dev); ++ ts->input_dev = NULL; ++ } ++err_input_dev_alloc_failed: ++err_chipvertrim_failed: ++ mutex_destroy(&ts->xbuf_lock); ++ mutex_destroy(&ts->lock); ++ nvt_gpio_deconfig(ts); ++err_gpio_config_failed: ++err_spi_setup: ++err_ckeck_full_duplex: ++ spi_set_drvdata(client, NULL); ++ if (ts->rbuf) { ++ kfree(ts->rbuf); ++ ts->rbuf = NULL; ++ } ++err_malloc_rbuf: ++ if (ts->xbuf) { ++ kfree(ts->xbuf); ++ ts->xbuf = NULL; ++ } ++err_malloc_xbuf: ++ if (ts) { ++ kfree(ts); ++ ts = NULL; ++ } ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen driver release function. ++ ++return: ++ Executive outcomes. 0---succeed. ++*******************************************************/ ++static void nvt_ts_remove(struct spi_device *client) ++{ ++ NVT_LOG("Removing driver...\n"); ++ ++#ifdef CONFIG_DRM ++ if (mi_drm_unregister_client(&ts->drm_notif)) ++ NVT_ERR("Error occurred while unregistering drm_notifier.\n"); ++#endif ++ ++#if NVT_TOUCH_ESD_PROTECT ++ if (nvt_esd_check_wq) { ++ cancel_delayed_work_sync(&nvt_esd_check_work); ++ nvt_esd_check_enable(false); ++ destroy_workqueue(nvt_esd_check_wq); ++ nvt_esd_check_wq = NULL; ++ } ++#endif ++ ++#if BOOT_UPDATE_FIRMWARE ++ if (nvt_fwu_wq) { ++ cancel_delayed_work_sync(&ts->nvt_fwu_work); ++ destroy_workqueue(nvt_fwu_wq); ++ nvt_fwu_wq = NULL; ++ } ++#endif ++ ++ nvt_irq_enable(false); ++ free_irq(client->irq, ts); ++ ++ mutex_destroy(&ts->xbuf_lock); ++ mutex_destroy(&ts->lock); ++ ++ nvt_gpio_deconfig(ts); ++ ++ if (ts->pen_support) { ++ if (ts->pen_input_dev) { ++ input_unregister_device(ts->pen_input_dev); ++ ts->pen_input_dev = NULL; ++ } ++ } ++ ++ if (ts->input_dev) { ++ input_unregister_device(ts->input_dev); ++ ts->input_dev = NULL; ++ } ++ ++ spi_set_drvdata(client, NULL); ++ ++ if (ts) { ++ kfree(ts); ++ ts = NULL; ++ } ++} ++ ++static void nvt_ts_shutdown(struct spi_device *client) ++{ ++ NVT_LOG("Shutdown driver...\n"); ++ ++ nvt_irq_enable(false); ++ ++#ifdef CONFIG_DRM ++ if (mi_drm_unregister_client(&ts->drm_notif)) ++ NVT_ERR("Error occurred while unregistering drm_notifier.\n"); ++#endif ++ ++ destroy_workqueue(ts->event_wq); ++ ++#if NVT_TOUCH_ESD_PROTECT ++ if (nvt_esd_check_wq) { ++ cancel_delayed_work_sync(&nvt_esd_check_work); ++ nvt_esd_check_enable(false); ++ destroy_workqueue(nvt_esd_check_wq); ++ nvt_esd_check_wq = NULL; ++ } ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++#if BOOT_UPDATE_FIRMWARE ++ if (nvt_fwu_wq) { ++ cancel_delayed_work_sync(&ts->nvt_fwu_work); ++ destroy_workqueue(nvt_fwu_wq); ++ nvt_fwu_wq = NULL; ++ } ++#endif ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen driver suspend function. ++ ++return: ++ Executive outcomes. 0---succeed. ++*******************************************************/ ++static int32_t nvt_ts_suspend(struct device *dev) ++{ ++ uint8_t buf[4] = {0}; ++#if MT_PROTOCOL_B ++ uint32_t i = 0; ++#endif ++ ++ if (!bTouchIsAwake) { ++ NVT_LOG("Touch is already suspend\n"); ++ return 0; ++ } ++ ++ pm_stay_awake(dev); ++ ts->ic_state = NVT_IC_SUSPEND_IN; ++ ++ if (!ts->db_wakeup) { ++ if (!ts->irq_enabled) ++ NVT_LOG("IRQ already disabled\n"); ++ else ++ nvt_irq_enable(false); ++ } ++ ++#if NVT_TOUCH_ESD_PROTECT ++ NVT_LOG("cancel delayed work sync\n"); ++ cancel_delayed_work_sync(&nvt_esd_check_work); ++ nvt_esd_check_enable(false); ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++ mutex_lock(&ts->lock); ++ ++ NVT_LOG("suspend start\n"); ++ ++ bTouchIsAwake = 0; ++ ++ if (ts->pen_input_dev_enable) { ++ NVT_LOG("if enable pen,will close it"); ++ } ++ ++ if (ts->db_wakeup) { ++ /*---write command to enter "wakeup gesture mode"---*/ ++ /*DoubleClick wakeup CMD was sent by display to meet timing*/ ++ /* ++ buf[0] = EVENT_MAP_HOST_CMD; ++ buf[1] = 0x13; ++ CTP_SPI_WRITE(ts->client, buf, 2); ++ */ ++ enable_irq_wake(ts->client->irq); ++ ++ NVT_LOG("Enabled touch wakeup gesture\n"); ++ } else { ++ /*---write command to enter "deep sleep mode"---*/ ++ buf[0] = EVENT_MAP_HOST_CMD; ++ buf[1] = 0x11; ++ CTP_SPI_WRITE(ts->client, buf, 2); ++ } ++ ++ mutex_unlock(&ts->lock); ++ ++ /* release all touches */ ++#if MT_PROTOCOL_B ++ for (i = 0; i < ts->max_touch_num; i++) { ++ input_mt_slot(ts->input_dev, i); ++ 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); ++ } ++#endif ++ input_report_key(ts->input_dev, BTN_TOUCH, 0); ++#if !MT_PROTOCOL_B ++ input_mt_sync(ts->input_dev); ++#endif ++ input_sync(ts->input_dev); ++ ++ msleep(50); ++ /* release pen event */ ++ release_pen_event(); ++ if (likely(ts->ic_state == NVT_IC_SUSPEND_IN)) ++ ts->ic_state = NVT_IC_SUSPEND_OUT; ++ else ++ NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); ++ pm_relax(dev); ++ NVT_LOG("end\n"); ++ ++ return 0; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen driver resume function. ++ ++return: ++ Executive outcomes. 0---succeed. ++*******************************************************/ ++static int32_t nvt_ts_resume(struct device *dev) ++{ ++ int ret = 0; ++ if (bTouchIsAwake) { ++ NVT_LOG("Touch is already resume\n"); ++ return 0; ++ } ++ ++ if (ts->dev_pm_suspend) ++ pm_stay_awake(dev); ++ ++ mutex_lock(&ts->lock); ++ ++ NVT_LOG("resume start\n"); ++ ts->ic_state = NVT_IC_RESUME_IN; ++ ++ // please make sure display reset(RESX) sequence and mipi dsi cmds sent before this ++#if NVT_TOUCH_SUPPORT_HW_RST ++ gpio_set_value(ts->reset_gpio, 1); ++#endif ++ ret = nvt_update_firmware(ts->fw_name); ++ if (ret) ++ NVT_ERR("download firmware failed\n"); ++ ++ nvt_check_fw_reset_state(RESET_STATE_REK); ++ ++ if (!ts->db_wakeup && !ts->irq_enabled) { ++ nvt_irq_enable(true); ++ } ++ ++#if NVT_TOUCH_ESD_PROTECT ++ nvt_esd_check_enable(false); ++ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work, ++ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD)); ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++ bTouchIsAwake = 1; ++ ++ mutex_unlock(&ts->lock); ++ ++ if (likely(ts->ic_state == NVT_IC_RESUME_IN)) { ++ ts->ic_state = NVT_IC_RESUME_OUT; ++ } else { ++ NVT_ERR("IC state may error,caused by suspend/resume flow, please CHECK!!"); ++ } ++ if (ts->gesture_command_delayed >= 0){ ++ ts->db_wakeup = ts->gesture_command_delayed; ++ ts->gesture_command_delayed = -1; ++ NVT_LOG("execute delayed command, set double click wakeup %d\n", ts->db_wakeup); ++ } ++ ++ if (ts->dev_pm_suspend) ++ pm_relax(dev); ++ NVT_LOG("end\n"); ++ ++ return 0; ++} ++ ++ ++#ifdef CONFIG_DRM ++static int nvt_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) ++{ ++ int blank = *(enum drm_notifier_data *)data; ++ struct nvt_ts_data *ts_data = ++ container_of(self, struct nvt_ts_data, drm_notif); ++ ++ if (data && ts_data) { ++ if (event == MI_DRM_EARLY_EVENT_BLANK) { ++ if (blank == MI_DRM_BLANK_POWERDOWN) { ++ NVT_LOG("event=%lu, *blank=%d\n", event, blank); ++ flush_workqueue(ts_data->event_wq); ++ queue_work(ts_data->event_wq, &ts_data->suspend_work); ++ } ++ } else if (event == MI_DRM_EVENT_BLANK) { ++ if (blank == MI_DRM_BLANK_UNBLANK) { ++ NVT_LOG("event=%lu, *blank=%d\n", event, blank); ++ flush_workqueue(ts_data->event_wq); ++ queue_work(ts_data->event_wq, &ts_data->resume_work); ++ } ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++static int nvt_pm_suspend(struct device *dev) ++{ ++ if (device_may_wakeup(dev) && ts->db_wakeup) { ++ NVT_LOG("enable touch irq wake\n"); ++ enable_irq_wake(ts->client->irq); ++ } ++ ts->dev_pm_suspend = true; ++ reinit_completion(&ts->dev_pm_suspend_completion); ++ ++ return 0; ++} ++ ++static int nvt_pm_resume(struct device *dev) ++{ ++ if (device_may_wakeup(dev) && ts->db_wakeup) { ++ NVT_LOG("disable touch irq wake\n"); ++ disable_irq_wake(ts->client->irq); ++ } ++ ts->dev_pm_suspend = false; ++ complete(&ts->dev_pm_suspend_completion); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops nvt_dev_pm_ops = { ++ .suspend = nvt_pm_suspend, ++ .resume = nvt_pm_resume, ++}; ++ ++static const struct spi_device_id nvt_ts_id[] = { ++ { NVT_SPI_NAME, 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(spi, nvt_ts_id); ++ ++#ifdef CONFIG_OF ++static struct of_device_id nvt_match_table[] = { ++ { .compatible = "novatek,NVT-ts-spi",}, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, nvt_match_table); ++#endif ++ ++static struct spi_driver nvt_spi_driver = { ++ .probe = nvt_ts_probe, ++ .remove = nvt_ts_remove, ++ .shutdown = nvt_ts_shutdown, ++ .id_table = nvt_ts_id, ++ .driver = { ++ .name = NVT_SPI_NAME, ++ .owner = THIS_MODULE, ++#ifdef CONFIG_PM ++ .pm = &nvt_dev_pm_ops, ++#endif ++#ifdef CONFIG_OF ++ .of_match_table = nvt_match_table, ++#endif ++ }, ++}; ++ ++module_spi_driver(nvt_spi_driver); ++ ++MODULE_DESCRIPTION("Novatek Touchscreen Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.h b/drivers/input/touchscreen/nt36523/nt36xxx.h +new file mode 100644 +index 000000000000..6642ec2f26cf +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.h +@@ -0,0 +1,242 @@ ++/* ++ * Copyright (C) 2010 - 2018 Novatek, Inc. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * $Revision: 69262 $ ++ * $Date: 2020-09-23 15:07:14 +0800 (週三, 23 九月 2020) $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ */ ++#ifndef _LINUX_NVT_TOUCH_H ++#define _LINUX_NVT_TOUCH_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "nt36xxx_mem_map.h" ++ ++#define NVT_DEBUG 1 ++ ++//---GPIO number--- ++#define NVTTOUCH_RST_PIN 980 ++#define NVTTOUCH_INT_PIN 943 ++ ++#define PINCTRL_STATE_ACTIVE "pmx_ts_active" ++#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" ++ ++//---INT trigger mode--- ++//#define IRQ_TYPE_EDGE_RISING 1 ++//#define IRQ_TYPE_EDGE_FALLING 2 ++#define INT_TRIGGER_TYPE IRQ_TYPE_EDGE_RISING ++ ++ ++//---SPI driver info.--- ++#define NVT_SPI_NAME "NVT-ts-spi" ++ ++#if NVT_DEBUG ++#define NVT_LOG(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) ++#else ++#define NVT_LOG(fmt, args...) pr_info("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) ++#endif ++#define NVT_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) ++ ++//---Input device info.--- ++#define NVT_TS_NAME "NVTCapacitiveTouchScreen" ++#define NVT_PEN_NAME "NVTCapacitivePen" ++ ++//---Touch info.--- ++#define TOUCH_DEFAULT_MAX_WIDTH 1600 ++#define TOUCH_DEFAULT_MAX_HEIGHT 2560 ++#define TOUCH_MAX_FINGER_NUM 10 ++#define TOUCH_KEY_NUM 0 ++#if TOUCH_KEY_NUM > 0 ++extern const uint16_t touch_key_array[TOUCH_KEY_NUM]; ++#endif ++#define TOUCH_FORCE_NUM 1000 ++//---for Pen--- ++#define PEN_PRESSURE_MAX (4095) ++#define PEN_DISTANCE_MAX (1) ++#define PEN_TILT_MIN (-60) ++#define PEN_TILT_MAX (60) ++ ++/* Enable only when module have tp reset pin and connected to host */ ++#define NVT_TOUCH_SUPPORT_HW_RST 0 ++ ++//---Customerized func.--- ++#define NVT_TOUCH_MP 0 ++#define NVT_TOUCH_MP_SETTING_CRITERIA_FROM_CSV 0 ++#define MT_PROTOCOL_B 1 ++#define FUNCPAGE_PALM 4 ++#define PACKET_PALM_ON 3 ++#define PACKET_PALM_OFF 4 ++ ++#define BOOT_UPDATE_FIRMWARE 1 ++#define DEFAULT_BOOT_UPDATE_FIRMWARE_NAME "novatek/nt36523.bin" ++#define DEFAULT_MP_UPDATE_FIRMWARE_NAME "novatek_ts_mp.bin" ++ ++//---ESD Protect.--- ++#define NVT_TOUCH_ESD_PROTECT 1 ++#define NVT_TOUCH_ESD_CHECK_PERIOD 1500 /* ms */ ++#define NVT_TOUCH_WDT_RECOVERY 1 ++ ++enum nvt_ic_state { ++ NVT_IC_SUSPEND_IN, ++ NVT_IC_SUSPEND_OUT, ++ NVT_IC_RESUME_IN, ++ NVT_IC_RESUME_OUT, ++ NVT_IC_INIT, ++}; ++ ++struct nvt_config_info { ++ u8 tp_vendor; ++ u8 tp_color; ++ u8 display_maker; ++ u8 glass_vendor; ++ const char *nvt_fw_name; ++ const char *nvt_mp_name; ++ const char *nvt_limit_name; ++}; ++ ++struct nvt_ts_data { ++ struct spi_device *client; ++ struct input_dev *input_dev; ++ struct delayed_work nvt_fwu_work; ++ struct work_struct switch_mode_work; ++ struct work_struct pen_charge_state_change_work; ++ bool pen_is_charge; ++ struct notifier_block pen_charge_state_notifier; ++ uint16_t addr; ++ int8_t phys[32]; ++#if defined(CONFIG_FB) ++#ifdef CONFIG_DRM ++ struct notifier_block drm_notif; ++#else ++ struct notifier_block fb_notif; ++#endif ++#endif ++ uint32_t config_array_size; ++ struct nvt_config_info *config_array; ++ const char *fw_name; ++ bool lkdown_readed; ++ uint8_t fw_ver; ++ uint8_t x_num; ++ uint8_t y_num; ++ int ic_state; ++ uint16_t abs_x_max; ++ uint16_t abs_y_max; ++ uint8_t max_touch_num; ++ uint8_t max_button_num; ++ uint32_t int_trigger_type; ++ int32_t irq_gpio; ++ uint32_t irq_flags; ++ int32_t reset_gpio; ++ uint32_t reset_flags; ++ struct mutex lock; ++ const struct nvt_ts_mem_map *mmap; ++ uint8_t carrier_system; ++ uint8_t hw_crc; ++ uint16_t nvt_pid; ++ uint8_t *rbuf; ++ uint8_t *xbuf; ++ struct mutex xbuf_lock; ++ bool irq_enabled; ++ uint8_t cascade; ++ bool pen_support; ++ bool wgp_stylus; ++ uint8_t x_gang_num; ++ uint8_t y_gang_num; ++ struct input_dev *pen_input_dev; ++ bool pen_input_dev_enable; ++ int8_t pen_phys[32]; ++ struct workqueue_struct *event_wq; ++ struct work_struct suspend_work; ++ struct work_struct resume_work; ++ int result_type; ++ int panel_index; ++ uint32_t spi_max_freq; ++ int db_wakeup; ++ uint8_t debug_flag; ++ bool fw_debug; ++ bool dev_pm_suspend; ++ struct completion dev_pm_suspend_completion; ++ bool palm_sensor_switch; ++ int gesture_command_delayed; ++ struct pinctrl *ts_pinctrl; ++ struct pinctrl_state *pinctrl_state_active; ++ struct pinctrl_state *pinctrl_state_suspend; ++}; ++ ++typedef enum { ++ RESET_STATE_INIT = 0xA0,// IC reset ++ RESET_STATE_REK, // ReK baseline ++ RESET_STATE_REK_FINISH, // baseline is ready ++ RESET_STATE_NORMAL_RUN, // normal run ++ RESET_STATE_MAX = 0xAF ++} RST_COMPLETE_STATE; ++ ++typedef enum { ++ EVENT_MAP_HOST_CMD = 0x50, ++ EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE = 0x51, ++ EVENT_MAP_RESET_COMPLETE = 0x60, ++ EVENT_MAP_FWINFO = 0x78, ++ EVENT_MAP_PROJECTID = 0x9A, ++} SPI_EVENT_MAP; ++ ++//---SPI READ/WRITE--- ++#define SPI_WRITE_MASK(a) (a | 0x80) ++#define SPI_READ_MASK(a) (a & 0x7F) ++ ++#define DUMMY_BYTES (1) ++#define NVT_TRANSFER_LEN (63*1024) ++#define NVT_READ_LEN (2*1024) ++ ++typedef enum { ++ NVTWRITE = 0, ++ NVTREAD = 1 ++} NVT_SPI_RW; ++ ++//---extern structures--- ++extern struct nvt_ts_data *ts; ++ ++//---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); ++void nvt_bootloader_reset(void); ++void nvt_eng_reset(void); ++void nvt_sw_reset(void); ++void nvt_sw_reset_idle(void); ++void nvt_boot_ready(void); ++void nvt_bld_crc_enable(void); ++void nvt_fw_crc_enable(void); ++void nvt_tx_auto_copy_mode(void); ++void nvt_set_dbgfw_status(bool enable); ++void nvt_match_fw(void); ++int32_t nvt_update_firmware(const char *firmware_name); ++int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state); ++int32_t nvt_get_fw_info(void); ++int32_t nvt_clear_fw_status(void); ++int32_t nvt_check_fw_status(void); ++int32_t nvt_check_spi_dma_tx_info(void); ++int32_t nvt_set_page(uint32_t addr); ++int32_t nvt_write_addr(uint32_t addr, uint8_t data); ++int32_t nvt_read_pid(void); ++bool nvt_get_dbgfw_status(void); ++int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); ++void Boot_Update_Firmware(struct work_struct *work); ++#if NVT_TOUCH_ESD_PROTECT ++extern void nvt_esd_check_enable(uint8_t enable); ++#endif /* #if NVT_TOUCH_ESD_PROTECT */ ++ ++#endif /* _LINUX_NVT_TOUCH_H */ +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c b/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c +new file mode 100644 +index 000000000000..4f383dac2c3c +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c +@@ -0,0 +1,857 @@ ++/* ++ * Copyright (C) 2010 - 2018 Novatek, Inc. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * $Revision: 68983 $ ++ * $Date: 2020-09-17 09:43:23 +0800 (週四, 17 九月 2020) $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ */ ++ ++#include ++#include ++ ++#include "nt36xxx.h" ++ ++#if BOOT_UPDATE_FIRMWARE ++ ++#define SIZE_4KB 4096 ++#define FLASH_SECTOR_SIZE SIZE_4KB ++#define FW_BIN_VER_OFFSET (fw_need_write_size - SIZE_4KB) ++#define FW_BIN_VER_BAR_OFFSET (FW_BIN_VER_OFFSET + 1) ++#define NVT_FLASH_END_FLAG_LEN 3 ++#define NVT_FLASH_END_FLAG_ADDR (fw_need_write_size - NVT_FLASH_END_FLAG_LEN) ++ ++static ktime_t start, end; ++const struct firmware *fw_entry = NULL; ++static size_t fw_need_write_size = 0; ++static uint8_t *fwbuf = NULL; ++ ++struct nvt_ts_bin_map { ++ char name[12]; ++ uint32_t BIN_addr; ++ uint32_t SRAM_addr; ++ uint32_t size; ++ uint32_t crc; ++}; ++ ++static struct nvt_ts_bin_map *bin_map; ++ ++/******************************************************* ++Description: ++ Novatek touchscreen init variable and allocate buffer ++for download firmware function. ++ ++return: ++ n.a. ++*******************************************************/ ++static int32_t nvt_download_init(void) ++{ ++ /* allocate buffer for transfer firmware */ ++ //NVT_LOG("NVT_TRANSFER_LEN = 0x%06X\n", NVT_TRANSFER_LEN); ++ ++ if (fwbuf == NULL) { ++ fwbuf = (uint8_t *)kzalloc((NVT_TRANSFER_LEN + 1 + DUMMY_BYTES), GFP_KERNEL); ++ if(fwbuf == NULL) { ++ NVT_ERR("kzalloc for fwbuf failed!\n"); ++ return -ENOMEM; ++ } ++ } ++ ++ return 0; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen checksum function. Calculate bin ++file checksum for comparison. ++ ++return: ++ n.a. ++*******************************************************/ ++static uint32_t CheckSum(const u8 *data, size_t len) ++{ ++ uint32_t i = 0; ++ uint32_t checksum = 0; ++ ++ for (i = 0 ; i < len+1 ; i++) ++ checksum += data[i]; ++ ++ checksum += len; ++ checksum = ~checksum +1; ++ ++ return checksum; ++} ++ ++static uint32_t byte_to_word(const uint8_t *data) ++{ ++ return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen parsing bin header function. ++ ++return: ++ n.a. ++*******************************************************/ ++static uint32_t partition = 0; ++static uint8_t ilm_dlm_num = 2; ++static uint8_t cascade_2nd_header_info = 0; ++static int32_t nvt_bin_header_parser(const u8 *fwdata, size_t fwsize) ++{ ++ uint32_t list = 0; ++ uint32_t pos = 0x00; ++ uint32_t end = 0x00; ++ uint8_t info_sec_num = 0; ++ uint8_t ovly_sec_num = 0; ++ uint8_t ovly_info = 0; ++ uint8_t find_bin_header = 0; ++ ++ /* Find the header size */ ++ end = fwdata[0] + (fwdata[1] << 8) + (fwdata[2] << 16) + (fwdata[3] << 24); ++ ++ /* check cascade next header */ ++ cascade_2nd_header_info = (fwdata[0x20] & 0x02) >> 1; ++ NVT_LOG("cascade_2nd_header_info = %d\n", cascade_2nd_header_info); ++ ++ if (cascade_2nd_header_info) { ++ pos = 0x30; // info section start at 0x30 offset ++ while (pos < (end / 2)) { ++ info_sec_num ++; ++ pos += 0x10; /* each header info is 16 bytes */ ++ } ++ ++ info_sec_num = info_sec_num + 1; //next header section ++ } else { ++ pos = 0x30; // info section start at 0x30 offset ++ while (pos < end) { ++ info_sec_num ++; ++ pos += 0x10; /* each header info is 16 bytes */ ++ } ++ } ++ ++ /* ++ * Find the DLM OVLY section ++ * [0:3] Overlay Section Number ++ * [4] Overlay Info ++ */ ++ ovly_info = (fwdata[0x28] & 0x10) >> 4; ++ ovly_sec_num = (ovly_info) ? (fwdata[0x28] & 0x0F) : 0; ++ ++ /* ++ * calculate all partition number ++ * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num ++ */ ++ partition = ilm_dlm_num + ovly_sec_num + info_sec_num; ++ NVT_LOG("ovly_info = %d, ilm_dlm_num = %d, ovly_sec_num = %d, info_sec_num = %d, partition = %d\n", ++ ovly_info, ilm_dlm_num, ovly_sec_num, info_sec_num, partition); ++ ++ /* allocated memory for header info */ ++ bin_map = (struct nvt_ts_bin_map *)kzalloc((partition+1) * sizeof(struct nvt_ts_bin_map), GFP_KERNEL); ++ if(bin_map == NULL) { ++ NVT_ERR("kzalloc for bin_map failed!\n"); ++ return -ENOMEM; ++ } ++ ++ for (list = 0; list < partition; list++) { ++ /* ++ * [1] parsing ILM & DLM header info ++ * BIN_addr : SRAM_addr : size (12-bytes) ++ * crc located at 0x18 & 0x1C ++ */ ++ if (list < ilm_dlm_num) { ++ bin_map[list].BIN_addr = byte_to_word(&fwdata[0 + list*12]); ++ bin_map[list].SRAM_addr = byte_to_word(&fwdata[4 + list*12]); ++ bin_map[list].size = byte_to_word(&fwdata[8 + list*12]); ++ if (ts->hw_crc) ++ bin_map[list].crc = byte_to_word(&fwdata[0x18 + list*4]); ++ else { //ts->hw_crc ++ if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize) ++ bin_map[list].crc = CheckSum(&fwdata[bin_map[list].BIN_addr], bin_map[list].size); ++ else { ++ NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", ++ bin_map[list].BIN_addr, bin_map[list].BIN_addr + bin_map[list].size); ++ return -EINVAL; ++ } ++ } //ts->hw_crc ++ if (list == 0) ++ sprintf(bin_map[list].name, "ILM"); ++ else if (list == 1) ++ sprintf(bin_map[list].name, "DLM"); ++ } ++ ++ /* ++ * [2] parsing others header info ++ * SRAM_addr : size : BIN_addr : crc (16-bytes) ++ */ ++ if ((list >= ilm_dlm_num) && (list < (ilm_dlm_num + info_sec_num))) { ++ if (find_bin_header == 0) { ++ /* others partition located at 0x30 offset */ ++ pos = 0x30 + (0x10 * (list - ilm_dlm_num)); ++ } else if (find_bin_header && cascade_2nd_header_info) { ++ /* cascade 2nd header info */ ++ pos = end - 0x10; ++ } ++ ++ bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); ++ bin_map[list].size = byte_to_word(&fwdata[pos+4]); ++ bin_map[list].BIN_addr = byte_to_word(&fwdata[pos+8]); ++ if (ts->hw_crc) ++ bin_map[list].crc = byte_to_word(&fwdata[pos+12]); ++ else { //ts->hw_crc ++ if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize) ++ bin_map[list].crc = CheckSum(&fwdata[bin_map[list].BIN_addr], bin_map[list].size); ++ else { ++ NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", ++ bin_map[list].BIN_addr, bin_map[list].BIN_addr + bin_map[list].size); ++ return -EINVAL; ++ } ++ } //ts->hw_crc ++ /* detect header end to protect parser function */ ++ if ((bin_map[list].BIN_addr < end) && (bin_map[list].size != 0)) { ++ sprintf(bin_map[list].name, "Header"); ++ find_bin_header = 1; ++ } else { ++ sprintf(bin_map[list].name, "Info-%d", (list - ilm_dlm_num)); ++ } ++ } ++ ++ /* ++ * [3] parsing overlay section header info ++ * SRAM_addr : size : BIN_addr : crc (16-bytes) ++ */ ++ if (list >= (ilm_dlm_num + info_sec_num)) { ++ /* overlay info located at DLM (list = 1) start addr */ ++ pos = bin_map[1].BIN_addr + (0x10 * (list- ilm_dlm_num - info_sec_num)); ++ ++ bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]); ++ bin_map[list].size = byte_to_word(&fwdata[pos+4]); ++ bin_map[list].BIN_addr = byte_to_word(&fwdata[pos+8]); ++ if (ts->hw_crc) ++ bin_map[list].crc = byte_to_word(&fwdata[pos+12]); ++ else { //ts->hw_crc ++ if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize) ++ bin_map[list].crc = CheckSum(&fwdata[bin_map[list].BIN_addr], bin_map[list].size); ++ else { ++ NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", ++ bin_map[list].BIN_addr, bin_map[list].BIN_addr + bin_map[list].size); ++ return -EINVAL; ++ } ++ } //ts->hw_crc ++ sprintf(bin_map[list].name, "Overlay-%d", (list- ilm_dlm_num - info_sec_num)); ++ } ++ ++ /* BIN size error detect */ ++ if ((bin_map[list].BIN_addr + bin_map[list].size) > fwsize) { ++ NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", ++ bin_map[list].BIN_addr, bin_map[list].BIN_addr + bin_map[list].size); ++ return -EINVAL; ++ } ++ ++// NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X), CRC (0x%08X)\n", ++// list, bin_map[list].name, ++// bin_map[list].SRAM_addr, bin_map[list].size, bin_map[list].BIN_addr, bin_map[list].crc); ++ } ++ ++ return 0; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen release update firmware function. ++ ++return: ++ n.a. ++*******************************************************/ ++static void update_firmware_release(void) ++{ ++ if (fw_entry) { ++ release_firmware(fw_entry); ++ } ++ ++ fw_entry = NULL; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen request update firmware function. ++ ++return: ++ Executive outcomes. 0---succeed. -1,-22---failed. ++*******************************************************/ ++static int32_t update_firmware_request(const char *filename) ++{ ++ uint8_t retry = 0; ++ int32_t ret = 0; ++ ++ if (NULL == filename) { ++ return -ENOENT; ++ } ++ ++ while (1) { ++ NVT_LOG("filename is %s\n", filename); ++ ++ ret = request_firmware(&fw_entry, filename, &ts->client->dev); ++ if (ret) { ++ NVT_ERR("firmware load failed, ret=%d\n", ret); ++ goto request_fail; ++ } ++ ++ fw_need_write_size = fw_entry->size; ++ ++ // check if FW version add FW version bar equals 0xFF ++ if (*(fw_entry->data + FW_BIN_VER_OFFSET) + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != 0xFF) { ++ NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n"); ++ NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", *(fw_entry->data+FW_BIN_VER_OFFSET), *(fw_entry->data+FW_BIN_VER_BAR_OFFSET)); ++ ret = -ENOEXEC; ++ goto invalid; ++ } ++ ++ /* BIN Header Parser */ ++ ret = nvt_bin_header_parser(fw_entry->data, fw_entry->size); ++ if (ret) { ++ NVT_ERR("bin header parser failed\n"); ++ goto invalid; ++ } else { ++ break; ++ } ++ ++invalid: ++ update_firmware_release(); ++ if (!IS_ERR_OR_NULL(bin_map)) { ++ kfree(bin_map); ++ bin_map = NULL; ++ } ++ ++request_fail: ++ retry++; ++ if(unlikely(retry > 2)) { ++ NVT_ERR("error, retry=%d\n", retry); ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen write data to sram function. ++ ++- fwdata : The buffer is written ++- SRAM_addr: The sram destination address ++- size : Number of data bytes in @fwdata being written ++- BIN_addr : The transferred data offset of @fwdata ++ ++return: ++ Executive outcomes. 0---succeed. else---fail. ++*******************************************************/ ++static int32_t nvt_write_sram(const u8 *fwdata, ++ uint32_t SRAM_addr, uint32_t size, uint32_t BIN_addr) ++{ ++ int32_t ret = 0; ++ uint32_t i = 0; ++ uint16_t len = 0; ++ int32_t count = 0; ++ ++ if (size % NVT_TRANSFER_LEN) ++ count = (size / NVT_TRANSFER_LEN) + 1; ++ else ++ count = (size / NVT_TRANSFER_LEN); ++ ++ for (i = 0 ; i < count ; i++) { ++ len = (size < NVT_TRANSFER_LEN) ? size : NVT_TRANSFER_LEN; ++ ++ //---set xdata index to start address of SRAM--- ++ ret = nvt_set_page(SRAM_addr); ++ if (ret) { ++ NVT_ERR("set page failed, ret = %d\n", ret); ++ return ret; ++ } ++ ++ //---write data into SRAM--- ++ fwbuf[0] = SRAM_addr & 0x7F; //offset ++ memcpy(fwbuf+1, &fwdata[BIN_addr], len); //payload ++ ret = CTP_SPI_WRITE(ts->client, fwbuf, len+1); ++ if (ret) { ++ NVT_ERR("write to sram failed, ret = %d\n", ret); ++ return ret; ++ } ++ ++ SRAM_addr += NVT_TRANSFER_LEN; ++ BIN_addr += NVT_TRANSFER_LEN; ++ size -= NVT_TRANSFER_LEN; ++ } ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen nvt_write_firmware function to write ++firmware into each partition. ++ ++return: ++ n.a. ++*******************************************************/ ++static int32_t nvt_write_firmware(const u8 *fwdata, size_t fwsize) ++{ ++ uint32_t list = 0; ++ char *name; ++ uint32_t BIN_addr, SRAM_addr, size; ++ int32_t ret = 0; ++ ++ memset(fwbuf, 0, (NVT_TRANSFER_LEN+1)); ++ ++ for (list = 0; list < partition; list++) { ++ /* initialize variable */ ++ SRAM_addr = bin_map[list].SRAM_addr; ++ size = bin_map[list].size; ++ BIN_addr = bin_map[list].BIN_addr; ++ name = bin_map[list].name; ++ ++// NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X)\n", ++// list, name, SRAM_addr, size, BIN_addr); ++ ++ /* Check data size */ ++ if ((BIN_addr + size) > fwsize) { ++ NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n", ++ BIN_addr, BIN_addr + size); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ /* ignore reserved partition (Reserved Partition size is zero) */ ++ if (!size) ++ continue; ++ else ++ size = size +1; ++ ++ /* write data to SRAM */ ++ ret = nvt_write_sram(fwdata, SRAM_addr, size, BIN_addr); ++ if (ret) { ++ NVT_ERR("sram program failed, ret = %d\n", ret); ++ goto out; ++ } ++ } ++ ++out: ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen check checksum function. ++This function will compare file checksum and fw checksum. ++ ++return: ++ n.a. ++*******************************************************/ ++static int32_t nvt_check_fw_checksum(void) ++{ ++ uint32_t fw_checksum = 0; ++ uint32_t len = partition*4; ++ uint32_t list = 0; ++ int32_t ret = 0; ++ ++ memset(fwbuf, 0, (len+1)); ++ ++ //---set xdata index to checksum--- ++ nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); ++ ++ /* read checksum */ ++ fwbuf[0] = (ts->mmap->R_ILM_CHECKSUM_ADDR) & 0x7F; ++ ret = CTP_SPI_READ(ts->client, fwbuf, len+1); ++ if (ret) { ++ NVT_ERR("Read fw checksum failed\n"); ++ return ret; ++ } ++ ++ /* ++ * Compare each checksum from fw ++ * ILM + DLM + Overlay + Info ++ * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num ++ */ ++ for (list = 0; list < partition; list++) { ++ fw_checksum = byte_to_word(&fwbuf[1+list*4]); ++ ++ /* ignore reserved partition (Reserved Partition size is zero) */ ++ if(!bin_map[list].size) ++ continue; ++ ++ if (bin_map[list].crc != fw_checksum) { ++ NVT_ERR("[%d] BIN_checksum=0x%08X, FW_checksum=0x%08X\n", ++ list, bin_map[list].crc, fw_checksum); ++ ret = -EIO; ++ } ++ } ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen set bootload crc reg bank function. ++This function will set hw crc reg before enable crc function. ++ ++return: ++ n.a. ++*******************************************************/ ++static void nvt_set_bld_crc_bank(uint32_t DES_ADDR, uint32_t SRAM_ADDR, ++ uint32_t LENGTH_ADDR, uint32_t size, ++ uint32_t G_CHECKSUM_ADDR, uint32_t crc) ++{ ++ /* write destination address */ ++ nvt_set_page(DES_ADDR); ++ fwbuf[0] = DES_ADDR & 0x7F; ++ fwbuf[1] = (SRAM_ADDR) & 0xFF; ++ fwbuf[2] = (SRAM_ADDR >> 8) & 0xFF; ++ fwbuf[3] = (SRAM_ADDR >> 16) & 0xFF; ++ CTP_SPI_WRITE(ts->client, fwbuf, 4); ++ ++ /* write length */ ++ //nvt_set_page(LENGTH_ADDR); ++ fwbuf[0] = LENGTH_ADDR & 0x7F; ++ fwbuf[1] = (size) & 0xFF; ++ fwbuf[2] = (size >> 8) & 0xFF; ++ fwbuf[3] = (size >> 16) & 0x01; ++ if (ts->hw_crc == 1) { ++ CTP_SPI_WRITE(ts->client, fwbuf, 3); ++ } else if (ts->hw_crc > 1) { ++ CTP_SPI_WRITE(ts->client, fwbuf, 4); ++ } ++ ++ /* write golden dlm checksum */ ++ //nvt_set_page(G_CHECKSUM_ADDR); ++ fwbuf[0] = G_CHECKSUM_ADDR & 0x7F; ++ fwbuf[1] = (crc) & 0xFF; ++ fwbuf[2] = (crc >> 8) & 0xFF; ++ fwbuf[3] = (crc >> 16) & 0xFF; ++ fwbuf[4] = (crc >> 24) & 0xFF; ++ CTP_SPI_WRITE(ts->client, fwbuf, 5); ++ ++ return; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen set BLD hw crc function. ++This function will set ILM and DLM crc information to register. ++ ++return: ++ n.a. ++*******************************************************/ ++static void nvt_set_bld_hw_crc(void) ++{ ++ /* [0] ILM */ ++ /* write register bank */ ++ nvt_set_bld_crc_bank(ts->mmap->ILM_DES_ADDR, bin_map[0].SRAM_addr, ++ ts->mmap->ILM_LENGTH_ADDR, bin_map[0].size, ++ ts->mmap->G_ILM_CHECKSUM_ADDR, bin_map[0].crc); ++ ++ /* [1] DLM */ ++ /* write register bank */ ++ nvt_set_bld_crc_bank(ts->mmap->DLM_DES_ADDR, bin_map[1].SRAM_addr, ++ ts->mmap->DLM_LENGTH_ADDR, bin_map[1].size, ++ ts->mmap->G_DLM_CHECKSUM_ADDR, bin_map[1].crc); ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen read BLD hw crc info function. ++This function will check crc results from register. ++ ++return: ++ n.a. ++*******************************************************/ ++static void nvt_read_bld_hw_crc(void) ++{ ++ uint8_t buf[8] = {0}; ++ uint32_t g_crc = 0, r_crc = 0; ++ ++ /* CRC Flag */ ++ nvt_set_page(ts->mmap->BLD_ILM_DLM_CRC_ADDR); ++ buf[0] = ts->mmap->BLD_ILM_DLM_CRC_ADDR & 0x7F; ++ buf[1] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 2); ++ NVT_ERR("crc_done = %d, ilm_crc_flag = %d, dlm_crc_flag = %d\n", ++ (buf[1] >> 2) & 0x01, (buf[1] >> 0) & 0x01, (buf[1] >> 1) & 0x01); ++ ++ /* ILM CRC */ ++ nvt_set_page(ts->mmap->G_ILM_CHECKSUM_ADDR); ++ buf[0] = ts->mmap->G_ILM_CHECKSUM_ADDR & 0x7F; ++ buf[1] = 0x00; ++ buf[2] = 0x00; ++ buf[3] = 0x00; ++ buf[4] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 5); ++ g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); ++ ++ nvt_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR); ++ buf[0] = ts->mmap->R_ILM_CHECKSUM_ADDR & 0x7F; ++ buf[1] = 0x00; ++ buf[2] = 0x00; ++ buf[3] = 0x00; ++ buf[4] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 5); ++ r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); ++ ++ NVT_ERR("ilm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", ++ bin_map[0].crc, g_crc, r_crc); ++ ++ /* DLM CRC */ ++ nvt_set_page(ts->mmap->G_DLM_CHECKSUM_ADDR); ++ buf[0] = ts->mmap->G_DLM_CHECKSUM_ADDR & 0x7F; ++ buf[1] = 0x00; ++ buf[2] = 0x00; ++ buf[3] = 0x00; ++ buf[4] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 5); ++ g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); ++ ++ nvt_set_page(ts->mmap->R_DLM_CHECKSUM_ADDR); ++ buf[0] = ts->mmap->R_DLM_CHECKSUM_ADDR & 0x7F; ++ buf[1] = 0x00; ++ buf[2] = 0x00; ++ buf[3] = 0x00; ++ buf[4] = 0x00; ++ CTP_SPI_READ(ts->client, buf, 5); ++ r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); ++ ++ NVT_ERR("dlm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n", ++ bin_map[1].crc, g_crc, r_crc); ++ ++ return; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen Download_Firmware with HW CRC ++function. It's complete download firmware flow. ++ ++return: ++ Executive outcomes. 0---succeed. else---fail. ++*******************************************************/ ++static int32_t nvt_download_firmware_hw_crc(void) ++{ ++ uint8_t retry = 0; ++ int32_t ret = 0; ++ ++ start = ktime_get(); ++ ++ while (1) { ++ /* bootloader reset to reset MCU */ ++ nvt_bootloader_reset(); ++ ++ /* set ilm & dlm reg bank */ ++ nvt_set_bld_hw_crc(); ++ ++ /* Start to write firmware process */ ++ if (cascade_2nd_header_info) { ++ /* for cascade */ ++ nvt_tx_auto_copy_mode(); ++ ++ ret = nvt_write_firmware(fw_entry->data, fw_entry->size); ++ if (ret) { ++ NVT_ERR("Write_Firmware failed. (%d)\n", ret); ++ goto fail; ++ } ++ ++ ret = nvt_check_spi_dma_tx_info(); ++ if (ret) { ++ NVT_ERR("spi dma tx info failed. (%d)\n", ret); ++ goto fail; ++ } ++ } else { ++ ret = nvt_write_firmware(fw_entry->data, fw_entry->size); ++ if (ret) { ++ NVT_ERR("Write_Firmware failed. (%d)\n", ret); ++ goto fail; ++ } ++ } ++ ++ /* enable hw bld crc function */ ++ nvt_bld_crc_enable(); ++ ++ /* clear fw reset status & enable fw crc check */ ++ nvt_fw_crc_enable(); ++ ++ /* Set Boot Ready Bit */ ++ nvt_boot_ready(); ++ ++ ret = nvt_check_fw_reset_state(RESET_STATE_INIT); ++ if (ret) { ++ NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); ++ goto fail; ++ } else { ++ break; ++ } ++ ++fail: ++ retry++; ++ if(unlikely(retry > 2)) { ++ NVT_ERR("error, retry=%d\n", retry); ++ nvt_read_bld_hw_crc(); ++ break; ++ } ++ } ++ ++ end = ktime_get(); ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen Download_Firmware function. It's ++complete download firmware flow. ++ ++return: ++ n.a. ++*******************************************************/ ++static int32_t nvt_download_firmware(void) ++{ ++ uint8_t retry = 0; ++ int32_t ret = 0; ++ ++ start = ktime_get(); ++ ++ while (1) { ++ /* ++ * Send eng reset cmd before download FW ++ * Keep TP_RESX low when send eng reset cmd ++ */ ++#if NVT_TOUCH_SUPPORT_HW_RST ++ gpio_set_value(ts->reset_gpio, 0); ++ mdelay(1); //wait 1ms ++#endif ++ nvt_eng_reset(); ++#if NVT_TOUCH_SUPPORT_HW_RST ++ gpio_set_value(ts->reset_gpio, 1); ++ mdelay(10); //wait tRT2BRST after TP_RST ++#endif ++ nvt_bootloader_reset(); ++ ++ /* clear fw reset status */ ++ nvt_write_addr(ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_RESET_COMPLETE, 0x00); ++ ++ /* Start to write firmware process */ ++ ret = nvt_write_firmware(fw_entry->data, fw_entry->size); ++ if (ret) { ++ NVT_ERR("Write_Firmware failed. (%d)\n", ret); ++ goto fail; ++ } ++ ++ /* Set Boot Ready Bit */ ++ nvt_boot_ready(); ++ ++ ret = nvt_check_fw_reset_state(RESET_STATE_INIT); ++ if (ret) { ++ NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret); ++ goto fail; ++ } ++ ++ /* check fw checksum result */ ++ ret = nvt_check_fw_checksum(); ++ if (ret) { ++ NVT_ERR("firmware checksum not match, retry=%d\n", retry); ++ goto fail; ++ } else { ++ break; ++ } ++ ++fail: ++ retry++; ++ if(unlikely(retry > 2)) { ++ NVT_ERR("error, retry=%d\n", retry); ++ break; ++ } ++ } ++ ++ end = ktime_get(); ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen update firmware main function. ++ ++return: ++ n.a. ++*******************************************************/ ++int32_t nvt_update_firmware(const char *firmware_name) ++{ ++ int32_t ret = 0; ++ ++ // request bin file in "/etc/firmware" ++ ret = update_firmware_request(firmware_name); ++ if (ret) { ++ NVT_ERR("update_firmware_request failed. (%d)\n", ret); ++ goto request_firmware_fail; ++ } ++ ++ /* initial buffer and variable */ ++ ret = nvt_download_init(); ++ if (ret) { ++ NVT_ERR("Download Init failed. (%d)\n", ret); ++ goto download_fail; ++ } ++ ++ /* download firmware process */ ++ if (ts->hw_crc) ++ ret = nvt_download_firmware_hw_crc(); ++ else ++ ret = nvt_download_firmware(); ++ if (ret) { ++ NVT_ERR("Download Firmware failed. (%d)\n", ret); ++ goto download_fail; ++ } ++ ++ NVT_LOG("Update firmware success! <%ld us>\n", ++ (long) ktime_us_delta(end, start)); ++ ++ /* Get FW Info */ ++ ret = nvt_get_fw_info(); ++ if (ret) { ++ NVT_ERR("nvt_get_fw_info failed. (%d)\n", ret); ++ } ++ ++download_fail: ++ if (!IS_ERR_OR_NULL(bin_map)) { ++ kfree(bin_map); ++ bin_map = NULL; ++ } ++ ++ update_firmware_release(); ++request_firmware_fail: ++ ++ return ret; ++} ++ ++/******************************************************* ++Description: ++ Novatek touchscreen update firmware when booting ++ function. ++ ++return: ++ n.a. ++*******************************************************/ ++void Boot_Update_Firmware(struct work_struct *work) ++{ ++ mutex_lock(&ts->lock); ++ nvt_update_firmware(ts->fw_name); ++ nvt_get_fw_info(); ++ mutex_unlock(&ts->lock); ++} ++#endif /* BOOT_UPDATE_FIRMWARE */ +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h b/drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h +new file mode 100644 +index 000000000000..3f4195d636a0 +--- /dev/null ++++ b/drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h +@@ -0,0 +1,390 @@ ++/* ++ * Copyright (C) 2010 - 2018 Novatek, Inc. ++ * Copyright (C) 2021 XiaoMi, Inc. ++ * ++ * $Revision: 57674 $ ++ * $Date: 2020-03-02 11:16:20 +0800 (週一, 02 三月 2020) $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ */ ++ ++#define CHIP_VER_TRIM_ADDR 0x3F004 ++#define CHIP_VER_TRIM_OLD_ADDR 0x1F64E ++ ++struct nvt_ts_mem_map { ++ uint32_t EVENT_BUF_ADDR; ++ uint32_t RAW_PIPE0_ADDR; ++ uint32_t RAW_PIPE1_ADDR; ++ uint32_t BASELINE_ADDR; ++ uint32_t BASELINE_BTN_ADDR; ++ uint32_t DIFF_PIPE0_ADDR; ++ uint32_t DIFF_PIPE1_ADDR; ++ uint32_t RAW_BTN_PIPE0_ADDR; ++ uint32_t RAW_BTN_PIPE1_ADDR; ++ uint32_t DIFF_BTN_PIPE0_ADDR; ++ uint32_t DIFF_BTN_PIPE1_ADDR; ++ uint32_t PEN_2D_BL_TIP_X_ADDR; ++ uint32_t PEN_2D_BL_TIP_Y_ADDR; ++ uint32_t PEN_2D_BL_RING_X_ADDR; ++ uint32_t PEN_2D_BL_RING_Y_ADDR; ++ uint32_t PEN_2D_DIFF_TIP_X_ADDR; ++ uint32_t PEN_2D_DIFF_TIP_Y_ADDR; ++ uint32_t PEN_2D_DIFF_RING_X_ADDR; ++ uint32_t PEN_2D_DIFF_RING_Y_ADDR; ++ uint32_t PEN_2D_RAW_TIP_X_ADDR; ++ uint32_t PEN_2D_RAW_TIP_Y_ADDR; ++ uint32_t PEN_2D_RAW_RING_X_ADDR; ++ uint32_t PEN_2D_RAW_RING_Y_ADDR; ++ uint32_t PEN_1D_DIFF_TIP_X_ADDR; ++ uint32_t PEN_1D_DIFF_TIP_Y_ADDR; ++ uint32_t PEN_1D_DIFF_RING_X_ADDR; ++ uint32_t PEN_1D_DIFF_RING_Y_ADDR; ++ uint32_t READ_FLASH_CHECKSUM_ADDR; ++ uint32_t RW_FLASH_DATA_ADDR; ++ /* Phase 2 Host Download */ ++ uint32_t BOOT_RDY_ADDR; ++ uint32_t POR_CD_ADDR; ++ uint32_t TX_AUTO_COPY_EN; ++ uint32_t SPI_DMA_TX_INFO; ++ /* BLD CRC */ ++ uint32_t BLD_LENGTH_ADDR; ++ uint32_t ILM_LENGTH_ADDR; ++ uint32_t DLM_LENGTH_ADDR; ++ uint32_t BLD_DES_ADDR; ++ uint32_t ILM_DES_ADDR; ++ uint32_t DLM_DES_ADDR; ++ uint32_t G_ILM_CHECKSUM_ADDR; ++ uint32_t G_DLM_CHECKSUM_ADDR; ++ uint32_t R_ILM_CHECKSUM_ADDR; ++ uint32_t R_DLM_CHECKSUM_ADDR; ++ uint32_t BLD_CRC_EN_ADDR; ++ uint32_t DMA_CRC_EN_ADDR; ++ uint32_t BLD_ILM_DLM_CRC_ADDR; ++ uint32_t DMA_CRC_FLAG_ADDR; ++ uint32_t FW_HISTORY_ADDR; ++}; ++ ++struct nvt_ts_hw_info { ++ uint8_t carrier_system; ++ uint8_t hw_crc; ++}; ++ ++static const struct nvt_ts_mem_map NT36523_memory_map = { ++ .EVENT_BUF_ADDR = 0x2FE00, ++ .RAW_PIPE0_ADDR = 0x30FA0, ++ .RAW_PIPE1_ADDR = 0x30FA0, ++ .BASELINE_ADDR = 0x36510, ++ .BASELINE_BTN_ADDR = 0, ++ .DIFF_PIPE0_ADDR = 0x373E8, ++ .DIFF_PIPE1_ADDR = 0x38068, ++ .RAW_BTN_PIPE0_ADDR = 0, ++ .RAW_BTN_PIPE1_ADDR = 0, ++ .DIFF_BTN_PIPE0_ADDR = 0, ++ .DIFF_BTN_PIPE1_ADDR = 0, ++ .PEN_2D_BL_TIP_X_ADDR = 0x2988A, ++ .PEN_2D_BL_TIP_Y_ADDR = 0x29A1A, ++ .PEN_2D_BL_RING_X_ADDR = 0x29BAA, ++ .PEN_2D_BL_RING_Y_ADDR = 0x29D3A, ++ .PEN_2D_DIFF_TIP_X_ADDR = 0x29ECA, ++ .PEN_2D_DIFF_TIP_Y_ADDR = 0x2A05A, ++ .PEN_2D_DIFF_RING_X_ADDR = 0x2A1EA, ++ .PEN_2D_DIFF_RING_Y_ADDR = 0x2A37A, ++ .PEN_2D_RAW_TIP_X_ADDR = 0x2A50A, ++ .PEN_2D_RAW_TIP_Y_ADDR = 0x2A69A, ++ .PEN_2D_RAW_RING_X_ADDR = 0x2A82A, ++ .PEN_2D_RAW_RING_Y_ADDR = 0x2A9BA, ++ .PEN_1D_DIFF_TIP_X_ADDR = 0x2AB4A, ++ .PEN_1D_DIFF_TIP_Y_ADDR = 0x2ABAE, ++ .PEN_1D_DIFF_RING_X_ADDR = 0x2AC12, ++ .PEN_1D_DIFF_RING_Y_ADDR = 0x2AC76, ++ .READ_FLASH_CHECKSUM_ADDR = 0x24000, ++ .RW_FLASH_DATA_ADDR = 0x24002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x3F10D, ++ .TX_AUTO_COPY_EN = 0x3F7E8, ++ .SPI_DMA_TX_INFO = 0x3F7F1, ++ /* BLD CRC */ ++ .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) ++ .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) ++ .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) ++ .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) ++ .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) ++ .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) ++ .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) ++ .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) ++ .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) ++ .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) ++ .BLD_CRC_EN_ADDR = 0x3F30E, ++ .DMA_CRC_EN_ADDR = 0x3F136, ++ .BLD_ILM_DLM_CRC_ADDR = 0x3F133, ++ .DMA_CRC_FLAG_ADDR = 0x3F134, ++ .FW_HISTORY_ADDR = 0x38D54, ++}; ++ ++static const struct nvt_ts_mem_map NT36526_memory_map = { ++ .EVENT_BUF_ADDR = 0x22D00, ++ .RAW_PIPE0_ADDR = 0x24000, ++ .RAW_PIPE1_ADDR = 0x24000, ++ .BASELINE_ADDR = 0x21758, ++ .BASELINE_BTN_ADDR = 0, ++ .DIFF_PIPE0_ADDR = 0x20AB0, ++ .DIFF_PIPE1_ADDR = 0x24AB0, ++ .RAW_BTN_PIPE0_ADDR = 0, ++ .RAW_BTN_PIPE1_ADDR = 0, ++ .DIFF_BTN_PIPE0_ADDR = 0, ++ .DIFF_BTN_PIPE1_ADDR = 0, ++ .READ_FLASH_CHECKSUM_ADDR = 0x24000, ++ .RW_FLASH_DATA_ADDR = 0x24002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x3F10D, ++ /* BLD CRC */ ++ .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) ++ .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) ++ .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) ++ .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) ++ .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) ++ .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) ++ .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) ++ .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) ++ .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) ++ .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) ++ .BLD_CRC_EN_ADDR = 0x3F30E, ++ .DMA_CRC_EN_ADDR = 0x3F136, ++ .BLD_ILM_DLM_CRC_ADDR = 0x3F133, ++ .DMA_CRC_FLAG_ADDR = 0x3F134, ++}; ++ ++ ++static const struct nvt_ts_mem_map NT36675_memory_map = { ++ .EVENT_BUF_ADDR = 0x22D00, ++ .RAW_PIPE0_ADDR = 0x24000, ++ .RAW_PIPE1_ADDR = 0x24000, ++ .BASELINE_ADDR = 0x21B90, ++ .BASELINE_BTN_ADDR = 0, ++ .DIFF_PIPE0_ADDR = 0x20C60, ++ .DIFF_PIPE1_ADDR = 0x24C60, ++ .RAW_BTN_PIPE0_ADDR = 0, ++ .RAW_BTN_PIPE1_ADDR = 0, ++ .DIFF_BTN_PIPE0_ADDR = 0, ++ .DIFF_BTN_PIPE1_ADDR = 0, ++ .READ_FLASH_CHECKSUM_ADDR = 0x24000, ++ .RW_FLASH_DATA_ADDR = 0x24002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x3F10D, ++ /* BLD CRC */ ++ .BLD_LENGTH_ADDR = 0x3F138, //0x3F138 ~ 0x3F13A (3 bytes) ++ .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F11A (3 bytes) ++ .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F132 (3 bytes) ++ .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) ++ .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) ++ .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) ++ .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) ++ .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) ++ .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) ++ .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) ++ .BLD_CRC_EN_ADDR = 0x3F30E, ++ .DMA_CRC_EN_ADDR = 0x3F136, ++ .BLD_ILM_DLM_CRC_ADDR = 0x3F133, ++ .DMA_CRC_FLAG_ADDR = 0x3F134, ++}; ++ ++ ++static const struct nvt_ts_mem_map NT36672A_memory_map = { ++ .EVENT_BUF_ADDR = 0x21C00, ++ .RAW_PIPE0_ADDR = 0x20000, ++ .RAW_PIPE1_ADDR = 0x23000, ++ .BASELINE_ADDR = 0x20BFC, ++ .BASELINE_BTN_ADDR = 0x23BFC, ++ .DIFF_PIPE0_ADDR = 0x206DC, ++ .DIFF_PIPE1_ADDR = 0x236DC, ++ .RAW_BTN_PIPE0_ADDR = 0x20510, ++ .RAW_BTN_PIPE1_ADDR = 0x23510, ++ .DIFF_BTN_PIPE0_ADDR = 0x20BF0, ++ .DIFF_BTN_PIPE1_ADDR = 0x23BF0, ++ .READ_FLASH_CHECKSUM_ADDR = 0x24000, ++ .RW_FLASH_DATA_ADDR = 0x24002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x3F10D, ++ /* BLD CRC */ ++ .BLD_LENGTH_ADDR = 0x3F10E, //0x3F10E ~ 0x3F10F (2 bytes) ++ .ILM_LENGTH_ADDR = 0x3F118, //0x3F118 ~ 0x3F119 (2 bytes) ++ .DLM_LENGTH_ADDR = 0x3F130, //0x3F130 ~ 0x3F131 (2 bytes) ++ .BLD_DES_ADDR = 0x3F114, //0x3F114 ~ 0x3F116 (3 bytes) ++ .ILM_DES_ADDR = 0x3F128, //0x3F128 ~ 0x3F12A (3 bytes) ++ .DLM_DES_ADDR = 0x3F12C, //0x3F12C ~ 0x3F12E (3 bytes) ++ .G_ILM_CHECKSUM_ADDR = 0x3F100, //0x3F100 ~ 0x3F103 (4 bytes) ++ .G_DLM_CHECKSUM_ADDR = 0x3F104, //0x3F104 ~ 0x3F107 (4 bytes) ++ .R_ILM_CHECKSUM_ADDR = 0x3F120, //0x3F120 ~ 0x3F123 (4 bytes) ++ .R_DLM_CHECKSUM_ADDR = 0x3F124, //0x3F124 ~ 0x3F127 (4 bytes) ++ .BLD_CRC_EN_ADDR = 0x3F30E, ++ .DMA_CRC_EN_ADDR = 0x3F132, ++ .BLD_ILM_DLM_CRC_ADDR = 0x3F133, ++ .DMA_CRC_FLAG_ADDR = 0x3F134, ++}; ++ ++static const struct nvt_ts_mem_map NT36772_memory_map = { ++ .EVENT_BUF_ADDR = 0x11E00, ++ .RAW_PIPE0_ADDR = 0x10000, ++ .RAW_PIPE1_ADDR = 0x12000, ++ .BASELINE_ADDR = 0x10E70, ++ .BASELINE_BTN_ADDR = 0x12E70, ++ .DIFF_PIPE0_ADDR = 0x10830, ++ .DIFF_PIPE1_ADDR = 0x12830, ++ .RAW_BTN_PIPE0_ADDR = 0x10E60, ++ .RAW_BTN_PIPE1_ADDR = 0x12E60, ++ .DIFF_BTN_PIPE0_ADDR = 0x10E68, ++ .DIFF_BTN_PIPE1_ADDR = 0x12E68, ++ .READ_FLASH_CHECKSUM_ADDR = 0x14000, ++ .RW_FLASH_DATA_ADDR = 0x14002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x1F141, ++ .POR_CD_ADDR = 0x1F61C, ++ /* BLD CRC */ ++ .R_ILM_CHECKSUM_ADDR = 0x1BF00, ++}; ++ ++static const struct nvt_ts_mem_map NT36525_memory_map = { ++ .EVENT_BUF_ADDR = 0x11A00, ++ .RAW_PIPE0_ADDR = 0x10000, ++ .RAW_PIPE1_ADDR = 0x12000, ++ .BASELINE_ADDR = 0x10B08, ++ .BASELINE_BTN_ADDR = 0x12B08, ++ .DIFF_PIPE0_ADDR = 0x1064C, ++ .DIFF_PIPE1_ADDR = 0x1264C, ++ .RAW_BTN_PIPE0_ADDR = 0x10634, ++ .RAW_BTN_PIPE1_ADDR = 0x12634, ++ .DIFF_BTN_PIPE0_ADDR = 0x10AFC, ++ .DIFF_BTN_PIPE1_ADDR = 0x12AFC, ++ .READ_FLASH_CHECKSUM_ADDR = 0x14000, ++ .RW_FLASH_DATA_ADDR = 0x14002, ++ /* Phase 2 Host Download */ ++ .BOOT_RDY_ADDR = 0x1F141, ++ .POR_CD_ADDR = 0x1F61C, ++ /* BLD CRC */ ++ .R_ILM_CHECKSUM_ADDR = 0x1BF00, ++}; ++ ++static const struct nvt_ts_mem_map NT36676F_memory_map = { ++ .EVENT_BUF_ADDR = 0x11A00, ++ .RAW_PIPE0_ADDR = 0x10000, ++ .RAW_PIPE1_ADDR = 0x12000, ++ .BASELINE_ADDR = 0x10B08, ++ .BASELINE_BTN_ADDR = 0x12B08, ++ .DIFF_PIPE0_ADDR = 0x1064C, ++ .DIFF_PIPE1_ADDR = 0x1264C, ++ .RAW_BTN_PIPE0_ADDR = 0x10634, ++ .RAW_BTN_PIPE1_ADDR = 0x12634, ++ .DIFF_BTN_PIPE0_ADDR = 0x10AFC, ++ .DIFF_BTN_PIPE1_ADDR = 0x12AFC, ++ .READ_FLASH_CHECKSUM_ADDR = 0x14000, ++ .RW_FLASH_DATA_ADDR = 0x14002, ++}; ++ ++static struct nvt_ts_hw_info NT36523_hw_info = { ++ .carrier_system = 2, ++ .hw_crc = 2, ++}; ++ ++static struct nvt_ts_hw_info NT36526_hw_info = { ++ .carrier_system = 2, ++ .hw_crc = 2, ++}; ++ ++static struct nvt_ts_hw_info NT36675_hw_info = { ++ .carrier_system = 2, ++ .hw_crc = 2, ++}; ++ ++static struct nvt_ts_hw_info NT36672A_hw_info = { ++ .carrier_system = 0, ++ .hw_crc = 1, ++}; ++ ++static struct nvt_ts_hw_info NT36772_hw_info = { ++ .carrier_system = 0, ++ .hw_crc = 0, ++}; ++ ++static struct nvt_ts_hw_info NT36525_hw_info = { ++ .carrier_system = 0, ++ .hw_crc = 0, ++}; ++ ++static struct nvt_ts_hw_info NT36676F_hw_info = { ++ .carrier_system = 0, ++ .hw_crc = 0, ++}; ++ ++#define NVT_ID_BYTE_MAX 6 ++struct nvt_ts_trim_id_table { ++ uint8_t id[NVT_ID_BYTE_MAX]; ++ uint8_t mask[NVT_ID_BYTE_MAX]; ++ const struct nvt_ts_mem_map *mmap; ++ const struct nvt_ts_hw_info *hwinfo; ++}; ++ ++static const struct nvt_ts_trim_id_table trim_id_table[] = { ++ {.id = {0x20, 0xFF, 0xFF, 0x23, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36523_memory_map, .hwinfo = &NT36523_hw_info}, ++ {.id = {0x0C, 0xFF, 0xFF, 0x23, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36523_memory_map, .hwinfo = &NT36523_hw_info}, ++ {.id = {0x0B, 0xFF, 0xFF, 0x23, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36523_memory_map, .hwinfo = &NT36523_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x23, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36523_memory_map, .hwinfo = &NT36523_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x23, 0x65, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36523_memory_map, .hwinfo = &NT36523_hw_info}, ++ {.id = {0x0C, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36675_memory_map, .hwinfo = &NT36675_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x26, 0x65, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36526_memory_map, .hwinfo = &NT36526_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x75, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36675_memory_map, .hwinfo = &NT36675_hw_info}, ++ {.id = {0x0B, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0B, 0xFF, 0xFF, 0x82, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0B, 0xFF, 0xFF, 0x25, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x72, 0x65, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x82, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x70, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0B, 0xFF, 0xFF, 0x70, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x0A, 0xFF, 0xFF, 0x72, 0x67, 0x03}, .mask = {1, 0, 0, 1, 1, 1}, ++ .mmap = &NT36672A_memory_map, .hwinfo = &NT36672A_hw_info}, ++ {.id = {0x55, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0x55, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36772_memory_map, .hwinfo = &NT36772_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x25, 0x65, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36525_memory_map, .hwinfo = &NT36525_hw_info}, ++ {.id = {0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1}, ++ .mmap = &NT36676F_memory_map, .hwinfo = &NT36676F_hw_info} ++}; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0004-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch b/patch/kernel/archive/sm8250-6.18/0004-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch new file mode 100644 index 000000000000..7a828e9780dc --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0004-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch @@ -0,0 +1,93 @@ +From 54e566e8003d80118308717465da1eebc9386fbf Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Mon, 6 Mar 2023 23:23:13 +0800 +Subject: [PATCH 04/62] arm64: dts: qcom: sm8250-xiaomi-elish: enable + touchscreen + +Signed-off-by: Jianhua Lu +Signed-off-by: Jiali Chen +--- + .../boot/dts/qcom/sm8250-xiaomi-elish-boe.dts | 5 +++ + .../dts/qcom/sm8250-xiaomi-elish-common.dtsi | 32 +++++++++++++++++++ + .../dts/qcom/sm8250-xiaomi-elish-csot.dts | 5 +++ + 3 files changed, 42 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts +index de6101ddebe7..b8d9e9406440 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts +@@ -16,3 +16,8 @@ &display_panel { + compatible = "xiaomi,elish-boe-nt36523", "novatek,nt36523"; + status = "okay"; + }; ++ ++&touchscreen { ++ firmware-name = "novatek/nt36523-boe.bin"; ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +index 465fd6e954a3..8977c74e0e02 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +@@ -772,6 +772,16 @@ &pon_resin { + status = "okay"; + }; + ++&qup_spi4_cs_gpio { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qup_spi4_data_clk { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ + &qupv3_id_0 { + status = "okay"; + }; +@@ -789,6 +799,28 @@ &slpi { + status = "okay"; + }; + ++&spi4 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qup_spi4_data_clk &qup_spi4_cs_gpio>; ++ cs-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; ++ touchscreen: touchscreen@0 { ++ compatible = "novatek,NVT-ts-spi"; ++ reg = <0>; //Same as CS ID ++ status = "disabled"; ++ ++ spi-max-frequency = <19200000>; //4800000,9600000,15000000,19200000 ++ novatek,irq-gpio = <&tlmm 39 0x2001>; ++ ++ novatek,pen-support; ++ novatek,wgp-stylus; ++ ++ /* 523 */ ++ novatek,swrst-n8-addr = <0x03F0FE>; ++ novatek,spi-rd-fast-addr = <0x03F310>; ++ }; ++}; ++ + &tlmm { + gpio-reserved-ranges = <40 4>; + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-csot.dts b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-csot.dts +index 4cffe9c703df..5953f652e812 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-csot.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-csot.dts +@@ -16,3 +16,8 @@ &display_panel { + compatible = "xiaomi,elish-csot-nt36523", "novatek,nt36523"; + status = "okay"; + }; ++ ++&touchscreen { ++ firmware-name = "novatek/nt36523-csot.bin"; ++ status = "okay"; ++}; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0005-ASoC-qcom-sm8250-Add-tdm-support.patch b/patch/kernel/archive/sm8250-6.18/0005-ASoC-qcom-sm8250-Add-tdm-support.patch new file mode 100644 index 000000000000..7283b7102945 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0005-ASoC-qcom-sm8250-Add-tdm-support.patch @@ -0,0 +1,135 @@ +From f9e7b23ad98367598d950c179e5d29aac07643f5 Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Mon, 11 Dec 2023 09:23:28 +0800 +Subject: [PATCH 05/62] ASoC: qcom: sm8250: Add tdm support + +Signed-off-by: Jiali Chen +--- + sound/soc/qcom/sm8250.c | 83 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 83 insertions(+) + +diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c +index f5b75a06e5bd..a383f74c5187 100644 +--- a/sound/soc/qcom/sm8250.c ++++ b/sound/soc/qcom/sm8250.c +@@ -17,6 +17,9 @@ + #include "sdw.h" + + #define MI2S_BCLK_RATE 1536000 ++#define TDM_BCLK_RATE 12288000 ++ ++static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + struct sm8250_snd_data { + bool stream_prepared[AFE_PORT_MAX]; +@@ -56,6 +59,57 @@ static void sm8250_snd_exit(struct snd_soc_pcm_runtime *rtd) + + } + ++static int sm8250_tdm_snd_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); ++ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); ++ ++ int ret = 0; ++ int channels, slots, slot_width; ++ ++ channels = params_channels(params); ++ slots = 8; ++ slot_width = 32; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x03, ++ slots, slot_width); ++ if (ret < 0) { ++ dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n", ++ __func__, ret); ++ goto end; ++ } ++ ++ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, ++ channels, tdm_slot_offset); ++ if (ret < 0) { ++ dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n", ++ __func__, ret); ++ goto end; ++ } ++ } else { ++ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0, ++ slots, slot_width); ++ if (ret < 0) { ++ dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n", ++ __func__, ret); ++ goto end; ++ } ++ ++ ret = snd_soc_dai_set_channel_map(cpu_dai, channels, ++ tdm_slot_offset, 0, NULL); ++ if (ret < 0) { ++ dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n", ++ __func__, ret); ++ goto end; ++ } ++ } ++ ++end: ++ return ret; ++} ++ + static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) + { +@@ -79,6 +133,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); ++ int ret,j; + + switch (cpu_dai->id) { + case PRIMARY_MI2S_RX: +@@ -105,6 +160,29 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) + snd_soc_dai_set_fmt(cpu_dai, fmt); + snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); + break; ++ case TERTIARY_TDM_RX_0: ++ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_DSP_A; ++ ret = snd_soc_dai_set_sysclk(cpu_dai, ++ Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT, ++ TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); ++ if (ret < 0) { ++ dev_err(rtd->dev, "TDM cpu sysclk err:%d\n", ret); ++ return ret; ++ } ++ ++ for_each_rtd_codec_dais(rtd, j, codec_dai) { ++ ret = snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); ++ if (ret < 0) { ++ dev_err(rtd->dev, "TDM fmt err:%d\n", ret); ++ return ret; ++ } ++ ret = snd_soc_dai_set_sysclk(codec_dai, 0, TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); ++ if (ret < 0) { ++ dev_err(rtd->dev, "TDM sysclk err:%d\n", ret); ++ return ret; ++ } ++ } ++ break; + default: + break; + } +@@ -130,6 +208,11 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); + ++ switch (cpu_dai->id) { ++ case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: ++ return sm8250_tdm_snd_hw_params(substream, params); ++ } ++ + return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); + } + +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0006-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch b/patch/kernel/archive/sm8250-6.18/0006-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch new file mode 100644 index 000000000000..3724ed0c49f6 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0006-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch @@ -0,0 +1,283 @@ +From 0e25973d676baf54980e8328a9ad286705f4d745 Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Sat, 18 Mar 2023 22:26:22 +0800 +Subject: [PATCH 06/62] arm64: dts: qcom: sm8250-xiaomi-elish: Add sound + support + +Signed-off-by: Jiali Chen +--- + .../dts/qcom/sm8250-xiaomi-elish-common.dtsi | 232 ++++++++++++++++++ + 1 file changed, 232 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +index 8977c74e0e02..0a9381b14e4b 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +@@ -6,6 +6,8 @@ + #include + #include + #include ++#include ++#include + #include + #include "sm8250.dtsi" + #include "pm8150.dtsi" +@@ -572,6 +574,152 @@ fuel-gauge@55 { + }; + }; + ++&i2c1 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ cs35l41_brh: speaker-amp@40 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x40>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "BRH"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_blh: speaker-amp@41 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x41>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <67 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "BLH"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_brl: speaker-amp@42 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x42>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <100 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "BRL"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_bll: speaker-amp@43 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x43>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <126 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 49 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "BLL"; ++ #sound-dai-cells = <1>; ++ }; ++}; ++ ++&i2c3 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ cs35l41_trh: speaker-amp@40 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x40>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <27 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "TRH"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_tlh: speaker-amp@41 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x41>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <92 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 78 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "TLH"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_tll: speaker-amp@42 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x42>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <112 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 30 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "TLL"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_trl: speaker-amp@43 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x43>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <129 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 144 GPIO_ACTIVE_HIGH>; ++ cirrus,boost-type = <0>; ++ cirrus,boost-peak-milliamp = <4000>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ cirrus,asp-sdout-hiz = <3>; ++ cirrus,gpio2-src-select = <4>; ++ cirrus,gpio2-output-enable; ++ sound-name-prefix = "TRL"; ++ #sound-dai-cells = <1>; ++ }; ++}; ++ + &i2c11 { + clock-frequency = <400000>; + status = "okay"; +@@ -794,11 +942,63 @@ &qupv3_id_2 { + status = "okay"; + }; + ++&q6afedai { ++ dai@56 { ++ reg = ; ++ qcom,tdm-sync-mode = <0>; ++ qcom,tdm-sync-src = <1>; ++ qcom,tdm-data-out = <0>; ++ qcom,tdm-invert-sync = <1>; ++ qcom,tdm-data-delay = <1>; ++ qcom,tdm-data-align = <0>; ++ }; ++}; ++ ++&q6asmdai { ++ dai@0 { ++ reg = <0>; ++ }; ++}; ++ + &slpi { + firmware-name = "qcom/sm8250/xiaomi/elish/slpi.mbn"; + status = "okay"; + }; + ++&sound { ++ compatible = "qcom,sm8250-sndcard"; ++ model = "Xiaomi Mi Pad 5 Pro"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&tert_tdm_active>; ++ ++ mm1-dai-link { ++ link-name = "MultiMedia1"; ++ ++ cpu { ++ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; ++ }; ++ }; ++ ++ speaker-dai-link { ++ link-name = "Tertiary TDM Playback"; ++ ++ cpu { ++ sound-dai = <&q6afedai TERTIARY_TDM_RX_0>; ++ }; ++ ++ platform { ++ sound-dai = <&q6routing>; ++ }; ++ ++ codec { ++ sound-dai = <&cs35l41_tlh 0>, <&cs35l41_tll 0>, ++ <&cs35l41_trh 0>, <&cs35l41_trl 0>, ++ <&cs35l41_blh 0>, <&cs35l41_bll 0>, ++ <&cs35l41_brh 0>, <&cs35l41_brl 0>; ++ }; ++ }; ++}; ++ + &spi4 { + status = "okay"; + pinctrl-names = "default"; +@@ -839,6 +1039,38 @@ wlan_en_state: wlan-default-state { + output-low; + bias-pull-up; + }; ++ ++ tert_tdm_active: tert-tdm-active-state { ++ sck-pins { ++ pins = "gpio133"; ++ function = "mi2s2_sck"; ++ drive-strength = <8>; ++ bias-disable; ++ output-high; ++ }; ++ ++ din-pins { ++ pins = "gpio134"; ++ function = "mi2s2_data0"; ++ drive-strength = <8>; ++ bias-disable; ++ }; ++ ++ ws-pins { ++ pins = "gpio135"; ++ function = "mi2s2_ws"; ++ drive-strength = <8>; ++ bias-disable; ++ output-high; ++ }; ++ ++ dout-pins { ++ pins = "gpio137"; ++ function = "mi2s2_data1"; ++ drive-strength = <8>; ++ bias-disable; ++ }; ++ }; + }; + + &uart6 { +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0007-Asoc-wm_adsp-Add-prefix-support.patch b/patch/kernel/archive/sm8250-6.18/0007-Asoc-wm_adsp-Add-prefix-support.patch new file mode 100644 index 000000000000..119d40aa800e --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0007-Asoc-wm_adsp-Add-prefix-support.patch @@ -0,0 +1,45 @@ +From eee00c8ad09457cbecb32563d00f4bcaa31a3e55 Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Wed, 29 Mar 2023 19:38:33 +0800 +Subject: [PATCH 07/62] Asoc: wm_adsp: Add prefix support + +Signed-off-by: Jiali Chen +--- + sound/soc/codecs/wm_adsp.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 8a1d5cc75d6c..80785f0eee59 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -741,6 +741,10 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part, + fwf, wm_adsp_fw[dsp->fw].file, system_name, + filetype); ++ else if (asoc_component_prefix) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part, ++ fwf, wm_adsp_fw[dsp->fw].file, asoc_component_prefix, ++ filetype); + else + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, fwf, + wm_adsp_fw[dsp->fw].file, filetype); +@@ -815,6 +819,16 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, + NULL, "bin"); + return 0; + } ++ } else if (suffix) { ++ if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, ++ cirrus_dir, NULL, ++ NULL, "wmfw")) { ++ adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ cirrus_dir, NULL, ++ suffix, "bin"); ++ return 0; ++ } + } + + /* Check system-specific bin without wmfw before falling back to generic */ +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0008-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Add-dev.patch b/patch/kernel/archive/sm8250-6.18/0008-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Add-dev.patch new file mode 100644 index 000000000000..fd72a75df322 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0008-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Add-dev.patch @@ -0,0 +1,865 @@ +From 3391aa2f8a60b5d82a39a28922521cdf140234d9 Mon Sep 17 00:00:00 2001 +From: Pangwalla +Date: Fri, 10 Mar 2023 19:09:42 -0500 +Subject: [PATCH 08/62] arm64: dts: qcom: sm8250-oneplus-instantnoodlep: Add + device tree for Oneplus 8 Pro + +Signed-off-by: Jiali Chen +--- + arch/arm64/boot/dts/qcom/Makefile | 1 + + .../qcom/sm8250-oneplus-instantnoodlep.dts | 831 ++++++++++++++++++ + 2 files changed, 832 insertions(+) + create mode 100644 arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts + +diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile +index 4bfa926b6a08..4dc01668765d 100644 +--- a/arch/arm64/boot/dts/qcom/Makefile ++++ b/arch/arm64/boot/dts/qcom/Makefile +@@ -281,6 +281,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8150-sony-xperia-kumano-bahamut.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8150-sony-xperia-kumano-griffin.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-hdk.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb ++dtb-$(CONFIG_ARCH_QCOM) += sm8250-oneplus-instantnoodlep.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-samsung-r8q.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-samsung-x1q.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-sony-xperia-edo-pdx203.dtb +diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts +new file mode 100644 +index 000000000000..2ff46c2979e5 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts +@@ -0,0 +1,831 @@ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "sm8250.dtsi" ++#include "pm8150.dtsi" ++#include "pm8150b.dtsi" ++#include "pm8150l.dtsi" ++#include "pm8009.dtsi" ++ ++/* ++ * Delete following upstream (sm8250.dtsi) reserved ++ * memory mappings which are different in this device. ++ */ ++/delete-node/ &removed_mem; ++/delete-node/ &camera_mem; ++/delete-node/ &wlan_mem; ++/delete-node/ &ipa_fw_mem; ++/delete-node/ &ipa_gsi_mem; ++/delete-node/ &gpu_mem; ++/delete-node/ &npu_mem; ++/delete-node/ &video_mem; ++/delete-node/ &cvp_mem; ++/delete-node/ &cdsp_mem; ++/delete-node/ &slpi_mem; ++/delete-node/ &adsp_mem; ++/delete-node/ &spss_mem; ++/delete-node/ &cdsp_secure_heap; ++ ++/ { ++ model = "OnePlus 8 Pro (instantnoodlep)"; ++ compatible = "oneplus,instantnoodlep", "qcom,kona", "qcom,sm8250"; ++ chassis-type = "handset"; ++ ++ qcom,msm-id = <0x164 0x10000>, <0x164 0x20001>; ++ qcom,board-id = <0x08 0x00>, <0x00 0x00>; ++ ++ aliases { ++ hsuart0 = &uart6; ++ }; ++ ++ chosen { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ stdout-path = "framebuffer0"; ++ ++ framebuffer0: framebuffer@9c000000 { ++ compatible = "simple-framebuffer"; ++ reg = <0x0 0x9c000000 0x0 (1080 * 2376 * 4)>; ++ width = <1080>; ++ height = <2376>; ++ stride = <(1080 * 4)>; ++ format = "a8r8g8b8"; ++ }; ++ }; ++ ++ gpio_keys: gpio-keys { ++ compatible = "gpio-keys"; ++ ++ vol-up { ++ label = "Volume Up"; ++ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <15>; ++ linux,can-disable; ++ gpio-key,wakeup; ++ }; ++ ++ vol-down { ++ label = "Volume Down"; ++ linux,code = ; ++ gpios = <&pm8150_gpios 7 GPIO_ACTIVE_LOW>; ++ debounce-interval = <15>; ++ linux,can-disable; ++ gpio-key,wakeup; ++ }; ++ }; ++ ++ reserved-memory { ++ removed_mem: memory@80b00000 { ++ reg = <0x0 0x80b00000 0x0 0xcd00000>; ++ no-map; ++ }; ++ ++ camera_mem: memory@8dc00000 { ++ reg = <0x0 0x8dc00000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ wlan_mem: memory@8e100000 { ++ reg = <0x0 0x8e100000 0x0 0x100000>; ++ no-map; ++ }; ++ ++ ipa_fw_mem: memory@8e200000 { ++ reg = <0x0 0x8e200000 0x0 0x10000>; ++ no-map; ++ }; ++ ++ ipa_gsi_mem: memory@8e210000 { ++ reg = <0x0 0x8e210000 0x0 0xa000>; ++ no-map; ++ }; ++ ++ gpu_mem: memory@8e21a000 { ++ reg = <0x0 0x8e21a000 0x0 0x2000>; ++ no-map; ++ }; ++ ++ npu_mem: memory@8e300000 { ++ reg = <0x0 0x8e300000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ video_mem: memory@8e800000 { ++ reg = <0x0 0x8e800000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ cvp_mem: memory@8ed00000 { ++ reg = <0x0 0x8ed00000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ cdsp_mem: memory@8f200000 { ++ reg = <0x0 0x8f200000 0x0 0x1400000>; ++ no-map; ++ }; ++ ++ slpi_mem: memory@90600000 { ++ reg = <0x0 0x90600000 0x0 0x1500000>; ++ no-map; ++ }; ++ ++ adsp_mem: memory@91b00000 { ++ reg = <0x00 0x91b00000 0x00 0x2500000>; ++ no-map; ++ }; ++ ++ spss_mem: memory@94000000 { ++ reg = <0x0 0x94000000 0x0 0x100000>; ++ no-map; ++ }; ++ ++ cdsp_secure_heap: memory@94100000 { ++ reg = <0x0 0x94100000 0x0 0x4600000>; ++ no-map; ++ }; ++ ++ cont_splash_mem: memory@9c000000 { ++ reg = <0x0 0x9c000000 0x0 0x2300000>; ++ no-map; ++ }; ++ ++ ramoops@b0000000 { ++ compatible = "ramoops"; ++ reg = <0x00 0xb0000000 0x00 0x400000>; ++ record-size = <0x40000>; ++ console-size = <0x40000>; ++ ecc-size = <0x00>; ++ no-map; ++ }; ++ }; ++ ++ vph_pwr: vph-pwr-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vph_pwr"; ++ regulator-min-microvolt = <3700000>; ++ regulator-max-microvolt = <3700000>; ++ }; ++ ++ vreg_s6c_0p88: smpc6-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vreg_s6c_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-always-on; ++ vin-supply = <&vph_pwr>; ++ }; ++ ++ vreg_s4a_1p8: vreg-s4a-1p8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vreg_s4a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ qca639x: qca639x { ++ compatible = "qcom,qca6390"; ++ #power-domain-cells = <0>; ++ ++ vddaon-supply = <&vreg_s6a_0p95>; ++ vddpmu-supply = <&vreg_s2f_0p95>; ++ vddrfa1-supply = <&vreg_s2f_0p95>; ++ vddrfa2-supply = <&vreg_s8c_1p3>; ++ vddrfa3-supply = <&vreg_s5a_1p9>; ++ vddpcie1-supply = <&vreg_s8c_1p3>; ++ vddpcie2-supply = <&vreg_s5a_1p9>; ++ vddio-supply = <&vreg_s4a_1p8>; ++ ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&wlan_en_active>; ++ pinctrl-1 = <&wlan_en_sleep>; ++ ++ wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ battery: battery { ++ compatible = "simple-battery"; ++ ++ charge-full-design-microamp-hours = <4410000>; ++ energy-full-design-microwatt-hours = <17060000>; ++ voltage-max-design-microvolt = <4350000>; ++ }; ++}; ++ ++&apps_rsc { ++ regulators-0 { ++ compatible = "qcom,pm8009-1-rpmh-regulators"; ++ qcom,pmic-id = "f"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-l2-supply = <&vreg_s8c_1p3>; ++ vdd-l5-l6-supply = <&vreg_bob>; ++ vdd-l7-supply = <&vreg_s4a_1p8>; ++ ++ vreg_s2f_0p95: smps2 { ++ regulator-name = "vreg_s2f_0p95"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <952000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l1f_1p1: ldo1 { ++ regulator-name = "vreg_l1f_1p1"; ++ regulator-min-microvolt = <1104000>; ++ regulator-max-microvolt = <1104000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2f_1p2: ldo2 { ++ regulator-name = "vreg_l2f_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6f_2p8: ldo6 { ++ regulator-name = "vreg_l6f_2p8"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7f_1p8: ldo7 { ++ regulator-name = "vreg_l7f_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++ ++ regulators-1 { ++ compatible = "qcom,pm8150-rpmh-regulators"; ++ qcom,pmic-id = "a"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-s9-supply = <&vph_pwr>; ++ vdd-s10-supply = <&vph_pwr>; ++ vdd-l2-l10-supply = <&vreg_bob>; ++ vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>; ++ vdd-l6-l9-supply = <&vreg_s8c_1p3>; ++ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>; ++ vdd-l13-l16-l17-supply = <&vreg_bob>; ++ ++ vreg_l2a_3p1: ldo2 { ++ regulator-name = "vreg_l2a_3p1"; ++ regulator-min-microvolt = <3072000>; ++ regulator-max-microvolt = <3072000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3a_0p9: ldo3 { ++ regulator-name = "vreg_l3a_0p9"; ++ regulator-min-microvolt = <928000>; ++ regulator-max-microvolt = <932000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l5a_0p88: ldo5 { ++ regulator-name = "vreg_l5a_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6a_1p2: ldo6 { ++ regulator-name = "vreg_l6a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7a_1p7: ldo7 { ++ regulator-name = "vreg_l7a_1p7"; ++ regulator-min-microvolt = <1704000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9a_1p2: ldo9 { ++ regulator-name = "vreg_l9a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l10a_1p8: ldo10 { ++ regulator-name = "vreg_l10a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l12a_1p8: ldo12 { ++ regulator-name = "vreg_l12a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l13a_ts_3p0: ldo13 { ++ regulator-name = "vreg_l13a_ts_3p0"; ++ regulator-min-microvolt = <3008000>; ++ regulator-max-microvolt = <3008000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l14a_1p8: ldo14 { ++ regulator-name = "vreg_l14a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l15a_1p8: ldo15 { ++ regulator-name = "vreg_l15a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l16a_2p7: ldo16 { ++ regulator-name = "vreg_l16a_2p7"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l17a_3p0: ldo17 { ++ regulator-name = "vreg_l17a_3p0"; ++ regulator-min-microvolt = <2856000>; ++ regulator-max-microvolt = <3008000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l18a_0p92: ldo18 { ++ regulator-name = "vreg_l18a_0p92"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <912000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s5a_1p9: smps5 { ++ regulator-name = "vreg_s5a_1p9"; ++ regulator-min-microvolt = <1904000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s6a_0p95: smps6 { ++ regulator-name = "vreg_s6a_0p95"; ++ regulator-min-microvolt = <920000>; ++ regulator-max-microvolt = <1128000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++ ++ regulators-2 { ++ compatible = "qcom,pm8150l-rpmh-regulators"; ++ qcom,pmic-id = "c"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-l1-l8-supply = <&vreg_s4a_1p8>; ++ vdd-l2-l3-supply = <&vreg_s8c_1p3>; ++ vdd-l4-l5-l6-supply = <&vreg_bob>; ++ vdd-l7-l11-supply = <&vreg_bob>; ++ vdd-l9-l10-supply = <&vreg_bob>; ++ vdd-bob-supply = <&vph_pwr>; ++ ++ vreg_bob: bob { ++ regulator-name = "vreg_bob"; ++ regulator-min-microvolt = <3008000>; ++ regulator-max-microvolt = <4000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l1c_1p8: ldo1 { ++ regulator-name = "vreg_l1c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2c_1p2: ldo2 { ++ regulator-name = "vreg_l2c_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3c_0p8: ldo3 { ++ regulator-name = "vreg_l3c_0p8"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l4c_1p7: ldo4 { ++ regulator-name = "vreg_l4c_1p7"; ++ regulator-min-microvolt = <1704000>; ++ regulator-max-microvolt = <2928000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l5c_1p8: ldo5 { ++ regulator-name = "vreg_l5c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2928000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6c_2p96: ldo6 { ++ regulator-name = "vreg_l6c_2p96"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7c_cam_vcm0_2p85: ldo7 { ++ regulator-name = "vreg_l7c_cam_vcm0_2p85"; ++ regulator-min-microvolt = <2856000>; ++ regulator-max-microvolt = <3104000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l8c_1p8: ldo8 { ++ regulator-name = "vreg_l8c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9c_2p96: ldo9 { ++ regulator-name = "vreg_l9c_2p96"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l10c_3p0: ldo10 { ++ regulator-name = "vreg_l10c_3p0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l11c_3p3: ldo11 { ++ regulator-name = "vreg_l11c_3p3"; ++ regulator-min-microvolt = <3296000>; ++ regulator-max-microvolt = <3296000>; ++ regulator-initial-mode = ; ++ regulator-always-on; ++ }; ++ ++ vreg_s8c_1p3: smps8 { ++ regulator-name = "vreg_s8c_1p3"; ++ regulator-min-microvolt = <1352000>; ++ regulator-max-microvolt = <1352000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++}; ++ ++&adsp { ++ firmware-name = "postmarketos/adsp.mbn"; ++ status = "okay"; ++}; ++ ++&cdsp { ++ firmware-name = "postmarketos/cdsp.mbn"; ++ status = "okay"; ++}; ++ ++&dispcc { ++ status = "disabled"; ++}; ++ ++&gmu { ++ status = "okay"; ++}; ++ ++&gpi_dma0 { ++ status = "okay"; ++}; ++ ++&gpi_dma1 { ++ status = "okay"; ++}; ++ ++&gpi_dma2 { ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ nfc@28 { ++ compatible = "nxp,nxp-nci-i2c"; ++ reg = <0x28>; ++ ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x6f IRQ_TYPE_LEVEL_HIGH>; ++ ++ enable-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>, ++ <&tlmm 110 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&i2c5 { ++ status = "okay"; ++ ++ charger@66 { ++ compatible = "ti,bq25980"; ++ reg = <0x66>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x0f 0x00>; ++ monitored-battery = <&battery>; ++ }; ++}; ++ ++&i2c16 { ++ status = "okay"; ++ ++ smart_battery: fuel-gauge@55 { ++ compatible = "ti,bq27541"; ++ reg = <0x55>; ++ monitored-battery = <&battery>; ++ }; ++}; ++ ++&i2c13 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ touchscreen@48 { ++ compatible = "samsung,s6sy761"; ++ reg = <0x48>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x27 0x2008>; ++ ++ vdd-supply = <&vreg_l13a_ts_3p0>; ++ avdd-supply = <&vreg_l1c_1p8>; ++ ++ touchscreen-size-x = <1440>; ++ touchscreen-size-y = <3168>; ++ ++ pinctrl-names = "default", "suspend"; ++ pinctrl-0 = <&ts_int_active>; ++ pinctrl-1 = <&ts_rst_suspend>; ++ }; ++}; ++ ++&mdss { ++ status = "okay"; ++}; ++ ++&slpi { ++ firmware-name = "postmarketos/slpi.mbn"; ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&pcie0_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++ power-domains = <&qca639x>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&pcie1_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&pcie2 { ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&pm8150_gpios { ++ vol_up_n: vol-up-n-state { ++ pins = "gpio6"; ++ function = "normal"; ++ power-source = <1>; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ vol_down_n: vol-down-n-state { ++ pins = "gpio7"; ++ function = "normal"; ++ power-source = <1>; ++ input-enable; ++ bias-pull-up; ++ }; ++}; ++ ++&pon_pwrkey { ++ status = "okay"; ++}; ++ ++&pon_resin { ++ linux,code = ; ++ status = "okay"; ++}; ++ ++&qup_spi4_cs_gpio { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qup_spi4_data_clk { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qupv3_id_0 { ++ status = "okay"; ++}; ++ ++&qupv3_id_1 { ++ status = "okay"; ++}; ++ ++&qupv3_id_2 { ++ status = "okay"; ++}; ++ ++&tlmm { ++ gpio-reserved-ranges = <28 4>, <40 4>; ++ ++ bt_en_active: bt-default-state { ++ bt-en { ++ pins = "gpio21"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-up; ++ }; ++ }; ++ ++ bt_en_sleep: bt-sleep-state { ++ pins = "gpio21"; ++ function = "gpio"; ++ ++ drive-strength = <0x02>; ++ output-low; ++ bias-pull-down; ++ }; ++ ++ wlan_en_active: wlan-default-state { ++ wlan-en { ++ pins = "gpio20"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-up; ++ }; ++ }; ++ ++ wlan_en_sleep: wlan-sleep-state { ++ pins = "gpio20"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-down; ++ }; ++ ++ ts_int_active: ts-int-active-state { ++ pins = "gpio38", "gpio39"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ ts_rst_suspend: ts-rst-suspend { ++ pins = "gpio38"; ++ function = "gpio"; ++ drive-strength = <0x02>; ++ bias-pull-down; ++ }; ++}; ++ ++&uart6 { ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "qcom,qca6390-bt"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&bt_en_active>; ++ pinctrl-1 = <&bt_en_sleep>; ++ ++ power-domains = <&qca639x>; ++ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&ufs_mem_hc { ++ vcc-supply = <&vreg_l17a_3p0>; ++ vcc-max-microamp = <800000>; ++ vccq-supply = <&vreg_l6a_1p2>; ++ vccq-max-microamp = <800000>; ++ vccq2-supply = <&vreg_s4a_1p8>; ++ vccq2-max-microamp = <800000>; ++ status = "okay"; ++}; ++ ++&ufs_mem_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&usb_1 { ++ /* USB 2.0 only */ ++ qcom,select-utmi-as-pipe-clk; ++ status = "okay"; ++}; ++ ++&usb_1_dwc3 { ++ dr_mode = "peripheral"; ++ maximum-speed = "high-speed"; ++ /* Remove USB3 phy */ ++ phys = <&usb_1_hsphy>; ++ phy-names = "usb2-phy"; ++}; ++ ++&usb_1_hsphy { ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ status = "okay"; ++}; ++ ++&usb_2 { ++ status = "okay"; ++}; ++ ++&usb_2_dwc3 { ++ dr_mode = "host"; ++}; ++ ++&usb_2_hsphy { ++ status = "okay"; ++ ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++}; ++ ++&usb_2_qmpphy { ++ status = "okay"; ++ ++ vdda-phy-supply = <&vreg_l9a_1p2>; ++ vdda-pll-supply = <&vreg_l18a_0p92>; ++}; ++ ++&venus { ++ firmware-name = "postmarketos/venus.mbn"; ++ status = "okay"; ++}; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0009-drm-msm-dsi-change-sync-mode-to-sync-on-DSI0-rather-.patch b/patch/kernel/archive/sm8250-6.18/0009-drm-msm-dsi-change-sync-mode-to-sync-on-DSI0-rather-.patch new file mode 100644 index 000000000000..33c4d20b59e7 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0009-drm-msm-dsi-change-sync-mode-to-sync-on-DSI0-rather-.patch @@ -0,0 +1,80 @@ +From dba36167ae2bd695ea866b7d5b779b4439ee7bc6 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov +Date: Sun, 4 Jun 2023 21:44:33 +0300 +Subject: [PATCH 09/62] drm/msm/dsi: change sync mode to sync on DSI0 rather + than DSI1 + +Change MSM DSI's sync-dual-dsi mode to resync on DSI0 rather than DSI1. + +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Jiali Chen +--- + drivers/gpu/drm/msm/dsi/dsi_manager.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c +index 168a254feecc..5373630543d8 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c +@@ -504,7 +504,7 @@ int msm_dsi_manager_connector_init(struct msm_dsi *msm_dsi, + int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) + { + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); +- struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); ++ struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + bool is_read = (msg->rx_buf && msg->rx_len); + bool need_sync = (IS_SYNC_NEEDED() && !is_read); +@@ -515,14 +515,14 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) + + /* In bonded master case, panel requires the same commands sent to + * both DSI links. Host issues the command trigger to both links +- * when DSI_1 calls the cmd transfer function, no matter it happens +- * before or after DSI_0 cmd transfer. ++ * when DSI_0 calls the cmd transfer function, no matter it happens ++ * before or after DSI_1 cmd transfer. + */ +- if (need_sync && (id == DSI_0)) ++ if (need_sync && (id == DSI_1)) + return is_read ? msg->rx_len : msg->tx_len; + +- if (need_sync && msm_dsi0) { +- ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg); ++ if (need_sync && msm_dsi1) { ++ ret = msm_dsi_host_xfer_prepare(msm_dsi1->host, msg); + if (ret) { + pr_err("%s: failed to prepare non-trigger host, %d\n", + __func__, ret); +@@ -541,8 +541,8 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) + msm_dsi_host_xfer_restore(host, msg); + + restore_host0: +- if (need_sync && msm_dsi0) +- msm_dsi_host_xfer_restore(msm_dsi0->host, msg); ++ if (need_sync && msm_dsi1) ++ msm_dsi_host_xfer_restore(msm_dsi1->host, msg); + + return ret; + } +@@ -550,14 +550,14 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) + bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len) + { + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); +- struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); ++ struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + +- if (IS_SYNC_NEEDED() && (id == DSI_0)) ++ if (IS_SYNC_NEEDED() && (id == DSI_1)) + return false; + +- if (IS_SYNC_NEEDED() && msm_dsi0) +- msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len); ++ if (IS_SYNC_NEEDED() && msm_dsi1) ++ msm_dsi_host_cmd_xfer_commit(msm_dsi1->host, dma_base, len); + + msm_dsi_host_cmd_xfer_commit(host, dma_base, len); + +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0010-arm64-dts-qcom-sm8250-xiaomi-elish-add-keyboard-supp.patch b/patch/kernel/archive/sm8250-6.18/0010-arm64-dts-qcom-sm8250-xiaomi-elish-add-keyboard-supp.patch new file mode 100644 index 000000000000..bb1cbf1d2db2 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0010-arm64-dts-qcom-sm8250-xiaomi-elish-add-keyboard-supp.patch @@ -0,0 +1,79 @@ +From adb2925c252c0c5ce169e4e469082471a57ae939 Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Sat, 2 Dec 2023 19:08:14 +0800 +Subject: [PATCH 10/62] arm64: dts: qcom: sm8250-xiaomi-elish: add keyboard + support + +Signed-off-by: Jiali Chen +--- + .../dts/qcom/sm8250-xiaomi-elish-common.dtsi | 40 +++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +index 0a9381b14e4b..4c99b9f9f6fe 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +@@ -748,6 +748,15 @@ fuel-gauge@55 { + }; + }; + ++&lpass_tlmm { ++ keyboard_en_state: keyboard-default-state { ++ pins = "gpio9"; ++ function = "i2s1_data"; ++ drive-strength = <8>; ++ bias-pull-up; ++ }; ++}; ++ + &mdss { + status = "okay"; + }; +@@ -1071,6 +1080,14 @@ dout-pins { + bias-disable; + }; + }; ++ ++ keyboard_vdd_pin: keyboard-vdd-state { ++ pins = "gpio127"; ++ function = "gpio"; ++ drive-strength = <8>; ++ bias-disable; ++ output-high; ++ }; + }; + + &uart6 { +@@ -1114,6 +1131,29 @@ &usb_1_dwc3_hs_out { + remote-endpoint = <&pm8150b_hs_in>; + }; + ++&usb_2 { ++ /* USB 2.0 only */ ++ qcom,select-utmi-as-pipe-clk; ++ status = "okay"; ++}; ++ ++&usb_2_dwc3 { ++ dr_mode = "host"; ++ maximum-speed = "high-speed"; ++ /* Remove USB3 phy */ ++ phys = <&usb_2_hsphy>; ++ phy-names = "usb2-phy"; ++}; ++ ++&usb_2_hsphy { ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ status = "okay"; ++ pinctrl-0 = <&keyboard_en_state>, <&keyboard_vdd_pin>; ++ pinctrl-names = "default"; ++}; ++ + &ufs_mem_hc { + vcc-supply = <&vreg_l17a_3p0>; + vcc-max-microamp = <800000>; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0011-arm64-dts-qcom-sm8250-oneplus-kebab-Add-device-tree-.patch b/patch/kernel/archive/sm8250-6.18/0011-arm64-dts-qcom-sm8250-oneplus-kebab-Add-device-tree-.patch new file mode 100644 index 000000000000..eb21fe7e97f8 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0011-arm64-dts-qcom-sm8250-oneplus-kebab-Add-device-tree-.patch @@ -0,0 +1,866 @@ +From bc3289ef49d50169a31feb03b81165b8fead57b3 Mon Sep 17 00:00:00 2001 +From: d4n1 +Date: Fri, 19 Jan 2024 15:17:45 +0500 +Subject: [PATCH 11/62] arm64: dts: qcom: sm8250-oneplus-kebab: Add device tree + for OnePlus 8t + +Signed-off-by: Jiali Chen +--- + arch/arm64/boot/dts/qcom/Makefile | 1 + + .../boot/dts/qcom/sm8250-oneplus-kebab.dts | 832 ++++++++++++++++++ + 2 files changed, 833 insertions(+) + create mode 100644 arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts + +diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile +index 4dc01668765d..305a66a7b991 100644 +--- a/arch/arm64/boot/dts/qcom/Makefile ++++ b/arch/arm64/boot/dts/qcom/Makefile +@@ -276,6 +276,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8150-sony-xperia-kumano-griffin.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-hdk.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-oneplus-instantnoodlep.dtb ++dtb-$(CONFIG_ARCH_QCOM) += sm8250-oneplus-kebab.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-samsung-r8q.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-samsung-x1q.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-sony-xperia-edo-pdx203.dtb +diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts +new file mode 100644 +index 000000000000..120632be9eee +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts +@@ -0,0 +1,832 @@ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "sm8250.dtsi" ++#include "pm8150.dtsi" ++#include "pm8150b.dtsi" ++#include "pm8150l.dtsi" ++#include "pm8009.dtsi" ++ ++/* ++ * Delete following upstream (sm8250.dtsi) reserved ++ * memory mappings which are different in this device. ++ */ ++/delete-node/ &removed_mem; ++/delete-node/ &camera_mem; ++/delete-node/ &wlan_mem; ++/delete-node/ &ipa_fw_mem; ++/delete-node/ &ipa_gsi_mem; ++/delete-node/ &gpu_mem; ++/delete-node/ &npu_mem; ++/delete-node/ &video_mem; ++/delete-node/ &cvp_mem; ++/delete-node/ &cdsp_mem; ++/delete-node/ &slpi_mem; ++/delete-node/ &adsp_mem; ++/delete-node/ &spss_mem; ++/delete-node/ &cdsp_secure_heap; ++ ++/ { ++ model = "OnePlus 8T (kebab)"; ++ compatible = "oneplus,kebab", "qcom,kona", "qcom,sm8250"; ++ chassis-type = "handset"; ++ ++ qcom,msm-id = <0x164 0x10000>, <0x164 0x20001>; ++ qcom,board-id = <0x08 0x00>, <0x00 0x00>; ++ ++ aliases { ++ hsuart0 = &uart6; ++ }; ++ ++ chosen { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ stdout-path = "framebuffer0"; ++ ++ framebuffer0: framebuffer@9c000000 { ++ compatible = "simple-framebuffer"; ++ reg = <0x0 0x9c000000 0x0 (1080 * 2376 * 4)>; ++ width = <1080>; ++ height = <2376>; ++ stride = <(1080 * 4)>; ++ format = "a8r8g8b8"; ++ }; ++ }; ++ ++ gpio_keys: gpio-keys { ++ compatible = "gpio-keys"; ++ ++ vol-up { ++ label = "Volume Up"; ++ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <15>; ++ linux,can-disable; ++ gpio-key,wakeup; ++ }; ++ ++ vol-down { ++ label = "Volume Down"; ++ linux,code = ; ++ gpios = <&pm8150_gpios 7 GPIO_ACTIVE_LOW>; ++ debounce-interval = <15>; ++ linux,can-disable; ++ gpio-key,wakeup; ++ }; ++ }; ++ ++ reserved-memory { ++ // removed_mem: memory@80b00000 { ++ // reg = <0x0 0x80b00000 0x0 0xcd00000>; ++ // no-map; ++ // }; ++ ++ camera_mem: memory@8dc00000 { ++ reg = <0x0 0x8dc00000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ wlan_mem: memory@8e100000 { ++ reg = <0x0 0x8e100000 0x0 0x100000>; ++ no-map; ++ }; ++ ++ ipa_fw_mem: memory@8e200000 { ++ reg = <0x0 0x8e200000 0x0 0x10000>; ++ no-map; ++ }; ++ ++ ipa_gsi_mem: memory@8e210000 { ++ reg = <0x0 0x8e210000 0x0 0xa000>; ++ no-map; ++ }; ++ ++ gpu_mem: memory@8e21a000 { ++ reg = <0x0 0x8e21a000 0x0 0x2000>; ++ no-map; ++ }; ++ ++ npu_mem: memory@8e300000 { ++ reg = <0x0 0x8e300000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ video_mem: memory@8e800000 { ++ reg = <0x0 0x8e800000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ cvp_mem: memory@8ed00000 { ++ reg = <0x0 0x8ed00000 0x0 0x500000>; ++ no-map; ++ }; ++ ++ cdsp_mem: memory@8f200000 { ++ reg = <0x0 0x8f200000 0x0 0x1400000>; ++ no-map; ++ }; ++ ++ slpi_mem: memory@90600000 { ++ reg = <0x0 0x90600000 0x0 0x1500000>; ++ no-map; ++ }; ++ ++ adsp_mem: memory@91b00000 { ++ reg = <0x00 0x91b00000 0x00 0x2500000>; ++ no-map; ++ }; ++ ++ spss_mem: memory@94000000 { ++ reg = <0x0 0x94000000 0x0 0x100000>; ++ no-map; ++ }; ++ ++ cdsp_secure_heap: memory@94100000 { ++ reg = <0x0 0x94100000 0x0 0x4600000>; ++ no-map; ++ }; ++ ++ cont_splash_mem: memory@9c000000 { ++ reg = <0x0 0x9c000000 0x0 0x2300000>; ++ no-map; ++ }; ++ ++ // ramoops@b0000000 { ++ // compatible = "ramoops"; ++ // reg = <0x00 0xb0000000 0x00 0x400000>; ++ // record-size = <0x40000>; ++ // console-size = <0x40000>; ++ // ecc-size = <0x00>; ++ // no-map; ++ // }; ++ }; ++ ++ vph_pwr: vph-pwr-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vph_pwr"; ++ regulator-min-microvolt = <3700000>; ++ regulator-max-microvolt = <3700000>; ++ }; ++ ++ vreg_s6c_0p88: smpc6-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vreg_s6c_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-always-on; ++ vin-supply = <&vph_pwr>; ++ }; ++ ++ vreg_s4a_1p8: vreg-s4a-1p8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vreg_s4a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ qca639x: qca639x { ++ compatible = "qcom,qca6390"; ++ #power-domain-cells = <0>; ++ ++ vddaon-supply = <&vreg_s6a_0p95>; ++ vddpmu-supply = <&vreg_s2f_0p95>; ++ vddrfa1-supply = <&vreg_s2f_0p95>; ++ vddrfa2-supply = <&vreg_s8c_1p3>; ++ vddrfa3-supply = <&vreg_s5a_1p9>; ++ vddpcie1-supply = <&vreg_s8c_1p3>; ++ vddpcie2-supply = <&vreg_s5a_1p9>; ++ vddio-supply = <&vreg_s4a_1p8>; ++ ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&wlan_en_active>; ++ pinctrl-1 = <&wlan_en_sleep>; ++ ++ wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ battery: battery { ++ compatible = "simple-battery"; ++ ++ charge-full-design-microamp-hours = <4410000>; ++ energy-full-design-microwatt-hours = <17060000>; ++ voltage-max-design-microvolt = <4350000>; ++ }; ++}; ++ ++&apps_rsc { ++ regulators-0 { ++ compatible = "qcom,pm8009-1-rpmh-regulators"; ++ qcom,pmic-id = "f"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-l2-supply = <&vreg_s8c_1p3>; ++ vdd-l5-l6-supply = <&vreg_bob>; ++ vdd-l7-supply = <&vreg_s4a_1p8>; ++ ++ vreg_s2f_0p95: smps2 { ++ regulator-name = "vreg_s2f_0p95"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <952000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l1f_1p1: ldo1 { ++ regulator-name = "vreg_l1f_1p1"; ++ regulator-min-microvolt = <1104000>; ++ regulator-max-microvolt = <1104000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2f_1p2: ldo2 { ++ regulator-name = "vreg_l2f_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6f_2p8: ldo6 { ++ regulator-name = "vreg_l6f_2p8"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7f_1p8: ldo7 { ++ regulator-name = "vreg_l7f_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++ ++ regulators-1 { ++ compatible = "qcom,pm8150-rpmh-regulators"; ++ qcom,pmic-id = "a"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-s9-supply = <&vph_pwr>; ++ vdd-s10-supply = <&vph_pwr>; ++ vdd-l2-l10-supply = <&vreg_bob>; ++ vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>; ++ vdd-l6-l9-supply = <&vreg_s8c_1p3>; ++ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>; ++ vdd-l13-l16-l17-supply = <&vreg_bob>; ++ ++ vreg_l2a_3p1: ldo2 { ++ regulator-name = "vreg_l2a_3p1"; ++ regulator-min-microvolt = <3072000>; ++ regulator-max-microvolt = <3072000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3a_0p9: ldo3 { ++ regulator-name = "vreg_l3a_0p9"; ++ regulator-min-microvolt = <928000>; ++ regulator-max-microvolt = <932000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l5a_0p88: ldo5 { ++ regulator-name = "vreg_l5a_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6a_1p2: ldo6 { ++ regulator-name = "vreg_l6a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7a_1p7: ldo7 { ++ regulator-name = "vreg_l7a_1p7"; ++ regulator-min-microvolt = <1704000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9a_1p2: ldo9 { ++ regulator-name = "vreg_l9a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l10a_1p8: ldo10 { ++ regulator-name = "vreg_l10a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l12a_1p8: ldo12 { ++ regulator-name = "vreg_l12a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l13a_ts_3p0: ldo13 { ++ regulator-name = "vreg_l13a_ts_3p0"; ++ regulator-min-microvolt = <3008000>; ++ regulator-max-microvolt = <3008000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l14a_1p8: ldo14 { ++ regulator-name = "vreg_l14a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l15a_1p8: ldo15 { ++ regulator-name = "vreg_l15a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l16a_2p7: ldo16 { ++ regulator-name = "vreg_l16a_2p7"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l17a_3p0: ldo17 { ++ regulator-name = "vreg_l17a_3p0"; ++ regulator-min-microvolt = <2856000>; ++ regulator-max-microvolt = <3008000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l18a_0p92: ldo18 { ++ regulator-name = "vreg_l18a_0p92"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <912000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s5a_1p9: smps5 { ++ regulator-name = "vreg_s5a_1p9"; ++ regulator-min-microvolt = <1904000>; ++ regulator-max-microvolt = <2000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s6a_0p95: smps6 { ++ regulator-name = "vreg_s6a_0p95"; ++ regulator-min-microvolt = <920000>; ++ regulator-max-microvolt = <1128000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++ ++ regulators-2 { ++ compatible = "qcom,pm8150l-rpmh-regulators"; ++ qcom,pmic-id = "c"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-l1-l8-supply = <&vreg_s4a_1p8>; ++ vdd-l2-l3-supply = <&vreg_s8c_1p3>; ++ vdd-l4-l5-l6-supply = <&vreg_bob>; ++ vdd-l7-l11-supply = <&vreg_bob>; ++ vdd-l9-l10-supply = <&vreg_bob>; ++ vdd-bob-supply = <&vph_pwr>; ++ ++ vreg_bob: bob { ++ regulator-name = "vreg_bob"; ++ regulator-min-microvolt = <3008000>; ++ regulator-max-microvolt = <4000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l1c_1p8: ldo1 { ++ regulator-name = "vreg_l1c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2c_1p2: ldo2 { ++ regulator-name = "vreg_l2c_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3c_0p8: ldo3 { ++ regulator-name = "vreg_l3c_0p8"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l4c_1p7: ldo4 { ++ regulator-name = "vreg_l4c_1p7"; ++ regulator-min-microvolt = <1704000>; ++ regulator-max-microvolt = <2928000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l5c_1p8: ldo5 { ++ regulator-name = "vreg_l5c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2928000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6c_2p96: ldo6 { ++ regulator-name = "vreg_l6c_2p96"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l7c_cam_vcm0_2p85: ldo7 { ++ regulator-name = "vreg_l7c_cam_vcm0_2p85"; ++ regulator-min-microvolt = <2856000>; ++ regulator-max-microvolt = <3104000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l8c_1p8: ldo8 { ++ regulator-name = "vreg_l8c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9c_2p96: ldo9 { ++ regulator-name = "vreg_l9c_2p96"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l10c_3p0: ldo10 { ++ regulator-name = "vreg_l10c_3p0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l11c_3p3: ldo11 { ++ regulator-name = "vreg_l11c_3p3"; ++ regulator-min-microvolt = <3296000>; ++ regulator-max-microvolt = <3296000>; ++ regulator-initial-mode = ; ++ regulator-always-on; ++ }; ++ ++ vreg_s8c_1p3: smps8 { ++ regulator-name = "vreg_s8c_1p3"; ++ regulator-min-microvolt = <1352000>; ++ regulator-max-microvolt = <1352000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++}; ++ ++&adsp { ++ firmware-name = "postmarketos/adsp.mbn"; ++ status = "okay"; ++}; ++ ++&cdsp { ++ firmware-name = "postmarketos/cdsp.mbn"; ++ status = "okay"; ++}; ++ ++&dispcc { ++ status = "disabled"; ++}; ++ ++&gmu { ++ status = "okay"; ++}; ++ ++&gpi_dma0 { ++ status = "okay"; ++}; ++ ++&gpi_dma1 { ++ status = "okay"; ++}; ++ ++&gpi_dma2 { ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ nfc@28 { ++ compatible = "nxp,nxp-nci-i2c"; ++ reg = <0x28>; ++ ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x6f IRQ_TYPE_LEVEL_HIGH>; ++ ++ enable-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>, ++ <&tlmm 110 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&i2c5 { ++ status = "okay"; ++ ++ charger@66 { ++ compatible = "ti,bq25980"; ++ status = "ok"; ++ reg = <0x66>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x0f 0x00>; ++ monitored-battery = <&battery>; ++ }; ++}; ++ ++&i2c16 { ++ status = "okay"; ++ ++ smart_battery: fuel-gauge@55 { ++ compatible = "ti,bq27541"; ++ reg = <0x55>; ++ monitored-battery = <&battery>; ++ }; ++}; ++ ++&i2c13 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ touchscreen@48 { ++ compatible = "samsung,s6sy761"; ++ reg = <0x48>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <0x27 0x2008>; ++ ++ vdd-supply = <&vreg_l13a_ts_3p0>; ++ avdd-supply = <&vreg_l1c_1p8>; ++ ++ touchscreen-size-x = <1440>; ++ touchscreen-size-y = <3168>; ++ ++ pinctrl-names = "default", "suspend"; ++ pinctrl-0 = <&ts_int_active>; ++ pinctrl-1 = <&ts_rst_suspend>; ++ }; ++}; ++ ++&mdss { ++ status = "okay"; ++}; ++ ++&slpi { ++ firmware-name = "postmarketos/slpi.mbn"; ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&pcie0_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++ power-domains = <&qca639x>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++}; ++ ++&pcie1_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&pcie2 { ++ status = "okay"; ++}; ++ ++&pcie2_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&pm8150_gpios { ++ vol_up_n: vol-up-n-state { ++ pins = "gpio6"; ++ function = "normal"; ++ power-source = <1>; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ vol_down_n: vol-down-n-state { ++ pins = "gpio7"; ++ function = "normal"; ++ power-source = <1>; ++ input-enable; ++ bias-pull-up; ++ }; ++}; ++ ++&pon_pwrkey { ++ status = "okay"; ++}; ++ ++&pon_resin { ++ linux,code = ; ++ status = "okay"; ++}; ++ ++&qup_spi4_cs_gpio { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qup_spi4_data_clk { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qupv3_id_0 { ++ status = "okay"; ++}; ++ ++&qupv3_id_1 { ++ status = "okay"; ++}; ++ ++&qupv3_id_2 { ++ status = "okay"; ++}; ++ ++&tlmm { ++ gpio-reserved-ranges = <28 4>, <40 4>; ++ ++ bt_en_active: bt-default-state { ++ bt-en { ++ pins = "gpio21"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-up; ++ }; ++ }; ++ ++ bt_en_sleep: bt-sleep-state { ++ pins = "gpio21"; ++ function = "gpio"; ++ ++ drive-strength = <0x02>; ++ output-low; ++ bias-pull-down; ++ }; ++ ++ wlan_en_active: wlan-default-state { ++ wlan-en { ++ pins = "gpio20"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-up; ++ }; ++ }; ++ ++ wlan_en_sleep: wlan-sleep-state { ++ pins = "gpio20"; ++ function = "gpio"; ++ ++ drive-strength = <16>; ++ output-low; ++ bias-pull-down; ++ }; ++ ++ ts_int_active: ts-int-active-state { ++ pins = "gpio38", "gpio39"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ ts_rst_suspend: ts-rst-suspend { ++ pins = "gpio38"; ++ function = "gpio"; ++ drive-strength = <0x02>; ++ bias-pull-down; ++ }; ++}; ++ ++&uart6 { ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "qcom,qca6390-bt"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&bt_en_active>; ++ pinctrl-1 = <&bt_en_sleep>; ++ ++ power-domains = <&qca639x>; ++ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&ufs_mem_hc { ++ vcc-supply = <&vreg_l17a_3p0>; ++ vcc-max-microamp = <800000>; ++ vccq-supply = <&vreg_l6a_1p2>; ++ vccq-max-microamp = <800000>; ++ vccq2-supply = <&vreg_s4a_1p8>; ++ vccq2-max-microamp = <800000>; ++ status = "okay"; ++}; ++ ++&ufs_mem_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&usb_1 { ++ /* USB 2.0 only */ ++ qcom,select-utmi-as-pipe-clk; ++ status = "okay"; ++}; ++ ++&usb_1_dwc3 { ++ dr_mode = "peripheral"; ++ maximum-speed = "high-speed"; ++ /* Remove USB3 phy */ ++ phys = <&usb_1_hsphy>; ++ phy-names = "usb2-phy"; ++}; ++ ++&usb_1_hsphy { ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ status = "okay"; ++}; ++ ++&usb_2 { ++ status = "okay"; ++}; ++ ++&usb_2_dwc3 { ++ dr_mode = "host"; ++}; ++ ++&usb_2_hsphy { ++ status = "okay"; ++ ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++}; ++ ++&usb_2_qmpphy { ++ status = "okay"; ++ ++ vdda-phy-supply = <&vreg_l9a_1p2>; ++ vdda-pll-supply = <&vreg_l18a_0p92>; ++}; ++ ++&venus { ++ firmware-name = "postmarketos/venus.mbn"; ++ status = "okay"; ++}; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0012-arm64-dts-qcom-sm8250-xiaomi-elish-remove-framebuffe.patch b/patch/kernel/archive/sm8250-6.18/0012-arm64-dts-qcom-sm8250-xiaomi-elish-remove-framebuffe.patch new file mode 100644 index 000000000000..9e2a69cda3da --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0012-arm64-dts-qcom-sm8250-xiaomi-elish-remove-framebuffe.patch @@ -0,0 +1,52 @@ +From 412b5fb6887b946382f4cfeb7a38feee685c589b Mon Sep 17 00:00:00 2001 +From: Jianhua Lu +Date: Mon, 11 Mar 2024 23:27:42 +0800 +Subject: [PATCH 12/62] arm64: dts: qcom: sm8250-xiaomi-elish: remove + framebuffer initialized by xbl + +Signed-off-by: Jiali Chen +--- + .../dts/qcom/sm8250-xiaomi-elish-common.dtsi | 20 ------------------- + 1 file changed, 20 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +index 4c99b9f9f6fe..c70dab6e9dd3 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi +@@ -36,21 +36,6 @@ aliases { + serial0 = &uart6; + }; + +- chosen { +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; +- +- framebuffer: framebuffer@9c000000 { +- compatible = "simple-framebuffer"; +- reg = <0x0 0x9c000000 0x0 0x2300000>; +- width = <1600>; +- height = <2560>; +- stride = <(1600 * 4)>; +- format = "a8r8g8b8"; +- }; +- }; +- + battery_l: battery-l { + compatible = "simple-battery"; + voltage-min-design-microvolt = <3870000>; +@@ -207,11 +192,6 @@ cdsp_secure_heap: cdsp-secure-heap@8e100000 { + no-map; + }; + +- cont_splash_mem: cont-splash@9c000000 { +- reg = <0x0 0x9c000000 0x0 0x2300000>; +- no-map; +- }; +- + ramoops@b0000000 { + compatible = "ramoops"; + reg = <0x0 0xb0000000 0x0 0x400000>; +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0013-input-nt36xxx-Enable-pen-support.patch b/patch/kernel/archive/sm8250-6.18/0013-input-nt36xxx-Enable-pen-support.patch new file mode 100644 index 000000000000..b5903b60426d --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0013-input-nt36xxx-Enable-pen-support.patch @@ -0,0 +1,121 @@ +From 387061a6bda0e321f4b61bffc4710c4de988428b Mon Sep 17 00:00:00 2001 +From: map220v +Date: Tue, 28 Nov 2023 15:28:53 +0300 +Subject: [PATCH 13/62] input: nt36xxx: Enable pen support + +Signed-off-by: Jiali Chen +--- + drivers/input/touchscreen/nt36523/nt36xxx.c | 49 +++++++++++++++++-- + drivers/input/touchscreen/nt36523/nt36xxx.h | 1 + + .../touchscreen/nt36523/nt36xxx_fw_update.c | 1 + + 3 files changed, 47 insertions(+), 4 deletions(-) + +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c +index 63c584f681d7..3a87a38a7780 100644 +--- a/drivers/input/touchscreen/nt36523/nt36xxx.c ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.c +@@ -1173,6 +1173,43 @@ static int8_t nvt_ts_check_chip_ver_trim(uint32_t chip_ver_trim_addr) + return 0; + } + ++int32_t disable_pen_input_device(bool disable) { ++ uint8_t buf[8] = {0}; ++ int32_t ret = 0; ++ ++ NVT_LOG("++\n"); ++ if (!bTouchIsAwake || !ts) { ++ NVT_LOG("touch suspend, stop set pen state %s", disable ? "DISABLE" : "ENABLE"); ++ goto nvt_set_pen_enable_out; ++ } ++ ++ msleep(35); ++ disable = (!(ts->pen_input_dev_enable) || ts->pen_is_charge) ? true : disable; ++ ++ //---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_pen_enable_out; ++ } ++ ++ buf[0] = EVENT_MAP_HOST_CMD; ++ buf[1] = 0x7B; ++ buf[2] = !!disable; ++ ret = CTP_SPI_WRITE(ts->client, buf, 3); ++ if (ret < 0) { ++ NVT_ERR("set pen %s failed!\n", disable ? "DISABLE" : "ENABLE"); ++ goto nvt_set_pen_enable_out; ++ } ++ NVT_LOG("pen charge state is %s, %s pen input device\n", ++ ts->pen_is_charge ? "ENABLE" : "DISABLE", ++ disable ? "DISABLE" : "ENABLE"); ++ ++nvt_set_pen_enable_out: ++ NVT_LOG("--\n"); ++ return ret; ++} ++ + static void nvt_suspend_work(struct work_struct *work) + { + struct nvt_ts_data *ts_core = container_of(work, struct nvt_ts_data, suspend_work); +@@ -1437,11 +1474,11 @@ static int32_t nvt_ts_probe(struct spi_device *client) + init_completion(&ts->dev_pm_suspend_completion); + ts->fw_debug = false; + +-#ifdef CONFIG_FACTORY_BUILD ++//#ifdef CONFIG_FACTORY_BUILD + ts->pen_input_dev_enable = 1; +-#else +- ts->pen_input_dev_enable = 0; +-#endif ++//#else ++// ts->pen_input_dev_enable = 0; ++//#endif + + #if BOOT_UPDATE_FIRMWARE + nvt_fwu_wq = alloc_workqueue("nvt_fwu_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); +@@ -1701,6 +1738,7 @@ static int32_t nvt_ts_suspend(struct device *dev) + + if (ts->pen_input_dev_enable) { + NVT_LOG("if enable pen,will close it"); ++ disable_pen_input_device(true); + } + + if (ts->db_wakeup) { +@@ -1796,6 +1834,9 @@ static int32_t nvt_ts_resume(struct device *dev) + + bTouchIsAwake = 1; + ++ NVT_LOG("always enable pen when resume"); ++ disable_pen_input_device(false); ++ + mutex_unlock(&ts->lock); + + if (likely(ts->ic_state == NVT_IC_RESUME_IN)) { +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.h b/drivers/input/touchscreen/nt36523/nt36xxx.h +index 6642ec2f26cf..33c7614436b0 100644 +--- a/drivers/input/touchscreen/nt36523/nt36xxx.h ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.h +@@ -235,6 +235,7 @@ int32_t nvt_read_pid(void); + bool nvt_get_dbgfw_status(void); + int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); + void Boot_Update_Firmware(struct work_struct *work); ++int32_t disable_pen_input_device(bool disable); + #if NVT_TOUCH_ESD_PROTECT + extern void nvt_esd_check_enable(uint8_t enable); + #endif /* #if NVT_TOUCH_ESD_PROTECT */ +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c b/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c +index 4f383dac2c3c..71c271d8c548 100644 +--- a/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c ++++ b/drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c +@@ -851,6 +851,7 @@ void Boot_Update_Firmware(struct work_struct *work) + { + mutex_lock(&ts->lock); + nvt_update_firmware(ts->fw_name); ++ disable_pen_input_device(false); + nvt_get_fw_info(); + mutex_unlock(&ts->lock); + } +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0014-nt36xxx-add-pen-input-resolution.patch b/patch/kernel/archive/sm8250-6.18/0014-nt36xxx-add-pen-input-resolution.patch new file mode 100644 index 000000000000..22d4ac92e863 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0014-nt36xxx-add-pen-input-resolution.patch @@ -0,0 +1,59 @@ +From 46405e71f2f05860ed6e60cb56334b5150ee7e75 Mon Sep 17 00:00:00 2001 +From: Nicola Guerrera +Date: Thu, 14 Nov 2024 22:57:02 +0100 +Subject: [PATCH 14/62] nt36xxx: add pen input resolution + +Signed-off-by: Jiali Chen +--- + drivers/input/touchscreen/nt36523/nt36xxx.c | 15 +++++++++++---- + drivers/input/touchscreen/nt36523/nt36xxx.h | 4 +++- + 2 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c +index 3a87a38a7780..ea098444dc83 100644 +--- a/drivers/input/touchscreen/nt36523/nt36xxx.c ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.c +@@ -1421,14 +1421,21 @@ static int32_t nvt_ts_probe(struct spi_device *client) + ts->pen_input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2); + ts->pen_input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT); + ++ int x_max, y_max; ++ + if (ts->wgp_stylus) { +- input_set_abs_params(ts->pen_input_dev, ABS_X, 0, ts->abs_x_max * 2 - 1, 0, 0); +- input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, ts->abs_y_max * 2 - 1, 0, 0); ++ x_max = ts->abs_x_max * 2 - 1; ++ y_max = ts->abs_y_max * 2 - 1; + } else { +- input_set_abs_params(ts->pen_input_dev, ABS_X, 0, ts->abs_x_max - 1, 0, 0); +- input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, ts->abs_y_max - 1, 0, 0); ++ x_max = ts->abs_x_max - 1; ++ y_max = ts->abs_y_max - 1; + } + ++ input_set_abs_params(ts->pen_input_dev, ABS_X, 0, x_max, 0, 0); ++ input_set_abs_params(ts->pen_input_dev, ABS_Y, 0, y_max , 0, 0); ++ input_abs_set_res(ts->pen_input_dev, ABS_X, x_max / PANEL_DEFAULT_WIDTH_MM); ++ input_abs_set_res(ts->pen_input_dev, ABS_Y, y_max / PANEL_DEFAULT_HEIGHT_MM); ++ + input_set_abs_params(ts->pen_input_dev, ABS_PRESSURE, 0, PEN_PRESSURE_MAX, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_DISTANCE, 0, PEN_DISTANCE_MAX, 0, 0); + input_set_abs_params(ts->pen_input_dev, ABS_TILT_X, PEN_TILT_MIN, PEN_TILT_MAX, 0, 0); +diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.h b/drivers/input/touchscreen/nt36523/nt36xxx.h +index 33c7614436b0..2c6a30ecceca 100644 +--- a/drivers/input/touchscreen/nt36523/nt36xxx.h ++++ b/drivers/input/touchscreen/nt36523/nt36xxx.h +@@ -70,7 +70,9 @@ extern const uint16_t touch_key_array[TOUCH_KEY_NUM]; + #define PEN_DISTANCE_MAX (1) + #define PEN_TILT_MIN (-60) + #define PEN_TILT_MAX (60) +- ++//---for pen resolution--- ++#define PANEL_DEFAULT_WIDTH_MM 148 // 148mm ++#define PANEL_DEFAULT_HEIGHT_MM 237 // 237mm + /* Enable only when module have tp reset pin and connected to host */ + #define NVT_TOUCH_SUPPORT_HW_RST 0 + +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0015-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Restore.patch b/patch/kernel/archive/sm8250-6.18/0015-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Restore.patch new file mode 100644 index 000000000000..1f7d834e8e13 --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0015-arm64-dts-qcom-sm8250-oneplus-instantnoodlep-Restore.patch @@ -0,0 +1,218 @@ +From 3166046dba446da76f5ab6b9d790db37b8657be0 Mon Sep 17 00:00:00 2001 +From: Denys Vitali +Date: Fri, 22 Nov 2024 15:50:44 +0100 +Subject: [PATCH 15/62] arm64: dts: qcom: sm8250-oneplus-instantnoodlep: + Restore Wi-Fi / BT functionality + +Signed-off-by: Jiali Chen +--- + .../qcom/sm8250-oneplus-instantnoodlep.dts | 131 +++++++++++++++--- + 1 file changed, 110 insertions(+), 21 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts +index 2ff46c2979e5..b3b878e6cbea 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-instantnoodlep.dts +@@ -78,6 +78,67 @@ vol-down { + gpio-key,wakeup; + }; + }; ++ ++ qca6390-pmu { ++ compatible = "qcom,qca6390-pmu"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_en_state>, <&wlan_en_state>; ++ ++ vddaon-supply = <&vreg_s6a_0p95>; ++ vddpmu-supply = <&vreg_s2f_0p95>; ++ vddrfa0p95-supply = <&vreg_s2f_0p95>; ++ vddrfa1p3-supply = <&vreg_s8c_1p3>; ++ vddrfa1p9-supply = <&vreg_s5a_1p9>; ++ vddpcie1p3-supply = <&vreg_s8c_1p3>; ++ vddpcie1p9-supply = <&vreg_s5a_1p9>; ++ vddio-supply = <&vreg_s4a_1p8>; ++ ++ wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; ++ bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; ++ ++ regulators { ++ vreg_pmu_rfa_cmn: ldo0 { ++ regulator-name = "vreg_pmu_rfa_cmn"; ++ }; ++ ++ vreg_pmu_aon_0p59: ldo1 { ++ regulator-name = "vreg_pmu_aon_0p59"; ++ }; ++ ++ vreg_pmu_wlcx_0p8: ldo2 { ++ regulator-name = "vreg_pmu_wlcx_0p8"; ++ }; ++ ++ vreg_pmu_wlmx_0p85: ldo3 { ++ regulator-name = "vreg_pmu_wlmx_0p85"; ++ }; ++ ++ vreg_pmu_btcmx_0p85: ldo4 { ++ regulator-name = "vreg_pmu_btcmx_0p85"; ++ }; ++ ++ vreg_pmu_rfa_0p8: ldo5 { ++ regulator-name = "vreg_pmu_rfa_0p8"; ++ }; ++ ++ vreg_pmu_rfa_1p2: ldo6 { ++ regulator-name = "vreg_pmu_rfa_1p2"; ++ }; ++ ++ vreg_pmu_rfa_1p7: ldo7 { ++ regulator-name = "vreg_pmu_rfa_1p7"; ++ }; ++ ++ vreg_pmu_pcie_0p9: ldo8 { ++ regulator-name = "vreg_pmu_pcie_0p9"; ++ }; ++ ++ vreg_pmu_pcie_1p8: ldo9 { ++ regulator-name = "vreg_pmu_pcie_1p8"; ++ }; ++ }; ++ }; + + reserved-memory { + removed_mem: memory@80b00000 { +@@ -192,7 +253,7 @@ vreg_s4a_1p8: vreg-s4a-1p8 { + qca639x: qca639x { + compatible = "qcom,qca6390"; + #power-domain-cells = <0>; +- ++ + vddaon-supply = <&vreg_s6a_0p95>; + vddpmu-supply = <&vreg_s2f_0p95>; + vddrfa1-supply = <&vreg_s2f_0p95>; +@@ -203,9 +264,9 @@ qca639x: qca639x { + vddio-supply = <&vreg_s4a_1p8>; + + pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&wlan_en_active>; ++ pinctrl-0 = <&wlan_en_state>; + pinctrl-1 = <&wlan_en_sleep>; +- ++ + wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; + }; + +@@ -390,6 +451,7 @@ vreg_s5a_1p9: smps5 { + regulator-initial-mode = ; + }; + ++ + vreg_s6a_0p95: smps6 { + regulator-name = "vreg_s6a_0p95"; + regulator-min-microvolt = <920000>; +@@ -614,15 +676,32 @@ &slpi { + status = "okay"; + }; + ++ + &pcie0 { + status = "okay"; + }; + + &pcie0_phy { ++ status = "okay"; + vdda-phy-supply = <&vreg_l5a_0p88>; + vdda-pll-supply = <&vreg_l9a_1p2>; +- status = "okay"; +- power-domains = <&qca639x>; ++}; ++ ++&pcieport0 { ++ wifi@0 { ++ compatible = "pci17cb,1101"; ++ reg = <0x10000 0x0 0x0 0x0 0x0>; ++ ++ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; ++ vddaon-supply = <&vreg_pmu_aon_0p59>; ++ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; ++ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; ++ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; ++ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; ++ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; ++ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; ++ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; ++ }; + }; + + &pcie1 { +@@ -697,7 +776,7 @@ &qupv3_id_2 { + &tlmm { + gpio-reserved-ranges = <28 4>, <40 4>; + +- bt_en_active: bt-default-state { ++ bt_en_state: bt-default-state { + bt-en { + pins = "gpio21"; + function = "gpio"; +@@ -717,7 +796,7 @@ bt_en_sleep: bt-sleep-state { + bias-pull-down; + }; + +- wlan_en_active: wlan-default-state { ++ wlan_en_state: wlan-default-state { + wlan-en { + pins = "gpio20"; + function = "gpio"; +@@ -752,20 +831,6 @@ ts_rst_suspend: ts-rst-suspend { + }; + }; + +-&uart6 { +- status = "okay"; +- +- bluetooth { +- compatible = "qcom,qca6390-bt"; +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&bt_en_active>; +- pinctrl-1 = <&bt_en_sleep>; +- +- power-domains = <&qca639x>; +- enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; +- }; +-}; +- + &ufs_mem_hc { + vcc-supply = <&vreg_l17a_3p0>; + vcc-max-microamp = <800000>; +@@ -830,3 +895,27 @@ &venus { + firmware-name = "postmarketos/venus.mbn"; + status = "okay"; + }; ++ ++ ++&uart6 { ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "qcom,qca6390-bt"; ++ ++ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; ++ vddaon-supply = <&vreg_pmu_aon_0p59>; ++ vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; ++ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; ++ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; ++ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; ++ }; ++}; ++ ++&qup_i2c7_default { ++ status = "disabled"; ++}; ++ ++&qup_spi7_data_clk { ++ status = "disabled"; ++}; +\ No newline at end of file +-- +2.47.3 + diff --git a/patch/kernel/archive/sm8250-6.18/0016-drm-panel-Add-panel-driver-for-samsung-amsa26zp01.patch b/patch/kernel/archive/sm8250-6.18/0016-drm-panel-Add-panel-driver-for-samsung-amsa26zp01.patch new file mode 100644 index 000000000000..d0f4a9f2a80f --- /dev/null +++ b/patch/kernel/archive/sm8250-6.18/0016-drm-panel-Add-panel-driver-for-samsung-amsa26zp01.patch @@ -0,0 +1,359 @@ +From 39c64936606b9c3eff787195531c4f3b6cde0903 Mon Sep 17 00:00:00 2001 +From: chalkin +Date: Sat, 21 Sep 2024 18:19:35 +0800 +Subject: [PATCH 16/62] drm/panel: Add panel driver for samsung amsa26zp01 + +Signed-off-by: Jiali Chen +--- + drivers/gpu/drm/panel/Kconfig | 11 + + drivers/gpu/drm/panel/Makefile | 1 + + .../gpu/drm/panel/panel-samsung-amsa26zp01.c | 302 ++++++++++++++++++ + 3 files changed, 314 insertions(+) + create mode 100644 drivers/gpu/drm/panel/panel-samsung-amsa26zp01.c + +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 09b9f7ff9340..c6f8382b0212 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -726,6 +726,17 @@ config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 + select DRM_MIPI_DSI + select VIDEOMODE_HELPERS + ++config DRM_PANEL_SAMSUNG_AMSA26ZP01 ++ tristate "Samsung AMSA26ZP01 DSI panel" ++ depends on OF ++ depends on DRM_MIPI_DSI ++ depends on BACKLIGHT_CLASS_DEVICE ++ select DRM_DISPLAY_DP_HELPER ++ select DRM_DISPLAY_HELPER ++ help ++ DRM panel driver for the Samsung AMSA26ZP01 panel. ++ This panel has a resolution of 2560x1600 @ 60hz or 120Hz. ++ + config DRM_PANEL_SAMSUNG_ATNA33XC20 + tristate "Samsung ATNA33XC20 eDP panel" + depends on OF +diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile +index 957555b49996..f297fc90f99e 100644 +--- a/drivers/gpu/drm/panel/Makefile ++++ b/drivers/gpu/drm/panel/Makefile +@@ -71,6 +71,7 @@ obj-$(CONFIG_DRM_PANEL_RENESAS_R69328) += panel-renesas-r69328.o + obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01) += panel-samsung-ams581vf01.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08) += panel-samsung-ams639rq08.o ++obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMSA26ZP01) += panel-samsung-amsa26zp01.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o +diff --git a/drivers/gpu/drm/panel/panel-samsung-amsa26zp01.c b/drivers/gpu/drm/panel/panel-samsung-amsa26zp01.c +new file mode 100644 +index 000000000000..8fe62ff43909 +--- /dev/null ++++ b/drivers/gpu/drm/panel/panel-samsung-amsa26zp01.c +@@ -0,0 +1,302 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: ++// Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. ++// Copyright (c) 2024 chalkin Deng ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include