Index | Thread | Search

From:
Marcus Glocker <marcus@nazgul.ch>
Subject:
Touchscreen support for the Samsung Galaxy Book4 Edge
To:
tech@openbsd.org
Date:
Thu, 21 May 2026 22:01:07 +0200

Download raw body.

Thread
This diff enables touchscreen support for the Samsung Galaxy Book4
Edge.  For now we need to stick with polling since we can't figure
out the GPIO pin for the touchscreen interrupts.

In a summary, those are the changes we had to do in the different
areas:

- DTS: Power up the device and declare it on the I2C bus; no interrupt
  line, so it runs in polling mode (we can't determine the IRQ pin).

- hidmt: Teach the shared multitouch layer to handle absolute
  touchscreens, not just touchpads.

- imt: Recognize and claim the panel as a touchscreen so it's driven by
  the multitouch layer instead of being mistaken for a plain mouse.

- ihidev: Synthesize the "finger lifted" event in polling mode, since
  the device signals release only by going silent.

If you have an i2c-Precision touchpad or an i2c-HID keyboard, please
test it still works.

Please note that the diff doesn't introduce multi-finger gestures,
just absolute pointer support (tap/drag).

Otherwise, feedback, OKs?


Index: sys/dev/hid/hidmt.c
===================================================================
RCS file: /cvs/src/sys/dev/hid/hidmt.c,v
diff -u -p -u -p -r1.16 hidmt.c
--- sys/dev/hid/hidmt.c	21 Jul 2025 21:46:40 -0000	1.16
+++ sys/dev/hid/hidmt.c	21 May 2026 19:02:12 -0000
@@ -203,8 +203,10 @@ hidmt_setup(struct device *self, struct 
 				mt->sc_resy = hidmt_get_resolution(&h);
 			}
 			break;
-		case HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH):
 		case HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIDENCE):
+			mt->sc_flags |= HIDMT_HASCONFIDENCE;
+			/* FALLTHROUGH */
+		case HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH):
 		case HID_USAGE2(HUP_DIGITIZERS, HUD_WIDTH):
 		case HID_USAGE2(HUP_DIGITIZERS, HUD_HEIGHT):
 		case HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTID):
@@ -239,7 +241,17 @@ hidmt_setup(struct device *self, struct 
 		goto fail;
 	}
 
