Devicetree
 help / color / mirror / Atom feed
* Re: MT7621 SoC Traffic Won't Flow on RGMII2 Bus/2nd GMAC
From: Arınç ÜNAL @ 2022-01-23 17:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: DENG Qingfang, Luiz Angelo Daros de Luca, Matthias Brugger,
	John Crispin, Siddhant Gupta, Ilya Lipnitskiy, Sergio Paracuellos,
	Felix Fietkau, Sean Wang, Mark Lee, Russell King, Jakub Kicinski,
	David Miller, René van Dorst,
	moderated list:ARM/Mediatek SoC support, netdev, linux-mips,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	openwrt-devel, erkin.bozoglu
In-Reply-To: <Ye1zwIFUa5LPQbQm@lunn.ch>

On 23/01/2022 18:26, Andrew Lunn wrote:
> On Sun, Jan 23, 2022 at 11:33:04AM +0300, Arınç ÜNAL wrote:
>> Hey Deng,
>>
>> On 23/01/2022 09:51, DENG Qingfang wrote:
>>> Hi,
>>>
>>> Do you set the ethernet pinmux correctly?
>>>
>>> &ethernet {
>>>       pinctrl-names = "default";
>>>       pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
>>> };
>>
>> This fixed it! We did have &rgmii2_pins on the gmac1 node (it was originally
>> on external_phy) so we never thought to investigate the pinctrl
>> configuration further! Turns out &rgmii2_pins needs to be defined on the
>> ethernet node instead.
> 
> PHYs are generally external, so pinmux on them makes no sense. PHYs in
> DT are not devices in the usual sense, so i don't think the driver
> core will handle pinmux for them, even if you did list them.
> 
> This could be interesting for the DT compliance checker. Ideally we
> want it to warn if it finds a pinmux configuration in a PHY node.

I don't see any warnings about it:

$ cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp 
drivers/staging/mt7621-dts/mt7621.dtsi mt7621.dtsi.preprocessed
$ dtc -I dts -O dtb -p 0x1000 mt7621.dtsi.preprocessed -o mt7621.dtb
drivers/staging/mt7621-dts/mt7621.dtsi:28.21-33.4: Warning 
(unit_address_vs_reg): /cpuintc@0: node has a unit name, but no reg property
drivers/staging/mt7621-dts/mt7621.dtsi:40.34-47.6: Warning 
(unit_address_vs_reg): /fixedregulator@0: node has a unit name, but no 
reg property
drivers/staging/mt7621-dts/mt7621.dtsi:49.39-56.4: Warning 
(unit_address_vs_reg): /fixedregulator@1: node has a unit name, but no 
reg property
drivers/staging/mt7621-dts/mt7621.dtsi:410.11-449.7: Warning 
(unit_address_vs_reg): /ethernet@1e100000/mdio-bus/switch0@0/ports: node 
has a reg or ranges property, but no unit name
drivers/staging/mt7621-dts/mt7621.dtsi:28.21-33.4: Warning 
(unique_unit_address): /cpuintc@0: duplicate unit-address (also used in 
node /fixedregulator@0)

> 
> It also sounds like you had them somewhere else wrong?

Yes, it was under the phy_external node:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/mt7621-dts/mt7621.dtsi#n350

I had put it under gmac1 node instead since we didn't enable the 
phy_external node.

Arınç

^ permalink raw reply

* [PATCH 6/6] arm64: dts: qcom: sdm845: add device tree for SHIFT6mq
From: Caleb Connolly @ 2022-01-23 17:38 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz

From: Alexander Martinz <amartinz@shiftphones.com>

Add initial support for the SHIFT SHIFT6mq (axolotl) based on
the sdm845-mtp DT.

Currently supported features:
* Buttons (power, volume)
* Bluetooth, DSPs and modem
* Display and GPU
* Touch
* UART
* USB peripheral mode
* WLAN

Co-developed-by: Caleb Connolly <caleb@connolly.tech>
Signed-off-by: Caleb Connolly <caleb@connolly.tech>
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
---
 arch/arm64/boot/dts/qcom/Makefile             |   1 +
 .../boot/dts/qcom/sdm845-shift-axolotl.dts    | 736 ++++++++++++++++++
 2 files changed, 737 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index f7232052d286..6e6f53f501e6 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -103,6 +103,7 @@ dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-sony-xperia-tama-akari.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-sony-xperia-tama-akatsuki.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-sony-xperia-tama-apollo.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-xiaomi-beryllium.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-shift-axolotl.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm850-lenovo-yoga-c630.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm6125-sony-xperia-seine-pdx201.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm6350-sony-xperia-lena-pdx213.dtb
diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
new file mode 100644
index 000000000000..8553c8bf79bd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022, Alexander Martinz <amartinz@shiftphones.com>
+ * Copyright (c) 2022, Caleb Connolly <caleb@connolly.tech>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sdm845.dtsi"
+#include "pm8998.dtsi"
+#include "pmi8998.dtsi"
+
+/ {
+	model = "SHIFT SHIFT6mq";
+	compatible = "shift,axolotl", "qcom,sdm845";
+	qcom,msm-id = <321 0x20001>;
+	qcom,board-id = <11 0>;
+
+	aliases {
+		display0 = &framebuffer0;
+		serial0 = &uart9;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0";
+
+		/* Use framebuffer setup by the bootloader. */
+		framebuffer0: framebuffer@9d400000 {
+			compatible = "simple-framebuffer";
+			reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
+			width = <1080>;
+			height = <2160>;
+			stride = <(1080 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&volume_up_gpio>;
+
+		vol-up {
+			label = "volume_up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&pm8998_gpio 6 GPIO_ACTIVE_LOW>;
+			debounce-interval = <15>;
+		};
+	};
+
+	reserved-memory {
+		framebuffer_region@9d400000 {
+			reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
+			no-map;
+		};
+
+		ramoops: ramoops@b0000000 {
+			compatible = "ramoops";
+			reg = <0 0xb0000000 0 0x00400000>;
+			record-size = <0x40000>;
+			console-size = <0x40000>;
+			ftrace-size = <0x40000>;
+			pmsg-size = <0x200000>;
+			ecc-size = <0x0>;
+		};
+	};
+
+	battery: battery {
+		compatible = "simple-battery";
+
+		charge-full-design-microamp-hours = <3850000>;
+		voltage-min-design-microvolt = <3600000>;
+		voltage-max-design-microvolt = <4400000>;
+	};
+
+	vph_pwr: vph-pwr-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vph_pwr";
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
+	};
+
+	vreg_s4a_1p8: pm8998-smps4 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_s4a_1p8";
+
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+
+		regulator-always-on;
+		regulator-boot-on;
+
+		vin-supply = <&vph_pwr>;
+	};
+};
+
+&adsp_pas {
+	status = "okay";
+	firmware-name = "qcom/sdm845/axolotl/adsp.mbn";
+};
+
+&apps_rsc {
+	pm8998-rpmh-regulators {
+		compatible = "qcom,pm8998-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-s11-supply = <&vph_pwr>;
+		vdd-s12-supply = <&vph_pwr>;
+		vdd-s13-supply = <&vph_pwr>;
+		vdd-l1-l27-supply = <&vreg_s7a_1p025>;
+		vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
+		vdd-l3-l11-supply = <&vreg_s7a_1p025>;
+		vdd-l4-l5-supply = <&vreg_s7a_1p025>;
+		vdd-l6-supply = <&vph_pwr>;
+		vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+		vdd-l9-supply = <&vreg_bob>;
+		vdd-l10-l23-l25-supply = <&vreg_bob>;
+		vdd-l13-l19-l21-supply = <&vreg_bob>;
+		vdd-l16-l28-supply = <&vreg_bob>;
+		vdd-l18-l22-supply = <&vreg_bob>;
+		vdd-l20-l24-supply = <&vreg_bob>;
+		vdd-l26-supply = <&vreg_s3a_1p35>;
+		vin-lvs-1-2-supply = <&vreg_s4a_1p8>;
+
+		vreg_s2a_1p125: smps2 {
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1100000>;
+		};
+
+		vreg_s3a_1p35: smps3 {
+			regulator-min-microvolt = <1352000>;
+			regulator-max-microvolt = <1352000>;
+		};
+
+		vreg_s5a_2p04: smps5 {
+			regulator-min-microvolt = <1904000>;
+			regulator-max-microvolt = <2040000>;
+		};
+
+		vreg_s7a_1p025: smps7 {
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <1028000>;
+		};
+
+		vdd_qusb_hs0:
+		vdda_hp_pcie_core:
+		vdda_mipi_csi0_0p9:
+		vdda_mipi_csi1_0p9:
+		vdda_mipi_csi2_0p9:
+		vdda_mipi_dsi0_pll:
+		vdda_mipi_dsi1_pll:
+		vdda_qlink_lv:
+		vdda_qlink_lv_ck:
+		vdda_qrefs_0p875:
+		vdda_pcie_core:
+		vdda_pll_cc_ebi01:
+		vdda_pll_cc_ebi23:
+		vdda_sp_sensor:
+		vdda_ufs1_core:
+		vdda_ufs2_core:
+		vdda_usb1_ss_core:
+		vdda_usb2_ss_core:
+		vreg_l1a_0p875: ldo1 {
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <880000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vddpx_10:
+		vreg_l2a_1p2: ldo2 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-always-on;
+		};
+
+		vreg_l3a_1p0: ldo3 {
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vdd_wcss_cx:
+		vdd_wcss_mx:
+		vdda_wcss_pll:
+		vreg_l5a_0p8: ldo5 {
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vddpx_13:
+		vreg_l6a_1p8: ldo6 {
+			regulator-min-microvolt = <1856000>;
+			regulator-max-microvolt = <1856000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a_1p8: ldo7 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a_1p2: ldo8 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1248000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a_1p8: ldo9 {
+			regulator-min-microvolt = <1704000>;
+			regulator-max-microvolt = <2928000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10a_1p8: ldo10 {
+			regulator-min-microvolt = <1704000>;
+			regulator-max-microvolt = <2928000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11a_1p0: ldo11 {
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1048000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vdd_qfprom:
+		vdd_qfprom_sp:
+		vdda_apc1_cs_1p8:
+		vdda_gfx_cs_1p8:
+		vdda_qrefs_1p8:
+		vdda_qusb_hs0_1p8:
+		vddpx_11:
+		vreg_l12a_1p8: ldo12 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vddpx_2:
+		vreg_l13a_2p95: ldo13 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14a_1p88: ldo14 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15a_1p8: ldo15 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16a_2p7: ldo16 {
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <2704000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17a_1p3: ldo17 {
+			regulator-min-microvolt = <1304000>;
+			regulator-max-microvolt = <1304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l18a_2p7: ldo18 {
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l19a_3p0: ldo19 {
+			regulator-min-microvolt = <2856000>;
+			regulator-max-microvolt = <3104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l20a_2p95: ldo20 {
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l21a_2p95: ldo21 {
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l22a_2p85: ldo22 {
+			regulator-min-microvolt = <2864000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l23a_3p3: ldo23 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vdda_qusb_hs0_3p1:
+		vreg_l24a_3p075: ldo24 {
+			regulator-min-microvolt = <3088000>;
+			regulator-max-microvolt = <3088000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l25a_3p3: ldo25 {
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vdda_hp_pcie_1p2:
+		vdda_hv_ebi0:
+		vdda_hv_ebi1:
+		vdda_hv_ebi2:
+		vdda_hv_ebi3:
+		vdda_mipi_csi_1p25:
+		vdda_mipi_dsi0_1p2:
+		vdda_mipi_dsi1_1p2:
+		vdda_pcie_1p2:
+		vdda_ufs1_1p2:
+		vdda_ufs2_1p2:
+		vdda_usb1_ss_1p2:
+		vdda_usb2_ss_1p2:
+		vreg_l26a_1p2: ldo26 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l28a_3p0: ldo28 {
+			regulator-min-microvolt = <2856000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_lvs1a_1p8: lvs1 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		vreg_lvs2a_1p8: lvs2 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+	};
+
+	pmi8998-rpmh-regulators {
+		compatible = "qcom,pmi8998-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		vdd-bob-supply = <&vph_pwr>;
+
+		vreg_bob: bob {
+			regulator-min-microvolt = <3312000>;
+			regulator-max-microvolt = <3600000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+			regulator-allow-bypass;
+		};
+	};
+
+	pm8005-rpmh-regulators {
+		compatible = "qcom,pm8005-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>;
+
+		vreg_s3c_0p6: smps3 {
+			regulator-min-microvolt = <600000>;
+			regulator-max-microvolt = <600000>;
+		};
+	};
+};
+
+&cdsp_pas {
+	status = "okay";
+	firmware-name = "qcom/sdm845/axolotl/cdsp.mbn";
+};
+
+&dsi0 {
+	status = "okay";
+	vdda-supply = <&vdda_mipi_dsi0_1p2>;
+
+	panel@0 {
+		compatible = "visionox,rm69299-shift";
+		status = "okay";
+		reg = <0>;
+		vdda-supply = <&vreg_l14a_1p88>;
+		vdd3p3-supply = <&vreg_l28a_3p0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+		pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+		port {
+			panel_in_0: endpoint {
+				remote-endpoint = <&dsi0_out>;
+			};
+		};
+	};
+};
+
+&dsi0_out {
+	remote-endpoint = <&panel_in_0>;
+	data-lanes = <0 1 2 3>;
+};
+
+&dsi0_phy {
+	status = "okay";
+	vdds-supply = <&vdda_mipi_dsi0_pll>;
+};
+
+&gcc {
+	protected-clocks = <GCC_QSPI_CORE_CLK>,
+			   <GCC_QSPI_CORE_CLK_SRC>,
+			   <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+			   <GCC_LPASS_Q6_AXI_CLK>,
+			   <GCC_LPASS_SWAY_CLK>;
+};
+
+&gmu {
+	status = "okay";
+};
+
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		memory-region = <&gpu_mem>;
+		firmware-name = "qcom/sdm845/axolotl/a630_zap.mbn";
+	};
+};
+
+&i2c5 {
+	status="okay";
+
+	touchscreen@38 {
+		compatible = "focaltech,fts8719";
+		reg = <0x38>;
+		wakeup-source;
+		interrupt-parent = <&tlmm>;
+		interrupts = <125 0x2>;
+		vdd-supply = <&vreg_l28a_3p0>;
+		vcc-i2c-supply = <&vreg_l14a_1p88>;
+
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&ts_int_active &ts_reset_active>;
+		pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+
+		reset-gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+		irq-gpio = <&tlmm 125 GPIO_TRANSITORY>;
+		touchscreen-size-x = <1080>;
+		touchscreen-size-y = <2160>;
+		focaltech,max-touch-number = <5>;
+	};
+};
+
+&ipa {
+	status = "okay";
+
+	memory-region = <&ipa_fw_mem>;
+	firmware-name = "qcom/sdm845/axolotl/ipa_fws.mbn";
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mss_pil {
+	status = "okay";
+	firmware-name = "qcom/sdm845/axolotl/mba.mbn", "qcom/sdm845/axolotl/modem.mbn";
+};
+
+&pm8998_gpio {
+	volume_up_gpio: pm8998_gpio6 {
+		pinconf {
+			pins = "gpio6";
+			function = "normal";
+			input-enable;
+			bias-pull-up;
+			qcom,drive-strength = <0>;
+		};
+	};
+};
+
+&pm8998_pon {
+	volume_down_resin: resin {
+		compatible = "qcom,pm8941-resin";
+		interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+		debounce = <15625>;
+		bias-pull-up;
+		linux,code = <KEY_VOLUMEDOWN>;
+	};
+};
+
+&qup_uart9_default {
+	pinconf-rx {
+		pins = "gpio5";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	pinconf-tx {
+		pins = "gpio4";
+		drive-strength = <2>;
+		bias-disable;
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&tlmm {
+	gpio-reserved-ranges = <0 4>, <81 4>;
+
+	sde_dsi_active: sde-dsi-active {
+		mux {
+			pins = "gpio6", "gpio11";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio6", "gpio11";
+			drive-strength = <8>;
+			bias-disable = <0>;
+		};
+	};
+
+	sde_dsi_suspend: sde-dsi-suspend {
+		mux {
+			pins = "gpio6", "gpio11";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio6", "gpio11";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+
+	sde_te_active: sde-te-active {
+		mux {
+			pins = "gpio10";
+			function = "mdp_vsync";
+		};
+
+		config {
+			pins = "gpio10";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+
+	sde_te_suspend: sde-te-suspend {
+		mux {
+			pins = "gpio10";
+			function = "mdp_vsync";
+		};
+
+		config {
+			pins = "gpio10";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+
+	ts_int_active: ts-int-active {
+		mux {
+			pins = "gpio125";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio125";
+			drive-strength = <8>;
+			bias-pull-up;
+			input-enable;
+		};
+	};
+
+	ts_int_suspend: ts-int-suspend {
+		mux {
+			pins = "gpio125";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio125";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+		};
+	};
+
+	ts_reset_active: ts-reset-active {
+		mux {
+			pins = "gpio99";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio99";
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+	};
+
+	ts_reset_suspend: ts-reset-suspend {
+		mux {
+			pins = "gpio99";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio99";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+};
+
+&uart6 {
+	status = "okay";
+
+	bluetooth {
+		compatible = "qcom,wcn3990-bt";
+
+		vddio-supply = <&vreg_s4a_1p8>;
+		vddxo-supply = <&vreg_l7a_1p8>;
+		vddrf-supply = <&vreg_l17a_1p3>;
+		vddch0-supply = <&vreg_l25a_3p3>;
+		max-speed = <3200000>;
+	};
+};
+
+&uart9 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	status = "okay";
+
+	reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
+
+	vcc-supply = <&vreg_l20a_2p95>;
+	vcc-max-microamp = <600000>;
+};
+
+&ufs_mem_phy {
+	status = "okay";
+
+	vdda-phy-supply = <&vdda_ufs1_core>;
+	vdda-pll-supply = <&vdda_ufs1_1p2>;
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+	status = "okay";
+
+	vdd-supply = <&vreg_l1a_0p875>;
+	vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
+	vdda-pll-supply = <&vreg_l12a_1p8>;
+};
+
+&usb_1_qmpphy {
+	status = "okay";
+
+	vdda-phy-supply = <&vreg_l26a_1p2>;
+	vdda-pll-supply = <&vreg_l1a_0p875>;
+};
+
+&venus {
+	status = "okay";
+	firmware-name = "qcom/sdm845/axolotl/venus.mbn";
+};
+
+&wifi {
+	status = "okay";
+
+	vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+	vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+	vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+	vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+	vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
+
+	qcom,snoc-host-cap-8bit-quirk;
+};
--
2.34.1



^ permalink raw reply related

* [PATCH 5/6] dt-bindings: vendor-prefixes: add vendor prefix for SHIFT
From: Caleb Connolly @ 2022-01-23 17:38 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz

Add SHIFT vendor prefix, SHIFT make various devices such as the SHIF6mq
phone.

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index c48ce3c54951..68981e865396 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1058,6 +1058,8 @@ patternProperties:
     description: SGX Sensortech
   "^sharp,.*":
     description: Sharp Corporation
+  "^shift,.*":
+    description: SHIFT GmbH
   "^shimafuji,.*":
     description: Shimafuji Electric, Inc.
   "^shiratech,.*":
--
2.34.1



^ permalink raw reply related

* [PATCH 4/6] drm/panel: visionox-rm69299: support the variant found in the SHIFT6mq
From: Caleb Connolly @ 2022-01-23 17:37 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz

Add support for another variant of the rm69299 panel. This panel is
1080x2160 and is found in the shift-axolotl (SHIFT6mq).

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
---
 .../gpu/drm/panel/panel-visionox-rm69299.c    | 281 ++++++++++++++----
 1 file changed, 221 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
index eb43503ec97b..e3c58ed8a96a 100644
--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c
+++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
@@ -20,10 +20,42 @@ struct visionox_rm69299 {
 	struct regulator_bulk_data supplies[2];
 	struct gpio_desc *reset_gpio;
 	struct mipi_dsi_device *dsi;
+	const struct drm_display_mode *mode;
 	bool prepared;
 	bool enabled;
 };

+static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = {
+	.name = "1080x2248",
+	.clock = 158695,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + 26,
+	.hsync_end = 1080 + 26 + 2,
+	.htotal = 1080 + 26 + 2 + 36,
+	.vdisplay = 2248,
+	.vsync_start = 2248 + 56,
+	.vsync_end = 2248 + 56 + 4,
+	.vtotal = 2248 + 56 + 4 + 4,
+	.flags = 0,
+};
+
+static const struct drm_display_mode visionox_rm69299_1080x2160_60hz = {
+	.name = "Visionox 1080x2160@60Hz",
+	.clock = 158695,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + 26,
+	.hsync_end = 1080 + 26 + 2,
+	.htotal = 1080 + 26 + 2 + 36,
+	.vdisplay = 2160,
+	.vsync_start = 2160 + 8,
+	.vsync_end = 2160 + 8 + 4,
+	.vtotal = 2160 + 8 + 4 + 4,
+	.flags = 0,
+	.width_mm = 74,
+	.height_mm = 131,
+	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
 static inline struct visionox_rm69299 *panel_to_ctx(struct drm_panel *panel)
 {
 	return container_of(panel, struct visionox_rm69299, panel);
@@ -68,14 +100,16 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel)

 	ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
 	if (ret < 0)
-		dev_err(ctx->panel.dev, "set_display_off cmd failed ret = %d\n", ret);
+		dev_err(ctx->panel.dev, "set_display_off cmd failed ret = %d\n",
+			ret);

 	/* 120ms delay required here as per DCS spec */
 	msleep(120);

 	ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
 	if (ret < 0) {
-		dev_err(ctx->panel.dev, "enter_sleep cmd failed ret = %d\n", ret);
+		dev_err(ctx->panel.dev, "enter_sleep cmd failed ret = %d\n",
+			ret);
 	}

 	ret = visionox_rm69299_power_off(ctx);
@@ -84,10 +118,123 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel)
 	return ret;
 }

+#define VISIONOX_RM69299_SHIFT_INIT_SEQ_LEN 432
+
+static const u8 visionox_rm69299_1080x2248_60hz_init_seq[VISIONOX_RM69299_SHIFT_INIT_SEQ_LEN][2] = {
+	{ 0xFE, 0x40 }, { 0x05, 0x04 }, { 0x06, 0x08 }, { 0x08, 0x04 },
+	{ 0x09, 0x08 }, { 0x0A, 0x07 }, { 0x0B, 0xCC }, { 0x0C, 0x07 },
+	{ 0x0D, 0x90 }, { 0x0F, 0x87 }, { 0x20, 0x8D }, { 0x21, 0x8D },
+	{ 0x24, 0x05 }, { 0x26, 0x05 }, { 0x28, 0x05 }, { 0x2A, 0x05 },
+	{ 0x2D, 0x28 }, { 0x2F, 0x28 }, { 0x30, 0x32 }, { 0x31, 0x32 },
+	{ 0x37, 0x80 }, { 0x38, 0x30 }, { 0x39, 0xA8 }, { 0x46, 0x48 },
+	{ 0x47, 0x48 }, { 0x6B, 0x10 }, { 0x6F, 0x02 }, { 0x74, 0x2B },
+	{ 0x80, 0x1A }, { 0xFE, 0x40 }, { 0x93, 0x10 }, { 0x16, 0x00 },
+	{ 0x85, 0x07 }, { 0x84, 0x01 }, { 0x86, 0x0F }, { 0x87, 0x05 },
+	{ 0x8C, 0x00 }, { 0x88, 0x2E }, { 0x89, 0x2E }, { 0x8B, 0x09 },
+	{ 0x95, 0x00 }, { 0x91, 0x00 }, { 0x90, 0x00 }, { 0x8D, 0xD0 },
+	{ 0x8A, 0x03 }, { 0xFE, 0xA0 }, { 0x13, 0x00 }, { 0x33, 0x00 },
+	{ 0x0B, 0x33 }, { 0x36, 0x1E }, { 0x31, 0x88 }, { 0x32, 0x88 },
+	{ 0x37, 0xF1 }, { 0xFE, 0x50 }, { 0x00, 0x00 }, { 0x01, 0x00 },
+	{ 0x02, 0x00 }, { 0x03, 0xE9 }, { 0x04, 0x00 }, { 0x05, 0xF6 },
+	{ 0x06, 0x01 }, { 0x07, 0x2C }, { 0x08, 0x01 }, { 0x09, 0x62 },
+	{ 0x0A, 0x01 }, { 0x0B, 0x98 }, { 0x0C, 0x01 }, { 0x0D, 0xBF },
+	{ 0x0E, 0x01 }, { 0x0F, 0xF6 }, { 0x10, 0x02 }, { 0x11, 0x24 },
+	{ 0x12, 0x02 }, { 0x13, 0x4E }, { 0x14, 0x02 }, { 0x15, 0x70 },
+	{ 0x16, 0x02 }, { 0x17, 0xAF }, { 0x18, 0x02 }, { 0x19, 0xE2 },
+	{ 0x1A, 0x03 }, { 0x1B, 0x1F }, { 0x1C, 0x03 }, { 0x1D, 0x52 },
+	{ 0x1E, 0x03 }, { 0x1F, 0x82 }, { 0x20, 0x03 }, { 0x21, 0xB6 },
+	{ 0x22, 0x03 }, { 0x23, 0xF0 }, { 0x24, 0x04 }, { 0x25, 0x1F },
+	{ 0x26, 0x04 }, { 0x27, 0x37 }, { 0x28, 0x04 }, { 0x29, 0x59 },
+	{ 0x2A, 0x04 }, { 0x2B, 0x68 }, { 0x30, 0x04 }, { 0x31, 0x85 },
+	{ 0x32, 0x04 }, { 0x33, 0xA2 }, { 0x34, 0x04 }, { 0x35, 0xBC },
+	{ 0x36, 0x04 }, { 0x37, 0xD8 }, { 0x38, 0x04 }, { 0x39, 0xF4 },
+	{ 0x3A, 0x05 }, { 0x3B, 0x0E }, { 0x40, 0x05 }, { 0x41, 0x13 },
+	{ 0x42, 0x05 }, { 0x43, 0x1F }, { 0x44, 0x05 }, { 0x45, 0x1F },
+	{ 0x46, 0x00 }, { 0x47, 0x00 }, { 0x48, 0x01 }, { 0x49, 0x43 },
+	{ 0x4A, 0x01 }, { 0x4B, 0x4C }, { 0x4C, 0x01 }, { 0x4D, 0x6F },
+	{ 0x4E, 0x01 }, { 0x4F, 0x92 }, { 0x50, 0x01 }, { 0x51, 0xB5 },
+	{ 0x52, 0x01 }, { 0x53, 0xD4 }, { 0x58, 0x02 }, { 0x59, 0x06 },
+	{ 0x5A, 0x02 }, { 0x5B, 0x33 }, { 0x5C, 0x02 }, { 0x5D, 0x59 },
+	{ 0x5E, 0x02 }, { 0x5F, 0x7D }, { 0x60, 0x02 }, { 0x61, 0xBD },
+	{ 0x62, 0x02 }, { 0x63, 0xF7 }, { 0x64, 0x03 }, { 0x65, 0x31 },
+	{ 0x66, 0x03 }, { 0x67, 0x63 }, { 0x68, 0x03 }, { 0x69, 0x9D },
+	{ 0x6A, 0x03 }, { 0x6B, 0xD2 }, { 0x6C, 0x04 }, { 0x6D, 0x05 },
+	{ 0x6E, 0x04 }, { 0x6F, 0x38 }, { 0x70, 0x04 }, { 0x71, 0x51 },
+	{ 0x72, 0x04 }, { 0x73, 0x70 }, { 0x74, 0x04 }, { 0x75, 0x85 },
+	{ 0x76, 0x04 }, { 0x77, 0xA1 }, { 0x78, 0x04 }, { 0x79, 0xC0 },
+	{ 0x7A, 0x04 }, { 0x7B, 0xD8 }, { 0x7C, 0x04 }, { 0x7D, 0xF2 },
+	{ 0x7E, 0x05 }, { 0x7F, 0x10 }, { 0x80, 0x05 }, { 0x81, 0x21 },
+	{ 0x82, 0x05 }, { 0x83, 0x2E }, { 0x84, 0x05 }, { 0x85, 0x3A },
+	{ 0x86, 0x05 }, { 0x87, 0x3E }, { 0x88, 0x00 }, { 0x89, 0x00 },
+	{ 0x8A, 0x01 }, { 0x8B, 0x86 }, { 0x8C, 0x01 }, { 0x8D, 0x8F },
+	{ 0x8E, 0x01 }, { 0x8F, 0xB3 }, { 0x90, 0x01 }, { 0x91, 0xD7 },
+	{ 0x92, 0x01 }, { 0x93, 0xFB }, { 0x94, 0x02 }, { 0x95, 0x18 },
+	{ 0x96, 0x02 }, { 0x97, 0x4F }, { 0x98, 0x02 }, { 0x99, 0x7E },
+	{ 0x9A, 0x02 }, { 0x9B, 0xA6 }, { 0x9C, 0x02 }, { 0x9D, 0xCF },
+	{ 0x9E, 0x03 }, { 0x9F, 0x14 }, { 0xA4, 0x03 }, { 0xA5, 0x52 },
+	{ 0xA6, 0x03 }, { 0xA7, 0x93 }, { 0xAC, 0x03 }, { 0xAD, 0xCF },
+	{ 0xAE, 0x04 }, { 0xAF, 0x08 }, { 0xB0, 0x04 }, { 0xB1, 0x42 },
+	{ 0xB2, 0x04 }, { 0xB3, 0x7F }, { 0xB4, 0x04 }, { 0xB5, 0xB4 },
+	{ 0xB6, 0x04 }, { 0xB7, 0xCC }, { 0xB8, 0x04 }, { 0xB9, 0xF2 },
+	{ 0xBA, 0x05 }, { 0xBB, 0x0C }, { 0xBC, 0x05 }, { 0xBD, 0x26 },
+	{ 0xBE, 0x05 }, { 0xBF, 0x4B }, { 0xC0, 0x05 }, { 0xC1, 0x64 },
+	{ 0xC2, 0x05 }, { 0xC3, 0x83 }, { 0xC4, 0x05 }, { 0xC5, 0xA1 },
+	{ 0xC6, 0x05 }, { 0xC7, 0xBA }, { 0xC8, 0x05 }, { 0xC9, 0xC4 },
+	{ 0xCA, 0x05 }, { 0xCB, 0xD5 }, { 0xCC, 0x05 }, { 0xCD, 0xD5 },
+	{ 0xCE, 0x00 }, { 0xCF, 0xCE }, { 0xD0, 0x00 }, { 0xD1, 0xDB },
+	{ 0xD2, 0x01 }, { 0xD3, 0x32 }, { 0xD4, 0x01 }, { 0xD5, 0x3B },
+	{ 0xD6, 0x01 }, { 0xD7, 0x74 }, { 0xD8, 0x01 }, { 0xD9, 0x7D },
+	{ 0xFE, 0x60 }, { 0x00, 0xCC }, { 0x01, 0x0F }, { 0x02, 0xFF },
+	{ 0x03, 0x01 }, { 0x04, 0x00 }, { 0x05, 0x02 }, { 0x06, 0x00 },
+	{ 0x07, 0x00 }, { 0x09, 0xC4 }, { 0x0A, 0x00 }, { 0x0B, 0x04 },
+	{ 0x0C, 0x01 }, { 0x0D, 0x00 }, { 0x0E, 0x04 }, { 0x0F, 0x00 },
+	{ 0x10, 0x71 }, { 0x12, 0xC4 }, { 0x13, 0x00 }, { 0x14, 0x04 },
+	{ 0x15, 0x01 }, { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 },
+	{ 0x19, 0x71 }, { 0x1B, 0xC4 }, { 0x1C, 0x00 }, { 0x1D, 0x02 },
+	{ 0x1E, 0x00 }, { 0x1F, 0x00 }, { 0x20, 0x08 }, { 0x21, 0x66 },
+	{ 0x22, 0xB4 }, { 0x24, 0xC4 }, { 0x25, 0x00 }, { 0x26, 0x02 },
+	{ 0x27, 0x00 }, { 0x28, 0x00 }, { 0x29, 0x07 }, { 0x2A, 0x66 },
+	{ 0x2B, 0xB4 }, { 0x2F, 0xC4 }, { 0x30, 0x00 }, { 0x31, 0x04 },
+	{ 0x32, 0x01 }, { 0x33, 0x00 }, { 0x34, 0x03 }, { 0x35, 0x00 },
+	{ 0x36, 0x71 }, { 0x38, 0xC4 }, { 0x39, 0x00 }, { 0x3A, 0x04 },
+	{ 0x3B, 0x01 }, { 0x3D, 0x00 }, { 0x3F, 0x05 }, { 0x40, 0x00 },
+	{ 0x41, 0x71 }, { 0x83, 0xCE }, { 0x84, 0x02 }, { 0x85, 0x20 },
+	{ 0x86, 0xDC }, { 0x87, 0x00 }, { 0x88, 0x04 }, { 0x89, 0x00 },
+	{ 0x8A, 0xBB }, { 0x8B, 0x80 }, { 0xC7, 0x0E }, { 0xC8, 0x05 },
+	{ 0xC9, 0x1F }, { 0xCA, 0x06 }, { 0xCB, 0x00 }, { 0xCC, 0x03 },
+	{ 0xCD, 0x04 }, { 0xCE, 0x1F }, { 0xCF, 0x1F }, { 0xD0, 0x1F },
+	{ 0xD1, 0x1F }, { 0xD2, 0x1F }, { 0xD3, 0x1F }, { 0xD4, 0x1F },
+	{ 0xD5, 0x1F }, { 0xD6, 0x1F }, { 0xD7, 0x17 }, { 0xD8, 0x1F },
+	{ 0xD9, 0x16 }, { 0xDA, 0x1F }, { 0xDB, 0x0E }, { 0xDC, 0x01 },
+	{ 0xDD, 0x1F }, { 0xDE, 0x02 }, { 0xDF, 0x00 }, { 0xE0, 0x03 },
+	{ 0xE1, 0x04 }, { 0xE2, 0x1F }, { 0xE3, 0x1F }, { 0xE4, 0x1F },
+	{ 0xE5, 0x1F }, { 0xE6, 0x1F }, { 0xE7, 0x1F }, { 0xE8, 0x1F },
+	{ 0xE9, 0x1F }, { 0xEA, 0x1F }, { 0xEB, 0x17 }, { 0xEC, 0x1F },
+	{ 0xED, 0x16 }, { 0xEE, 0x1F }, { 0xEF, 0x03 }, { 0xFE, 0x70 },
+	{ 0x5A, 0x0B }, { 0x5B, 0x0B }, { 0x5C, 0x55 }, { 0x5D, 0x24 },
+	{ 0xFE, 0x90 }, { 0x12, 0x24 }, { 0x13, 0x49 }, { 0x14, 0x92 },
+	{ 0x15, 0x86 }, { 0x16, 0x61 }, { 0x17, 0x18 }, { 0x18, 0x24 },
+	{ 0x19, 0x49 }, { 0x1A, 0x92 }, { 0x1B, 0x86 }, { 0x1C, 0x61 },
+	{ 0x1D, 0x18 }, { 0x1E, 0x24 }, { 0x1F, 0x49 }, { 0x20, 0x92 },
+	{ 0x21, 0x86 }, { 0x22, 0x61 }, { 0x23, 0x18 }, { 0xFE, 0x40 },
+	{ 0x0E, 0x10 }, { 0xFE, 0xA0 }, { 0x04, 0x80 }, { 0x16, 0x00 },
+	{ 0x26, 0x10 }, { 0x2F, 0x37 }, { 0xFE, 0xD0 }, { 0x06, 0x0F },
+	{ 0x4B, 0x00 }, { 0x56, 0x4A }, { 0xFE, 0x00 }, { 0xC2, 0x09 },
+	{ 0x35, 0x00 }, { 0xFE, 0x70 }, { 0x7D, 0x61 }, { 0x7F, 0x00 },
+	{ 0x7E, 0x4E }, { 0x52, 0x2C }, { 0x49, 0x00 }, { 0x4A, 0x00 },
+	{ 0x4B, 0x00 }, { 0x4C, 0x00 }, { 0x4D, 0xE8 }, { 0x4E, 0x25 },
+	{ 0x4F, 0x6E }, { 0x50, 0xAE }, { 0x51, 0x2F }, { 0xAD, 0xF4 },
+	{ 0xAE, 0x8F }, { 0xAF, 0x00 }, { 0xB0, 0x54 }, { 0xB1, 0x3A },
+	{ 0xB2, 0x00 }, { 0xB3, 0x00 }, { 0xB4, 0x00 }, { 0xB5, 0x00 },
+	{ 0xB6, 0x18 }, { 0xB7, 0x30 }, { 0xB8, 0x4A }, { 0xB9, 0x98 },
+	{ 0xBA, 0x30 }, { 0xBB, 0x60 }, { 0xBC, 0x50 }, { 0xBD, 0x00 },
+	{ 0xBE, 0x00 }, { 0xBF, 0x39 }, { 0xFE, 0x00 }, { 0x51, 0x66 },
+};
+
 static int visionox_rm69299_prepare(struct drm_panel *panel)
 {
 	struct visionox_rm69299 *ctx = panel_to_ctx(panel);
-	int ret;
+	int ret, i;

 	if (ctx->prepared)
 		return 0;
@@ -98,34 +245,55 @@ static int visionox_rm69299_prepare(struct drm_panel *panel)

 	ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM;

-	ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xfe, 0x00 }, 2);
-	if (ret < 0) {
-		dev_err(ctx->panel.dev, "cmd set tx 0 failed, ret = %d\n", ret);
-		goto power_off;
-	}
-
-	ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xc2, 0x08 }, 2);
-	if (ret < 0) {
-		dev_err(ctx->panel.dev, "cmd set tx 1 failed, ret = %d\n", ret);
-		goto power_off;
-	}
-
-	ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x35, 0x00 }, 2);
-	if (ret < 0) {
-		dev_err(ctx->panel.dev, "cmd set tx 2 failed, ret = %d\n", ret);
-		goto power_off;
-	}
-
-	ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x51, 0xff }, 2);
-	if (ret < 0) {
-		dev_err(ctx->panel.dev, "cmd set tx 3 failed, ret = %d\n", ret);
-		goto power_off;
+	if (ctx->mode == &visionox_rm69299_1080x2160_60hz) {
+		for (i = 0; i < VISIONOX_RM69299_SHIFT_INIT_SEQ_LEN; i++) {
+			ret = mipi_dsi_dcs_write_buffer(ctx->dsi,
+				visionox_rm69299_1080x2248_60hz_init_seq[i], 2);
+			if (ret < 0) {
+				dev_err(ctx->panel.dev,
+					"cmd set tx 0 failed, ret = %d\n", ret);
+				return ret;
+			}
+		}
+	} else {
+		ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]){ 0xfe, 0x00 },
+						2);
+		if (ret < 0) {
+			dev_err(ctx->panel.dev,
+				"cmd set tx 0 failed, ret = %d\n", ret);
+			return ret;
+		}
+
+		ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]){ 0xc2, 0x08 },
+						2);
+		if (ret < 0) {
+			dev_err(ctx->panel.dev,
+				"cmd set tx 1 failed, ret = %d\n", ret);
+			return ret;
+		}
+
+		ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]){ 0x35, 0x00 },
+						2);
+		if (ret < 0) {
+			dev_err(ctx->panel.dev,
+				"cmd set tx 2 failed, ret = %d\n", ret);
+			return ret;
+		}
+
+		ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]){ 0x51, 0xff },
+						2);
+		if (ret < 0) {
+			dev_err(ctx->panel.dev,
+				"cmd set tx 3 failed, ret = %d\n", ret);
+			return ret;
+		}
 	}

 	ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
 	if (ret < 0) {
-		dev_err(ctx->panel.dev, "exit_sleep_mode cmd failed ret = %d\n", ret);
-		goto power_off;
+		dev_err(ctx->panel.dev, "exit_sleep_mode cmd failed ret = %d\n",
+			ret);
+		return ret;
 	}

 	/* Per DSI spec wait 120ms after sending exit sleep DCS command */
@@ -133,8 +301,9 @@ static int visionox_rm69299_prepare(struct drm_panel *panel)

 	ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
 	if (ret < 0) {
-		dev_err(ctx->panel.dev, "set_display_on cmd failed ret = %d\n", ret);
-		goto power_off;
+		dev_err(ctx->panel.dev, "set_display_on cmd failed ret = %d\n",
+			ret);
+		return ret;
 	}

 	/* Per DSI spec wait 120ms after sending set_display_on DCS command */
@@ -143,41 +312,23 @@ static int visionox_rm69299_prepare(struct drm_panel *panel)
 	ctx->prepared = true;

 	return 0;
-
-power_off:
-	return ret;
 }

-static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = {
-	.name = "1080x2248",
-	.clock = 158695,
-	.hdisplay = 1080,
-	.hsync_start = 1080 + 26,
-	.hsync_end = 1080 + 26 + 2,
-	.htotal = 1080 + 26 + 2 + 36,
-	.vdisplay = 2248,
-	.vsync_start = 2248 + 56,
-	.vsync_end = 2248 + 56 + 4,
-	.vtotal = 2248 + 56 + 4 + 4,
-	.flags = 0,
-};
-
 static int visionox_rm69299_get_modes(struct drm_panel *panel,
 				      struct drm_connector *connector)
 {
 	struct visionox_rm69299 *ctx = panel_to_ctx(panel);
 	struct drm_display_mode *mode;

-	mode = drm_mode_create(connector->dev);
-	if (!mode) {
-		dev_err(ctx->panel.dev, "failed to create a new display mode\n");
-		return 0;
-	}
+	mode = drm_mode_duplicate(connector->dev, ctx->mode);
+	if (!mode)
+		return -ENOMEM;
+
+	drm_mode_set_name(mode);

-	connector->display_info.width_mm = 74;
-	connector->display_info.height_mm = 131;
-	drm_mode_copy(mode, &visionox_rm69299_1080x2248_60hz);
 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	connector->display_info.width_mm = mode->width_mm;
+	connector->display_info.height_mm = mode->height_mm;
 	drm_mode_probed_add(connector, mode);

 	return 1;
@@ -199,6 +350,8 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi)
 	if (!ctx)
 		return -ENOMEM;

+	ctx->mode = of_device_get_match_data(dev);
+
 	mipi_dsi_set_drvdata(dsi, ctx);

 	ctx->panel.dev = dev;
@@ -212,10 +365,11 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi)
 	if (ret < 0)
 		return ret;

-	ctx->reset_gpio = devm_gpiod_get(ctx->panel.dev,
-					 "reset", GPIOD_OUT_LOW);
+	ctx->reset_gpio =
+		devm_gpiod_get(ctx->panel.dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ctx->reset_gpio)) {
-		dev_err(dev, "cannot get reset gpio %ld\n", PTR_ERR(ctx->reset_gpio));
+		dev_err(dev, "cannot get reset gpio %ld\n",
+			PTR_ERR(ctx->reset_gpio));
 		return PTR_ERR(ctx->reset_gpio);
 	}

@@ -237,13 +391,17 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi)

 	ret = regulator_set_load(ctx->supplies[0].consumer, 32000);
 	if (ret) {
-		dev_err(dev, "regulator set load failed for vdda supply ret = %d\n", ret);
+		dev_err(dev,
+			"regulator set load failed for vdda supply ret = %d\n",
+			ret);
 		goto err_set_load;
 	}

 	ret = regulator_set_load(ctx->supplies[1].consumer, 13200);
 	if (ret) {
-		dev_err(dev, "regulator set load failed for vdd3p3 supply ret = %d\n", ret);
+		dev_err(dev,
+			"regulator set load failed for vdd3p3 supply ret = %d\n",
+			ret);
 		goto err_set_load;
 	}

@@ -268,7 +426,10 @@ static int visionox_rm69299_remove(struct mipi_dsi_device *dsi)
 }

 static const struct of_device_id visionox_rm69299_of_match[] = {
-	{ .compatible = "visionox,rm69299-1080p-display", },
+	{ .compatible = "visionox,rm69299-1080p-display",
+	  .data = &visionox_rm69299_1080x2248_60hz },
+	{ .compatible = "visionox,rm69299-shift",
+	  .data = &visionox_rm69299_1080x2160_60hz },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, visionox_rm69299_of_match);
--
2.34.1



^ permalink raw reply related

* [PATCH 3/6] dt-bindings: display: visionox-rm69299: document new compatible string
From: Caleb Connolly @ 2022-01-23 17:37 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz

Document a new compatible string for the second panel variant.

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
---
 .../devicetree/bindings/display/panel/visionox,rm69299.yaml   | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
index 076b057b4af5..b02ca75756a7 100644
--- a/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
+++ b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
@@ -17,7 +17,9 @@ allOf:

 properties:
   compatible:
-    const: visionox,rm69299-1080p-display
+    enum:
+      - visionox,rm69299-1080p-display
+      - visionox,rm69299-shift

   vdda-supply:
     description: |
--
2.34.1



^ permalink raw reply related

* [PATCH 2/6] input: touchscreen: add focaltech FTS driver
From: Caleb Connolly @ 2022-01-23 17:37 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz
In-Reply-To: <20220123173650.290349-1-caleb@connolly.tech>

The focaltech FTS driver supports several variants of focaltech touch
screens found in ~2018 era smartphones including a variant of the
PocoPhone F1 and the SHIFT6mq. This driver is loosely based on the
original driver from Focaltech but has been simplified and largely
reworked.

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
---
 drivers/input/touchscreen/Kconfig         |   9 +
 drivers/input/touchscreen/Makefile        |   1 +
 drivers/input/touchscreen/focaltech_fts.c | 870 ++++++++++++++++++++++
 3 files changed, 880 insertions(+)
 create mode 100644 drivers/input/touchscreen/focaltech_fts.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2f6adfb7b938..10874f2d17ac 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -372,6 +372,15 @@ config TOUCHSCREEN_EXC3000
 	  To compile this driver as a module, choose M here: the
 	  module will be called exc3000.

+config TOUCHSCREEN_FOCALTECH_FTS
+	tristate "Focaltech FTS Touchscreen"
+	depends on I2C
+	help
+	  Say Y here to enable support for Focaltech FTS based
+	  touch panels, including the 5452 and 8917 panels.
+
+	  If unsure, say N.
+
 config TOUCHSCREEN_FUJITSU
 	tristate "Fujitsu serial touchscreen"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 39a8127cf6a5..79f877d4ba02 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)	+= egalax_ts_serial.o
 obj-$(CONFIG_TOUCHSCREEN_EXC3000)	+= exc3000.o
+obj-$(CONFIG_TOUCHSCREEN_FOCALTECH_FTS)	+= focaltech_fts.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HIDEEP)	+= hideep.o
diff --git a/drivers/input/touchscreen/focaltech_fts.c b/drivers/input/touchscreen/focaltech_fts.c
new file mode 100644
index 000000000000..c62dc40a5bd0
--- /dev/null
+++ b/drivers/input/touchscreen/focaltech_fts.c
@@ -0,0 +1,870 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *
+ * FocalTech touchscreen driver.
+ *
+ * Copyright (c) 2010-2017, FocalTech Systems, Ltd., all rights reserved.
+ * Copyright (C) 2018 XiaoMi, Inc.
+ * Copyright (c) 2021 Caleb Connolly <caleb@connolly.tech>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/unistd.h>
+#include <linux/vmalloc.h>
+#include <linux/notifier.h>
+
+#define FTS_CMD_START1 0x55
+#define FTS_CMD_START2 0xAA
+#define FTS_CMD_START_DELAY 10
+#define FTS_CMD_READ_ID 0x90
+#define FTS_CMD_READ_ID_LEN 4
+
+#define FTS_REG_INT_CNT 0x8F
+#define FTS_REG_FLOW_WORK_CNT 0x91
+#define FTS_REG_WORKMODE 0x00
+#define FTS_REG_WORKMODE_FACTORY_VALUE 0x40
+#define FTS_REG_WORKMODE_WORK_VALUE 0x00
+#define FTS_REG_ESDCHECK_DISABLE 0x8D
+#define FTS_REG_CHIP_ID 0xA3
+#define FTS_REG_CHIP_ID2 0x9F
+#define FTS_REG_POWER_MODE 0xA5
+#define FTS_REG_POWER_MODE_SLEEP_VALUE 0x03
+#define FTS_REG_FW_VER 0xA6
+#define FTS_REG_VENDOR_ID 0xA8
+#define FTS_REG_LCD_BUSY_NUM 0xAB
+#define FTS_REG_FACE_DEC_MODE_EN 0xB0
+#define FTS_REG_FACE_DEC_MODE_STATUS 0x01
+#define FTS_REG_IDE_PARA_VER_ID 0xB5
+#define FTS_REG_IDE_PARA_STATUS 0xB6
+#define FTS_REG_GLOVE_MODE_EN 0xC0
+#define FTS_REG_COVER_MODE_EN 0xC1
+#define FTS_REG_CHARGER_MODE_EN 0x8B
+#define FTS_REG_GESTURE_EN 0xD0
+#define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3
+#define FTS_REG_MODULE_ID 0xE3
+#define FTS_REG_LIC_VER 0xE4
+#define FTS_REG_ESD_SATURATE 0xED
+
+#define FTS_MAX_POINTS_SUPPORT 10
+#define FTS_ONE_TCH_LEN 6
+
+#define FTS_MAX_ID 0x0A
+#define FTS_TOUCH_X_H_POS 3
+#define FTS_TOUCH_X_L_POS 4
+#define FTS_TOUCH_Y_H_POS 5
+#define FTS_TOUCH_Y_L_POS 6
+#define FTS_TOUCH_PRE_POS 7
+#define FTS_TOUCH_AREA_POS 8
+#define FTS_TOUCH_POINT_NUM 2
+#define FTS_TOUCH_EVENT_POS 3
+#define FTS_TOUCH_ID_POS 5
+#define FTS_COORDS_ARR_SIZE 2
+
+#define FTS_TOUCH_DOWN 0
+#define FTS_TOUCH_UP 1
+#define FTS_TOUCH_CONTACT 2
+
+#define EVENT_DOWN(flag) ((flag == FTS_TOUCH_DOWN) || (flag == FTS_TOUCH_CONTACT))
+
+#define FTS_LOCKDOWN_INFO_SIZE 8
+#define LOCKDOWN_INFO_ADDR 0x1FA0
+
+#define FTS_DRIVER_NAME "fts-i2c"
+#define INTERVAL_READ_REG 100 /* unit:ms */
+#define TIMEOUT_READ_REG 2000 /* unit:ms */
+#define FTS_VDD_MIN_UV 2600000
+#define FTS_VDD_MAX_UV 3300000
+#define FTS_I2C_VCC_MIN_UV 1800000
+#define FTS_I2C_VCC_MAX_UV 1800000
+
+#define I2C_RETRY_NUMBER 3
+
+#define CHIP_TYPE_5452 0x5452
+#define CHIP_TYPE_8719 0x8719
+
+static DEFINE_MUTEX(i2c_rw_access);
+
+struct ts_event {
+	int x; /*x coordinate */
+	int y; /*y coordinate */
+	int p; /* pressure */
+	int flag; /* touch event flag: 0 -- down; 1-- up; 2 -- contact */
+	int id; /*touch ID */
+	int area;
+};
+
+struct fts_ts_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	struct regulator *vdd;
+	struct regulator *vcc_i2c;
+	spinlock_t irq_lock;
+	struct mutex report_mutex;
+	int irq;
+	bool irq_disabled;
+	bool power_disabled;
+
+	/* multi-touch */
+	struct ts_event *events;
+	u32 max_touch_number;
+	u8 *point_buf;
+	int pnt_buf_size;
+	int touches;
+	int touch_point;
+	int point_num;
+	bool dev_pm_suspend;
+	bool low_power_mode;
+	struct completion dev_pm_suspend_completion;
+	struct pinctrl *pinctrl;
+
+	// DT data
+	struct gpio_desc *irq_gpio;
+	struct gpio_desc *reset_gpio;
+	u32 width;
+	u32 height;
+};
+
+int fts_i2c_read(struct i2c_client *client, char *writebuf, int writelen,
+		 char *readbuf, int readlen)
+{
+	int ret = 0;
+	int msg_count = !!writelen + 1;
+	struct i2c_msg msgs[2];
+
+	if (readlen < 0 || writelen < 0)
+		return -EINVAL;
+
+	// If writelen is zero then only populate msgs[0].
+	// otherwise we read into msgs[1]
+	msgs[msg_count-1].len = readlen;
+	msgs[msg_count-1].buf = readbuf;
+	msgs[msg_count-1].addr = client->addr;
+	msgs[msg_count-1].flags = I2C_M_RD;
+
+	if (writelen > 0) {
+		msgs[0].len = writelen;
+		msgs[0].buf = writebuf;
+		msgs[0].addr = client->addr;
+		msgs[0].flags = 0;
+	}
+
+	mutex_lock(&i2c_rw_access);
+
+	ret = i2c_transfer(client->adapter, msgs, msg_count);
+
+	mutex_unlock(&i2c_rw_access);
+	return ret;
+}
+
+int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue)
+{
+	return fts_i2c_read(client, &regaddr, 1, regvalue, 1);
+}
+
+static bool fts_chip_is_valid(struct fts_ts_data *data, u16 id)
+{
+	if (id != CHIP_TYPE_5452 && id != CHIP_TYPE_8719)
+		return false;
+
+	return true;
+}
+
+int fts_wait_ready(struct fts_ts_data *data)
+{
+	int ret = 0;
+	int cnt = 0;
+	u8 reg_value[2];
+	struct i2c_client *client = data->client;
+
+	do {
+		ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &reg_value[0]);
+		ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID2, &reg_value[1]);
+		if (fts_chip_is_valid(data, reg_value[0] << 8 | reg_value[1])) {
+			dev_dbg(&data->client->dev, "TP Ready, Device ID = 0x%x%x, count = %d",
+				reg_value[0], reg_value[1], cnt);
+			return 0;
+		}
+		cnt++;
+		msleep(INTERVAL_READ_REG);
+	} while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
+
+	return -EIO;
+}
+
+static int fts_power_source_init(struct fts_ts_data *data)
+{
+	int ret = 0;
+
+	data->vdd = devm_regulator_get(&data->client->dev, "vdd");
+	if (IS_ERR_OR_NULL(data->vdd)) {
+		ret = PTR_ERR(data->vdd);
+		dev_err(&data->client->dev, "get vdd regulator failed,ret=%d", ret);
+		return ret;
+	}
+
+	if (regulator_count_voltages(data->vdd) > 0) {
+		ret = regulator_set_voltage(data->vdd, FTS_VDD_MIN_UV,
+					    FTS_VDD_MAX_UV);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "failed to set vdd regulator ret=%d", ret);
+			goto exit;
+		}
+	}
+
+	data->vcc_i2c = devm_regulator_get(&data->client->dev, "vcc-i2c");
+	if (IS_ERR(data->vcc_i2c)) {
+		ret = PTR_ERR(data->vcc_i2c);
+		dev_err(&data->client->dev, "get vcc_i2c regulator failed,ret=%d", ret);
+		return ret;
+	}
+
+	if (regulator_count_voltages(data->vcc_i2c) > 0) {
+		ret = regulator_set_voltage(data->vcc_i2c, FTS_I2C_VCC_MIN_UV,
+					    FTS_I2C_VCC_MAX_UV);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "failed to set vcc_i2c regulator ret=%d",
+				ret);
+			goto exit;
+		}
+	}
+
+exit:
+	return ret;
+}
+
+static int fts_power_source_release(struct fts_ts_data *data)
+{
+	if (!data->power_disabled) {
+		regulator_disable(data->vdd);
+		regulator_disable(data->vcc_i2c);
+	}
+
+	devm_regulator_put(data->vdd);
+	devm_regulator_put(data->vcc_i2c);
+
+	return 0;
+}
+
+static int fts_power_source_ctrl(struct fts_ts_data *data, bool enable)
+{
+	int ret = 0;
+
+	if (enable) {
+		if (data->power_disabled) {
+			ret = regulator_enable(data->vdd);
+			if (ret < 0) {
+				dev_err(&data->client->dev,
+					"enable vdd regulator failed,ret=%d",
+					ret);
+			}
+
+			ret = regulator_enable(data->vcc_i2c);
+			if (ret < 0) {
+				dev_err(&data->client->dev, "enable vcc_i2c regulator failed,ret=%d",
+					  ret);
+			}
+			data->power_disabled = false;
+		}
+	} else {
+		if (!data->power_disabled) {
+			ret = regulator_disable(data->vdd);
+			if (ret < 0) {
+				dev_err(&data->client->dev,
+					"disable vdd regulator failed,ret=%d",
+					ret);
+			}
+
+			ret = regulator_disable(data->vcc_i2c);
+			if (ret < 0) {
+				dev_err(&data->client->dev, "disable vcc_i2c regulator failed,ret=%d",
+					  ret);
+			}
+
+			data->power_disabled = true;
+		}
+	}
+
+	return ret;
+}
+
+static int fts_pinctrl_set_active(struct fts_ts_data *data, bool enable)
+{
+	int ret = 0;
+	struct pinctrl_state *state = pinctrl_lookup_state(data->pinctrl,
+		enable ? "default" : "suspend");
+
+	if (IS_ERR_OR_NULL(state)) {
+		dev_err(&data->client->dev, "pinctrl lookup %s failed\n",
+			enable ? "default" : "suspend");
+		return -EINVAL;
+	}
+
+	ret = pinctrl_select_state(data->pinctrl, state);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"Failed to set pinctrl state: enable = %d, ret = %d",
+			enable, ret);
+	}
+
+	return ret;
+}
+
+static void fts_release_all_finger(struct fts_ts_data *data)
+{
+	struct input_dev *input_dev = data->input_dev;
+	u32 finger_count = 0;
+
+	mutex_lock(&data->report_mutex);
+
+	for (finger_count = 0; finger_count < data->max_touch_number;
+	     finger_count++) {
+		input_mt_slot(input_dev, finger_count);
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+	}
+
+	input_report_key(input_dev, BTN_TOUCH, 0);
+	input_sync(input_dev);
+
+	mutex_unlock(&data->report_mutex);
+}
+
+static int fts_input_report_b(struct fts_ts_data *data)
+{
+	int i = 0;
+	int uppoint = 0;
+	int touches = 0;
+	bool va_reported = false;
+	struct ts_event *events = data->events;
+
+	for (i = 0; i < data->touch_point; i++) {
+		if (events[i].id >= data->max_touch_number)
+			break;
+
+		va_reported = true;
+		input_mt_slot(data->input_dev, events[i].id);
+
+		if (events[i].flag == FTS_TOUCH_DOWN || events[i].flag == FTS_TOUCH_CONTACT) {
+			input_mt_report_slot_state(data->input_dev,
+						   MT_TOOL_FINGER, true);
+
+			if (events[i].p <= 0)
+				events[i].p = 0x3f;
+
+			input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+					 events[i].p);
+
+			if (events[i].area <= 0)
+				events[i].area = 0x09;
+
+			input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+					 events[i].area);
+			input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+					 events[i].x);
+			input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+					 events[i].y);
+
+			touches |= BIT(events[i].id);
+			data->touches |= BIT(events[i].id);
+		} else {
+			uppoint++;
+
+			input_report_abs(data->input_dev, ABS_MT_PRESSURE, 0);
+
+			input_mt_report_slot_state(data->input_dev,
+						   MT_TOOL_FINGER, false);
+			data->touches &= ~BIT(events[i].id);
+		}
+	}
+
+	if (data->touches ^ touches) {
+		for (i = 0; i < data->max_touch_number; i++) {
+			if (BIT(i) & (data->touches ^ touches)) {
+				va_reported = true;
+				input_mt_slot(data->input_dev, i);
+				input_mt_report_slot_state(
+					data->input_dev, MT_TOOL_FINGER, false);
+			}
+		}
+	}
+	data->touches = touches;
+
+	if (va_reported) {
+		if (!data->point_num || !touches)
+			input_report_key(data->input_dev, BTN_TOUCH, 0);
+		else
+			input_report_key(data->input_dev, BTN_TOUCH, 1);
+	} else {
+		dev_err(&data->client->dev, "va not reported, but touches=%d", touches);
+	}
+
+	input_sync(data->input_dev);
+	return 0;
+}
+
+static int fts_read_touchdata(struct fts_ts_data *data)
+{
+	int ret = 0;
+	int i = 0;
+	u8 pointid;
+	int base;
+	struct ts_event *events = data->events;
+	int max_touch_num = data->max_touch_number;
+	u8 *buf = data->point_buf;
+
+	data->point_num = 0;
+	data->touch_point = 0;
+
+	memset(buf, 0xFF, data->pnt_buf_size);
+	buf[0] = 0x00;
+
+	ret = fts_i2c_read(data->client, buf, 1, buf, data->pnt_buf_size);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "read touchdata failed, ret:%d", ret);
+		return ret;
+	}
+	data->point_num = buf[FTS_TOUCH_POINT_NUM] & 0x0F;
+
+	if (data->point_num > max_touch_num)
+		return -EINVAL;
+
+	for (i = 0; i < max_touch_num; i++) {
+		base = FTS_ONE_TCH_LEN * i;
+
+		pointid = (buf[FTS_TOUCH_ID_POS + base]) >> 4;
+		if (pointid >= FTS_MAX_ID)
+			break;
+
+		else if (pointid >= max_touch_num)
+			return -EINVAL;
+
+		data->touch_point++;
+
+		events[i].x = ((buf[FTS_TOUCH_X_H_POS + base] & 0x0F) << 8) +
+			      (buf[FTS_TOUCH_X_L_POS + base] & 0xFF);
+		events[i].y = ((buf[FTS_TOUCH_Y_H_POS + base] & 0x0F) << 8) +
+			      (buf[FTS_TOUCH_Y_L_POS + base] & 0xFF);
+		events[i].flag = buf[FTS_TOUCH_EVENT_POS + base] >> 6;
+		events[i].id = buf[FTS_TOUCH_ID_POS + base] >> 4;
+		events[i].area = buf[FTS_TOUCH_AREA_POS + base] >> 4;
+		events[i].p = buf[FTS_TOUCH_PRE_POS + base];
+
+		if (((events[i].flag == FTS_TOUCH_DOWN) || (events[i].flag == FTS_TOUCH_CONTACT))
+		    && (data->point_num == 0)) {
+			dev_err(&data->client->dev, "abnormal touch data from fw");
+			return -EIO;
+		}
+	}
+	if (data->touch_point == 0) {
+		dev_err(&data->client->dev, "no touch point information");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void fts_report_event(struct fts_ts_data *data)
+{
+	fts_input_report_b(data);
+}
+
+static irqreturn_t fts_ts_interrupt(int irq, void *d)
+{
+	int ret = 0;
+	struct fts_ts_data *data = (struct fts_ts_data *)d;
+
+	if (!data) {
+		dev_err(&data->client->dev, "%s() Invalid fts_ts_data", __func__);
+		return IRQ_HANDLED;
+	}
+
+	if (data->dev_pm_suspend) {
+		ret = wait_for_completion_timeout(
+			&data->dev_pm_suspend_completion,
+			msecs_to_jiffies(700));
+		if (!ret) {
+			dev_err(&data->client->dev,
+				"Didn't resume in time, skipping wakeup event handling\n");
+			return IRQ_HANDLED;
+		}
+	}
+
+	ret = fts_read_touchdata(data);
+	if (ret == 0) {
+		mutex_lock(&data->report_mutex);
+		fts_report_event(data);
+		mutex_unlock(&data->report_mutex);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int fts_input_init(struct fts_ts_data *data)
+{
+	int ret = 0;
+	struct input_dev *input_dev;
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		dev_err(&data->client->dev, "Failed to allocate memory for input device");
+		return -ENOMEM;
+	}
+
+	/* Init and register Input device */
+	input_dev->name = FTS_DRIVER_NAME;
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->dev.parent = &data->client->dev;
+
+	input_set_drvdata(input_dev, data);
+
+	__set_bit(EV_SYN, input_dev->evbit);
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);
+	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+	input_mt_init_slots(input_dev, data->max_touch_number,
+			    INPUT_MT_DIRECT);
+
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+			     data->width - 1, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+			     data->height - 1, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);
+
+	input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
+
+	data->pnt_buf_size = data->max_touch_number * FTS_ONE_TCH_LEN + 3;
+	data->point_buf = devm_kzalloc(&data->client->dev, data->pnt_buf_size, GFP_KERNEL);
+	if (!data->point_buf) {
+		dev_err(&data->client->dev, "Failed to alloc memory for point buf!");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	data->events = devm_kzalloc(&data->client->dev,
+		data->max_touch_number * sizeof(struct ts_event), GFP_KERNEL);
+	if (!data->events) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+	ret = input_register_device(input_dev);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Input device registration failed");
+		goto err_out;
+	}
+
+	data->input_dev = input_dev;
+
+	return 0;
+
+err_out:
+	input_set_drvdata(input_dev, NULL);
+	input_free_device(input_dev);
+	input_dev = NULL;
+
+	return ret;
+}
+
+static int fts_reset(struct fts_ts_data *data)
+{
+	gpiod_set_value_cansleep(data->reset_gpio, 0);
+	msleep(20);
+	gpiod_set_value_cansleep(data->reset_gpio, 1);
+
+	return 0;
+}
+
+static int fts_parse_dt(struct fts_ts_data *data)
+{
+	int ret = 0;
+	struct device *dev = &data->client->dev;
+	struct device_node *np = dev->of_node;
+	u32 val;
+
+	ret = of_property_read_u32(np, "touchscreen-size-x", &data->width);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Unable to read property 'touchscreen-size-x'");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(np, "touchscreen-size-y", &data->height);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Unable to read property 'touchscreen-size-y'");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(np, "focaltech,max-touch-number", &val);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Unable to read property 'focaltech,max-touch-number'");
+		return -EINVAL;
+	}
+	if (val < 2 || val > FTS_MAX_POINTS_SUPPORT) {
+		dev_err(&data->client->dev, "'focaltech,max-touch-number' out of range [2, %d]",
+			FTS_MAX_POINTS_SUPPORT);
+		return -EINVAL;
+	}
+	data->max_touch_number = val;
+
+	data->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (data->reset_gpio < 0) {
+		dev_err(&data->client->dev, "Unable to get reset gpio");
+		return -EINVAL;
+	}
+
+	data->irq_gpio = devm_gpiod_get_optional(dev, "irq", GPIOD_OUT_LOW);
+
+	return 0;
+}
+
+static int fts_ts_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct fts_ts_data *data;
+	struct pinctrl_state *pinctrl_state_temp;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&data->client->dev, "I2C not supported");
+		return -ENODEV;
+	}
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->client = client;
+	ret = fts_parse_dt(data);
+	if (ret < 0)
+		return ret;
+
+	i2c_set_clientdata(client, data);
+
+	spin_lock_init(&data->irq_lock);
+	mutex_init(&data->report_mutex);
+
+	ret = fts_input_init(data);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Input initialization fail");
+		goto err_input_init;
+	}
+
+	ret = fts_power_source_init(data);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "fail to get vdd/vcc_i2c regulator");
+		goto err_power_init;
+	}
+
+	data->power_disabled = true;
+	ret = fts_power_source_ctrl(data, true);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "fail to enable vdd/vcc_i2c regulator");
+		goto err_power_ctrl;
+	}
+
+	data->pinctrl = devm_pinctrl_get(&client->dev);
+	if (IS_ERR_OR_NULL(data->pinctrl)) {
+		dev_err(&data->client->dev, "Failed to get pinctrl, please check dts");
+		ret = PTR_ERR(data->pinctrl);
+		goto err_power_ctrl;
+	}
+
+	pinctrl_state_temp = pinctrl_lookup_state(data->pinctrl, "default");
+	if (IS_ERR_OR_NULL(pinctrl_state_temp) ||
+		IS_ERR_OR_NULL(pinctrl_lookup_state(data->pinctrl, "suspend"))) {
+		dev_err(&data->client->dev, "Failed to get default or suspend pinctrl state, please check dts");
+		goto err_power_ctrl;
+	}
+
+	fts_pinctrl_set_active(data, true);
+
+	ret = fts_reset(data);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Failed to reset chip");
+		goto err_gpio_config;
+	}
+
+	ret = fts_wait_ready(data);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Touch IC didn't turn on or is unsupported");
+		goto err_gpio_config;
+	}
+
+	if (data->irq_gpio) {
+		data->irq = gpiod_to_irq(data->irq_gpio);
+
+		ret = request_threaded_irq(data->irq, NULL, fts_ts_interrupt,
+					IRQF_ONESHOT,
+					data->client->name, data);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "request irq failed");
+			goto err_gpio_config;
+		}
+		device_init_wakeup(&client->dev, true);
+	}
+
+	data->dev_pm_suspend = false;
+	init_completion(&data->dev_pm_suspend_completion);
+
+	return 0;
+
+err_gpio_config:
+	fts_power_source_ctrl(data, false);
+err_power_ctrl:
+	fts_power_source_release(data);
+err_power_init:
+	input_unregister_device(data->input_dev);
+err_input_init:
+	devm_kfree(&client->dev, data);
+
+	return ret;
+}
+
+static int fts_ts_remove(struct i2c_client *client)
+{
+	struct fts_ts_data *data = i2c_get_clientdata(client);
+
+	free_irq(client->irq, data);
+	input_unregister_device(data->input_dev);
+
+	fts_power_source_ctrl(data, false);
+	fts_power_source_release(data);
+
+	kfree(data->point_buf);
+	kfree(data->events);
+
+	devm_kfree(&client->dev, data);
+
+	return 0;
+}
+
+static int fts_ts_suspend(struct device *dev)
+{
+	struct fts_ts_data *data = dev_get_drvdata(dev);
+	int ret = 0;
+
+	disable_irq(data->irq);
+
+	ret = fts_power_source_ctrl(data, false);
+	if (ret < 0)
+		dev_err(dev, "power off fail, ret=%d", ret);
+	fts_pinctrl_set_active(data, false);
+
+	return 0;
+}
+
+static int fts_ts_resume(struct device *dev)
+{
+	struct fts_ts_data *data = dev_get_drvdata(dev);
+
+	fts_release_all_finger(data);
+
+	fts_power_source_ctrl(data, true);
+	fts_pinctrl_set_active(data, true);
+
+	fts_wait_ready(data);
+
+	enable_irq(data->irq);
+
+	return 0;
+}
+
+static int fts_pm_suspend(struct device *dev)
+{
+	struct fts_ts_data *data = dev_get_drvdata(dev);
+	int ret = 0;
+
+	data->dev_pm_suspend = true;
+
+	if (data->low_power_mode) {
+		ret = enable_irq_wake(data->irq);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "enable_irq_wake(irq:%d) failed",
+				 data->irq);
+		}
+	} else {
+		ret = fts_ts_suspend(dev);
+	}
+
+	reinit_completion(&data->dev_pm_suspend_completion);
+
+	return ret;
+}
+
+static int fts_pm_resume(struct device *dev)
+{
+	struct fts_ts_data *data = dev_get_drvdata(dev);
+	int ret = 0;
+
+	data->dev_pm_suspend = false;
+
+	if (data->low_power_mode) {
+		ret = disable_irq_wake(data->irq);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "disable_irq_wake(irq:%d) failed",
+				 data->irq);
+		}
+	} else {
+		ret = fts_ts_resume(dev);
+	}
+
+	complete(&data->dev_pm_suspend_completion);
+
+	return 0;
+}
+
+static const struct dev_pm_ops fts_dev_pm_ops = {
+	.suspend = fts_pm_suspend,
+	.resume = fts_pm_resume,
+};
+
+static const struct of_device_id fts_match_table[] = {
+	{ .compatible = "focaltech,fts5452", },
+	{ .compatible = "focaltech,fts8719", },
+	{ /* sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, fts_match_table);
+
+static struct i2c_driver fts_ts_driver = {
+	.probe = fts_ts_probe,
+	.remove = fts_ts_remove,
+	.driver = {
+		.name = FTS_DRIVER_NAME,
+		.pm = &fts_dev_pm_ops,
+		.of_match_table = fts_match_table,
+	},
+};
+module_i2c_driver(fts_ts_driver);
+
+MODULE_AUTHOR("Caleb Connolly <caleb@connolly.tech>");
+MODULE_DESCRIPTION("FocalTech touchscreen Driver");
+MODULE_LICENSE("GPL v2");
--
2.34.1



^ permalink raw reply related

* [PATCH 1/6] dt-bindings: input: touchscreen: add bindings for focaltech,fts
From: Caleb Connolly @ 2022-01-23 17:37 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz
In-Reply-To: <20220123173650.290349-1-caleb@connolly.tech>

Add devicetree bindings for the Focaltech FTS touchscreen drivers.

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
---
 .../input/touchscreen/focaltech,fts.yaml      | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/focaltech,fts.yaml

diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech,fts.yaml b/Documentation/devicetree/bindings/input/touchscreen/focaltech,fts.yaml
new file mode 100644
index 000000000000..bb25a4f8ad71
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/focaltech,fts.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/focaltech,fts.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Focaltech FTS I2C Touchscreen Controller
+
+maintainers:
+  - Caleb Connolly <caleb@connolly.tech>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - focaltech,fts5452
+      - focaltech,fts8719
+  reg:
+    const: 0x38
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  wakeup-source:
+    type: boolean
+    description: touchscreen can be used as a wakeup source.
+
+  focaltech,max-touch-number:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: max number of fingers supported
+    minimum: 2
+    maximum: 10
+
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - focaltech,max-touch-number
+  - touchscreen-size-x
+  - touchscreen-size-y
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    &i2c5 {
+      status="okay";
+
+      touchscreen: focaltech@38 {
+        compatible = "focaltech,fts8719";
+        reg = <0x38>;
+        wakeup-source;
+        interrupt-parent = <&tlmm>;
+        interrupts = <125 0x2>;
+        vdd-supply = <&vreg_l28a_3p0>;
+        vcc-i2c-supply = <&vreg_l14a_1p88>;
+
+        pinctrl-names = "default", "suspend";
+        pinctrl-0 = <&ts_int_active &ts_reset_active>;
+        pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+
+        reset-gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+        irq-gpio = <&tlmm 125 GPIO_TRANSITORY>;
+        touchscreen-size-x = <1080>;
+        touchscreen-size-y = <2160>;
+        focaltech,max-touch-number = <5>;
+      };
+    };
--
2.34.1



^ permalink raw reply related

* [PATCH 0/6] Add support for the SHIFT SHIFT6mq
From: Caleb Connolly @ 2022-01-23 17:37 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, David Airlie, Daniel Vetter,
	Rob Herring, Dmitry Torokhov, Andy Gross, Bjorn Andersson,
	Kees Cook, Anton Vorontsov, Colin Cross, Tony Luck,
	Henrik Rydberg, Harigovindan P, Caleb Connolly, dri-devel,
	devicetree, linux-kernel, linux-input, linux-arm-msm,
	Alexander Martinz

This series adds initial support for the SHIFT6mq. SHIFT are a sustainably
oriented device manufacturer who aim to build repairable devices with long
lifespans.

The SHIFT6mq is a Snapdragon 845 based device, it features a 1080p OLED panel,
8GB of RAM, 128GB of UFS storage and display port alt mode. The device also
ships with secure-boot off, potentially allowing end-users to modify usually
inaccesible parts of the device like the bootloader. They've been keen to see
their devices supported upstream kernels!

This brings up initial support for the device, with all core features working:

* Display / GPU / touch
* WIFI
* Modem (sms and mobile data are supported with ModemManager)

- Caleb

Alexander Martinz (1):
  arm64: dts: qcom: sdm845: add device tree for SHIFT6mq

Caleb Connolly (5):
  dt-bindings: input: touchscreen: add bindings for focaltech,fts
  input: touchscreen: add focaltech FTS driver
  dt-bindings: display: visionox-rm69299: document new compatible string
  drm/panel: visionox-rm69299: support the variant found in the SHIFT6mq
  dt-bindings: vendor-prefixes: add vendor prefix for SHIFT

 .../display/panel/visionox,rm69299.yaml       |   4 +-
 .../input/touchscreen/focaltech,fts.yaml      |  78 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/qcom/Makefile             |   1 +
 .../boot/dts/qcom/sdm845-shift-axolotl.dts    | 736 +++++++++++++++
 .../gpu/drm/panel/panel-visionox-rm69299.c    | 281 ++++--
 drivers/input/touchscreen/Kconfig             |   9 +
 drivers/input/touchscreen/Makefile            |   1 +
 drivers/input/touchscreen/focaltech_fts.c     | 870 ++++++++++++++++++
 9 files changed, 1921 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/focaltech,fts.yaml
 create mode 100644 arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
 create mode 100644 drivers/input/touchscreen/focaltech_fts.c

--
2.34.1



^ permalink raw reply

* [PATCH 3/3] drm/panel: Add MIPI DBI compatible SPI driver
From: Noralf Trønnes @ 2022-01-23 17:25 UTC (permalink / raw)
  To: robh+dt, thierry.reding
  Cc: sam, maxime, dave.stevenson, david, devicetree, dri-devel,
	Noralf Trønnes
In-Reply-To: <20220123172520.48741-1-noralf@tronnes.org>

Add a driver that will work with most MIPI DBI compatible SPI panels.
This avoids adding a driver for every new MIPI DBI compatible controller
that is to be used by Linux. The 'model' Device Tree property contains the
name of the display and will be used to load a firmware file that contains
the controller configuration.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 MAINTAINERS                            |   7 +
 drivers/gpu/drm/panel/Kconfig          |  11 +
 drivers/gpu/drm/panel/Makefile         |   1 +
 drivers/gpu/drm/panel/panel-mipi-dbi.c | 385 +++++++++++++++++++++++++
 4 files changed, 404 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-mipi-dbi.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ba6fa65df8bb..8a46c36c50dc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6035,6 +6035,13 @@ T:	git git://anongit.freedesktop.org/drm/drm-misc
 F:	Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
 F:	drivers/gpu/drm/tiny/mi0283qt.c
 
+DRM DRIVER FOR MIPI DBI compatible panels
+M:	Noralf Trønnes <noralf@tronnes.org>
+S:	Maintained
+T:	git git://anongit.freedesktop.org/drm/drm-misc
+F:	Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
+F:	drivers/gpu/drm/panel/panel-mipi-dbi.c
+
 DRM DRIVER FOR MSM ADRENO GPU
 M:	Rob Clark <robdclark@gmail.com>
 M:	Sean Paul <sean@poorly.run>
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 434c2861bb40..1851cda5f877 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -274,6 +274,17 @@ config DRM_PANEL_LG_LG4573
 	  Say Y here if you want to enable support for LG4573 RGB panel.
 	  To compile this driver as a module, choose M here.
 
+config DRM_PANEL_MIPI_DBI
+	tristate "MIPI DBI compatible panel"
+	depends on SPI
+	depends on BACKLIGHT_CLASS_DEVICE
+	depends on DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_MIPI_DBI
+	help
+	  Say Y here if you want to enable support for MIPI DBI compatible panels.
+	  To compile this driver as a module, choose M here.
+
 config DRM_PANEL_NEC_NL8048HL11
 	tristate "NEC NL8048HL11 RGB panel"
 	depends on GPIOLIB && OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index d99fbbce49d1..a90c30459964 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o
 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
+obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
diff --git a/drivers/gpu/drm/panel/panel-mipi-dbi.c b/drivers/gpu/drm/panel/panel-mipi-dbi.c
new file mode 100644
index 000000000000..767658426061
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-mipi-dbi.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DRM driver for MIPI DBI compatible display panels
+ *
+ * Copyright 2022 Noralf Trønnes
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_mipi_dbi.h>
+#include <drm/drm_modeset_helper.h>
+#include <video/mipi_display.h>
+
+static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I',
+					     0, 0, 0, 0, 0, 0, 0 };
+
+/*
+ * The display panel configuration is stored in a firmware file. The Device Tree 'model' property
+ * value with a '.bin' suffix is passed to request_firmware() to fetch this file.
+ */
+struct panel_mipi_dbi_config {
+	/* Magic string: panel_mipi_dbi_magic */
+	u8 magic[15];
+
+	/* Config file format version */
+	u8 file_format_version;
+
+	/* Width in pixels */
+	__be16 width;
+	/* Height in pixels */
+	__be16 height;
+
+	/* Width in millimeters (optional) */
+	__be16 width_mm;
+	/* Height in millimeters (optional) */
+	__be16 height_mm;
+
+	/* X-axis panel offset */
+	__be16 x_offset;
+	/* Y-axis panel offset */
+	__be16 y_offset;
+
+	/* 4 pad bytes, must be zero */
+	u8 pad[4];
+
+	/*
+	 * Optional MIPI commands to execute when the display pipeline is enabled.
+	 * This can be used to configure the display controller.
+	 *
+	 * The commands are stored in a byte array with the format:
+	 *     command, num_parameters, [ parameter, ...], command, ...
+	 *
+	 * Some commands require a pause before the next command can be received.
+	 * Inserting a delay in the command sequence is done by using the NOP command with one
+	 * parameter: delay in miliseconds (the No Operation command is part of the MIPI Display
+	 * Command Set where it has no parameters).
+	 *
+	 * Example:
+	 *     command 0x11
+	 *     sleep 120ms
+	 *     command 0xb1 parameters 0x01, 0x2c, 0x2d
+	 *     command 0x29
+	 *
+	 * Byte sequence:
+	 *     0x11 0x00
+	 *     0x00 0x01 0x78
+	 *     0xb1 0x03 0x01 0x2c 0x2d
+	 *     0x29 0x00
+	 */
+	u8 commands[];
+};
+
+struct panel_mipi_dbi_commands {
+	const u8 *buf;
+	size_t len;
+};
+
+static void panel_mipi_dbi_enable(struct drm_simple_display_pipe *pipe,
+				  struct drm_crtc_state *crtc_state,
+				  struct drm_plane_state *plane_state)
+{
+	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
+	struct panel_mipi_dbi_commands *commands = dbidev->driver_private;
+	struct mipi_dbi *dbi = &dbidev->dbi;
+	unsigned int i = 0;
+	int ret, idx;
+
+	if (!drm_dev_enter(pipe->crtc.dev, &idx))
+		return;
+
+	drm_dbg(pipe->crtc.dev, "\n");
+
+	ret = mipi_dbi_poweron_conditional_reset(dbidev);
+	if (ret < 0)
+		goto out_exit;
+	if (ret == 1)
+		goto out_enable;
+
+	if (!commands)
+		goto out_enable;
+
+	while (i < commands->len) {
+		u8 command = commands->buf[i++];
+		u8 num_parameters = commands->buf[i++];
+		const u8 *parameters = &commands->buf[i];
+
+		if (command == 0x00 && num_parameters == 1)
+			msleep(parameters[0]);
+		else if (num_parameters)
+			mipi_dbi_command_stackbuf(dbi, command, parameters, num_parameters);
+		else
+			mipi_dbi_command(dbi, command);
+
+		i += num_parameters;
+	}
+
+out_enable:
+	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+out_exit:
+	drm_dev_exit(idx);
+}
+
+static const struct drm_simple_display_pipe_funcs panel_mipi_dbi_pipe_funcs = {
+	.enable = panel_mipi_dbi_enable,
+	.disable = mipi_dbi_pipe_disable,
+	.update = mipi_dbi_pipe_update,
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(panel_mipi_dbi_fops);
+
+static const struct drm_driver panel_mipi_dbi_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+	.fops			= &panel_mipi_dbi_fops,
+	DRM_GEM_CMA_DRIVER_OPS_VMAP,
+	.debugfs_init		= mipi_dbi_debugfs_init,
+	.name			= "panel-mipi-dbi",
+	.desc			= "MIPI DBI compatible display panel",
+	.date			= "20220103",
+	.major			= 1,
+	.minor			= 0,
+};
+
+static int panel_mipi_dbi_parse_config(struct mipi_dbi_dev *dbidev,
+				       struct drm_display_mode *mode,
+				       const struct firmware *fw)
+{
+	const struct panel_mipi_dbi_config *config = (struct panel_mipi_dbi_config *)fw->data;
+	unsigned int width, height, x_offset, y_offset;
+	struct panel_mipi_dbi_commands *commands;
+	struct drm_device *drm = &dbidev->drm;
+	struct device *dev = dbidev->drm.dev;
+	size_t size = fw->size, commands_len;
+	unsigned int i = 0;
+
+	if (size < sizeof(*config)) {
+		dev_err(dev, "config: file size=%zu is too small\n", size);
+		return -EINVAL;
+	}
+
+	if (memcmp(config->magic, panel_mipi_dbi_magic, sizeof(config->magic))) {
+		dev_err(dev, "config: Bad magic: %15ph\n", config->magic);
+		return -EINVAL;
+	}
+
+	if (config->file_format_version != 1) {
+		dev_err(dev, "config: version=%u is not supported\n", config->file_format_version);
+		return -EINVAL;
+	}
+
+	width = be16_to_cpu(config->width);
+	height = be16_to_cpu(config->height);
+	x_offset = be16_to_cpu(config->x_offset);
+	y_offset = be16_to_cpu(config->y_offset);
+
+	drm_dbg(drm, "size=%zu version=%u\n", size, config->file_format_version);
+	drm_dbg(drm, "width=%u height=%u\n", width, height);
+	drm_dbg(drm, "x_offset=%u y_offset=%u\n", x_offset, y_offset);
+
+	if (width && height) {
+		struct drm_display_mode simple_mode = {
+			DRM_SIMPLE_MODE(width, height, be16_to_cpu(config->width_mm),
+					be16_to_cpu(config->height_mm))
+		};
+
+		*mode = simple_mode;
+	} else {
+		dev_err(dev, "config: width or height can't be zero\n");
+		return -EINVAL;
+	}
+
+	dbidev->left_offset = x_offset;
+	dbidev->top_offset = y_offset;
+
+	commands_len = size - sizeof(*config);
+	if (!commands_len)
+		return 0;
+
+	while ((i + 1) < commands_len) {
+		u8 command = config->commands[i++];
+		u8 num_parameters = config->commands[i++];
+		const u8 *parameters = &config->commands[i];
+
+		i += num_parameters;
+		if (i > commands_len) {
+			dev_err(dev, "config: command=0x%02x num_parameters=%u overflows\n",
+				command, num_parameters);
+			return -EINVAL;
+		}
+
+		if (command == 0x00 && num_parameters == 1)
+			drm_dbg(drm, "sleep %ums\n", parameters[0]);
+		else
+			drm_dbg(drm, "command %02x %*ph\n", command, num_parameters, parameters);
+	}
+
+	if (i != commands_len) {
+		dev_err(dev, "config: malformed command array\n");
+		return -EINVAL;
+	}
+
+	commands = devm_kzalloc(dev, sizeof(*commands), GFP_KERNEL);
+	if (!commands)
+		return -ENOMEM;
+
+	commands->len = commands_len;
+	commands->buf = devm_kmemdup(dev, config->commands, commands->len, GFP_KERNEL);
+	if (!commands->buf)
+		return -ENOMEM;
+
+	dbidev->driver_private = commands;
+
+	return 0;
+}
+
+static int panel_mipi_dbi_spi_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct drm_display_mode mode;
+	struct mipi_dbi_dev *dbidev;
+	const struct firmware *fw;
+	struct drm_device *drm;
+	struct mipi_dbi *dbi;
+	struct gpio_desc *dc;
+	const char *model;
+	char fw_name[40];
+	int ret;
+
+	ret = device_property_read_string(dev, "model", &model);
+	if (ret) {
+		dev_err(dev, "Failed to get 'model' property\n");
+		return ret;
+	}
+
+	dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm);
+	if (IS_ERR(dbidev))
+		return PTR_ERR(dbidev);
+
+	dbi = &dbidev->dbi;
+	drm = &dbidev->drm;
+
+	snprintf(fw_name, sizeof(fw_name), "%s.bin", model);
+
+	ret = request_firmware(&fw, fw_name, dev);
+	if (ret)
+		return ret;
+
+	ret = panel_mipi_dbi_parse_config(dbidev, &mode, fw);
+	release_firmware(fw);
+	if (ret)
+		return ret;
+
+	dbidev->regulator = devm_regulator_get(dev, "power");
+	if (IS_ERR(dbidev->regulator))
+		return dev_err_probe(dev, PTR_ERR(dbidev->regulator),
+				     "Failed to get regulator 'power'\n");
+
+	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(dbi->reset))
+		return dev_err_probe(dev, PTR_ERR(dbi->reset), "Failed to get GPIO 'reset'\n");
+
+	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
+	if (IS_ERR(dc))
+		return dev_err_probe(dev, PTR_ERR(dc), "Failed to get GPIO 'dc'\n");
+
+	dbidev->backlight = devm_of_find_backlight(dev);
+	if (IS_ERR(dbidev->backlight))
+		return dev_err_probe(dev, PTR_ERR(dbidev->backlight), "Failed to get backlight\n");
+
+	ret = mipi_dbi_spi_init(spi, dbi, dc);
+	if (ret)
+		return ret;
+
+	if (device_property_present(dev, "write-only"))
+		dbi->read_commands = NULL;
+
+	ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0);
+	if (ret)
+		return ret;
+
+	drm_mode_config_reset(drm);
+
+	ret = drm_dev_register(drm, 0);
+	if (ret)
+		return ret;
+
+	spi_set_drvdata(spi, drm);
+
+	drm_fbdev_generic_setup(drm, 0);
+
+	return 0;
+}
+
+static int panel_mipi_dbi_spi_remove(struct spi_device *spi)
+{
+	struct drm_device *drm = spi_get_drvdata(spi);
+
+	drm_dev_unplug(drm);
+	drm_atomic_helper_shutdown(drm);
+
+	return 0;
+}
+
+static void panel_mipi_dbi_spi_shutdown(struct spi_device *spi)
+{
+	drm_atomic_helper_shutdown(spi_get_drvdata(spi));
+}
+
+static int __maybe_unused panel_mipi_dbi_pm_suspend(struct device *dev)
+{
+	return drm_mode_config_helper_suspend(dev_get_drvdata(dev));
+}
+
+static int __maybe_unused panel_mipi_dbi_pm_resume(struct device *dev)
+{
+	drm_mode_config_helper_resume(dev_get_drvdata(dev));
+
+	return 0;
+}
+
+static const struct dev_pm_ops panel_mipi_dbi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(panel_mipi_dbi_pm_suspend, panel_mipi_dbi_pm_resume)
+};
+
+static const struct of_device_id panel_mipi_dbi_spi_of_match[] = {
+	{ .compatible = "panel-mipi-dbi-spi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, panel_mipi_dbi_spi_of_match);
+
+static const struct spi_device_id panel_mipi_dbi_spi_id[] = {
+	{ "panel-mipi-dbi-spi", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, panel_mipi_dbi_spi_id);
+
+static struct spi_driver panel_mipi_dbi_spi_driver = {
+	.driver = {
+		.name = "panel-mipi-dbi-spi",
+		.owner = THIS_MODULE,
+		.of_match_table = panel_mipi_dbi_spi_of_match,
+		.pm = &panel_mipi_dbi_pm_ops,
+	},
+	.id_table = panel_mipi_dbi_spi_id,
+	.probe = panel_mipi_dbi_spi_probe,
+	.remove = panel_mipi_dbi_spi_remove,
+	.shutdown = panel_mipi_dbi_spi_shutdown,
+};
+module_spi_driver(panel_mipi_dbi_spi_driver);
+
+MODULE_DESCRIPTION("MIPI DBI compatible display panel driver");
+MODULE_AUTHOR("Noralf Trønnes");
+MODULE_LICENSE("GPL");
-- 
2.33.0


^ permalink raw reply related

* [PATCH 1/3] dt-bindings: display: add bindings for MIPI DBI compatible SPI panels
From: Noralf Trønnes @ 2022-01-23 17:25 UTC (permalink / raw)
  To: robh+dt, thierry.reding
  Cc: sam, maxime, dave.stevenson, david, devicetree, dri-devel,
	Noralf Trønnes
In-Reply-To: <20220123172520.48741-1-noralf@tronnes.org>

Add binding for MIPI DBI compatible SPI panels.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 .../display/panel/panel-mipi-dbi-spi.yaml     | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
new file mode 100644
index 000000000000..d6c8accb045c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MIPI DBI SPI Panels Device Tree Bindings
+
+maintainers:
+  - Noralf Trønnes <noralf@tronnes.org>
+
+description:
+  This binding is for display panels using a MIPI DBI controller
+  in SPI mode.
+
+allOf:
+  - $ref: panel/panel-common.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: panel-mipi-dbi-spi
+
+  model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: The name of the display panel.
+
+  write-only:
+    type: boolean
+    description:
+      Controller is not readable (ie. MISO is not wired up).
+
+  dc-gpios:
+    maxItems: 1
+    description: |
+      Controller data/command selection (D/CX) in 4-line SPI mode.
+      If not set, the controller is in 3-line SPI mode.
+
+  backlight: true
+  reg: true
+  reset-gpios: true
+
+required:
+  - compatible
+  - model
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            display@0{
+                    compatible = "panel-mipi-dbi-spi";
+                    model = "sainsmart18";
+                    reg = <0>;
+                    spi-max-frequency = <40000000>;
+                    dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+                    reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+                    write-only;
+            };
+    };
+
+...
-- 
2.33.0


^ permalink raw reply related

* [PATCH 2/3] drm/mipi-dbi: Add driver_private member to struct mipi_dbi_dev
From: Noralf Trønnes @ 2022-01-23 17:25 UTC (permalink / raw)
  To: robh+dt, thierry.reding
  Cc: sam, maxime, dave.stevenson, david, devicetree, dri-devel,
	Noralf Trønnes
In-Reply-To: <20220123172520.48741-1-noralf@tronnes.org>

devm_drm_dev_alloc() can't allocate structures that embed a structure
which then again embeds drm_device. Workaround this by adding a
driver_private pointer to struct mipi_dbi_dev which the driver can use for
its additional state.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 include/drm/drm_mipi_dbi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 05e194958265..e24865058d87 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -130,6 +130,8 @@ struct mipi_dbi_dev {
 	 * @dbi: MIPI DBI interface
 	 */
 	struct mipi_dbi dbi;
+
+	void *driver_private;
 };
 
 static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm)
-- 
2.33.0


^ permalink raw reply related

* [PATCH 0/3] drm/panel: Add MIPI DBI compatible SPI driver
From: Noralf Trønnes @ 2022-01-23 17:25 UTC (permalink / raw)
  To: robh+dt, thierry.reding
  Cc: sam, maxime, dave.stevenson, david, devicetree, dri-devel,
	Noralf Trønnes

Hi,

This patchset adds a driver that will work with most MIPI DBI compatible
SPI panels out there.

It's a follow up on 'drm/tiny/st7735r: Match up with staging/fbtft
driver'[1] which aimed at making the st7735r driver work with all panels
adding DT properties.

Maxime gave[2] a good overview of the situation with these displays and
proposed to make a driver that works with all MIPI DBI compatible
controllers and use a firmware file to provide the controller setup for
a particular panel.

Noralf.

[1] https://lore.kernel.org/dri-devel/20211124150757.17929-1-noralf@tronnes.org/
[2] https://lore.kernel.org/dri-devel/20211129093946.xhp22mvdut3m67sc@houat/


Noralf Trønnes (3):
  dt-bindings: display: add bindings for MIPI DBI compatible SPI panels
  drm/mipi-dbi: Add driver_private member to struct mipi_dbi_dev
  drm/panel: Add MIPI DBI compatible SPI driver

 .../display/panel/panel-mipi-dbi-spi.yaml     |  69 ++++
 MAINTAINERS                                   |   7 +
 drivers/gpu/drm/panel/Kconfig                 |  11 +
 drivers/gpu/drm/panel/Makefile                |   1 +
 drivers/gpu/drm/panel/panel-mipi-dbi.c        | 385 ++++++++++++++++++
 include/drm/drm_mipi_dbi.h                    |   2 +
 6 files changed, 475 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-mipi-dbi.c

-- 
2.33.0


^ permalink raw reply

* Re: (subset) [PATCH v2 1/5] arm64: dts: exynos: Align MAX77843 nodes with dtschema on TM2
From: Krzysztof Kozlowski @ 2022-01-23 17:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-samsung-soc, Rob Herring,
	Liam Girdwood, Chanwoo Choi, Mark Brown, MyungJoo Ham, Lee Jones,
	devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20220111174805.223732-2-krzysztof.kozlowski@canonical.com>

On Tue, 11 Jan 2022 18:48:01 +0100, Krzysztof Kozlowski wrote:
> The newly introduced dtschema for MAX77843 MUIC require the children to
> have proper naming and a port@0 property.
> 
> This should not have actual impact on MFD children driver binding,
> because the max77843 MFD driver uses compatibles.  The port@0 is
> disabled to avoid any impact.
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: exynos: Align MAX77843 nodes with dtschema on TM2
      commit: 7638d3c945beb6c781acf5dd0a78e04c76f1c32f

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [RFT][PATCH 1/3] ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
From: Krzysztof Kozlowski @ 2022-01-23 17:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-samsung-soc, Chanho Park,
	Marek Szyprowski, Jaehoon Chung, devicetree, linux-arm-kernel,
	Sam Protsenko, linux-kernel
  Cc: stable, Sylwester Nawrocki
In-Reply-To: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>

On Thu, 30 Dec 2021 20:53:23 +0100, Krzysztof Kozlowski wrote:
> The gpa1-4 pin was put twice in UART3 pin configuration of Exynos5250,
> instead of proper pin gpa1-5.
> 
> 

Applied, thanks!

[1/3] ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
      commit: 372d7027fed43c8570018e124cf78b89523a1f8e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [PATCH v5 1/4] ARM: dts: exynos: split dmas into array of phandles in Exynos5250
From: Krzysztof Kozlowski @ 2022-01-23 17:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Guenter Roeck, linux-samsung-soc,
	Pratyush Yadav, Rob Herring, Andi Shyti, linux-spi, Mark Brown,
	Benson Leung, Lee Jones, devicetree, linux-arm-kernel,
	Sam Protsenko, linux-kernel
  Cc: Alim Akhtar
In-Reply-To: <20220120175747.43403-2-krzysztof.kozlowski@canonical.com>

On Thu, 20 Jan 2022 18:57:44 +0100, Krzysztof Kozlowski wrote:
> "dmas" property should be rather an array of phandles, as dtschema
> points.
> 
> 

Applied, thanks!

[1/4] ARM: dts: exynos: split dmas into array of phandles in Exynos5250
      commit: 88829baee3db050a06fd5ce8a2be0c39992f90da

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [PATCH v2 1/4] ARM: dts: exynos: Align MAX77836 nodes with dtschema on Monk and Rinato
From: Krzysztof Kozlowski @ 2022-01-23 17:10 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sebastian Reichel, linux-pm, Rob Herring,
	linux-samsung-soc, Liam Girdwood, Chanwoo Choi, Mark Brown,
	Lee Jones, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20220111174337.223320-2-krzysztof.kozlowski@canonical.com>

On Tue, 11 Jan 2022 18:43:34 +0100, Krzysztof Kozlowski wrote:
> The newly introduced dtschema for MAX77836 MUIC requires proper naming
> of extcon child node.
> 
> This should not have actual impact on MFD children driver binding,
> because the max77836 MFD driver uses compatibles.
> 
> 
> [...]

Applied, thanks!

[1/4] ARM: dts: exynos: Align MAX77836 nodes with dtschema on Monk and Rinato
      commit: 8d6f5af71e2ada6214df028441d479e1925e105b

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [PATCH 2/8] ARM: dts: exynos: add necessary clock controller inputs in Exynos5260
From: Krzysztof Kozlowski @ 2022-01-23 17:10 UTC (permalink / raw)
  To: Stephen Boyd, Krzysztof Kozlowski, linux-samsung-soc, Rob Herring,
	Chanwoo Choi, linux-clk, Sylwester Nawrocki, linux-arm-kernel,
	devicetree, Michael Turquette, Tomasz Figa, linux-kernel
In-Reply-To: <20220102115356.75796-2-krzysztof.kozlowski@canonical.com>

On Sun, 2 Jan 2022 12:53:50 +0100, Krzysztof Kozlowski wrote:
> Exynos5260 bindings require to feed clock controllers with certain clock
> inputs.  The IO clocks are expected to be provided by the board.  The
> PHY clocks are usually followed by mux which can choose between the PHY
> clock and main 24 MHz oscillator, so skip defining them and just use the
> latter one.
> 
> 
> [...]

Applied, thanks!

[2/8] ARM: dts: exynos: add necessary clock controller inputs in Exynos5260
      commit: 9eb8090f95e2ef8d19ebce6a77e87b26b56fc831

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [PATCH 1/8] arm64: dts: exynos: add necessary clock inputs in Exynos7
From: Krzysztof Kozlowski @ 2022-01-23 17:09 UTC (permalink / raw)
  To: Stephen Boyd, Krzysztof Kozlowski, linux-samsung-soc, Rob Herring,
	Chanwoo Choi, linux-clk, Sylwester Nawrocki, linux-arm-kernel,
	devicetree, Michael Turquette, Tomasz Figa, linux-kernel
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>

On Sun, 2 Jan 2022 12:53:49 +0100, Krzysztof Kozlowski wrote:
> Exynos7 devicetree bindings require more input clocks for TOP0 and
> PERIC1 clock controllers, than already provided.  Existing DTS was not
> matching the bindings, so let's update the DTS, even though the error
> could be in the bindings.
> 
> 

Applied, thanks!

[1/8] arm64: dts: exynos: add necessary clock inputs in Exynos7
      commit: 372d171cd9b472cff7852211195f211150bc27d2

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: (subset) [PATCH 1/3] ARM: dts: exynos: drop unsupported MAX77802 regulators on Odroid XU
From: Krzysztof Kozlowski @ 2022-01-23 17:09 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux-samsung-soc, Javier Martinez Canillas,
	Rob Herring, Liam Girdwood, Mark Brown, Lee Jones, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20211228164305.35877-2-krzysztof.kozlowski@canonical.com>

On Tue, 28 Dec 2021 17:43:03 +0100, Krzysztof Kozlowski wrote:
> The numbering of regulators is not continuous and the MAX77802 does not
> support regulators LDO16, LDO22 and LDO31.
> 
> 

Applied, thanks!

[1/3] ARM: dts: exynos: drop unsupported MAX77802 regulators on Odroid XU
      commit: 0d42eb5ac66d816c95573135951142483640181c

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* Re: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to dtschema
From: Krzysztof Kozlowski @ 2022-01-23 17:09 UTC (permalink / raw)
  To: linux-kernel, Krzysztof Kozlowski, Rob Herring, linux-gpio,
	Linus Walleij, Sylwester Nawrocki, Tomasz Figa, devicetree,
	linux-arm-kernel, linux-samsung-soc
  Cc: Marek Szyprowski, Chanho Park, Sam Protsenko, Alim Akhtar
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>

On Tue, 11 Jan 2022 21:13:58 +0100, Krzysztof Kozlowski wrote:
> Changes since v1
> ================
> 1. Patch #1: add missing pin assignment (Alim).
> 2. Patch #2: correct double sizeof() (Alim).
> 3. Patch #7, #8: put label-override in proper patch (Alim).
> 4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
> 5. New patches: #25 - #28.
>    Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
>    handling, so they need their own compatibles.
>    Please kindly review and provide feedback on these as I do not have
>    details.
> 6. Add review tags.
> 
> [...]

Applied, thanks!

To Samsung SoC tree (Exynos850 is skipped because it was not merged into
v5.17-rc1):

[03/28] ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
        (no commit info)
[04/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
        (no commit info)
[05/28] ARM: dts: exynos: override pins by label in Peach Pit
        (no commit info)
[06/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
        (no commit info)
[07/28] ARM: dts: exynos: override pins by label in Peach Pi
        (no commit info)
[08/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
        (no commit info)
[09/28] ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
        (no commit info)
[10/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
        (no commit info)
[11/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
        (no commit info)
[12/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
        (no commit info)
[13/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
        (no commit info)
[14/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
        (no commit info)
[15/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
        (no commit info)
[16/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
        (no commit info)
[17/28] arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
        (no commit info)
[18/28] arm64: dts: exynos: align pinctrl with dtschema in Exynos7
        (no commit info)
[20/28] arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
        (no commit info)
[21/28] ARM: dts: s3c24xx: align pinctrl with dtschema
        (no commit info)
[22/28] ARM: dts: s3c64xx: align pinctrl with dtschema
        (no commit info)
[23/28] ARM: dts: s5pv210: align pinctrl with dtschema
        (no commit info)
[28/28] arm64: dts: exynos: use dedicated wake-up pinctrl compatible in ExynosAutov9
        (no commit info)

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

^ permalink raw reply

* RE: [PATCH v2 1/4] dt-bindings: Add headers for Tegra234 I2C
From: Akhil R @ 2022-01-23 16:56 UTC (permalink / raw)
  To: Dmitry Osipenko, devicetree@vger.kernel.org, Jonathan Hunter,
	Laxman Dewangan, linux-i2c@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org,
	Mikko Perttunen, robh+dt@kernel.org, thierry.reding@gmail.com
In-Reply-To: <103960bf-ed5c-4a0c-9142-65ffc2e4bca0@gmail.com>

> > Add dt-bindings header files for I2C controllers for Tegra234
> >
> > Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> > ---
> >  include/dt-bindings/clock/tegra234-clock.h | 19 +++++++++++++++++++
> > include/dt-bindings/reset/tegra234-reset.h |  8 ++++++++
> >  2 files changed, 27 insertions(+)
> >
> > diff --git a/include/dt-bindings/clock/tegra234-clock.h
> > b/include/dt-bindings/clock/tegra234-clock.h
> > index 8d7e66e..5d05c19 100644
> > --- a/include/dt-bindings/clock/tegra234-clock.h
> > +++ b/include/dt-bindings/clock/tegra234-clock.h
> > @@ -30,5 +30,24 @@
> >  #define TEGRA234_CLK_PLLC4                   237U
> >  /** @brief 32K input clock provided by PMIC */
> >  #define TEGRA234_CLK_CLK_32K                 289U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 */
> > +#define TEGRA234_CLK_I2C1                    48U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 */
> > +#define TEGRA234_CLK_I2C2                    49U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 */
> > +#define TEGRA234_CLK_I2C3                    50U
> > +/** output of mux controlled by CLK_RST_CONTROLLER_CLK_SOURCE_I2C4
> */
> > +#define TEGRA234_CLK_I2C4                    51U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 */
> > +#define TEGRA234_CLK_I2C6                    52U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C7 */
> > +#define TEGRA234_CLK_I2C7                    53U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C8 */
> > +#define TEGRA234_CLK_I2C8                    54U
> > +/** @brief output of mux controlled by
> CLK_RST_CONTROLLER_CLK_SOURCE_I2C9 */
> > +#define TEGRA234_CLK_I2C9                    55U
> > +
> > +/** @brief PLLP clk output */
> > +#define TEGRA234_CLK_PLLP_OUT0                       102U
> >
> >  #endif
> > diff --git a/include/dt-bindings/reset/tegra234-reset.h
> > b/include/dt-bindings/reset/tegra234-reset.h
> > index 50e13bc..e07e898 100644
> > --- a/include/dt-bindings/reset/tegra234-reset.h
> > +++ b/include/dt-bindings/reset/tegra234-reset.h
> > @@ -12,6 +12,14 @@
> >   */
> >  #define TEGRA234_RESET_SDMMC4                        85U
> >  #define TEGRA234_RESET_UARTA                 100U
> > +#define TEGRA234_RESET_I2C1                  24U
> > +#define TEGRA234_RESET_I2C2                  29U
> > +#define TEGRA234_RESET_I2C3                  30U
> > +#define TEGRA234_RESET_I2C4                  31U
> > +#define TEGRA234_RESET_I2C6                  32U
> > +#define TEGRA234_RESET_I2C7                  33U
> > +#define TEGRA234_RESET_I2C8                  34U
> > +#define TEGRA234_RESET_I2C9                  35U
> 
> Why ID order isn't maintained?
Do you mean RESET_UART4, SDMMC4 etc should be
below RESET_I2C*?

Regards,
Akhil

--
nvpublic

^ permalink raw reply

* Re: [PATCH 4/4] arm64: dts: rockchip: enable the pine64 touch screen on rockpro64
From: Peter Geis @ 2022-01-23 16:50 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Rob Herring, devicetree, arm-mail-list,
	open list:ARM/Rockchip SoC..., Linux Kernel Mailing List
In-Reply-To: <5747938.922zgog0jt@phil>

On Sun, Jan 23, 2022 at 10:30 AM Heiko Stuebner <heiko@sntech.de> wrote:
>
> Hi Peter,
>
> Am Freitag, 7. Januar 2022, 06:13:35 CET schrieb Peter Geis:
> > Enable the touch screen, backlight, and dsi nodes for the Pine64 touch panel
> > attached to the rockpro64.
>
> can you please also include me in the other patches of the series?
> I.e. they introduce a new property for the display, so it's nice to know
> when they get applied.

Apologies, I use get-maintainers.pl automatically and it seems to need
some help with tagging you in some Rockchip elements.
I'll be sure to always manually include you and the rockchip mailing
list on all patches in future series of this sort.

>
> While I do agree with patch 3/4, I'm hesistant about this one.
> The display/touchscreen will probably not be connected on every rockpro64
> so what happens if it doesn't?

This was supposed to be tagged as Do-Not-Merge, but it seems I failed
to do so on the actual patch.
It's here for purely completeness and testing purposes.

>
> I.e are there alternative uses for the affected pins, that may get fried
> when this is always enabled?
>
> So part of me would think that an dt-overlay enabling this might be the
> nicer way to go?

Absolutely.

>
>
> Heiko

Thanks,
Peter

>
>
> > Signed-off-by: Peter Geis <pgwipeout@gmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > index 158befb9a48c..f6c36fcd6db3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > @@ -26,7 +26,7 @@ backlight: backlight {
> >               pwms = <&pwm0 0 1000000 0>;
> >               brightness-levels = <0 4 8 16 32 64 128 255>;
> >               default-brightness-level = <5>;
> > -             status = "disabled";
> > +             status = "okay";
> >       };
> >
> >       clkin_gmac: external-gmac-clock {
> > @@ -594,7 +594,7 @@ touch: touchscreen@5d {
> >               interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
> >               irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
> >               reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
> > -             status = "disabled";
> > +             status = "okay";
> >       };
> >  };
> >
> > @@ -633,7 +633,7 @@ &io_domains {
> >
> >  /* enable for pine64 panel display support */
> >  &mipi_dsi {
> > -     status = "disabled";
> > +     status = "okay";
> >       clock-master;
> >
> >       ports {
> >
>
>
>
>

^ permalink raw reply

* RE: [PATCH v16 2/4] dmaengine: tegra: Add tegra gpcdma driver
From: Akhil R @ 2022-01-23 16:49 UTC (permalink / raw)
  To: Dmitry Osipenko, dan.j.williams@intel.com,
	devicetree@vger.kernel.org, dmaengine@vger.kernel.org,
	Jonathan Hunter, Krishna Yarlagadda, Laxman Dewangan,
	linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org,
	p.zabel@pengutronix.de, Rajesh Gumasta, robh+dt@kernel.org,
	thierry.reding@gmail.com, vkoul@kernel.org
  Cc: Pavan Kunapuli
In-Reply-To: <31ba2627-65c7-1340-e6b9-7c328a485456@gmail.com>

> 21.01.2022 19:24, Akhil R пишет:
> >>>>>>> +static int tegra_dma_terminate_all(struct dma_chan *dc) {
> >>>>>>> +     struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
> >>>>>>> +     unsigned long flags;
> >>>>>>> +     LIST_HEAD(head);
> >>>>>>> +     int err;
> >>>>>>> +
> >>>>>>> +     if (tdc->dma_desc) {
> >>>>>>
> >>>>>> Needs locking protection against racing with the interrupt handler.
> >>>>> tegra_dma_stop_client() waits for the in-flight transfer to
> >>>>> complete and prevents any additional transfer to start.
> >>>>> Wouldn't it manage the race? Do you see any potential issue there?
> >>>>
> >>>> You should consider interrupt handler like a process running in a
> >>>> parallel thread. The interrupt handler sets tdc->dma_desc to NULL,
> >>>> hence you'll get NULL dereference in tegra_dma_stop_client().
> >>>
> >>> Is it better if I remove the below part from tegra_dma_stop_client()
> >>> so that dma_desc is not accessed at all?
> >>>
> >>> +     wcount = tdc_read(tdc, TEGRA_GPCDMA_CHAN_XFER_COUNT);
> >>> +     tdc->dma_desc->bytes_transferred +=
> >>> +                     tdc->dma_desc->bytes_requested - (wcount * 4);
> >>>
> >>> Because I don't see a point in updating the value there. dma_desc is
> >>> set to NULL in the next step in terminate_all() anyway.
> >>
> >> That isn't going help you much because you also can't release DMA
> >> descriptor while interrupt handler still may be running and using
> >> that descriptor.
> >
> > Does the below functions look good to resolve the issue, provided
> > tegra_dma_stop_client() doesn't access dma_desc?
> 
> Stop shall not race with the start.
> 
> > +static int tegra_dma_terminate_all(struct dma_chan *dc) {
> > +       struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
> > +       unsigned long flags;
> > +       LIST_HEAD(head);
> > +       int err;
> > +
> > +       err = tegra_dma_stop_client(tdc);
> > +       if (err)
> > +               return err;
> > +
> > +       tegra_dma_stop(tdc);
> > +
> > +       spin_lock_irqsave(&tdc->vc.lock, flags);
> > +       tegra_dma_sid_free(tdc);
> > +       tdc->dma_desc = NULL;
> > +
> > +       vchan_get_all_descriptors(&tdc->vc, &head);
> > +       spin_unlock_irqrestore(&tdc->vc.lock, flags);
> > +
> > +       vchan_dma_desc_free_list(&tdc->vc, &head);
> > +
> > +       return 0;
> > +}
> >
> > +static irqreturn_t tegra_dma_isr(int irq, void *dev_id) {
> > +       struct tegra_dma_channel *tdc = dev_id;
> > +       struct tegra_dma_desc *dma_desc = tdc->dma_desc;
> > +       struct tegra_dma_sg_req *sg_req;
> > +       u32 status;
> > +
> > +       /* Check channel error status register */
> > +       status = tdc_read(tdc, TEGRA_GPCDMA_CHAN_ERR_STATUS);
> > +       if (status) {
> > +               tegra_dma_chan_decode_error(tdc, status);
> > +               tegra_dma_dump_chan_regs(tdc);
> > +               tdc_write(tdc, TEGRA_GPCDMA_CHAN_ERR_STATUS, 0xFFFFFFFF);
> > +       }
> > +
> > +       status = tdc_read(tdc, TEGRA_GPCDMA_CHAN_STATUS);
> > +       if (!(status & TEGRA_GPCDMA_STATUS_ISE_EOC))
> > +               return IRQ_HANDLED;
> > +
> > +       tdc_write(tdc, TEGRA_GPCDMA_CHAN_STATUS,
> > +                 TEGRA_GPCDMA_STATUS_ISE_EOC);
> > +
> > +       spin_lock(&tdc->vc.lock);
> > +       if (!dma_desc)
> All checks and assignments must be done inside of critical section.

Okay. So, the lock should be held throughout the function.
Do you think tegra_dma_pause should also hold a lock
and remove irq_synchronize? That function also writes
to CSR register.

Regards,
Akhil

^ permalink raw reply

* Re: [PATCH] ARM: dts: exynos: use define for TMU clock on Exynos4412
From: Alim Akhtar @ 2022-01-23 16:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, devicetree, linux-arm-kernel, linux-samsung-soc,
	open list
In-Reply-To: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>

Hi Krzysztof

On Sun, Jan 23, 2022 at 8:42 PM Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
>
> Replace clock hard-coded number with a define from bindings.  No
> functional change.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>


>  arch/arm/boot/dts/exynos4412.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
> index d3802046c8b8..aa0b61b59970 100644
> --- a/arch/arm/boot/dts/exynos4412.dtsi
> +++ b/arch/arm/boot/dts/exynos4412.dtsi
> @@ -813,7 +813,7 @@ &tmu {
>         interrupt-parent = <&combiner>;
>         interrupts = <2 4>;
>         reg = <0x100C0000 0x100>;
> -       clocks = <&clock 383>;
> +       clocks = <&clock CLK_TMU_APBIF>;
>         clock-names = "tmu_apbif";
>         status = "disabled";
>  };
> --
> 2.32.0
>


-- 
Regards,
Alim

^ permalink raw reply

* Re: (subset) [PATCH v2 0/3] (Re)enable DP/HDMI audio for RK3399 Gru
From: Heiko Stuebner @ 2022-01-23 15:40 UTC (permalink / raw)
  To: Mark Brown, Brian Norris, Daniel Vetter, David Airlie,
	Liam Girdwood
  Cc: Heiko Stuebner, Rob Herring, linux-arm-kernel, dri-devel,
	Lin Huang, devicetree, linux-rockchip, linux-kernel, alsa-devel,
	Sandy Huang
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>

On Fri, 14 Jan 2022 15:02:06 -0800, Brian Norris wrote:
> This series fixes DP/HDMI audio for RK3399 Gru systems.
> 
> First, there was a regression with the switch to SPDIF. Patch 1 can be
> taken separately as a regression fix if desired. But it's not quite so
> useful (at least on Chrome OS systems) without the second part.
> 
> Second, jack detection was never upstreamed, because the hdmi-codec
> dependencies were still being worked out when this platform was first
> supported.
> 
> [...]

Applied as fix for 5.17, thanks!

[1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
      commit: b5fbaf7d779f5f02b7f75b080e7707222573be2a

Best regards,
-- 
Heiko Stuebner <heiko@sntech.de>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox