diff --git a/device/testing/linux-postmarketos-qcom-sm8250-alioth/0001-Added-POCO-F3-dts-panel-and-touchscreen-drivers.patch b/device/testing/linux-postmarketos-qcom-sm8250-alioth/0001-Added-POCO-F3-dts-panel-and-touchscreen-drivers.patch new file mode 100644 index 000000000..358c15af0 --- /dev/null +++ b/device/testing/linux-postmarketos-qcom-sm8250-alioth/0001-Added-POCO-F3-dts-panel-and-touchscreen-drivers.patch @@ -0,0 +1,2625 @@ +From 532657e0d71103bd000612df893d38e09491ba1b Mon Sep 17 00:00:00 2001 +From: Bartek G +Date: Sat, 28 Mar 2026 14:55:28 +0100 +Subject: [PATCH] Added POCO F3 dts, panel and touchscreen drivers + +--- + arch/arm64/boot/dts/qcom/Makefile | 1 + + .../boot/dts/qcom/sm8250-xiaomi-alioth.dts | 1344 +++++++++++++++++ + drivers/gpu/drm/panel/Kconfig | 10 + + drivers/gpu/drm/panel/Makefile | 1 + + .../gpu/drm/panel/panel-samsung-ams667xx01.c | 522 +++++++ + drivers/input/touchscreen/Kconfig | 14 + + drivers/input/touchscreen/Makefile | 1 + + drivers/input/touchscreen/ft8756.c | 635 ++++++++ + 8 files changed, 2528 insertions(+) + create mode 100644 arch/arm64/boot/dts/qcom/sm8250-xiaomi-alioth.dts + create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams667xx01.c + create mode 100644 drivers/input/touchscreen/ft8756.c + +diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile +index 259136d9875a..6938d10c4b09 100644 +--- a/arch/arm64/boot/dts/qcom/Makefile ++++ b/arch/arm64/boot/dts/qcom/Makefile +@@ -285,6 +285,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8250-xiaomi-elish-csot.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-xiaomi-enuma.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-xiaomi-pipa-csot.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8250-xiaomi-pipa-tianma.dtb ++dtb-$(CONFIG_ARCH_QCOM) += sm8250-xiaomi-alioth.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8350-hdk.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8350-microsoft-surface-duo2.dtb + dtb-$(CONFIG_ARCH_QCOM) += sm8350-mtp.dtb +diff --git a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-alioth.dts b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-alioth.dts +new file mode 100644 +index 000000000000..4652c6241f38 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-alioth.dts +@@ -0,0 +1,1344 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++/* ++ * Copyright (c) 2025 Vitalii Skorkin ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sm8250.dtsi" ++#include "pm8150.dtsi" ++#include "pm8150b.dtsi" ++#include "pm8150l.dtsi" ++ ++/* ++ * Delete following upstream (sm8250.dtsi) reserved ++ * memory mappings which are different on this device. ++ */ ++/delete-node/ &adsp_mem; ++/delete-node/ &cdsp_secure_heap; ++/delete-node/ &slpi_mem; ++/delete-node/ &spss_mem; ++/delete-node/ &xbl_aop_mem; ++ ++/ { ++ ++ model = "Xiaomi POCO F3"; ++ compatible = "xiaomi,alioth", "qcom,sm8250"; ++ chassis-type = "handset"; ++ ++ /* required for bootloader to select correct board */ ++ qcom,msm-id = ; /* SM8250 v2.1 */ ++ qcom,board-id = <44 0>; ++ ++ aliases { ++ serial0 = &uart6; ++ }; ++ ++ chosen { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ }; ++ ++ battery: battery { ++ compatible = "simple-battery"; ++ charge-full-design-microamp-hours = <4520000>; ++ energy-full-design-microwatt-hours = <17500000>; ++ voltage-min-design-microvolt = <3400000>; ++ voltage-max-design-microvolt = <4460000>; ++ }; ++ ++ gpio_keys: gpio-keys { ++ compatible = "gpio-keys"; ++ ++ pinctrl-0 = <&vol_up_n>; ++ pinctrl-names = "default"; ++ ++ key-vol-up { ++ label = "Volume Up"; ++ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <15>; ++ linux,can-disable; ++ wakeup-source; ++ }; ++ }; ++ ++ vph_pwr: vph-pwr-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vph_pwr"; ++ regulator-min-microvolt = <3700000>; ++ regulator-max-microvolt = <3700000>; ++ }; ++ ++ /* S6c is really ebi.lvl but it's there for supply map completeness sake. */ ++ vreg_s6c_0p88: smpc6-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vreg_s6c_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-always-on; ++ vin-supply = <&vph_pwr>; ++ }; ++ ++ qca6390-pmu { ++ compatible = "qcom,qca6390-pmu"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_en_state>, <&wlan_en_state>; ++ ++ vddaon-supply = <&vreg_s6a_0p95>; ++ vddpmu-supply = <&vreg_s6a_0p95>; ++ vddrfa0p95-supply = <&vreg_s6a_0p95>; ++ vddrfa1p3-supply = <&vreg_s8c_1p35>; ++ vddrfa1p9-supply = <&vreg_s5a_1p9>; ++ vddpcie1p3-supply = <&vreg_s8c_1p35>; ++ vddpcie1p9-supply = <&vreg_s5a_1p9>; ++ vddio-supply = <&vreg_s4a_1p8>; ++ ++ wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>; ++ bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; ++ ++ regulators { ++ vreg_pmu_rfa_cmn: ldo0 { ++ regulator-name = "vreg_pmu_rfa_cmn"; ++ }; ++ ++ vreg_pmu_aon_0p59: ldo1 { ++ regulator-name = "vreg_pmu_aon_0p59"; ++ }; ++ ++ vreg_pmu_wlcx_0p8: ldo2 { ++ regulator-name = "vreg_pmu_wlcx_0p8"; ++ }; ++ ++ vreg_pmu_wlmx_0p85: ldo3 { ++ regulator-name = "vreg_pmu_wlmx_0p85"; ++ }; ++ ++ vreg_pmu_btcmx_0p85: ldo4 { ++ regulator-name = "vreg_pmu_btcmx_0p85"; ++ }; ++ ++ vreg_pmu_rfa_0p8: ldo5 { ++ regulator-name = "vreg_pmu_rfa_0p8"; ++ }; ++ ++ vreg_pmu_rfa_1p2: ldo6 { ++ regulator-name = "vreg_pmu_rfa_1p2"; ++ }; ++ ++ vreg_pmu_rfa_1p7: ldo7 { ++ regulator-name = "vreg_pmu_rfa_1p7"; ++ }; ++ ++ vreg_pmu_pcie_0p9: ldo8 { ++ regulator-name = "vreg_pmu_pcie_0p9"; ++ }; ++ ++ vreg_pmu_pcie_1p8: ldo9 { ++ regulator-name = "vreg_pmu_pcie_1p8"; ++ }; ++ }; ++ }; ++ ++ reserved-memory { ++ xbl_aop_mem: xbl-aop@80700000 { ++ reg = <0x0 0x80600000 0x0 0x260000>; ++ no-map; ++ }; ++ ++ slpi_mem: slpi@88c00000 { ++ reg = <0x0 0x88c00000 0x0 0x2f00000>; ++ no-map; ++ }; ++ ++ adsp_mem: adsp@8bb00000 { ++ reg = <0x0 0x8bb00000 0x0 0x2500000>; ++ no-map; ++ }; ++ ++ spss_mem: spss@8e000000 { ++ reg = <0x0 0x8e000000 0x0 0x100000>; ++ no-map; ++ }; ++ ++ cdsp_secure_heap: cdsp-secure-heap@8e100000 { ++ reg = <0x0 0x8e100000 0x0 0x4600000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&adsp { ++ firmware-name = "qcom/sm8250/xiaomi/alioth/adsp.mbn"; ++ status = "okay"; ++}; ++ ++&apps_rsc { ++ pm8150-rpmh-regulators { ++ compatible = "qcom,pm8150-rpmh-regulators"; ++ qcom,pmic-id = "a"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-s9-supply = <&vph_pwr>; ++ vdd-s10-supply = <&vph_pwr>; ++ vdd-l1-l8-l11-supply = <&vreg_s6c_0p88>; ++ vdd-l2-l10-supply = <&vreg_bob>; ++ vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>; ++ vdd-l6-l9-supply = <&vreg_s8c_1p35>; ++ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>; ++ vdd-l13-l16-l17-supply = <&vreg_bob>; ++ ++ /* (S1+S2+S3) - cx.lvl (ARC) */ ++ ++ vreg_s4a_1p8: smps4 { ++ regulator-name = "vreg_s4a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1920000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s5a_1p9: smps5 { ++ regulator-name = "vreg_s5a_1p9"; ++ regulator-min-microvolt = <1824000>; ++ regulator-max-microvolt = <2040000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s6a_0p95: smps6 { ++ regulator-name = "vreg_s6a_0p95"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <1128000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2a_3p1: ldo2 { ++ regulator-name = "vreg_l2a_3p1"; ++ regulator-min-microvolt = <3072000>; ++ regulator-max-microvolt = <3072000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3a_0p9: ldo3 { ++ regulator-name = "vreg_l3a_0p9"; ++ regulator-min-microvolt = <928000>; ++ regulator-max-microvolt = <932000>; ++ regulator-initial-mode = ; ++ }; ++ ++ /* L4 - lmx.lvl (ARC) */ ++ ++ vreg_l5a_0p88: ldo5 { ++ regulator-name = "vreg_l5a_0p88"; ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6a_1p2: ldo6 { ++ regulator-name = "vreg_l6a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9a_1p2: ldo9 { ++ regulator-name = "vreg_l9a_1p2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l12a_1p8: ldo12 { ++ regulator-name = "vreg_l12a_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l13a_3p3: ldo13 { ++ regulator-name = "vreg_l13a_3p3"; ++ regulator-min-microvolt = <3304000>; ++ regulator-max-microvolt = <3304000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l14a_1p88: ldo14 { ++ regulator-name = "vreg_l14a_1p88"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1880000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l16a_3p3: ldo16 { ++ regulator-name = "vreg_l16a_3p3"; ++ regulator-min-microvolt = <3024000>; ++ regulator-max-microvolt = <3304000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l17a_3p0: ldo17 { ++ regulator-name = "vreg_l17a_3p0"; ++ regulator-min-microvolt = <2496000>; ++ regulator-max-microvolt = <3008000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l18a_0p9: ldo18 { ++ regulator-name = "vreg_l18a_0p9"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <920000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++ ++ /* ++ * Remaining regulators that are not yet supported: ++ * OLEDB: 4925000-8100000 ++ * ab: 4600000-6100000 ++ * ibb: 800000-5400000 ++ */ ++ pm8150l-rpmh-regulators { ++ compatible = "qcom,pm8150l-rpmh-regulators"; ++ qcom,pmic-id = "c"; ++ ++ vdd-s1-supply = <&vph_pwr>; ++ vdd-s2-supply = <&vph_pwr>; ++ vdd-s3-supply = <&vph_pwr>; ++ vdd-s4-supply = <&vph_pwr>; ++ vdd-s5-supply = <&vph_pwr>; ++ vdd-s6-supply = <&vph_pwr>; ++ vdd-s7-supply = <&vph_pwr>; ++ vdd-s8-supply = <&vph_pwr>; ++ vdd-l1-l8-supply = <&vreg_s4a_1p8>; ++ vdd-l2-l3-supply = <&vreg_s8c_1p35>; ++ vdd-l4-l5-l6-supply = <&vreg_bob>; ++ vdd-l7-l11-supply = <&vreg_bob>; ++ vdd-l9-l10-supply = <&vreg_bob>; ++ vdd-bob-supply = <&vph_pwr>; ++ ++ vreg_bob: bob { ++ regulator-name = "vreg_bob"; ++ regulator-min-microvolt = <3008000>; ++ regulator-max-microvolt = <3960000>; ++ regulator-initial-mode = ; ++ }; ++ ++ /* ++ * S1-S6 are ARCs: ++ * (S1+S2) - gfx.lvl, ++ * S3 - mx.lvl, ++ * (S4+S5) - mmcx.lvl, ++ * S6 - ebi.lvl ++ */ ++ ++ vreg_s7c_0p35: smps7 { ++ regulator-name = "vreg_s7c_0p35"; ++ regulator-min-microvolt = <348000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_s8c_1p35: smps8 { ++ regulator-name = "vreg_s8c_1p35"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l1c_1p8: ldo1 { ++ regulator-name = "vreg_l1c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l2c_1p3: ldo2 { ++ regulator-name = "vreg_l2c_1p8"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1304000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l3c_1p2: ldo3 { ++ regulator-name = "vreg_l3c_1p2"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l5c_1p8: ldo5 { ++ regulator-name = "vreg_l5c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l6c_2p9: ldo6 { ++ regulator-name = "vreg_l6c_2p9"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ }; ++ ++ vreg_l7c_2p85: ldo7 { ++ regulator-name = "vreg_l7c_2p85"; ++ regulator-min-microvolt = <2856000>; ++ regulator-max-microvolt = <3104000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l8c_1p8: ldo8 { ++ regulator-name = "vreg_l8c_1p8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l9c_2p9: ldo9 { ++ regulator-name = "vreg_l9c_2p9"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2960000>; ++ regulator-initial-mode = ; ++ regulator-allow-set-load; ++ }; ++ ++ vreg_l10c_3p0: ldo10 { ++ regulator-name = "vreg_l10c_303"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3312000>; ++ regulator-initial-mode = ; ++ }; ++ ++ vreg_l11c_3p0: ldo11 { ++ regulator-name = "vreg_l11c_3p0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-initial-mode = ; ++ }; ++ }; ++}; ++ ++&cdsp { ++ firmware-name = "qcom/sm8250/xiaomi/alioth/cdsp.mbn"; ++ status = "okay"; ++}; ++ ++// SD870 additional cpu frequency ++&cpu7_opp_table { ++ cpu7_opp21: opp-3187200000 { ++ opp-hz = /bits/ 64 <3187200000>; ++ opp-peak-kBps = <8368000 51609600>; ++ }; ++}; ++ ++&camcc { ++ status = "okay"; ++}; ++ ++&camss { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ csiphy0_ep: endpoint { ++ clock-lanes = <7>; ++ data-lanes = <0 1>; ++ bus-type = ; ++ remote-endpoint = <&cam_s5k5e9_ep>; ++ }; ++ }; ++ ++ port@1 { ++ csiphy1_ep: endpoint { ++ clock-lanes = <7>; ++ data-lanes = <0 1 2 3>; ++ bus-type = ; ++ remote-endpoint = <&cam_imx582_ep>; ++ }; ++ }; ++ ++ port@2 { ++ csiphy2_ep: endpoint { ++ clock-lanes = <7>; ++ data-lanes = <0 1 2 3>; ++ bus-type = ; ++ remote-endpoint = <&cam_imx355_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&cci0 { ++ status = "okay"; ++}; ++ ++&cci0_i2c0 { ++ imx582_gt24p128e: eeprom@51 { ++ compatible = "giantec,gt24p128e", ++ "atmel,24c128"; ++ reg = <0x51>; ++ vcc-supply = <&vreg_l5c_1p8>; ++ read-only; ++ }; ++ ++ imx582_vcm: dw9800@c { ++ compatible = "dongwoon,dw9800"; ++ reg = <0x0c>; ++ ++ vin-supply = <&vreg_l5c_1p8>; ++ vdd-supply = <&vreg_l7c_2p85>; ++ }; ++ ++ imx582@10 { ++ compatible = "sony,imx582"; ++ reg = <0x10>; ++ ++ clocks = <&camcc CAM_CC_MCLK0_CLK>; ++ clock-names = "mclk"; ++ clock-frequency = <19200000>; ++ assigned-clocks = <&camcc CAM_CC_MCLK0_CLK>; ++ assigned-clock-rates = <19200000>; ++ ++ reset-gpios = <&tlmm 93 GPIO_ACTIVE_HIGH>; ++ ++ vio-supply = <&vreg_l5c_1p8>; ++ vana-supply = <&vreg_l7p>; ++ vdig-supply = <&vreg_l2p>; ++ custom-supply = <&vreg_l6p>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cam_imx582_default>; ++ ++ orientation = <1>; ++ rotation = <270>; ++ ++ lens-focus = <&imx582_vcm>; ++ ++ port { ++ cam_imx582_ep: endpoint { ++ data-lanes = <1 2 3 4>; ++ link-frequencies = /bits/ 64 <720000000>; ++ remote-endpoint = <&csiphy1_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&cci0_i2c1 { ++ s5k5e9_eeprom: eeprom@52 { ++ compatible = "puya,p24c64f", ++ "atmel,24c64"; ++ reg = <0x52>; ++ vcc-supply = <&vreg_l5c_1p8>; ++ read-only; ++ }; ++ ++ s5k5e9_vcm: dw9800@c { ++ compatible = "dongwoon,dw9800"; ++ reg = <0x0c>; ++ ++ vin-supply = <&vreg_l5c_1p8>; ++ vdd-supply = <&vreg_l7c_2p85>; ++ }; ++ ++ s5k5e9@2d { ++ compatible = "samsung,s5k5e9"; ++ reg = <0x2d>; ++ ++ vio-supply = <&vreg_l5c_1p8>; ++ vana-supply = <&vreg_l4p>; ++ vdig-supply = <&vreg_l2c_1p3>; ++ ++ clocks = <&camcc CAM_CC_MCLK1_CLK>; ++ clock-names = "xvclk"; ++ clock-frequency = <19200000>; ++ assigned-clocks = <&camcc CAM_CC_MCLK1_CLK>; ++ assigned-clock-rates = <19200000>; ++ ++ reset-gpios = <&tlmm 92 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cam_s5k5e9_default>; ++ ++ orientation = <1>; ++ rotation = <270>; ++ ++ lens-focus = <&s5k5e9_vcm>; ++ ++ port { ++ cam_s5k5e9_ep: endpoint { ++ data-lanes = <1 2>; ++ link-frequencies = /bits/ 64 <480000000>; ++ remote-endpoint = <&csiphy0_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&cci1 { ++ status = "okay"; ++}; ++ ++&cci1_i2c0 { ++ imx355_eeprom: eeprom@50 { ++ compatible = "giantec,gt24p64e", ++ "atmel,24c64"; ++ reg = <0x50>; ++ vcc-supply = <&vreg_l5c_1p8>; ++ read-only; ++ }; ++ ++ imx355@1a { ++ compatible = "sony,imx355"; ++ reg = <0x1a>; ++ ++ clocks = <&camcc CAM_CC_MCLK2_CLK>; ++ clock-names = "mclk"; ++ clock-frequency = <19200000>; ++ assigned-clocks = <&camcc CAM_CC_MCLK2_CLK>; ++ assigned-clock-rates = <19200000>; ++ ++ reset-gpios = <&tlmm 78 GPIO_ACTIVE_HIGH>; ++ ++ vio-supply = <&vreg_l5c_1p8>; ++ vana-supply = <&vreg_l3p>; ++ vdig-supply = <&vreg_l3c_1p2>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cam_imx355_default>; ++ ++ orientation = <1>; ++ rotation = <270>; ++ ++ port { ++ cam_imx355_ep: endpoint { ++ data-lanes = <1 2 3 4>; ++ link-frequencies = /bits/ 64 <360000000>; ++ remote-endpoint = <&csiphy2_ep>; ++ }; ++ }; ++ }; ++}; ++ ++&cci1_i2c1 { ++ /* DPHY S5K3T2 @ 0x10 */ ++ ++ s5k3t2_eeprom: eeprom@51 { ++ compatible = "puya,p24c64f", ++ "atmel,24c64"; ++ reg = <0x51>; ++ vcc-supply = <&vreg_l5c_1p8>; ++ read-only; ++ }; ++}; ++ ++&gmu { ++ status = "okay"; ++}; ++ ++&gpi_dma0 { ++ status = "okay"; ++}; ++ ++&gpi_dma1 { ++ status = "okay"; ++}; ++ ++&gpi_dma2 { ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ ++ zap-shader { ++ memory-region = <&gpu_mem>; ++ firmware-name = "qcom/sm8250/xiaomi/alioth/a650_zap.mbn"; ++ }; ++}; ++ ++&mdss { ++ status = "okay"; ++}; ++ ++&mdss_dsi0 { ++ vdda-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++ ++ panel: panel@0 { ++ compatible = "xiaomi,alioth-ams667xx01"; ++ reg = <0>; ++ ++ pinctrl-0 = <&sde_dsi_active &sde_te_active_sleep>; ++ pinctrl-1 = <&sde_dsi_sleep &sde_te_active_sleep>; ++ pinctrl-names = "default", "sleep"; ++ ++ vddio-supply = <&vreg_l14a_1p88>; ++ vci-supply = <&vreg_l11c_3p0>; ++ reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; ++ ++ port { ++ panel_in: endpoint { ++ remote-endpoint = <&mdss_dsi0_out>; ++ }; ++ }; ++ }; ++}; ++ ++&mdss_dsi0_out { ++ remote-endpoint = <&panel_in>; ++ data-lanes = <0 1 2 3>; ++}; ++ ++&mdss_dsi0_phy { ++ vdds-supply = <&vreg_l5a_0p88>; ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ nfc@28 { ++ compatible = "nxp,pn553", ++ "nxp,nxp-nci-i2c"; ++ reg = <0x28>; ++ ++ interrupt-parent = <&tlmm>; ++ interrupts = <111 IRQ_TYPE_EDGE_RISING>; ++ ++ enable-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>; ++ firmware-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&i2c3 { ++ clock-frequency = <1000000>; ++ status = "okay"; ++ ++ cs35l41_rcv: speaker-amp@40 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x40>; ++ VA-supply = <&vreg_s4a_1p8>; ++ VP-supply = <&vph_pwr>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <113 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 114 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 = "RCV"; ++ #sound-dai-cells = <1>; ++ }; ++ ++ cs35l41_lcv: speaker-amp@41 { ++ compatible = "cirrus,cs35l41"; ++ reg = <0x41>; ++ VA-supply = <&vreg_s4a_1p8>; ++ VP-supply = <&vph_pwr>; ++ interrupt-parent = <&tlmm>; ++ interrupts = <112 IRQ_TYPE_LEVEL_LOW>; ++ reset-gpios = <&tlmm 114 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 = "LCV"; ++ #sound-dai-cells = <1>; ++ }; ++}; ++ ++&i2c15 { ++ clock-frequency = <100000>; ++ status = "okay"; ++ ++ typec-mux@42 { ++ compatible = "fcs,fsa4480"; ++ reg = <0x42>; ++ ++ vcc-supply = <&vreg_bob>; ++ ++ mode-switch; ++ orientation-switch; ++ ++ port { ++ fsa4480_sbu_mux: endpoint { ++ remote-endpoint = <&pm8150b_typec_sbu_out>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c16 { ++ status = "okay"; ++ ++ pm8008: pmic@8 { ++ compatible = "qcom,pm8008"; ++ reg = <0x8>; ++ ++ interrupts-extended = <&tlmm 84 IRQ_TYPE_EDGE_RISING>; ++ reset-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>; ++ ++ vdd-l1-l2-supply = <&vreg_s8c_1p35>; ++ vdd-l3-l4-supply = <&vreg_bob>; ++ vdd-l5-supply = <&vreg_bob>; ++ vdd-l6-supply = <&vreg_bob>; ++ vdd-l7-supply = <&vreg_bob>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pm8008_int_default>, <&pm8008_reset_n_default>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pm8008 0 0 2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ #thermal-sensor-cells = <0>; ++ ++ regulators { ++ vreg_l1p: ldo1 { ++ regulator-name = "vreg_l1p"; ++ regulator-min-microvolt = <1056000>; ++ regulator-max-microvolt = <1056000>; ++ }; ++ ++ vreg_l2p: ldo2 { ++ regulator-name = "vreg_l2p"; ++ regulator-min-microvolt = <1104000>; ++ regulator-max-microvolt = <1104000>; ++ }; ++ ++ vreg_l3p: ldo3 { ++ regulator-name = "vreg_l3p"; ++ regulator-min-microvolt = <2704000>; ++ regulator-max-microvolt = <2704000>; ++ }; ++ ++ vreg_l4p: ldo4 { ++ regulator-name = "vreg_l4p"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ }; ++ ++ vreg_l5p: ldo5 { ++ regulator-name = "vreg_l5p"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ }; ++ ++ vreg_l6p: ldo6 { ++ regulator-name = "vreg_l6p"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ vreg_l7p: ldo7 { ++ regulator-name = "vreg_l7p"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2900000>; ++ }; ++ }; ++ }; ++}; ++ ++&spi2 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qup_spi2_data_clk>; ++ clock-frequency = <50000000>; ++ ++ irled@0 { ++ compatible = "ir-spi-led"; ++ reg = <0x0>; ++ ++ spi-max-frequency = <19200000>; ++ power-supply = <&vph_pwr>; ++ duty-cycle = /bits/ 8 <60>; ++ led-active-low; ++ }; ++}; ++ ++&qup_spi4_cs_gpio { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&qup_spi4_data_clk { ++ drive-strength = <6>; ++ bias-disable; ++}; ++ ++&spi4 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&qup_spi4_data_clk &qup_spi4_cs_gpio>; ++ cs-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>; ++ ++ touchscreen@0 { ++ compatible = "focaltech,ft8756-spi"; ++ reg = <0>; ++ ++ spi-max-frequency = <6000000>; ++ ++ pinctrl-0 = <&ts_active>; ++ pinctrl-names = "default"; ++ ++ irq-gpio = <&tlmm 39 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpio = <&tlmm 33 GPIO_ACTIVE_HIGH>; ++ ++ vio-supply = <&vreg_l10c_3p0>; ++ ibb-supply = <&vreg_l1c_1p8>; ++ }; ++}; ++ ++&pcie0 { ++ status = "okay"; ++}; ++ ++&pcie0_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&pcieport0 { ++ wifi@0 { ++ compatible = "pci17cb,1101"; ++ reg = <0x10000 0x0 0x0 0x0 0x0>; ++ ++ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; ++ vddaon-supply = <&vreg_pmu_aon_0p59>; ++ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; ++ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; ++ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; ++ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; ++ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; ++ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; ++ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; ++ }; ++}; ++ ++&pm8150_gpios { ++ vol_up_n: vol-up-n-state { ++ pins = "gpio6"; ++ function = "normal"; ++ power-source = <1>; ++ input-enable; ++ bias-pull-up; ++ }; ++}; ++ ++&pm8150b_vbus { ++ regulator-min-microamp = <500000>; ++ regulator-max-microamp = <3000000>; ++ status = "okay"; ++}; ++ ++&pm8150b_typec { ++ status = "okay"; ++ ++ vdd-pdphy-supply = <&vreg_l2a_3p1>; ++ ++ connector { ++ compatible = "usb-c-connector"; ++ ++ power-role = "dual"; ++ data-role = "dual"; ++ try-power-role = "sink"; ++ self-powered; ++ ++ op-sink-microwatt = <33000000>; ++ ++ source-pdos = ; ++ ++ sink-pdos = ; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ pm8150b_hs_in: endpoint { ++ remote-endpoint = <&usb_1_dwc3_hs_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ ++ pm8150b_typec_sbu_out: endpoint { ++ remote-endpoint = <&fsa4480_sbu_mux>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&pm8150b_fg { ++ status = "okay"; ++ monitored-battery = <&battery>; ++ power-supplies = <&pm8150b_charger>; ++}; ++ ++&pm8150b_charger { ++ status = "okay"; ++ monitored-battery = <&battery>; ++}; ++ ++&pm8150l_flash { ++ status = "okay"; ++ ++ led-0 { ++ function = LED_FUNCTION_FLASH; ++ color = ; ++ led-sources = <1>; ++ led-max-microamp = <300000>; ++ flash-max-microamp = <1000000>; ++ flash-max-timeout-us = <1280000>; ++ }; ++}; ++ ++&pon_pwrkey { ++ status = "okay"; ++}; ++ ++&pon_resin { ++ linux,code = ; ++ status = "okay"; ++}; ++ ++&qupv3_id_0 { ++ status = "okay"; ++}; ++ ++&qupv3_id_1 { ++ status = "okay"; ++}; ++ ++&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>; ++ }; ++}; ++ ++&vamacro { ++ status = "disabled"; ++}; ++ ++&lpass_tlmm { ++ status = "disabled"; ++}; ++ ++&sound { ++ compatible = "qcom,sm8250-sndcard"; ++ model = "xiaomi-alioth"; ++ 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_rcv 0>, <&cs35l41_lcv 0>; ++ }; ++ }; ++}; ++ ++&slpi { ++ firmware-name = "qcom/sm8250/xiaomi/alioth/slpi.mbn"; ++ status = "okay"; ++}; ++ ++&tlmm { ++ gpio-reserved-ranges = <28 4>, <40 4>; ++ ++ 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; ++ }; ++ }; ++ ++ 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; ++ }; ++ }; ++ ++ ts_active: ts-active { ++ mux { ++ pins = "gpio33", "gpio39"; ++ function = "gpio"; ++ }; ++ ++ config { ++ pins = "gpio33", "gpio39"; ++ drive-strength = <8>; ++ bias-pull-up; ++ }; ++ }; ++ ++ sde_dsi_active: sde_dsi_active-state { ++ pins = "gpio12"; ++ function = "gpio"; ++ drive-strength = <8>; ++ bias-disable; ++ output-high; ++ }; ++ ++ sde_dsi_sleep: sde-dsi-sleep-state { ++ pins = "gpio12"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-down; ++ output-high; ++ }; ++ ++ sde_te_active_sleep: sde_te_active-state { ++ pins = "gpio66"; ++ function = "mdp_vsync"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ sw_ctrl: sw-ctrl-state { ++ pins = "gpio124"; ++ function = "gpio"; ++ bias-pull-down; ++ }; ++ ++ pm8008_int_default: pm8008-int-default-state { ++ pins = "gpio84"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ pm8008_reset_n_default: pm8008-reset-n-default-state { ++ pins = "gpio77"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ cam_s5k5e9_default: cam-s5k5e9-default-state { ++ rst-pins { ++ pins = "gpio92"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ mclk1-pins { ++ pins = "gpio95"; ++ function = "cam_mclk"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ }; ++ ++ cam_imx355_default: cam-imx355-default-state { ++ rst-pins { ++ pins = "gpio78"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ mclk2-pins { ++ pins = "gpio96"; ++ function = "cam_mclk"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ }; ++ ++ cam_imx582_default: cam-imx582-default-state { ++ rst-pins { ++ pins = "gpio93"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ mclk0-pins { ++ pins = "gpio94"; ++ function = "cam_mclk"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ }; ++}; ++ ++&uart6 { ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "qcom,qca6390-bt"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sw_ctrl>; ++ swctrl-gpios = <&tlmm 124 GPIO_ACTIVE_HIGH>; ++ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; ++ vddaon-supply = <&vreg_pmu_aon_0p59>; ++ vddasd-supply = <&vreg_l16a_3p3>; ++ vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; ++ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; ++ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; ++ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; ++ }; ++}; ++ ++&usb_1 { ++ /* USB 2.0 only */ ++ qcom,select-utmi-as-pipe-clk; ++ status = "okay"; ++}; ++ ++&usb_1_dwc3 { ++ dr_mode = "otg"; ++ usb-role-switch; ++ maximum-speed = "high-speed"; ++ /* Remove USB3 phy */ ++ phys = <&usb_1_hsphy>; ++ phy-names = "usb2-phy"; ++}; ++ ++&usb_1_dwc3_hs_out { ++ remote-endpoint = <&pm8150b_hs_in>; ++}; ++ ++&usb_1_hsphy { ++ vdda-pll-supply = <&vreg_l5a_0p88>; ++ vdda18-supply = <&vreg_l12a_1p8>; ++ vdda33-supply = <&vreg_l2a_3p1>; ++ status = "okay"; ++}; ++ ++&ufs_mem_hc { ++ vcc-supply = <&vreg_l17a_3p0>; ++ vcc-max-microamp = <800000>; ++ vccq-supply = <&vreg_l6a_1p2>; ++ vccq-max-microamp = <800000>; ++ vccq2-supply = <&vreg_s4a_1p8>; ++ vccq2-max-microamp = <800000>; ++ status = "okay"; ++}; ++ ++&ufs_mem_phy { ++ vdda-phy-supply = <&vreg_l5a_0p88>; ++ vdda-pll-supply = <&vreg_l9a_1p2>; ++ status = "okay"; ++}; ++ ++&venus { ++ firmware-name = "qcom/sm8250/xiaomi/alioth/venus.mbn"; ++ status = "okay"; ++}; +\ No newline at end of file +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 7537f91aad93..197af21ac891 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -720,6 +720,16 @@ config DRM_PANEL_SAMSUNG_AMS639RQ08 + Say Y or M here if you want to enable support for the + Samsung AMS639RQ08 FHD Plus (2340x1080@60Hz) CMD mode panel. + ++config DRM_PANEL_SAMSUNG_AMS667XX01 ++ tristate "Samsung AMS667XX01 panel" ++ depends on OF ++ depends on DRM_MIPI_DSI ++ depends on BACKLIGHT_CLASS_DEVICE ++ help ++ Say Y or M here if you want to enable support for the ++ Samsung AMS667XX01 FHD Plus (2400x1080@120Hz) CMD mode panel, ++ display panels, such as the one found in the POCO F3 smartphone. ++ + config DRM_PANEL_SAMSUNG_S6E88A0_AMS427AP24 + tristate "Samsung AMS427AP24 panel with S6E88A0 controller" + depends on GPIOLIB && OF && REGULATOR +diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile +index 78860b1ac568..d1a7bd1e1954 100644 +--- a/drivers/gpu/drm/panel/Makefile ++++ b/drivers/gpu/drm/panel/Makefile +@@ -72,6 +72,7 @@ obj-$(CONFIG_DRM_PANEL_RENESAS_R69328) += panel-renesas-r69328.o + obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01) += panel-samsung-ams581vf01.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08) += panel-samsung-ams639rq08.o ++obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS667XX01) += panel-samsung-ams667xx01.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMSA26ZP01) += panel-samsung-amsa26zp01.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o +diff --git a/drivers/gpu/drm/panel/panel-samsung-ams667xx01.c b/drivers/gpu/drm/panel/panel-samsung-ams667xx01.c +new file mode 100644 +index 000000000000..751ebd18aeb4 +--- /dev/null ++++ b/drivers/gpu/drm/panel/panel-samsung-ams667xx01.c +@@ -0,0 +1,522 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Copyright (c) 2025 Vitalii Skorkin ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include