mirror of https://github.com/armbian/build.git
sm8250-6.11: add oneplus kebab patches
This commit is contained in:
parent
14314337da
commit
92bd238f83
|
@ -0,0 +1,106 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Connolly <caleb@postmarketos.org>
|
||||
Date: Sun, 30 Jun 2024 20:36:27 +0200
|
||||
Subject: drm: mipi: add mipi_dsi_generic_write_multi_type()
|
||||
|
||||
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 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/drm_mipi_dsi.c
|
||||
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
|
||||
@@ -820,6 +820,46 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
|
||||
}
|
||||
EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
|
||||
|
||||
+/**
|
||||
+ * mipi_dsi_generic_write_raw_multi() - transmit data using a generic write packet of
|
||||
+ * a specific type
|
||||
+ * @ctx: Context for multiple DSI transactions
|
||||
+ * @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_raw_multi(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_raw_multi);
|
||||
+
|
||||
/**
|
||||
* mipi_dsi_generic_read() - receive data using a generic read packet
|
||||
* @dsi: DSI peripheral device
|
||||
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/include/drm/drm_mipi_dsi.h
|
||||
+++ b/include/drm/drm_mipi_dsi.h
|
||||
@@ -289,6 +289,8 @@ 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_raw_multi(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);
|
||||
|
||||
@@ -440,6 +442,20 @@ void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
|
||||
mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
|
||||
} while (0)
|
||||
|
||||
+/**
|
||||
+ * mipi_dsi_dcs_write_long_multi - transmit a DCS long command with payload
|
||||
+ * @ctx: Context for multiple DSI transactions
|
||||
+ * @cmd: Commands
|
||||
+ * @seq: buffer containing data to be transmitted
|
||||
+ */
|
||||
+#define mipi_dsi_dcs_write_long_multi(ctx, cmd, seq...) \
|
||||
+ do { \
|
||||
+ static const u8 d[] = { cmd, seq }; \
|
||||
+ mipi_dsi_generic_write_raw_multi(ctx, \
|
||||
+ MIPI_DSI_DCS_LONG_WRITE, \
|
||||
+ d, ARRAY_SIZE(d)); \
|
||||
+ } while (0)
|
||||
+
|
||||
/**
|
||||
* struct mipi_dsi_driver - DSI driver
|
||||
* @driver: device driver model driver
|
||||
--
|
||||
Armbian
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Connolly <caleb@postmarketos.org>
|
||||
Date: Sun, 30 Jun 2024 20:36:28 +0200
|
||||
Subject: drm/mipi-dsi: add set column/page multi helpers
|
||||
|
||||
Introduce mipi_dsi_dcs_set_column_address_multi() and
|
||||
mipi_dsi_dcs_set_page_address_multi() helpers.
|
||||
|
||||
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
|
||||
---
|
||||
include/drm/drm_mipi_dsi.h | 16 ++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/include/drm/drm_mipi_dsi.h
|
||||
+++ b/include/drm/drm_mipi_dsi.h
|
||||
@@ -442,6 +442,22 @@ void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
|
||||
mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
|
||||
} while (0)
|
||||
|
||||
+#define mipi_dsi_dcs_set_column_address_multi(ctx, start, end) \
|
||||
+ do { \
|
||||
+ static const u8 d[] = { MIPI_DCS_SET_COLUMN_ADDRESS, \
|
||||
+ (start) >> 8, (start) & 0xff, \
|
||||
+ (end) >> 8, (end) & 0xff }; \
|
||||
+ mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define mipi_dsi_dcs_set_page_address_multi(ctx, start, end) \
|
||||
+ do { \
|
||||
+ static const u8 d[] = { MIPI_DCS_SET_PAGE_ADDRESS, \
|
||||
+ (start) >> 8, (start) & 0xff, \
|
||||
+ (end) >> 8, (end) & 0xff }; \
|
||||
+ mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
|
||||
+ } while (0)
|
||||
+
|
||||
/**
|
||||
* mipi_dsi_dcs_write_long_multi - transmit a DCS long command with payload
|
||||
* @ctx: Context for multiple DSI transactions
|
||||
--
|
||||
Armbian
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Connolly <caleb@postmarketos.org>
|
||||
Date: Sun, 30 Jun 2024 20:36:29 +0200
|
||||
Subject: drm/panel: add driver for samsung amb655x
|
||||
|
||||
This is a 1080x2400 120hz panel used on the OnePlus 8T. It uses DSC but
|
||||
with many non-standard DCS commands.
|
||||
|
||||
The only user of this panel (the OnePlus 8T) has a bug somewhere in the
|
||||
DSI stack whereby it isn't possible to properly initialize this panel
|
||||
after a reset. As a result, the reset GPIO is made optional so it can be
|
||||
left unused on that device.
|
||||
|
||||
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 | 399 ++++++++++
|
||||
4 files changed, 416 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -7231,6 +7231,13 @@ 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
|
||||
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/panel/Kconfig
|
||||
+++ b/drivers/gpu/drm/panel/Kconfig
|
||||
@@ -611,6 +611,15 @@ config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01
|
||||
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
|
||||
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/panel/Makefile
|
||||
+++ b/drivers/gpu/drm/panel/Makefile
|
||||
@@ -61,6 +61,7 @@ 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
|
||||
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..111111111111
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpu/drm/panel/panel-samsung-amb655x.c
|
||||
@@ -0,0 +1,399 @@
|
||||
+// 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 };
|
||||
+
|
||||
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
+
|
||||
+ drm_dsc_pps_payload_pack(&pps, &amb655x->dsc);
|
||||
+
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_buffer_multi(&ctx, &pps, sizeof(pps));
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0x9d, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
|
||||
+ mipi_dsi_msleep(&ctx, 11);
|
||||
+
|
||||
+ /* VLIN CURRENT LIMIT */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x04);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xd5, 0x24, 0x9e, 0x9e, 0x00, 0x20);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ /* OSC Select */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xfc, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x16);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xd1, 0x22);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xd6, 0x11);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xfc, 0xa5, 0xa5);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ /* TE ON */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, MIPI_DCS_SET_TEAR_ON, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ /* TSP Setting */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xdf, 0x83, 0x00, 0x10);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xe6, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ mipi_dsi_dcs_set_column_address_multi(&ctx, 0x0000, 1080 - 1);
|
||||
+ mipi_dsi_dcs_set_page_address_multi(&ctx, 0x0000, 2400 - 1);
|
||||
+
|
||||
+ /* FD Setting */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xd5, 0x8d);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x0a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xd5, 0x05);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ /* FFC Function */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xfc, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xe4, 0xa6, 0x75, 0xa3);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xe9,
|
||||
+ 0x11, 0x75, 0xa6, 0x75,
|
||||
+ 0xa3, 0x4b, 0x17, 0xac,
|
||||
+ 0x4b, 0x17, 0xac, 0x00,
|
||||
+ 0x19, 0x19);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xfc, 0xa5, 0xa5);
|
||||
+ mipi_dsi_msleep(&ctx, 61);
|
||||
+
|
||||
+ /* Dimming Setting */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x06);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb7, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x05);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb7, 0x13);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb0, 0x01);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xb7, 0x4c);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
+
|
||||
+ /* refresh rate Transition */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ /* 60 Hz */
|
||||
+ //mipi_dsi_dcs_write_long_multi(&ctx, 0x60, 0x00);
|
||||
+ /* 120 Hz */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0x60, 0x10);
|
||||
+
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+
|
||||
+ /* ACL Mode */
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0x5a, 0x5a);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0xf0, 0xa5, 0xa5);
|
||||
+ mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
|
||||
+ mipi_dsi_msleep(&ctx, 110);
|
||||
+
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0x9F, 0x5A, 0x5A);
|
||||
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
|
||||
+ mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_ENTER_NORMAL_MODE);
|
||||
+ mipi_dsi_dcs_write_long_multi(&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 };
|
||||
+
|
||||
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
+
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0x9f, 0x5a, 0x5a);
|
||||
+
|
||||
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
|
||||
+ mipi_dsi_msleep(&ctx, 20);
|
||||
+
|
||||
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
|
||||
+ mipi_dsi_msleep(&ctx, 20);
|
||||
+
|
||||
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
|
||||
+ mipi_dsi_dcs_write_long_multi(&ctx, 0x9f, 0xa5, 0xa5);
|
||||
+
|
||||
+ mipi_dsi_msleep(&ctx, 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;
|
||||
+
|
||||
+ /*
|
||||
+ * During the first call to prepare, the regulators are already enabled
|
||||
+ * since they're boot-on. Avoid enabling them twice so we keep the refcounts
|
||||
+ * balanced.
|
||||
+ */
|
||||
+ if (!regulator_is_enabled(ctx->supplies[0].consumer)) {
|
||||
+ 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 *amb655x = to_samsung_amb655x(panel);
|
||||
+ struct device *dev = &amb655x->dsi->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = samsung_amb655x_off(amb655x);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
|
||||
+
|
||||
+ gpiod_set_value_cansleep(amb655x->reset_gpio, 1);
|
||||
+
|
||||
+ ret = regulator_bulk_disable(ARRAY_SIZE(amb655x->supplies), amb655x->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");
|
||||
--
|
||||
Armbian
|
||||
|
|
@ -0,0 +1,660 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Connolly <caleb@postmarketos.org>
|
||||
Date: Sun, 30 Jun 2024 20:36:30 +0200
|
||||
Subject: Input: touchscreen: add Synaptics TCM oncell S3908
|
||||
|
||||
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 | 571 ++++++++++
|
||||
4 files changed, 590 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -22082,6 +22082,13 @@ 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>
|
||||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/input/touchscreen/Kconfig
|
||||
+++ b/drivers/input/touchscreen/Kconfig
|
||||
@@ -534,6 +534,17 @@ 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
|
||||
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/input/touchscreen/Makefile
|
||||
+++ b/drivers/input/touchscreen/Makefile
|
||||
@@ -89,6 +89,7 @@ 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
|
||||
diff --git a/drivers/input/touchscreen/synaptics_tcm_oncell.c b/drivers/input/touchscreen/synaptics_tcm_oncell.c
|
||||
new file mode 100644
|
||||
index 000000000000..111111111111
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/touchscreen/synaptics_tcm_oncell.c
|
||||
@@ -0,0 +1,571 @@
|
||||
+// 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 <asm-generic/unaligned.h>
|
||||
+#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
|
||||
+
|
||||
+/* 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
|
||||
+
|
||||
+struct tcm_message_header {
|
||||
+ u8 marker;
|
||||
+ u8 code;
|
||||
+ __le16 length;
|
||||
+} __packed;
|
||||
+
|
||||
+struct tcm_cmd {
|
||||
+ u8 cmd;
|
||||
+ __le16 length;
|
||||
+ u8 data[];
|
||||
+};
|
||||
+
|
||||
+struct tcm_identification {
|
||||
+ struct tcm_message_header header;
|
||||
+ 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;
|
||||
+ u8 version[2];
|
||||
+ __le16 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];
|
||||
+ __le16 max_x;
|
||||
+ __le16 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_data {
|
||||
+ struct i2c_client *client;
|
||||
+ struct regmap *regmap;
|
||||
+ struct input_dev *input;
|
||||
+ struct gpio_desc *reset_gpio;
|
||||
+ struct completion response;
|
||||
+ struct touchscreen_properties props;
|
||||
+ 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_report_point {
|
||||
+ u8 unknown;
|
||||
+ u8 buttons;
|
||||
+ __le32 point; /* idx : 4, class : 4, x : 12, y : 12 */
|
||||
+ // 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;
|
||||
+
|
||||
+static int tcm_handle_touch_report(struct tcm_data *tcm, const char *buf, size_t len)
|
||||
+{
|
||||
+ const struct tcm_report_point *point;
|
||||
+ /* If the input device hasn't registered yet then we can't do anything */
|
||||
+ if (!tcm->input)
|
||||
+ return 0;
|
||||
+
|
||||
+ buf += sizeof(struct tcm_message_header);
|
||||
+ len -= sizeof(struct tcm_message_header);
|
||||
+
|
||||
+ dev_dbg(&tcm->client->dev, "touch report len %zu\n", len);
|
||||
+ if ((len - 3) % sizeof(*point))
|
||||
+ dev_err(&tcm->client->dev, "invalid touch report length\n");
|
||||
+
|
||||
+ buf++; /* Skip the FPS report */
|
||||
+
|
||||
+ /* We don't need to report releases because we have INPUT_MT_DROP_UNUSED */
|
||||
+ for (int i = 0; i < (len - 1) / sizeof(*point); i++) {
|
||||
+ u8 major_width, minor_width;
|
||||
+ u16 idx, x, y;
|
||||
+ u32 _point;
|
||||
+
|
||||
+ point = (struct tcm_report_point *)buf;
|
||||
+ _point = le32_to_cpu(point->point);
|
||||
+
|
||||
+ minor_width = point->width_x;
|
||||
+ major_width = point->width_y;
|
||||
+
|
||||
+ if (minor_width > major_width)
|
||||
+ swap(major_width, minor_width);
|
||||
+
|
||||
+ idx = _point & 0xf;
|
||||
+ x = (_point >> 8) & 0xfff;
|
||||
+ y = (_point >> 20) & 0xfff;
|
||||
+
|
||||
+ dev_dbg(&tcm->client->dev, "touch report: idx %u x %u y %u\n",
|
||||
+ idx, x, y);
|
||||
+
|
||||
+ input_mt_slot(tcm->input, idx);
|
||||
+ input_mt_report_slot_state(tcm->input, MT_TOOL_FINGER, true);
|
||||
+
|
||||
+ touchscreen_report_pos(tcm->input, &tcm->props, x, y, true);
|
||||
+
|
||||
+ 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, point->z);
|
||||
+
|
||||
+ buf += sizeof(*point);
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ len = le32_to_cpu(header->length);
|
||||
+
|
||||
+ 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 };
|
||||
+ u16 status;
|
||||
+
|
||||
+ /*
|
||||
+ * 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;
|
||||
+ }
|
||||
+ status = le16_to_cpu(app_info.status);
|
||||
+ } while (status == APP_STATUS_BOOTING || 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,
|
||||
+ status);
|
||||
+
|
||||
+ *max_x = le16_to_cpu(app_info.max_x);
|
||||
+ *max_y = le16_to_cpu(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_cansleep(tcm->reset_gpio, 1);
|
||||
+ usleep_range(10000, 11000);
|
||||
+ gpiod_set_value_cansleep(tcm->reset_gpio, 0);
|
||||
+ usleep_range(80000, 81000);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tcm_probe(struct i2c_client *client)
|
||||
+{
|
||||
+ struct tcm_data *tcm;
|
||||
+ 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_LOW);
|
||||
+
|
||||
+ 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_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->props);
|
||||
+
|
||||
+ 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");
|
||||
+
|
||||
--
|
||||
Armbian
|
||||
|
|
@ -0,0 +1,988 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Connolly <caleb@postmarketos.org>
|
||||
Date: Sun, 30 Jun 2024 20:36:31 +0200
|
||||
Subject: arm64: dts: qcom: add OnePlus 8T (kebab)
|
||||
|
||||
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 +
|
||||
arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi | 909 ++++++++++
|
||||
arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts | 36 +
|
||||
3 files changed, 946 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/Makefile
|
||||
+++ b/arch/arm64/boot/dts/qcom/Makefile
|
||||
@@ -236,6 +236,7 @@ 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-instantnoodlep.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
|
||||
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..111111111111
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
|
||||
@@ -0,0 +1,909 @@
|
||||
+// 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;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ panel_avdd_5p5: regulator-panel-avdd {
|
||||
+ 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;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&panel_avdd_pins>;
|
||||
+ };
|
||||
+
|
||||
+ vph_pwr: regulator-vph-pwr {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "vph_pwr";
|
||||
+ regulator-min-microvolt = <3700000>;
|
||||
+ regulator-max-microvolt = <3700000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ vreg_s4a_1p8: regulator-vreg-s4a-1p8 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "vreg_s4a_1p8";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ 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 {
|
||||
+ firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&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_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>;
|
||||
+ };
|
||||
+
|
||||
+ 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>;
|
||||
+ regulator-allow-set-load;
|
||||
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
|
||||
+ 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_LPM>;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ 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>;
|
||||
+ regulator-allow-set-load;
|
||||
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
|
||||
+ 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>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ 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_s8c_1p3: smps8 {
|
||||
+ regulator-name = "vreg_s8c_1p3";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <1400000>;
|
||||
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
|
||||
+ };
|
||||
+
|
||||
+ 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;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&cdsp {
|
||||
+ firmware-name = "qcom/sm8250/OnePlus/cdsp.mbn";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&crypto {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&gmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&gpu {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ zap-shader {
|
||||
+ memory-region = <&gpu_mem>;
|
||||
+ firmware-name = "qcom/sm8250/OnePlus/a650_zap.mbn";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c2 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ /*
|
||||
+ * Pixelworks Iris 5 @ 26 (i3c) or 22 (i2c)
|
||||
+ * This is a co-processor for the display which needs to be
|
||||
+ * initialized along with the panel.
|
||||
+ */
|
||||
+};
|
||||
+
|
||||
+&i2c15 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ typec-mux@42 {
|
||||
+ compatible = "fcs,fsa4480";
|
||||
+ reg = <0x42>;
|
||||
+
|
||||
+ vcc-supply = <&vreg_s4a_1p8>;
|
||||
+
|
||||
+ orientation-switch;
|
||||
+
|
||||
+ /* Currently unsupported */
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ port {
|
||||
+ fsa4480_sbu_mux: endpoint {
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c16 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ bq27541_fg: bq27541-battery@55 {
|
||||
+ compatible = "ti,bq27541";
|
||||
+ status = "okay";
|
||||
+ reg = <0x55>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mdss {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mdss_dsi0 {
|
||||
+ vdda-supply = <&vreg_l9a_1p2>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ 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";
|
||||
+};
|
||||
+
|
||||
+&pcie0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie0_phy {
|
||||
+ vdda-phy-supply = <&vreg_l5a_0p88>;
|
||||
+ vdda-pll-supply = <&vreg_l9a_1p2>;
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcieport0 {
|
||||
+ wifi@0 {
|
||||
+ compatible = "pci17cb,1101";
|
||||
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
|
||||
+
|
||||
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
|
||||
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
|
||||
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
|
||||
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
|
||||
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
|
||||
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
+ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
|
||||
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
|
||||
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pcie2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie2_phy {
|
||||
+ vdda-phy-supply = <&vreg_l5a_0p88>;
|
||||
+ vdda-pll-supply = <&vreg_l9a_1p2>;
|
||||
+ 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>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pm8150_gpios {
|
||||
+ /*
|
||||
+ * These are marked as reserved in downstream
|
||||
+ * with no description, without schematics we
|
||||
+ * don't know what the deal is here.
|
||||
+ */
|
||||
+ gpio-reserved-ranges = <2 1>, <4 2>, <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 {
|
||||
+ 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..111111111111
|
||||
--- /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";
|
||||
+};
|
||||
+
|
||||
+&display_panel {
|
||||
+ compatible = "samsung,amb655x";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&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_LOW>;
|
||||
+
|
||||
+ vdd-supply = <&vreg_l13a_ts_3p0>;
|
||||
+ vcc-supply = <&vreg_l1c_1p8>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: amazingfate <liujianfeng1994@gmail.com>
|
||||
Date: Thu, 17 Oct 2024 17:10:02 +0800
|
||||
Subject: arm64: dts: qcom: Add venus firmware for OnePlus 8T
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
|
||||
@@ -34,3 +34,7 @@ touchscreen@4b {
|
||||
vcc-supply = <&vreg_l1c_1p8>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+&venus {
|
||||
+ firmware-name = "qcom/sm8250/OnePlus/kebab/venus.mbn";
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
Loading…
Reference in New Issue