linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] qcom: initial support for the OnePlus 8T
@ 2024-06-24  1:30 Caleb Connolly
  2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
                   ` (7 more replies)
  0 siblings, 8 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

Add bindings for the SM8250 OnePlus devices, a common devicetree,
touchscreen and display drivers, and a dts for the OnePlus 8T (kebab).

The OnePlus 8 series is made up of 3 flagship smartphones from 2019,
featuring the Qualcomm X55 5G PCIe modem.

This series introduces initial support for the 8T, adding drivers for
the 1080x2400 120Hz DSC panel and the Synaptics TCM Oncell touchscreen.

The panel driver suffers from similar limitations to the LG SW43408
panel found on the Pixel 3, namely that after toggling the reset GPIO it
is not possible to get the panel into a working state.

Given the apparent prevelance of this issue, particularly with DSC
panels, I believe this is a bug in the core DSI code, and not a device
or panel specific issue. I think it is still useful to accept these
panel drivers into upstream since, from a users perspective, the panel
is fully functional just by leaving the reset GPIO alone and keeping the
regulator on. The only (theoretical) downside is worse battery life,
which is a small price to pay for a working display.

The Synaptics TCM Oncell touchscreens are a new generation of Synaptics
controllers with a totally incompatible firmware compared to the older
rmi4 touchscreens. A new driver is written which currently only supports
the S3908 controller found on the OnePlus 8T. Downstream vendor drivers
suggest that the controller supports custom touch report configuration,
one can define the exact bit packing of the touch reports, however the
combination of controller and firmware available on this device does not
allow for programming in cusotm configs, so for simplicity this initial
driver uses a hardcoded bit packing to decode the touch reports.

With this series, the OnePlus 8T can boot up to GNOME shell, connect to
a wifi network and browse the web with GPU acceleration.

The touchscreen driver included here is loosely based on a previous
attempt by Frieder Hannenheim which can be found below.

Link: https://lore.kernel.org/lkml/20240327214643.7055-1-friederhannenheim@riseup.net/

---
Caleb Connolly (7):
      dt-bindings: panel: document Samsung AMB655X
      dt-bindings: input: touchscreen: document synaptics TCM oncell
      dt-bindings: arm: qcom: add OnePlus 8 series
      drm: mipi: add mipi_dsi_generic_write_multi_type()
      drm/panel: add driver for samsung amb655x
      Input: touchscreen: add Synaptics TCM oncell S3908
      arm64: dts: qcom: add OnePlus 8T (kebab)

 Documentation/devicetree/bindings/arm/qcom.yaml    |   3 +
 .../bindings/display/panel/samsung,amb655x.yaml    |  59 ++
 .../input/touchscreen/syna,tcm-oncell.yaml         |  66 ++
 MAINTAINERS                                        |  14 +
 arch/arm64/boot/dts/qcom/Makefile                  |   1 +
 .../arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi | 866 +++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts  |  36 +
 drivers/gpu/drm/drm_mipi_dsi.c                     |  40 +
 drivers/gpu/drm/panel/Kconfig                      |   9 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-samsung-amb655x.c      | 420 ++++++++++
 drivers/input/touchscreen/Kconfig                  |  11 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/synaptics_tcm_oncell.c   | 617 +++++++++++++++
 include/drm/drm_mipi_dsi.h                         |  16 +
 15 files changed, 2160 insertions(+)
---
change-id: 20240622-oneplus8-788005cc74ae
base-commit: f76698bd9a8ca01d3581236082d786e9a6b72bb7

// Caleb (they/them)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  1:33   ` Caleb Connolly
  2024-06-27 22:12   ` Rob Herring
  2024-06-24  1:30 ` [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell Caleb Connolly
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

Describe the Samsung AMB655X panel. It has three supplies.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 .../bindings/display/panel/samsung,amb655x.yaml    | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
new file mode 100644
index 000000000000..eb987d022a0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,amb655x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung AMB655X 1080x2400 120hz AMOLED panel
+
+maintainers:
+  - Caleb Connolly <caleb@postmarketos.org>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: samsung,amb655x
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    description: reset gpio, must be GPIO_ACTIVE_LOW
+  vddio-supply: true
+  vdd-supply: true
+  avdd-supply: true
+  enable-gpios: true
+  port: true
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - avdd-supply
+  - vddio-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        panel@0 {
+            compatible = "samsung,ams495qa01";
+            reg = <0>;
+            reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
+            vdd-supply = <&vcc_3v3>;
+
+            port {
+                mipi_in_panel: endpoint {
+                  remote-endpoint = <&mipi_out_panel>;
+                };
+            };
+        };
+    };
+
+...

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
  2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  2:42   ` Rob Herring (Arm)
  2024-06-24  7:25   ` Dmitry Torokhov
  2024-06-24  1:30 ` [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series Caleb Connolly
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

Document the Synaptics TCM oncell series of touchscreens, starting with
the s3908.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 .../input/touchscreen/syna,tcm-oncell.yaml         | 66 ++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml b/Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
new file mode 100644
index 000000000000..1795df584987
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/syna,s3908.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synaptics TCM Oncell i2c touchscreen
+
+maintainers:
+  - Caleb Connolly <caleb@postmarketos.org>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - syna,s3908
+
+  reg:
+    maxItems: 1
+
+  interrupts-extended:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+    description: Reset GPIO the chip is connected to.
+
+  vdd-supply:
+    description: a phandle for the regulator supplying 3V power.
+
+  vcc-supply:
+    description: a phandle for the regulator supplying IO power.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts-extended
+  - reset-gpios
+  - vdd-supply
+  - vcc-supply
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+      clock-frequency = <400000>;
+      status = "okay";
+
+      touchscreen@4b {
+        compatible = "syna,s3908";
+        reg = <0x4B>;
+
+        interrupts-extended = <&tlmm 39 0x2008>;
+
+        reset-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+
+        vdd-supply = <&vreg_l13a_ts_3p0>;
+        vcc-supply = <&vreg_l1c_1p8>;
+      };
+    };

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
  2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
  2024-06-24  1:30 ` [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  4:52   ` Krzysztof Kozlowski
  2024-06-24 20:40   ` Rob Herring
  2024-06-24  1:30 ` [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type() Caleb Connolly
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

Add bindings for the OnePlus 8, 8 Pro, and 8T devices.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index d839691a900c..a41eeb8c3fc5 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -986,8 +986,11 @@ properties:
           - enum:
               - qcom,qrb5165-rb5
               - qcom,sm8250-hdk
               - qcom,sm8250-mtp
+              - oneplus,kebab
+              - oneplus,instantnoodle
+              - oneplus,instantnoodlep
               - sony,pdx203-generic
               - sony,pdx206-generic
               - xiaomi,elish
               - xiaomi,pipa

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type()
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
                   ` (2 preceding siblings ...)
  2024-06-24  1:30 ` [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  5:21   ` Dmitry Baryshkov
  2024-06-24  1:30 ` [PATCH 5/7] drm/panel: add driver for samsung amb655x Caleb Connolly
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

Some panels like the Samsung AMB655X use long write commands for all
non-standard messages and do not work when trying to use the appropriate
command type.

Support these panels by introducing a new helper to send commands of a
specific type, overriding the normal rules.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 40 ++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     | 16 ++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index a471c46f5ca6..d0fee0498d91 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -819,8 +819,48 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
 	}
 }
 EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
 
+/**
+ * mipi_dsi_generic_write_type() - transmit data using a generic write packet of
+ * a specific type
+ * @dsi: DSI peripheral device
+ * @type: data type of the packet
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * This function will automatically choose the right data type depending on
+ * the payload length.
+ *
+ * Return: The number of bytes transmitted on success or a negative error code
+ * on failure.
+ */
+ssize_t mipi_dsi_generic_write_multi_type(struct mipi_dsi_multi_context *ctx,
+					  u8 type, const void *payload, size_t size)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct mipi_dsi_msg msg = {
+		.channel = dsi->channel,
+		.tx_buf = payload,
+		.tx_len = size,
+		.type = type,
+	};
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return 0;
+
+	ret = mipi_dsi_device_transfer(dsi, &msg);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(&dsi->dev, "sending generic data %*ph failed: %zd\n",
+			(int)size, payload, ret);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_multi_type);
+
 /**
  * mipi_dsi_generic_read() - receive data using a generic read packet
  * @dsi: DSI peripheral device
  * @params: buffer containing the request parameters
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 71d121aeef24..a5d949e695d4 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -287,8 +287,10 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
 				  const void *payload, size_t size);
 void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
 				  const void *payload, size_t size);
+ssize_t mipi_dsi_generic_write_multi_type(struct mipi_dsi_multi_context *ctx, u8 type,
+				    const void *payload, size_t size);
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
 #define mipi_dsi_msleep(ctx, delay)	\
@@ -432,8 +434,22 @@ void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
 		static const u8 d[] = { cmd, seq };                     \
 		mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
 	} while (0)
 
+/**
+ * mipi_dsi_dcs_write_long - transmit a DCS long command with payload
+ * @dsi: DSI peripheral device
+ * @cmd: Commands
+ * @seq: buffer containing data to be transmitted
+ */
+#define mipi_dsi_dcs_write_long(ctx, cmd, seq...)                          \
+	do {                                                               \
+		static const u8 d[] = { cmd, seq };                        \
+		mipi_dsi_generic_write_multi_type(ctx,                     \
+						  MIPI_DSI_DCS_LONG_WRITE, \
+						  d, ARRAY_SIZE(d));       \
+	} while (0)
+
 /**
  * struct mipi_dsi_driver - DSI driver
  * @driver: device driver model driver
  * @probe: callback for device binding

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 5/7] drm/panel: add driver for samsung amb655x
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
                   ` (3 preceding siblings ...)
  2024-06-24  1:30 ` [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type() Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  5:31   ` Dmitry Baryshkov
  2024-06-24  1:30 ` [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908 Caleb Connolly
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

This is a 1080x2400 120hz panel used on the OnePlus 8T. It uses DSC but
uses non-standard DCS commands.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 MAINTAINERS                                   |   7 +
 drivers/gpu/drm/panel/Kconfig                 |   9 +
 drivers/gpu/drm/panel/Makefile                |   1 +
 drivers/gpu/drm/panel/panel-samsung-amb655x.c | 420 ++++++++++++++++++++++++++
 4 files changed, 437 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 807feae089c4..2b9cfbf92d7a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7142,8 +7142,15 @@ M:	Robert Chiras <robert.chiras@nxp.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
 F:	drivers/gpu/drm/panel/panel-raydium-rm67191.c
 
+DRM DRIVER FOR SAMSUNG AMB655X PANEL
+M:	Caleb Connolly <caleb@postmarketos.org>
+S:	Maintained
+T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
+F:	drivers/gpu/drm/panel/panel-samsung-amb655x.c
+
 DRM DRIVER FOR SAMSUNG DB7430 PANELS
 M:	Linus Walleij <linus.walleij@linaro.org>
 S:	Maintained
 T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index bf4eadfe21cb..7203d16ab20a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -590,8 +590,17 @@ config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01
 	depends on OF
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS
 
+config DRM_PANEL_SAMSUNG_AMB655X
+	tristate "Samsung AMB655X DSI panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  DRM panel driver for the Samsung AMB655X panel.
+	  This panel has a resolution of 1080x2400 @ 60hz or 120Hz.
+
 config DRM_PANEL_SAMSUNG_ATNA33XC20
 	tristate "Samsung ATNA33XC20 eDP panel"
 	depends on OF
 	depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 051b75b3df7b..be6d500a56a4 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -58,8 +58,9 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o
 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o
 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o
 obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMB655X) += panel-samsung-amb655x.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-amb655x.c b/drivers/gpu/drm/panel/panel-samsung-amb655x.c
new file mode 100644
index 000000000000..2af89bfd798a
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-amb655x.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree:
+//   Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+//   Copyright (c) 2024 Caleb Connolly <caleb@postmarketos.org>
+
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dsc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+struct samsung_amb655x {
+	struct drm_panel panel;
+	struct mipi_dsi_device *dsi;
+	struct drm_dsc_config dsc;
+	struct gpio_desc *reset_gpio;
+	struct regulator_bulk_data supplies[3];
+};
+
+static inline
+struct samsung_amb655x *to_samsung_amb655x(struct drm_panel *panel)
+{
+	return container_of(panel, struct samsung_amb655x, panel);
+}
+
+static void samsung_amb655x_reset(struct samsung_amb655x *amb655x)
+{
+	gpiod_set_value_cansleep(amb655x->reset_gpio, 0);
+	usleep_range(10000, 11000);
+	gpiod_set_value_cansleep(amb655x->reset_gpio, 1);
+	usleep_range(1000, 2000);
+	gpiod_set_value_cansleep(amb655x->reset_gpio, 0);
+	usleep_range(10000, 11000);
+}
+
+static int samsung_amb655x_on(struct samsung_amb655x *amb655x)
+{
+	struct drm_dsc_picture_parameter_set pps;
+	struct mipi_dsi_device *dsi = amb655x->dsi;
+	struct mipi_dsi_multi_context ctx = { .dsi = dsi };
+	struct device *dev = &dsi->dev;
+	int ret;
+
+	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	drm_dsc_pps_payload_pack(&pps, &amb655x->dsc);
+
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_buffer_multi(&ctx, &pps, sizeof(pps));
+	mipi_dsi_dcs_write_long(&ctx, 0x9d, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+		return ret;
+	}
+	usleep_range(11000, 12000);
+
+	/* VLIN CURRENT LIMIT */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x04);
+	mipi_dsi_dcs_write_long(&ctx, 0xd5, 0x24, 0x9e, 0x9e, 0x00, 0x20);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	/* OSC Select */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x16);
+	mipi_dsi_dcs_write_long(&ctx, 0xd1, 0x22);
+	mipi_dsi_dcs_write_long(&ctx, 0xd6, 0x11);
+	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0xa5, 0xa5);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	/* TE ON */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, MIPI_DCS_SET_TEAR_ON, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	/* TSP Setting */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xdf, 0x83, 0x00, 0x10);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xe6, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000, 1080 - 1);
+	if (ret < 0) {
+		dev_err(dev, "Failed to set column address: %d\n", ret);
+		return ret;
+	}
+
+	ret = mipi_dsi_dcs_set_page_address(dsi, 0x0000, 2400 - 1);
+	if (ret < 0) {
+		dev_err(dev, "Failed to set page address: %d\n", ret);
+		return ret;
+	}
+
+	/* FD Setting */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xd5, 0x8d);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x0a);
+	mipi_dsi_dcs_write_long(&ctx, 0xd5, 0x05);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	/* FFC Function */
+	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xe4, 0xa6, 0x75, 0xa3);
+	mipi_dsi_dcs_write_long(&ctx, 0xe9,
+			       0x11, 0x75, 0xa6, 0x75, 0xa3, 0x4b, 0x17, 0xac,
+			       0x4b, 0x17, 0xac, 0x00, 0x19, 0x19);
+	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0xa5, 0xa5);
+	msleep(61);
+
+	/* Dimming Setting */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x06);
+	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x05);
+	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x13);
+	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x4c);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	mipi_dsi_dcs_write_long(&ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
+
+	/* refresh rate Transition */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	/* 60 Hz */
+	//mipi_dsi_dcs_write_long(&ctx, 0x60, 0x00);
+	/* 120 Hz */
+	mipi_dsi_dcs_write_long(&ctx, 0x60, 0x10);
+
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+
+	/* ACL Mode */
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_dcs_write_long(&ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
+	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
+	mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
+	msleep(110);
+
+	/* Enable backlight */
+	mipi_dsi_dcs_write_long(&ctx, 0x9F, 0x5A, 0x5A);
+	mipi_dsi_dcs_set_display_on(dsi);
+	mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_ENTER_NORMAL_MODE);
+	mipi_dsi_dcs_write_long(&ctx, 0x9F, 0xA5, 0xA5);
+
+	return ctx.accum_err;
+}
+
+static int samsung_amb655x_off(struct samsung_amb655x *amb655x)
+{
+	struct mipi_dsi_device *dsi = amb655x->dsi;
+	struct mipi_dsi_multi_context ctx = { .dsi = dsi };
+	struct device *dev = &dsi->dev;
+	int ret;
+
+	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	mipi_dsi_dcs_write_long(&ctx, 0x9f, 0x5a, 0x5a);
+
+	ret = mipi_dsi_dcs_set_display_on(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to set display on: %d\n", ret);
+		return ret;
+	}
+	msleep(20);
+
+	ret = mipi_dsi_dcs_set_display_off(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to set display off: %d\n", ret);
+		return ret;
+	}
+	msleep(20);
+
+	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
+		return ret;
+	}
+
+	mipi_dsi_dcs_write_long(&ctx, 0x9f, 0xa5, 0xa5);
+	msleep(150);
+
+	return ctx.accum_err;
+}
+
+static int samsung_amb655x_prepare(struct drm_panel *panel)
+{
+	struct samsung_amb655x *ctx = to_samsung_amb655x(panel);
+	struct device *dev = &ctx->dsi->dev;
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret) {
+		dev_err(dev, "Failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	samsung_amb655x_reset(ctx);
+
+	ret = samsung_amb655x_on(ctx);
+	if (ret < 0) {
+		dev_err(dev, "Failed to initialize panel: %d\n", ret);
+		gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+		return ret;
+	}
+
+	msleep(28);
+
+	return 0;
+}
+
+static int samsung_amb655x_unprepare(struct drm_panel *panel)
+{
+	struct samsung_amb655x *ctx = to_samsung_amb655x(panel);
+	struct device *dev = &ctx->dsi->dev;
+	int ret;
+
+	ret = samsung_amb655x_off(ctx);
+	if (ret < 0)
+		dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
+
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret) {
+		dev_err(dev, "Failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct drm_display_mode samsung_amb655x_120_mode = {
+	.clock = (1080 + 52 + 24 + 24) * (2400 + 4 + 4 + 8) * 120 / 1000,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + 52,
+	.hsync_end = 1080 + 52 + 24,
+	.htotal = 1080 + 52 + 24 + 24,
+	.vdisplay = 2400,
+	.vsync_start = 2400 + 4,
+	.vsync_end = 2400 + 4 + 4,
+	.vtotal = 2400 + 4 + 4 + 8,
+	.width_mm = 70,
+	.height_mm = 151,
+};
+
+static int samsung_amb655x_get_modes(struct drm_panel *panel,
+				     struct drm_connector *connector)
+{
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_duplicate(connector->dev, &samsung_amb655x_120_mode);
+	if (!mode)
+		return -ENOMEM;
+
+	drm_mode_set_name(mode);
+
+	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;
+}
+
+static const struct drm_panel_funcs samsung_amb655x_panel_funcs = {
+	.prepare = samsung_amb655x_prepare,
+	.unprepare = samsung_amb655x_unprepare,
+	.get_modes = samsung_amb655x_get_modes,
+};
+
+static int samsung_amb655x_bl_update_status(struct backlight_device *bl)
+{
+	struct mipi_dsi_device *dsi = bl_get_data(bl);
+	u16 brightness = backlight_get_brightness(bl);
+	int ret;
+
+	ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct backlight_ops samsung_amb655x_bl_ops = {
+	.update_status = samsung_amb655x_bl_update_status,
+};
+
+static struct backlight_device *
+samsung_amb655x_create_backlight(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	const struct backlight_properties props = {
+		.type = BACKLIGHT_RAW,
+		.brightness = 2047,
+		.max_brightness = 2047,
+	};
+
+	return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+					      &samsung_amb655x_bl_ops, &props);
+}
+
+static int samsung_amb655x_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct samsung_amb655x *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->supplies[0].supply = "vddio";
+	ctx->supplies[1].supply = "vdd";
+	ctx->supplies[2].supply = "avdd";
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get vddio regulator\n");
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret)
+		dev_err(dev, "Failed to enable regulators: %d\n", ret);
+
+	ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+				     "Failed to get reset-gpios\n");
+
+	ctx->dsi = dsi;
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+
+	drm_panel_init(&ctx->panel, dev, &samsung_amb655x_panel_funcs,
+		       DRM_MODE_CONNECTOR_DSI);
+	ctx->panel.prepare_prev_first = true;
+
+	ctx->panel.backlight = samsung_amb655x_create_backlight(dsi);
+	if (IS_ERR(ctx->panel.backlight))
+		return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
+				     "Failed to create backlight\n");
+
+	drm_panel_add(&ctx->panel);
+
+	/* This panel only supports DSC; unconditionally enable it */
+	dsi->dsc = &ctx->dsc;
+
+	ctx->dsc.dsc_version_major = 1;
+	ctx->dsc.dsc_version_minor = 1;
+
+	/* TODO: Pass slice_per_pkt = 2 */
+	ctx->dsc.slice_height = 30;
+	ctx->dsc.slice_width = 540;
+	/*
+	 * TODO: hdisplay should be read from the selected mode once
+	 * it is passed back to drm_panel (in prepare?)
+	 */
+	WARN_ON(1080 % ctx->dsc.slice_width);
+	ctx->dsc.slice_count = 1080 / ctx->dsc.slice_width;
+	ctx->dsc.bits_per_component = 8;
+	ctx->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */
+	ctx->dsc.block_pred_enable = true;
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
+		drm_panel_remove(&ctx->panel);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void samsung_amb655x_remove(struct mipi_dsi_device *dsi)
+{
+	struct samsung_amb655x *ctx = mipi_dsi_get_drvdata(dsi);
+	int ret;
+
+	ret = mipi_dsi_detach(dsi);
+	if (ret < 0)
+		dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
+
+	drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id samsung_amb655x_of_match[] = {
+	{ .compatible = "samsung,amb655x" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, samsung_amb655x_of_match);
+
+static struct mipi_dsi_driver samsung_amb655x_driver = {
+	.probe = samsung_amb655x_probe,
+	.remove = samsung_amb655x_remove,
+	.driver = {
+		.name = "panel-samsung-amb655x",
+		.of_match_table = samsung_amb655x_of_match,
+	},
+};
+module_mipi_dsi_driver(samsung_amb655x_driver);
+
+MODULE_AUTHOR("Caleb Connolly <caleb@postmarketos.org>");
+MODULE_DESCRIPTION("DRM driver for Samsung AMB655X DSC DSI panel");
+MODULE_LICENSE("GPL");

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
                   ` (4 preceding siblings ...)
  2024-06-24  1:30 ` [PATCH 5/7] drm/panel: add driver for samsung amb655x Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-24  7:42   ` Dmitry Torokhov
  2024-06-24  1:30 ` [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab) Caleb Connolly
  2024-06-24  5:18 ` [PATCH 0/7] qcom: initial support for the OnePlus 8T Dmitry Baryshkov
  7 siblings, 1 reply; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

The TCM oncell is the next generation of Synaptics touchscreen ICs.
These run a very featured firmware with a reasonably well defined API.
It is however entirely incompatible with the existing RMI4 interface.

Unfortunately, no public datasheet for the interface seems to be
available, instead this driver was created through a combination of
vendor drivers and trial and error.

The firmware interface implies support for defining the exact bit
encoding of the touch reports, however on the S3908 chip + firmware
found in the OnePlus 8t the TCM_SET_TOUCH_REPORT_CONFIG command appears
to be unsupported.

Co-developed-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
Signed-off-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 MAINTAINERS                                      |   7 +
 drivers/input/touchscreen/Kconfig                |  11 +
 drivers/input/touchscreen/Makefile               |   1 +
 drivers/input/touchscreen/synaptics_tcm_oncell.c | 617 +++++++++++++++++++++++
 4 files changed, 636 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b9cfbf92d7a..db589c841d8c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21826,8 +21826,15 @@ M:	Icenowy Zheng <icenowy@aosc.io>
 S:	Maintained
 F:	Documentation/devicetree/bindings/regulator/silergy,sy8106a.yaml
 F:	drivers/regulator/sy8106a-regulator.c
 
+SYNAPTICS TCM ONCELL TOUCHSCREEN DRIVER
+M:	Caleb Connolly <caleb@postmarketos.org>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
+F:	drivers/input/touchscreen/synaptics_tcm_oncell.c
+
 SYNC FILE FRAMEWORK
 M:	Sumit Semwal <sumit.semwal@linaro.org>
 R:	Gustavo Padovan <gustavo@padovan.org>
 L:	linux-media@vger.kernel.org
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c821fe3ee794..43c4fd80601c 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -531,8 +531,19 @@ config TOUCHSCREEN_S6SY761
 
 	  To compile this driver as module, choose M here: the
 	  module will be called s6sy761.
 
+config TOUCHSCREEN_SYNAPTICS_TCM_ONCELL
+	tristate "Synaptics TCM Oncell Touchscreen driver"
+	depends on I2C
+	help
+	  Say Y if you have the Synaptics S3908 TCM Oncell
+
+	  If unsure, say N
+
+	  To compile this driver as module, choose M here: the
+	  module will be called synaptics_tcm_oncell.
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	select SERIO
 	help
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index a81cb5aa21a5..6a2b85050c3a 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -88,8 +88,9 @@ obj-$(CONFIG_TOUCHSCREEN_STMFTS)	+= stmfts.o
 obj-$(CONFIG_TOUCHSCREEN_STMPE)		+= stmpe-ts.o
 obj-$(CONFIG_TOUCHSCREEN_SUN4I)		+= sun4i-ts.o
 obj-$(CONFIG_TOUCHSCREEN_SUR40)		+= sur40.o
 obj-$(CONFIG_TOUCHSCREEN_SURFACE3_SPI)	+= surface3_spi.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_ONCELL)	+= synaptics_tcm_oncell.o
 obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)	+= ti_am335x_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
