From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: MCC45TR Date: Tue, 25 Aug 2026 18:43:59 +0300 Subject: [PATCH 15/21] input: drm: adapt Nabu touch lifecycle to Linux 7.2 --- .../boot/dts/qcom/sm8150-xiaomi-nabu.dts | 2 +- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_notifier.c | 29 +++++++++++++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 9 ++++ drivers/gpu/drm/panel/panel-novatek-nt36523.c | 10 ++--- drivers/input/touchscreen/nt36523/nt36xxx.c | 41 +++++-------------- drivers/input/touchscreen/nt36523/nt36xxx.h | 3 +- include/drm/drm_notifier.h | 19 +++++++++ 8 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/drm_notifier.c create mode 100644 include/drm/drm_notifier.h diff --git a/arch/arm64/boot/dts/qcom/sm8150-xiaomi-nabu.dts b/arch/arm64/boot/dts/qcom/sm8150-xiaomi-nabu.dts index 6bba0ff08c77..08c007afff2e 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-xiaomi-nabu.dts +++ b/arch/arm64/boot/dts/qcom/sm8150-xiaomi-nabu.dts @@ -863,7 +863,7 @@ touchscreen@0 { reg = <0>; spi-max-frequency = <9600000>; - novatek,irq-gpio = <&tlmm 39 0x2001>; + irq-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; novatek,pen-support; novatek,wgp-stylus; diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e97faabcd783..653cb956824b 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -73,6 +73,7 @@ drm-y := \ drm_vblank_work.o \ drm_vma_manager.o \ drm_writeback.o +drm-y += drm_notifier.o drm-$(CONFIG_DRM_CLIENT) += \ drm_client.o \ drm_client_event.o \ diff --git a/drivers/gpu/drm/drm_notifier.c b/drivers/gpu/drm/drm_notifier.c new file mode 100644 index 000000000000..e25791e9428e --- /dev/null +++ b/drivers/gpu/drm/drm_notifier.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Display blank notifier used by the Xiaomi Nabu touch controller. + * + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2021 Xiaomi, Inc. + */ + +#include + +static BLOCKING_NOTIFIER_HEAD(mi_drm_notifier_list); + +int mi_drm_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&mi_drm_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(mi_drm_register_client); + +int mi_drm_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&mi_drm_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(mi_drm_unregister_client); + +int mi_drm_notifier_call_chain(unsigned long val, void *v) +{ + return blocking_notifier_call_chain(&mi_drm_notifier_list, val, v); +} +EXPORT_SYMBOL_GPL(mi_drm_notifier_call_chain); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 10d905c8a8b9..772827dab447 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -4,6 +4,7 @@ */ #include "drm/drm_bridge_connector.h" +#include "drm/drm_notifier.h" #include "msm_kms.h" #include "dsi.h" @@ -282,6 +283,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; bool is_bonded_dsi = IS_BONDED_DSI(); + enum drm_notifier_data notifier_data; int ret; DBG("id=%d", id); @@ -296,6 +298,9 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) return; } + notifier_data = MI_DRM_BLANK_UNBLANK; + mi_drm_notifier_call_chain(MI_DRM_EVENT_BLANK, ¬ifier_data); + ret = msm_dsi_host_enable(host); if (ret) { pr_err("%s: enable host %d failed, %d\n", __func__, id, ret); @@ -338,10 +343,14 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; bool is_bonded_dsi = IS_BONDED_DSI(); + enum drm_notifier_data notifier_data; int ret; DBG("id=%d", id); + notifier_data = MI_DRM_BLANK_POWERDOWN; + mi_drm_notifier_call_chain(MI_DRM_EARLY_EVENT_BLANK, ¬ifier_data); + /* * Do nothing with the host if it is slave-DSI in case of bonded DSI. * It is safe to call dsi_mgr_phy_disable() here because a single PHY diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index 5f16cd47319d..07ae4f00e097 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -1283,18 +1283,18 @@ static int nt36523_sync_pen_fps(struct panel_info *pinfo, bool panel_init) } /* Xiaomi's downstream panel commands synchronize the TDDI scan rate. */ - mipi_dsi_dual_dcs_write_seq_multi(dsi_ctx, dsi0, dsi1, 0xff, 0x2a); + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, 0xff, 0x2a); /* The vendor's live sync sequence omits the page-unlock write. */ if (panel_init) - mipi_dsi_dual_dcs_write_seq_multi(dsi_ctx, dsi0, dsi1, + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, 0xfb, 0x01); if (pinfo->refresh_rate == 60) - mipi_dsi_dual_dcs_write_seq_multi(dsi_ctx, dsi0, dsi1, + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, 0x23, 0x0c); else - mipi_dsi_dual_dcs_write_seq_multi(dsi_ctx, dsi0, dsi1, + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, 0x23, 0x0d); - mipi_dsi_dual_dcs_write_seq_multi(dsi_ctx, dsi0, dsi1, 0xff, 0x10); + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, 0xff, 0x10); if (dsi_ctx.accum_err) dev_err(pinfo->panel.dev, diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.c b/drivers/input/touchscreen/nt36523/nt36xxx.c index 3d31d2268356..2c51ff2d0887 100644 --- a/drivers/input/touchscreen/nt36523/nt36xxx.c +++ b/drivers/input/touchscreen/nt36523/nt36xxx.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #ifdef CONFIG_DRM @@ -681,8 +680,10 @@ static int32_t nvt_parse_dt(struct device *dev) 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->irq_gpio = devm_gpiod_get(dev, "irq", GPIOD_IN); + if (IS_ERR(ts->irq_gpio)) + return dev_err_probe(dev, PTR_ERR(ts->irq_gpio), + "failed to acquire IRQ GPIO\n"); ts->pen_support = of_property_read_bool(np, "novatek,pen-support"); NVT_LOG("novatek,pen-support=%d\n", ts->pen_support); @@ -736,11 +737,7 @@ static int32_t nvt_parse_dt(struct device *dev) #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; + return -ENODEV; } #endif @@ -753,36 +750,20 @@ static int32_t nvt_parse_dt(struct device *dev) *******************************************************/ static int nvt_gpio_config(struct nvt_ts_data *ts) { - int32_t ret = 0; - #if NVT_TOUCH_SUPPORT_HW_RST + int32_t ret; + /* 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; + return ret; } } #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; + return 0; } /******************************************************* @@ -794,8 +775,6 @@ static int nvt_gpio_config(struct nvt_ts_data *ts) *******************************************************/ 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); @@ -1488,7 +1467,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) } /* if (ts->pen_support) */ //---set int-pin & request irq--- - client->irq = gpio_to_irq(ts->irq_gpio); + client->irq = gpiod_to_irq(ts->irq_gpio); if (client->irq) { NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type); ts->irq_enabled = true; diff --git a/drivers/input/touchscreen/nt36523/nt36xxx.h b/drivers/input/touchscreen/nt36523/nt36xxx.h index 489b5d780761..368e5be6248e 100644 --- a/drivers/input/touchscreen/nt36523/nt36xxx.h +++ b/drivers/input/touchscreen/nt36523/nt36xxx.h @@ -20,6 +20,7 @@ #define _LINUX_NVT_TOUCH_H #include +#include #include #include #include @@ -141,7 +142,7 @@ struct nvt_ts_data { uint8_t max_touch_num; uint8_t max_button_num; uint32_t int_trigger_type; - int32_t irq_gpio; + struct gpio_desc *irq_gpio; uint32_t irq_flags; int32_t reset_gpio; uint32_t reset_flags; diff --git a/include/drm/drm_notifier.h b/include/drm/drm_notifier.h new file mode 100644 index 000000000000..e17fd2f775f0 --- /dev/null +++ b/include/drm/drm_notifier.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _DRM_NOTIFIER_H_ +#define _DRM_NOTIFIER_H_ + +#include + +#define MI_DRM_EVENT_BLANK 0x01 +#define MI_DRM_EARLY_EVENT_BLANK 0x02 + +enum drm_notifier_data { + MI_DRM_BLANK_UNBLANK, + 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