diff --git a/patch/kernel/archive/sm8250-6.5/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch b/patch/kernel/archive/sm8250-6.5/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch deleted file mode 100644 index 8701076f42a6..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 04:52:34 +0300 -Subject: drm/msm/dpu1: improve support for active CTLs - -- Support setting master interface if several INTFs are to be handled by - a single CTL - -- Support setting handling several MERGE_3D instances using a single - CTL. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 15 ++++++++++ - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ - 2 files changed, 17 insertions(+) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -index 86182c734606..4ecffbcdba20 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -@@ -510,6 +510,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, - u32 intf_active = 0; - u32 wb_active = 0; - u32 mode_sel = 0; -+ u32 merge_3d_active = 0; - - /* CTL_TOP[31:28] carries group_id to collate CTL paths - * per VM. Explicitly disable it until VM support is -@@ -530,16 +531,30 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, - if (cfg->wb) - wb_active |= BIT(cfg->wb - WB_0); - -+ merge_3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE); -+ if (cfg->merge_3d) -+ merge_3d_active |= BIT(cfg->merge_3d - MERGE_3D_0); -+ - DPU_REG_WRITE(c, CTL_TOP, mode_sel); - DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); - DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); - -+ if (cfg->intf_master) -+ DPU_REG_WRITE(c, CTL_INTF_MASTER, BIT(cfg->intf_master - INTF_0)); -+ - if (cfg->merge_3d) - DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, - BIT(cfg->merge_3d - MERGE_3D_0)); - - if (cfg->dsc) - DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); -+ if (cfg->merge_3d) -+ DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active); -+ -+ if (cfg->intf_master) -+ DPU_DEBUG_DRIVER("ACTIVE: %x %x %lx\n", intf_active, merge_3d_active, BIT(cfg->intf_master - INTF_0)); -+ else -+ DPU_DEBUG_DRIVER("ACTIVE: %x %x\n", intf_active, merge_3d_active); - } - - static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -index 1c242298ff2e..36dd4e91a0b4 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -@@ -36,6 +36,7 @@ struct dpu_hw_stage_cfg { - /** - * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface - * @intf : Interface id -+ * @intf_master: Master interface id in the dual pipe topology - * @mode_3d: 3d mux configuration - * @merge_3d: 3d merge block used - * @intf_mode_sel: Interface mode, cmd / vid -@@ -44,6 +45,7 @@ struct dpu_hw_stage_cfg { - */ - struct dpu_hw_intf_cfg { - enum dpu_intf intf; -+ enum dpu_intf intf_master; - enum dpu_wb wb; - enum dpu_3d_blend_mode mode_3d; - enum dpu_merge_3d merge_3d; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch b/patch/kernel/archive/sm8250-6.5/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch deleted file mode 100644 index d12843f09b56..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 04:58:32 +0300 -Subject: drm/msm/dpu1: use one active CTL if it is available - -Unlike previous generation, with newer ("active") CTLs it is possible to -use just one CTL to handle both interfaces. And one has to use single -CTL to support master/slave DSI config. So use one active CTL if it is -available. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 8 ++++-- - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 14 +++++++--- - drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 1 + - 6 files changed, 20 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -index 4589b7a04399..e81230fe6895 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -@@ -15,6 +15,7 @@ static const struct dpu_caps sm8150_dpu_caps = { - .has_dim_layer = true, - .has_idle_pc = true, - .has_3d_merge = true, -+ .has_active_ctls = true, - .max_linewidth = 4096, - .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, - .max_hdeci_exp = MAX_HORZ_DECIMATION, -diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -index 0e17be6ed94f..04e85889c6ec 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -@@ -15,6 +15,7 @@ static const struct dpu_caps sm8250_dpu_caps = { - .has_dim_layer = true, - .has_idle_pc = true, - .has_3d_merge = true, -+ .has_active_ctls = true, - .max_linewidth = 4096, - .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, - }; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -index 493905a5b63a..2e3c767d9427 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -@@ -1107,14 +1107,18 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, - return; - } - -- if (!hw_ctl[i]) { -+ /* Use first (and only) CTL if active CTLs are supported */ -+ if (dpu_kms->catalog->caps->has_active_ctls) -+ phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[0]); -+ else -+ phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); -+ if (!phys->hw_ctl) { - DPU_ERROR_ENC(dpu_enc, - "no ctl block assigned at idx: %d\n", i); - return; - } - - phys->hw_pp = dpu_enc->hw_pp[i]; -- phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - - phys->cached_mode = crtc_state->adjusted_mode; - if (phys->ops.atomic_mode_set) -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -index b860784ade72..0a290add46ad 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -@@ -382,6 +382,7 @@ struct dpu_caps { - bool has_dim_layer; - bool has_idle_pc; - bool has_3d_merge; -+ bool has_active_ctls; - /* SSPP limits */ - u32 max_linewidth; - u32 pixel_ram_size; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -index 471842bbb950..978d03e4988e 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -@@ -195,6 +195,7 @@ int dpu_rm_init(struct dpu_rm *rm, - } - rm->ctl_blks[ctl->id - CTL_0] = &hw->base; - } -+ rm->has_active_ctls = cat->caps->has_active_ctls; - - for (i = 0; i < cat->dspp_count; i++) { - struct dpu_hw_dspp *hw; -@@ -427,10 +428,15 @@ static int _dpu_rm_reserve_ctls( - int i = 0, j, num_ctls; - bool needs_split_display; - -- /* each hw_intf needs its own hw_ctrl to program its control path */ -- num_ctls = top->num_intf; -+ if (rm->has_active_ctls) { -+ num_ctls = 1; -+ needs_split_display = false; -+ } else { -+ /* each hw_intf needs its own hw_ctrl to program its control path */ -+ num_ctls = top->num_intf; - -- needs_split_display = _dpu_rm_needs_split_display(top); -+ needs_split_display = _dpu_rm_needs_split_display(top); -+ } - - for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) { - const struct dpu_hw_ctl *ctl; -@@ -448,7 +454,7 @@ static int _dpu_rm_reserve_ctls( - - DPU_DEBUG("ctl %d caps 0x%lX\n", j + CTL_0, features); - -- if (needs_split_display != has_split_display) -+ if (!rm->has_active_ctls && needs_split_display != has_split_display) - continue; - - ctl_idx[i] = j; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -index d62c2edb2460..d1b55482b8b1 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -@@ -33,6 +33,7 @@ struct dpu_rm { - struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; - struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; - struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE]; -+ bool has_active_ctls; - }; - - /** --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch b/patch/kernel/archive/sm8250-6.5/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch deleted file mode 100644 index e4d4c1bfb4f8..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 05:03:35 +0300 -Subject: drm/msm/dpu1: dpu_encoder_phys_*: proper suppor for active CTLs - -Adapt dpu_encoder_phys_* to properly support active CTLs and their -features. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 5 ++++- - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -index b856c6286c85..c821b6a53b12 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -@@ -56,6 +56,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( - return; - - intf_cfg.intf = phys_enc->hw_intf->idx; -+ if (phys_enc->split_role == ENC_ROLE_MASTER) -+ intf_cfg.intf_master = phys_enc->hw_intf->idx; - intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; - intf_cfg.stream_sel = cmd_enc->stream_sel; - intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -index 662d74ded1b9..a379d0e3a3f7 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -@@ -271,6 +271,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine( - DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); - - intf_cfg.intf = phys_enc->hw_intf->idx; -+ if (phys_enc->split_role == ENC_ROLE_MASTER) -+ intf_cfg.intf_master = phys_enc->hw_intf->idx; - intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; - intf_cfg.stream_sel = 0; /* Don't care value for video mode */ - intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); -@@ -344,7 +346,8 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx) - static bool dpu_encoder_phys_vid_needs_single_flush( - struct dpu_encoder_phys *phys_enc) - { -- return phys_enc->split_role != ENC_ROLE_SOLO; -+ return !(phys_enc->hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG)) && -+ phys_enc->split_role != ENC_ROLE_SOLO; - } - - static void dpu_encoder_phys_vid_atomic_mode_set( --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch b/patch/kernel/archive/sm8250-6.5/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch deleted file mode 100644 index 5a17b7e1029c..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 20 Dec 2020 18:47:57 +0300 -Subject: dt-bindings: mfd: qcom,qca639x: add binding for QCA639x defvice - -Qualcomm QCA639x is a family of WiFi + Bluetooth SoCs, with BT part -being controlled through the UART and WiFi being present on PCIe bus. -Both blocks share common power sources. Add binding to describe power -sequencing required to power up this device. - -Signed-off-by: Dmitry Baryshkov ---- - Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml | 84 ++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml b/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml -new file mode 100644 -index 000000000000..d43c75da136f ---- /dev/null -+++ b/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml -@@ -0,0 +1,84 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: "http://devicetree.org/schemas/mfd/qcom,qca639x.yaml#" -+$schema: "http://devicetree.org/meta-schemas/core.yaml#" -+ -+title: Qualcomm QCA639x WiFi + Bluetoot SoC bindings -+ -+maintainers: -+ - Andy Gross -+ - Bjorn Andersson -+ -+description: | -+ This binding describes thes Qualcomm QCA6390 or QCA6391 power supplies and -+ enablement pins. -+ -+properties: -+ compatible: -+ const: qcom,qca639x -+ -+ '#power-domain-cells': -+ const: 0 -+ -+ pinctrl-0: true -+ pinctrl-1: true -+ -+ pinctrl-names: -+ items: -+ - const: default -+ - const: active -+ -+ vddaon-supply: -+ description: -+ 0.95V always-on LDO power input -+ -+ vddpmu-supply: -+ description: -+ 0.95V LDO power input to PMU -+ -+ vddrfa1-supply: -+ description: -+ 0.95V LDO power input to RFA -+ -+ vddrfa2-supply: -+ description: -+ 1.25V LDO power input to RFA -+ -+ vddrfa3-supply: -+ description: -+ 2V LDO power input to RFA -+ -+ vddpcie1-supply: -+ description: -+ 1.25V LDO power input to PCIe part -+ -+ vddpcie2-supply: -+ description: -+ 2V LDO power input to PCIe part -+ -+ vddio-supply: -+ description: -+ 1.8V VIO input -+ -+additionalProperties: false -+ -+examples: -+ - | -+ qca639x: qca639x { -+ compatible = "qcom,qca639x"; -+ #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", "active"; -+ pinctrl-0 = <&wlan_default_state &bt_default_state>; -+ pinctrl-1 = <&wlan_active_state &bt_active_state>; -+ }; -+... --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch b/patch/kernel/archive/sm8250-6.5/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch deleted file mode 100644 index a519dc117691..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Fri, 18 Dec 2020 16:24:56 +0300 -Subject: mfd: qca639x: add support for QCA639x powerup sequence - -Qualcomm QCA639x is a family of WiFi + Bluetooth SoCs, with BT part -being controlled through the UART and WiFi being present on PCIe -bus. Both blocks share common power sources. So add mfd device driver -handling power sequencing of QCA6390/1. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/Kconfig | 12 + - drivers/mfd/Makefile | 1 + - drivers/mfd/qcom-qca639x.c | 162 ++++++++++ - 3 files changed, 175 insertions(+) - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index f6b519eaaa71..eda2ae2ac764 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -1099,6 +1099,18 @@ config MFD_PM8XXX - Say M here if you want to include support for PM8xxx chips as a - module. This will build a module called "pm8xxx-core". - -+config MFD_QCOM_QCA639X -+ tristate "Qualcomm QCA639x WiFi/Bluetooth module support" -+ depends on REGULATOR && PM_GENERIC_DOMAINS -+ help -+ If you say yes to this option, support will be included for Qualcomm -+ QCA639x family of WiFi and Bluetooth SoCs. Note, this driver supports -+ only power control for this SoC, you still have to enable individual -+ Bluetooth and WiFi drivers. -+ -+ Say M here if you want to include support for QCA639x chips as a -+ module. This will build a module called "qcom-qca639x". -+ - config MFD_QCOM_RPM - tristate "Qualcomm Resource Power Manager (RPM)" - depends on ARCH_QCOM && OF -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index f3d1f1dc73b5..954bb5f992ae 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -201,6 +201,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o - obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o - obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o - obj-$(CONFIG_MFD_PM8XXX) += qcom-pm8xxx.o ssbi.o -+obj-$(CONFIG_MFD_QCOM_QCA639X) += qcom-qca639x.o - obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o - obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o - obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -new file mode 100644 -index 000000000000..b31e4b65bec5 ---- /dev/null -+++ b/drivers/mfd/qcom-qca639x.c -@@ -0,0 +1,162 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_NUM_REGULATORS 8 -+ -+static struct vreg { -+ const char *name; -+ unsigned int load_uA; -+} vregs [MAX_NUM_REGULATORS] = { -+ /* 2.0 V */ -+ { "vddpcie2", 15000 }, -+ { "vddrfa3", 400000 }, -+ -+ /* 0.95 V */ -+ { "vddaon", 100000 }, -+ { "vddpmu", 1250000 }, -+ { "vddrfa1", 200000 }, -+ -+ /* 1.35 V */ -+ { "vddrfa2", 400000 }, -+ { "vddpcie1", 35000 }, -+ -+ /* 1.8 V */ -+ { "vddio", 20000 }, -+}; -+ -+struct qca639x_data { -+ struct regulator_bulk_data regulators[MAX_NUM_REGULATORS]; -+ size_t num_vregs; -+ struct device *dev; -+ struct pinctrl_state *active_state; -+ struct generic_pm_domain pd; -+}; -+ -+#define domain_to_data(domain) container_of(domain, struct qca639x_data, pd) -+ -+static int qca639x_power_on(struct generic_pm_domain *domain) -+{ -+ struct qca639x_data *data = domain_to_data(domain); -+ int ret; -+ -+ dev_warn(&domain->dev, "DUMMY POWER ON\n"); -+ -+ ret = regulator_bulk_enable(data->num_vregs, data->regulators); -+ if (ret) { -+ dev_err(data->dev, "Failed to enable regulators"); -+ return ret; -+ } -+ -+ /* Wait for 1ms before toggling enable pins. */ -+ msleep(1); -+ -+ ret = pinctrl_select_state(data->dev->pins->p, data->active_state); -+ if (ret) { -+ dev_err(data->dev, "Failed to select active state"); -+ return ret; -+ } -+ -+ /* Wait for all power levels to stabilize */ -+ msleep(6); -+ -+ return 0; -+} -+ -+static int qca639x_power_off(struct generic_pm_domain *domain) -+{ -+ struct qca639x_data *data = domain_to_data(domain); -+ -+ dev_warn(&domain->dev, "DUMMY POWER OFF\n"); -+ -+ pinctrl_select_default_state(data->dev); -+ regulator_bulk_disable(data->num_vregs, data->regulators); -+ -+ return 0; -+} -+ -+static int qca639x_probe(struct platform_device *pdev) -+{ -+ struct qca639x_data *data; -+ struct device *dev = &pdev->dev; -+ int i, ret; -+ -+ if (!dev->pins || IS_ERR_OR_NULL(dev->pins->default_state)) -+ return -EINVAL; -+ -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->dev = dev; -+ data->num_vregs = ARRAY_SIZE(vregs); -+ -+ data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); -+ if (IS_ERR(data->active_state)) { -+ ret = PTR_ERR(data->active_state); -+ dev_err(dev, "Failed to get active_state: %d\n", ret); -+ return ret; -+ } -+ -+ for (i = 0; i < data->num_vregs; i++) -+ data->regulators[i].supply = vregs[i].name; -+ ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); -+ if (ret < 0) -+ return ret; -+ -+ for (i = 0; i < data->num_vregs; i++) { -+ ret = regulator_set_load(data->regulators[i].consumer, vregs[i].load_uA); -+ if (ret) -+ return ret; -+ } -+ -+ data->pd.name = dev_name(dev); -+ data->pd.power_on = qca639x_power_on; -+ data->pd.power_off = qca639x_power_off; -+ -+ ret = pm_genpd_init(&data->pd, NULL, true); -+ if (ret < 0) -+ return ret; -+ -+ ret = of_genpd_add_provider_simple(dev->of_node, &data->pd); -+ if (ret < 0) { -+ pm_genpd_remove(&data->pd); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, data); -+ -+ return 0; -+} -+ -+static int qca639x_remove(struct platform_device *pdev) -+{ -+ struct qca639x_data *data = platform_get_drvdata(pdev); -+ -+ pm_genpd_remove(&data->pd); -+ -+ return 0; -+} -+ -+static const struct of_device_id qca639x_of_match[] = { -+ { .compatible = "qcom,qca639x" }, -+}; -+ -+static struct platform_driver qca639x_driver = { -+ .probe = qca639x_probe, -+ .remove = qca639x_remove, -+ .driver = { -+ .name = "qca639x", -+ .of_match_table = qca639x_of_match, -+ }, -+}; -+ -+module_platform_driver(qca639x_driver); -+MODULE_LICENSE("GPL v2"); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch b/patch/kernel/archive/sm8250-6.5/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch deleted file mode 100644 index 3d795fec064a..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 21:13:18 +0300 -Subject: mfd: qcom-qca639x: switch to platform config data - -Change qcom-qca639x to use platform config data, in preparation to -supporting other devices. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/qcom-qca639x.c | 74 ++++++---- - 1 file changed, 46 insertions(+), 28 deletions(-) - -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -index b31e4b65bec5..22792561dbad 100644 ---- a/drivers/mfd/qcom-qca639x.c -+++ b/drivers/mfd/qcom-qca639x.c -@@ -1,4 +1,5 @@ - #include -+#include - #include - #include - #include -@@ -6,15 +7,21 @@ - #include - #include - #include -+#include - #include - #include - --#define MAX_NUM_REGULATORS 8 -- --static struct vreg { -+struct vreg { - const char *name; - unsigned int load_uA; --} vregs [MAX_NUM_REGULATORS] = { -+}; -+ -+struct qca_cfg_data { -+ const struct vreg *vregs; -+ size_t num_vregs; -+}; -+ -+static const struct vreg qca6390_vregs[] = { - /* 2.0 V */ - { "vddpcie2", 15000 }, - { "vddrfa3", 400000 }, -@@ -32,19 +39,24 @@ static struct vreg { - { "vddio", 20000 }, - }; - --struct qca639x_data { -- struct regulator_bulk_data regulators[MAX_NUM_REGULATORS]; -+static const struct qca_cfg_data qca6390_cfg_data = { -+ .vregs = qca6390_vregs, -+ .num_vregs = ARRAY_SIZE(qca6390_vregs), -+}; -+ -+struct qca_data { - size_t num_vregs; - struct device *dev; - struct pinctrl_state *active_state; - struct generic_pm_domain pd; -+ struct regulator_bulk_data regulators[]; - }; - --#define domain_to_data(domain) container_of(domain, struct qca639x_data, pd) -+#define domain_to_data(domain) container_of(domain, struct qca_data, pd) - --static int qca639x_power_on(struct generic_pm_domain *domain) -+static int qca_power_on(struct generic_pm_domain *domain) - { -- struct qca639x_data *data = domain_to_data(domain); -+ struct qca_data *data = domain_to_data(domain); - int ret; - - dev_warn(&domain->dev, "DUMMY POWER ON\n"); -@@ -70,9 +82,9 @@ static int qca639x_power_on(struct generic_pm_domain *domain) - return 0; - } - --static int qca639x_power_off(struct generic_pm_domain *domain) -+static int qca_power_off(struct generic_pm_domain *domain) - { -- struct qca639x_data *data = domain_to_data(domain); -+ struct qca_data *data = domain_to_data(domain); - - dev_warn(&domain->dev, "DUMMY POWER OFF\n"); - -@@ -82,21 +94,26 @@ static int qca639x_power_off(struct generic_pm_domain *domain) - return 0; - } - --static int qca639x_probe(struct platform_device *pdev) -+static int qca_probe(struct platform_device *pdev) - { -- struct qca639x_data *data; -+ const struct qca_cfg_data *cfg; -+ struct qca_data *data; - struct device *dev = &pdev->dev; - int i, ret; - -+ cfg = device_get_match_data(&pdev->dev); -+ if (!cfg) -+ return -EINVAL; -+ - if (!dev->pins || IS_ERR_OR_NULL(dev->pins->default_state)) - return -EINVAL; - -- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ data = devm_kzalloc(dev, struct_size(data, regulators, cfg->num_vregs), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->dev = dev; -- data->num_vregs = ARRAY_SIZE(vregs); -+ data->num_vregs = cfg->num_vregs; - - data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); - if (IS_ERR(data->active_state)) { -@@ -106,20 +123,20 @@ static int qca639x_probe(struct platform_device *pdev) - } - - for (i = 0; i < data->num_vregs; i++) -- data->regulators[i].supply = vregs[i].name; -+ data->regulators[i].supply = cfg->vregs[i].name; - ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); - if (ret < 0) - return ret; - - for (i = 0; i < data->num_vregs; i++) { -- ret = regulator_set_load(data->regulators[i].consumer, vregs[i].load_uA); -+ ret = regulator_set_load(data->regulators[i].consumer, cfg->vregs[i].load_uA); - if (ret) - return ret; - } - - data->pd.name = dev_name(dev); -- data->pd.power_on = qca639x_power_on; -- data->pd.power_off = qca639x_power_off; -+ data->pd.power_on = qca_power_on; -+ data->pd.power_off = qca_power_off; - - ret = pm_genpd_init(&data->pd, NULL, true); - if (ret < 0) -@@ -136,27 +153,28 @@ static int qca639x_probe(struct platform_device *pdev) - return 0; - } - --static int qca639x_remove(struct platform_device *pdev) -+static int qca_remove(struct platform_device *pdev) - { -- struct qca639x_data *data = platform_get_drvdata(pdev); -+ struct qca_data *data = platform_get_drvdata(pdev); - - pm_genpd_remove(&data->pd); - - return 0; - } - --static const struct of_device_id qca639x_of_match[] = { -- { .compatible = "qcom,qca639x" }, -+static const struct of_device_id qca_of_match[] = { -+ { .compatible = "qcom,qca6390", .data = &qca6390_cfg_data }, -+ { }, - }; - --static struct platform_driver qca639x_driver = { -- .probe = qca639x_probe, -- .remove = qca639x_remove, -+static struct platform_driver qca_driver = { -+ .probe = qca_probe, -+ .remove = qca_remove, - .driver = { - .name = "qca639x", -- .of_match_table = qca639x_of_match, -+ .of_match_table = qca_of_match, - }, - }; - --module_platform_driver(qca639x_driver); -+module_platform_driver(qca_driver); - MODULE_LICENSE("GPL v2"); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch b/patch/kernel/archive/sm8250-6.5/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch deleted file mode 100644 index 2570a84bde28..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 21:17:22 +0300 -Subject: mfd: qcom-qca639x: change qca639x to use gpios rather than pinctrl - -Use gpio interface instead of pinctrl interface to toggle enable pins. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/qcom-qca639x.c | 33 ++++++---- - 1 file changed, 19 insertions(+), 14 deletions(-) - -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -index 22792561dbad..4de860e9bbd0 100644 ---- a/drivers/mfd/qcom-qca639x.c -+++ b/drivers/mfd/qcom-qca639x.c -@@ -47,8 +47,9 @@ static const struct qca_cfg_data qca6390_cfg_data = { - struct qca_data { - size_t num_vregs; - struct device *dev; -- struct pinctrl_state *active_state; - struct generic_pm_domain pd; -+ struct gpio_desc *wlan_en_gpio; -+ struct gpio_desc *bt_en_gpio; - struct regulator_bulk_data regulators[]; - }; - -@@ -70,11 +71,10 @@ static int qca_power_on(struct generic_pm_domain *domain) - /* Wait for 1ms before toggling enable pins. */ - msleep(1); - -- ret = pinctrl_select_state(data->dev->pins->p, data->active_state); -- if (ret) { -- dev_err(data->dev, "Failed to select active state"); -- return ret; -- } -+ if (data->wlan_en_gpio) -+ gpiod_set_value(data->wlan_en_gpio, 1); -+ if (data->bt_en_gpio) -+ gpiod_set_value(data->bt_en_gpio, 1); - - /* Wait for all power levels to stabilize */ - msleep(6); -@@ -88,7 +88,11 @@ static int qca_power_off(struct generic_pm_domain *domain) - - dev_warn(&domain->dev, "DUMMY POWER OFF\n"); - -- pinctrl_select_default_state(data->dev); -+ if (data->wlan_en_gpio) -+ gpiod_set_value(data->wlan_en_gpio, 0); -+ if (data->bt_en_gpio) -+ gpiod_set_value(data->bt_en_gpio, 0); -+ - regulator_bulk_disable(data->num_vregs, data->regulators); - - return 0; -@@ -115,13 +119,6 @@ static int qca_probe(struct platform_device *pdev) - data->dev = dev; - data->num_vregs = cfg->num_vregs; - -- data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); -- if (IS_ERR(data->active_state)) { -- ret = PTR_ERR(data->active_state); -- dev_err(dev, "Failed to get active_state: %d\n", ret); -- return ret; -- } -- - for (i = 0; i < data->num_vregs; i++) - data->regulators[i].supply = cfg->vregs[i].name; - ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); -@@ -134,6 +131,14 @@ static int qca_probe(struct platform_device *pdev) - return ret; - } - -+ data->wlan_en_gpio = devm_gpiod_get_optional(&pdev->dev, "wlan-en", GPIOD_OUT_LOW); -+ if (IS_ERR(data->wlan_en_gpio)) -+ return PTR_ERR(data->wlan_en_gpio); -+ -+ data->bt_en_gpio = devm_gpiod_get_optional(&pdev->dev, "bt-en", GPIOD_OUT_LOW); -+ if (IS_ERR(data->bt_en_gpio)) -+ return PTR_ERR(data->bt_en_gpio); -+ - data->pd.name = dev_name(dev); - data->pd.power_on = qca_power_on; - data->pd.power_off = qca_power_off; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch b/patch/kernel/archive/sm8250-6.5/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch deleted file mode 100644 index 447f91fc77f1..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 23:07:54 +0300 -Subject: Bluetooth: hci_qca: reopen serial port after toggling power - -Reopen the serial port after toggling the power. This saves us from -getting command timeouts on first command submitted. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/bluetooth/hci_qca.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c -index e30c979535b1..0c2a182bed3c 100644 ---- a/drivers/bluetooth/hci_qca.c -+++ b/drivers/bluetooth/hci_qca.c -@@ -1699,6 +1699,8 @@ static int qca_power_on(struct hci_dev *hdev) - gpiod_set_value_cansleep(qcadev->bt_en, 1); - /* Controller needs time to bootup. */ - msleep(150); -+ serdev_device_close(hu->serdev); -+ ret = serdev_device_open(hu->serdev); - } - } - --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0009-drm-Add-drm-notifier-support.patch b/patch/kernel/archive/sm8250-6.5/0009-drm-Add-drm-notifier-support.patch deleted file mode 100644 index 4b05ac6fce40..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0009-drm-Add-drm-notifier-support.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Thu, 4 Aug 2022 13:26:53 +0800 -Subject: drm: Add drm notifier support - ---- - drivers/gpu/drm/Makefile | 3 +- - drivers/gpu/drm/drm_notifier.c | 57 ++++++++++ - include/drm/drm_notifier.h | 37 ++++++ - 3 files changed, 96 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile -index 7a09a89b493b..8e18dbb6986c 100644 ---- a/drivers/gpu/drm/Makefile -+++ b/drivers/gpu/drm/Makefile -@@ -45,7 +45,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_LEGACY) += \ - drm_agpsupport.o \ - drm_bufs.o \ -diff --git a/drivers/gpu/drm/drm_notifier.c b/drivers/gpu/drm/drm_notifier.c -new file mode 100644 -index 000000000000..792069640ea7 ---- /dev/null -+++ b/drivers/gpu/drm/drm_notifier.c -@@ -0,0 +1,57 @@ -+/* -+ * 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 -+ -+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); -\ No newline at end of file -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 */ --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch b/patch/kernel/archive/sm8250-6.5/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch deleted file mode 100644 index ec52243de5ca..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 17 Oct 2022 08:02:58 +0800 -Subject: drm: dsi: emit panel turn on/off signal to touchscreen - ---- - 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 28b8012a21f2..f9d05c711c2f 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 -@@ -303,6 +304,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); - if (!msm_dsi_device_connected(msm_dsi)) -@@ -318,6 +320,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); -@@ -361,12 +366,16 @@ 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); - - if (!msm_dsi_device_connected(msm_dsi)) - return; - -+ 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 --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0011-Input-Add-nt36523-touchscreen-driver.patch b/patch/kernel/archive/sm8250-6.5/0011-Input-Add-nt36523-touchscreen-driver.patch deleted file mode 100644 index a0c02f0bd248..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0011-Input-Add-nt36523-touchscreen-driver.patch +++ /dev/null @@ -1,3491 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Thu, 4 Aug 2022 13:26:26 +0800 -Subject: Input: Add nt36523 touchscreen driver - ---- - 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 | 1908 ++++++++++ - drivers/input/touchscreen/nt36523/nt36xxx.h | 240 ++ - drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c | 857 +++++ - drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h | 390 ++ - 8 files changed, 3417 insertions(+) - -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index c2cbd332af1d..5bc85a3c7bb8 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 159cd5136fdb..9b99430d79d6 100644 ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -117,3 +117,4 @@ obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o - obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.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..45500ad5cd91 ---- /dev/null -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.c -@@ -0,0 +1,1908 @@ -+/* -+ * 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->master->flags & SPI_MASTER_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 }, -+ { } -+}; -+ -+#ifdef CONFIG_OF -+static struct of_device_id nvt_match_table[] = { -+ { .compatible = "novatek,NVT-ts-spi",}, -+ { }, -+}; -+#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..2ec9ccb3b522 ---- /dev/null -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.h -@@ -0,0 +1,240 @@ -+/* -+ * 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" -+ -+#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); -+bool nvt_get_dbgfw_status(void); -+int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); -+#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} -+}; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch b/patch/kernel/archive/sm8250-6.5/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch deleted file mode 100644 index 72574393e321..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 6 Mar 2023 23:13:06 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: enable wifi and bluetooth - -Signed-off-by: Jianhua Lu ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 61 ++++++++++ - 1 file changed, 61 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 b841ea9192ae..f857fa8c1f2a 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -29,6 +29,10 @@ / { - qcom,msm-id = ; /* SM8250 v2.1 */ - qcom,board-id = <0x10008 0>; - -+ aliases { -+ hsuart0 = &uart6; -+ }; -+ - chosen { - #address-cells = <2>; - #size-cells = <2>; -@@ -113,6 +117,25 @@ vreg_s6c_0p88: smpc6-regulator { - vin-supply = <&vph_pwr>; - }; - -+ qca639x: qca639x { -+ compatible = "qcom,qca6390"; -+ #power-domain-cells = <0>; -+ -+ vddaon-supply = <&vreg_s6a_0p95>; -+ vddpmu-supply = <&vreg_s6a_0p95>; -+ vddrfa1-supply = <&vreg_s6a_0p95>; -+ vddrfa2-supply = <&vreg_s8c_1p35>; -+ vddrfa3-supply = <&vreg_s5a_1p9>; -+ vddpcie1-supply = <&vreg_s8c_1p35>; -+ vddpcie2-supply = <&vreg_s5a_1p9>; -+ vddio-supply = <&vreg_s4a_1p8>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wlan_en_state>; -+ -+ wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; -+ }; -+ - reserved-memory { - xbl_aop_mem: xbl-aop@80700000 { - reg = <0x0 0x80600000 0x0 0x260000>; -@@ -615,6 +638,9 @@ &pcie0_phy { - vdda-phy-supply = <&vreg_l5a_0p88>; - vdda-pll-supply = <&vreg_l9a_1p2>; - status = "okay"; -+ -+ /* Power on QCA639x chip, otherwise PCIe bus timeouts */ -+ power-domains = <&qca639x>; - }; - - &pm8150_gpios { -@@ -655,6 +681,41 @@ &slpi { - - &tlmm { - gpio-reserved-ranges = <40 4>; -+ -+ bt_en_state: bt-default-state { -+ bt-en-pins { -+ pins = "gpio21"; -+ function = "gpio"; -+ -+ drive-strength = <16>; -+ output-low; -+ bias-pull-up; -+ }; -+ }; -+ -+ wlan_en_state: wlan-default-state { -+ wlan-en-pins { -+ pins = "gpio20"; -+ function = "gpio"; -+ -+ drive-strength = <16>; -+ output-low; -+ bias-pull-up; -+ }; -+ }; -+}; -+ -+&uart6 { -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "qcom,qca6390-bt"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_en_state>; -+ -+ power-domains = <&qca639x>; -+ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; -+ }; - }; - - &usb_1 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch b/patch/kernel/archive/sm8250-6.5/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch deleted file mode 100644 index 3a3e0ddfb59c..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 6 Mar 2023 23:23:13 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: enable touchscreen - -Signed-off-by: Jianhua Lu ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts | 5 ++ - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 32 ++++++++++ - arch/arm64/boot/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 f857fa8c1f2a..f61a00a86e89 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -662,6 +662,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"; - }; -@@ -679,6 +689,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"; -+}; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch b/patch/kernel/archive/sm8250-6.5/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch deleted file mode 100644 index 8e6556503b02..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Wed, 29 Mar 2023 01:57:43 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Disable slpi - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -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 f61a00a86e89..e3745af861eb 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -686,7 +686,7 @@ &qupv3_id_2 { - - &slpi { - firmware-name = "qcom/sm8250/xiaomi/elish/slpi.mbn"; -- status = "okay"; -+ status = "disabled"; - }; - - &spi4 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch b/patch/kernel/archive/sm8250-6.5/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch deleted file mode 100644 index 01a39cee0b90..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Fri, 17 Feb 2023 21:31:38 +0800 -Subject: sound: soc: qcom: sm8250: Add tdm support - ---- - sound/soc/qcom/sdw.c | 65 ++++++++++ - sound/soc/qcom/sm8250.c | 17 +++ - 2 files changed, 82 insertions(+) - -diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c -index 1a41419c7eb8..5e09fb1e3143 100644 ---- a/sound/soc/qcom/sdw.c -+++ b/sound/soc/qcom/sdw.c -@@ -4,9 +4,12 @@ - - #include - #include -+#include - #include "qdsp6/q6afe.h" - #include "sdw.h" - -+static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; -+ - int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *sruntime, - bool *stream_prepared) -@@ -58,6 +61,64 @@ int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - } - EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); - -+static int qcom_tdm_snd_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); -+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); -+ -+ int ret = 0; -+ int channels, slot_width; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ slot_width = 32; -+ break; -+ default: -+ dev_err(rtd->dev, "%s: invalid param format 0x%x\n", -+ __func__, params_format(params)); -+ return -EINVAL; -+ } -+ -+ channels = params_channels(params); -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x03, -+ 8, 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, -+ 8, 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; -+} -+ - int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct sdw_stream_runtime **psruntime) -@@ -82,6 +143,10 @@ int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - *psruntime = sruntime; - } - break; -+ case TERTIARY_TDM_RX_0: -+ case TERTIARY_TDM_TX_0: -+ qcom_tdm_snd_hw_params(substream, params); -+ break; - } - - return 0; -diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c -index 9626a9ef78c2..abeab190337a 100644 ---- a/sound/soc/qcom/sm8250.c -+++ b/sound/soc/qcom/sm8250.c -@@ -16,6 +16,7 @@ - - #define DRIVER_NAME "sm8250" - #define MI2S_BCLK_RATE 1536000 -+#define TDM_BCLK_RATE 12288000 - - struct sm8250_snd_data { - bool stream_prepared[AFE_PORT_MAX]; -@@ -53,6 +54,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); -+ int ret,j; - - switch (cpu_dai->id) { - case TERTIARY_MI2S_RX: -@@ -63,6 +65,21 @@ 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; -+ snd_soc_dai_set_sysclk(cpu_dai, -+ Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT, -+ TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); -+ -+ for_each_rtd_codec_dais(rtd, j, codec_dai) { -+ ret = snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); -+ snd_soc_dai_set_sysclk(codec_dai, 0, TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); -+ if (ret < 0) { -+ dev_err(rtd->dev, "TDM fmt err:%d\n", ret); -+ return ret; -+ } -+ } -+ break; - default: - break; - } --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch b/patch/kernel/archive/sm8250-6.5/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch deleted file mode 100644 index d2e07cc4c8a3..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Sat, 18 Mar 2023 22:26:22 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Add sound support - ---- - arch/arm64/boot/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 e3745af861eb..38166e05127f 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 "sm8250.dtsi" - #include "pm8150.dtsi" - #include "pm8150b.dtsi" -@@ -529,6 +531,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"; -@@ -684,11 +832,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 = "disabled"; - }; - -+&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"; -@@ -735,6 +935,38 @@ wlan-en-pins { - 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 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0017-Asoc-wm_adsp-Add-prefix-support.patch b/patch/kernel/archive/sm8250-6.5/0017-Asoc-wm_adsp-Add-prefix-support.patch deleted file mode 100644 index 706972d16e81..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0017-Asoc-wm_adsp-Add-prefix-support.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Wed, 29 Mar 2023 19:38:33 +0800 -Subject: Asoc: wm_adsp: Add prefix support - ---- - 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 8c20ff680894..c1d8d7786244 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -750,6 +750,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, - dsp->fwf_name, 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, -+ dsp->fwf_name, wm_adsp_fw[dsp->fw].file, asoc_component_prefix, -+ filetype); - else - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, dsp->fwf_name, - wm_adsp_fw[dsp->fw].file, filetype); -@@ -821,6 +825,16 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, - NULL, "bin"); - return 0; - } -+ } else if (asoc_component_prefix) { -+ 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, -+ asoc_component_prefix, "bin"); -+ return 0; -+ } - } - - if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch b/patch/kernel/archive/sm8250-6.5/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch deleted file mode 100644 index 85b000333bd9..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xin Xu -Date: Tue, 22 Aug 2023 00:04:45 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Add xiaomi-keyboard support - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 56 ++++++++++ - 1 file changed, 56 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 38166e05127f..d276fb5f0b5b 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -178,6 +178,14 @@ ramoops@b0000000 { - no-map; - }; - }; -+ -+ extcon_usb: extcon-usb { -+ compatible = "linux,extcon-usb-gpio"; -+ id-gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; -+ vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&keyboard_active &usb_2_vbus_det_n>; -+ pinctrl-names = "default"; -+ }; - }; - - &adsp { -@@ -792,6 +800,14 @@ &pcie0_phy { - }; - - &pm8150_gpios { -+ usb_2_vbus_det_n: usb-2-vbus-det-state { -+ pins = "gpio10"; -+ function = "normal"; -+ power-source = <1>; -+ input-enable; -+ bias-pull-down; -+ }; -+ - vol_up_n: vol-up-n-state { - pins = "gpio6"; - function = "normal"; -@@ -967,6 +983,23 @@ dout-pins { - bias-disable; - }; - }; -+ -+ keyboard_active: keyboard-active-state { -+ active-pins { -+ pins = "gpio155"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-pull-up; -+ }; -+ -+ vdd-pins { -+ pins = "gpio127"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-disable; -+ output-high; -+ }; -+ }; - }; - - &uart6 { -@@ -1003,6 +1036,29 @@ &usb_1_hsphy { - status = "okay"; - }; - -+&usb_2 { -+ status = "okay"; -+}; -+ -+&usb_2_dwc3 { -+ dr_mode = "host"; -+ maximum-speed = "super-speed"; -+ extcon = <&extcon_usb>; -+}; -+ -+&usb_2_hsphy { -+ vdda-pll-supply = <&vreg_l5a_0p88>; -+ vdda18-supply = <&vreg_l12a_1p8>; -+ vdda33-supply = <&vreg_l2a_3p1>; -+ status = "okay"; -+}; -+ -+&usb_2_qmpphy { -+ vdda-phy-supply = <&vreg_l9a_1p2>; -+ vdda-pll-supply = <&vreg_l18a_0p9>; -+ status = "okay"; -+}; -+ - &ufs_mem_hc { - vcc-supply = <&vreg_l17a_3p0>; - vcc-max-microamp = <800000>; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch b/patch/kernel/archive/sm8250-6.5/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch deleted file mode 100644 index 4bd42bd12d8c..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:28:48 +0800 -Subject: drm/panel: nt36523: Fix for kernel 6.5 - ---- - drivers/gpu/drm/panel/panel-novatek-nt36523.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c -index c3befa7f253d..3ac5ae7f97b3 100644 ---- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c -+++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c -@@ -1274,6 +1274,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) - - pinfo->dsi[0] = dsi; - mipi_dsi_set_drvdata(dsi, pinfo); -+ pinfo->panel.prepare_prev_first = true; - drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); - - ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch b/patch/kernel/archive/sm8250-6.5/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch deleted file mode 100644 index 9bc77a42e383..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch +++ /dev/null @@ -1,723 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:29:58 +0800 -Subject: drivers/input/misc: add xiaomi keyboard vendor driver - ---- - drivers/input/misc/Kconfig | 1 + - drivers/input/misc/Makefile | 1 + - drivers/input/misc/xiaomi_keyboard/Kconfig | 8 + - drivers/input/misc/xiaomi_keyboard/Makefile | 1 + - drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c | 608 ++++++++++ - drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h | 45 + - 6 files changed, 664 insertions(+) - -diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig -index 8a320e6218e3..9cff88458f38 100644 ---- a/drivers/input/misc/Kconfig -+++ b/drivers/input/misc/Kconfig -@@ -939,4 +939,5 @@ config INPUT_STPMIC1_ONKEY - To compile this driver as a module, choose M here: the - module will be called stpmic1_onkey. - -+source "drivers/input/misc/xiaomi_keyboard/Kconfig" - endif -diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile -index 04296a4abe8e..83773d457387 100644 ---- a/drivers/input/misc/Makefile -+++ b/drivers/input/misc/Makefile -@@ -90,3 +90,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o - obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o - obj-$(CONFIG_INPUT_YEALINK) += yealink.o - obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o -+obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard/ -diff --git a/drivers/input/misc/xiaomi_keyboard/Kconfig b/drivers/input/misc/xiaomi_keyboard/Kconfig -new file mode 100644 -index 000000000000..bfc4b1d891e5 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/Kconfig -@@ -0,0 +1,8 @@ -+config XIAOMI_KEYBOARD -+ bool "xiaomi keyboard control-driver" -+ depends on INPUT -+ default n -+ help -+ Say Y here, compile xiaomi keyboard control driver. -+ -+ If unsure, say N. -diff --git a/drivers/input/misc/xiaomi_keyboard/Makefile b/drivers/input/misc/xiaomi_keyboard/Makefile -new file mode 100644 -index 000000000000..0a00118c658e ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard.o -\ No newline at end of file -diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c -new file mode 100644 -index 000000000000..a7a736f3c1e8 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c -@@ -0,0 +1,608 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xiaomi_keyboard.h" -+#include -+#include -+ -+static struct xiaomi_keyboard_data *mdata; -+ -+static void set_keyboard_status(bool on); -+ -+static void xiaomi_keyboard_reset(void) -+{ -+ if (!mdata || !mdata->pdata) { -+ MI_KB_ERR("reset failed!Invalid Memory\n"); -+ return; -+ } -+ MI_KB_INFO("xiaomi keyboard IC Reset\n"); -+ gpio_direction_output(mdata->pdata->rst_gpio, 0); -+ msleep(2); -+ gpio_direction_output(mdata->pdata->rst_gpio, 1); -+} -+ -+static void xiaomi_keyboard_connected_notify(struct device *dev) -+{ -+ sysfs_notify(&dev->kobj, NULL, "xiaomi_keyboard_conn_status"); -+ MI_KB_INFO("connected status notify\n"); -+} -+ -+static ssize_t xiaomi_keyboard_conn_status_show (struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ int ret = 0, value = 1; -+ MI_KB_INFO("%s enter\n", __func__); -+ if (!mdata) { -+ MI_KB_ERR("Invalid driver info\n"); -+ return ret; -+ } -+ -+ mutex_lock(&mdata->rw_mutex); -+ value = mdata->keyboard_conn_status; -+ mutex_unlock(&mdata->rw_mutex); -+ -+ return scnprintf(buf, PAGE_SIZE, "%d", value); -+} -+ -+static ssize_t xiaomi_keyboard_conn_status_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ char *cmd; -+ cmd = kzalloc(count + 1, GFP_KERNEL); -+ -+ if (!cmd) { -+ MI_KB_ERR("Allocate Meomory Failed\n"); -+ goto out; -+ } -+ memcpy(cmd, buf, count); -+ -+ if (!mdata) -+ goto out; -+ -+ if (!strncmp(cmd, "reset", 5)) { -+ xiaomi_keyboard_reset(); -+ } else if (!strncmp(cmd, "enable_keyboard", 15)) { -+ MI_KB_INFO("enable keyboard\n"); -+ set_keyboard_status(1); -+ } else if (!strncmp(cmd, "disable_keyboard", 16)) { -+ MI_KB_INFO("disable keyboard\n"); -+ set_keyboard_status(0); -+ } -+ else -+ MI_KB_ERR("Undefined CMD: %s\n", cmd); -+out: -+ if (cmd) -+ kfree(cmd); -+ return count; -+} -+ -+DEVICE_ATTR(xiaomi_keyboard_conn_status, (S_IRUGO | S_IWUSR | S_IWGRP), xiaomi_keyboard_conn_status_show, xiaomi_keyboard_conn_status_store); -+ -+static irqreturn_t xiaomi_keyboard_irq_func(int irq, void *data) -+{ -+ int value = 0; -+ MI_KB_INFO("keyboard event: wakeup system\n"); -+ pm_wakeup_event(&mdata->pdev->dev, 500); -+ value = gpio_get_value_cansleep(mdata->pdata->in_irq_gpio); -+ -+ mutex_lock(&mdata->rw_mutex); -+ mdata->keyboard_conn_status = !mdata->keyboard_conn_status; -+ mutex_unlock(&mdata->rw_mutex); -+ -+ xiaomi_keyboard_connected_notify(&mdata->pdev->dev); -+ MI_KB_INFO("keyboard connected status: %d", mdata->keyboard_conn_status); -+ return IRQ_HANDLED; -+} -+ -+static int xiaomi_keyboard_gpio_config(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ if (gpio_is_valid(pdata->rst_gpio)) { -+ ret = gpio_request_one(pdata->rst_gpio, GPIOF_OUT_INIT_LOW, "kb_rst"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi keyboard rst gpio\n"); -+ goto err_request_rst_gpio; -+ } -+ } -+ -+ if (gpio_is_valid(pdata->in_irq_gpio)) { -+ ret = gpio_request_one(pdata->in_irq_gpio, GPIOF_IN, "kb_in_irq"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi keyboard in-irq gpio\n"); -+ goto err_request_in_irq_gpio; -+ } -+ } -+ -+ return ret; -+err_request_in_irq_gpio: -+ gpio_free(pdata->rst_gpio); -+err_request_rst_gpio: -+ return ret; -+} -+ -+static void xiaomi_keyboard_gpio_deconfig(struct xiaomi_keyboard_platdata *pdata) -+{ -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_free(pdata->rst_gpio); -+ -+ if (gpio_is_valid(pdata->in_irq_gpio)) -+ gpio_free(pdata->in_irq_gpio); -+} -+ -+static int xiaomi_keyboard_setup_gpio(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ if (!pdata) { -+ MI_KB_ERR("xiaomi keyboard platdata is NULL\n"); -+ return -EINVAL; -+ } -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_direction_output(pdata->rst_gpio, 1); -+ -+ mdata->irq = gpio_to_irq(pdata->in_irq_gpio); -+ if (mdata->irq) { -+ ret = request_threaded_irq(mdata->irq, NULL, xiaomi_keyboard_irq_func, -+ IRQF_TRIGGER_RISING|IRQF_ONESHOT, "MiKB-IRQ", mdata); -+ if (ret != 0) { -+ MI_KB_ERR("request threaded irq failed\n"); -+ return ret; -+ } -+ } -+ -+ return ret; -+} -+ -+static int xiaomi_keyboard_resetup_gpio(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ -+ if (!mdata || !pdata) { -+ MI_KB_ERR("mdata or pdata not ready, return!"); -+ return -EINVAL; -+ } -+ -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_direction_output(pdata->rst_gpio, 0); -+ -+ free_irq(mdata->irq, mdata); -+ -+ return ret; -+} -+ -+#ifdef CONFIG_OF -+static int xiaomi_keyboard_parse_dt(struct device *dev) -+{ -+ struct device_node *np = dev->of_node; -+ struct xiaomi_keyboard_platdata *pdata; -+ int ret = 0; -+ -+ pdata = mdata->pdata; -+ -+ pdata->rst_gpio = of_get_named_gpio(np, "xiaomi-keyboard,rst-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,reset-gpio=%d\n", pdata->rst_gpio); -+ -+ pdata->in_irq_gpio = of_get_named_gpio(np, "xiaomi-keyboard,in-irq-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,in-irq-gpio=%d\n", pdata->in_irq_gpio); -+ -+ pdata->vdd_gpio = of_get_named_gpio(np, "xiaomi-keyboard,vdd-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,vdd-gpio=%d\n", pdata->vdd_gpio); -+ -+ return ret; -+} -+#else -+static int xiaomi_keyboard_parse_dt(struct device *dev) -+{ -+ MI_KB_ERR("Xiaomi Keyboard dev is not defined\n"); -+ return -EINVAL; -+} -+#endif -+ -+static int xiaomi_keyboard_pinctrl_init(struct device *dev) -+{ -+ int ret = 0; -+ -+ mdata->pinctrl = devm_pinctrl_get(dev); -+ if (IS_ERR_OR_NULL(mdata->pinctrl)) { -+ MI_KB_ERR("Failed to get pinctrl, please check dts\n"); -+ ret = PTR_ERR(mdata->pinctrl); -+ goto err_pinctrl_get; -+ } -+ mdata->pins_active = pinctrl_lookup_state(mdata->pinctrl, "pm_kb_active"); -+ if (IS_ERR_OR_NULL(mdata->pins_active)) { -+ MI_KB_ERR("Pin state [active] not found\n"); -+ ret = PTR_ERR(mdata->pins_active); -+ goto err_pinctrl_lookup; -+ } -+ -+ mdata->pins_suspend = pinctrl_lookup_state(mdata->pinctrl, "pm_kb_suspend"); -+ if (IS_ERR_OR_NULL(mdata->pins_suspend)) { -+ MI_KB_ERR("Pin state [suspend] not found\n"); -+ ret = PTR_ERR(mdata->pins_suspend); -+ goto err_pinctrl_lookup; -+ } -+ -+ return 0; -+err_pinctrl_lookup: -+ if (mdata->pinctrl) { -+ devm_pinctrl_put(mdata->pinctrl); -+ } -+err_pinctrl_get: -+ return ret; -+} -+ -+static int xiaomi_keyboard_power_on(void) -+{ -+ int ret = 0; -+ struct xiaomi_keyboard_platdata *pdata; -+ pdata = mdata->pdata; -+ MI_KB_INFO("Power On\n"); -+ if (gpio_is_valid(pdata->vdd_gpio)) { -+ ret = gpio_request_one(pdata->vdd_gpio, GPIOF_OUT_INIT_HIGH, "kb_vdd_gpio"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi-keyboard-out-irq gpio\n"); -+ goto err_request_vdd_gpio; -+ } -+ } -+ -+ gpio_direction_output(pdata->vdd_gpio, 1); -+err_request_vdd_gpio: -+ return ret; -+} -+ -+static void xiaomi_keyboard_power_off(void) -+{ -+ struct xiaomi_keyboard_platdata *pdata; -+ pdata = mdata->pdata; -+ MI_KB_INFO("Power Off\n"); -+ if (gpio_is_valid(pdata->vdd_gpio)) { -+ gpio_direction_output(pdata->vdd_gpio, 0); -+ gpio_free(pdata->vdd_gpio); -+ } -+ return; -+} -+ -+static int xiaomi_keyboard_suspend(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ if (mdata->pinctrl && mdata->pins_suspend) { -+ ret = (mdata->keyboard_is_enable && mdata->is_usb_exist) -+ ? 0 : pinctrl_select_state(mdata->pinctrl, mdata->pins_suspend); -+ if (ret < 0) { -+ MI_KB_ERR("Set suspend pin state error:%d\n", ret); -+ } -+ } -+ MI_KB_INFO("exit\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_resume(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ if (!mdata->keyboard_is_enable) { -+ MI_KB_INFO("keyboard_is_enable is false, stop resume.\n"); -+ MI_KB_INFO("exit\n"); -+ return -1; -+ } -+ if (mdata->pinctrl && mdata->pins_active) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_active); -+ if (ret < 0) { -+ MI_KB_ERR("Set active pin state error:%d\n", ret); -+ } -+ } -+ MI_KB_INFO("exit\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_pm_suspend(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ enable_irq_wake(mdata->irq); -+ mdata->dev_pm_suspend = true; -+ return ret; -+} -+ -+static int xiaomi_keyboard_pm_resume(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ disable_irq_wake(mdata->irq); -+ mdata->dev_pm_suspend = false; -+ return ret; -+} -+ -+static const struct dev_pm_ops xiaomi_keyboard_pm_ops = { -+ .suspend = xiaomi_keyboard_pm_suspend, -+ .resume = xiaomi_keyboard_pm_resume, -+}; -+ -+static int keyboard_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) -+{ -+ int blank = *(enum drm_notifier_data *)data; -+ struct xiaomi_keyboard_data *mdata = -+ container_of(self, struct xiaomi_keyboard_data, drm_notif); -+ -+ if (mdata) { -+ flush_workqueue(mdata->event_wq); -+ if (event == MI_DRM_EARLY_EVENT_BLANK) { -+ if (blank == MI_DRM_BLANK_POWERDOWN) { -+ MI_KB_ERR("keyboard suspend"); -+ mdata->is_in_suspend = true; -+ queue_work(mdata->event_wq, &mdata->suspend_work); -+ } -+ } else if (event == MI_DRM_EVENT_BLANK) { -+ if (blank == MI_DRM_BLANK_UNBLANK) { -+ MI_KB_ERR("keyboard resume"); -+ mdata->is_in_suspend = false; -+ flush_workqueue(mdata->event_wq); -+ queue_work(mdata->event_wq, &mdata->resume_work); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static void keyboard_resume_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, resume_work); -+ xiaomi_keyboard_resume(&mdata->pdev->dev); -+} -+ -+static void keyboard_suspend_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, resume_work); -+ xiaomi_keyboard_suspend(&mdata->pdev->dev); -+} -+ -+static int kb_power_supply_event(struct notifier_block *nb, -+ unsigned long event, void *ptr) -+{ -+ struct xiaomi_keyboard_data *mdata = -+ container_of(nb, struct xiaomi_keyboard_data, power_supply_notifier); -+ -+ if (mdata != NULL) -+ queue_work(mdata->event_wq, &mdata->power_supply_work); -+ -+ return 0; -+} -+ -+static void kb_power_supply_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, power_supply_work); -+ int is_usb_exist = 0; -+ -+ mutex_lock(&mdata->power_supply_lock); -+ is_usb_exist = !!power_supply_is_system_supplied(); -+ if (is_usb_exist != mdata->is_usb_exist) { -+ mdata->is_usb_exist = is_usb_exist; -+ MI_KB_INFO("power supply is: %d", mdata->is_usb_exist); -+ } -+ mutex_unlock(&mdata->power_supply_lock); -+} -+ -+static void set_keyboard_status(bool on) { -+ int ret = 0; -+ -+ if (!mdata || !(mdata->pdata)) { -+ MI_KB_ERR("mdata or pdata not ready, return!"); -+ return; -+ } -+ -+ if (on && !(mdata->keyboard_is_enable)) { -+ ret = xiaomi_keyboard_power_on(); -+ if (ret) { -+ MI_KB_ERR("Init 3.3V power failed\n"); -+ return; -+ } -+ msleep(1); -+ ret = xiaomi_keyboard_setup_gpio(mdata->pdata); -+ if (ret) { -+ MI_KB_ERR("setup gpio failed\n"); -+ return; -+ } -+ msleep(2); -+ -+ if (!mdata->is_in_suspend) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_active); -+ if (ret < 0) { -+ MI_KB_ERR("Set active pin state error:%d\n", ret); -+ } -+ } -+ mdata->keyboard_is_enable = true; -+ -+ } else if (!on && mdata->keyboard_is_enable) { -+ if (!mdata->is_in_suspend) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_suspend); -+ if (ret < 0) { -+ MI_KB_ERR("Set suspend pin state error:%d\n", ret); -+ } -+ } -+ -+ ret = xiaomi_keyboard_resetup_gpio(mdata->pdata); -+ if (ret < 0) { -+ MI_KB_ERR("resetup gpio failed\n"); -+ return; -+ } -+ xiaomi_keyboard_power_off(); -+ mdata->keyboard_is_enable = false; -+ } else { -+ MI_KB_INFO("keyboard status do not need change!"); -+ } -+} -+ -+/******************************************************* -+Description: -+ xiami pad keyboard driver probe function. -+ -+return: -+ Executive outcomes. 0---succeed. negative---failed -+*******************************************************/ -+static int xiaomi_keyboard_probe(struct platform_device *pdev) -+{ -+ struct xiaomi_keyboard_platdata *pdata; -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ mdata = kzalloc(sizeof(struct xiaomi_keyboard_data), GFP_KERNEL); -+ if (!mdata) { -+ MI_KB_ERR("Alloc Memory for xiaomi_keyboard_data failed\n"); -+ return -ENOMEM; -+ } -+ -+ pdata = devm_kzalloc(&pdev->dev, sizeof(struct xiaomi_keyboard_platdata), GFP_KERNEL); -+ if (!pdata) { -+ MI_KB_ERR("Alloc Memory for xiaomi_keyboard_platdata failed\n"); -+ return -ENOMEM; -+ } -+ -+ mdata->pdev = pdev; -+ mdata->pdata = pdata; -+ mutex_init(&mdata->rw_mutex); -+ mutex_init(&mdata->power_supply_lock); -+ mdata->is_usb_exist = 0; -+ -+ ret = xiaomi_keyboard_parse_dt(&pdev->dev); -+ if (ret) { -+ MI_KB_ERR("parse device tree failed\n"); -+ goto out; -+ } -+ -+ ret = xiaomi_keyboard_pinctrl_init(&pdev->dev); -+ if (ret) { -+ MI_KB_ERR("Pinctrl init failed\n"); -+ goto out; -+ } -+ -+ pdata = mdata->pdata; -+ ret = xiaomi_keyboard_gpio_config(pdata); -+ if (ret) { -+ MI_KB_ERR("set gpio config failed\n"); -+ goto out; -+ } -+ -+ mdata->dev_pm_suspend = false; -+ mdata->keyboard_is_enable = false; -+ mdata->is_in_suspend = false; -+ -+ ret = sysfs_create_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+ if (ret < 0) { -+ MI_KB_ERR("Create sysfs attribute xiaomi_keyboard_conn_status Failed\n"); -+ goto err_pinctrl_select; -+ } -+ -+ mdata->event_wq = alloc_workqueue("kb-event-queue", -+ WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); -+ if (!mdata->event_wq) { -+ MI_KB_ERR("Can not create work thread for suspend/resume!!"); -+ ret = -ENOMEM; -+ goto err_alloc_work_thread_failed; -+ } -+ -+ set_keyboard_status(1); -+ -+ INIT_WORK(&mdata->resume_work, keyboard_resume_work); -+ INIT_WORK(&mdata->suspend_work, keyboard_suspend_work); -+ INIT_WORK(&mdata->power_supply_work, kb_power_supply_work); -+ -+ mdata->drm_notif.notifier_call = keyboard_drm_notifier_callback; -+ ret = mi_drm_register_client(&mdata->drm_notif); -+ if(ret) { -+ MI_KB_ERR("register drm_notifier failed. ret=%d\n", ret); -+ goto err_register_drm_notif_failed; -+ } -+ -+ mdata->power_supply_notifier.notifier_call = kb_power_supply_event; -+ ret = power_supply_reg_notifier(&mdata->power_supply_notifier); -+ if (ret) { -+ MI_KB_ERR("register power_supply_notifier failed. ret=%d\n", ret); -+ goto err_register_power_supply_notif_failed; -+ } -+ -+ MI_KB_INFO("Success\n"); -+ return ret; -+ -+err_register_power_supply_notif_failed: -+err_register_drm_notif_failed: -+ if (mdata->event_wq) { -+ destroy_workqueue(mdata->event_wq); -+ } -+err_alloc_work_thread_failed: -+ sysfs_remove_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+err_pinctrl_select: -+ if (mdata->pinctrl) { -+ devm_pinctrl_put(mdata->pinctrl); -+ } -+ xiaomi_keyboard_gpio_deconfig(pdata); -+out: -+ mutex_destroy(&mdata->rw_mutex); -+ mutex_destroy(&mdata->power_supply_lock); -+ if (mdata) { -+ kfree(mdata); -+ mdata = NULL; -+ } -+ MI_KB_ERR("Failed\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_remove(struct platform_device *pdev) -+{ -+ MI_KB_INFO("enter\n"); -+ mi_drm_unregister_client(&mdata->drm_notif); -+ destroy_workqueue(mdata->event_wq); -+ xiaomi_keyboard_gpio_deconfig(mdata->pdata); -+ sysfs_remove_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+ xiaomi_keyboard_power_off(); -+ devm_pinctrl_put(mdata->pinctrl); -+ xiaomi_keyboard_gpio_deconfig(mdata->pdata); -+ mutex_destroy(&mdata->rw_mutex); -+ mutex_destroy(&mdata->power_supply_lock); -+ if (mdata) { -+ kfree(mdata); -+ mdata = NULL; -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id xiaomi_keyboard_dt_match[] = { -+ { .compatible = "xiaomi,keyboard" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, xiaomi_keyboard_dt_match); -+#endif -+ -+static const struct platform_device_id xiaomi_keyboard_driver_ids[] = { -+ { -+ .name = "xiaomi-keyboard", -+ .driver_data = 0, -+ }, -+}; -+MODULE_DEVICE_TABLE(platform, xiaomi_keyboard_driver_ids); -+ -+ -+static struct platform_driver xiaomi_keyboard_driver = { -+ .probe = xiaomi_keyboard_probe, -+ .remove = xiaomi_keyboard_remove, -+ .driver = { -+ .name = "xiaomi-keyboard", -+ .of_match_table = of_match_ptr(xiaomi_keyboard_dt_match), -+ .pm = &xiaomi_keyboard_pm_ops, -+ }, -+ .id_table = xiaomi_keyboard_driver_ids, -+}; -+ -+module_platform_driver(xiaomi_keyboard_driver); -+ -+MODULE_DESCRIPTION("Xiaomi Keyboard Control-driver"); -+MODULE_AUTHOR("Tonghui Wang"); -diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h -new file mode 100644 -index 000000000000..5c4220077bf8 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h -@@ -0,0 +1,45 @@ -+#ifndef __XIAOMI_KEYBOARD_H -+#define __XIAOMI_KEYBOARD_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define XIAOMI_KB_TAG "xiaomi-keyboard" -+#define MI_KB_INFO(fmt, args...) pr_info("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) -+#define MI_KB_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) -+ -+struct xiaomi_keyboard_platdata { -+ u32 rst_gpio; -+ u32 rst_flags; -+ u32 in_irq_gpio; -+ u32 in_irq_flags; -+ u32 vdd_gpio; -+}; -+ -+struct xiaomi_keyboard_data { -+ struct notifier_block drm_notif; -+ struct xiaomi_keyboard_platdata *pdata; -+ bool dev_pm_suspend; -+ int irq; -+ struct platform_device *pdev; -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pins_active; -+ struct pinctrl_state *pins_suspend; -+ struct workqueue_struct *event_wq; -+ struct work_struct resume_work; -+ struct work_struct suspend_work; -+ int keyboard_conn_status; -+ struct mutex rw_mutex; -+ -+ struct mutex power_supply_lock; -+ struct work_struct power_supply_work; -+ struct notifier_block power_supply_notifier; -+ int is_usb_exist; -+ bool keyboard_is_enable; -+ bool is_in_suspend; -+}; -+#endif --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch b/patch/kernel/archive/sm8250-6.5/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch deleted file mode 100644 index deca5464069a..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:31:25 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: use vendor keyboard driver - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 58 +++++----- - 1 file changed, 31 insertions(+), 27 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 d276fb5f0b5b..115cb9c86458 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -179,12 +179,14 @@ ramoops@b0000000 { - }; - }; - -- extcon_usb: extcon-usb { -- compatible = "linux,extcon-usb-gpio"; -- id-gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; -- vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; -- pinctrl-0 = <&keyboard_active &usb_2_vbus_det_n>; -- pinctrl-names = "default"; -+ xiaomi_keyboard { -+ compatible = "xiaomi,keyboard"; -+ pinctrl-names = "pm_kb_active", "pm_kb_suspend"; -+ pinctrl-0 = <&xiaomi_keyboard_active>; -+ pinctrl-1 = <&xiaomi_keyboard_suspend>; -+ xiaomi-keyboard,rst-gpio = <&tlmm 141 0x00>; -+ xiaomi-keyboard,in-irq-gpio = <&tlmm 83 0x2001>; -+ xiaomi-keyboard,vdd-gpio = <&tlmm 127 0x00>; - }; - }; - -@@ -800,14 +802,6 @@ &pcie0_phy { - }; - - &pm8150_gpios { -- usb_2_vbus_det_n: usb-2-vbus-det-state { -- pins = "gpio10"; -- function = "normal"; -- power-source = <1>; -- input-enable; -- bias-pull-down; -- }; -- - vol_up_n: vol-up-n-state { - pins = "gpio6"; - function = "normal"; -@@ -984,20 +978,31 @@ dout-pins { - }; - }; - -- keyboard_active: keyboard-active-state { -- active-pins { -- pins = "gpio155"; -- function = "gpio"; -- drive-strength = <8>; -- bias-pull-up; -+ xiaomi_keyboard_mcu { -+ xiaomi_keyboard_suspend: xiaomi_keyboard_suspend { -+ mux { -+ pins = "gpio155"; -+ function = "gpio"; -+ }; -+ -+ config { -+ pins = "gpio155"; -+ drive-strength = <8>; -+ bias-pull-down; -+ }; - }; - -- vdd-pins { -- pins = "gpio127"; -- function = "gpio"; -- drive-strength = <8>; -- bias-disable; -- output-high; -+ xiaomi_keyboard_active: xiaomi_keyboard_active { -+ mux { -+ pins = "gpio155"; -+ function = "gpio"; -+ }; -+ -+ config { -+ pins = "gpio155"; -+ drive-strength = <8>; -+ bias-pull-up; -+ }; - }; - }; - }; -@@ -1043,7 +1048,6 @@ &usb_2 { - &usb_2_dwc3 { - dr_mode = "host"; - maximum-speed = "super-speed"; -- extcon = <&extcon_usb>; - }; - - &usb_2_hsphy { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch b/patch/kernel/archive/sm8250-6.5/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch deleted file mode 100644 index 25f3798fec15..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:32:19 +0800 -Subject: drivers/spmi/spmi-pmic-arb.c: remove warnings - ---- - drivers/spmi/spmi-pmic-arb.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c -index dcb675d980d4..2688ac2a7e55 100644 ---- a/drivers/spmi/spmi-pmic-arb.c -+++ b/drivers/spmi/spmi-pmic-arb.c -@@ -289,7 +289,6 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, - if (status & PMIC_ARB_STATUS_FAILURE) { - dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n", - __func__, sid, addr, status); -- WARN_ON(1); - return -EIO; - } - --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch b/patch/kernel/archive/sm8250-6.5/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch deleted file mode 100644 index 511edcfa5c75..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:32:58 +0800 -Subject: tty: serial: qcom-geni: fix zero dma-rx-len-in - ---- - drivers/tty/serial/qcom_geni_serial.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c -index 67484c062edd..ca50417f41db 100644 ---- a/drivers/tty/serial/qcom_geni_serial.c -+++ b/drivers/tty/serial/qcom_geni_serial.c -@@ -821,7 +821,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop) - rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN); - if (!rx_in) { - dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n"); -- return; -+ //return; - } - - if (!drop) --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch b/patch/kernel/archive/sm8250-6.5/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch deleted file mode 100644 index 7c332c660f6a..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Tue, 24 Oct 2023 01:01:46 +0800 -Subject: Asoc: wm_adsp: Use xiaomi-elish firmware name - ---- - sound/soc/codecs/wm_adsp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c -index c1d8d7786244..dc234dce8ed8 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -827,7 +827,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, - } - } else if (asoc_component_prefix) { - if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, -- cirrus_dir, NULL, -+ cirrus_dir, "xiaomi-elish", - NULL, "wmfw")) { - adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); - wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.5/0025-input-nt36523-short-the-firmware-download-delay-from.patch b/patch/kernel/archive/sm8250-6.5/0025-input-nt36523-short-the-firmware-download-delay-from.patch deleted file mode 100644 index 4b1d5303f3f7..000000000000 --- a/patch/kernel/archive/sm8250-6.5/0025-input-nt36523-short-the-firmware-download-delay-from.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Thu, 26 Oct 2023 13:13:34 +0800 -Subject: input: nt36523: short the firmware download delay from 14s to 4s - ---- - drivers/input/touchscreen/nt36523/nt36xxx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c -index 45500ad5cd91..27f93e531290 100644 ---- a/drivers/input/touchscreen/nt36523/nt36xxx.c -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.c -@@ -1452,7 +1452,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) - } - 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)); -+ queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(4000)); - #endif - - NVT_LOG("NVT_TOUCH_ESD_PROTECT is %d\n", NVT_TOUCH_ESD_PROTECT); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch b/patch/kernel/archive/sm8250-6.6/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch deleted file mode 100644 index 8701076f42a6..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0001-drm-msm-dpu1-improve-support-for-active-CTLs.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 04:52:34 +0300 -Subject: drm/msm/dpu1: improve support for active CTLs - -- Support setting master interface if several INTFs are to be handled by - a single CTL - -- Support setting handling several MERGE_3D instances using a single - CTL. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 15 ++++++++++ - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ - 2 files changed, 17 insertions(+) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -index 86182c734606..4ecffbcdba20 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c -@@ -510,6 +510,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, - u32 intf_active = 0; - u32 wb_active = 0; - u32 mode_sel = 0; -+ u32 merge_3d_active = 0; - - /* CTL_TOP[31:28] carries group_id to collate CTL paths - * per VM. Explicitly disable it until VM support is -@@ -530,16 +531,30 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, - if (cfg->wb) - wb_active |= BIT(cfg->wb - WB_0); - -+ merge_3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE); -+ if (cfg->merge_3d) -+ merge_3d_active |= BIT(cfg->merge_3d - MERGE_3D_0); -+ - DPU_REG_WRITE(c, CTL_TOP, mode_sel); - DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); - DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); - -+ if (cfg->intf_master) -+ DPU_REG_WRITE(c, CTL_INTF_MASTER, BIT(cfg->intf_master - INTF_0)); -+ - if (cfg->merge_3d) - DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, - BIT(cfg->merge_3d - MERGE_3D_0)); - - if (cfg->dsc) - DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); -+ if (cfg->merge_3d) -+ DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active); -+ -+ if (cfg->intf_master) -+ DPU_DEBUG_DRIVER("ACTIVE: %x %x %lx\n", intf_active, merge_3d_active, BIT(cfg->intf_master - INTF_0)); -+ else -+ DPU_DEBUG_DRIVER("ACTIVE: %x %x\n", intf_active, merge_3d_active); - } - - static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -index 1c242298ff2e..36dd4e91a0b4 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h -@@ -36,6 +36,7 @@ struct dpu_hw_stage_cfg { - /** - * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface - * @intf : Interface id -+ * @intf_master: Master interface id in the dual pipe topology - * @mode_3d: 3d mux configuration - * @merge_3d: 3d merge block used - * @intf_mode_sel: Interface mode, cmd / vid -@@ -44,6 +45,7 @@ struct dpu_hw_stage_cfg { - */ - struct dpu_hw_intf_cfg { - enum dpu_intf intf; -+ enum dpu_intf intf_master; - enum dpu_wb wb; - enum dpu_3d_blend_mode mode_3d; - enum dpu_merge_3d merge_3d; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch b/patch/kernel/archive/sm8250-6.6/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch deleted file mode 100644 index d721d466fdd9..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0002-drm-msm-dpu1-use-one-active-CTL-if-it-is-available.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 04:58:32 +0300 -Subject: drm/msm/dpu1: use one active CTL if it is available - -Unlike previous generation, with newer ("active") CTLs it is possible to -use just one CTL to handle both interfaces. And one has to use single -CTL to support master/slave DSI config. So use one active CTL if it is -available. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 8 ++++-- - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + - drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 14 +++++++--- - drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 1 + - 6 files changed, 20 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -index 99acaf917e43..9449b05e556b 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h -@@ -15,6 +15,7 @@ static const struct dpu_caps sm8150_dpu_caps = { - .has_dim_layer = true, - .has_idle_pc = true, - .has_3d_merge = true, -+ .has_active_ctls = true, - .max_linewidth = 4096, - .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, - .max_hdeci_exp = MAX_HORZ_DECIMATION, -diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -index 5f9b437b82a6..ab72b64d5d33 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h -@@ -15,6 +15,7 @@ static const struct dpu_caps sm8250_dpu_caps = { - .has_dim_layer = true, - .has_idle_pc = true, - .has_3d_merge = true, -+ .has_active_ctls = true, - .max_linewidth = 4096, - .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, - }; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -index d34e684a4178..b68103afc687 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -@@ -1117,14 +1117,18 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, - return; - } - -- if (!hw_ctl[i]) { -+ /* Use first (and only) CTL if active CTLs are supported */ -+ if (dpu_kms->catalog->caps->has_active_ctls) -+ phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[0]); -+ else -+ phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); -+ if (!phys->hw_ctl) { - DPU_ERROR_ENC(dpu_enc, - "no ctl block assigned at idx: %d\n", i); - return; - } - - phys->hw_pp = dpu_enc->hw_pp[i]; -- phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - - phys->cached_mode = crtc_state->adjusted_mode; - if (phys->ops.atomic_mode_set) -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -index 6c9634209e9f..de0804253110 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h -@@ -363,6 +363,7 @@ struct dpu_caps { - bool has_dim_layer; - bool has_idle_pc; - bool has_3d_merge; -+ bool has_active_ctls; - /* SSPP limits */ - u32 max_linewidth; - u32 pixel_ram_size; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -index f9215643c71a..c836a4c76c92 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c -@@ -196,6 +196,7 @@ int dpu_rm_init(struct dpu_rm *rm, - } - rm->ctl_blks[ctl->id - CTL_0] = &hw->base; - } -+ rm->has_active_ctls = cat->caps->has_active_ctls; - - for (i = 0; i < cat->dspp_count; i++) { - struct dpu_hw_dspp *hw; -@@ -418,10 +419,15 @@ static int _dpu_rm_reserve_ctls( - int i = 0, j, num_ctls; - bool needs_split_display; - -- /* each hw_intf needs its own hw_ctrl to program its control path */ -- num_ctls = top->num_intf; -+ if (rm->has_active_ctls) { -+ num_ctls = 1; -+ needs_split_display = false; -+ } else { -+ /* each hw_intf needs its own hw_ctrl to program its control path */ -+ num_ctls = top->num_intf; - -- needs_split_display = _dpu_rm_needs_split_display(top); -+ needs_split_display = _dpu_rm_needs_split_display(top); -+ } - - for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) { - const struct dpu_hw_ctl *ctl; -@@ -439,7 +445,7 @@ static int _dpu_rm_reserve_ctls( - - DPU_DEBUG("ctl %d caps 0x%lX\n", j + CTL_0, features); - -- if (needs_split_display != has_split_display) -+ if (!rm->has_active_ctls && needs_split_display != has_split_display) - continue; - - ctl_idx[i] = j; -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -index 2b551566cbf4..6e4777f57e23 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h -@@ -33,6 +33,7 @@ struct dpu_rm { - struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; - struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; - struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE]; -+ bool has_active_ctls; - }; - - /** --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch b/patch/kernel/archive/sm8250-6.6/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch deleted file mode 100644 index f77460b200f2..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0003-drm-msm-dpu1-dpu_encoder_phys_-proper-suppor-for-act.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 14 Mar 2021 05:03:35 +0300 -Subject: drm/msm/dpu1: dpu_encoder_phys_*: proper suppor for active CTLs - -Adapt dpu_encoder_phys_* to properly support active CTLs and their -features. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 5 ++++- - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -index df88358e7037..6d1ac183531e 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c -@@ -57,6 +57,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( - return; - - intf_cfg.intf = phys_enc->hw_intf->idx; -+ if (phys_enc->split_role == ENC_ROLE_MASTER) -+ intf_cfg.intf_master = phys_enc->hw_intf->idx; - intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; - intf_cfg.stream_sel = cmd_enc->stream_sel; - intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -index c2189e58de6a..5d5c7c8088f6 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -@@ -271,6 +271,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine( - DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); - - intf_cfg.intf = phys_enc->hw_intf->idx; -+ if (phys_enc->split_role == ENC_ROLE_MASTER) -+ intf_cfg.intf_master = phys_enc->hw_intf->idx; - intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; - intf_cfg.stream_sel = 0; /* Don't care value for video mode */ - intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); -@@ -344,7 +346,8 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx) - static bool dpu_encoder_phys_vid_needs_single_flush( - struct dpu_encoder_phys *phys_enc) - { -- return phys_enc->split_role != ENC_ROLE_SOLO; -+ return !(phys_enc->hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG)) && -+ phys_enc->split_role != ENC_ROLE_SOLO; - } - - static void dpu_encoder_phys_vid_atomic_mode_set( --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch b/patch/kernel/archive/sm8250-6.6/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch deleted file mode 100644 index 5a17b7e1029c..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0004-dt-bindings-mfd-qcom-qca639x-add-binding-for-QCA639x.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sun, 20 Dec 2020 18:47:57 +0300 -Subject: dt-bindings: mfd: qcom,qca639x: add binding for QCA639x defvice - -Qualcomm QCA639x is a family of WiFi + Bluetooth SoCs, with BT part -being controlled through the UART and WiFi being present on PCIe bus. -Both blocks share common power sources. Add binding to describe power -sequencing required to power up this device. - -Signed-off-by: Dmitry Baryshkov ---- - Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml | 84 ++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml b/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml -new file mode 100644 -index 000000000000..d43c75da136f ---- /dev/null -+++ b/Documentation/devicetree/bindings/mfd/qcom,qca639x.yaml -@@ -0,0 +1,84 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: "http://devicetree.org/schemas/mfd/qcom,qca639x.yaml#" -+$schema: "http://devicetree.org/meta-schemas/core.yaml#" -+ -+title: Qualcomm QCA639x WiFi + Bluetoot SoC bindings -+ -+maintainers: -+ - Andy Gross -+ - Bjorn Andersson -+ -+description: | -+ This binding describes thes Qualcomm QCA6390 or QCA6391 power supplies and -+ enablement pins. -+ -+properties: -+ compatible: -+ const: qcom,qca639x -+ -+ '#power-domain-cells': -+ const: 0 -+ -+ pinctrl-0: true -+ pinctrl-1: true -+ -+ pinctrl-names: -+ items: -+ - const: default -+ - const: active -+ -+ vddaon-supply: -+ description: -+ 0.95V always-on LDO power input -+ -+ vddpmu-supply: -+ description: -+ 0.95V LDO power input to PMU -+ -+ vddrfa1-supply: -+ description: -+ 0.95V LDO power input to RFA -+ -+ vddrfa2-supply: -+ description: -+ 1.25V LDO power input to RFA -+ -+ vddrfa3-supply: -+ description: -+ 2V LDO power input to RFA -+ -+ vddpcie1-supply: -+ description: -+ 1.25V LDO power input to PCIe part -+ -+ vddpcie2-supply: -+ description: -+ 2V LDO power input to PCIe part -+ -+ vddio-supply: -+ description: -+ 1.8V VIO input -+ -+additionalProperties: false -+ -+examples: -+ - | -+ qca639x: qca639x { -+ compatible = "qcom,qca639x"; -+ #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", "active"; -+ pinctrl-0 = <&wlan_default_state &bt_default_state>; -+ pinctrl-1 = <&wlan_active_state &bt_active_state>; -+ }; -+... --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch b/patch/kernel/archive/sm8250-6.6/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch deleted file mode 100644 index d92bc95bae0c..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0005-mfd-qca639x-add-support-for-QCA639x-powerup-sequence.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Fri, 18 Dec 2020 16:24:56 +0300 -Subject: mfd: qca639x: add support for QCA639x powerup sequence - -Qualcomm QCA639x is a family of WiFi + Bluetooth SoCs, with BT part -being controlled through the UART and WiFi being present on PCIe -bus. Both blocks share common power sources. So add mfd device driver -handling power sequencing of QCA6390/1. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/Kconfig | 12 + - drivers/mfd/Makefile | 1 + - drivers/mfd/qcom-qca639x.c | 162 ++++++++++ - 3 files changed, 175 insertions(+) - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 90ce58fd629e..2dd393ff2cf5 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -1123,6 +1123,18 @@ config MFD_PM8XXX - Say M here if you want to include support for PM8xxx chips as a - module. This will build a module called "pm8xxx-core". - -+config MFD_QCOM_QCA639X -+ tristate "Qualcomm QCA639x WiFi/Bluetooth module support" -+ depends on REGULATOR && PM_GENERIC_DOMAINS -+ help -+ If you say yes to this option, support will be included for Qualcomm -+ QCA639x family of WiFi and Bluetooth SoCs. Note, this driver supports -+ only power control for this SoC, you still have to enable individual -+ Bluetooth and WiFi drivers. -+ -+ Say M here if you want to include support for QCA639x chips as a -+ module. This will build a module called "qcom-qca639x". -+ - config MFD_QCOM_RPM - tristate "Qualcomm Resource Power Manager (RPM)" - depends on ARCH_QCOM && OF -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index c66f07edcd0e..3e1b32dd0d8a 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -204,6 +204,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o - obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o - obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o - obj-$(CONFIG_MFD_PM8XXX) += qcom-pm8xxx.o ssbi.o -+obj-$(CONFIG_MFD_QCOM_QCA639X) += qcom-qca639x.o - obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o - obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o - obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -new file mode 100644 -index 000000000000..b31e4b65bec5 ---- /dev/null -+++ b/drivers/mfd/qcom-qca639x.c -@@ -0,0 +1,162 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_NUM_REGULATORS 8 -+ -+static struct vreg { -+ const char *name; -+ unsigned int load_uA; -+} vregs [MAX_NUM_REGULATORS] = { -+ /* 2.0 V */ -+ { "vddpcie2", 15000 }, -+ { "vddrfa3", 400000 }, -+ -+ /* 0.95 V */ -+ { "vddaon", 100000 }, -+ { "vddpmu", 1250000 }, -+ { "vddrfa1", 200000 }, -+ -+ /* 1.35 V */ -+ { "vddrfa2", 400000 }, -+ { "vddpcie1", 35000 }, -+ -+ /* 1.8 V */ -+ { "vddio", 20000 }, -+}; -+ -+struct qca639x_data { -+ struct regulator_bulk_data regulators[MAX_NUM_REGULATORS]; -+ size_t num_vregs; -+ struct device *dev; -+ struct pinctrl_state *active_state; -+ struct generic_pm_domain pd; -+}; -+ -+#define domain_to_data(domain) container_of(domain, struct qca639x_data, pd) -+ -+static int qca639x_power_on(struct generic_pm_domain *domain) -+{ -+ struct qca639x_data *data = domain_to_data(domain); -+ int ret; -+ -+ dev_warn(&domain->dev, "DUMMY POWER ON\n"); -+ -+ ret = regulator_bulk_enable(data->num_vregs, data->regulators); -+ if (ret) { -+ dev_err(data->dev, "Failed to enable regulators"); -+ return ret; -+ } -+ -+ /* Wait for 1ms before toggling enable pins. */ -+ msleep(1); -+ -+ ret = pinctrl_select_state(data->dev->pins->p, data->active_state); -+ if (ret) { -+ dev_err(data->dev, "Failed to select active state"); -+ return ret; -+ } -+ -+ /* Wait for all power levels to stabilize */ -+ msleep(6); -+ -+ return 0; -+} -+ -+static int qca639x_power_off(struct generic_pm_domain *domain) -+{ -+ struct qca639x_data *data = domain_to_data(domain); -+ -+ dev_warn(&domain->dev, "DUMMY POWER OFF\n"); -+ -+ pinctrl_select_default_state(data->dev); -+ regulator_bulk_disable(data->num_vregs, data->regulators); -+ -+ return 0; -+} -+ -+static int qca639x_probe(struct platform_device *pdev) -+{ -+ struct qca639x_data *data; -+ struct device *dev = &pdev->dev; -+ int i, ret; -+ -+ if (!dev->pins || IS_ERR_OR_NULL(dev->pins->default_state)) -+ return -EINVAL; -+ -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->dev = dev; -+ data->num_vregs = ARRAY_SIZE(vregs); -+ -+ data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); -+ if (IS_ERR(data->active_state)) { -+ ret = PTR_ERR(data->active_state); -+ dev_err(dev, "Failed to get active_state: %d\n", ret); -+ return ret; -+ } -+ -+ for (i = 0; i < data->num_vregs; i++) -+ data->regulators[i].supply = vregs[i].name; -+ ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); -+ if (ret < 0) -+ return ret; -+ -+ for (i = 0; i < data->num_vregs; i++) { -+ ret = regulator_set_load(data->regulators[i].consumer, vregs[i].load_uA); -+ if (ret) -+ return ret; -+ } -+ -+ data->pd.name = dev_name(dev); -+ data->pd.power_on = qca639x_power_on; -+ data->pd.power_off = qca639x_power_off; -+ -+ ret = pm_genpd_init(&data->pd, NULL, true); -+ if (ret < 0) -+ return ret; -+ -+ ret = of_genpd_add_provider_simple(dev->of_node, &data->pd); -+ if (ret < 0) { -+ pm_genpd_remove(&data->pd); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, data); -+ -+ return 0; -+} -+ -+static int qca639x_remove(struct platform_device *pdev) -+{ -+ struct qca639x_data *data = platform_get_drvdata(pdev); -+ -+ pm_genpd_remove(&data->pd); -+ -+ return 0; -+} -+ -+static const struct of_device_id qca639x_of_match[] = { -+ { .compatible = "qcom,qca639x" }, -+}; -+ -+static struct platform_driver qca639x_driver = { -+ .probe = qca639x_probe, -+ .remove = qca639x_remove, -+ .driver = { -+ .name = "qca639x", -+ .of_match_table = qca639x_of_match, -+ }, -+}; -+ -+module_platform_driver(qca639x_driver); -+MODULE_LICENSE("GPL v2"); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch b/patch/kernel/archive/sm8250-6.6/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch deleted file mode 100644 index 3d795fec064a..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0006-mfd-qcom-qca639x-switch-to-platform-config-data.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 21:13:18 +0300 -Subject: mfd: qcom-qca639x: switch to platform config data - -Change qcom-qca639x to use platform config data, in preparation to -supporting other devices. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/qcom-qca639x.c | 74 ++++++---- - 1 file changed, 46 insertions(+), 28 deletions(-) - -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -index b31e4b65bec5..22792561dbad 100644 ---- a/drivers/mfd/qcom-qca639x.c -+++ b/drivers/mfd/qcom-qca639x.c -@@ -1,4 +1,5 @@ - #include -+#include - #include - #include - #include -@@ -6,15 +7,21 @@ - #include - #include - #include -+#include - #include - #include - --#define MAX_NUM_REGULATORS 8 -- --static struct vreg { -+struct vreg { - const char *name; - unsigned int load_uA; --} vregs [MAX_NUM_REGULATORS] = { -+}; -+ -+struct qca_cfg_data { -+ const struct vreg *vregs; -+ size_t num_vregs; -+}; -+ -+static const struct vreg qca6390_vregs[] = { - /* 2.0 V */ - { "vddpcie2", 15000 }, - { "vddrfa3", 400000 }, -@@ -32,19 +39,24 @@ static struct vreg { - { "vddio", 20000 }, - }; - --struct qca639x_data { -- struct regulator_bulk_data regulators[MAX_NUM_REGULATORS]; -+static const struct qca_cfg_data qca6390_cfg_data = { -+ .vregs = qca6390_vregs, -+ .num_vregs = ARRAY_SIZE(qca6390_vregs), -+}; -+ -+struct qca_data { - size_t num_vregs; - struct device *dev; - struct pinctrl_state *active_state; - struct generic_pm_domain pd; -+ struct regulator_bulk_data regulators[]; - }; - --#define domain_to_data(domain) container_of(domain, struct qca639x_data, pd) -+#define domain_to_data(domain) container_of(domain, struct qca_data, pd) - --static int qca639x_power_on(struct generic_pm_domain *domain) -+static int qca_power_on(struct generic_pm_domain *domain) - { -- struct qca639x_data *data = domain_to_data(domain); -+ struct qca_data *data = domain_to_data(domain); - int ret; - - dev_warn(&domain->dev, "DUMMY POWER ON\n"); -@@ -70,9 +82,9 @@ static int qca639x_power_on(struct generic_pm_domain *domain) - return 0; - } - --static int qca639x_power_off(struct generic_pm_domain *domain) -+static int qca_power_off(struct generic_pm_domain *domain) - { -- struct qca639x_data *data = domain_to_data(domain); -+ struct qca_data *data = domain_to_data(domain); - - dev_warn(&domain->dev, "DUMMY POWER OFF\n"); - -@@ -82,21 +94,26 @@ static int qca639x_power_off(struct generic_pm_domain *domain) - return 0; - } - --static int qca639x_probe(struct platform_device *pdev) -+static int qca_probe(struct platform_device *pdev) - { -- struct qca639x_data *data; -+ const struct qca_cfg_data *cfg; -+ struct qca_data *data; - struct device *dev = &pdev->dev; - int i, ret; - -+ cfg = device_get_match_data(&pdev->dev); -+ if (!cfg) -+ return -EINVAL; -+ - if (!dev->pins || IS_ERR_OR_NULL(dev->pins->default_state)) - return -EINVAL; - -- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ data = devm_kzalloc(dev, struct_size(data, regulators, cfg->num_vregs), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->dev = dev; -- data->num_vregs = ARRAY_SIZE(vregs); -+ data->num_vregs = cfg->num_vregs; - - data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); - if (IS_ERR(data->active_state)) { -@@ -106,20 +123,20 @@ static int qca639x_probe(struct platform_device *pdev) - } - - for (i = 0; i < data->num_vregs; i++) -- data->regulators[i].supply = vregs[i].name; -+ data->regulators[i].supply = cfg->vregs[i].name; - ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); - if (ret < 0) - return ret; - - for (i = 0; i < data->num_vregs; i++) { -- ret = regulator_set_load(data->regulators[i].consumer, vregs[i].load_uA); -+ ret = regulator_set_load(data->regulators[i].consumer, cfg->vregs[i].load_uA); - if (ret) - return ret; - } - - data->pd.name = dev_name(dev); -- data->pd.power_on = qca639x_power_on; -- data->pd.power_off = qca639x_power_off; -+ data->pd.power_on = qca_power_on; -+ data->pd.power_off = qca_power_off; - - ret = pm_genpd_init(&data->pd, NULL, true); - if (ret < 0) -@@ -136,27 +153,28 @@ static int qca639x_probe(struct platform_device *pdev) - return 0; - } - --static int qca639x_remove(struct platform_device *pdev) -+static int qca_remove(struct platform_device *pdev) - { -- struct qca639x_data *data = platform_get_drvdata(pdev); -+ struct qca_data *data = platform_get_drvdata(pdev); - - pm_genpd_remove(&data->pd); - - return 0; - } - --static const struct of_device_id qca639x_of_match[] = { -- { .compatible = "qcom,qca639x" }, -+static const struct of_device_id qca_of_match[] = { -+ { .compatible = "qcom,qca6390", .data = &qca6390_cfg_data }, -+ { }, - }; - --static struct platform_driver qca639x_driver = { -- .probe = qca639x_probe, -- .remove = qca639x_remove, -+static struct platform_driver qca_driver = { -+ .probe = qca_probe, -+ .remove = qca_remove, - .driver = { - .name = "qca639x", -- .of_match_table = qca639x_of_match, -+ .of_match_table = qca_of_match, - }, - }; - --module_platform_driver(qca639x_driver); -+module_platform_driver(qca_driver); - MODULE_LICENSE("GPL v2"); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch b/patch/kernel/archive/sm8250-6.6/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch deleted file mode 100644 index 2570a84bde28..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0007-mfd-qcom-qca639x-change-qca639x-to-use-gpios-rather-.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 21:17:22 +0300 -Subject: mfd: qcom-qca639x: change qca639x to use gpios rather than pinctrl - -Use gpio interface instead of pinctrl interface to toggle enable pins. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/mfd/qcom-qca639x.c | 33 ++++++---- - 1 file changed, 19 insertions(+), 14 deletions(-) - -diff --git a/drivers/mfd/qcom-qca639x.c b/drivers/mfd/qcom-qca639x.c -index 22792561dbad..4de860e9bbd0 100644 ---- a/drivers/mfd/qcom-qca639x.c -+++ b/drivers/mfd/qcom-qca639x.c -@@ -47,8 +47,9 @@ static const struct qca_cfg_data qca6390_cfg_data = { - struct qca_data { - size_t num_vregs; - struct device *dev; -- struct pinctrl_state *active_state; - struct generic_pm_domain pd; -+ struct gpio_desc *wlan_en_gpio; -+ struct gpio_desc *bt_en_gpio; - struct regulator_bulk_data regulators[]; - }; - -@@ -70,11 +71,10 @@ static int qca_power_on(struct generic_pm_domain *domain) - /* Wait for 1ms before toggling enable pins. */ - msleep(1); - -- ret = pinctrl_select_state(data->dev->pins->p, data->active_state); -- if (ret) { -- dev_err(data->dev, "Failed to select active state"); -- return ret; -- } -+ if (data->wlan_en_gpio) -+ gpiod_set_value(data->wlan_en_gpio, 1); -+ if (data->bt_en_gpio) -+ gpiod_set_value(data->bt_en_gpio, 1); - - /* Wait for all power levels to stabilize */ - msleep(6); -@@ -88,7 +88,11 @@ static int qca_power_off(struct generic_pm_domain *domain) - - dev_warn(&domain->dev, "DUMMY POWER OFF\n"); - -- pinctrl_select_default_state(data->dev); -+ if (data->wlan_en_gpio) -+ gpiod_set_value(data->wlan_en_gpio, 0); -+ if (data->bt_en_gpio) -+ gpiod_set_value(data->bt_en_gpio, 0); -+ - regulator_bulk_disable(data->num_vregs, data->regulators); - - return 0; -@@ -115,13 +119,6 @@ static int qca_probe(struct platform_device *pdev) - data->dev = dev; - data->num_vregs = cfg->num_vregs; - -- data->active_state = pinctrl_lookup_state(dev->pins->p, "active"); -- if (IS_ERR(data->active_state)) { -- ret = PTR_ERR(data->active_state); -- dev_err(dev, "Failed to get active_state: %d\n", ret); -- return ret; -- } -- - for (i = 0; i < data->num_vregs; i++) - data->regulators[i].supply = cfg->vregs[i].name; - ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators); -@@ -134,6 +131,14 @@ static int qca_probe(struct platform_device *pdev) - return ret; - } - -+ data->wlan_en_gpio = devm_gpiod_get_optional(&pdev->dev, "wlan-en", GPIOD_OUT_LOW); -+ if (IS_ERR(data->wlan_en_gpio)) -+ return PTR_ERR(data->wlan_en_gpio); -+ -+ data->bt_en_gpio = devm_gpiod_get_optional(&pdev->dev, "bt-en", GPIOD_OUT_LOW); -+ if (IS_ERR(data->bt_en_gpio)) -+ return PTR_ERR(data->bt_en_gpio); -+ - data->pd.name = dev_name(dev); - data->pd.power_on = qca_power_on; - data->pd.power_off = qca_power_off; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch b/patch/kernel/archive/sm8250-6.6/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch deleted file mode 100644 index e386b2f4a7ef..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0008-Bluetooth-hci_qca-reopen-serial-port-after-toggling-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Baryshkov -Date: Sat, 26 Feb 2022 23:07:54 +0300 -Subject: Bluetooth: hci_qca: reopen serial port after toggling power - -Reopen the serial port after toggling the power. This saves us from -getting command timeouts on first command submitted. - -Signed-off-by: Dmitry Baryshkov ---- - drivers/bluetooth/hci_qca.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c -index 4b57e15f9c7a..e96ebb27188a 100644 ---- a/drivers/bluetooth/hci_qca.c -+++ b/drivers/bluetooth/hci_qca.c -@@ -1797,6 +1797,8 @@ static int qca_power_on(struct hci_dev *hdev) - gpiod_set_value_cansleep(qcadev->bt_en, 1); - /* Controller needs time to bootup. */ - msleep(150); -+ serdev_device_close(hu->serdev); -+ ret = serdev_device_open(hu->serdev); - } - } - --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0009-drm-Add-drm-notifier-support.patch b/patch/kernel/archive/sm8250-6.6/0009-drm-Add-drm-notifier-support.patch deleted file mode 100644 index 3042fc9c8fc5..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0009-drm-Add-drm-notifier-support.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Thu, 4 Aug 2022 13:26:53 +0800 -Subject: drm: Add drm notifier support - ---- - drivers/gpu/drm/Makefile | 3 +- - drivers/gpu/drm/drm_notifier.c | 57 ++++++++++ - include/drm/drm_notifier.h | 37 ++++++ - 3 files changed, 96 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile -index 215e78e79125..541f41fcda73 100644 ---- a/drivers/gpu/drm/Makefile -+++ b/drivers/gpu/drm/Makefile -@@ -46,7 +46,8 @@ drm-y := \ - drm_vblank_work.o \ - drm_vma_manager.o \ - drm_gpuva_mgr.o \ -- drm_writeback.o -+ drm_writeback.o \ -+ drm_notifier.o - drm-$(CONFIG_DRM_LEGACY) += \ - drm_agpsupport.o \ - drm_bufs.o \ -diff --git a/drivers/gpu/drm/drm_notifier.c b/drivers/gpu/drm/drm_notifier.c -new file mode 100644 -index 000000000000..792069640ea7 ---- /dev/null -+++ b/drivers/gpu/drm/drm_notifier.c -@@ -0,0 +1,57 @@ -+/* -+ * 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 -+ -+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); -\ No newline at end of file -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 */ --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch b/patch/kernel/archive/sm8250-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch deleted file mode 100644 index c31c4414fbaa..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 7648741002eeb851ceb394864253445b77ea3d25 Mon Sep 17 00:00:00 2001 -From: Catalin Marinas -Date: Wed, 10 Apr 2024 08:25:37 -0400 -Subject: [PATCH] arm64: swiotlb: Reduce the default size if no ZONE_DMA - bouncing needed - -With CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC enabled, the arm64 kernel still -allocates the default SWIOTLB buffer (64MB) even if ZONE_DMA is disabled -or all the RAM fits into this zone. However, this potentially wastes a -non-negligible amount of memory on platforms with little RAM. - -Reduce the SWIOTLB size to 1MB per 1GB of RAM if only needed for -kmalloc() buffer bouncing. - -Signed-off-by: Catalin Marinas -Suggested-by: Ross Burton -Cc: Ross Burton -Cc: Will Deacon -Reviewed-by: Robin Murphy ---- - arch/arm64/mm/init.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c -index 8a0f8604348b..8deec68028ac 100644 ---- a/arch/arm64/mm/init.c -+++ b/arch/arm64/mm/init.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -493,8 +494,16 @@ void __init mem_init(void) - { - bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit); - -- if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC)) -+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) { -+ /* -+ * If no bouncing needed for ZONE_DMA, reduce the swiotlb -+ * buffer for kmalloc() bouncing to 1MB per 1GB of RAM. -+ */ -+ unsigned long size = -+ DIV_ROUND_UP(memblock_phys_mem_size(), 1024); -+ swiotlb_adjust_size(min(swiotlb_size_or_default(), size)); - swiotlb = true; -+ } - - swiotlb_init(swiotlb, SWIOTLB_VERBOSE); - --- -2.39.2 - diff --git a/patch/kernel/archive/sm8250-6.6/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch b/patch/kernel/archive/sm8250-6.6/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch deleted file mode 100644 index ec52243de5ca..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0010-drm-dsi-emit-panel-turn-on-off-signal-to-touchscreen.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 17 Oct 2022 08:02:58 +0800 -Subject: drm: dsi: emit panel turn on/off signal to touchscreen - ---- - 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 28b8012a21f2..f9d05c711c2f 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 -@@ -303,6 +304,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); - if (!msm_dsi_device_connected(msm_dsi)) -@@ -318,6 +320,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); -@@ -361,12 +366,16 @@ 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); - - if (!msm_dsi_device_connected(msm_dsi)) - return; - -+ 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 --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0011-Input-Add-nt36523-touchscreen-driver.patch b/patch/kernel/archive/sm8250-6.6/0011-Input-Add-nt36523-touchscreen-driver.patch deleted file mode 100644 index 543715163750..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0011-Input-Add-nt36523-touchscreen-driver.patch +++ /dev/null @@ -1,3491 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Thu, 4 Aug 2022 13:26:26 +0800 -Subject: Input: Add nt36523 touchscreen driver - ---- - 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 | 1908 ++++++++++ - drivers/input/touchscreen/nt36523/nt36xxx.h | 240 ++ - drivers/input/touchscreen/nt36523/nt36xxx_fw_update.c | 857 +++++ - drivers/input/touchscreen/nt36523/nt36xxx_mem_map.h | 390 ++ - 8 files changed, 3417 insertions(+) - -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index e3e2324547b9..1f8b33c2b03d 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 62bd24f3ac8e..7d52592f4290 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..45500ad5cd91 ---- /dev/null -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.c -@@ -0,0 +1,1908 @@ -+/* -+ * 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->master->flags & SPI_MASTER_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 }, -+ { } -+}; -+ -+#ifdef CONFIG_OF -+static struct of_device_id nvt_match_table[] = { -+ { .compatible = "novatek,NVT-ts-spi",}, -+ { }, -+}; -+#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..2ec9ccb3b522 ---- /dev/null -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.h -@@ -0,0 +1,240 @@ -+/* -+ * 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" -+ -+#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); -+bool nvt_get_dbgfw_status(void); -+int32_t nvt_set_pocket_palm_switch(uint8_t pocket_palm_switch); -+#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} -+}; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch b/patch/kernel/archive/sm8250-6.6/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch deleted file mode 100644 index 54ede9402b9e..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0012-arm64-dts-qcom-sm8250-xiaomi-elish-enable-wifi-and-b.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 6 Mar 2023 23:13:06 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: enable wifi and bluetooth - -Signed-off-by: Jianhua Lu ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 61 ++++++++++ - 1 file changed, 61 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 85e5cf3dc91e..d7ec6bdd1c88 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -29,6 +29,10 @@ / { - qcom,msm-id = ; /* SM8250 v2.1 */ - qcom,board-id = <0x10008 0>; - -+ aliases { -+ hsuart0 = &uart6; -+ }; -+ - chosen { - #address-cells = <2>; - #size-cells = <2>; -@@ -113,6 +117,25 @@ vreg_s6c_0p88: smpc6-regulator { - vin-supply = <&vph_pwr>; - }; - -+ qca639x: qca639x { -+ compatible = "qcom,qca6390"; -+ #power-domain-cells = <0>; -+ -+ vddaon-supply = <&vreg_s6a_0p95>; -+ vddpmu-supply = <&vreg_s6a_0p95>; -+ vddrfa1-supply = <&vreg_s6a_0p95>; -+ vddrfa2-supply = <&vreg_s8c_1p35>; -+ vddrfa3-supply = <&vreg_s5a_1p9>; -+ vddpcie1-supply = <&vreg_s8c_1p35>; -+ vddpcie2-supply = <&vreg_s5a_1p9>; -+ vddio-supply = <&vreg_s4a_1p8>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wlan_en_state>; -+ -+ wlan-en-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; -+ }; -+ - reserved-memory { - xbl_aop_mem: xbl-aop@80700000 { - reg = <0x0 0x80600000 0x0 0x260000>; -@@ -615,6 +638,9 @@ &pcie0_phy { - vdda-phy-supply = <&vreg_l5a_0p88>; - vdda-pll-supply = <&vreg_l9a_1p2>; - status = "okay"; -+ -+ /* Power on QCA639x chip, otherwise PCIe bus timeouts */ -+ power-domains = <&qca639x>; - }; - - &pm8150_gpios { -@@ -655,6 +681,41 @@ &slpi { - - &tlmm { - gpio-reserved-ranges = <40 4>; -+ -+ bt_en_state: bt-default-state { -+ bt-en-pins { -+ pins = "gpio21"; -+ function = "gpio"; -+ -+ drive-strength = <16>; -+ output-low; -+ bias-pull-up; -+ }; -+ }; -+ -+ wlan_en_state: wlan-default-state { -+ wlan-en-pins { -+ pins = "gpio20"; -+ function = "gpio"; -+ -+ drive-strength = <16>; -+ output-low; -+ bias-pull-up; -+ }; -+ }; -+}; -+ -+&uart6 { -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "qcom,qca6390-bt"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_en_state>; -+ -+ power-domains = <&qca639x>; -+ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; -+ }; - }; - - &usb_1 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch b/patch/kernel/archive/sm8250-6.6/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch deleted file mode 100644 index 7a8c585ec599..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0013-arm64-dts-qcom-sm8250-xiaomi-elish-enable-touchscree.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Mon, 6 Mar 2023 23:23:13 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: enable touchscreen - -Signed-off-by: Jianhua Lu ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts | 5 ++ - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 32 ++++++++++ - arch/arm64/boot/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 d7ec6bdd1c88..b0fe139f8d86 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -662,6 +662,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"; - }; -@@ -679,6 +689,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"; -+}; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch b/patch/kernel/archive/sm8250-6.6/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch deleted file mode 100644 index e1df7f06f48f..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0014-arm64-dts-qcom-sm8250-xiaomi-elish-Disable-slpi.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Wed, 29 Mar 2023 01:57:43 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Disable slpi - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -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 b0fe139f8d86..2da3820ddbda 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -686,7 +686,7 @@ &qupv3_id_2 { - - &slpi { - firmware-name = "qcom/sm8250/xiaomi/elish/slpi.mbn"; -- status = "okay"; -+ status = "disabled"; - }; - - &spi4 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch b/patch/kernel/archive/sm8250-6.6/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch deleted file mode 100644 index 01a39cee0b90..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0015-sound-soc-qcom-sm8250-Add-tdm-support.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Fri, 17 Feb 2023 21:31:38 +0800 -Subject: sound: soc: qcom: sm8250: Add tdm support - ---- - sound/soc/qcom/sdw.c | 65 ++++++++++ - sound/soc/qcom/sm8250.c | 17 +++ - 2 files changed, 82 insertions(+) - -diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c -index 1a41419c7eb8..5e09fb1e3143 100644 ---- a/sound/soc/qcom/sdw.c -+++ b/sound/soc/qcom/sdw.c -@@ -4,9 +4,12 @@ - - #include - #include -+#include - #include "qdsp6/q6afe.h" - #include "sdw.h" - -+static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; -+ - int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *sruntime, - bool *stream_prepared) -@@ -58,6 +61,64 @@ int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - } - EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); - -+static int qcom_tdm_snd_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); -+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); -+ -+ int ret = 0; -+ int channels, slot_width; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ slot_width = 32; -+ break; -+ default: -+ dev_err(rtd->dev, "%s: invalid param format 0x%x\n", -+ __func__, params_format(params)); -+ return -EINVAL; -+ } -+ -+ channels = params_channels(params); -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x03, -+ 8, 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, -+ 8, 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; -+} -+ - int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct sdw_stream_runtime **psruntime) -@@ -82,6 +143,10 @@ int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - *psruntime = sruntime; - } - break; -+ case TERTIARY_TDM_RX_0: -+ case TERTIARY_TDM_TX_0: -+ qcom_tdm_snd_hw_params(substream, params); -+ break; - } - - return 0; -diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c -index 9626a9ef78c2..abeab190337a 100644 ---- a/sound/soc/qcom/sm8250.c -+++ b/sound/soc/qcom/sm8250.c -@@ -16,6 +16,7 @@ - - #define DRIVER_NAME "sm8250" - #define MI2S_BCLK_RATE 1536000 -+#define TDM_BCLK_RATE 12288000 - - struct sm8250_snd_data { - bool stream_prepared[AFE_PORT_MAX]; -@@ -53,6 +54,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); -+ int ret,j; - - switch (cpu_dai->id) { - case TERTIARY_MI2S_RX: -@@ -63,6 +65,21 @@ 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; -+ snd_soc_dai_set_sysclk(cpu_dai, -+ Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT, -+ TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); -+ -+ for_each_rtd_codec_dais(rtd, j, codec_dai) { -+ ret = snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); -+ snd_soc_dai_set_sysclk(codec_dai, 0, TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); -+ if (ret < 0) { -+ dev_err(rtd->dev, "TDM fmt err:%d\n", ret); -+ return ret; -+ } -+ } -+ break; - default: - break; - } --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch b/patch/kernel/archive/sm8250-6.6/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch deleted file mode 100644 index 57a382b7615d..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0016-arm64-dts-qcom-sm8250-xiaomi-elish-Add-sound-support.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Sat, 18 Mar 2023 22:26:22 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Add sound support - ---- - arch/arm64/boot/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 2da3820ddbda..45775428cb92 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 "sm8250.dtsi" - #include "pm8150.dtsi" - #include "pm8150b.dtsi" -@@ -529,6 +531,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"; -@@ -684,11 +832,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 = "disabled"; - }; - -+&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"; -@@ -735,6 +935,38 @@ wlan-en-pins { - 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 { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0017-Asoc-wm_adsp-Add-prefix-support.patch b/patch/kernel/archive/sm8250-6.6/0017-Asoc-wm_adsp-Add-prefix-support.patch deleted file mode 100644 index 9cecfa65a1e7..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0017-Asoc-wm_adsp-Add-prefix-support.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jianhua Lu -Date: Wed, 29 Mar 2023 19:38:33 +0800 -Subject: Asoc: wm_adsp: Add prefix support - ---- - 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 d1b9238d391e..60480d365616 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -750,6 +750,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, - dsp->fwf_name, 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, -+ dsp->fwf_name, wm_adsp_fw[dsp->fw].file, asoc_component_prefix, -+ filetype); - else - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, dsp->fwf_name, - wm_adsp_fw[dsp->fw].file, filetype); -@@ -821,6 +825,16 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, - NULL, "bin"); - return 0; - } -+ } else if (asoc_component_prefix) { -+ 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, -+ asoc_component_prefix, "bin"); -+ return 0; -+ } - } - - if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch b/patch/kernel/archive/sm8250-6.6/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch deleted file mode 100644 index b9087cc38c4f..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0018-arm64-dts-qcom-sm8250-xiaomi-elish-Add-xiaomi-keyboa.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xin Xu -Date: Tue, 22 Aug 2023 00:04:45 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: Add xiaomi-keyboard support - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 56 ++++++++++ - 1 file changed, 56 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 45775428cb92..a8a684b2d7f8 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -178,6 +178,14 @@ ramoops@b0000000 { - no-map; - }; - }; -+ -+ extcon_usb: extcon-usb { -+ compatible = "linux,extcon-usb-gpio"; -+ id-gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; -+ vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&keyboard_active &usb_2_vbus_det_n>; -+ pinctrl-names = "default"; -+ }; - }; - - &adsp { -@@ -792,6 +800,14 @@ &pcie0_phy { - }; - - &pm8150_gpios { -+ usb_2_vbus_det_n: usb-2-vbus-det-state { -+ pins = "gpio10"; -+ function = "normal"; -+ power-source = <1>; -+ input-enable; -+ bias-pull-down; -+ }; -+ - vol_up_n: vol-up-n-state { - pins = "gpio6"; - function = "normal"; -@@ -967,6 +983,23 @@ dout-pins { - bias-disable; - }; - }; -+ -+ keyboard_active: keyboard-active-state { -+ active-pins { -+ pins = "gpio155"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-pull-up; -+ }; -+ -+ vdd-pins { -+ pins = "gpio127"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-disable; -+ output-high; -+ }; -+ }; - }; - - &uart6 { -@@ -1003,6 +1036,29 @@ &usb_1_hsphy { - status = "okay"; - }; - -+&usb_2 { -+ status = "okay"; -+}; -+ -+&usb_2_dwc3 { -+ dr_mode = "host"; -+ maximum-speed = "super-speed"; -+ extcon = <&extcon_usb>; -+}; -+ -+&usb_2_hsphy { -+ vdda-pll-supply = <&vreg_l5a_0p88>; -+ vdda18-supply = <&vreg_l12a_1p8>; -+ vdda33-supply = <&vreg_l2a_3p1>; -+ status = "okay"; -+}; -+ -+&usb_2_qmpphy { -+ vdda-phy-supply = <&vreg_l9a_1p2>; -+ vdda-pll-supply = <&vreg_l18a_0p9>; -+ status = "okay"; -+}; -+ - &ufs_mem_hc { - vcc-supply = <&vreg_l17a_3p0>; - vcc-max-microamp = <800000>; --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch b/patch/kernel/archive/sm8250-6.6/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch deleted file mode 100644 index 5249fcf692f5..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0019-drm-panel-nt36523-Fix-for-kernel-6.5.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:28:48 +0800 -Subject: drm/panel: nt36523: Fix for kernel 6.5 - ---- - drivers/gpu/drm/panel/panel-novatek-nt36523.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c -index 9632b9e95b71..a78970cdd5b1 100644 ---- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c -+++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c -@@ -1274,6 +1274,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) - - pinfo->dsi[0] = dsi; - mipi_dsi_set_drvdata(dsi, pinfo); -+ pinfo->panel.prepare_prev_first = true; - drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); - - ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch b/patch/kernel/archive/sm8250-6.6/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch deleted file mode 100644 index 40e5059fda70..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0020-drivers-input-misc-add-xiaomi-keyboard-vendor-driver.patch +++ /dev/null @@ -1,723 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:29:58 +0800 -Subject: drivers/input/misc: add xiaomi keyboard vendor driver - ---- - drivers/input/misc/Kconfig | 1 + - drivers/input/misc/Makefile | 1 + - drivers/input/misc/xiaomi_keyboard/Kconfig | 8 + - drivers/input/misc/xiaomi_keyboard/Makefile | 1 + - drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c | 608 ++++++++++ - drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h | 45 + - 6 files changed, 664 insertions(+) - -diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig -index 6ba984d7f0b1..8ff29af395d0 100644 ---- a/drivers/input/misc/Kconfig -+++ b/drivers/input/misc/Kconfig -@@ -939,4 +939,5 @@ config INPUT_STPMIC1_ONKEY - To compile this driver as a module, choose M here: the - module will be called stpmic1_onkey. - -+source "drivers/input/misc/xiaomi_keyboard/Kconfig" - endif -diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile -index 04296a4abe8e..83773d457387 100644 ---- a/drivers/input/misc/Makefile -+++ b/drivers/input/misc/Makefile -@@ -90,3 +90,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o - obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o - obj-$(CONFIG_INPUT_YEALINK) += yealink.o - obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o -+obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard/ -diff --git a/drivers/input/misc/xiaomi_keyboard/Kconfig b/drivers/input/misc/xiaomi_keyboard/Kconfig -new file mode 100644 -index 000000000000..bfc4b1d891e5 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/Kconfig -@@ -0,0 +1,8 @@ -+config XIAOMI_KEYBOARD -+ bool "xiaomi keyboard control-driver" -+ depends on INPUT -+ default n -+ help -+ Say Y here, compile xiaomi keyboard control driver. -+ -+ If unsure, say N. -diff --git a/drivers/input/misc/xiaomi_keyboard/Makefile b/drivers/input/misc/xiaomi_keyboard/Makefile -new file mode 100644 -index 000000000000..0a00118c658e ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_XIAOMI_KEYBOARD) += xiaomi_keyboard.o -\ No newline at end of file -diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c -new file mode 100644 -index 000000000000..a7a736f3c1e8 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.c -@@ -0,0 +1,608 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xiaomi_keyboard.h" -+#include -+#include -+ -+static struct xiaomi_keyboard_data *mdata; -+ -+static void set_keyboard_status(bool on); -+ -+static void xiaomi_keyboard_reset(void) -+{ -+ if (!mdata || !mdata->pdata) { -+ MI_KB_ERR("reset failed!Invalid Memory\n"); -+ return; -+ } -+ MI_KB_INFO("xiaomi keyboard IC Reset\n"); -+ gpio_direction_output(mdata->pdata->rst_gpio, 0); -+ msleep(2); -+ gpio_direction_output(mdata->pdata->rst_gpio, 1); -+} -+ -+static void xiaomi_keyboard_connected_notify(struct device *dev) -+{ -+ sysfs_notify(&dev->kobj, NULL, "xiaomi_keyboard_conn_status"); -+ MI_KB_INFO("connected status notify\n"); -+} -+ -+static ssize_t xiaomi_keyboard_conn_status_show (struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ int ret = 0, value = 1; -+ MI_KB_INFO("%s enter\n", __func__); -+ if (!mdata) { -+ MI_KB_ERR("Invalid driver info\n"); -+ return ret; -+ } -+ -+ mutex_lock(&mdata->rw_mutex); -+ value = mdata->keyboard_conn_status; -+ mutex_unlock(&mdata->rw_mutex); -+ -+ return scnprintf(buf, PAGE_SIZE, "%d", value); -+} -+ -+static ssize_t xiaomi_keyboard_conn_status_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ char *cmd; -+ cmd = kzalloc(count + 1, GFP_KERNEL); -+ -+ if (!cmd) { -+ MI_KB_ERR("Allocate Meomory Failed\n"); -+ goto out; -+ } -+ memcpy(cmd, buf, count); -+ -+ if (!mdata) -+ goto out; -+ -+ if (!strncmp(cmd, "reset", 5)) { -+ xiaomi_keyboard_reset(); -+ } else if (!strncmp(cmd, "enable_keyboard", 15)) { -+ MI_KB_INFO("enable keyboard\n"); -+ set_keyboard_status(1); -+ } else if (!strncmp(cmd, "disable_keyboard", 16)) { -+ MI_KB_INFO("disable keyboard\n"); -+ set_keyboard_status(0); -+ } -+ else -+ MI_KB_ERR("Undefined CMD: %s\n", cmd); -+out: -+ if (cmd) -+ kfree(cmd); -+ return count; -+} -+ -+DEVICE_ATTR(xiaomi_keyboard_conn_status, (S_IRUGO | S_IWUSR | S_IWGRP), xiaomi_keyboard_conn_status_show, xiaomi_keyboard_conn_status_store); -+ -+static irqreturn_t xiaomi_keyboard_irq_func(int irq, void *data) -+{ -+ int value = 0; -+ MI_KB_INFO("keyboard event: wakeup system\n"); -+ pm_wakeup_event(&mdata->pdev->dev, 500); -+ value = gpio_get_value_cansleep(mdata->pdata->in_irq_gpio); -+ -+ mutex_lock(&mdata->rw_mutex); -+ mdata->keyboard_conn_status = !mdata->keyboard_conn_status; -+ mutex_unlock(&mdata->rw_mutex); -+ -+ xiaomi_keyboard_connected_notify(&mdata->pdev->dev); -+ MI_KB_INFO("keyboard connected status: %d", mdata->keyboard_conn_status); -+ return IRQ_HANDLED; -+} -+ -+static int xiaomi_keyboard_gpio_config(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ if (gpio_is_valid(pdata->rst_gpio)) { -+ ret = gpio_request_one(pdata->rst_gpio, GPIOF_OUT_INIT_LOW, "kb_rst"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi keyboard rst gpio\n"); -+ goto err_request_rst_gpio; -+ } -+ } -+ -+ if (gpio_is_valid(pdata->in_irq_gpio)) { -+ ret = gpio_request_one(pdata->in_irq_gpio, GPIOF_IN, "kb_in_irq"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi keyboard in-irq gpio\n"); -+ goto err_request_in_irq_gpio; -+ } -+ } -+ -+ return ret; -+err_request_in_irq_gpio: -+ gpio_free(pdata->rst_gpio); -+err_request_rst_gpio: -+ return ret; -+} -+ -+static void xiaomi_keyboard_gpio_deconfig(struct xiaomi_keyboard_platdata *pdata) -+{ -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_free(pdata->rst_gpio); -+ -+ if (gpio_is_valid(pdata->in_irq_gpio)) -+ gpio_free(pdata->in_irq_gpio); -+} -+ -+static int xiaomi_keyboard_setup_gpio(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ if (!pdata) { -+ MI_KB_ERR("xiaomi keyboard platdata is NULL\n"); -+ return -EINVAL; -+ } -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_direction_output(pdata->rst_gpio, 1); -+ -+ mdata->irq = gpio_to_irq(pdata->in_irq_gpio); -+ if (mdata->irq) { -+ ret = request_threaded_irq(mdata->irq, NULL, xiaomi_keyboard_irq_func, -+ IRQF_TRIGGER_RISING|IRQF_ONESHOT, "MiKB-IRQ", mdata); -+ if (ret != 0) { -+ MI_KB_ERR("request threaded irq failed\n"); -+ return ret; -+ } -+ } -+ -+ return ret; -+} -+ -+static int xiaomi_keyboard_resetup_gpio(struct xiaomi_keyboard_platdata *pdata) -+{ -+ int ret = 0; -+ -+ if (!mdata || !pdata) { -+ MI_KB_ERR("mdata or pdata not ready, return!"); -+ return -EINVAL; -+ } -+ -+ if (gpio_is_valid(pdata->rst_gpio)) -+ gpio_direction_output(pdata->rst_gpio, 0); -+ -+ free_irq(mdata->irq, mdata); -+ -+ return ret; -+} -+ -+#ifdef CONFIG_OF -+static int xiaomi_keyboard_parse_dt(struct device *dev) -+{ -+ struct device_node *np = dev->of_node; -+ struct xiaomi_keyboard_platdata *pdata; -+ int ret = 0; -+ -+ pdata = mdata->pdata; -+ -+ pdata->rst_gpio = of_get_named_gpio(np, "xiaomi-keyboard,rst-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,reset-gpio=%d\n", pdata->rst_gpio); -+ -+ pdata->in_irq_gpio = of_get_named_gpio(np, "xiaomi-keyboard,in-irq-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,in-irq-gpio=%d\n", pdata->in_irq_gpio); -+ -+ pdata->vdd_gpio = of_get_named_gpio(np, "xiaomi-keyboard,vdd-gpio", 0); -+ MI_KB_INFO("xiaomi-kb,vdd-gpio=%d\n", pdata->vdd_gpio); -+ -+ return ret; -+} -+#else -+static int xiaomi_keyboard_parse_dt(struct device *dev) -+{ -+ MI_KB_ERR("Xiaomi Keyboard dev is not defined\n"); -+ return -EINVAL; -+} -+#endif -+ -+static int xiaomi_keyboard_pinctrl_init(struct device *dev) -+{ -+ int ret = 0; -+ -+ mdata->pinctrl = devm_pinctrl_get(dev); -+ if (IS_ERR_OR_NULL(mdata->pinctrl)) { -+ MI_KB_ERR("Failed to get pinctrl, please check dts\n"); -+ ret = PTR_ERR(mdata->pinctrl); -+ goto err_pinctrl_get; -+ } -+ mdata->pins_active = pinctrl_lookup_state(mdata->pinctrl, "pm_kb_active"); -+ if (IS_ERR_OR_NULL(mdata->pins_active)) { -+ MI_KB_ERR("Pin state [active] not found\n"); -+ ret = PTR_ERR(mdata->pins_active); -+ goto err_pinctrl_lookup; -+ } -+ -+ mdata->pins_suspend = pinctrl_lookup_state(mdata->pinctrl, "pm_kb_suspend"); -+ if (IS_ERR_OR_NULL(mdata->pins_suspend)) { -+ MI_KB_ERR("Pin state [suspend] not found\n"); -+ ret = PTR_ERR(mdata->pins_suspend); -+ goto err_pinctrl_lookup; -+ } -+ -+ return 0; -+err_pinctrl_lookup: -+ if (mdata->pinctrl) { -+ devm_pinctrl_put(mdata->pinctrl); -+ } -+err_pinctrl_get: -+ return ret; -+} -+ -+static int xiaomi_keyboard_power_on(void) -+{ -+ int ret = 0; -+ struct xiaomi_keyboard_platdata *pdata; -+ pdata = mdata->pdata; -+ MI_KB_INFO("Power On\n"); -+ if (gpio_is_valid(pdata->vdd_gpio)) { -+ ret = gpio_request_one(pdata->vdd_gpio, GPIOF_OUT_INIT_HIGH, "kb_vdd_gpio"); -+ if (ret) { -+ MI_KB_ERR("Failed to request xiaomi-keyboard-out-irq gpio\n"); -+ goto err_request_vdd_gpio; -+ } -+ } -+ -+ gpio_direction_output(pdata->vdd_gpio, 1); -+err_request_vdd_gpio: -+ return ret; -+} -+ -+static void xiaomi_keyboard_power_off(void) -+{ -+ struct xiaomi_keyboard_platdata *pdata; -+ pdata = mdata->pdata; -+ MI_KB_INFO("Power Off\n"); -+ if (gpio_is_valid(pdata->vdd_gpio)) { -+ gpio_direction_output(pdata->vdd_gpio, 0); -+ gpio_free(pdata->vdd_gpio); -+ } -+ return; -+} -+ -+static int xiaomi_keyboard_suspend(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ if (mdata->pinctrl && mdata->pins_suspend) { -+ ret = (mdata->keyboard_is_enable && mdata->is_usb_exist) -+ ? 0 : pinctrl_select_state(mdata->pinctrl, mdata->pins_suspend); -+ if (ret < 0) { -+ MI_KB_ERR("Set suspend pin state error:%d\n", ret); -+ } -+ } -+ MI_KB_INFO("exit\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_resume(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ if (!mdata->keyboard_is_enable) { -+ MI_KB_INFO("keyboard_is_enable is false, stop resume.\n"); -+ MI_KB_INFO("exit\n"); -+ return -1; -+ } -+ if (mdata->pinctrl && mdata->pins_active) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_active); -+ if (ret < 0) { -+ MI_KB_ERR("Set active pin state error:%d\n", ret); -+ } -+ } -+ MI_KB_INFO("exit\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_pm_suspend(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ enable_irq_wake(mdata->irq); -+ mdata->dev_pm_suspend = true; -+ return ret; -+} -+ -+static int xiaomi_keyboard_pm_resume(struct device *dev) -+{ -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ disable_irq_wake(mdata->irq); -+ mdata->dev_pm_suspend = false; -+ return ret; -+} -+ -+static const struct dev_pm_ops xiaomi_keyboard_pm_ops = { -+ .suspend = xiaomi_keyboard_pm_suspend, -+ .resume = xiaomi_keyboard_pm_resume, -+}; -+ -+static int keyboard_drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data) -+{ -+ int blank = *(enum drm_notifier_data *)data; -+ struct xiaomi_keyboard_data *mdata = -+ container_of(self, struct xiaomi_keyboard_data, drm_notif); -+ -+ if (mdata) { -+ flush_workqueue(mdata->event_wq); -+ if (event == MI_DRM_EARLY_EVENT_BLANK) { -+ if (blank == MI_DRM_BLANK_POWERDOWN) { -+ MI_KB_ERR("keyboard suspend"); -+ mdata->is_in_suspend = true; -+ queue_work(mdata->event_wq, &mdata->suspend_work); -+ } -+ } else if (event == MI_DRM_EVENT_BLANK) { -+ if (blank == MI_DRM_BLANK_UNBLANK) { -+ MI_KB_ERR("keyboard resume"); -+ mdata->is_in_suspend = false; -+ flush_workqueue(mdata->event_wq); -+ queue_work(mdata->event_wq, &mdata->resume_work); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static void keyboard_resume_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, resume_work); -+ xiaomi_keyboard_resume(&mdata->pdev->dev); -+} -+ -+static void keyboard_suspend_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, resume_work); -+ xiaomi_keyboard_suspend(&mdata->pdev->dev); -+} -+ -+static int kb_power_supply_event(struct notifier_block *nb, -+ unsigned long event, void *ptr) -+{ -+ struct xiaomi_keyboard_data *mdata = -+ container_of(nb, struct xiaomi_keyboard_data, power_supply_notifier); -+ -+ if (mdata != NULL) -+ queue_work(mdata->event_wq, &mdata->power_supply_work); -+ -+ return 0; -+} -+ -+static void kb_power_supply_work(struct work_struct *work) -+{ -+ struct xiaomi_keyboard_data *mdata = container_of(work, struct xiaomi_keyboard_data, power_supply_work); -+ int is_usb_exist = 0; -+ -+ mutex_lock(&mdata->power_supply_lock); -+ is_usb_exist = !!power_supply_is_system_supplied(); -+ if (is_usb_exist != mdata->is_usb_exist) { -+ mdata->is_usb_exist = is_usb_exist; -+ MI_KB_INFO("power supply is: %d", mdata->is_usb_exist); -+ } -+ mutex_unlock(&mdata->power_supply_lock); -+} -+ -+static void set_keyboard_status(bool on) { -+ int ret = 0; -+ -+ if (!mdata || !(mdata->pdata)) { -+ MI_KB_ERR("mdata or pdata not ready, return!"); -+ return; -+ } -+ -+ if (on && !(mdata->keyboard_is_enable)) { -+ ret = xiaomi_keyboard_power_on(); -+ if (ret) { -+ MI_KB_ERR("Init 3.3V power failed\n"); -+ return; -+ } -+ msleep(1); -+ ret = xiaomi_keyboard_setup_gpio(mdata->pdata); -+ if (ret) { -+ MI_KB_ERR("setup gpio failed\n"); -+ return; -+ } -+ msleep(2); -+ -+ if (!mdata->is_in_suspend) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_active); -+ if (ret < 0) { -+ MI_KB_ERR("Set active pin state error:%d\n", ret); -+ } -+ } -+ mdata->keyboard_is_enable = true; -+ -+ } else if (!on && mdata->keyboard_is_enable) { -+ if (!mdata->is_in_suspend) { -+ ret = pinctrl_select_state(mdata->pinctrl, mdata->pins_suspend); -+ if (ret < 0) { -+ MI_KB_ERR("Set suspend pin state error:%d\n", ret); -+ } -+ } -+ -+ ret = xiaomi_keyboard_resetup_gpio(mdata->pdata); -+ if (ret < 0) { -+ MI_KB_ERR("resetup gpio failed\n"); -+ return; -+ } -+ xiaomi_keyboard_power_off(); -+ mdata->keyboard_is_enable = false; -+ } else { -+ MI_KB_INFO("keyboard status do not need change!"); -+ } -+} -+ -+/******************************************************* -+Description: -+ xiami pad keyboard driver probe function. -+ -+return: -+ Executive outcomes. 0---succeed. negative---failed -+*******************************************************/ -+static int xiaomi_keyboard_probe(struct platform_device *pdev) -+{ -+ struct xiaomi_keyboard_platdata *pdata; -+ int ret = 0; -+ MI_KB_INFO("enter\n"); -+ mdata = kzalloc(sizeof(struct xiaomi_keyboard_data), GFP_KERNEL); -+ if (!mdata) { -+ MI_KB_ERR("Alloc Memory for xiaomi_keyboard_data failed\n"); -+ return -ENOMEM; -+ } -+ -+ pdata = devm_kzalloc(&pdev->dev, sizeof(struct xiaomi_keyboard_platdata), GFP_KERNEL); -+ if (!pdata) { -+ MI_KB_ERR("Alloc Memory for xiaomi_keyboard_platdata failed\n"); -+ return -ENOMEM; -+ } -+ -+ mdata->pdev = pdev; -+ mdata->pdata = pdata; -+ mutex_init(&mdata->rw_mutex); -+ mutex_init(&mdata->power_supply_lock); -+ mdata->is_usb_exist = 0; -+ -+ ret = xiaomi_keyboard_parse_dt(&pdev->dev); -+ if (ret) { -+ MI_KB_ERR("parse device tree failed\n"); -+ goto out; -+ } -+ -+ ret = xiaomi_keyboard_pinctrl_init(&pdev->dev); -+ if (ret) { -+ MI_KB_ERR("Pinctrl init failed\n"); -+ goto out; -+ } -+ -+ pdata = mdata->pdata; -+ ret = xiaomi_keyboard_gpio_config(pdata); -+ if (ret) { -+ MI_KB_ERR("set gpio config failed\n"); -+ goto out; -+ } -+ -+ mdata->dev_pm_suspend = false; -+ mdata->keyboard_is_enable = false; -+ mdata->is_in_suspend = false; -+ -+ ret = sysfs_create_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+ if (ret < 0) { -+ MI_KB_ERR("Create sysfs attribute xiaomi_keyboard_conn_status Failed\n"); -+ goto err_pinctrl_select; -+ } -+ -+ mdata->event_wq = alloc_workqueue("kb-event-queue", -+ WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); -+ if (!mdata->event_wq) { -+ MI_KB_ERR("Can not create work thread for suspend/resume!!"); -+ ret = -ENOMEM; -+ goto err_alloc_work_thread_failed; -+ } -+ -+ set_keyboard_status(1); -+ -+ INIT_WORK(&mdata->resume_work, keyboard_resume_work); -+ INIT_WORK(&mdata->suspend_work, keyboard_suspend_work); -+ INIT_WORK(&mdata->power_supply_work, kb_power_supply_work); -+ -+ mdata->drm_notif.notifier_call = keyboard_drm_notifier_callback; -+ ret = mi_drm_register_client(&mdata->drm_notif); -+ if(ret) { -+ MI_KB_ERR("register drm_notifier failed. ret=%d\n", ret); -+ goto err_register_drm_notif_failed; -+ } -+ -+ mdata->power_supply_notifier.notifier_call = kb_power_supply_event; -+ ret = power_supply_reg_notifier(&mdata->power_supply_notifier); -+ if (ret) { -+ MI_KB_ERR("register power_supply_notifier failed. ret=%d\n", ret); -+ goto err_register_power_supply_notif_failed; -+ } -+ -+ MI_KB_INFO("Success\n"); -+ return ret; -+ -+err_register_power_supply_notif_failed: -+err_register_drm_notif_failed: -+ if (mdata->event_wq) { -+ destroy_workqueue(mdata->event_wq); -+ } -+err_alloc_work_thread_failed: -+ sysfs_remove_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+err_pinctrl_select: -+ if (mdata->pinctrl) { -+ devm_pinctrl_put(mdata->pinctrl); -+ } -+ xiaomi_keyboard_gpio_deconfig(pdata); -+out: -+ mutex_destroy(&mdata->rw_mutex); -+ mutex_destroy(&mdata->power_supply_lock); -+ if (mdata) { -+ kfree(mdata); -+ mdata = NULL; -+ } -+ MI_KB_ERR("Failed\n"); -+ return ret; -+} -+ -+static int xiaomi_keyboard_remove(struct platform_device *pdev) -+{ -+ MI_KB_INFO("enter\n"); -+ mi_drm_unregister_client(&mdata->drm_notif); -+ destroy_workqueue(mdata->event_wq); -+ xiaomi_keyboard_gpio_deconfig(mdata->pdata); -+ sysfs_remove_file(&mdata->pdev->dev.kobj, &dev_attr_xiaomi_keyboard_conn_status.attr); -+ xiaomi_keyboard_power_off(); -+ devm_pinctrl_put(mdata->pinctrl); -+ xiaomi_keyboard_gpio_deconfig(mdata->pdata); -+ mutex_destroy(&mdata->rw_mutex); -+ mutex_destroy(&mdata->power_supply_lock); -+ if (mdata) { -+ kfree(mdata); -+ mdata = NULL; -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id xiaomi_keyboard_dt_match[] = { -+ { .compatible = "xiaomi,keyboard" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, xiaomi_keyboard_dt_match); -+#endif -+ -+static const struct platform_device_id xiaomi_keyboard_driver_ids[] = { -+ { -+ .name = "xiaomi-keyboard", -+ .driver_data = 0, -+ }, -+}; -+MODULE_DEVICE_TABLE(platform, xiaomi_keyboard_driver_ids); -+ -+ -+static struct platform_driver xiaomi_keyboard_driver = { -+ .probe = xiaomi_keyboard_probe, -+ .remove = xiaomi_keyboard_remove, -+ .driver = { -+ .name = "xiaomi-keyboard", -+ .of_match_table = of_match_ptr(xiaomi_keyboard_dt_match), -+ .pm = &xiaomi_keyboard_pm_ops, -+ }, -+ .id_table = xiaomi_keyboard_driver_ids, -+}; -+ -+module_platform_driver(xiaomi_keyboard_driver); -+ -+MODULE_DESCRIPTION("Xiaomi Keyboard Control-driver"); -+MODULE_AUTHOR("Tonghui Wang"); -diff --git a/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h -new file mode 100644 -index 000000000000..5c4220077bf8 ---- /dev/null -+++ b/drivers/input/misc/xiaomi_keyboard/xiaomi_keyboard.h -@@ -0,0 +1,45 @@ -+#ifndef __XIAOMI_KEYBOARD_H -+#define __XIAOMI_KEYBOARD_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define XIAOMI_KB_TAG "xiaomi-keyboard" -+#define MI_KB_INFO(fmt, args...) pr_info("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) -+#define MI_KB_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, XIAOMI_KB_TAG, __func__, __LINE__, ##args) -+ -+struct xiaomi_keyboard_platdata { -+ u32 rst_gpio; -+ u32 rst_flags; -+ u32 in_irq_gpio; -+ u32 in_irq_flags; -+ u32 vdd_gpio; -+}; -+ -+struct xiaomi_keyboard_data { -+ struct notifier_block drm_notif; -+ struct xiaomi_keyboard_platdata *pdata; -+ bool dev_pm_suspend; -+ int irq; -+ struct platform_device *pdev; -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pins_active; -+ struct pinctrl_state *pins_suspend; -+ struct workqueue_struct *event_wq; -+ struct work_struct resume_work; -+ struct work_struct suspend_work; -+ int keyboard_conn_status; -+ struct mutex rw_mutex; -+ -+ struct mutex power_supply_lock; -+ struct work_struct power_supply_work; -+ struct notifier_block power_supply_notifier; -+ int is_usb_exist; -+ bool keyboard_is_enable; -+ bool is_in_suspend; -+}; -+#endif --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch b/patch/kernel/archive/sm8250-6.6/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch deleted file mode 100644 index 429638edd10b..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0021-arm64-dts-qcom-sm8250-xiaomi-elish-use-vendor-keyboa.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:31:25 +0800 -Subject: arm64: dts: qcom: sm8250-xiaomi-elish: use vendor keyboard driver - ---- - arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi | 58 +++++----- - 1 file changed, 31 insertions(+), 27 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 a8a684b2d7f8..ae6e0df3e66c 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi -@@ -179,12 +179,14 @@ ramoops@b0000000 { - }; - }; - -- extcon_usb: extcon-usb { -- compatible = "linux,extcon-usb-gpio"; -- id-gpio = <&tlmm 91 GPIO_ACTIVE_HIGH>; -- vbus-gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; -- pinctrl-0 = <&keyboard_active &usb_2_vbus_det_n>; -- pinctrl-names = "default"; -+ xiaomi_keyboard { -+ compatible = "xiaomi,keyboard"; -+ pinctrl-names = "pm_kb_active", "pm_kb_suspend"; -+ pinctrl-0 = <&xiaomi_keyboard_active>; -+ pinctrl-1 = <&xiaomi_keyboard_suspend>; -+ xiaomi-keyboard,rst-gpio = <&tlmm 141 0x00>; -+ xiaomi-keyboard,in-irq-gpio = <&tlmm 83 0x2001>; -+ xiaomi-keyboard,vdd-gpio = <&tlmm 127 0x00>; - }; - }; - -@@ -800,14 +802,6 @@ &pcie0_phy { - }; - - &pm8150_gpios { -- usb_2_vbus_det_n: usb-2-vbus-det-state { -- pins = "gpio10"; -- function = "normal"; -- power-source = <1>; -- input-enable; -- bias-pull-down; -- }; -- - vol_up_n: vol-up-n-state { - pins = "gpio6"; - function = "normal"; -@@ -984,20 +978,31 @@ dout-pins { - }; - }; - -- keyboard_active: keyboard-active-state { -- active-pins { -- pins = "gpio155"; -- function = "gpio"; -- drive-strength = <8>; -- bias-pull-up; -+ xiaomi_keyboard_mcu { -+ xiaomi_keyboard_suspend: xiaomi_keyboard_suspend { -+ mux { -+ pins = "gpio155"; -+ function = "gpio"; -+ }; -+ -+ config { -+ pins = "gpio155"; -+ drive-strength = <8>; -+ bias-pull-down; -+ }; - }; - -- vdd-pins { -- pins = "gpio127"; -- function = "gpio"; -- drive-strength = <8>; -- bias-disable; -- output-high; -+ xiaomi_keyboard_active: xiaomi_keyboard_active { -+ mux { -+ pins = "gpio155"; -+ function = "gpio"; -+ }; -+ -+ config { -+ pins = "gpio155"; -+ drive-strength = <8>; -+ bias-pull-up; -+ }; - }; - }; - }; -@@ -1043,7 +1048,6 @@ &usb_2 { - &usb_2_dwc3 { - dr_mode = "host"; - maximum-speed = "super-speed"; -- extcon = <&extcon_usb>; - }; - - &usb_2_hsphy { --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch b/patch/kernel/archive/sm8250-6.6/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch deleted file mode 100644 index 25f3798fec15..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0022-drivers-spmi-spmi-pmic-arb.c-remove-warnings.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:32:19 +0800 -Subject: drivers/spmi/spmi-pmic-arb.c: remove warnings - ---- - drivers/spmi/spmi-pmic-arb.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c -index dcb675d980d4..2688ac2a7e55 100644 ---- a/drivers/spmi/spmi-pmic-arb.c -+++ b/drivers/spmi/spmi-pmic-arb.c -@@ -289,7 +289,6 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, - if (status & PMIC_ARB_STATUS_FAILURE) { - dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n", - __func__, sid, addr, status); -- WARN_ON(1); - return -EIO; - } - --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch b/patch/kernel/archive/sm8250-6.6/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch deleted file mode 100644 index a41c343bf472..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0023-tty-serial-qcom-geni-fix-zero-dma-rx-len-in.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Mon, 16 Oct 2023 13:32:58 +0800 -Subject: tty: serial: qcom-geni: fix zero dma-rx-len-in - ---- - drivers/tty/serial/qcom_geni_serial.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c -index b8aa4c1293ba..336cd300fc63 100644 ---- a/drivers/tty/serial/qcom_geni_serial.c -+++ b/drivers/tty/serial/qcom_geni_serial.c -@@ -820,7 +820,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop) - rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN); - if (!rx_in) { - dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n"); -- return; -+ //return; - } - - if (!drop) --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch b/patch/kernel/archive/sm8250-6.6/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch deleted file mode 100644 index e1d359792864..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0024-Asoc-wm_adsp-Use-xiaomi-elish-firmware-name.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Tue, 24 Oct 2023 01:01:46 +0800 -Subject: Asoc: wm_adsp: Use xiaomi-elish firmware name - ---- - sound/soc/codecs/wm_adsp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c -index 60480d365616..b1d59ba61963 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -827,7 +827,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, - } - } else if (asoc_component_prefix) { - if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, -- cirrus_dir, NULL, -+ cirrus_dir, "xiaomi-elish", - NULL, "wmfw")) { - adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); - wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0025-input-nt36523-short-the-firmware-download-delay-from.patch b/patch/kernel/archive/sm8250-6.6/0025-input-nt36523-short-the-firmware-download-delay-from.patch deleted file mode 100644 index 4b1d5303f3f7..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0025-input-nt36523-short-the-firmware-download-delay-from.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Thu, 26 Oct 2023 13:13:34 +0800 -Subject: input: nt36523: short the firmware download delay from 14s to 4s - ---- - drivers/input/touchscreen/nt36523/nt36xxx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c -index 45500ad5cd91..27f93e531290 100644 ---- a/drivers/input/touchscreen/nt36523/nt36xxx.c -+++ b/drivers/input/touchscreen/nt36523/nt36xxx.c -@@ -1452,7 +1452,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) - } - 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)); -+ queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(4000)); - #endif - - NVT_LOG("NVT_TOUCH_ESD_PROTECT is %d\n", NVT_TOUCH_ESD_PROTECT); --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0026-Enable-non-coherent-dst-bufs-for-Venus-V4L2-driver.patch b/patch/kernel/archive/sm8250-6.6/0026-Enable-non-coherent-dst-bufs-for-Venus-V4L2-driver.patch deleted file mode 100644 index d4d1c0a695d6..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0026-Enable-non-coherent-dst-bufs-for-Venus-V4L2-driver.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Fri, 3 Nov 2023 11:20:40 +0800 -Subject: Enable non-coherent dst bufs for Venus V4L2 driver - ---- - drivers/media/platform/qcom/venus/vdec.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c -index dbf305cec120..14b5d2ebbdf2 100644 ---- a/drivers/media/platform/qcom/venus/vdec.c -+++ b/drivers/media/platform/qcom/venus/vdec.c -@@ -1659,6 +1659,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, - dst_vq->min_buffers_needed = 0; - dst_vq->dev = inst->core->dev; - dst_vq->lock = &inst->ctx_q_lock; -+ dst_vq->allow_cache_hints = 1; - return vb2_queue_init(dst_vq); - } - --- -Armbian - diff --git a/patch/kernel/archive/sm8250-6.6/0027-bluetooth-fix-some-blutooth-LE-devices-not-pairing.patch b/patch/kernel/archive/sm8250-6.6/0027-bluetooth-fix-some-blutooth-LE-devices-not-pairing.patch deleted file mode 100644 index 89e8e02d56b9..000000000000 --- a/patch/kernel/archive/sm8250-6.6/0027-bluetooth-fix-some-blutooth-LE-devices-not-pairing.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: amazingfate -Date: Sun, 5 Nov 2023 12:23:48 +0800 -Subject: bluetooth: fix some blutooth LE devices not pairing - ---- - net/bluetooth/smp.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c -index f1a9fc0012f0..62c4f3b56d22 100644 ---- a/net/bluetooth/smp.c -+++ b/net/bluetooth/smp.c -@@ -2970,8 +2970,11 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) - if (code > SMP_CMD_MAX) - goto drop; - -- if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) -- goto drop; -+ if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) { -+ bt_dev_warn(hcon->hdev, "test_and_clear_bit failed with command code 0x%2.2x", code); -+ if ((code != SMP_CMD_ENCRYPT_INFO) && (code != SMP_CMD_INITIATOR_IDENT)) -+ goto drop; -+ } - - /* If we don't have a context the only allowed commands are - * pairing request and security request. --- -Armbian -