diff --git a/drivers/input/touchscreen/synaptics_tcm_oncell.c b/drivers/input/touchscreen/synaptics_tcm_oncell.c
new file mode 100644
index 000000000000..c1ba9a3a93c0
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_tcm_oncell.c
@@ -0,0 +1,617 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Driver for Synaptics TCM Oncell Touchscreens
+ *
+ *  Copyright (c) 2024 Frieder Hannenheim <frieder.hannenheim@proton.me>
+ *  Copyright (c) 2024 Caleb Connolly <caleb@postmarketos.org>
+ */
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <asm/unaligned.h>
+#include <linux/delay.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+/*
+ * The TCM oncell interface uses a command byte, which may be followed by additional
+ * data. The packet format is defined in the tcm_cmd struct.
+ *
+ * The following list only defines commands that are used in this driver (and their
+ * counterparts for context). Vendor reference implementations can be found at
+ * https://github.com/LineageOS/android_kernel_oneplus_sm8250/tree/ee0a7ee1939ffd53000e42051caf8f0800defb27/drivers/input/touchscreen/synaptics_tcm
+ */
+
+/*
+ * Request information about the chip. We don't send this command explicitly as
+ * the controller automatically sends this information when starting up.
+ */
+#define TCM_IDENTIFY 0x02
+
+/* Enable/disable reporting touch inputs */
+#define TCM_ENABLE_REPORT 0x05
+#define TCM_DISABLE_REPORT 0x06
+
+/*
+ * After powering on, we send this to exit the bootloader mode and run the main
+ * firmware.
+ */
+#define TCM_RUN_APPLICATION_FIRMWARE 0x14
+
+/*
+ * Reports information about the vendor provided application firmware. This is
+ * also used to determine when the firmware has finished booting.
+ */
+#define TCM_GET_APPLICATION_INFO 0x20
+
+#define MODE_APPLICATION 0x01
+
+#define APP_STATUS_OK 0x00
+#define APP_STATUS_BOOTING 0x01
+#define APP_STATUS_UPDATING 0x02
+#define APP_STATUS_BAD_APP_CONFIG 0xff
+
+/* status codes */
+#define REPORT_IDLE 0x00
+#define REPORT_OK 0x01
+#define REPORT_BUSY 0x02
+#define REPORT_CONTINUED_READ 0x03
+#define REPORT_RECEIVE_BUFFER_OVERFLOW 0x0c
+#define REPORT_PREVIOUS_COMMAND_PENDING 0x0d
+#define REPORT_NOT_IMPLEMENTED 0x0e
+#define REPORT_ERROR 0x0f
+
+/* report types */
+#define REPORT_IDENTIFY 0x10
+#define REPORT_TOUCH 0x11
+#define REPORT_DELTA 0x12
+#define REPORT_RAW 0x13
+#define REPORT_DEBUG 0x14
+#define REPORT_LOG 0x1d
+#define REPORT_TOUCH_HOLD 0x20
+#define REPORT_INVALID 0xff
+
+/* Touch report codes */
+#define TOUCH_END 0
+#define TOUCH_FOREACH_ACTIVE_OBJECT 1
+#define TOUCH_FOREACH_OBJECT 2
+#define TOUCH_FOREACH_END 3
+#define TOUCH_PAD_TO_NEXT_BYTE 4
+#define TOUCH_TIMESTAMP 5
+#define TOUCH_OBJECT_N_INDEX 6
+#define TOUCH_OBJECT_N_CLASSIFICATION 7
+#define TOUCH_OBJECT_N_X_POSITION 8
+#define TOUCH_OBJECT_N_Y_POSITION 9
+#define TOUCH_OBJECT_N_Z 10
+#define TOUCH_OBJECT_N_X_WIDTH 11
+#define TOUCH_OBJECT_N_Y_WIDTH 12
+#define TOUCH_OBJECT_N_TX_POSITION_TIXELS 13
+#define TOUCH_OBJECT_N_RX_POSITION_TIXELS 14
+#define TOUCH_0D_BUTTONS_STATE 15
+#define TOUCH_GESTURE_DOUBLE_TAP 16
+#define TOUCH_FRAME_RATE 17 /* Normally 80hz */
+#define TOUCH_POWER_IM 18
+#define TOUCH_CID_IM 19
+#define TOUCH_RAIL_IM 20
+#define TOUCH_CID_VARIANCE_IM 21
+#define TOUCH_NSM_FREQUENCY 22
+#define TOUCH_NSM_STATE 23
+#define TOUCH_NUM_OF_ACTIVE_OBJECTS 23
+#define TOUCH_NUM_OF_CPU_CYCLES_USED_SINCE_LAST_FRAME 24
+#define TOUCH_TUNING_GAUSSIAN_WIDTHS 0x80
+#define TOUCH_TUNING_SMALL_OBJECT_PARAMS 0x81
+#define TOUCH_TUNING_0D_BUTTONS_VARIANCE 0x82
+#define TOUCH_REPORT_GESTURE_SWIPE 193
+#define TOUCH_REPORT_GESTURE_CIRCLE 194
+#define TOUCH_REPORT_GESTURE_UNICODE 195
+#define TOUCH_REPORT_GESTURE_VEE 196
+#define TOUCH_REPORT_GESTURE_TRIANGLE 197
+#define TOUCH_REPORT_GESTURE_INFO 198
+#define TOUCH_REPORT_GESTURE_COORDINATE 199
+#define TOUCH_REPORT_CUSTOMER_GRIP_INFO 203
+
+struct tcm_message_header {
+	u8 marker;
+	u8 code;
+} __packed;
+
+/* header + 2 bytes (which are length of data depending on report code) */
+#define REPORT_PEAK_LEN (sizeof(struct tcm_message_header) + 2)
+
+struct tcm_cmd {
+	u8 cmd;
+	u16 length;
+	u8 data[];
+};
+
+struct tcm_identification {
+	struct tcm_message_header header;
+	u16 length;
+	u8 version;
+	u8 mode;
+	char part_number[16];
+	u8 build_id[4];
+	u8 max_write_size[2];
+} __packed;
+
+struct tcm_app_info {
+	struct tcm_message_header header;
+	u16 length;
+	u8 version[2];
+	u16 status;
+	u8 static_config_size[2];
+	u8 dynamic_config_size[2];
+	u8 app_config_start_write_block[2];
+	u8 app_config_size[2];
+	u8 max_touch_report_config_size[2];
+	u8 max_touch_report_payload_size[2];
+	char customer_config_id[16];
+	u16 max_x;
+	u16 max_y;
+	u8 max_objects[2];
+	u8 num_of_buttons[2];
+	u8 num_of_image_rows[2];
+	u8 num_of_image_cols[2];
+	u8 has_hybrid_data[2];
+} __packed;
+
+struct tcm_report_config_prop {
+	u8 id; /* TOUCH_OBJECT_* */
+	u8 bits; /* Size of the field in bits */
+};
+
+struct tcm_report_config_entry {
+	u8 foreach; /* TOUCH_FOREACH_* (and maybe other things?) */
+	int n_props;
+	const struct tcm_report_config_prop *props;
+};
+
+struct tcm_report_config {
+	int n_entries;
+	const struct tcm_report_config_entry *entries;
+};
+
+struct tcm_data {
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct input_dev *input;
+	struct touchscreen_properties prop;
+	struct gpio_desc *reset_gpio;
+	struct completion response;
+	struct regulator_bulk_data supplies[2];
+
+	/* annoying state */
+	u16 buf_size;
+	char buf[256];
+};
+
+static int tcm_send_cmd(struct tcm_data *tcm, struct tcm_cmd *cmd)
+{
+	struct i2c_client *client = tcm->client;
+	struct i2c_msg msg;
+	int ret;
+
+	dev_dbg(&client->dev, "sending command %#x\n", cmd->cmd);
+
+	msg.addr = client->addr;
+	msg.flags = 0;
+	msg.len = 1 + cmd->length;
+	msg.buf = (u8 *)cmd;
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret == 1)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static int tcm_send_cmd_noargs(struct tcm_data *tcm, u8 cmd)
+{
+	struct tcm_cmd c = {
+		.cmd = cmd,
+		.length = 0,
+	};
+
+	return tcm_send_cmd(tcm, &c);
+}
+
+static int tcm_recv_report(struct tcm_data *tcm,
+			   void *buf, size_t length)
+{
+	struct i2c_client *client = tcm->client;
+	struct i2c_msg msg;
+	int ret;
+
+	msg.addr = client->addr;
+	msg.flags = I2C_M_RD;
+	msg.len = length;
+	msg.buf = buf;
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret == 1)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static int tcm_read_message(struct tcm_data *tcm, u8 cmd, void *buf, size_t length)
+{
+	int ret;
+
+	reinit_completion(&tcm->response);
+	ret = tcm_send_cmd_noargs(tcm, cmd);
+	if (ret)
+		return ret;
+
+	ret = wait_for_completion_timeout(&tcm->response, msecs_to_jiffies(1000));
+	if (ret == 0)
+		return -ETIMEDOUT;
+
+	if (buf) {
+		if (length > tcm->buf_size) {
+			dev_warn(&tcm->client->dev, "expected %zu bytes, got %u\n",
+				 length, tcm->buf_size);
+		}
+		length = min(tcm->buf_size, length);
+		memcpy(buf, tcm->buf, length);
+	}
+
+	return 0;
+}
+
+static void tcm_power_off(void *data)
+{
+	struct tcm_data *tcm = data;
+
+	disable_irq(tcm->client->irq);
+	regulator_bulk_disable(ARRAY_SIZE(tcm->supplies), tcm->supplies);
+}
+
+static int tcm_input_open(struct input_dev *dev)
+{
+	struct tcm_data *tcm = input_get_drvdata(dev);
+
+	return i2c_smbus_write_byte(tcm->client, TCM_ENABLE_REPORT);
+}
+
+static void tcm_input_close(struct input_dev *dev)
+{
+	struct tcm_data *tcm = input_get_drvdata(dev);
+	int ret;
+
+	ret = i2c_smbus_write_byte(tcm->client, TCM_DISABLE_REPORT);
+	if (ret)
+		dev_err(&tcm->client->dev, "failed to turn off sensing\n");
+}
+
+/*
+ * The default report config looks like this:
+ *
+ * a5 01 80 00 11 08 1e 08 0f 01 04 01 06 04 07 04
+ * 08 0c 09 0c 0a 08 0b 08 0c 08 0d 10 0e 10 03 00
+ * 00 00
+ *
+ * a5 01 80 00 - HEADER + length
+ *
+ * 11 08 - TOUCH_FRAME_RATE (8 bits)
+ * 30 08 - UNKNOWN (8 bits)
+ * 0f 01 - TOUCH_0D_BUTTONS_STATE (1 bit)
+ * 04 01 - TOUCH_PAD_TO_NEXT_BYTE (7 bits - padding)
+ * 06 04 - TOUCH_OBJECT_N_INDEX (4 bits)
+ * 07 04 - TOUCH_OBJECT_N_CLASSIFICATION (4 bits)
+ * 08 0c - TOUCH_OBJECT_N_X_POSITION (12 bits)
+ * 09 0c - TOUCH_OBJECT_N_Y_POSITION (12 bits)
+ * 0a 08 - TOUCH_OBJECT_N_Z (8 bits)
+ * 0b 08 - TOUCH_OBJECT_N_X_WIDTH (8 bits)
+ * 0c 08 - TOUCH_OBJECT_N_Y_WIDTH (8 bits)
+ * 0d 10 - TOUCH_OBJECT_N_TX_POSITION_TIXELS (16 bits) ??
+ * 0e 10 - TOUCH_OBJECT_N_RX_POSITION_TIXELS (16 bits) ??
+ * 03 00 - TOUCH_FOREACH_END (0 bits)
+ * 00 00 - TOUCH_END (0 bits)
+ *
+ * Since we only support this report config, we just hardcode the format below.
+ * To support additional report configs, we would need to parse the config and
+ * use it to parse the reports dynamically.
+ */
+
+struct tcm_default_report_data {
+	u8 fps;
+	struct {
+		u8 unknown;
+		u8 buttons;
+		u8 idx : 4;
+		u8 classification : 4;
+		u16 x : 12;
+		u16 y : 12;
+		u8 z;
+		u8 width_x;
+		u8 width_y;
+		u8 tx;
+		u8 rx;
+	} __packed points[];
+} __packed;
+
+static int tcm_handle_touch_report(struct tcm_data *tcm, char *buf, size_t len)
+{
+	struct tcm_default_report_data *data;
+
+	buf += REPORT_PEAK_LEN;
+	len -= REPORT_PEAK_LEN;
+
+	dev_dbg(&tcm->client->dev, "touch report len %zu\n", len);
+	if ((len - 1) % 11)
+		dev_err(&tcm->client->dev, "invalid touch report length\n");
+
+	data = (struct tcm_default_report_data *)buf;
+
+	/* We don't need to report releases because we have INPUT_MT_DROP_UNUSED */
+	for (int i = 0; i < (len - 1) / 11; i++) {
+		u8 major_width, minor_width;
+
+		minor_width = data->points[i].width_x;
+		major_width = data->points[i].width_y;
+
+		if (minor_width > major_width)
+			swap(major_width, minor_width);
+
+		dev_dbg(&tcm->client->dev, "touch report: idx %u x %u y %u\n",
+			data->points[i].idx, data->points[i].x, data->points[i].y);
+		input_mt_slot(tcm->input, data->points[i].idx);
+		input_mt_report_slot_state(tcm->input, MT_TOOL_FINGER, true);
+
+		input_report_abs(tcm->input, ABS_MT_POSITION_X, data->points[i].x);
+		input_report_abs(tcm->input, ABS_MT_POSITION_Y, data->points[i].y);
+		input_report_abs(tcm->input, ABS_MT_TOUCH_MAJOR, major_width);
+		input_report_abs(tcm->input, ABS_MT_TOUCH_MINOR, minor_width);
+		input_report_abs(tcm->input, ABS_MT_PRESSURE, data->points[i].z);
+	}
+
+	input_mt_sync_frame(tcm->input);
+	input_sync(tcm->input);
+
+	return 0;
+}
+
+static irqreturn_t tcm_report_irq(int irq, void *data)
+{
+	struct tcm_data *tcm = data;
+	struct tcm_message_header *header;
+	char buf[256];
+	u16 len;
+	int ret;
+
+	header = (struct tcm_message_header *)buf;
+	ret = tcm_recv_report(tcm, buf, sizeof(buf));
+	if (ret) {
+		dev_err(&tcm->client->dev, "failed to read report: %d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	switch (header->code) {
+	case REPORT_OK:
+	case REPORT_IDENTIFY:
+	case REPORT_TOUCH:
+	case REPORT_DELTA:
+	case REPORT_RAW:
+	case REPORT_DEBUG:
+	case REPORT_TOUCH_HOLD:
+		break;
+	default:
+		dev_dbg(&tcm->client->dev, "Ignoring report %#x\n", header->code);
+		return IRQ_HANDLED;
+	}
+
+	/* Not present for REPORT_CONTINUED_READ */
+	len = get_unaligned_le16(buf + sizeof(*header));
+
+	dev_dbg(&tcm->client->dev, "report %#x len %u\n", header->code, len);
+	print_hex_dump_bytes("report: ", DUMP_PREFIX_OFFSET, buf,
+			     min(sizeof(buf), len + sizeof(*header)));
+
+	if (len > sizeof(buf) - sizeof(*header)) {
+		dev_err(&tcm->client->dev, "report too long\n");
+		return IRQ_HANDLED;
+	}
+
+	/* Check if this is a read response or an indication. For indications
+	 * (user touched the screen) we just parse the report directly.
+	 */
+	if (completion_done(&tcm->response) && header->code == REPORT_TOUCH) {
+		tcm_handle_touch_report(tcm, buf, len + sizeof(*header));
+		return IRQ_HANDLED;
+	}
+
+	tcm->buf_size = len + sizeof(*header);
+	memcpy(tcm->buf, buf, len + sizeof(*header));
+	complete(&tcm->response);
+
+	return IRQ_HANDLED;
+}
+
+static int tcm_hw_init(struct tcm_data *tcm, u16 *max_x, u16 *max_y)
+{
+	int ret;
+	struct tcm_identification id = { 0 };
+	struct tcm_app_info app_info = { 0 };
+
+	/*
+	 * Tell the firmware to start up. After starting it sends an IDENTIFY report, which
+	 * we treat like a response to this message even though it's technically a new report.
+	 */
+	ret = tcm_read_message(tcm, TCM_RUN_APPLICATION_FIRMWARE, &id, sizeof(id));
+	if (ret) {
+		dev_err(&tcm->client->dev, "failed to identify device: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(&tcm->client->dev, "Synaptics TCM %s v%d mode %d\n",
+		id.part_number, id.version, id.mode);
+	if (id.mode != MODE_APPLICATION) {
+		/* We don't support firmware updates or anything else */
+		dev_err(&tcm->client->dev, "Device is not in application mode\n");
+		return -ENODEV;
+	}
+
+	do {
+		msleep(20);
+		ret = tcm_read_message(tcm, TCM_GET_APPLICATION_INFO, &app_info, sizeof(app_info));
+		if (ret) {
+			dev_err(&tcm->client->dev, "failed to get application info: %d\n", ret);
+			return ret;
+		}
+	} while (app_info.status == APP_STATUS_BOOTING || app_info.status == APP_STATUS_UPDATING);
+
+	dev_dbg(&tcm->client->dev, "Application firmware v%d.%d (customer '%s') status %d\n",
+		 app_info.version[0], app_info.version[1], app_info.customer_config_id,
+		 app_info.status);
+
+	*max_x = app_info.max_x;
+	*max_y = app_info.max_y;
+
+	return 0;
+}
+
+static int tcm_power_on(struct tcm_data *tcm)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(tcm->supplies),
+				    tcm->supplies);
+	if (ret)
+		return ret;
+
+	gpiod_set_value(tcm->reset_gpio, false);
+	usleep_range(10000, 11000);
+	gpiod_set_value(tcm->reset_gpio, true);
+	usleep_range(80000, 81000);
+
+	return 0;
+}
+
+static int tcm_probe(struct i2c_client *client)
+{
+	struct tcm_data *tcm;
+	struct tcm_report_config __maybe_unused report_config;
+	u16 max_x, max_y;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+						I2C_FUNC_SMBUS_BYTE_DATA |
+						I2C_FUNC_SMBUS_I2C_BLOCK))
+		return -ENODEV;
+
+	tcm = devm_kzalloc(&client->dev, sizeof(struct tcm_data), GFP_KERNEL);
+	if (!tcm)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tcm);
+	tcm->client = client;
+
+	init_completion(&tcm->response);
+
+	tcm->supplies[0].supply = "vdd";
+	tcm->supplies[1].supply = "vcc";
+	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(tcm->supplies),
+				      tcm->supplies);
+	if (ret)
+		return ret;
+
+	tcm->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+
+	ret = devm_add_action_or_reset(&client->dev, tcm_power_off,
+				       tcm);
+	if (ret)
+		return ret;
+
+	ret = tcm_power_on(tcm);
+	if (ret)
+		return ret;
+
+	ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+					tcm_report_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					"synaptics_tcm_report", tcm);
+	if (ret < 0)
+		return ret;
+
+	ret = tcm_hw_init(tcm, &max_x, &max_y);
+	if (ret) {
+		dev_err(&client->dev, "failed to initialize hardware\n");
+		return ret;
+	}
+
+	tcm->input = devm_input_allocate_device(&client->dev);
+	if (!tcm->input)
+		return -ENOMEM;
+
+	tcm->input->name = "Synaptics TCM Oncell Touchscreen";
+	tcm->input->id.bustype = BUS_I2C;
+	tcm->input->open = tcm_input_open;
+	tcm->input->close = tcm_input_close;
+
+	input_set_abs_params(tcm->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+	input_set_abs_params(tcm->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
+	input_set_abs_params(tcm->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+	touchscreen_parse_properties(tcm->input, true, &tcm->prop);
+
+	ret = input_mt_init_slots(tcm->input, 10, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (ret)
+		return ret;
+
+	input_set_drvdata(tcm->input, tcm);
+
+	ret = input_register_device(tcm->input);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct of_device_id syna_driver_ids[] = {
+	{
+		.compatible = "syna,s3908",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, syna_driver_ids);
+
+static const struct i2c_device_id syna_i2c_ids[] = {
+	{ "synaptics-tcm", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, syna_i2c_ids);
+
+static struct i2c_driver syna_i2c_driver = {
+	.probe	= tcm_probe,
+	.id_table	= syna_i2c_ids,
+	.driver	= {
+	.name	= "synaptics-tcm",
+	.of_match_table = syna_driver_ids,
+	},
+};
+
+module_i2c_driver(syna_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Frieder Hannenheim <frieder.hannenheim@proton.me>");
+MODULE_AUTHOR("Caleb Connolly <caleb@postmarketos.org>");
+MODULE_DESCRIPTION("A driver for Synaptics TCM Oncell Touchpanels");
+

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab)
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
                   ` (5 preceding siblings ...)
  2024-06-24  1:30 ` [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908 Caleb Connolly
@ 2024-06-24  1:30 ` Caleb Connolly
  2024-06-26  4:16   ` Bjorn Andersson
  2024-06-26  9:43   ` Konrad Dybcio
  2024-06-24  5:18 ` [PATCH 0/7] qcom: initial support for the OnePlus 8T Dmitry Baryshkov
  7 siblings, 2 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:30 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

Initial support for USB, UFS, touchscreen, panel, wifi, and bluetooth.

Co-developed-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
Signed-off-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
---
 arch/arm64/boot/dts/qcom/Makefile                  |   1 +
 .../arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi | 866 +++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts  |  36 +
 3 files changed, 903 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 5576c7d6ea06..14efed297df3 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -231,8 +231,9 @@ dtb-$(CONFIG_ARCH_QCOM)	+= sm8150-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8150-sony-xperia-kumano-bahamut.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8150-sony-xperia-kumano-griffin.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-hdk.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-oneplus-kebab.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-sony-xperia-edo-pdx203.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-sony-xperia-edo-pdx206.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-xiaomi-elish-boe.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8250-xiaomi-elish-csot.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
new file mode 100644
index 000000000000..ea5b46b54183
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
@@ -0,0 +1,866 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (c) 2024, Frieder Hannenheim <frieder.hannenheim@proton.me>
+ * Copyright (c) 2024, Caleb Connolly <caleb@postmarketos.org>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
+#include <dt-bindings/sound/qcom,q6asm.h>
+#include <dt-bindings/usb/pd.h>
+#include "sm8250.dtsi"
+#include "pm8150.dtsi"
+#include "pm8150b.dtsi"
+#include "pm8150l.dtsi"
+
+/* removed_mem @ 0x80b00000 is bigger so we gotta shift everything up... */
+/delete-node/ &removed_mem;
+/delete-node/ &camera_mem;
+/delete-node/ &wlan_mem;
+/delete-node/ &ipa_fw_mem;
+/delete-node/ &ipa_gsi_mem;
+/delete-node/ &gpu_mem;
+/delete-node/ &npu_mem;
+/delete-node/ &video_mem;
+/delete-node/ &cvp_mem;
+/delete-node/ &cdsp_mem;
+/delete-node/ &slpi_mem;
+/delete-node/ &adsp_mem;
+/delete-node/ &spss_mem;
+/delete-node/ &cdsp_secure_heap;
+
+
+/ {
+	aliases {
+		serial0 = &uart12;
+		serial1 = &uart6;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0:115200n8";
+
+		framebuffer: framebuffer@9c000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0x9c000000 0 0x2300000>;
+			width = <1080>;
+			height = <2400>;
+			stride = <(1080 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+
+		key-vol-up {
+			label = "Volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>;
+		};
+
+		key-vol-dowm {
+			label = "Volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&pm8150_gpios 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	reserved-memory {
+		camera_mem: camera@8dc00000 {
+			reg = <0x0 0x8dc00000 0x0 0x500000>;
+			no-map;
+		};
+
+		wlan_mem: wlan@8e100000 {
+			reg = <0x0 0x8e100000 0x0 0x100000>;
+			no-map;
+		};
+
+		ipa_fw_mem: ipa-fw@8e200000 {
+			reg = <0x0 0x8e200000 0x0 0x10000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi@8e210000 {
+			reg = <0x0 0x8e210000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_mem: gpu@8e21a000 {
+			reg = <0x0 0x8e21a000 0x0 0x2000>;
+			no-map;
+		};
+
+		npu_mem: memory@8e300000 {
+			reg = <0x0 0x8e300000 0x0 0x500000>;
+			no-map;
+		};
+
+		video_mem: video@8e800000 {
+			reg = <0x0 0x8e800000 0x0 0x500000>;
+			no-map;
+		};
+
+		cvp_mem: cvp@8ed00000 {
+			reg = <0x0 0x8ed00000 0x0 0x500000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp@8f200000 {
+			reg = <0x0 0x8f200000 0x0 0x1400000>;
+			no-map;
+		};
+
+		slpi_mem: slpi@90600000 {
+			reg = <0x0 0x90600000 0x0 0x1500000>;
+			no-map;
+		};
+
+		adsp_mem: adsp@91b00000 {
+			reg = <0x00 0x91b00000 0x00 0x2500000>;
+			no-map;
+		};
+
+		spss_mem: spss@94000000 {
+			reg = <0x0 0x94000000 0x0 0x100000>;
+			no-map;
+		};
+
+		cdsp_secure_heap: cdsp-secure@94100000 {
+			reg = <0x0 0x94100000 0x0 0x4600000>;
+			no-map;
+		};
+
+		framebuffer@9c000000 {
+			reg = <0 0x9c000000 0 0x2300000>;
+			no-map;
+		};
+	};
+
+	vph_pwr: vph-pwr-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vph_pwr";
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
+		regulator-always-on;
+	};
+
+	vreg_s4a_1p8: vreg-s4a-1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_s4a_1p8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	panel_avdd_5p5: panel-avdd-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "panel_avdd_5p5";
+		regulator-min-microvolt = <5500000>;
+		regulator-max-microvolt = <5500000>;
+		regulator-enable-ramp-delay = <233>;
+		gpio = <&tlmm 61 GPIO_ACTIVE_HIGH>;
+		regulator-boot-on;
+		/* FIXME: we don't yet support power cycling the panel so keep this on */
+		regulator-always-on;
+		pinctrl-names = "default";
+		pinctrl-0 = <&panel_avdd_pins>;
+	};
+
+	qca6390-pmu {
+		compatible = "qcom,qca6390-pmu";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en_state>, <&wlan_en_state>;
+
+		vddaon-supply = <&vreg_s6a_0p95>;
+		vddpmu-supply = <&vreg_s6a_0p95>;
+		vddrfa0p95-supply = <&vreg_s6a_0p95>;
+		vddrfa1p3-supply = <&vreg_s8c_1p3>;
+		vddrfa1p9-supply = <&vreg_s5a_1p9>;
+		vddpcie1p3-supply = <&vreg_s8c_1p3>;
+		vddpcie1p9-supply = <&vreg_s5a_1p9>;
+		vddio-supply = <&vreg_s4a_1p8>;
+
+		wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+		bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			vreg_pmu_rfa_cmn: ldo0 {
+				regulator-name = "vreg_pmu_rfa_cmn";
+			};
+
+			vreg_pmu_aon_0p59: ldo1 {
+				regulator-name = "vreg_pmu_aon_0p59";
+			};
+
+			vreg_pmu_wlcx_0p8: ldo2 {
+				regulator-name = "vreg_pmu_wlcx_0p8";
+			};
+
+			vreg_pmu_wlmx_0p85: ldo3 {
+				regulator-name = "vreg_pmu_wlmx_0p85";
+			};
+
+			vreg_pmu_btcmx_0p85: ldo4 {
+				regulator-name = "vreg_pmu_btcmx_0p85";
+			};
+
+			vreg_pmu_rfa_0p8: ldo5 {
+				regulator-name = "vreg_pmu_rfa_0p8";
+			};
+
+			vreg_pmu_rfa_1p2: ldo6 {
+				regulator-name = "vreg_pmu_rfa_1p2";
+			};
+
+			vreg_pmu_rfa_1p7: ldo7 {
+				regulator-name = "vreg_pmu_rfa_1p7";
+			};
+
+			vreg_pmu_pcie_0p9: ldo8 {
+				regulator-name = "vreg_pmu_pcie_0p9";
+			};
+
+			vreg_pmu_pcie_1p8: ldo9 {
+				regulator-name = "vreg_pmu_pcie_1p8";
+			};
+		};
+	};
+};
+
+&adsp {
+	status = "okay";
+	firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8150-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s6-supply = <&vph_pwr>;
+		vdd-s7-supply = <&vph_pwr>;
+		vdd-s8-supply = <&vph_pwr>;
+		vdd-s9-supply = <&vph_pwr>;
+		vdd-s10-supply = <&vph_pwr>;
+		vdd-l2-l10-supply = <&vreg_bob>;
+		vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>;
+		vdd-l6-l9-supply = <&vreg_s8c_1p3>;
+		vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>;
+		vdd-l13-l16-l17-supply = <&vreg_bob>;
+
+		vreg_l2a_3p1: ldo2 {
+			regulator-name = "vreg_l2a_3p1";
+			regulator-min-microvolt = <3072000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a_0p9: ldo3 {
+			regulator-name = "vreg_l3a_0p9";
+			regulator-min-microvolt = <928000>;
+			regulator-max-microvolt = <932000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		/* l4 = VDD_SSC_MX (lmx.lvl) */
+
+		vreg_l5a_0p88: ldo5 {
+			regulator-name = "vreg_l5a_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <880000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a_1p2: ldo6 {
+			regulator-name = "vreg_l6a_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a_1p7: ldo7 {
+			regulator-name = "vreg_l7a_1p7";
+			regulator-min-microvolt = <1704000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a_1p2: ldo9 {
+			regulator-name = "vreg_l9a_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10a_1p8: ldo10 {
+			regulator-name = "vreg_l10a_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		/* l11 = VDD_SSC_CX (lxc.lvl) */
+
+		vreg_l12a_1p8: ldo12 {
+			regulator-name = "vreg_l12a_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13a_ts_3p0: ldo13 {
+			regulator-name = "vreg_l13a_ts_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14a_1p8: ldo14 {
+			regulator-name = "vreg_l14a_1p8";
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <1880000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15a_1p8: ldo15 {
+			regulator-name = "vreg_l15a_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		/* Fingerprint reader power (goodix_fp) */
+		vreg_l16a_2p7: ldo16 {
+			regulator-name = "vreg_l16a_2p7";
+			regulator-min-microvolt = <3024000>;
+			regulator-max-microvolt = <3304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17a_3p0: ldo17 {
+			regulator-name = "vreg_l17a_3p0";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l18a_0p92: ldo18 {
+			regulator-name = "vreg_l18a_0p92";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5a_1p9: smps5 {
+			regulator-name = "vreg_s5a_1p9";
+			regulator-min-microvolt = <1904000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6a_0p95: smps6 {
+			regulator-name = "vreg_s6a_0p95";
+			regulator-min-microvolt = <920000>;
+			regulator-max-microvolt = <1128000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8150l-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s6-supply = <&vph_pwr>;
+		vdd-s7-supply = <&vph_pwr>;
+		vdd-s8-supply = <&vph_pwr>;
+		vdd-l1-l8-supply = <&vreg_s4a_1p8>;
+		vdd-l2-l3-supply = <&vreg_s8c_1p3>;
+		vdd-l4-l5-l6-supply = <&vreg_bob>;
+		vdd-l7-l11-supply = <&vreg_bob>;
+		vdd-l9-l10-supply = <&vreg_bob>;
+		vdd-bob-supply = <&vph_pwr>;
+
+		vreg_bob: bob {
+			regulator-name = "vreg_bob";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <4000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+		};
+
+		vreg_l1c_1p8: ldo1 {
+			regulator-name = "vreg_l1c_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c_1p2: ldo2 {
+			regulator-name = "vreg_l2c_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c_0p8: ldo3 {
+			regulator-name = "vreg_l3c_0p8";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c_1p7: ldo4 {
+			regulator-name = "vreg_l4c_1p7";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5c_1p8: ldo5 {
+			regulator-name = "vreg_l5c_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c_2p96: ldo6 {
+			regulator-name = "vreg_l6c_2p96";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c_cam_vcm0_2p85: ldo7 {
+			regulator-name = "vreg_l7c_cam_vcm0_2p85";
+			regulator-min-microvolt = <2856000>;
+			regulator-max-microvolt = <3104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c_1p8: ldo8 {
+			regulator-name = "vreg_l8c_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c_2p96: ldo9 {
+			regulator-name = "vreg_l9c_2p96";
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10c_3p0: ldo10 {
+			regulator-name = "vreg_l10c_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11c_3p3: ldo11 {
+			regulator-name = "vreg_l11c_3p3";
+			regulator-min-microvolt = <2900000>;
+			regulator-max-microvolt = <3304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-boot-on;
+			/* FIXME: we don't yet support power cycling the panel */
+			regulator-always-on;
+		};
+
+		vreg_s8c_1p3: smps8 {
+			regulator-name = "vreg_s8c_1p3";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&cdsp {
+	status = "okay";
+	firmware-name = "qcom/sm8250/OnePlus/cdsp.mbn";
+};
+
+&crypto {
+	status = "disabled";
+};
+
+&gmu {
+	status = "okay";
+};
+
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		memory-region = <&gpu_mem>;
+		firmware-name = "qcom/sm8250/OnePlus/a650_zap.mbn";
+	};
+};
+
+/* LS-I2C1 */
+&i2c15 {
+	status = "okay";
+
+	// fcs,fsa4480 @ 42
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi0 {
+	status = "okay";
+	vdda-supply = <&vreg_l9a_1p2>;
+
+	display_panel: panel@0 {
+		reg = <0>;
+		vddio-supply = <&vreg_l14a_1p8>;
+		vdd-supply = <&vreg_l11c_3p3>;
+		avdd-supply = <&panel_avdd_5p5>;
+		/* FIXME: There is a bug somewhere in the display stack and it isn't
+		 * possible to get the panel to a working state after toggling reset.
+		 * At best it just shows one or more vertical red lines. So for now
+		 * let's skip the reset GPIO.
+		 */
+		// reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
+
+		pinctrl-0 = <&panel_reset_pins &panel_vsync_pins &panel_vout_pins>;
+		pinctrl-names = "default";
+
+		status = "disabled";
+
+		port {
+			panel_in_0: endpoint {
+				remote-endpoint = <&mdss_dsi0_out>;
+			};
+		};
+	};
+
+};
+
+&mdss_dsi0_out {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&panel_in_0>;
+};
+
+&mdss_dsi0_phy {
+	vdds-supply = <&vreg_l5a_0p88>;
+	status = "okay";
+};
+
+&pm8150_adc {
+	channel@4c {
+		reg = <ADC5_XO_THERM_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "xo_therm";
+	};
+
+	channel@4d {
+		reg = <ADC5_AMUX_THM2_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "skin_therm";
+	};
+
+	channel@4e {
+		reg = <ADC5_AMUX_THM2_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "wifi_therm";
+	};
+};
+
+&pm8150_adc_tm {
+	status = "okay";
+
+	xo-therm@0 {
+		reg = <0>;
+		io-channels = <&pm8150_adc ADC5_XO_THERM_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	skin-therm@1 {
+		reg = <1>;
+		io-channels = <&pm8150_adc ADC5_XO_THERM_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	wifi-therm@2 {
+		reg = <2>;
+		io-channels = <&pm8150_adc ADC5_AMUX_THM2_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+};
+
+&pcie0 {
+	status = "okay";
+};
+
+&pcie0_phy {
+	status = "okay";
+
+	vdda-phy-supply = <&vreg_l5a_0p88>;
+	vdda-pll-supply = <&vreg_l9a_1p2>;
+};
+
+&pcieport0 {
+	wifi@0 {
+		compatible = "pci17cb,1101";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+		vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+		vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+		vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+	};
+};
+
+&pcie2 {
+	status = "okay";
+};
+
+&pcie2_phy {
+	status = "okay";
+	vdda-phy-supply = <&vreg_l5a_0p88>;
+	vdda-pll-supply = <&vreg_l9a_1p2>;
+};
+
+&pm8150_gpios {
+	gpio-reserved-ranges = <2 1>, <4 1>, <8 1>;
+};
+
+&pm8150b_adc {
+	channel@4f {
+		reg = <ADC5_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "conn_therm";
+	};
+};
+
+&pm8150b_adc_tm {
+	status = "okay";
+
+	conn-therm@0 {
+		reg = <0>;
+		io-channels = <&pm8150b_adc ADC5_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+};
+
+&pm8150l_adc {
+	channel@4e {
+		reg = <ADC5_AMUX_THM2_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "skin_msm_therm";
+	};
+
+	channel@4f {
+		reg = <ADC5_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		label = "pm8150l_therm";
+	};
+};
+
+&pm8150l_adc_tm {
+	status = "okay";
+
+	skin-msm-therm@0 {
+		reg = <0>;
+		io-channels = <&pm8150l_adc ADC5_AMUX_THM2_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	pm8150l-therm@1 {
+		reg = <1>;
+		io-channels = <&pm8150l_adc ADC5_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	status = "okay";
+
+	linux,code = <KEY_VOLUMEDOWN>;
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&qupv3_id_2 {
+	status = "okay";
+};
+
+&tlmm {
+	gpio-reserved-ranges = <28 4>, <40 4>;
+
+	bt_en_state: bt-default-state {
+		pins = "gpio21";
+		function = "gpio";
+		drive-strength = <16>;
+		output-low;
+		bias-pull-up;
+	};
+
+	wlan_en_state: wlan-default-state {
+		wlan-en-pins {
+			pins = "gpio20";
+			function = "gpio";
+
+			drive-strength = <16>;
+			output-low;
+			bias-pull-up;
+		};
+	};
+
+	panel_reset_pins: panel-reset-state {
+		pins = "gpio75";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	panel_vsync_pins: panel-vsync-state {
+		pins = "gpio66";
+		function = "mdp_vsync";
+		drive-strength = <16>;
+		bias-pull-down;
+	};
+
+	panel_vout_pins: panel-vout-state {
+		pins = "gpio24";
+		function = "gpio";
+		drive-strength = <16>;
+		output-high;
+	};
+
+	panel_avdd_pins: panel-avdd-state {
+		pins = "gpio65";
+		function = "gpio";
+		drive-strength = <8>;
+		output-high;
+	};
+
+	touch_irq_active: touch-irq-state {
+		pins = "gpio39";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+		output-disable;
+	};
+
+	touch_rst_active: touch-rst-state {
+		pins = "gpio38";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+	};
+};
+
+&uart6 {
+	status = "okay";
+
+	bluetooth {
+		compatible = "qcom,qca6390-bt";
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+	};
+};
+
+&uart12 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	status = "okay";
+
+	vcc-supply = <&vreg_l17a_3p0>;
+	vcc-max-microamp = <800000>;
+	vccq-supply = <&vreg_l6a_1p2>;
+	vccq-max-microamp = <800000>;
+	vccq2-supply = <&vreg_s4a_1p8>;
+	vccq2-max-microamp = <800000>;
+};
+
+&ufs_mem_phy {
+	status = "okay";
+
+	vdda-phy-supply = <&vreg_l5a_0p88>;
+	vdda-pll-supply = <&vreg_l9a_1p2>;
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+	status = "okay";
+
+	vdda-pll-supply = <&vreg_l5a_0p88>;
+	vdda33-supply = <&vreg_l2a_3p1>;
+	vdda18-supply = <&vreg_l12a_1p8>;
+};
+
+&usb_1_qmpphy {
+	status = "okay";
+
+	vdda-phy-supply = <&vreg_l9a_1p2>;
+	vdda-pll-supply = <&vreg_l18a_0p92>;
+};
+
+&venus {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
new file mode 100644
index 000000000000..642c19321e03
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (c) 2024, Caleb Connolly <caleb.connolly@linaro.org>
+ */
+
+#include "sm8250-oneplus-common.dtsi"
+
+/ {
+	model = "OnePlus 8T";
+	compatible = "oneplus,kebab", "qcom,sm8250";
+};
+
+&i2c13 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	touchscreen@4b {
+		compatible = "syna,s3908";
+		reg = <0x4B>;
+
+		pinctrl-0 = <&touch_irq_active &touch_rst_active>;
+		pinctrl-names = "default";
+
+		interrupts-extended = <&tlmm 39 0x2008>;
+
+		reset-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+
+		vdd-supply = <&vreg_l13a_ts_3p0>;
+		vcc-supply = <&vreg_l1c_1p8>;
+	};
+};
+
+&display_panel {
+	compatible = "samsung,amb655x";
+	status = "okay";
+};

-- 
2.45.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X
  2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
@ 2024-06-24  1:33   ` Caleb Connolly
  2024-06-27 22:12   ` Rob Herring
  1 sibling, 0 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24  1:33 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming



On 24/06/2024 03:30, Caleb Connolly wrote:
> Describe the Samsung AMB655X panel. It has three supplies.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>   .../bindings/display/panel/samsung,amb655x.yaml    | 59 ++++++++++++++++++++++
>   1 file changed, 59 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
> new file mode 100644
> index 000000000000..eb987d022a0d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
> @@ -0,0 +1,59 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/samsung,amb655x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung AMB655X 1080x2400 120hz AMOLED panel
> +
> +maintainers:
> +  - Caleb Connolly <caleb@postmarketos.org>
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +    const: samsung,amb655x
> +
> +  reg:
> +    maxItems: 1
> +
> +  reset-gpios:
> +    description: reset gpio, must be GPIO_ACTIVE_LOW
> +  vddio-supply: true
> +  vdd-supply: true
> +  avdd-supply: true
> +  enable-gpios: true
> +  port: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - vdd-supply
> +  - avdd-supply
> +  - vddio-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        panel@0 {
> +            compatible = "samsung,ams495qa01";

I clearly need a comb with finer teeth... Will fix this example for v2.
> +            reg = <0>;
> +            reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
> +            vdd-supply = <&vcc_3v3>;
> +
> +            port {
> +                mipi_in_panel: endpoint {
> +                  remote-endpoint = <&mipi_out_panel>;
> +                };
> +            };
> +        };
> +    };
> +
> +...
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell
  2024-06-24  1:30 ` [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell Caleb Connolly
@ 2024-06-24  2:42   ` Rob Herring (Arm)
  2024-06-24  7:25   ` Dmitry Torokhov
  1 sibling, 0 replies; 25+ messages in thread
From: Rob Herring (Arm) @ 2024-06-24  2:42 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: devicetree, Henrik Rydberg, Maarten Lankhorst, dri-devel,
	linux-arm-msm, David Airlie, Dmitry Torokhov, Thomas Zimmermann,
	Daniel Vetter, Maxime Ripard, Bjorn Andersson, linux-input,
	~postmarketos/upstreaming, Krzysztof Kozlowski, Konrad Dybcio,
	Jessica Zhang, Conor Dooley, Neil Armstrong


On Mon, 24 Jun 2024 03:30:26 +0200, Caleb Connolly wrote:
> Document the Synaptics TCM oncell series of touchscreens, starting with
> the s3908.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  .../input/touchscreen/syna,tcm-oncell.yaml         | 66 ++++++++++++++++++++++
>  1 file changed, 66 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml: $id: Cannot determine base path from $id, relative path/filename doesn't match actual path or filename
 	 $id: http://devicetree.org/schemas/input/touchscreen/syna,s3908.yaml
 	file: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dts:27.13-26: Warning (reg_format): /example-0/i2c/touchscreen@4b:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (simple_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dts:21.13-36.11: Warning (i2c_bus_bridge): /example-0/i2c: incorrect #address-cells for I2C bus
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dts:21.13-36.11: Warning (i2c_bus_bridge): /example-0/i2c: incorrect #size-cells for I2C bus
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (i2c_bus_reg): Failed prerequisite 'i2c_bus_bridge'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dts:25.26-35.13: Warning (avoid_default_addr_size): /example-0/i2c/touchscreen@4b: Relying on default #address-cells value
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dts:25.26-35.13: Warning (avoid_default_addr_size): /example-0/i2c/touchscreen@4b: Relying on default #size-cells value
Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.example.dtb: Warning (unique_unit_address_if_enabled): Failed prerequisite 'avoid_default_addr_size'

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240624-oneplus8-v1-2-388eecf2dff7@postmarketos.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series
  2024-06-24  1:30 ` [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series Caleb Connolly
@ 2024-06-24  4:52   ` Krzysztof Kozlowski
  2024-06-24 20:40   ` Rob Herring
  1 sibling, 0 replies; 25+ messages in thread
From: Krzysztof Kozlowski @ 2024-06-24  4:52 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Konrad Dybcio, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

On 24/06/2024 03:30, Caleb Connolly wrote:
> Add bindings for the OnePlus 8, 8 Pro, and 8T devices.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/7] qcom: initial support for the OnePlus 8T
  2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
                   ` (6 preceding siblings ...)
  2024-06-24  1:30 ` [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab) Caleb Connolly
@ 2024-06-24  5:18 ` Dmitry Baryshkov
  2024-06-24 11:32   ` Caleb Connolly
  7 siblings, 1 reply; 25+ messages in thread
From: Dmitry Baryshkov @ 2024-06-24  5:18 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming,
	Frieder Hannenheim

On Mon, Jun 24, 2024 at 03:30:24AM GMT, Caleb Connolly wrote:
> Add bindings for the SM8250 OnePlus devices, a common devicetree,
> touchscreen and display drivers, and a dts for the OnePlus 8T (kebab).
> 
> The OnePlus 8 series is made up of 3 flagship smartphones from 2019,
> featuring the Qualcomm X55 5G PCIe modem.
> 
> This series introduces initial support for the 8T, adding drivers for
> the 1080x2400 120Hz DSC panel and the Synaptics TCM Oncell touchscreen.
> 
> The panel driver suffers from similar limitations to the LG SW43408
> panel found on the Pixel 3, namely that after toggling the reset GPIO it
> is not possible to get the panel into a working state.

Just to point it out: this is no longer true for SW43408. The panel
wakes up and works after toggling the reset. It seems, there is an issue
with one of the regulators, but not with the reset and/or panel startup.

> Given the apparent prevelance of this issue, particularly with DSC
> panels, I believe this is a bug in the core DSI code, and not a device
> or panel specific issue. I think it is still useful to accept these
> panel drivers into upstream since, from a users perspective, the panel
> is fully functional just by leaving the reset GPIO alone and keeping the
> regulator on. The only (theoretical) downside is worse battery life,
> which is a small price to pay for a working display.
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type()
  2024-06-24  1:30 ` [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type() Caleb Connolly
@ 2024-06-24  5:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 25+ messages in thread
From: Dmitry Baryshkov @ 2024-06-24  5:21 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming

On Mon, Jun 24, 2024 at 03:30:28AM GMT, Caleb Connolly wrote:
> Some panels like the Samsung AMB655X use long write commands for all
> non-standard messages and do not work when trying to use the appropriate
> command type.
> 
> Support these panels by introducing a new helper to send commands of a
> specific type, overriding the normal rules.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dsi.h     | 16 ++++++++++++++++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index a471c46f5ca6..d0fee0498d91 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -819,8 +819,48 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
>  	}
>  }
>  EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
>  
> +/**
> + * mipi_dsi_generic_write_type() - transmit data using a generic write packet of

This doesn't match the name of the function.

> + * a specific type
> + * @dsi: DSI peripheral device
> + * @type: data type of the packet
> + * @payload: buffer containing the payload
> + * @size: size of payload buffer
> + *
> + * This function will automatically choose the right data type depending on
> + * the payload length.
> + *
> + * Return: The number of bytes transmitted on success or a negative error code
> + * on failure.
> + */
> +ssize_t mipi_dsi_generic_write_multi_type(struct mipi_dsi_multi_context *ctx,
> +					  u8 type, const void *payload, size_t size)

write_type_multi. Or maybe write_raw_multi.

> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct mipi_dsi_msg msg = {
> +		.channel = dsi->channel,
> +		.tx_buf = payload,
> +		.tx_len = size,
> +		.type = type,
> +	};
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return 0;
> +
> +	ret = mipi_dsi_device_transfer(dsi, &msg);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(&dsi->dev, "sending generic data %*ph failed: %zd\n",
> +			(int)size, payload, ret);
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(mipi_dsi_generic_write_multi_type);
> +
>  /**
>   * mipi_dsi_generic_read() - receive data using a generic read packet
>   * @dsi: DSI peripheral device
>   * @params: buffer containing the request parameters
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 71d121aeef24..a5d949e695d4 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -287,8 +287,10 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
>  int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
>  				  const void *payload, size_t size);
>  void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
>  				  const void *payload, size_t size);
> +ssize_t mipi_dsi_generic_write_multi_type(struct mipi_dsi_multi_context *ctx, u8 type,
> +				    const void *payload, size_t size);
>  ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>  			      size_t num_params, void *data, size_t size);
>  
>  #define mipi_dsi_msleep(ctx, delay)	\
> @@ -432,8 +434,22 @@ void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
>  		static const u8 d[] = { cmd, seq };                     \
>  		mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
>  	} while (0)
>  
> +/**
> + * mipi_dsi_dcs_write_long - transmit a DCS long command with payload
> + * @dsi: DSI peripheral device
> + * @cmd: Commands
> + * @seq: buffer containing data to be transmitted
> + */
> +#define mipi_dsi_dcs_write_long(ctx, cmd, seq...)                          \

foo_multi

> +	do {                                                               \
> +		static const u8 d[] = { cmd, seq };                        \
> +		mipi_dsi_generic_write_multi_type(ctx,                     \
> +						  MIPI_DSI_DCS_LONG_WRITE, \
> +						  d, ARRAY_SIZE(d));       \
> +	} while (0)
> +
>  /**
>   * struct mipi_dsi_driver - DSI driver
>   * @driver: device driver model driver
>   * @probe: callback for device binding
> 
> -- 
> 2.45.0
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 5/7] drm/panel: add driver for samsung amb655x
  2024-06-24  1:30 ` [PATCH 5/7] drm/panel: add driver for samsung amb655x Caleb Connolly
@ 2024-06-24  5:31   ` Dmitry Baryshkov
  0 siblings, 0 replies; 25+ messages in thread
From: Dmitry Baryshkov @ 2024-06-24  5:31 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming

On Mon, Jun 24, 2024 at 03:30:29AM GMT, Caleb Connolly wrote:
> This is a 1080x2400 120hz panel used on the OnePlus 8T. It uses DSC but
> uses non-standard DCS commands.

Please add a note regarding the panel using long packets for all the
commands.

Also the cover letter had a mention of the panel not fully comming up
after being reset, is that still true? If so, it should be mentioned in
the commit message too.

> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  MAINTAINERS                                   |   7 +
>  drivers/gpu/drm/panel/Kconfig                 |   9 +
>  drivers/gpu/drm/panel/Makefile                |   1 +
>  drivers/gpu/drm/panel/panel-samsung-amb655x.c | 420 ++++++++++++++++++++++++++
>  4 files changed, 437 insertions(+)



> +static int samsung_amb655x_on(struct samsung_amb655x *amb655x)
> +{
> +	struct drm_dsc_picture_parameter_set pps;
> +	struct mipi_dsi_device *dsi = amb655x->dsi;
> +	struct mipi_dsi_multi_context ctx = { .dsi = dsi };
> +	struct device *dev = &dsi->dev;
> +	int ret;
> +
> +	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> +
> +	drm_dsc_pps_payload_pack(&pps, &amb655x->dsc);
> +
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
> +	mipi_dsi_dcs_write_buffer_multi(&ctx, &pps, sizeof(pps));
> +	mipi_dsi_dcs_write_long(&ctx, 0x9d, 0x01);
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
> +
> +	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);

_multi. Shouldn't it be a long package too?

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
> +		return ret;
> +	}
> +	usleep_range(11000, 12000);

mipi_dsi_msleep() or add mipi_dsi_usleep_range().

> +	ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000, 1080 - 1);

_multi, adding the function as required

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set column address: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = mipi_dsi_dcs_set_page_address(dsi, 0x0000, 2400 - 1);

_multi

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set page address: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* FD Setting */
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
> +	mipi_dsi_dcs_write_long(&ctx, 0xd5, 0x8d);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x0a);
> +	mipi_dsi_dcs_write_long(&ctx, 0xd5, 0x05);
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
> +
> +	/* FFC Function */
> +	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0x5a, 0x5a);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x01);
> +	mipi_dsi_dcs_write_long(&ctx, 0xe4, 0xa6, 0x75, 0xa3);
> +	mipi_dsi_dcs_write_long(&ctx, 0xe9,
> +			       0x11, 0x75, 0xa6, 0x75, 0xa3, 0x4b, 0x17, 0xac,
> +			       0x4b, 0x17, 0xac, 0x00, 0x19, 0x19);
> +	mipi_dsi_dcs_write_long(&ctx, 0xfc, 0xa5, 0xa5);
> +	msleep(61);

mipi_dsi_msleep

> +
> +	/* Dimming Setting */
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x06);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x01);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x05);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x13);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb0, 0x01);
> +	mipi_dsi_dcs_write_long(&ctx, 0xb7, 0x4c);
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
> +
> +	mipi_dsi_dcs_write_long(&ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
> +
> +	/* refresh rate Transition */
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
> +	/* 60 Hz */
> +	//mipi_dsi_dcs_write_long(&ctx, 0x60, 0x00);
> +	/* 120 Hz */
> +	mipi_dsi_dcs_write_long(&ctx, 0x60, 0x10);
> +
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
> +
> +	/* ACL Mode */
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0x5a, 0x5a);
> +	mipi_dsi_dcs_write_long(&ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
> +	mipi_dsi_dcs_write_long(&ctx, 0xf0, 0xa5, 0xa5);
> +	mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);

_multi

> +	msleep(110);

mipi_dsi_msleep()

> +
> +	/* Enable backlight */
> +	mipi_dsi_dcs_write_long(&ctx, 0x9F, 0x5A, 0x5A);
> +	mipi_dsi_dcs_set_display_on(dsi);

_multi

> +	mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_ENTER_NORMAL_MODE);

_multi

> +	mipi_dsi_dcs_write_long(&ctx, 0x9F, 0xA5, 0xA5);
> +
> +	return ctx.accum_err;
> +}
> +
> +static int samsung_amb655x_off(struct samsung_amb655x *amb655x)
> +{
> +	struct mipi_dsi_device *dsi = amb655x->dsi;
> +	struct mipi_dsi_multi_context ctx = { .dsi = dsi };
> +	struct device *dev = &dsi->dev;
> +	int ret;
> +
> +	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> +
> +	mipi_dsi_dcs_write_long(&ctx, 0x9f, 0x5a, 0x5a);
> +
> +	ret = mipi_dsi_dcs_set_display_on(dsi);

_multi

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set display on: %d\n", ret);
> +		return ret;
> +	}
> +	msleep(20);

mipi_dsi_msleep

> +
> +	ret = mipi_dsi_dcs_set_display_off(dsi);

_multi

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set display off: %d\n", ret);
> +		return ret;
> +	}
> +	msleep(20);

mipi_dsi_msleep
> +
> +	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);

_multi

> +	if (ret < 0) {
> +		dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
> +		return ret;
> +	}
> +
> +	mipi_dsi_dcs_write_long(&ctx, 0x9f, 0xa5, 0xa5);
> +	msleep(150);
> +
> +	return ctx.accum_err;
> +}
> +

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell
  2024-06-24  1:30 ` [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell Caleb Connolly
  2024-06-24  2:42   ` Rob Herring (Arm)
@ 2024-06-24  7:25   ` Dmitry Torokhov
  1 sibling, 0 replies; 25+ messages in thread
From: Dmitry Torokhov @ 2024-06-24  7:25 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Henrik Rydberg, dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming

Hi Caleb,

On Mon, Jun 24, 2024 at 03:30:26AM +0200, Caleb Connolly wrote:
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    i2c {
> +      clock-frequency = <400000>;
> +      status = "okay";
> +
> +      touchscreen@4b {
> +        compatible = "syna,s3908";
> +        reg = <0x4B>;
> +
> +        interrupts-extended = <&tlmm 39 0x2008>;
> +
> +        reset-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;

This shows wrong default polarity. It should be GPIO_ACTIVE_LOW.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908
  2024-06-24  1:30 ` [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908 Caleb Connolly
@ 2024-06-24  7:42   ` Dmitry Torokhov
  2024-06-27 23:35     ` Caleb Connolly
  0 siblings, 1 reply; 25+ messages in thread
From: Dmitry Torokhov @ 2024-06-24  7:42 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Henrik Rydberg, dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

Hi Caleb,

On Mon, Jun 24, 2024 at 03:30:30AM +0200, Caleb Connolly wrote:
> The TCM oncell is the next generation of Synaptics touchscreen ICs.
> These run a very featured firmware with a reasonably well defined API.
> It is however entirely incompatible with the existing RMI4 interface.
> 
> Unfortunately, no public datasheet for the interface seems to be
> available, instead this driver was created through a combination of
> vendor drivers and trial and error.
> 
> The firmware interface implies support for defining the exact bit
> encoding of the touch reports, however on the S3908 chip + firmware
> found in the OnePlus 8t the TCM_SET_TOUCH_REPORT_CONFIG command appears
> to be unsupported.
> 
> Co-developed-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
> Signed-off-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  MAINTAINERS                                      |   7 +
>  drivers/input/touchscreen/Kconfig                |  11 +
>  drivers/input/touchscreen/Makefile               |   1 +
>  drivers/input/touchscreen/synaptics_tcm_oncell.c | 617 +++++++++++++++++++++++
>  4 files changed, 636 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2b9cfbf92d7a..db589c841d8c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21826,8 +21826,15 @@ M:	Icenowy Zheng <icenowy@aosc.io>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/regulator/silergy,sy8106a.yaml
>  F:	drivers/regulator/sy8106a-regulator.c
>  
> +SYNAPTICS TCM ONCELL TOUCHSCREEN DRIVER
> +M:	Caleb Connolly <caleb@postmarketos.org>
> +L:	linux-input@vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
> +F:	drivers/input/touchscreen/synaptics_tcm_oncell.c
> +
>  SYNC FILE FRAMEWORK
>  M:	Sumit Semwal <sumit.semwal@linaro.org>
>  R:	Gustavo Padovan <gustavo@padovan.org>
>  L:	linux-media@vger.kernel.org
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index c821fe3ee794..43c4fd80601c 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -531,8 +531,19 @@ config TOUCHSCREEN_S6SY761
>  
>  	  To compile this driver as module, choose M here: the
>  	  module will be called s6sy761.
>  
> +config TOUCHSCREEN_SYNAPTICS_TCM_ONCELL
> +	tristate "Synaptics TCM Oncell Touchscreen driver"
> +	depends on I2C
> +	help
> +	  Say Y if you have the Synaptics S3908 TCM Oncell
> +
> +	  If unsure, say N
> +
> +	  To compile this driver as module, choose M here: the
> +	  module will be called synaptics_tcm_oncell.
> +
>  config TOUCHSCREEN_GUNZE
>  	tristate "Gunze AHL-51S touchscreen"
>  	select SERIO
>  	help
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index a81cb5aa21a5..6a2b85050c3a 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -88,8 +88,9 @@ obj-$(CONFIG_TOUCHSCREEN_STMFTS)	+= stmfts.o
>  obj-$(CONFIG_TOUCHSCREEN_STMPE)		+= stmpe-ts.o
>  obj-$(CONFIG_TOUCHSCREEN_SUN4I)		+= sun4i-ts.o
>  obj-$(CONFIG_TOUCHSCREEN_SUR40)		+= sur40.o
>  obj-$(CONFIG_TOUCHSCREEN_SURFACE3_SPI)	+= surface3_spi.o
> +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_ONCELL)	+= synaptics_tcm_oncell.o
>  obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)	+= ti_am335x_tsc.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
>  obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
> diff --git a/drivers/input/touchscreen/synaptics_tcm_oncell.c b/drivers/input/touchscreen/synaptics_tcm_oncell.c
> new file mode 100644
> index 000000000000..c1ba9a3a93c0
> --- /dev/null
> +++ b/drivers/input/touchscreen/synaptics_tcm_oncell.c
> @@ -0,0 +1,617 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *  Driver for Synaptics TCM Oncell Touchscreens
> + *
> + *  Copyright (c) 2024 Frieder Hannenheim <frieder.hannenheim@proton.me>
> + *  Copyright (c) 2024 Caleb Connolly <caleb@postmarketos.org>
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/property.h>
> +#include <asm/unaligned.h>
> +#include <linux/delay.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/of_gpio.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +/*
> + * The TCM oncell interface uses a command byte, which may be followed by additional
> + * data. The packet format is defined in the tcm_cmd struct.
> + *
> + * The following list only defines commands that are used in this driver (and their
> + * counterparts for context). Vendor reference implementations can be found at
> + * https://github.com/LineageOS/android_kernel_oneplus_sm8250/tree/ee0a7ee1939ffd53000e42051caf8f0800defb27/drivers/input/touchscreen/synaptics_tcm
> + */
> +
> +/*
> + * Request information about the chip. We don't send this command explicitly as
> + * the controller automatically sends this information when starting up.
> + */
> +#define TCM_IDENTIFY 0x02
> +
> +/* Enable/disable reporting touch inputs */
> +#define TCM_ENABLE_REPORT 0x05
> +#define TCM_DISABLE_REPORT 0x06
> +
> +/*
> + * After powering on, we send this to exit the bootloader mode and run the main
> + * firmware.
> + */
> +#define TCM_RUN_APPLICATION_FIRMWARE 0x14
> +
> +/*
> + * Reports information about the vendor provided application firmware. This is
> + * also used to determine when the firmware has finished booting.
> + */
> +#define TCM_GET_APPLICATION_INFO 0x20
> +
> +#define MODE_APPLICATION 0x01
> +
> +#define APP_STATUS_OK 0x00
> +#define APP_STATUS_BOOTING 0x01
> +#define APP_STATUS_UPDATING 0x02
> +#define APP_STATUS_BAD_APP_CONFIG 0xff
> +
> +/* status codes */
> +#define REPORT_IDLE 0x00
> +#define REPORT_OK 0x01
> +#define REPORT_BUSY 0x02
> +#define REPORT_CONTINUED_READ 0x03
> +#define REPORT_RECEIVE_BUFFER_OVERFLOW 0x0c
> +#define REPORT_PREVIOUS_COMMAND_PENDING 0x0d
> +#define REPORT_NOT_IMPLEMENTED 0x0e
> +#define REPORT_ERROR 0x0f
> +
> +/* report types */
> +#define REPORT_IDENTIFY 0x10
> +#define REPORT_TOUCH 0x11
> +#define REPORT_DELTA 0x12
> +#define REPORT_RAW 0x13
> +#define REPORT_DEBUG 0x14
> +#define REPORT_LOG 0x1d
> +#define REPORT_TOUCH_HOLD 0x20
> +#define REPORT_INVALID 0xff
> +
> +/* Touch report codes */
> +#define TOUCH_END 0
> +#define TOUCH_FOREACH_ACTIVE_OBJECT 1
> +#define TOUCH_FOREACH_OBJECT 2
> +#define TOUCH_FOREACH_END 3
> +#define TOUCH_PAD_TO_NEXT_BYTE 4
> +#define TOUCH_TIMESTAMP 5
> +#define TOUCH_OBJECT_N_INDEX 6
> +#define TOUCH_OBJECT_N_CLASSIFICATION 7
> +#define TOUCH_OBJECT_N_X_POSITION 8
> +#define TOUCH_OBJECT_N_Y_POSITION 9
> +#define TOUCH_OBJECT_N_Z 10
> +#define TOUCH_OBJECT_N_X_WIDTH 11
> +#define TOUCH_OBJECT_N_Y_WIDTH 12
> +#define TOUCH_OBJECT_N_TX_POSITION_TIXELS 13
> +#define TOUCH_OBJECT_N_RX_POSITION_TIXELS 14
> +#define TOUCH_0D_BUTTONS_STATE 15
> +#define TOUCH_GESTURE_DOUBLE_TAP 16
> +#define TOUCH_FRAME_RATE 17 /* Normally 80hz */
> +#define TOUCH_POWER_IM 18
> +#define TOUCH_CID_IM 19
> +#define TOUCH_RAIL_IM 20
> +#define TOUCH_CID_VARIANCE_IM 21
> +#define TOUCH_NSM_FREQUENCY 22
> +#define TOUCH_NSM_STATE 23
> +#define TOUCH_NUM_OF_ACTIVE_OBJECTS 23
> +#define TOUCH_NUM_OF_CPU_CYCLES_USED_SINCE_LAST_FRAME 24
> +#define TOUCH_TUNING_GAUSSIAN_WIDTHS 0x80
> +#define TOUCH_TUNING_SMALL_OBJECT_PARAMS 0x81
> +#define TOUCH_TUNING_0D_BUTTONS_VARIANCE 0x82
> +#define TOUCH_REPORT_GESTURE_SWIPE 193
> +#define TOUCH_REPORT_GESTURE_CIRCLE 194
> +#define TOUCH_REPORT_GESTURE_UNICODE 195
> +#define TOUCH_REPORT_GESTURE_VEE 196
> +#define TOUCH_REPORT_GESTURE_TRIANGLE 197
> +#define TOUCH_REPORT_GESTURE_INFO 198
> +#define TOUCH_REPORT_GESTURE_COORDINATE 199
> +#define TOUCH_REPORT_CUSTOMER_GRIP_INFO 203

I don't think all these are used. Also, could we align values on the
same column please?

> +
> +struct tcm_message_header {
> +	u8 marker;
> +	u8 code;
> +} __packed;

I don't think this needs to be packed.

> +
> +/* header + 2 bytes (which are length of data depending on report code) */
> +#define REPORT_PEAK_LEN (sizeof(struct tcm_message_header) + 2)
> +
> +struct tcm_cmd {
> +	u8 cmd;
> +	u16 length;
> +	u8 data[];
> +};
> +
> +struct tcm_identification {
> +	struct tcm_message_header header;
> +	u16 length;
> +	u8 version;
> +	u8 mode;
> +	char part_number[16];
> +	u8 build_id[4];
> +	u8 max_write_size[2];
> +} __packed;
> +
> +struct tcm_app_info {
> +	struct tcm_message_header header;
> +	u16 length;

On-wire data needs to be annotated with proper endiannes (__le16 or
__be16) and converted to CPU-endianness before use.

> +	u8 version[2];
> +	u16 status;
> +	u8 static_config_size[2];

Should this be __le16 or __be16.

> +	u8 dynamic_config_size[2];
> +	u8 app_config_start_write_block[2];
> +	u8 app_config_size[2];
> +	u8 max_touch_report_config_size[2];
> +	u8 max_touch_report_payload_size[2];
> +	char customer_config_id[16];
> +	u16 max_x;
> +	u16 max_y;
> +	u8 max_objects[2];
> +	u8 num_of_buttons[2];
> +	u8 num_of_image_rows[2];
> +	u8 num_of_image_cols[2];
> +	u8 has_hybrid_data[2];
> +} __packed;
> +
> +struct tcm_report_config_prop {
> +	u8 id; /* TOUCH_OBJECT_* */
> +	u8 bits; /* Size of the field in bits */
> +};
> +
> +struct tcm_report_config_entry {
> +	u8 foreach; /* TOUCH_FOREACH_* (and maybe other things?) */
> +	int n_props;
> +	const struct tcm_report_config_prop *props;
> +};
> +
> +struct tcm_report_config {
> +	int n_entries;
> +	const struct tcm_report_config_entry *entries;
> +};
> +
> +struct tcm_data {
> +	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct input_dev *input;
> +	struct touchscreen_properties prop;
> +	struct gpio_desc *reset_gpio;
> +	struct completion response;
> +	struct regulator_bulk_data supplies[2];
> +
> +	/* annoying state */
> +	u16 buf_size;
> +	char buf[256];
> +};
> +
> +static int tcm_send_cmd(struct tcm_data *tcm, struct tcm_cmd *cmd)
> +{
> +	struct i2c_client *client = tcm->client;
> +	struct i2c_msg msg;
> +	int ret;
> +
> +	dev_dbg(&client->dev, "sending command %#x\n", cmd->cmd);
> +
> +	msg.addr = client->addr;
> +	msg.flags = 0;
> +	msg.len = 1 + cmd->length;
> +	msg.buf = (u8 *)cmd;
> +
> +	ret = i2c_transfer(client->adapter, &msg, 1);
> +	if (ret == 1)
> +		return 0;
> +	else if (ret < 0)
> +		return ret;
> +	else
> +		return -EIO;
> +}
> +
> +static int tcm_send_cmd_noargs(struct tcm_data *tcm, u8 cmd)
> +{
> +	struct tcm_cmd c = {
> +		.cmd = cmd,
> +		.length = 0,
> +	};
> +
> +	return tcm_send_cmd(tcm, &c);
> +}
> +
> +static int tcm_recv_report(struct tcm_data *tcm,
> +			   void *buf, size_t length)
> +{
> +	struct i2c_client *client = tcm->client;
> +	struct i2c_msg msg;
> +	int ret;
> +
> +	msg.addr = client->addr;
> +	msg.flags = I2C_M_RD;
> +	msg.len = length;
> +	msg.buf = buf;
> +
> +	ret = i2c_transfer(client->adapter, &msg, 1);
> +	if (ret == 1)
> +		return 0;
> +	else if (ret < 0)
> +		return ret;
> +	else
> +		return -EIO;
> +}
> +
> +static int tcm_read_message(struct tcm_data *tcm, u8 cmd, void *buf, size_t length)
> +{
> +	int ret;
> +
> +	reinit_completion(&tcm->response);
> +	ret = tcm_send_cmd_noargs(tcm, cmd);
> +	if (ret)
> +		return ret;
> +
> +	ret = wait_for_completion_timeout(&tcm->response, msecs_to_jiffies(1000));
> +	if (ret == 0)
> +		return -ETIMEDOUT;
> +
> +	if (buf) {
> +		if (length > tcm->buf_size) {
> +			dev_warn(&tcm->client->dev, "expected %zu bytes, got %u\n",
> +				 length, tcm->buf_size);
> +		}
> +		length = min(tcm->buf_size, length);
> +		memcpy(buf, tcm->buf, length);
> +	}
> +
> +	return 0;
> +}
> +
> +static void tcm_power_off(void *data)
> +{
> +	struct tcm_data *tcm = data;
> +
> +	disable_irq(tcm->client->irq);
> +	regulator_bulk_disable(ARRAY_SIZE(tcm->supplies), tcm->supplies);
> +}
> +
> +static int tcm_input_open(struct input_dev *dev)
> +{
> +	struct tcm_data *tcm = input_get_drvdata(dev);
> +
> +	return i2c_smbus_write_byte(tcm->client, TCM_ENABLE_REPORT);
> +}
> +
> +static void tcm_input_close(struct input_dev *dev)
> +{
> +	struct tcm_data *tcm = input_get_drvdata(dev);
> +	int ret;
> +
> +	ret = i2c_smbus_write_byte(tcm->client, TCM_DISABLE_REPORT);
> +	if (ret)
> +		dev_err(&tcm->client->dev, "failed to turn off sensing\n");
> +}
> +
> +/*
> + * The default report config looks like this:
> + *
> + * a5 01 80 00 11 08 1e 08 0f 01 04 01 06 04 07 04
> + * 08 0c 09 0c 0a 08 0b 08 0c 08 0d 10 0e 10 03 00
> + * 00 00
> + *
> + * a5 01 80 00 - HEADER + length
> + *
> + * 11 08 - TOUCH_FRAME_RATE (8 bits)
> + * 30 08 - UNKNOWN (8 bits)
> + * 0f 01 - TOUCH_0D_BUTTONS_STATE (1 bit)
> + * 04 01 - TOUCH_PAD_TO_NEXT_BYTE (7 bits - padding)
> + * 06 04 - TOUCH_OBJECT_N_INDEX (4 bits)
> + * 07 04 - TOUCH_OBJECT_N_CLASSIFICATION (4 bits)
> + * 08 0c - TOUCH_OBJECT_N_X_POSITION (12 bits)
> + * 09 0c - TOUCH_OBJECT_N_Y_POSITION (12 bits)
> + * 0a 08 - TOUCH_OBJECT_N_Z (8 bits)
> + * 0b 08 - TOUCH_OBJECT_N_X_WIDTH (8 bits)
> + * 0c 08 - TOUCH_OBJECT_N_Y_WIDTH (8 bits)
> + * 0d 10 - TOUCH_OBJECT_N_TX_POSITION_TIXELS (16 bits) ??
> + * 0e 10 - TOUCH_OBJECT_N_RX_POSITION_TIXELS (16 bits) ??
> + * 03 00 - TOUCH_FOREACH_END (0 bits)
> + * 00 00 - TOUCH_END (0 bits)
> + *
> + * Since we only support this report config, we just hardcode the format below.
> + * To support additional report configs, we would need to parse the config and
> + * use it to parse the reports dynamically.
> + */
> +
> +struct tcm_default_report_data {
> +	u8 fps;
> +	struct {
> +		u8 unknown;
> +		u8 buttons;
> +		u8 idx : 4;
> +		u8 classification : 4;
> +		u16 x : 12;
> +		u16 y : 12;

This will be a mess on big endian. Please no bitfields. Use normally
sized fields (u8, u16, etc) and masks/shifts to get data.

> +		u8 z;
> +		u8 width_x;
> +		u8 width_y;
> +		u8 tx;
> +		u8 rx;
> +	} __packed points[];
> +} __packed;
> +
> +static int tcm_handle_touch_report(struct tcm_data *tcm, char *buf, size_t len)
> +{
> +	struct tcm_default_report_data *data;
> +
> +	buf += REPORT_PEAK_LEN;
> +	len -= REPORT_PEAK_LEN;
> +
> +	dev_dbg(&tcm->client->dev, "touch report len %zu\n", len);
> +	if ((len - 1) % 11)
> +		dev_err(&tcm->client->dev, "invalid touch report length\n");
> +
> +	data = (struct tcm_default_report_data *)buf;
> +
> +	/* We don't need to report releases because we have INPUT_MT_DROP_UNUSED */
> +	for (int i = 0; i < (len - 1) / 11; i++) {
> +		u8 major_width, minor_width;
> +
> +		minor_width = data->points[i].width_x;
> +		major_width = data->points[i].width_y;
> +
> +		if (minor_width > major_width)
> +			swap(major_width, minor_width);
> +
> +		dev_dbg(&tcm->client->dev, "touch report: idx %u x %u y %u\n",
> +			data->points[i].idx, data->points[i].x, data->points[i].y);
> +		input_mt_slot(tcm->input, data->points[i].idx);
> +		input_mt_report_slot_state(tcm->input, MT_TOOL_FINGER, true);
> +
> +		input_report_abs(tcm->input, ABS_MT_POSITION_X, data->points[i].x);
> +		input_report_abs(tcm->input, ABS_MT_POSITION_Y, data->points[i].y);

touchscreen_report_pos(...) instead of the 2 above so that rotation/axis
swap will be handled properly.

> +		input_report_abs(tcm->input, ABS_MT_TOUCH_MAJOR, major_width);
> +		input_report_abs(tcm->input, ABS_MT_TOUCH_MINOR, minor_width);
> +		input_report_abs(tcm->input, ABS_MT_PRESSURE, data->points[i].z);
> +	}
> +
> +	input_mt_sync_frame(tcm->input);
> +	input_sync(tcm->input);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t tcm_report_irq(int irq, void *data)
> +{
> +	struct tcm_data *tcm = data;
> +	struct tcm_message_header *header;
> +	char buf[256];
> +	u16 len;
> +	int ret;
> +
> +	header = (struct tcm_message_header *)buf;
> +	ret = tcm_recv_report(tcm, buf, sizeof(buf));
> +	if (ret) {
> +		dev_err(&tcm->client->dev, "failed to read report: %d\n", ret);
> +		return IRQ_HANDLED;
> +	}
> +
> +	switch (header->code) {
> +	case REPORT_OK:
> +	case REPORT_IDENTIFY:
> +	case REPORT_TOUCH:
> +	case REPORT_DELTA:
> +	case REPORT_RAW:
> +	case REPORT_DEBUG:
> +	case REPORT_TOUCH_HOLD:
> +		break;
> +	default:
> +		dev_dbg(&tcm->client->dev, "Ignoring report %#x\n", header->code);
> +		return IRQ_HANDLED;
> +	}
> +
> +	/* Not present for REPORT_CONTINUED_READ */
> +	len = get_unaligned_le16(buf + sizeof(*header));
> +
> +	dev_dbg(&tcm->client->dev, "report %#x len %u\n", header->code, len);
> +	print_hex_dump_bytes("report: ", DUMP_PREFIX_OFFSET, buf,
> +			     min(sizeof(buf), len + sizeof(*header)));
> +
> +	if (len > sizeof(buf) - sizeof(*header)) {
> +		dev_err(&tcm->client->dev, "report too long\n");
> +		return IRQ_HANDLED;
> +	}
> +
> +	/* Check if this is a read response or an indication. For indications
> +	 * (user touched the screen) we just parse the report directly.
> +	 */
> +	if (completion_done(&tcm->response) && header->code == REPORT_TOUCH) {
> +		tcm_handle_touch_report(tcm, buf, len + sizeof(*header));
> +		return IRQ_HANDLED;
> +	}
> +
> +	tcm->buf_size = len + sizeof(*header);
> +	memcpy(tcm->buf, buf, len + sizeof(*header));
> +	complete(&tcm->response);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int tcm_hw_init(struct tcm_data *tcm, u16 *max_x, u16 *max_y)
> +{
> +	int ret;
> +	struct tcm_identification id = { 0 };
> +	struct tcm_app_info app_info = { 0 };
> +
> +	/*
> +	 * Tell the firmware to start up. After starting it sends an IDENTIFY report, which
> +	 * we treat like a response to this message even though it's technically a new report.
> +	 */
> +	ret = tcm_read_message(tcm, TCM_RUN_APPLICATION_FIRMWARE, &id, sizeof(id));
> +	if (ret) {
> +		dev_err(&tcm->client->dev, "failed to identify device: %d\n", ret);
> +		return ret;
> +	}
> +
> +	dev_dbg(&tcm->client->dev, "Synaptics TCM %s v%d mode %d\n",
> +		id.part_number, id.version, id.mode);
> +	if (id.mode != MODE_APPLICATION) {
> +		/* We don't support firmware updates or anything else */
> +		dev_err(&tcm->client->dev, "Device is not in application mode\n");
> +		return -ENODEV;
> +	}
> +
> +	do {
> +		msleep(20);
> +		ret = tcm_read_message(tcm, TCM_GET_APPLICATION_INFO, &app_info, sizeof(app_info));
> +		if (ret) {
> +			dev_err(&tcm->client->dev, "failed to get application info: %d\n", ret);
> +			return ret;
> +		}
> +	} while (app_info.status == APP_STATUS_BOOTING || app_info.status == APP_STATUS_UPDATING);
> +
> +	dev_dbg(&tcm->client->dev, "Application firmware v%d.%d (customer '%s') status %d\n",
> +		 app_info.version[0], app_info.version[1], app_info.customer_config_id,
> +		 app_info.status);
> +
> +	*max_x = app_info.max_x;
> +	*max_y = app_info.max_y;
> +
> +	return 0;
> +}
> +
> +static int tcm_power_on(struct tcm_data *tcm)
> +{
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(tcm->supplies),
> +				    tcm->supplies);
> +	if (ret)
> +		return ret;
> +
> +	gpiod_set_value(tcm->reset_gpio, false);
> +	usleep_range(10000, 11000);
> +	gpiod_set_value(tcm->reset_gpio, true);

Here you have reset GPIO asserted, which means that the controller will
stay in reset state indefinitely.

gpiod API operates on logical states (active/inactive) and performs
conversion to physical state (LOW/HIGH) internally.

Also we should use gpiod_set_value_cansleep() unless we are in atomic
context.

> +	usleep_range(80000, 81000);
> +
> +	return 0;
> +}
> +
> +static int tcm_probe(struct i2c_client *client)
> +{
> +	struct tcm_data *tcm;
> +	struct tcm_report_config __maybe_unused report_config;

It is definitely not used, there no "maybe" about it.

> +	u16 max_x, max_y;
> +	int ret;

Call this and similar variables holding error code "error" please.

> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
> +						I2C_FUNC_SMBUS_BYTE_DATA |
> +						I2C_FUNC_SMBUS_I2C_BLOCK))
> +		return -ENODEV;
> +
> +	tcm = devm_kzalloc(&client->dev, sizeof(struct tcm_data), GFP_KERNEL);

sizeof(*tcm)

> +	if (!tcm)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, tcm);
> +	tcm->client = client;
> +
> +	init_completion(&tcm->response);
> +
> +	tcm->supplies[0].supply = "vdd";
> +	tcm->supplies[1].supply = "vcc";
> +	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(tcm->supplies),
> +				      tcm->supplies);
> +	if (ret)
> +		return ret;
> +
> +	tcm->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);

Do all designs require GPIO line be specified? Can it be made optional?

> +
> +	ret = devm_add_action_or_reset(&client->dev, tcm_power_off,
> +				       tcm);
> +	if (ret)
> +		return ret;
> +
> +	ret = tcm_power_on(tcm);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
> +					tcm_report_irq,
> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT,

Please do not hardcode trigger (besides IRQF_ONESHOT), let platform
decide.

Also interrupt is hot there, are you sure we will not try to report
input events for not-yet-allocated input device if someone is thouching
the device at this point?

> +					"synaptics_tcm_report", tcm);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = tcm_hw_init(tcm, &max_x, &max_y);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to initialize hardware\n");
> +		return ret;
> +	}
> +
> +	tcm->input = devm_input_allocate_device(&client->dev);
> +	if (!tcm->input)
> +		return -ENOMEM;
> +
> +	tcm->input->name = "Synaptics TCM Oncell Touchscreen";
> +	tcm->input->id.bustype = BUS_I2C;
> +	tcm->input->open = tcm_input_open;
> +	tcm->input->close = tcm_input_close;
> +
> +	input_set_abs_params(tcm->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
> +	input_set_abs_params(tcm->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
> +	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
> +	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
> +	input_set_abs_params(tcm->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
> +
> +	touchscreen_parse_properties(tcm->input, true, &tcm->prop);
> +
> +	ret = input_mt_init_slots(tcm->input, 10, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
> +	if (ret)
> +		return ret;
> +
> +	input_set_drvdata(tcm->input, tcm);
> +
> +	ret = input_register_device(tcm->input);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id syna_driver_ids[] = {
> +	{
> +		.compatible = "syna,s3908",
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, syna_driver_ids);
> +
> +static const struct i2c_device_id syna_i2c_ids[] = {
> +	{ "synaptics-tcm", 0 },
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, syna_i2c_ids);
> +
> +static struct i2c_driver syna_i2c_driver = {
> +	.probe	= tcm_probe,
> +	.id_table	= syna_i2c_ids,
> +	.driver	= {
> +	.name	= "synaptics-tcm",
> +	.of_match_table = syna_driver_ids,
> +	},
> +};
> +
> +module_i2c_driver(syna_i2c_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Frieder Hannenheim <frieder.hannenheim@proton.me>");
> +MODULE_AUTHOR("Caleb Connolly <caleb@postmarketos.org>");
> +MODULE_DESCRIPTION("A driver for Synaptics TCM Oncell Touchpanels");
> +
> 
> -- 
> 2.45.0
> 

-- 
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/7] qcom: initial support for the OnePlus 8T
  2024-06-24  5:18 ` [PATCH 0/7] qcom: initial support for the OnePlus 8T Dmitry Baryshkov
@ 2024-06-24 11:32   ` Caleb Connolly
  2024-06-24 11:33     ` Dmitry Baryshkov
  0 siblings, 1 reply; 25+ messages in thread
From: Caleb Connolly @ 2024-06-24 11:32 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming,
	Frieder Hannenheim



On 24/06/2024 07:18, Dmitry Baryshkov wrote:
> On Mon, Jun 24, 2024 at 03:30:24AM GMT, Caleb Connolly wrote:
>> Add bindings for the SM8250 OnePlus devices, a common devicetree,
>> touchscreen and display drivers, and a dts for the OnePlus 8T (kebab).
>>
>> The OnePlus 8 series is made up of 3 flagship smartphones from 2019,
>> featuring the Qualcomm X55 5G PCIe modem.
>>
>> This series introduces initial support for the 8T, adding drivers for
>> the 1080x2400 120Hz DSC panel and the Synaptics TCM Oncell touchscreen.
>>
>> The panel driver suffers from similar limitations to the LG SW43408
>> panel found on the Pixel 3, namely that after toggling the reset GPIO it
>> is not possible to get the panel into a working state.
> 
> Just to point it out: this is no longer true for SW43408. The panel
> wakes up and works after toggling the reset. It seems, there is an issue
> with one of the regulators, but not with the reset and/or panel startup.

Hmm ok, I've heard mixed reports then, I should try it out myself again.

I'll update the cover letter to reflect this. Thanks.
> 
>> Given the apparent prevelance of this issue, particularly with DSC
>> panels, I believe this is a bug in the core DSI code, and not a device
>> or panel specific issue. I think it is still useful to accept these
>> panel drivers into upstream since, from a users perspective, the panel
>> is fully functional just by leaving the reset GPIO alone and keeping the
>> regulator on. The only (theoretical) downside is worse battery life,
>> which is a small price to pay for a working display.
>>
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/7] qcom: initial support for the OnePlus 8T
  2024-06-24 11:32   ` Caleb Connolly
@ 2024-06-24 11:33     ` Dmitry Baryshkov
  0 siblings, 0 replies; 25+ messages in thread
From: Dmitry Baryshkov @ 2024-06-24 11:33 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming,
	Frieder Hannenheim

On Mon, 24 Jun 2024 at 14:33, Caleb Connolly <caleb@postmarketos.org> wrote:
>
>
>
> On 24/06/2024 07:18, Dmitry Baryshkov wrote:
> > On Mon, Jun 24, 2024 at 03:30:24AM GMT, Caleb Connolly wrote:
> >> Add bindings for the SM8250 OnePlus devices, a common devicetree,
> >> touchscreen and display drivers, and a dts for the OnePlus 8T (kebab).
> >>
> >> The OnePlus 8 series is made up of 3 flagship smartphones from 2019,
> >> featuring the Qualcomm X55 5G PCIe modem.
> >>
> >> This series introduces initial support for the 8T, adding drivers for
> >> the 1080x2400 120Hz DSC panel and the Synaptics TCM Oncell touchscreen.
> >>
> >> The panel driver suffers from similar limitations to the LG SW43408
> >> panel found on the Pixel 3, namely that after toggling the reset GPIO it
> >> is not possible to get the panel into a working state.
> >
> > Just to point it out: this is no longer true for SW43408. The panel
> > wakes up and works after toggling the reset. It seems, there is an issue
> > with one of the regulators, but not with the reset and/or panel startup.
>
> Hmm ok, I've heard mixed reports then, I should try it out myself again.

During MAD24 we have seen an issue with the regulators, when the panel
doesn't wake up. But resetting the panel works.

>
> I'll update the cover letter to reflect this. Thanks.
> >
> >> Given the apparent prevelance of this issue, particularly with DSC
> >> panels, I believe this is a bug in the core DSI code, and not a device
> >> or panel specific issue. I think it is still useful to accept these
> >> panel drivers into upstream since, from a users perspective, the panel
> >> is fully functional just by leaving the reset GPIO alone and keeping the
> >> regulator on. The only (theoretical) downside is worse battery life,
> >> which is a small price to pay for a working display.
> >>
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series
  2024-06-24  1:30 ` [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series Caleb Connolly
  2024-06-24  4:52   ` Krzysztof Kozlowski
@ 2024-06-24 20:40   ` Rob Herring
  1 sibling, 0 replies; 25+ messages in thread
From: Rob Herring @ 2024-06-24 20:40 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming

On Mon, Jun 24, 2024 at 03:30:27AM +0200, Caleb Connolly wrote:
> Add bindings for the OnePlus 8, 8 Pro, and 8T devices.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  Documentation/devicetree/bindings/arm/qcom.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
> index d839691a900c..a41eeb8c3fc5 100644
> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
> @@ -986,8 +986,11 @@ properties:
>            - enum:
>                - qcom,qrb5165-rb5
>                - qcom,sm8250-hdk
>                - qcom,sm8250-mtp
> +              - oneplus,kebab
> +              - oneplus,instantnoodle
> +              - oneplus,instantnoodlep

Which one is which device in the commit msg? I can only guess that 'p' 
here corresponds to Pro. A comment after the compatibles would help.

>                - sony,pdx203-generic
>                - sony,pdx206-generic
>                - xiaomi,elish
>                - xiaomi,pipa
> 
> -- 
> 2.45.0
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab)
  2024-06-24  1:30 ` [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab) Caleb Connolly
@ 2024-06-26  4:16   ` Bjorn Andersson
  2024-06-27 23:40     ` Caleb Connolly
  2024-06-26  9:43   ` Konrad Dybcio
  1 sibling, 1 reply; 25+ messages in thread
From: Bjorn Andersson @ 2024-06-26  4:16 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov, Konrad Dybcio,
	Henrik Rydberg, dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

On Mon, Jun 24, 2024 at 03:30:31AM GMT, Caleb Connolly wrote:
> Initial support for USB, UFS, touchscreen, panel, wifi, and bluetooth.
> 

Nice.

> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
[..]
> +	vph_pwr: vph-pwr-regulator {

Please keep nodes sorted by address, then node name, then label (as
applicable). Perhaps making the -regulator suffix a regulator- prefix
instead (to keep them grouped).

> +		compatible = "regulator-fixed";
> +		regulator-name = "vph_pwr";
> +		regulator-min-microvolt = <3700000>;
> +		regulator-max-microvolt = <3700000>;
> +		regulator-always-on;
> +	};
> +
> +	vreg_s4a_1p8: vreg-s4a-1p8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vreg_s4a_1p8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		regulator-always-on;
> +	};
[..]
> +&adsp {
> +	status = "okay";

Per Documentation/devicetree/bindings/dts-coding-style.rst please keep
"status" as last property in your nodes.

> +	firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
> +};
> +
[..]
> +&mdss_dsi0 {
> +	status = "okay";
> +	vdda-supply = <&vreg_l9a_1p2>;
> +
> +	display_panel: panel@0 {
> +		reg = <0>;
> +		vddio-supply = <&vreg_l14a_1p8>;
> +		vdd-supply = <&vreg_l11c_3p3>;
> +		avdd-supply = <&panel_avdd_5p5>;

How do you know that the panel will have these properties, when you
don't give it a compatible here? Not a strong objection, but perhaps
this should be pushed out?

> +		/* FIXME: There is a bug somewhere in the display stack and it isn't
> +		 * possible to get the panel to a working state after toggling reset.
> +		 * At best it just shows one or more vertical red lines. So for now
> +		 * let's skip the reset GPIO.
> +		 */
> +		// reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
> +
> +		pinctrl-0 = <&panel_reset_pins &panel_vsync_pins &panel_vout_pins>;
> +		pinctrl-names = "default";
> +
> +		status = "disabled";
> +
> +		port {
> +			panel_in_0: endpoint {
> +				remote-endpoint = <&mdss_dsi0_out>;
> +			};
> +		};
> +	};
> +
> +};
[..]
> +&pm8150_gpios {
> +	gpio-reserved-ranges = <2 1>, <4 1>, <8 1>;

How come?

> +};
> +
[..]
> +&tlmm {
> +	gpio-reserved-ranges = <28 4>, <40 4>;
> +
> +	bt_en_state: bt-default-state {
> +		pins = "gpio21";
> +		function = "gpio";
> +		drive-strength = <16>;
> +		output-low;
> +		bias-pull-up;
> +	};
> +
> +	wlan_en_state: wlan-default-state {
> +		wlan-en-pins {

Perhaps flatten this?

> +			pins = "gpio20";
> +			function = "gpio";
> +
> +			drive-strength = <16>;
> +			output-low;
> +			bias-pull-up;
> +		};
> +	};
> +
[..]
> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
[..]
> +&i2c13 {
[..]
> +};
> +
> +&display_panel {

'd' < 'i'

Regards,
Bjorn

> +	compatible = "samsung,amb655x";
> +	status = "okay";
> +};
> 
> -- 
> 2.45.0
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab)
  2024-06-24  1:30 ` [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab) Caleb Connolly
  2024-06-26  4:16   ` Bjorn Andersson
@ 2024-06-26  9:43   ` Konrad Dybcio
  1 sibling, 0 replies; 25+ messages in thread
From: Konrad Dybcio @ 2024-06-26  9:43 UTC (permalink / raw)
  To: Caleb Connolly, Neil Armstrong, Jessica Zhang, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Bjorn Andersson, Henrik Rydberg
  Cc: dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim

On 24.06.2024 3:30 AM, Caleb Connolly wrote:
> Initial support for USB, UFS, touchscreen, panel, wifi, and bluetooth.
> 
> Co-developed-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
> Signed-off-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---

[...]

> +&adsp {
> +	status = "okay";
> +	firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
> +};

Status last pls

[...]

> +&gmu {
> +	status = "okay";
> +};

already enabled (or should be)

[...]

> +/* LS-I2C1 */
> +&i2c15 {
> +	status = "okay";
> +
> +	// fcs,fsa4480 @ 42

Just describe it ;)

[...]


> +		/* FIXME: There is a bug somewhere in the display stack and it isn't

/*
 * FIXME:
> +		 * possible to get the panel to a working state after toggling reset.
> +		 * At best it just shows one or more vertical red lines. So for now
> +		 * let's skip the reset GPIO.
> +		 */
> +		// reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;

/* */

[...]

> +&ufs_mem_hc {
> +	status = "okay";
> +
> +	vcc-supply = <&vreg_l17a_3p0>;
> +	vcc-max-microamp = <800000>;
> +	vccq-supply = <&vreg_l6a_1p2>;
> +	vccq-max-microamp = <800000>;
> +	vccq2-supply = <&vreg_s4a_1p8>;
> +	vccq2-max-microamp = <800000>;

allow set mode + allowed modes

Konrad

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X
  2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
  2024-06-24  1:33   ` Caleb Connolly
@ 2024-06-27 22:12   ` Rob Herring
  2024-06-27 23:24     ` Caleb Connolly
  1 sibling, 1 reply; 25+ messages in thread
From: Rob Herring @ 2024-06-27 22:12 UTC (permalink / raw)
  To: Caleb Connolly
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming

On Mon, Jun 24, 2024 at 03:30:25AM +0200, Caleb Connolly wrote:
> Describe the Samsung AMB655X panel. It has three supplies.
> 
> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
> ---
>  .../bindings/display/panel/samsung,amb655x.yaml    | 59 ++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
> new file mode 100644
> index 000000000000..eb987d022a0d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
> @@ -0,0 +1,59 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/samsung,amb655x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung AMB655X 1080x2400 120hz AMOLED panel
> +
> +maintainers:
> +  - Caleb Connolly <caleb@postmarketos.org>
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +    const: samsung,amb655x

'x' is not a wildcard is it? Those are generally not allowed.

> +
> +  reg:
> +    maxItems: 1
> +
> +  reset-gpios:
> +    description: reset gpio, must be GPIO_ACTIVE_LOW

blank line

> +  vddio-supply: true
> +  vdd-supply: true
> +  avdd-supply: true
> +  enable-gpios: true
> +  port: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - vdd-supply
> +  - avdd-supply
> +  - vddio-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        panel@0 {
> +            compatible = "samsung,ams495qa01";
> +            reg = <0>;
> +            reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
> +            vdd-supply = <&vcc_3v3>;
> +
> +            port {
> +                mipi_in_panel: endpoint {
> +                  remote-endpoint = <&mipi_out_panel>;
> +                };
> +            };
> +        };
> +    };
> +
> +...
> 
> -- 
> 2.45.0
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X
  2024-06-27 22:12   ` Rob Herring
@ 2024-06-27 23:24     ` Caleb Connolly
  0 siblings, 0 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-27 23:24 UTC (permalink / raw)
  To: Rob Herring
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov,
	Bjorn Andersson, Konrad Dybcio, Henrik Rydberg, dri-devel,
	devicetree, linux-input, linux-arm-msm, ~postmarketos/upstreaming



On 28/06/2024 00:12, Rob Herring wrote:
> On Mon, Jun 24, 2024 at 03:30:25AM +0200, Caleb Connolly wrote:
>> Describe the Samsung AMB655X panel. It has three supplies.
>>
>> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
>> ---
>>   .../bindings/display/panel/samsung,amb655x.yaml    | 59 ++++++++++++++++++++++
>>   1 file changed, 59 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
>> new file mode 100644
>> index 000000000000..eb987d022a0d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/panel/samsung,amb655x.yaml
>> @@ -0,0 +1,59 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/display/panel/samsung,amb655x.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung AMB655X 1080x2400 120hz AMOLED panel
>> +
>> +maintainers:
>> +  - Caleb Connolly <caleb@postmarketos.org>
>> +
>> +allOf:
>> +  - $ref: panel-common.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: samsung,amb655x
> 
> 'x' is not a wildcard is it? Those are generally not allowed.

No, not as far as I can tell. every reference I can find refers to this 
panel as amb655x, there i haven't found anything else and I don't know 
of any variations of the panel.
> 
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  reset-gpios:
>> +    description: reset gpio, must be GPIO_ACTIVE_LOW
> 
> blank line
> 
>> +  vddio-supply: true
>> +  vdd-supply: true
>> +  avdd-supply: true
>> +  enable-gpios: true
>> +  port: true
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - vdd-supply
>> +  - avdd-supply
>> +  - vddio-supply
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/gpio/gpio.h>
>> +    spi {
>> +        #address-cells = <1>;
>> +        #size-cells = <0>;
>> +        panel@0 {
>> +            compatible = "samsung,ams495qa01";
>> +            reg = <0>;
>> +            reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
>> +            vdd-supply = <&vcc_3v3>;
>> +
>> +            port {
>> +                mipi_in_panel: endpoint {
>> +                  remote-endpoint = <&mipi_out_panel>;
>> +                };
>> +            };
>> +        };
>> +    };
>> +
>> +...
>>
>> -- 
>> 2.45.0
>>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908
  2024-06-24  7:42   ` Dmitry Torokhov
@ 2024-06-27 23:35     ` Caleb Connolly
  0 siblings, 0 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-27 23:35 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Henrik Rydberg, dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim



On 24/06/2024 09:42, Dmitry Torokhov wrote:
> Hi Caleb,
> 
> On Mon, Jun 24, 2024 at 03:30:30AM +0200, Caleb Connolly wrote:
>> The TCM oncell is the next generation of Synaptics touchscreen ICs.
>> These run a very featured firmware with a reasonably well defined API.
>> It is however entirely incompatible with the existing RMI4 interface.
>>
>> Unfortunately, no public datasheet for the interface seems to be
>> available, instead this driver was created through a combination of
>> vendor drivers and trial and error.
>>
>> The firmware interface implies support for defining the exact bit
>> encoding of the touch reports, however on the S3908 chip + firmware
>> found in the OnePlus 8t the TCM_SET_TOUCH_REPORT_CONFIG command appears
>> to be unsupported.
>>
>> Co-developed-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
>> Signed-off-by: Frieder Hannenheim <frieder.hannenheim@proton.me>
>> Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
>> ---
>>   MAINTAINERS                                      |   7 +
>>   drivers/input/touchscreen/Kconfig                |  11 +
>>   drivers/input/touchscreen/Makefile               |   1 +
>>   drivers/input/touchscreen/synaptics_tcm_oncell.c | 617 +++++++++++++++++++++++
>>   4 files changed, 636 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 2b9cfbf92d7a..db589c841d8c 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -21826,8 +21826,15 @@ M:	Icenowy Zheng <icenowy@aosc.io>
>>   S:	Maintained
>>   F:	Documentation/devicetree/bindings/regulator/silergy,sy8106a.yaml
>>   F:	drivers/regulator/sy8106a-regulator.c
>>   
>> +SYNAPTICS TCM ONCELL TOUCHSCREEN DRIVER
>> +M:	Caleb Connolly <caleb@postmarketos.org>
>> +L:	linux-input@vger.kernel.org
>> +S:	Maintained
>> +F:	Documentation/devicetree/bindings/input/touchscreen/syna,tcm-oncell.yaml
>> +F:	drivers/input/touchscreen/synaptics_tcm_oncell.c
>> +
>>   SYNC FILE FRAMEWORK
>>   M:	Sumit Semwal <sumit.semwal@linaro.org>
>>   R:	Gustavo Padovan <gustavo@padovan.org>
>>   L:	linux-media@vger.kernel.org
>> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
>> index c821fe3ee794..43c4fd80601c 100644
>> --- a/drivers/input/touchscreen/Kconfig
>> +++ b/drivers/input/touchscreen/Kconfig
>> @@ -531,8 +531,19 @@ config TOUCHSCREEN_S6SY761
>>   
>>   	  To compile this driver as module, choose M here: the
>>   	  module will be called s6sy761.
>>   
>> +config TOUCHSCREEN_SYNAPTICS_TCM_ONCELL
>> +	tristate "Synaptics TCM Oncell Touchscreen driver"
>> +	depends on I2C
>> +	help
>> +	  Say Y if you have the Synaptics S3908 TCM Oncell
>> +
>> +	  If unsure, say N
>> +
>> +	  To compile this driver as module, choose M here: the
>> +	  module will be called synaptics_tcm_oncell.
>> +
>>   config TOUCHSCREEN_GUNZE
>>   	tristate "Gunze AHL-51S touchscreen"
>>   	select SERIO
>>   	help
>> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
>> index a81cb5aa21a5..6a2b85050c3a 100644
>> --- a/drivers/input/touchscreen/Makefile
>> +++ b/drivers/input/touchscreen/Makefile
>> @@ -88,8 +88,9 @@ obj-$(CONFIG_TOUCHSCREEN_STMFTS)	+= stmfts.o
>>   obj-$(CONFIG_TOUCHSCREEN_STMPE)		+= stmpe-ts.o
>>   obj-$(CONFIG_TOUCHSCREEN_SUN4I)		+= sun4i-ts.o
>>   obj-$(CONFIG_TOUCHSCREEN_SUR40)		+= sur40.o
>>   obj-$(CONFIG_TOUCHSCREEN_SURFACE3_SPI)	+= surface3_spi.o
>> +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_ONCELL)	+= synaptics_tcm_oncell.o
>>   obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)	+= ti_am335x_tsc.o
>>   obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
>>   obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
>>   obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
>> diff --git a/drivers/input/touchscreen/synaptics_tcm_oncell.c b/drivers/input/touchscreen/synaptics_tcm_oncell.c
>> new file mode 100644
>> index 000000000000..c1ba9a3a93c0
>> --- /dev/null
>> +++ b/drivers/input/touchscreen/synaptics_tcm_oncell.c
>> @@ -0,0 +1,617 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + *  Driver for Synaptics TCM Oncell Touchscreens
>> + *
>> + *  Copyright (c) 2024 Frieder Hannenheim <frieder.hannenheim@proton.me>
>> + *  Copyright (c) 2024 Caleb Connolly <caleb@postmarketos.org>
>> + */
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/input.h>
>> +#include <linux/input/touchscreen.h>
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/module.h>
>> +#include <linux/property.h>
>> +#include <asm/unaligned.h>
>> +#include <linux/delay.h>
>> +#include <linux/input/mt.h>
>> +#include <linux/input/touchscreen.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irq.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +/*
>> + * The TCM oncell interface uses a command byte, which may be followed by additional
>> + * data. The packet format is defined in the tcm_cmd struct.
>> + *
>> + * The following list only defines commands that are used in this driver (and their
>> + * counterparts for context). Vendor reference implementations can be found at
>> + * https://github.com/LineageOS/android_kernel_oneplus_sm8250/tree/ee0a7ee1939ffd53000e42051caf8f0800defb27/drivers/input/touchscreen/synaptics_tcm
>> + */
>> +
>> +/*
>> + * Request information about the chip. We don't send this command explicitly as
>> + * the controller automatically sends this information when starting up.
>> + */
>> +#define TCM_IDENTIFY 0x02
>> +
>> +/* Enable/disable reporting touch inputs */
>> +#define TCM_ENABLE_REPORT 0x05
>> +#define TCM_DISABLE_REPORT 0x06
>> +
>> +/*
>> + * After powering on, we send this to exit the bootloader mode and run the main
>> + * firmware.
>> + */
>> +#define TCM_RUN_APPLICATION_FIRMWARE 0x14
>> +
>> +/*
>> + * Reports information about the vendor provided application firmware. This is
>> + * also used to determine when the firmware has finished booting.
>> + */
>> +#define TCM_GET_APPLICATION_INFO 0x20
>> +
>> +#define MODE_APPLICATION 0x01
>> +
>> +#define APP_STATUS_OK 0x00
>> +#define APP_STATUS_BOOTING 0x01
>> +#define APP_STATUS_UPDATING 0x02
>> +#define APP_STATUS_BAD_APP_CONFIG 0xff
>> +
>> +/* status codes */
>> +#define REPORT_IDLE 0x00
>> +#define REPORT_OK 0x01
>> +#define REPORT_BUSY 0x02
>> +#define REPORT_CONTINUED_READ 0x03
>> +#define REPORT_RECEIVE_BUFFER_OVERFLOW 0x0c
>> +#define REPORT_PREVIOUS_COMMAND_PENDING 0x0d
>> +#define REPORT_NOT_IMPLEMENTED 0x0e
>> +#define REPORT_ERROR 0x0f
>> +
>> +/* report types */
>> +#define REPORT_IDENTIFY 0x10
>> +#define REPORT_TOUCH 0x11
>> +#define REPORT_DELTA 0x12
>> +#define REPORT_RAW 0x13
>> +#define REPORT_DEBUG 0x14
>> +#define REPORT_LOG 0x1d
>> +#define REPORT_TOUCH_HOLD 0x20
>> +#define REPORT_INVALID 0xff
>> +
>> +/* Touch report codes */
>> +#define TOUCH_END 0
>> +#define TOUCH_FOREACH_ACTIVE_OBJECT 1
>> +#define TOUCH_FOREACH_OBJECT 2
>> +#define TOUCH_FOREACH_END 3
>> +#define TOUCH_PAD_TO_NEXT_BYTE 4
>> +#define TOUCH_TIMESTAMP 5
>> +#define TOUCH_OBJECT_N_INDEX 6
>> +#define TOUCH_OBJECT_N_CLASSIFICATION 7
>> +#define TOUCH_OBJECT_N_X_POSITION 8
>> +#define TOUCH_OBJECT_N_Y_POSITION 9
>> +#define TOUCH_OBJECT_N_Z 10
>> +#define TOUCH_OBJECT_N_X_WIDTH 11
>> +#define TOUCH_OBJECT_N_Y_WIDTH 12
>> +#define TOUCH_OBJECT_N_TX_POSITION_TIXELS 13
>> +#define TOUCH_OBJECT_N_RX_POSITION_TIXELS 14
>> +#define TOUCH_0D_BUTTONS_STATE 15
>> +#define TOUCH_GESTURE_DOUBLE_TAP 16
>> +#define TOUCH_FRAME_RATE 17 /* Normally 80hz */
>> +#define TOUCH_POWER_IM 18
>> +#define TOUCH_CID_IM 19
>> +#define TOUCH_RAIL_IM 20
>> +#define TOUCH_CID_VARIANCE_IM 21
>> +#define TOUCH_NSM_FREQUENCY 22
>> +#define TOUCH_NSM_STATE 23
>> +#define TOUCH_NUM_OF_ACTIVE_OBJECTS 23
>> +#define TOUCH_NUM_OF_CPU_CYCLES_USED_SINCE_LAST_FRAME 24
>> +#define TOUCH_TUNING_GAUSSIAN_WIDTHS 0x80
>> +#define TOUCH_TUNING_SMALL_OBJECT_PARAMS 0x81
>> +#define TOUCH_TUNING_0D_BUTTONS_VARIANCE 0x82
>> +#define TOUCH_REPORT_GESTURE_SWIPE 193
>> +#define TOUCH_REPORT_GESTURE_CIRCLE 194
>> +#define TOUCH_REPORT_GESTURE_UNICODE 195
>> +#define TOUCH_REPORT_GESTURE_VEE 196
>> +#define TOUCH_REPORT_GESTURE_TRIANGLE 197
>> +#define TOUCH_REPORT_GESTURE_INFO 198
>> +#define TOUCH_REPORT_GESTURE_COORDINATE 199
>> +#define TOUCH_REPORT_CUSTOMER_GRIP_INFO 203
> 
> I don't think all these are used. Also, could we align values on the
> same column please?

Yes will do
> 
>> +
>> +struct tcm_message_header {
>> +	u8 marker;
>> +	u8 code;
>> +} __packed;
> 
> I don't think this needs to be packed.

Ack
> 
>> +
>> +/* header + 2 bytes (which are length of data depending on report code) */
>> +#define REPORT_PEAK_LEN (sizeof(struct tcm_message_header) + 2)
>> +
>> +struct tcm_cmd {
>> +	u8 cmd;
>> +	u16 length;
>> +	u8 data[];
>> +};
>> +
>> +struct tcm_identification {
>> +	struct tcm_message_header header;
>> +	u16 length;
>> +	u8 version;
>> +	u8 mode;
>> +	char part_number[16];
>> +	u8 build_id[4];
>> +	u8 max_write_size[2];
>> +} __packed;
>> +
>> +struct tcm_app_info {
>> +	struct tcm_message_header header;
>> +	u16 length;
> 
> On-wire data needs to be annotated with proper endiannes (__le16 or
> __be16) and converted to CPU-endianness before use.

Ah, ok, will do.
> 
>> +	u8 version[2];
>> +	u16 status;
>> +	u8 static_config_size[2];
> 
> Should this be __le16 or __be16.
> 
>> +	u8 dynamic_config_size[2];
>> +	u8 app_config_start_write_block[2];
>> +	u8 app_config_size[2];
>> +	u8 max_touch_report_config_size[2];
>> +	u8 max_touch_report_payload_size[2];
>> +	char customer_config_id[16];
>> +	u16 max_x;
>> +	u16 max_y;
>> +	u8 max_objects[2];
>> +	u8 num_of_buttons[2];
>> +	u8 num_of_image_rows[2];
>> +	u8 num_of_image_cols[2];
>> +	u8 has_hybrid_data[2];
>> +} __packed;
>> +
>> +struct tcm_report_config_prop {
>> +	u8 id; /* TOUCH_OBJECT_* */
>> +	u8 bits; /* Size of the field in bits */
>> +};
>> +
>> +struct tcm_report_config_entry {
>> +	u8 foreach; /* TOUCH_FOREACH_* (and maybe other things?) */
>> +	int n_props;
>> +	const struct tcm_report_config_prop *props;
>> +};
>> +
>> +struct tcm_report_config {
>> +	int n_entries;
>> +	const struct tcm_report_config_entry *entries;
>> +};
>> +
>> +struct tcm_data {
>> +	struct i2c_client *client;
>> +	struct regmap *regmap;
>> +	struct input_dev *input;
>> +	struct touchscreen_properties prop;
>> +	struct gpio_desc *reset_gpio;
>> +	struct completion response;
>> +	struct regulator_bulk_data supplies[2];
>> +
>> +	/* annoying state */
>> +	u16 buf_size;
>> +	char buf[256];
>> +};
>> +
>> +static int tcm_send_cmd(struct tcm_data *tcm, struct tcm_cmd *cmd)
>> +{
>> +	struct i2c_client *client = tcm->client;
>> +	struct i2c_msg msg;
>> +	int ret;
>> +
>> +	dev_dbg(&client->dev, "sending command %#x\n", cmd->cmd);
>> +
>> +	msg.addr = client->addr;
>> +	msg.flags = 0;
>> +	msg.len = 1 + cmd->length;
>> +	msg.buf = (u8 *)cmd;
>> +
>> +	ret = i2c_transfer(client->adapter, &msg, 1);
>> +	if (ret == 1)
>> +		return 0;
>> +	else if (ret < 0)
>> +		return ret;
>> +	else
>> +		return -EIO;
>> +}
>> +
>> +static int tcm_send_cmd_noargs(struct tcm_data *tcm, u8 cmd)
>> +{
>> +	struct tcm_cmd c = {
>> +		.cmd = cmd,
>> +		.length = 0,
>> +	};
>> +
>> +	return tcm_send_cmd(tcm, &c);
>> +}
>> +
>> +static int tcm_recv_report(struct tcm_data *tcm,
>> +			   void *buf, size_t length)
>> +{
>> +	struct i2c_client *client = tcm->client;
>> +	struct i2c_msg msg;
>> +	int ret;
>> +
>> +	msg.addr = client->addr;
>> +	msg.flags = I2C_M_RD;
>> +	msg.len = length;
>> +	msg.buf = buf;
>> +
>> +	ret = i2c_transfer(client->adapter, &msg, 1);
>> +	if (ret == 1)
>> +		return 0;
>> +	else if (ret < 0)
>> +		return ret;
>> +	else
>> +		return -EIO;
>> +}
>> +
>> +static int tcm_read_message(struct tcm_data *tcm, u8 cmd, void *buf, size_t length)
>> +{
>> +	int ret;
>> +
>> +	reinit_completion(&tcm->response);
>> +	ret = tcm_send_cmd_noargs(tcm, cmd);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = wait_for_completion_timeout(&tcm->response, msecs_to_jiffies(1000));
>> +	if (ret == 0)
>> +		return -ETIMEDOUT;
>> +
>> +	if (buf) {
>> +		if (length > tcm->buf_size) {
>> +			dev_warn(&tcm->client->dev, "expected %zu bytes, got %u\n",
>> +				 length, tcm->buf_size);
>> +		}
>> +		length = min(tcm->buf_size, length);
>> +		memcpy(buf, tcm->buf, length);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void tcm_power_off(void *data)
>> +{
>> +	struct tcm_data *tcm = data;
>> +
>> +	disable_irq(tcm->client->irq);
>> +	regulator_bulk_disable(ARRAY_SIZE(tcm->supplies), tcm->supplies);
>> +}
>> +
>> +static int tcm_input_open(struct input_dev *dev)
>> +{
>> +	struct tcm_data *tcm = input_get_drvdata(dev);
>> +
>> +	return i2c_smbus_write_byte(tcm->client, TCM_ENABLE_REPORT);
>> +}
>> +
>> +static void tcm_input_close(struct input_dev *dev)
>> +{
>> +	struct tcm_data *tcm = input_get_drvdata(dev);
>> +	int ret;
>> +
>> +	ret = i2c_smbus_write_byte(tcm->client, TCM_DISABLE_REPORT);
>> +	if (ret)
>> +		dev_err(&tcm->client->dev, "failed to turn off sensing\n");
>> +}
>> +
>> +/*
>> + * The default report config looks like this:
>> + *
>> + * a5 01 80 00 11 08 1e 08 0f 01 04 01 06 04 07 04
>> + * 08 0c 09 0c 0a 08 0b 08 0c 08 0d 10 0e 10 03 00
>> + * 00 00
>> + *
>> + * a5 01 80 00 - HEADER + length
>> + *
>> + * 11 08 - TOUCH_FRAME_RATE (8 bits)
>> + * 30 08 - UNKNOWN (8 bits)
>> + * 0f 01 - TOUCH_0D_BUTTONS_STATE (1 bit)
>> + * 04 01 - TOUCH_PAD_TO_NEXT_BYTE (7 bits - padding)
>> + * 06 04 - TOUCH_OBJECT_N_INDEX (4 bits)
>> + * 07 04 - TOUCH_OBJECT_N_CLASSIFICATION (4 bits)
>> + * 08 0c - TOUCH_OBJECT_N_X_POSITION (12 bits)
>> + * 09 0c - TOUCH_OBJECT_N_Y_POSITION (12 bits)
>> + * 0a 08 - TOUCH_OBJECT_N_Z (8 bits)
>> + * 0b 08 - TOUCH_OBJECT_N_X_WIDTH (8 bits)
>> + * 0c 08 - TOUCH_OBJECT_N_Y_WIDTH (8 bits)
>> + * 0d 10 - TOUCH_OBJECT_N_TX_POSITION_TIXELS (16 bits) ??
>> + * 0e 10 - TOUCH_OBJECT_N_RX_POSITION_TIXELS (16 bits) ??
>> + * 03 00 - TOUCH_FOREACH_END (0 bits)
>> + * 00 00 - TOUCH_END (0 bits)
>> + *
>> + * Since we only support this report config, we just hardcode the format below.
>> + * To support additional report configs, we would need to parse the config and
>> + * use it to parse the reports dynamically.
>> + */
>> +
>> +struct tcm_default_report_data {
>> +	u8 fps;
>> +	struct {
>> +		u8 unknown;
>> +		u8 buttons;
>> +		u8 idx : 4;
>> +		u8 classification : 4;
>> +		u16 x : 12;
>> +		u16 y : 12;
> 
> This will be a mess on big endian. Please no bitfields. Use normally
> sized fields (u8, u16, etc) and masks/shifts to get data.

argh! yeah, I'll go do this properly XD
> 
>> +		u8 z;
>> +		u8 width_x;
>> +		u8 width_y;
>> +		u8 tx;
>> +		u8 rx;
>> +	} __packed points[];
>> +} __packed;
>> +
>> +static int tcm_handle_touch_report(struct tcm_data *tcm, char *buf, size_t len)
>> +{
>> +	struct tcm_default_report_data *data;
>> +
>> +	buf += REPORT_PEAK_LEN;
>> +	len -= REPORT_PEAK_LEN;
>> +
>> +	dev_dbg(&tcm->client->dev, "touch report len %zu\n", len);
>> +	if ((len - 1) % 11)
>> +		dev_err(&tcm->client->dev, "invalid touch report length\n");
>> +
>> +	data = (struct tcm_default_report_data *)buf;
>> +
>> +	/* We don't need to report releases because we have INPUT_MT_DROP_UNUSED */
>> +	for (int i = 0; i < (len - 1) / 11; i++) {
>> +		u8 major_width, minor_width;
>> +
>> +		minor_width = data->points[i].width_x;
>> +		major_width = data->points[i].width_y;
>> +
>> +		if (minor_width > major_width)
>> +			swap(major_width, minor_width);
>> +
>> +		dev_dbg(&tcm->client->dev, "touch report: idx %u x %u y %u\n",
>> +			data->points[i].idx, data->points[i].x, data->points[i].y);
>> +		input_mt_slot(tcm->input, data->points[i].idx);
>> +		input_mt_report_slot_state(tcm->input, MT_TOOL_FINGER, true);
>> +
>> +		input_report_abs(tcm->input, ABS_MT_POSITION_X, data->points[i].x);
>> +		input_report_abs(tcm->input, ABS_MT_POSITION_Y, data->points[i].y);
> 
> touchscreen_report_pos(...) instead of the 2 above so that rotation/axis
> swap will be handled properly.

Oh nice, thannks
> 
>> +		input_report_abs(tcm->input, ABS_MT_TOUCH_MAJOR, major_width);
>> +		input_report_abs(tcm->input, ABS_MT_TOUCH_MINOR, minor_width);
>> +		input_report_abs(tcm->input, ABS_MT_PRESSURE, data->points[i].z);
>> +	}
>> +
>> +	input_mt_sync_frame(tcm->input);
>> +	input_sync(tcm->input);
>> +
>> +	return 0;
>> +}
>> +
>> +static irqreturn_t tcm_report_irq(int irq, void *data)
>> +{
>> +	struct tcm_data *tcm = data;
>> +	struct tcm_message_header *header;
>> +	char buf[256];
>> +	u16 len;
>> +	int ret;
>> +
>> +	header = (struct tcm_message_header *)buf;
>> +	ret = tcm_recv_report(tcm, buf, sizeof(buf));
>> +	if (ret) {
>> +		dev_err(&tcm->client->dev, "failed to read report: %d\n", ret);
>> +		return IRQ_HANDLED;
>> +	}
>> +
>> +	switch (header->code) {
>> +	case REPORT_OK:
>> +	case REPORT_IDENTIFY:
>> +	case REPORT_TOUCH:
>> +	case REPORT_DELTA:
>> +	case REPORT_RAW:
>> +	case REPORT_DEBUG:
>> +	case REPORT_TOUCH_HOLD:
>> +		break;
>> +	default:
>> +		dev_dbg(&tcm->client->dev, "Ignoring report %#x\n", header->code);
>> +		return IRQ_HANDLED;
>> +	}
>> +
>> +	/* Not present for REPORT_CONTINUED_READ */
>> +	len = get_unaligned_le16(buf + sizeof(*header));
>> +
>> +	dev_dbg(&tcm->client->dev, "report %#x len %u\n", header->code, len);
>> +	print_hex_dump_bytes("report: ", DUMP_PREFIX_OFFSET, buf,
>> +			     min(sizeof(buf), len + sizeof(*header)));
>> +
>> +	if (len > sizeof(buf) - sizeof(*header)) {
>> +		dev_err(&tcm->client->dev, "report too long\n");
>> +		return IRQ_HANDLED;
>> +	}
>> +
>> +	/* Check if this is a read response or an indication. For indications
>> +	 * (user touched the screen) we just parse the report directly.
>> +	 */
>> +	if (completion_done(&tcm->response) && header->code == REPORT_TOUCH) {
>> +		tcm_handle_touch_report(tcm, buf, len + sizeof(*header));
>> +		return IRQ_HANDLED;
>> +	}
>> +
>> +	tcm->buf_size = len + sizeof(*header);
>> +	memcpy(tcm->buf, buf, len + sizeof(*header));
>> +	complete(&tcm->response);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static int tcm_hw_init(struct tcm_data *tcm, u16 *max_x, u16 *max_y)
>> +{
>> +	int ret;
>> +	struct tcm_identification id = { 0 };
>> +	struct tcm_app_info app_info = { 0 };
>> +
>> +	/*
>> +	 * Tell the firmware to start up. After starting it sends an IDENTIFY report, which
>> +	 * we treat like a response to this message even though it's technically a new report.
>> +	 */
>> +	ret = tcm_read_message(tcm, TCM_RUN_APPLICATION_FIRMWARE, &id, sizeof(id));
>> +	if (ret) {
>> +		dev_err(&tcm->client->dev, "failed to identify device: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	dev_dbg(&tcm->client->dev, "Synaptics TCM %s v%d mode %d\n",
>> +		id.part_number, id.version, id.mode);
>> +	if (id.mode != MODE_APPLICATION) {
>> +		/* We don't support firmware updates or anything else */
>> +		dev_err(&tcm->client->dev, "Device is not in application mode\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	do {
>> +		msleep(20);
>> +		ret = tcm_read_message(tcm, TCM_GET_APPLICATION_INFO, &app_info, sizeof(app_info));
>> +		if (ret) {
>> +			dev_err(&tcm->client->dev, "failed to get application info: %d\n", ret);
>> +			return ret;
>> +		}
>> +	} while (app_info.status == APP_STATUS_BOOTING || app_info.status == APP_STATUS_UPDATING);
>> +
>> +	dev_dbg(&tcm->client->dev, "Application firmware v%d.%d (customer '%s') status %d\n",
>> +		 app_info.version[0], app_info.version[1], app_info.customer_config_id,
>> +		 app_info.status);
>> +
>> +	*max_x = app_info.max_x;
>> +	*max_y = app_info.max_y;
>> +
>> +	return 0;
>> +}
>> +
>> +static int tcm_power_on(struct tcm_data *tcm)
>> +{
>> +	int ret;
>> +
>> +	ret = regulator_bulk_enable(ARRAY_SIZE(tcm->supplies),
>> +				    tcm->supplies);
>> +	if (ret)
>> +		return ret;
>> +
>> +	gpiod_set_value(tcm->reset_gpio, false);
>> +	usleep_range(10000, 11000);
>> +	gpiod_set_value(tcm->reset_gpio, true);
> 
> Here you have reset GPIO asserted, which means that the controller will
> stay in reset state indefinitely.
> 
> gpiod API operates on logical states (active/inactive) and performs
> conversion to physical state (LOW/HIGH) internally.
> 
> Also we should use gpiod_set_value_cansleep() unless we are in atomic
> context.

Ahh yes, this is all inverted, thanks.
> 
>> +	usleep_range(80000, 81000);
>> +
>> +	return 0;
>> +}
>> +
>> +static int tcm_probe(struct i2c_client *client)
>> +{
>> +	struct tcm_data *tcm;
>> +	struct tcm_report_config __maybe_unused report_config;
> 
> It is definitely not used, there no "maybe" about it.
> 
>> +	u16 max_x, max_y;
>> +	int ret;
> 
> Call this and similar variables holding error code "error" please.
> 
>> +
>> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
>> +						I2C_FUNC_SMBUS_BYTE_DATA |
>> +						I2C_FUNC_SMBUS_I2C_BLOCK))
>> +		return -ENODEV;
>> +
>> +	tcm = devm_kzalloc(&client->dev, sizeof(struct tcm_data), GFP_KERNEL);
> 
> sizeof(*tcm)
> 
>> +	if (!tcm)
>> +		return -ENOMEM;
>> +
>> +	i2c_set_clientdata(client, tcm);
>> +	tcm->client = client;
>> +
>> +	init_completion(&tcm->response);
>> +
>> +	tcm->supplies[0].supply = "vdd";
>> +	tcm->supplies[1].supply = "vcc";
>> +	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(tcm->supplies),
>> +				      tcm->supplies);
>> +	if (ret)
>> +		return ret;
>> +
>> +	tcm->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
> 
> Do all designs require GPIO line be specified? Can it be made optional?

I have no idea, no access to docs or much prior art. Maybe best to wait 
until someone shows up with a device that doesn't use it?
> 
>> +
>> +	ret = devm_add_action_or_reset(&client->dev, tcm_power_off,
>> +				       tcm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = tcm_power_on(tcm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
>> +					tcm_report_irq,
>> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> 
> Please do not hardcode trigger (besides IRQF_ONESHOT), let platform
> decide.
> 

Right, this is a leftover from downstream code I guess, will fix.

> Also interrupt is hot there, are you sure we will not try to report
> input events for not-yet-allocated input device if someone is thouching
> the device at this point?

Hmm, I guess this could happen after tcm_hw_init() and before everything 
is initialised, but it won't happen until we send the 
TCM_RUN_APPLICATION_FIRMWARE command. I think deferring the 
tcm_hw_init() call until after we set things up should be acceptable here.
> 
>> +					"synaptics_tcm_report", tcm);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	ret = tcm_hw_init(tcm, &max_x, &max_y);
>> +	if (ret) {
>> +		dev_err(&client->dev, "failed to initialize hardware\n");
>> +		return ret;
>> +	}
>> +
>> +	tcm->input = devm_input_allocate_device(&client->dev);
>> +	if (!tcm->input)
>> +		return -ENOMEM;
>> +
>> +	tcm->input->name = "Synaptics TCM Oncell Touchscreen";
>> +	tcm->input->id.bustype = BUS_I2C;
>> +	tcm->input->open = tcm_input_open;
>> +	tcm->input->close = tcm_input_close;
>> +
>> +	input_set_abs_params(tcm->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
>> +	input_set_abs_params(tcm->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
>> +	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
>> +	input_set_abs_params(tcm->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
>> +	input_set_abs_params(tcm->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
>> +
>> +	touchscreen_parse_properties(tcm->input, true, &tcm->prop);
>> +
>> +	ret = input_mt_init_slots(tcm->input, 10, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
>> +	if (ret)
>> +		return ret;
>> +
>> +	input_set_drvdata(tcm->input, tcm);
>> +
>> +	ret = input_register_device(tcm->input);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id syna_driver_ids[] = {
>> +	{
>> +		.compatible = "syna,s3908",
>> +	},
>> +	{}
>> +};
>> +MODULE_DEVICE_TABLE(of, syna_driver_ids);
>> +
>> +static const struct i2c_device_id syna_i2c_ids[] = {
>> +	{ "synaptics-tcm", 0 },
>> +	{ }
>> +};
>> +
>> +MODULE_DEVICE_TABLE(i2c, syna_i2c_ids);
>> +
>> +static struct i2c_driver syna_i2c_driver = {
>> +	.probe	= tcm_probe,
>> +	.id_table	= syna_i2c_ids,
>> +	.driver	= {
>> +	.name	= "synaptics-tcm",
>> +	.of_match_table = syna_driver_ids,
>> +	},
>> +};
>> +
>> +module_i2c_driver(syna_i2c_driver);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Frieder Hannenheim <frieder.hannenheim@proton.me>");
>> +MODULE_AUTHOR("Caleb Connolly <caleb@postmarketos.org>");
>> +MODULE_DESCRIPTION("A driver for Synaptics TCM Oncell Touchpanels");
>> +
>>
>> -- 
>> 2.45.0
>>
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab)
  2024-06-26  4:16   ` Bjorn Andersson
@ 2024-06-27 23:40     ` Caleb Connolly
  0 siblings, 0 replies; 25+ messages in thread
From: Caleb Connolly @ 2024-06-27 23:40 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Neil Armstrong, Jessica Zhang, David Airlie, Daniel Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Dmitry Torokhov, Konrad Dybcio,
	Henrik Rydberg, dri-devel, devicetree, linux-input, linux-arm-msm,
	~postmarketos/upstreaming, Frieder Hannenheim



On 26/06/2024 06:16, Bjorn Andersson wrote:
> On Mon, Jun 24, 2024 at 03:30:31AM GMT, Caleb Connolly wrote:
>> Initial support for USB, UFS, touchscreen, panel, wifi, and bluetooth.
>>
> 
> Nice.
> 
>> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
> [..]
>> +	vph_pwr: vph-pwr-regulator {
> 
> Please keep nodes sorted by address, then node name, then label (as
> applicable). Perhaps making the -regulator suffix a regulator- prefix
> instead (to keep them grouped).
> 
>> +		compatible = "regulator-fixed";
>> +		regulator-name = "vph_pwr";
>> +		regulator-min-microvolt = <3700000>;
>> +		regulator-max-microvolt = <3700000>;
>> +		regulator-always-on;
>> +	};
>> +
>> +	vreg_s4a_1p8: vreg-s4a-1p8 {
>> +		compatible = "regulator-fixed";
>> +		regulator-name = "vreg_s4a_1p8";
>> +		regulator-min-microvolt = <1800000>;
>> +		regulator-max-microvolt = <1800000>;
>> +		regulator-always-on;
>> +	};
> [..]
>> +&adsp {
>> +	status = "okay";
> 
> Per Documentation/devicetree/bindings/dts-coding-style.rst please keep
> "status" as last property in your nodes.
> 
>> +	firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
>> +};
>> +
> [..]
>> +&mdss_dsi0 {
>> +	status = "okay";
>> +	vdda-supply = <&vreg_l9a_1p2>;
>> +
>> +	display_panel: panel@0 {
>> +		reg = <0>;
>> +		vddio-supply = <&vreg_l14a_1p8>;
>> +		vdd-supply = <&vreg_l11c_3p3>;
>> +		avdd-supply = <&panel_avdd_5p5>;
> 
> How do you know that the panel will have these properties, when you
> don't give it a compatible here? Not a strong objection, but perhaps
> this should be pushed out?

I'll double check, I assumed all the panels on all the variants of this 
platform used the same regulators (the 8 and 8 pro as well) but i could 
be mistaken.
> 
>> +		/* FIXME: There is a bug somewhere in the display stack and it isn't
>> +		 * possible to get the panel to a working state after toggling reset.
>> +		 * At best it just shows one or more vertical red lines. So for now
>> +		 * let's skip the reset GPIO.
>> +		 */
>> +		// reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
>> +
>> +		pinctrl-0 = <&panel_reset_pins &panel_vsync_pins &panel_vout_pins>;
>> +		pinctrl-names = "default";
>> +
>> +		status = "disabled";
>> +
>> +		port {
>> +			panel_in_0: endpoint {
>> +				remote-endpoint = <&mdss_dsi0_out>;
>> +			};
>> +		};
>> +	};
>> +
>> +};
> [..]
>> +&pm8150_gpios {
>> +	gpio-reserved-ranges = <2 1>, <4 1>, <8 1>;
> 
> How come?

I'll check this, I forgot to make a note originally, but I do remember 
that I was only able to figure out which GPIOs were causing the 
crashdump by squinting at the magic writing in the tz log (one of the 
values corresponds to to a register address iirc).
> 
>> +};
>> +
> [..]
>> +&tlmm {
>> +	gpio-reserved-ranges = <28 4>, <40 4>;
>> +
>> +	bt_en_state: bt-default-state {
>> +		pins = "gpio21";
>> +		function = "gpio";
>> +		drive-strength = <16>;
>> +		output-low;
>> +		bias-pull-up;
>> +	};
>> +
>> +	wlan_en_state: wlan-default-state {
>> +		wlan-en-pins {
> 
> Perhaps flatten this? >
>> +			pins = "gpio20";
>> +			function = "gpio";
>> +
>> +			drive-strength = <16>;
>> +			output-low;
>> +			bias-pull-up;
>> +		};
>> +	};
>> +
> [..]
>> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
> [..]
>> +&i2c13 {
> [..]
>> +};
>> +
>> +&display_panel {
> 
> 'd' < 'i'

Ack, thanks for the review :)
> 
> Regards,
> Bjorn
> 
>> +	compatible = "samsung,amb655x";
>> +	status = "okay";
>> +};
>>
>> -- 
>> 2.45.0
>>

Kind regards,
Caleb (they/them)

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2024-06-27 23:40 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-24  1:30 [PATCH 0/7] qcom: initial support for the OnePlus 8T Caleb Connolly
2024-06-24  1:30 ` [PATCH 1/7] dt-bindings: panel: document Samsung AMB655X Caleb Connolly
2024-06-24  1:33   ` Caleb Connolly
2024-06-27 22:12   ` Rob Herring
2024-06-27 23:24     ` Caleb Connolly
2024-06-24  1:30 ` [PATCH 2/7] dt-bindings: input: touchscreen: document synaptics TCM oncell Caleb Connolly
2024-06-24  2:42   ` Rob Herring (Arm)
2024-06-24  7:25   ` Dmitry Torokhov
2024-06-24  1:30 ` [PATCH 3/7] dt-bindings: arm: qcom: add OnePlus 8 series Caleb Connolly
2024-06-24  4:52   ` Krzysztof Kozlowski
2024-06-24 20:40   ` Rob Herring
2024-06-24  1:30 ` [PATCH 4/7] drm: mipi: add mipi_dsi_generic_write_multi_type() Caleb Connolly
2024-06-24  5:21   ` Dmitry Baryshkov
2024-06-24  1:30 ` [PATCH 5/7] drm/panel: add driver for samsung amb655x Caleb Connolly
2024-06-24  5:31   ` Dmitry Baryshkov
2024-06-24  1:30 ` [PATCH 6/7] Input: touchscreen: add Synaptics TCM oncell S3908 Caleb Connolly
2024-06-24  7:42   ` Dmitry Torokhov
2024-06-27 23:35     ` Caleb Connolly
2024-06-24  1:30 ` [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab) Caleb Connolly
2024-06-26  4:16   ` Bjorn Andersson
2024-06-27 23:40     ` Caleb Connolly
2024-06-26  9:43   ` Konrad Dybcio
2024-06-24  5:18 ` [PATCH 0/7] qcom: initial support for the OnePlus 8T Dmitry Baryshkov
2024-06-24 11:32   ` Caleb Connolly
2024-06-24 11:33     ` Dmitry Baryshkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).