-	if (hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT_TOUCHPAD)) {
+	/* default touchscreen calibration to the device's reported range */
+	mt->sc_calibminx = mt->sc_minx;
+	mt->sc_calibmaxx = mt->sc_maxx;
+	mt->sc_calibminy = mt->sc_miny;
+	mt->sc_calibmaxy = mt->sc_maxy;
+	mt->sc_calibswapxy = 0;
+
+	/* only switch input mode if there is a config report (touchpads) */
+	if (mt->sc_rep_config != 0 &&
+	    hidmt_set_input_mode(mt, (mt->sc_flags & HIDMT_TOUCHSCREEN) ?
+	    HIDMT_INPUT_MODE_MT_TOUCHSCREEN : HIDMT_INPUT_MODE_MT_TOUCHPAD)) {
 		printf("\n%s: switch to multitouch mode failed\n",
 		    self->dv_xname);
 		goto fail;
@@ -268,9 +280,14 @@ hidmt_configure(struct hidmt *mt)
 		return;
 
 	hw = wsmouse_get_hw(mt->sc_wsmousedev);
-	hw->type = WSMOUSE_TYPE_TOUCHPAD;
-	hw->hw_type = (mt->sc_clickpad
-	    ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD);
+	if (mt->sc_flags & HIDMT_TOUCHSCREEN) {
+		hw->type = WSMOUSE_TYPE_TPANEL;
+		hw->hw_type = WSMOUSEHW_TPANEL;
+	} else {
+		hw->type = WSMOUSE_TYPE_TOUCHPAD;
+		hw->hw_type = (mt->sc_clickpad
+		    ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD);
+	}
 	hw->x_min = mt->sc_minx;
 	hw->x_max = mt->sc_maxx;
 	hw->y_min = mt->sc_miny;
@@ -287,9 +304,13 @@ hidmt_attach(struct hidmt *mt, const str
 {
 	struct wsmousedev_attach_args a;
 
-	printf(": %spad, %d contact%s\n",
-	    (mt->sc_clickpad ? "click" : "touch"), mt->sc_num_contacts,
-	    (mt->sc_num_contacts == 1 ? "" : "s"));
+	if (mt->sc_flags & HIDMT_TOUCHSCREEN)
+		printf(": touchscreen, %d contact%s\n", mt->sc_num_contacts,
+		    (mt->sc_num_contacts == 1 ? "" : "s"));
+	else
+		printf(": %spad, %d contact%s\n",
+		    (mt->sc_clickpad ? "click" : "touch"), mt->sc_num_contacts,
+		    (mt->sc_num_contacts == 1 ? "" : "s"));
 
 	a.accessops = ops;
 	a.accesscookie = mt->sc_device;
@@ -455,11 +476,30 @@ hidmt_input(struct hidmt *mt, uint8_t *d
 		seencontacts++;
 	}
 
+	/* no physical buttons on a touchscreen: a finger down is a click */
+	if (mt->sc_flags & HIDMT_TOUCHSCREEN)
+		buttons = tips ? 1 : 0;
+
 	s = spltty();
 	if (mt->sc_buttons != buttons) {
 		wsmouse_buttons(mt->sc_wsmousedev, buttons);
 		mt->sc_buttons = buttons;
 	}
+
+	/* all fingers up: release exactly the slots we recorded as down */
+	if ((mt->sc_flags & HIDMT_TOUCHSCREEN) && tips == 0) {
+		for (i = 0; i < HIDMT_MAX_CONTACTS; i++) {
+			if (!(mt->sc_touches & (1 << i)))
+				continue;
+			mt->sc_contacts[i].seen = 0;
+			wsmouse_mtstate(mt->sc_wsmousedev, i, 0, 0, 0);
+		}
+		mt->sc_touches = 0;
+		wsmouse_input_sync(mt->sc_wsmousedev);
+		splx(s);
+		return;
+	}
+
 	for (i = 0; i < HIDMT_MAX_CONTACTS; i++) {
 		if (!mt->sc_contacts[i].seen)
 			continue;
@@ -480,13 +520,19 @@ hidmt_input(struct hidmt *mt, uint8_t *d
 		    mt->sc_contacts[i].height,
 		    mt->sc_buttons));
 
-		if (mt->sc_contacts[i].tip && !mt->sc_contacts[i].confidence)
+		if ((mt->sc_flags & HIDMT_HASCONFIDENCE) &&
+		    mt->sc_contacts[i].tip && !mt->sc_contacts[i].confidence)
 			continue;
 
 		/* Report width as pressure. */
 		z = (mt->sc_contacts[i].tip
 		    ? imax(mt->sc_contacts[i].width, 50) : 0);
 
+		if (z > 0)
+			mt->sc_touches |= (1 << i);
+		else
+			mt->sc_touches &= ~(1 << i);
+
 		wsmouse_mtstate(mt->sc_wsmousedev,
 		    i, mt->sc_contacts[i].x, mt->sc_contacts[i].y, z);
 	}
@@ -520,12 +566,20 @@ hidmt_ioctl(struct hidmt *mt, u_long cmd
 		break;
 	}
 
+	case WSMOUSEIO_SCALIBCOORDS:
+		mt->sc_calibminx = wsmc->minx;
+		mt->sc_calibmaxx = wsmc->maxx;
+		mt->sc_calibminy = wsmc->miny;
+		mt->sc_calibmaxy = wsmc->maxy;
+		mt->sc_calibswapxy = wsmc->swapxy;
+		break;
+
 	case WSMOUSEIO_GCALIBCOORDS:
-		wsmc->minx = mt->sc_minx;
-		wsmc->maxx = mt->sc_maxx;
-		wsmc->miny = mt->sc_miny;
-		wsmc->maxy = mt->sc_maxy;
-		wsmc->swapxy = 0;
+		wsmc->minx = mt->sc_calibminx;
+		wsmc->maxx = mt->sc_calibmaxx;
+		wsmc->miny = mt->sc_calibminy;
+		wsmc->maxy = mt->sc_calibmaxy;
+		wsmc->swapxy = mt->sc_calibswapxy;
 		wsmc->resx = mt->sc_resx;
 		wsmc->resy = mt->sc_resy;
 		break;
@@ -593,4 +647,45 @@ hidmt_find_winptp_reports(const void *de
 	    nitems(cap_usages), cap_usages, ptp_collections);
 
 	return (*input_rid > 0 && *config_rid > 0 && *cap_rid > 0);
+}
+
+/* Like hidmt_find_winptp_reports() but for a HUD_TOUCHSCREEN: no
+ * Confidence usage, and the Input Mode config report is optional. */
+int
+hidmt_find_touchscreen_reports(const void *desc, int len, int *input_rid,
+    int *config_rid, int *cap_rid)
+{
+	static int32_t ts_collections[] = {
+		HID_USAGE2(HUP_DIGITIZERS, HUD_FINGER), 0
+	};
+	static int32_t input_usages[] = {
+		/* report-level */
+		HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT),
+		/* contact-level */
+		HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
+		HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
+		HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH),
+		HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTID),
+	};
+	static int32_t cfg_usages[] = {
+		HID_USAGE2(HUP_DIGITIZERS, HUD_INPUT_MODE),
+	};
+	static int32_t cap_usages[] = {
+		HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACT_MAX),
+	};
+
+	*input_rid = hid_find_report(desc, len, hid_input,
+	    HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN),
+	    nitems(input_usages), input_usages, ts_collections);
+	*cap_rid = hid_find_report(desc, len, hid_feature,
+	    HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN),
+	    nitems(cap_usages), cap_usages, ts_collections);
+
+	*config_rid = hid_find_report(desc, len, hid_feature,
+	    HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIG),
+	    nitems(cfg_usages), cfg_usages, ts_collections);
+	if (*config_rid < 0)
+		*config_rid = 0;
+
+	return (*input_rid > 0 && *cap_rid > 0);
 }
Index: sys/dev/hid/hidmtvar.h
===================================================================
RCS file: /cvs/src/sys/dev/hid/hidmtvar.h,v
diff -u -p -u -p -r1.10 hidmtvar.h
--- sys/dev/hid/hidmtvar.h	28 Oct 2025 15:36:46 -0000	1.10
+++ sys/dev/hid/hidmtvar.h	21 May 2026 19:02:12 -0000
@@ -36,7 +36,9 @@ struct hidmt_contact {
 struct hidmt {
 	int		sc_enabled;
 	uint32_t	sc_flags;
-#define HIDMT_REVY	0x0001	/* Y-axis is reversed ("natural" scrolling) */
+#define HIDMT_REVY		0x0001	/* Y-axis is reversed ("natural" scrolling) */
+#define HIDMT_TOUCHSCREEN	0x0002	/* absolute touch panel, not a touchpad */
+#define HIDMT_HASCONFIDENCE	0x0004	/* device reports a Confidence usage */
 
 	struct device	*sc_device;
 	int		(*hidev_report_type_conv)(int);
@@ -61,9 +63,15 @@ struct hidmt {
 	int		sc_miny, sc_maxy;
 	int		sc_resx, sc_resy;
 
+	/* touchscreen calibration set via WSMOUSEIO_SCALIBCOORDS */
+	int		sc_calibminx, sc_calibmaxx;
+	int		sc_calibminy, sc_calibmaxy;
+	int		sc_calibswapxy;
+
 	struct hidmt_contact sc_contacts[HIDMT_MAX_CONTACTS];
 	int		sc_cur_contactcount;
 	int		sc_buttons;
+	uint32_t	sc_touches;	/* bitmap of slots currently down */
 };
 
 int	hidmt_set_input_mode(struct hidmt *, uint16_t);
@@ -78,3 +86,4 @@ void	hidmt_input(struct hidmt *, uint8_t
 int	hidmt_ioctl(struct hidmt *, u_long, caddr_t, int, struct proc *);
 int	hidmt_setup(struct device *, struct hidmt *, void *, int);
 int	hidmt_find_winptp_reports(const void *, int, int *, int *, int *);
+int	hidmt_find_touchscreen_reports(const void *, int, int *, int *, int *);
Index: sys/dev/i2c/ihidev.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v
diff -u -p -u -p -r1.41 ihidev.c
--- sys/dev/i2c/ihidev.c	28 Oct 2025 15:36:46 -0000	1.41
+++ sys/dev/i2c/ihidev.c	21 May 2026 19:02:12 -0000
@@ -142,6 +142,7 @@ ihidev_attach(struct device *parent, str
 	sc->sc_tag = ia->ia_tag;
 	sc->sc_addr = ia->ia_addr;
 	sc->sc_hid_desc_addr = ia->ia_size;
+	sc->sc_lastrepid = -1;
 
 	if (ihidev_hid_command(sc, I2C_HID_CMD_DESCR, NULL) ||
 	    ihidev_hid_desc_parse(sc)) {
@@ -159,10 +160,13 @@ ihidev_attach(struct device *parent, str
 
 	/* find largest report size and allocate memory for input buffer */
 	sc->sc_isize = letoh16(sc->hid_desc.wMaxInputLength);
+	sc->sc_repsizes = mallocarray(sc->sc_nrepid, sizeof(int),
+	    M_DEVBUF, M_WAITOK | M_ZERO);
 	for (repid = 0; repid < sc->sc_nrepid; repid++) {
 		repsz = hid_report_size(sc->sc_report, sc->sc_reportlen,
 		    hid_input, repid);
 		repsizes[repid] = repsz;
+		sc->sc_repsizes[repid] = repsz;
 		if (repsz > sc->sc_isize)
 			sc->sc_isize = repsz;
 		if (repsz != 0)
@@ -255,6 +259,9 @@ ihidev_detach(struct device *self, int f
 	if (sc->sc_report != NULL)
 		free(sc->sc_report, M_DEVBUF, sc->sc_reportlen);
 
+	if (sc->sc_repsizes != NULL)
+		free(sc->sc_repsizes, M_DEVBUF, sc->sc_nrepid * sizeof(int));
+
 	return (0);
 }
 
@@ -718,10 +725,21 @@ ihidev_intr(void *arg)
 	psize = sc->sc_ibuf[0] | sc->sc_ibuf[1] << 8;
 	if (psize <= 2 || psize > sc->sc_isize) {
 		if (sc->sc_poll) {
-			/*
-			 * TODO: all fingers are up, should we pass to hid
-			 * layer?
-			 */
+			/* empty packet: hand the last subdev a zeroed report
+			 * once so it releases its contacts (polled finger-up) */
+			int lrep = sc->sc_lastrepid;
+			int rsz;
+
+			if (lrep >= 0 && lrep < sc->sc_nrepid &&
+			    (scd = sc->sc_subdevs[lrep]) != NULL &&
+			    (scd->sc_state & IHIDEV_OPEN) && !sc->sc_dying) {
+				rsz = sc->sc_repsizes[lrep];
+				if (rsz > 0 && rsz <= sc->sc_isize) {
+					memset(sc->sc_ibuf, 0, rsz);
+					scd->sc_intr(scd, sc->sc_ibuf, rsz);
+				}
+				sc->sc_lastrepid = -1;
+			}
 			sc->sc_fastpoll = 0;
 			goto more_polling;
 		} else
@@ -770,8 +788,10 @@ ihidev_intr(void *arg)
 		return (1);
 	}
 
-	if (!sc->sc_dying)
+	if (!sc->sc_dying) {
+		sc->sc_lastrepid = rep;
 		scd->sc_intr(scd, p, psize);
+	}
 
 	if (sc->sc_poll && (fast != sc->sc_fastpoll)) {
 		DPRINTF(("%s: %s->%s polling\n", sc->sc_dev.dv_xname,
Index: sys/dev/i2c/ihidev.h
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v
diff -u -p -u -p -r1.11 ihidev.h
--- sys/dev/i2c/ihidev.h	7 Jan 2025 19:26:14 -0000	1.11
+++ sys/dev/i2c/ihidev.h	21 May 2026 19:02:12 -0000
@@ -85,6 +85,8 @@ struct ihidev_softc {
 
 	u_int		sc_isize;
 	u_char		*sc_ibuf;
+	int		sc_lastrepid;	/* report id of last non-empty input */
+	int		*sc_repsizes;	/* per-report input size, for poll path */
 
 	int		sc_refcnt;
 
Index: sys/dev/i2c/imt.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/imt.c,v
diff -u -p -u -p -r1.7 imt.c
--- sys/dev/i2c/imt.c	21 Jul 2025 21:46:40 -0000	1.7
+++ sys/dev/i2c/imt.c	21 May 2026 19:02:12 -0000
@@ -83,11 +83,15 @@ imt_match(struct device *parent, void *m
 	if (iha->reportid == IHIDEV_CLAIM_MULTIPLEID) {
 		ihidev_get_report_desc(iha->parent, &desc, &size);
 		if (hidmt_find_winptp_reports(desc, size,
+		    &input_rid, &conf_rid, &cap_rid) ||
+		    hidmt_find_touchscreen_reports(desc, size,
 		    &input_rid, &conf_rid, &cap_rid)) {
-			iha->claims[0] = input_rid;
-			iha->claims[1] = conf_rid;
-			iha->claims[2] = cap_rid;
-			iha->nclaims = 3;
+			/* a touchscreen may have no config (Input Mode) report */
+			iha->nclaims = 0;
+			iha->claims[iha->nclaims++] = input_rid;
+			if (conf_rid > 0)
+				iha->claims[iha->nclaims++] = conf_rid;
+			iha->claims[iha->nclaims++] = cap_rid;
 			return (IMATCH_DEVCLASS_DEVSUBCLASS);
 		}
 	}
@@ -108,13 +112,18 @@ imt_attach(struct device *parent, struct
 	sc->sc_hdev.sc_parent = iha->parent;
 
 	ihidev_get_report_desc(iha->parent, &desc, &size);
-	hidmt_find_winptp_reports(desc, size, &sc->sc_rep_input,
-	    &sc->sc_rep_config, &sc->sc_rep_cap);
 
 	memset(mt, 0, sizeof(sc->sc_mt));
 
-	/* assume everything has "natural scrolling" where Y axis is reversed */
-	mt->sc_flags = HIDMT_REVY;
+	if (hidmt_find_winptp_reports(desc, size, &sc->sc_rep_input,
+	    &sc->sc_rep_config, &sc->sc_rep_cap)) {
+		/* assume "natural scrolling" where the Y axis is reversed */
+		mt->sc_flags = HIDMT_REVY;
+	} else if (hidmt_find_touchscreen_reports(desc, size, &sc->sc_rep_input,
+	    &sc->sc_rep_config, &sc->sc_rep_cap)) {
+		/* an absolute touch panel maps 1:1, so do not reverse Y */
+		mt->sc_flags = HIDMT_TOUCHSCREEN;
+	}
 
 	mt->hidev_report_type_conv = ihidev_report_type_conv;
 	mt->hidev_get_report = imt_hidev_get_report;
Index: sysutils/firmware/arm64-qcom-dtb/Makefile
===================================================================
RCS file: /cvs/ports/sysutils/firmware/arm64-qcom-dtb/Makefile,v
diff -u -p -u -p -r1.29 Makefile
--- sysutils/firmware/arm64-qcom-dtb/Makefile	19 May 2026 04:47:35 -0000	1.29
+++ sysutils/firmware/arm64-qcom-dtb/Makefile	21 May 2026 19:32:13 -0000
@@ -1,6 +1,6 @@
 FW_DRIVER=	arm64-qcom-dtb
 FW_VER=		2.7
-REVISION=	1
+REVISION=	2
 
 DISTNAME=	devicetree-rebasing-6.17-dts
 
Index: sysutils/firmware/arm64-qcom-dtb/patches/patch-src_arm64_qcom_x1e80100-samsung-galaxy-book4-edge_dts
===================================================================
RCS file: /cvs/ports/sysutils/firmware/arm64-qcom-dtb/patches/patch-src_arm64_qcom_x1e80100-samsung-galaxy-book4-edge_dts,v
diff -u -p -u -p -r1.3 patch-src_arm64_qcom_x1e80100-samsung-galaxy-book4-edge_dts
--- sysutils/firmware/arm64-qcom-dtb/patches/patch-src_arm64_qcom_x1e80100-samsung-galaxy-book4-edge_dts	19 May 2026 04:47:35 -0000	1.3
+++ sysutils/firmware/arm64-qcom-dtb/patches/patch-src_arm64_qcom_x1e80100-samsung-galaxy-book4-edge_dts	21 May 2026 19:32:13 -0000
@@ -1,7 +1,7 @@
 Index: src/arm64/qcom/x1e80100-samsung-galaxy-book4-edge.dts
 --- src/arm64/qcom/x1e80100-samsung-galaxy-book4-edge.dts.orig
 +++ src/arm64/qcom/x1e80100-samsung-galaxy-book4-edge.dts
-@@ -0,0 +1,977 @@
+@@ -0,0 +1,988 @@
 +// SPDX-License-Identifier: BSD-3-Clause
 +/*
 + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
@@ -10,6 +10,7 @@ Index: src/arm64/qcom/x1e80100-samsung-g
 +/dts-v1/;
 +
 +#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 +#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 +
 +#include "x1e80100.dtsi"
@@ -181,6 +182,24 @@ Index: src/arm64/qcom/x1e80100-samsung-g
 +		regulator-always-on;
 +		regulator-boot-on;
 +	};
++
++	/* 3V3 rail powering the touchscreen, gated by pm8550ve_8 gpio6 */
++	vreg_misc_3p3: regulator-misc-3p3 {
++		compatible = "regulator-fixed";
++
++		regulator-name = "VREG_MISC_3P3";
++		regulator-min-microvolt = <3300000>;
++		regulator-max-microvolt = <3300000>;
++
++		gpio = <&pm8550ve_8_gpios 6 GPIO_ACTIVE_HIGH>;
++		enable-active-high;
++
++		pinctrl-0 = <&misc_3p3_reg_en>;
++		pinctrl-names = "default";
++
++		regulator-boot-on;
++		regulator-always-on;
++	};
 +};
 +
 +&apps_rsc {
@@ -572,26 +591,33 @@ Index: src/arm64/qcom/x1e80100-samsung-g
 +	};
 +};
 +
++/* GXTP7936 touchscreen, powered by vreg_misc_3p3.  No usable IRQ pin
++ * known, so ihidev(4) polls. */
 +&i2c8 {
 +	clock-frequency = <400000>;
 +
-+	status = "disabled";
++	status = "okay";
 +
 +	touchscreen@5d {
 +		compatible = "hid-over-i2c";
 +		reg = <0x5d>;
 +
 +		hid-descr-addr = <0x1>;
-+		/*
-+		 * Pin 51 is creating an interrupt storm.  Hence, choosing
-+		 * some other pin which just does nothing.  But obviously,
-+		 * the touchscreen won't work for now.
-+		 */
-+		 //interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>;
-+		interrupts-extended = <&tlmm 33 IRQ_TYPE_LEVEL_LOW>;
 +
-+		pinctrl-0 = <&ts0_default>;
-+		pinctrl-names = "default";
++		vdd-supply = <&vreg_misc_3p3>;
++	};
++};
++
++&pm8550ve_8_gpios {
++	misc_3p3_reg_en: misc-3p3-reg-en-state {
++		pins = "gpio6";
++		function = "normal";
++		bias-disable;
++		input-disable;
++		output-enable;
++		drive-push-pull;
++		power-source = <1>;	/* 1.8 V */
++		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
 +	};
 +};
 +
@@ -863,21 +889,6 @@ Index: src/arm64/qcom/x1e80100-samsung-g
 +		pins = "gpio3";
 +		function = "gpio";
 +		bias-disable;
-+	};
-+
-+	ts0_default: ts0-default-state {
-+		int-n-pins {
-+			pins = "gpio51";
-+			function = "gpio";
-+			bias-disable;
-+		};
-+
-+		reset-n-pins {
-+			pins = "gpio48";
-+			function = "gpio";
-+			output-high;
-+			drive-strength = <16>;
-+		};
 +	};
 +
 +	wcd_default: wcd-reset-n-active-state {