* [PATCH 1/3] dt-bindings: gpio: add Axiado SGPIO controller
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add device tree binding for the Axiado SGPIO controller.
The SGPIO controller provides a serialized interface for
controlling multiple GPIO signals over a limited number of
physical lines. It supports configurable data direction and
interrupt handling.
The binding describes the properties required to instantiate
the controller and register it as a GPIO provider.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
.../devicetree/bindings/gpio/axiado,sgpio.yaml | 98 ++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml b/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
new file mode 100644
index 000000000000..1533446d69f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/axiado,sgpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Axiado SGPIO Controller
+
+maintainers:
+ - Petar Stepanovic <pstepanovic@axiado.com>
+ - SriNavmani A <srinavmani@axiado.com>
+ - Prasad Bolisetty <pbolisetty@axiado.com>
+
+description: |
+ The SGPIO controller provides a serialized interface for controlling
+ multiple GPIO signals over a limited number of physical lines.
+ It supports configurable data direction and interrupt handling.
+
+properties:
+ compatible:
+ enum:
+ - axiado,sgpio
+
+ reg:
+ maxItems: 1
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 2
+
+ design-variant:
+ description: SGPIO design variant size in bits (e.g. 128 or 512).
+ enum: [128, 512]
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ ngpios:
+ description: The number of gpios this controller has.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ bus-frequency:
+ description: The SGPIO shift clock frequency in Hz.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ apb-frequency:
+ description: The APB bus frequency in Hz.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ dout-init:
+ description: Initial values for the dout registers.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+
+required:
+ - compatible
+ - reg
+ - gpio-controller
+ - '#gpio-cells'
+ - interrupts
+ - interrupt-controller
+ - '#interrupt-cells'
+ - design-variant
+ - ngpios
+ - bus-frequency
+ - apb-frequency
+ - dout-init
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ sgpio@a000 {
+ compatible = "axiado,sgpio";
+ reg = <0xa000 0x800>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+ design-variant = <128>;
+ ngpios = <128>;
+ bus-frequency = <1000000>;
+ apb-frequency = <100000000>;
+ dout-init = <0x00300000 0x00006371 0x00003800 0x00000000>;
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH 3/3] MAINTAINERS: add Axiado SGPIO controller
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add MAINTAINERS entry for the Axiado SGPIO controller driver
and corresponding device tree binding.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
MAINTAINERS | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 67db88b04537..56835c0a1863 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4234,6 +4234,15 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
+AXIADO SGPIO DRIVER
+M: Petar Stepanovic <pstepanovic@axiado.com>
+M: SriNavmani A <srinavmani@axiado.com>
+M: Prasad Bolisetty <pbolisetty@axiado.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
+F: drivers/gpio/gpio-axiado-sgpio.c
+
AXIS ARTPEC ARM64 SoC SUPPORT
M: Jesper Nilsson <jesper.nilsson@axis.com>
M: Lars Persson <lars.persson@axis.com>
--
2.34.1
^ permalink raw reply related
* [PATCH 2/3] gpio: axiado: add SGPIO controller support
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add support for the Axiado SGPIO controller.
The controller provides a serialized interface for GPIOs with
configurable direction and interrupt support.
The driver registers the controller as a gpio_chip and uses
regmap for register access.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
drivers/gpio/Kconfig | 18 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-axiado-sgpio.c | 780 +++++++++++++++++++++++++++++++++++++++
3 files changed, 799 insertions(+)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bd185482a7fd..42c56d157092 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -198,6 +198,24 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
+config GPIO_AXIADO_SGPIO
+ bool "Axiado SGPIO support"
+ depends on OF_GPIO
+ depends on ARCH_AXIADO || COMPILE_TEST
+ select GPIO_GENERIC
+ select GPIOLIB_IRQCHIP
+ select REGMAP
+ help
+ Enable support for the Axiado Serial GPIO (SGPIO) controller.
+
+ The SGPIO controller provides a serialized interface for
+ controlling multiple GPIO signals over a limited number of
+ physical lines. It supports configurable data direction and
+ interrupt handling.
+
+ This driver integrates with the Linux GPIO subsystem and
+ exposes the controller as a standard GPIO provider.
+
config GPIO_RASPBERRYPI_EXP
tristate "Raspberry Pi 3 GPIO Expander"
default RASPBERRYPI_FIRMWARE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2421a8fd3733..909a97551807 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
obj-$(CONFIG_GPIO_ASPEED_SGPIO) += gpio-aspeed-sgpio.o
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
+obj-$(CONFIG_GPIO_AXIADO_SGPIO) += gpio-axiado-sgpio.o
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o
obj-$(CONFIG_GPIO_BD71815) += gpio-bd71815.o
diff --git a/drivers/gpio/gpio-axiado-sgpio.c b/drivers/gpio/gpio-axiado-sgpio.c
new file mode 100644
index 000000000000..8cd349ec6f53
--- /dev/null
+++ b/drivers/gpio/gpio-axiado-sgpio.c
@@ -0,0 +1,780 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022-2026 Axiado Corporation
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#include <linux/gpio/driver.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#include <linux/regmap.h>
+
+struct sgpio_reg_offsets {
+ u32 mux_0;
+ u32 preset_0;
+ u32 count_0;
+ u32 pos_0;
+
+ u32 mux_1;
+ u32 ld;
+ u32 ld_ss;
+
+ u32 preset_1;
+ u32 count_1;
+ u32 pos_1;
+
+ u32 mux_2;
+ u32 dout;
+ u32 dout_ss;
+
+ u32 preset_2;
+ u32 count_2;
+ u32 pos_2;
+
+ u32 mux_3;
+ u32 preset_3;
+ u32 count_3;
+ u32 pos_3;
+
+ u32 mux_4;
+ u32 oe;
+ u32 oe_ss;
+
+ u32 preset_4;
+ u32 count_4;
+ u32 pos_4;
+
+ u32 mask;
+ u32 ctrl_en;
+ u32 ctrl_en_pos;
+
+ u32 din_ss;
+ u32 status;
+};
+
+static const struct sgpio_reg_offsets sgpio_offsets_512 = {
+ .mux_0 = 0x000,
+ .preset_0 = 0x1dc,
+ .count_0 = 0x1f0,
+ .pos_0 = 0x204,
+
+ .mux_1 = 0x004,
+ .ld = 0x014,
+ .ld_ss = 0x0d8,
+
+ .preset_1 = 0x1e0,
+ .count_1 = 0x1f4,
+ .pos_1 = 0x208,
+
+ .mux_2 = 0x008,
+ .dout = 0x054,
+ .dout_ss = 0x158,
+
+ .preset_2 = 0x1e4,
+ .count_2 = 0x1f8,
+ .pos_2 = 0x20c,
+
+ .mux_3 = 0x00c,
+ .preset_3 = 0x1e8,
+ .count_3 = 0x1fc,
+ .pos_3 = 0x210,
+
+ .mux_4 = 0x010,
+ .oe = 0x0d4,
+ .oe_ss = 0x1d8,
+
+ .preset_4 = 0x1ec,
+ .count_4 = 0x200,
+ .pos_4 = 0x214,
+
+ .mask = 0x224,
+ .ctrl_en = 0x218,
+ .ctrl_en_pos = 0x21c,
+
+ .din_ss = 0x198,
+ .status = 0x228,
+};
+
+static const struct sgpio_reg_offsets sgpio_offsets_128 = {
+ .mux_0 = 0x000,
+ .preset_0 = 0x08c,
+ .count_0 = 0x0a0,
+ .pos_0 = 0x0b4,
+
+ .mux_1 = 0x004,
+ .ld = 0x014,
+ .ld_ss = 0x048,
+
+ .preset_1 = 0x090,
+ .count_1 = 0x0a4,
+ .pos_1 = 0x0b8,
+
+ .mux_2 = 0x008,
+ .dout = 0x024,
+ .dout_ss = 0x068,
+
+ .preset_2 = 0x094,
+ .count_2 = 0x0a8,
+ .pos_2 = 0x0bc,
+
+ .mux_3 = 0x00c,
+ .preset_3 = 0x098,
+ .count_3 = 0x0ac,
+ .pos_3 = 0x0c0,
+
+ .mux_4 = 0x010,
+ .oe = 0x044,
+ .oe_ss = 0x088,
+
+ .preset_4 = 0x09c,
+ .count_4 = 0x0b0,
+ .pos_4 = 0x0c4,
+
+ .mask = 0x0d4,
+ .ctrl_en = 0x0c8,
+ .ctrl_en_pos = 0x0cc,
+
+ .din_ss = 0x078,
+ .status = 0x0d8,
+};
+
+#define MAX_SGPIO_PINS 512
+#define MAX_OFFSET_REG 16
+#define MAX_SLICE_COUNT 5
+
+struct ax3000_slice_info {
+ u32 out_mux;
+ u32 sgpio_mux;
+ u32 slice_mux;
+ u32 reg[MAX_OFFSET_REG];
+ u32 reg_ss[MAX_OFFSET_REG];
+ u32 preset;
+ u32 count;
+ u32 pos;
+};
+
+struct ax3000_sgpio {
+ u32 preset_value;
+ u32 count_value;
+ u32 pos_reg;
+ struct ax3000_slice_info
+ slices[MAX_SLICE_COUNT]; /* 0=clk,1=load,2=out,3=in,4=oe */
+ spinlock_t lock;
+ int ngpios;
+ int max_sgpio_pins;
+ int max_offset_regs;
+ struct gpio_chip chip;
+ u32 irq_unmasked[MAX_SGPIO_PINS];
+ int parent_irq;
+ struct regmap *regmap;
+ u32 regmap_base_offset;
+ struct sgpio_reg_offsets *regs;
+};
+
+static int sgpio_set_irq_type(struct irq_data *d, unsigned int type);
+static void sgpio_mask_irq(struct irq_data *d);
+static void sgpio_unmask_irq(struct irq_data *d);
+static void sgpio_irq_shutdown(struct irq_data *d);
+
+static const struct irq_chip axiado_sgpio_irqchip = {
+ .name = "axiado-sgpio",
+ .irq_mask = sgpio_mask_irq,
+ .irq_unmask = sgpio_unmask_irq,
+ .irq_set_type = sgpio_set_irq_type,
+ .irq_shutdown = sgpio_irq_shutdown,
+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static void ax3000_sgpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct ax3000_sgpio *sgpio = gpiochip_get_data(chip);
+ unsigned long flags;
+ u32 bank = (offset / 2) / 32;
+ u32 position = (offset / 2) % 32;
+
+ spin_lock_irqsave(&sgpio->lock, flags);
+ if (value)
+ sgpio->slices[2].reg_ss[bank] |= BIT(position);
+ else
+ sgpio->slices[2].reg_ss[bank] &= ~BIT(position);
+
+ spin_unlock_irqrestore(&sgpio->lock, flags);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (bank * 4),
+ sgpio->slices[2].reg_ss[bank]);
+}
+
+static int ax3000_sgpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct ax3000_sgpio *sgpio = gpiochip_get_data(chip);
+ u32 bank = (offset / 2) / 32;
+ u32 position = (offset / 2) % 32;
+
+ if (offset % 2 == 0)
+ return !!(sgpio->slices[3].reg_ss[bank] & BIT(position));
+ else
+ return !!(sgpio->slices[2].reg_ss[bank] & BIT(position));
+}
+
+static int ax3000_sgpio_dir_in(struct gpio_chip *chip, unsigned int offset)
+{
+ if (!(offset % 2))
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static int ax3000_sgpio_dir_out(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ if (offset % 2) {
+ if (chip->set)
+ chip->set(chip, offset, value);
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t sgpio_irq_handler(int irq, void *arg)
+{
+ struct ax3000_sgpio *sgpio = (struct ax3000_sgpio *)arg;
+ unsigned long flags;
+ u32 status, new_value;
+ u32 changed_value;
+ int i, bit, reg_ptr;
+
+ /* Read-on-clear (ACK) parent cause */
+ regmap_read(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->status, &status);
+ status >>= 16;
+
+ bool has_shifted_layout = (sgpio->max_offset_regs == MAX_OFFSET_REG);
+
+ reg_ptr = has_shifted_layout ? 16 - DIV_ROUND_UP(sgpio->ngpios, 32) : 0;
+
+ for (i = 0; i < DIV_ROUND_UP(sgpio->ngpios, 32); i++, reg_ptr++) {
+ if (status & BIT(reg_ptr)) {
+ regmap_read(sgpio->regmap,
+ sgpio->regmap_base_offset +
+ sgpio->regs->din_ss + (reg_ptr * 4),
+ &new_value);
+ spin_lock_irqsave(&sgpio->lock, flags);
+ changed_value = sgpio->slices[3].reg_ss[i] ^ new_value;
+ sgpio->slices[3].reg_ss[i] = new_value;
+ spin_unlock_irqrestore(&sgpio->lock, flags);
+
+ while (changed_value) {
+ bit = __ffs(changed_value);
+ changed_value &= ~BIT(bit);
+
+ irq_hw_number_t hwirq = i * 32 + bit;
+
+ if (sgpio->irq_unmasked[hwirq]) {
+ unsigned int child_irq;
+
+ child_irq = irq_find_mapping(sgpio->chip.irq.domain,
+ hwirq);
+
+ if (child_irq)
+ handle_nested_irq(child_irq);
+ }
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void sgpio_hw_init(struct ax3000_sgpio *sgpio)
+{
+ u32 bank;
+ u32 position;
+ int i = 0;
+ bool has_shifted_layout = (sgpio->max_offset_regs == MAX_OFFSET_REG);
+
+ /* slice A0, Clock Pin - 0 */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_0, 0x306);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_0,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_0,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_0, 0x1f001f);
+
+ /* Slice B1, Data Load Pin - 1 */
+ bank = (sgpio->ngpios - 1) / 32;
+ position = (sgpio->ngpios - 1) % 32;
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_1,
+ has_shifted_layout ? 0x30c : 0x304);
+
+ for (i = 0; i < bank; i++) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld +
+ (i * 4),
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld_ss +
+ (i * 4),
+ 0xffffffff);
+ }
+
+ if (position) {
+ u32 val;
+
+ val = sgpio->slices[1].reg_ss[i];
+ val |= GENMASK(position - 1, 0);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld +
+ (i * 4),
+ val);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld_ss +
+ (i * 4),
+ val);
+ }
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_1,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_1,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_1,
+ sgpio->pos_reg);
+
+ /* Slice C2, Data Out Pin - 2 */
+ bank = sgpio->ngpios / 32;
+ position = sgpio->ngpios % 32;
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_2,
+ has_shifted_layout ? 0x30c : 0x304);
+
+ for (i = 0; i < bank; i++) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ }
+
+ if (position) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ }
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_2,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_2,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_2,
+ sgpio->pos_reg);
+
+ /* Slice D3, Data In Pin - 3 */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_3, 0x14C);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_3,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_3,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_3,
+ sgpio->pos_reg);
+
+ /* Slice E4, Output Enable for respective pins */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_4,
+ has_shifted_layout ? 0x10c : 0x104);
+ regmap_write(sgpio->regmap, sgpio->regmap_base_offset + sgpio->regs->oe,
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->oe_ss,
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_4,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_4,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_4, 0x1f001f);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mask, 0xdfff);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en, 0xffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en_pos,
+ 0xffff);
+}
+
+static int sgpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_EDGE_FALLING:
+ irq_set_handler_locked(d, handle_edge_irq);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void sgpio_mask_irq(struct irq_data *d)
+{
+ struct gpio_chip *chip;
+ struct ax3000_sgpio *sgpio;
+ u32 irq_num;
+
+ chip = irq_data_get_irq_chip_data(d);
+ if (!chip) {
+ pr_err("Unable to get gpio_chip for IRQ\n");
+ return;
+ }
+
+ sgpio = gpiochip_get_data(chip);
+ if (!sgpio) {
+ pr_err("Unable to get chip data\n");
+ return;
+ }
+
+ irq_num = irqd_to_hwirq(d);
+ sgpio->irq_unmasked[irq_num / 2] = 0;
+}
+
+static void sgpio_unmask_irq(struct irq_data *d)
+{
+ struct gpio_chip *chip;
+ struct ax3000_sgpio *sgpio;
+ u32 irq_num;
+
+ chip = irq_data_get_irq_chip_data(d);
+ if (!chip) {
+ pr_err("Unable to get gpio_chip for IRQ\n");
+ return;
+ }
+
+ sgpio = gpiochip_get_data(chip);
+ if (!sgpio) {
+ pr_err("Unable to get chip data\n");
+ return;
+ }
+
+ irq_num = irqd_to_hwirq(d);
+ sgpio->irq_unmasked[irq_num / 2] = 1;
+}
+
+static void sgpio_irq_shutdown(struct irq_data *d)
+{
+ sgpio_mask_irq(d);
+}
+
+static int sgpio_probe(struct platform_device *pdev)
+{
+ int rc;
+ int irq;
+ int i;
+ const __be32 *prop;
+ struct gpio_irq_chip *girq;
+ struct ax3000_sgpio *sgpio;
+ u32 variant;
+ u32 dout_value;
+ u32 bus_frequency;
+ u32 apb_frequency;
+ int dout_reverse;
+
+ void __iomem *base;
+
+ const struct regmap_config regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ };
+
+ sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL);
+ if (!sgpio)
+ return -ENOMEM;
+
+ spin_lock_init(&sgpio->lock);
+
+ sgpio->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+
+ if (sgpio->regmap) {
+ rc = of_property_read_u32(pdev->dev.of_node, "reg",
+ &sgpio->regmap_base_offset);
+ if (rc) {
+ dev_err(&pdev->dev, "Failed to read reg property: %d\n",
+ rc);
+ return rc;
+ }
+ dev_info(&pdev->dev, "Using regmap with base offset: 0x%x\n",
+ sgpio->regmap_base_offset);
+ } else {
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ sgpio->regmap =
+ devm_regmap_init_mmio(&pdev->dev, base, ®map_config);
+
+ if (IS_ERR(sgpio->regmap))
+ return PTR_ERR(sgpio->regmap);
+
+ sgpio->regmap_base_offset = 0;
+
+ dev_info(&pdev->dev, "Using MMIO regmap\n");
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "ngpios", &sgpio->ngpios);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read ngpios property\n");
+ return -EINVAL;
+ }
+
+ if (device_property_read_u32(&pdev->dev, "design-variant", &variant)) {
+ dev_err(&pdev->dev, "design-variant not specified in DT\n");
+ return -EINVAL;
+ }
+
+ if (variant == 128) {
+ sgpio->regs = &sgpio_offsets_128;
+ sgpio->max_sgpio_pins = 128;
+ sgpio->max_offset_regs = 4;
+ } else if (variant == 512) {
+ sgpio->regs = &sgpio_offsets_512;
+ sgpio->max_sgpio_pins = 512;
+ sgpio->max_offset_regs = 16;
+ } else {
+ return -EINVAL;
+ }
+
+ if (sgpio->ngpios > sgpio->max_sgpio_pins) {
+ dev_err(&pdev->dev, "ngpio is greater than 512 pins\n");
+ return -EINVAL;
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "bus-frequency",
+ &bus_frequency);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read bus-frequency property\n");
+ return -EINVAL;
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "apb-frequency",
+ &apb_frequency);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read apb-frequency property\n");
+ return -EINVAL;
+ }
+
+ sgpio->preset_value = (apb_frequency / bus_frequency) - 1;
+ sgpio->count_value = sgpio->preset_value;
+
+ u32 pos;
+
+ pos = sgpio->ngpios - 1;
+ sgpio->pos_reg = (pos << 16) | pos;
+
+ prop = of_get_property(pdev->dev.of_node, "dout-init", NULL);
+ if (!prop) {
+ dev_err(&pdev->dev, "Failed to get dout-init\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < sgpio->max_offset_regs; i++) {
+ sgpio->slices[2].reg_ss[i] = 0;
+ dout_value = be32_to_cpu(prop[i]);
+
+ for (dout_reverse = 0; dout_reverse < 32; ++dout_reverse) {
+ sgpio->slices[2].reg_ss[i] <<= 1;
+ sgpio->slices[2].reg_ss[i] |= (dout_value & 1);
+ dout_value >>= 1;
+ }
+ }
+
+ sgpio_hw_init(sgpio);
+
+ irq = platform_get_irq(pdev, 0);
+
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get parent IRQ: %d\n", irq);
+ return irq;
+ }
+ /* Store parent IRQ for cleanup */
+ sgpio->parent_irq = irq;
+
+ rc = devm_request_threaded_irq(&pdev->dev, irq, NULL, sgpio_irq_handler,
+ IRQF_ONESHOT, "axiado-sgpio", sgpio);
+
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to request threaded IRQ %d: %d\n",
+ irq, rc);
+ return rc;
+ }
+
+ sgpio->chip.parent = &pdev->dev;
+ sgpio->chip.ngpio = sgpio->ngpios * 2;
+ sgpio->chip.owner = THIS_MODULE;
+ sgpio->chip.direction_input = ax3000_sgpio_dir_in;
+ sgpio->chip.direction_output = ax3000_sgpio_dir_out;
+ sgpio->chip.get = ax3000_sgpio_get;
+ sgpio->chip.set = ax3000_sgpio_set;
+ sgpio->chip.label = dev_name(&pdev->dev);
+ sgpio->chip.base = -1;
+
+ girq = &sgpio->chip.irq;
+
+ girq->chip = &axiado_sgpio_irqchip;
+ girq->handler = handle_edge_irq;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->num_parents = 1;
+ girq->parents =
+ devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents), GFP_KERNEL);
+ if (!girq->parents) {
+ dev_err(&pdev->dev, "Failed to allocate parents array\n");
+ return -ENOMEM;
+ }
+ girq->parents[0] = irq;
+
+ rc = devm_gpiochip_add_data(&pdev->dev, &sgpio->chip, sgpio);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n", rc);
+ return rc;
+ }
+
+ /* Store driver data for remove() */
+ platform_set_drvdata(pdev, sgpio);
+ dev_info(&pdev->dev, "SGPIO registered with %d GPIOs\n",
+ sgpio->chip.ngpio);
+
+ return 0;
+}
+
+static int sgpio_remove(struct platform_device *pdev)
+{
+ struct ax3000_sgpio *sgpio = platform_get_drvdata(pdev);
+ int i;
+
+ if (!sgpio)
+ return 0;
+
+ /* Disable interrupts in hardware */
+ if (sgpio->regs) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mask,
+ 0x0);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en,
+ 0x0);
+ }
+
+ /* Disable and synchronize parent IRQ to avoid races with handlers */
+ if (sgpio->parent_irq >= 0) {
+ disable_irq(sgpio->parent_irq);
+ synchronize_irq(sgpio->parent_irq);
+ }
+
+ /* Ensure all GPIO IRQ handlers complete before removal */
+ if (sgpio->chip.irq.domain) {
+ struct irq_domain *domain = sgpio->chip.irq.domain;
+ unsigned int irq;
+ int hwirq;
+
+ for (hwirq = 0; hwirq < sgpio->chip.ngpio; hwirq++) {
+ irq = irq_find_mapping(domain, hwirq);
+ if (irq) {
+ disable_irq(irq);
+ synchronize_irq(irq);
+ }
+ }
+ }
+
+ /* Clear internal IRQ state */
+ for (i = 0; i < sgpio->max_sgpio_pins; i++)
+ sgpio->irq_unmasked[i] = 0;
+
+ return 0;
+}
+
+static const struct of_device_id ax_sgpio_match[] = {
+ { .compatible = "axiado,sgpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ax_sgpio_match);
+
+static struct platform_driver sgpio_driver = {
+ .driver = {
+ .name = "sgpio",
+ .owner = THIS_MODULE,
+ .of_match_table = ax_sgpio_match,
+ },
+ .probe = sgpio_probe,
+ .remove = sgpio_remove,
+};
+
+static int __init ax_sgpio_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&sgpio_driver);
+ if (ret < 0) {
+ pr_err("Failed to register SGPIO driver\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit ax_sgpio_exit(void)
+{
+ platform_driver_unregister(&sgpio_driver);
+}
+
+module_init(ax_sgpio_init);
+module_exit(ax_sgpio_exit);
+
+MODULE_DESCRIPTION("Axiado Serial GPIO Driver");
+MODULE_AUTHOR("Axiado Corporation");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 2/3] pmdomain: core: add support for power-domains-child-ids
From: Ulf Hansson @ 2026-04-14 13:42 UTC (permalink / raw)
To: Kevin Hilman
Cc: Rob Herring, Geert Uytterhoeven, linux-pm, devicetree,
linux-kernel, arm-scmi, linux-arm-kernel
In-Reply-To: <7hqzomqwpv.fsf@baylibre.com>
On Sat, 11 Apr 2026 at 00:25, Kevin Hilman <khilman@baylibre.com> wrote:
>
> Ulf Hansson <ulf.hansson@linaro.org> writes:
>
> > On Fri, 10 Apr 2026 at 02:45, Kevin Hilman <khilman@baylibre.com> wrote:
> >>
> >> Ulf Hansson <ulf.hansson@linaro.org> writes:
> >>
> >> > On Wed, 11 Mar 2026 at 01:19, Kevin Hilman (TI) <khilman@baylibre.com> wrote:
> >> >>
> >> >> Currently, PM domains can only support hierarchy for simple
> >> >> providers (e.g. ones with #power-domain-cells = 0).
> >> >>
> >> >> Add support for oncell providers as well by adding a new property
> >> >> `power-domains-child-ids` to describe the parent/child relationship.
> >> >>
> >> >> For example, an SCMI PM domain provider has multiple domains, each of
> >> >> which might be a child of diffeent parent domains. In this example,
> >> >> the parent domains are MAIN_PD and WKUP_PD:
> >> >>
> >> >> scmi_pds: protocol@11 {
> >> >> reg = <0x11>;
> >> >> #power-domain-cells = <1>;
> >> >> power-domains = <&MAIN_PD>, <&WKUP_PD>;
> >> >> power-domains-child-ids = <15>, <19>;
> >> >> };
> >> >>
> >> >> With this example using the new property, SCMI PM domain 15 becomes a
> >> >> child domain of MAIN_PD, and SCMI domain 19 becomes a child domain of
> >> >> WKUP_PD.
> >> >>
> >> >> To support this feature, add two new core functions
> >> >>
> >> >> - of_genpd_add_child_ids()
> >> >> - of_genpd_remove_child_ids()
> >> >>
> >> >> which can be called by pmdomain providers to add/remove child domains
> >> >> if they support the new property power-domains-child-ids.
> >> >>
> >> >> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
> >> >
> >> > Thanks for working on this! It certainly is a missing feature!
> >>
> >> You're welcome, thanks for the detailed review.
> >>
> >> >> ---
> >> >> drivers/pmdomain/core.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> >> include/linux/pm_domain.h | 16 ++++++++++++++++
> >> >> 2 files changed, 185 insertions(+)
> >> >>
> >> >> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> >> >> index 61c2277c9ce3..acb45dd540b7 100644
> >> >> --- a/drivers/pmdomain/core.c
> >> >> +++ b/drivers/pmdomain/core.c
> >> >> @@ -2909,6 +2909,175 @@ static struct generic_pm_domain *genpd_get_from_provider(
> >> >> return genpd;
> >> >> }
> >> >>
> >> >> +/**
> >> >> + * of_genpd_add_child_ids() - Parse power-domains-child-ids property
> >> >> + * @np: Device node pointer associated with the PM domain provider.
> >> >> + * @data: Pointer to the onecell data associated with the PM domain provider.
> >> >> + *
> >> >> + * Parse the power-domains and power-domains-child-ids properties to establish
> >> >> + * parent-child relationships for PM domains. The power-domains property lists
> >> >> + * parent domains, and power-domains-child-ids lists which child domain IDs
> >> >> + * should be associated with each parent.
> >> >> + *
> >> >> + * Returns 0 on success, -ENOENT if properties don't exist, or negative error code.
> >> >
> >> > I think we should avoid returning specific error codes for specific
> >> > errors, simply because it usually becomes messy.
> >> >
> >> > If I understand correctly the intent here is to allow the caller to
> >> > check for -ENOENT and potentially avoid bailing out as it may not
> >> > really be an error, right?
> >>
> >> Right, -ENOENT is not an error of parsing, it's to indicate that there
> >> are no child-ids to be parsed.
> >>
> >> > Perhaps a better option is to return the number of children for whom
> >> > we successfully assigned parents. Hence 0 or a positive value allows
> >> > the caller to understand what happened. More importantly, a negative
> >> > error code then really becomes an error for the caller to consider.
> >>
> >> I explored this a bit, but it gets messy quick. It means we have to
> >> track cases where only some of the children were added as well as when
> >> all children were added. Personally, I think this should be an "all or
> >> nothing" thing. If all the children cannot be parsed/added, then none
> >> of them should be added.
> >>
> >> This also allows the remove to not have to care about how many were
> >> added, and just remove them all, with the additional benefit of not
> >> having to track the state of how many children were successfully added.
> >>
> >
> > I fully agree, it should be all or nothing. Failing with one
> > child/parent should end up with an error code being returned.
> >
> > That said, it still seems to make perfect sense to return the number
> > of children for whom we assigned parents for, no?
>
> No, because what will the caller use that number for? If we are
> assuming "all or nothing", what would we use it for (other than a debug print?)
>
> It also makes it a bit confusing what a zero return value means. Does
> that mean success? Or that zero children were added (which would be
> fail.)
>
> I prefer to keep it as is.
In that case, how should we treat the scenario where the device node
lacks a "power-domains-child-ids" property? In some cases it is
probably fine, while in others it may not be.
I guess the caller of of_genpd_add_child_ids(), would then need to
pre-parse for the "power-domains-child-ids" property before deciding
to call of_genpd_add_child_ids().
At least, we don't of_genpd_add_child_ids() to return an error code if
there is no "power-domains-child-ids" in the device node, as that
would just confuse the caller.
Kind regards
Uffe
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: iio: dac: add support for Microchip MCP48FEB02 to MCP47FEB02
From: Ariana.Lazar @ 2026-04-14 13:39 UTC (permalink / raw)
To: conor
Cc: dlechner, nuno.sa, Conor.Dooley, Jonathan.Cameron, robh, jic23,
andy, krzk+dt, linux-iio, conor+dt, linux-kernel, devicetree
In-Reply-To: <20260403-speed-childless-1360de358229@spud>
Hi Conor,
> >
> > patternProperties:
> > @@ -161,8 +222,7 @@ patternProperties:
> > properties:
> > reg:
> > description: The channel number.
> > - minItems: 1
> > - maxItems: 8
> > + maxItems: 1
>
> Why is this changing? Was it originally a mistake and what you wanted
> was a max of 8 but only one entry?
>
> >
Thank you for the review.
It was a mistake I missed in the devicetree
binding for the mcp47feb02 driver. The property contains a single
integer representing the channel number (0-7), as you said.
Should I send a fix for the mcp47feb02 binding first or can I continue
to rewrite/split mcp47feb02 driver into the core module with I2C
protocol file and include this binding fix there too?
Best regards,
Ariana
^ permalink raw reply
* Re: [PATCH v2 2/2] riscv: dts: spacemit: Add cpu scaling for K1 SoC
From: Anand Moon @ 2026-04-14 13:25 UTC (permalink / raw)
To: Shuwei Wu
Cc: Rafael J. Wysocki, Viresh Kumar, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, linux-pm, linux-kernel, linux-riscv,
spacemit, devicetree
In-Reply-To: <20260410-shadow-deps-v2-2-4e16b8c0f60e@mailbox.org>
Hi Shuwei,
On Fri, 10 Apr 2026 at 13:30, Shuwei Wu <shuwei.wu@mailbox.org> wrote:
>
> Add Operating Performance Points (OPP) tables and CPU clock properties
> for the two clusters in the SpacemiT K1 SoC.
>
> Also assign the CPU power supply (cpu-supply) for the Banana Pi BPI-F3
> board to fully enable CPU DVFS.
>
> Signed-off-by: Shuwei Wu <shuwei.wu@mailbox.org>
>
> ---
> Changes in v2:
> - Add k1-opp.dtsi with OPP tables for both CPU clusters
> - Assign CPU supplies and include OPP table for Banana Pi BPI-F3
> ---
> arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 35 +++++++-
> arch/riscv/boot/dts/spacemit/k1-opp.dtsi | 105 ++++++++++++++++++++++++
> arch/riscv/boot/dts/spacemit/k1.dtsi | 8 ++
> 3 files changed, 147 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> index 444c3b1e6f44..3780593f610d 100644
> --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> @@ -5,6 +5,7 @@
>
> #include "k1.dtsi"
> #include "k1-pinctrl.dtsi"
> +#include "k1-opp.dtsi"
>
> / {
> model = "Banana Pi BPI-F3";
> @@ -86,6 +87,38 @@ &combo_phy {
> status = "okay";
> };
>
> +&cpu_0 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_1 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_2 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_3 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_4 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_5 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_6 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> +&cpu_7 {
> + cpu-supply = <&buck1_3v45>;
> +};
> +
> &emmc {
> bus-width = <8>;
> mmc-hs400-1_8v;
> @@ -201,7 +234,7 @@ pmic@41 {
> dldoin2-supply = <&buck5>;
>
> regulators {
> - buck1 {
> + buck1_3v45: buck1 {
> regulator-min-microvolt = <500000>;
> regulator-max-microvolt = <3450000>;
> regulator-ramp-delay = <5000>;
> diff --git a/arch/riscv/boot/dts/spacemit/k1-opp.dtsi b/arch/riscv/boot/dts/spacemit/k1-opp.dtsi
> new file mode 100644
> index 000000000000..768ae390686d
> --- /dev/null
> +++ b/arch/riscv/boot/dts/spacemit/k1-opp.dtsi
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +/ {
> + cluster0_opp_table: opp-table-cluster0 {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-614400000 {
> + opp-hz = /bits/ 64 <614400000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-819000000 {
> + opp-hz = /bits/ 64 <819000000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1000000000 {
> + opp-hz = /bits/ 64 <1000000000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1228800000 {
> + opp-hz = /bits/ 64 <1228800000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1600000000 {
> + opp-hz = /bits/ 64 <1600000000>;
> + opp-microvolt = <1050000>;
> + clock-latency-ns = <200000>;
> + };
> + };
> +
> + cluster1_opp_table: opp-table-cluster1 {
> + compatible = "operating-points-v2";
> + opp-shared;
> +
> + opp-614400000 {
> + opp-hz = /bits/ 64 <614400000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-819000000 {
> + opp-hz = /bits/ 64 <819000000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1000000000 {
> + opp-hz = /bits/ 64 <1000000000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1228800000 {
> + opp-hz = /bits/ 64 <1228800000>;
> + opp-microvolt = <950000>;
> + clock-latency-ns = <200000>;
> + };
> +
> + opp-1600000000 {
> + opp-hz = /bits/ 64 <1600000000>;
> + opp-microvolt = <1050000>;
> + clock-latency-ns = <200000>;
> + };
> + };
> +};
> +
> +&cpu_0 {
> + operating-points-v2 = <&cluster0_opp_table>;
> +};
> +
> +&cpu_1 {
> + operating-points-v2 = <&cluster0_opp_table>;
> +};
> +
> +&cpu_2 {
> + operating-points-v2 = <&cluster0_opp_table>;
> +};
> +
> +&cpu_3 {
> + operating-points-v2 = <&cluster0_opp_table>;
> +};
> +
> +&cpu_4 {
> + operating-points-v2 = <&cluster1_opp_table>;
> +};
> +
> +&cpu_5 {
> + operating-points-v2 = <&cluster1_opp_table>;
> +};
> +
> +&cpu_6 {
> + operating-points-v2 = <&cluster1_opp_table>;
> +};
> +
> +&cpu_7 {
> + operating-points-v2 = <&cluster1_opp_table>;
> +};
> diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
> index 529ec68e9c23..bdd109b81730 100644
> --- a/arch/riscv/boot/dts/spacemit/k1.dtsi
> +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
> @@ -54,6 +54,7 @@ cpu_0: cpu@0 {
> compatible = "spacemit,x60", "riscv";
> device_type = "cpu";
> reg = <0>;
> + clocks = <&syscon_apmu CLK_CPU_C0_CORE>;
> riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt";
> riscv,isa-base = "rv64i";
> riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom",
> @@ -84,6 +85,7 @@ cpu_1: cpu@1 {
> compatible = "spacemit,x60", "riscv";
> device_type = "cpu";
> reg = <1>;
> + clocks = <&syscon_apmu CLK_CPU_C0_CORE>;
Based on the Spacemit kernel source, the k1-x_opp_table.dtsi file
defines several additional clocks for the Operating Performance Points
(OPP) table:
clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>,
<&ccu CLK_CCI550>, <&ccu CLK_PLL3>, <&ccu
CLK_CPU_C0_HI>, <&ccu CLK_CPU_C1_HI>;
clock-names = "ace0","ace1","tcm","cci","pll3", "c0hi", "c1hi";
These hardware clocks are also explicitly registered in the APMU clock driver
via the k1_ccu_apmu_hws array, confirming their availability for frequency
and voltage scaling on the K1-X SoC.
static struct clk_hw *k1_ccu_apmu_hws[] = {
[CLK_CCI550] = &cci550_clk.common.hw,
[CLK_CPU_C0_HI] = &cpu_c0_hi_clk.common.hw,
[CLK_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw,
[CLK_CPU_C0_ACE] = &cpu_c0_ace_clk.common.hw,
[CLK_CPU_C0_TCM] = &cpu_c0_tcm_clk.common.hw,
[CLK_CPU_C1_HI] = &cpu_c1_hi_clk.common.hw,
[CLK_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw,
[CLK_CPU_C1_ACE] = &cpu_c1_ace_clk.common.hw,
Yes, it is possible to add these clocks for DVFS to work correctly,
provided they are managed by the appropriate driver and declared in
the Device Tree (DT).
Thanks
-Anand
^ permalink raw reply
* Re: [PATCH v4] ASoC: dt-bindings: ti,pcm3060: add descriptions and rename binding
From: Padmashree S S @ 2026-04-14 13:22 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: k.marinushkin, lgirdwood, broonie, robh, krzk+dt, conor+dt,
linux-sound, devicetree, linux-kernel
In-Reply-To: <20260414-tentacled-mantis-of-control-cb08f3@quoll>
On Tue, Apr 14, 2026 at 12:09 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Tue, Apr 14, 2026 at 09:18:54AM +0530, Padmashree S S wrote:
> > Add description to reg property and overall binding mentioning that this
> > driver supports both I2C and SPI. Rename binding to match compatible
> > naming convention.
> >
> > Signed-off-by: Padmashree S S <padmashreess2006@gmail.com>
> > ---
> > Changes in v4:
> > - Rename binding from pcm3060 to ti,pcm3060
> > - Add binding description
> > - Add description to 'reg' property
> > - Remove unused label in example
> >
> > Changes in v3:
> > - Remove description from 'reg' property
> > ---
> > .../bindings/sound/{pcm3060.yaml => ti,pcm3060.yaml} | 10 +++++-----
>
> What v4 is that of? There is no such file.
>
> Do not attach (thread) your patchsets to some other threads (unrelated
> or older versions). This buries them deep in the mailbox and might
> interfere with applying entire sets. See also:
> https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830
>
> Best regards,
> Krzysztof
>
Thanks for pointing this out.
Since this is a DT binding patch for the same pcm3060 device, I linked
it to the previous version. However, I realize the subject changed
significantly, which made the threading confusing.
I’m planning to resend it as a new patch in a separate thread. Please
let me know if that works.
^ permalink raw reply
* Re: [PATCH v4 00/11] Add support for the TI BQ25792 battery charger
From: Mark Brown @ 2026-04-14 13:07 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Chris Morgan, Liam Girdwood, Sebastian Reichel, Alexey Charkov
Cc: devicetree, linux-kernel, Sebastian Reichel, linux-pm,
Krzysztof Kozlowski, stable
In-Reply-To: <20260311-bq25792-v4-0-7213415d9eec@flipper.net>
On Wed, 11 Mar 2026 15:56:13 +0400, Alexey Charkov wrote:
> This adds support for the TI BQ25792 battery charger, which is similar in
> overall logic to the BQ25703A, but has a different register layout and
> slightly different lower-level programming logic.
>
> The series is organized as follows:
> - Patch 1 adds the new variant to the existing DT binding, including the
> changes in electrical characteristics
> - Patches 2-4 are minor cleanups to the existing BQ25703A OTG regulator
> driver, slimming down the code and making it more reusable for the new
> BQ25792 variant
> - Patch 5 is a logical fix to the BQ25703A clamping logic for VSYSMIN
> (this is a standalone fix which can be applied independently and may be
> backported to stable)
> - Patches 6-8 are slight refactoring of the existing BQ25703A charger
> driver to make it more reusable for the new BQ25792 variant
> - Patch 9 adds platform data to distinguish between the two variants in
> the parent MFD driver, and binds it to the new compatible string
> - Patches 10-11 add variant-specific code to support the new BQ25792
> variant in the regulator part and the charger part respectively,
> selected by the platform data added in patch 9
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
Thanks!
[01/11] dt-bindings: mfd: ti,bq25703a: Expand to include BQ25792
(no commit info)
[02/11] regulator: bq257xx: Remove reference to the parent MFD's dev
https://git.kernel.org/broonie/misc/c/aef4d87f2c1f
[03/11] regulator: bq257xx: Drop the regulator_dev from the driver data
(no commit info)
[04/11] regulator: bq257xx: Make OTG enable GPIO really optional
https://git.kernel.org/broonie/misc/c/de76a763805d
[05/11] power: supply: bq257xx: Fix VSYSMIN clamping logic
(no commit info)
[06/11] power: supply: bq257xx: Make the default current limit a per-chip attribute
(no commit info)
[07/11] power: supply: bq257xx: Consistently use indirect get/set helpers
(no commit info)
[08/11] power: supply: bq257xx: Add fields for 'charging' and 'overvoltage' states
(no commit info)
[09/11] mfd: bq257xx: Add BQ25792 support
(no commit info)
[10/11] regulator: bq257xx: Add support for BQ25792
(no commit info)
[11/11] power: supply: bq257xx: Add support for BQ25792
(no commit info)
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* Re: [PATCH v4 00/11] drm/mxsfb/lcdif: use DRM_BRIDGE_ATTACH_NO_CONNECTOR and the bridge-connector
From: Luca Ceresoli @ 2026-04-14 13:04 UTC (permalink / raw)
To: Marek Vasut, Stefan Agner, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Liu Ying, Rob Herring,
Saravana Kannan, Luca Ceresoli
Cc: Damon Ding, Kory Maincent (TI.com), Hervé Codina, Hui Pu,
Ian Ray, Thomas Petazzoni, dri-devel, imx, linux-arm-kernel,
linux-kernel, devicetree, Adam Ford, Alexander Stein,
Christopher Obbard, Daniel Scally, Emanuele Ghidoli,
Fabio Estevam, Francesco Dolcini, Frieder Schrempf, Gilles Talis,
Goran Rađenović, Heiko Schocher, Josua Mayer,
Kieran Bingham, Marco Felsch, Martyn Welch, Oleksij Rempel,
Peng Fan, Richard Hu, Shengjiu Wang, Stefan Eichenberger,
Vitor Soares
In-Reply-To: <20260407-drm-lcdif-dbanc-v4-0-247a16e61ef9@bootlin.com>
On Tue, 07 Apr 2026 14:24:14 +0200, Luca Ceresoli wrote:
> This series modernizes the i.mx8mp LCDIF driver to use the
> bridge-connector, which is the current best practice in DRM.
>
> == Call for testing on i.MX8MP boards (especially those using HDMI)!
>
> For who tested previous versions (thanks!): some patches have changed
> ingnificantly in v2 and v3 so I had to drop your Tested-by on them. A new
> round of test would still be useful.
>
> [...]
Applied, thanks!
[01/11] drm/mxsfb/lcdif: simplify remote pointer management using __free
commit: 1bff813f8864f72528da4e1b389b62360e9c26ad
[02/11] drm/mxsfb/lcdif: simplify ep pointer management using __free
commit: 23bc92902eddd51e51613790c9c0f9e759fde174
[03/11] drm/mxsfb/lcdif: use dev_err_probe() consistently in lcdif_attach_bridge
commit: b08bfcbc138a450434e9fa38dfd487f687ae7ba3
[04/11] drm/mxsfb/lcdif: move iteration-specific variables declaration inside loop in lcdif_attach_bridge
commit: a6bdf27448b49af6a9daa1d081e2f019fb002a4a
[05/11] drm/bridge: dw-hdmi: document the output_port field
commit: ec9dfa70c2915c2dd3676d674287ee56e52a7ef5
[06/11] drm/bridge: dw-hdmi: warn on unsupported attach combination
commit: 5316b7464c998357c468fcfe3717be6258330708
[07/11] drm/bridge: dw-hdmi: move next_bridge lookup to attach time
commit: 91938b4fdc267931943d3e9f1b14d46d2b615330
[08/11] drm/bridge: imx8mp-hdmi-tx-connector-fixup: add an hdmi-connector when missing using a DT overlay at boot time
commit: 73cb588a6d90849301ef48ac89f3439a8942a890
[09/11] drm/bridge: imx8mp-hdmi-tx-connector-fixup: show a warning when adding the overlay
commit: 1148ef0c600f641f4ea95b3d8275cc911fd2f232
[10/11] drm/bridge: imx8mp-hdmi-tx: switch to DRM_BRIDGE_ATTACH_NO_CONNECTOR
commit: 06a2950fef18c0a8a26bee01b9550bf3006545c6
[11/11] drm/mxsfb/lcdif: use DRM_BRIDGE_ATTACH_NO_CONNECTOR and the bridge-connector
commit: f604819d9cc9532f88bb4cbd76e7227532ce5abb
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply
* Re: [PATCH v3 16/21] drm/panel: jadard-jd9365da-h3: support Waveshare 720p DSI panels
From: Neil Armstrong @ 2026-04-14 12:59 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Cong Yang, Ondrej Jirman,
Javier Martinez Canillas, Jagan Teki, Liam Girdwood, Mark Brown,
Linus Walleij, Bartosz Golaszewski, Jie Gan
Cc: dri-devel, devicetree, linux-kernel, linux-gpio, Riccardo Mereu
In-Reply-To: <20260413-waveshare-dsi-touch-v3-16-3aeb53022c32@oss.qualcomm.com>
On 4/13/26 16:05, Dmitry Baryshkov wrote:
> Add configuration for Waveshare 9.0" and 10.1" 720p DSI panels using
> JD9365 controller.
>
> Tested-by: Riccardo Mereu <r.mereu@arduino.cc>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 312 +++++++++++++++++++++++
> 1 file changed, 312 insertions(+)
>
> diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> index 7744c66514c9..6fff3299f4ad 100644
> --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> @@ -21,6 +21,8 @@
> #include <linux/of.h>
> #include <linux/regulator/consumer.h>
>
> +#include <video/mipi_display.h>
> +
> struct jadard;
>
> struct jadard_panel_desc {
> @@ -2283,6 +2285,49 @@ static const struct jadard_panel_desc waveshare_8_0_inch_a_desc = {
> MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> };
>
> +static int waveshare_10_1_b_init(struct jadard *jadard);
> +
> +static const struct jadard_panel_desc waveshare_9_0_inch_b_desc = {
> + .mode_4ln = &(const struct drm_display_mode) {
> + .clock = (720 + 60 + 60 + 4) * (1280 + 16 + 12 + 4) * 60 / 1000,
> +
> + .hdisplay = 720,
> + .hsync_start = 720 + 60,
> + .hsync_end = 720 + 60 + 60,
> + .htotal = 720 + 60 + 60 + 4,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 16,
> + .vsync_end = 1280 + 16 + 12,
> + .vtotal = 1280 + 16 + 12 + 4,
> +
> + .width_mm = 114,
> + .height_mm = 196,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .mode_2ln = &(const struct drm_display_mode) {
> + .clock = (720 + 50 + 50 + 50) * (1280 + 26 + 12 + 4) * 60 / 1000,
> +
> + .hdisplay = 720,
> + .hsync_start = 720 + 50,
> + .hsync_end = 720 + 50 + 50,
> + .htotal = 720 + 50 + 50 + 50,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 26,
> + .vsync_end = 1280 + 26 + 12,
> + .vtotal = 1280 + 26 + 12 + 4,
> +
> + .width_mm = 114,
> + .height_mm = 196,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_10_1_b_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> static const struct drm_display_mode waveshare_10_1_a_mode = {
> .clock = (800 + 40 + 20 + 20) * (1280 + 20 + 20 + 4) * 60 / 1000,
>
> @@ -2627,6 +2672,265 @@ static const struct jadard_panel_desc waveshare_10_1_inch_a_desc = {
> MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> };
>
> +static int waveshare_10_1_b_init(struct jadard *jadard)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + jadard_enable_standard_cmds(&dsi_ctx);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x3f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xbf);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xbf);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x74);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xa0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x7e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x24);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0xa9);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x38);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x1a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x65);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x52);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x23);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x3f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x34);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x27);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x24);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x65);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x52);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x23);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x3f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x2d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x34);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x27);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x24);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x00);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x51);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x55);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x51);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x51);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x55);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x51);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x11);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x15);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x11);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x11);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x15);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x11);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x66);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x55);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x13);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x66);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xe3);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0xd5);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x21);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x66);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xb3);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x60);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x58);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x0f);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1d);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + msleep(120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + msleep(5);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_TEAR_ON);
> +
> + return 0;
> +}
> +
> +static const struct jadard_panel_desc waveshare_10_1_inch_b_desc = {
> + .mode_4ln = &(const struct drm_display_mode) {
> + .clock = (720 + 60 + 60 + 4) * (1280 + 16 + 12 + 4) * 60 / 1000,
> +
> + .hdisplay = 720,
> + .hsync_start = 720 + 60,
> + .hsync_end = 720 + 60 + 60,
> + .htotal = 720 + 60 + 60 + 4,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 16,
> + .vsync_end = 1280 + 16 + 12,
> + .vtotal = 1280 + 16 + 12 + 4,
> +
> + .width_mm = 125,
> + .height_mm = 222,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .mode_2ln = &(const struct drm_display_mode) {
> + .clock = (720 + 50 + 50 + 50) * (1280 + 26 + 12 + 4) * 60 / 1000,
> +
> + .hdisplay = 720,
> + .hsync_start = 720 + 50,
> + .hsync_end = 720 + 50 + 50,
> + .htotal = 720 + 50 + 50 + 50,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 26,
> + .vsync_end = 1280 + 26 + 12,
> + .vtotal = 1280 + 26 + 12 + 4,
> +
> + .width_mm = 125,
> + .height_mm = 222,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_10_1_b_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> static int jadard_dsi_probe(struct mipi_dsi_device *dsi)
> {
> struct device *dev = &dsi->dev;
> @@ -2762,10 +3066,18 @@ static const struct of_device_id jadard_of_match[] = {
> .compatible = "waveshare,8.0-dsi-touch-a",
> .data = &waveshare_8_0_inch_a_desc
> },
> + {
> + .compatible = "waveshare,9.0-dsi-touch-b",
> + .data = &waveshare_9_0_inch_b_desc
> + },
> {
> .compatible = "waveshare,10.1-dsi-touch-a",
> .data = &waveshare_10_1_inch_a_desc
> },
> + {
> + .compatible = "waveshare,10.1-dsi-touch-b",
> + .data = &waveshare_10_1_inch_b_desc
> + },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, jadard_of_match);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v3 15/21] drm/panel: jadard-jd9365da-h3: support Waveshare WXGA DSI panels
From: Neil Armstrong @ 2026-04-14 12:58 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Cong Yang, Ondrej Jirman,
Javier Martinez Canillas, Jagan Teki, Liam Girdwood, Mark Brown,
Linus Walleij, Bartosz Golaszewski, Jie Gan
Cc: dri-devel, devicetree, linux-kernel, linux-gpio, Riccardo Mereu
In-Reply-To: <20260413-waveshare-dsi-touch-v3-15-3aeb53022c32@oss.qualcomm.com>
On 4/13/26 16:05, Dmitry Baryshkov wrote:
> Add configuration for several Waveshare 8.0" and 10.1" WXGA DSI panels
> using JD9365 controller
>
> Tested-by: Riccardo Mereu <r.mereu@arduino.cc>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 568 +++++++++++++++++++++++
> 1 file changed, 568 insertions(+)
>
> diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> index 61d67efed379..7744c66514c9 100644
> --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> @@ -2067,6 +2067,566 @@ static const struct jadard_panel_desc waveshare_4_0_inch_c_desc = {
> MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> };
>
> +static int waveshare_8_0_a_init(struct jadard *jadard)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + jadard_enable_standard_cmds(&dsi_ctx);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x7e);
> + else
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x4e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x65);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x74);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xb7);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xb7);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x70);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xa0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0xa9);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x78);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x63);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x54);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x38);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x62);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x23);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x78);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x63);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x54);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x38);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x62);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x23);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x10);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x35);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x35);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x6b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x0c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x56);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x7b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xf8);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0xd5);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x2e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x12);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x7b);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xb3);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x60);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x59);
> + if (jadard->dsi->lanes != 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x58);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x0f);
> + }
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + msleep(120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + msleep(60);
> +
> + return 0;
> +}
> +
> +static const struct drm_display_mode waveshare_8_0_a_mode = {
> + .clock = (800 + 40 + 20 + 20) * (1280 + 30 + 12 + 4) * 60 / 1000,
> +
> + .hdisplay = 800,
> + .hsync_start = 800 + 40,
> + .hsync_end = 800 + 40 + 20,
> + .htotal = 800 + 40 + 20 + 20,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 30,
> + .vsync_end = 1280 + 30 + 12,
> + .vtotal = 1280 + 30 + 12 + 4,
> +
> + .width_mm = 107,
> + .height_mm = 172,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +};
> +
> +static const struct jadard_panel_desc waveshare_8_0_inch_a_desc = {
> + .mode_4ln = &waveshare_8_0_a_mode,
> + .mode_2ln = &waveshare_8_0_a_mode,
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_8_0_a_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> +static const struct drm_display_mode waveshare_10_1_a_mode = {
> + .clock = (800 + 40 + 20 + 20) * (1280 + 20 + 20 + 4) * 60 / 1000,
> +
> + .hdisplay = 800,
> + .hsync_start = 800 + 40,
> + .hsync_end = 800 + 40 + 20,
> + .htotal = 800 + 40 + 20 + 20,
> +
> + .vdisplay = 1280,
> + .vsync_start = 1280 + 20,
> + .vsync_end = 1280 + 20 + 20,
> + .vtotal = 1280 + 20 + 20 + 4,
> +
> + .width_mm = 135,
> + .height_mm = 216,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +};
> +
> +static int waveshare_10_1_a_init(struct jadard *jadard)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + jadard_enable_standard_cmds(&dsi_ctx);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x3b);
> + else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x38);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x38);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x74);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xaf);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xaf);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x26);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x78);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xa0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x81);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x23);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0d);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x28);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x69);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x6b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x5c);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x6a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x5b);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x4f);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x4d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x3f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x2b);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x2a);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x43);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x63);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x62);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x52);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x5a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x4f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x4e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x0f);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x59);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x3a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x26);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x6b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x5c);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x6a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x5b);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x4f);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x4d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x3f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x2b);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x2a);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x43);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x63);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x62);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x52);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x5a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x4f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x4e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x0f);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x59);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x3a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x26);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x00);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x37);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x77);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x49);
> + if (jadard->dsi->lanes == 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x37);
> + } else {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x77);
> + }
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x48);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x1f);
> + else
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x30);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x16);
> + else
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x34);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x6a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x1d);
> + else
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x6a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0xdd);
> + if (jadard->dsi->lanes == 4)
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x3f);
> + else
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x2c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x15);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x82);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xb3);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x61);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x48);
> + if (jadard->dsi->lanes != 4) {
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x58);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x0f);
> + }
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe6, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe7, 0x0c);
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + msleep(120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + msleep(60);
> +
> + return dsi_ctx.accum_err;
> +}
> +
> +static const struct jadard_panel_desc waveshare_10_1_inch_a_desc = {
> + .mode_4ln = &waveshare_10_1_a_mode,
> + .mode_2ln = &waveshare_10_1_a_mode,
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_10_1_a_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> static int jadard_dsi_probe(struct mipi_dsi_device *dsi)
> {
> struct device *dev = &dsi->dev;
> @@ -2198,6 +2758,14 @@ static const struct of_device_id jadard_of_match[] = {
> .compatible = "waveshare,4.0-dsi-touch-c",
> .data = &waveshare_4_0_inch_c_desc
> },
> + {
> + .compatible = "waveshare,8.0-dsi-touch-a",
> + .data = &waveshare_8_0_inch_a_desc
> + },
> + {
> + .compatible = "waveshare,10.1-dsi-touch-a",
> + .data = &waveshare_10_1_inch_a_desc
> + },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, jadard_of_match);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v3 14/21] drm/panel: jadard-jd9365da-h3: support Waveshare round DSI panels
From: Neil Armstrong @ 2026-04-14 12:58 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Cong Yang, Ondrej Jirman,
Javier Martinez Canillas, Jagan Teki, Liam Girdwood, Mark Brown,
Linus Walleij, Bartosz Golaszewski, Jie Gan
Cc: dri-devel, devicetree, linux-kernel, linux-gpio, Riccardo Mereu
In-Reply-To: <20260413-waveshare-dsi-touch-v3-14-3aeb53022c32@oss.qualcomm.com>
On 4/13/26 16:05, Dmitry Baryshkov wrote:
> Add configuration for Waveshare 3.4" and 4.0" round DSI panels using
> JD9365 controller.
>
> Tested-by: Riccardo Mereu <r.mereu@arduino.cc>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 476 +++++++++++++++++++++++
> 1 file changed, 476 insertions(+)
>
> diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> index bc079b97cfb3..61d67efed379 100644
> --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> @@ -1599,6 +1599,474 @@ static const struct jadard_panel_desc taiguan_xti05101_01a_desc = {
> .enter_sleep_to_reset_down_delay_ms = 100,
> };
>
> +static int waveshare_3_4_c_init(struct jadard *jadard)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + jadard_enable_standard_cmds(&dsi_ctx);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xd0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xd0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x26);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x78);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x64);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0xc7);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x1b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x56);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x16);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x2f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x32);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x53);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x31);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x56);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x16);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x2f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x32);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x53);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x31);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x0f);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0xa6);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xd9);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x43);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> +
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + msleep(120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + msleep(5);
> + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> +
> + return dsi_ctx.accum_err;
> +}
> +
> +static const struct jadard_panel_desc waveshare_3_4_inch_c_desc = {
> + .mode_2ln = &(const struct drm_display_mode) {
> + .clock = (800 + 40 + 20 + 20) * (800 + 24 + 4 + 12) * 60 / 1000,
> +
> + .hdisplay = 800,
> + .hsync_start = 800 + 40,
> + .hsync_end = 800 + 40 + 20,
> + .htotal = 800 + 40 + 20 + 20,
> +
> + .vdisplay = 800,
> + .vsync_start = 800 + 24,
> + .vsync_end = 800 + 24 + 4,
> + .vtotal = 800 + 24 + 4 + 12,
> +
> + .width_mm = 88,
> + .height_mm = 88,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .lanes = 2,
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_3_4_c_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> +static int waveshare_4_0_c_init(struct jadard *jadard)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> + jadard_enable_standard_cmds(&dsi_ctx);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xd0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xd0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x26);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x78);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x64);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0xc7);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x14);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x1b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x56);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x16);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x2f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x32);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x53);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x31);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x56);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x37);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x25);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x2a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x16);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x2f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x32);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x53);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x4c);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x3d);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x31);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x0f);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x48);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x4a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x44);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x46);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x42);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x5e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x50);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x49);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x4b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x45);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x47);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x57);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x77);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x41);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x07);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x09);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1e);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x0a);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x1f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x17);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0xa6);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x43);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xd9);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x43);
> +
> + jd9365da_switch_page(&dsi_ctx, 0x00);
> +
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + msleep(120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + msleep(5);
> + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> +
> + return dsi_ctx.accum_err;
> +}
> +
> +static const struct jadard_panel_desc waveshare_4_0_inch_c_desc = {
> + .mode_2ln = &(const struct drm_display_mode) {
> + .clock = (720 + 40 + 20 + 20) * (720 + 24 + 4 + 12) * 60 / 1000,
> +
> + .hdisplay = 720,
> + .hsync_start = 720 + 40,
> + .hsync_end = 720 + 40 + 20,
> + .htotal = 720 + 40 + 20 + 20,
> +
> + .vdisplay = 720,
> + .vsync_start = 720 + 24,
> + .vsync_end = 720 + 24 + 4,
> + .vtotal = 720 + 24 + 4 + 12,
> +
> + .width_mm = 88,
> + .height_mm = 88,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> + },
> + .lanes = 2,
> + .format = MIPI_DSI_FMT_RGB888,
> + .init = waveshare_4_0_c_init,
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +};
> +
> static int jadard_dsi_probe(struct mipi_dsi_device *dsi)
> {
> struct device *dev = &dsi->dev;
> @@ -1722,6 +2190,14 @@ static const struct of_device_id jadard_of_match[] = {
> .compatible = "taiguanck,xti05101-01a",
> .data = &taiguan_xti05101_01a_desc
> },
> + {
> + .compatible = "waveshare,3.4-dsi-touch-c",
> + .data = &waveshare_3_4_inch_c_desc
> + },
> + {
> + .compatible = "waveshare,4.0-dsi-touch-c",
> + .data = &waveshare_4_0_inch_c_desc
> + },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, jadard_of_match);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v3 07/21] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel
From: Neil Armstrong @ 2026-04-14 12:57 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Cong Yang, Ondrej Jirman,
Javier Martinez Canillas, Jagan Teki, Liam Girdwood, Mark Brown,
Linus Walleij, Bartosz Golaszewski, Jie Gan
Cc: dri-devel, devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260413-waveshare-dsi-touch-v3-7-3aeb53022c32@oss.qualcomm.com>
On 4/13/26 16:05, Dmitry Baryshkov wrote:
> Add support for the Waveshare 12.3" DSI TOUCH-A panel. According to the
> vendor driver, it uses different mode_flags, so let the panel
> descriptions override driver-wide defaults.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/panel/panel-himax-hx83102.c | 144 +++++++++++++++++++++++++++-
> 1 file changed, 142 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c b/drivers/gpu/drm/panel/panel-himax-hx83102.c
> index 8b2a68ee851e..eab67893da86 100644
> --- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
> +++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
> @@ -29,11 +29,14 @@
> #define HX83102_UNKNOWN_B8 0xb8
> #define HX83102_SETEXTC 0xb9
> #define HX83102_SETMIPI 0xba
> +#define HX83102_UNKNOWN_BB 0xbb
> #define HX83102_SETVDC 0xbc
> #define HX83102_SETBANK 0xbd
> #define HX83102_UNKNOWN_BE 0xbe
> #define HX83102_SETPTBA 0xbf
> #define HX83102_SETSTBA 0xc0
> +#define HX83102_UNKNOWN_C2 0xc2
> +#define HX83102_UNKNOWN_C6 0xc6
> #define HX83102_SETTCON 0xc7
> #define HX83102_SETRAMDMY 0xc8
> #define HX83102_SETPWM 0xc9
> @@ -78,6 +81,7 @@ struct hx83102_panel_desc {
> } size;
>
> bool has_backlight;
> + unsigned long mode_flags;
>
> int (*init)(struct hx83102 *ctx);
> };
> @@ -765,6 +769,111 @@ static int holitech_htf065h045_init(struct hx83102 *ctx)
> return dsi_ctx.accum_err;
> }
>
> +/* This is HX83102-E, assuming commands are the same as the normal HX83102 */
> +static int waveshare_12_3_a_init(struct hx83102 *ctx)
> +{
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETEXTC, 0x83, 0x10, 0x2e);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcd);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_BB, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPCTRL, 0x67, 0x2c, 0xff, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_BE, 0x11, 0x96, 0x89);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D9, 0x04, 0x03, 0x04);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER,
> + 0x10, 0xfa, 0xaf, 0xaf, 0x33, 0x33, 0xb1, 0x4d, 0x2f, 0x36,
> + 0x36, 0x36, 0x36, 0x22, 0x21, 0x15, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP,
> + 0x00, 0xd0, 0x27, 0x80, 0x00, 0x14, 0x40, 0x2c, 0x32, 0x02,
> + 0x00, 0x00, 0x15, 0x20, 0xd7, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC,
> + 0x98, 0xa0, 0x01, 0x01, 0x98, 0xa0, 0x68, 0x50, 0x01, 0xc7,
> + 0x01, 0x58, 0x00, 0xff, 0x00, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_B6, 0x4d, 0x4d, 0xe3);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xfc, 0x85, 0x80);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0x33, 0x33);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0,
> + 0x00, 0x00, 0x00, 0x00, 0x64, 0x04, 0x00, 0x08, 0x08, 0x27,
> + 0x27, 0x22, 0x2f, 0x15, 0x15, 0x04, 0x04, 0x32, 0x10, 0x13,
> + 0x00, 0x13, 0x32, 0x10, 0x1f, 0x00,
> + 0x02, 0x32, 0x17, 0xfd, 0x00, 0x10, 0x00, 0x00, 0x20,
> + 0x30, 0x01, 0x55, 0x21, 0x38, 0x01, 0x55, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA,
> + 0x00, 0x0c, 0x1a, 0x23, 0x2b, 0x4f, 0x64, 0x69, 0x6c, 0x64,
> + 0x77, 0x77, 0x76, 0x80, 0x79, 0x7e, 0x85, 0x9a, 0x97, 0x4d,
> + 0x56, 0x64, 0x70, 0x00, 0x0c, 0x1a, 0x23, 0x2b, 0x4f, 0x64,
> + 0x69, 0x6c, 0x64, 0x77, 0x77, 0x76, 0x80, 0x79, 0x7e, 0x85,
> + 0x9a, 0x97, 0x4d, 0x56, 0x64, 0x76);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x01, 0x9b, 0x01, 0x31);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK,
> + 0x80, 0x36, 0x12, 0x16, 0xc0, 0x28, 0x40, 0x84, 0x22);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0,
> + 0x01, 0x00, 0xfc, 0x00, 0x00, 0x11, 0x10, 0x00, 0x0e, 0x00,
> + 0x01);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x4e, 0x00, 0x33, 0x11, 0x33, 0x88);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xf2, 0x00, 0x02);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSTBA,
> + 0x23, 0x23, 0x22, 0x11, 0xa2, 0x17, 0x00, 0x80, 0x00, 0x00,
> + 0x08, 0x00, 0x63, 0x63);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_C6, 0xf9);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTCON, 0x30);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETRAMDMY,
> + 0x00, 0x04, 0x04, 0x00, 0x00, 0x82, 0x13, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCASCADE, 0x07, 0x04, 0x05);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP1,
> + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x21, 0x20, 0x21, 0x20,
> + 0x01, 0x00, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06, 0x1a, 0x1a,
> + 0x1a, 0x1a, 0x9a, 0x9a, 0x9a, 0x9a, 0x18, 0x18, 0x18, 0x18,
> + 0x21, 0x20, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
> + 0x18, 0x18, 0x18, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP2,
> + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x21, 0x20, 0x21,
> + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x1a, 0x1a,
> + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x18, 0x18, 0x18, 0x18,
> + 0x20, 0x21, 0x20, 0x21, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
> + 0x98, 0x98, 0x98, 0x98);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1,
> + 0x00, 0x34, 0x01, 0x88, 0x0e, 0xbe, 0x0f);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_C2, 0x43, 0xff, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPANEL, 0x02);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x80);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3,
> + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> + 0xaa, 0xaa, 0xaa, 0x80, 0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0x80,
> + 0x2a, 0xaa, 0xaa, 0xaa);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3,
> + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> + 0xaa, 0xaa);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3,
> + 0xff, 0xff, 0xff, 0xff,
> + 0xff, 0xf0, 0xff, 0xff,
> + 0xff, 0xff, 0xff, 0xf0);
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
> +
> + return dsi_ctx.accum_err;
> +};
> +
> static const struct drm_display_mode starry_mode = {
> .clock = 162680,
> .hdisplay = 1200,
> @@ -920,6 +1029,30 @@ static const struct hx83102_panel_desc holitech_htf065h045_desc = {
> .init = holitech_htf065h045_init,
> };
>
> +static const struct drm_display_mode waveshare_12_3_a_mode = {
> + .clock = 95000,
> + .hdisplay = 720,
> + .hsync_start = 720 + 10,
> + .hsync_end = 720 + 10 + 10,
> + .htotal = 720 + 10 + 10 + 12,
> + .vdisplay = 1920,
> + .vsync_start = 1920 + 64,
> + .vsync_end = 1920 + 64 + 18,
> + .vtotal = 1920 + 64 + 18 + 4,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +};
> +
> +static const struct hx83102_panel_desc waveshare_12_3_inch_a_desc = {
> + .modes = &waveshare_12_3_a_mode,
> + .size = {
> + .width_mm = 109,
> + .height_mm = 292,
> + },
> + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> + .init = waveshare_12_3_a_init,
> +};
> +
> static int hx83102_enable(struct drm_panel *panel)
> {
> msleep(130);
> @@ -1168,8 +1301,12 @@ static int hx83102_probe(struct mipi_dsi_device *dsi)
> desc = of_device_get_match_data(&dsi->dev);
> dsi->lanes = 4;
> dsi->format = MIPI_DSI_FMT_RGB888;
> - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
> - MIPI_DSI_MODE_LPM;
> + if (desc->mode_flags)
> + dsi->mode_flags = desc->mode_flags;
> + else
> + dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
> + MIPI_DSI_MODE_LPM;
> ctx->desc = desc;
> ctx->dsi = dsi;
> ret = hx83102_panel_add(ctx);
> @@ -1220,6 +1357,9 @@ static const struct of_device_id hx83102_of_match[] = {
> { .compatible = "holitech,htf065h045",
> .data = &holitech_htf065h045_desc
> },
> + { .compatible = "waveshare,12.3-dsi-touch-a",
> + .data = &waveshare_12_3_inch_a_desc
> + },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, hx83102_of_match);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: socfpga: Add the Agilex7 series SoC's
From: Krzysztof Kozlowski @ 2026-04-14 12:55 UTC (permalink / raw)
To: Dinh Nguyen; +Cc: robh, krzk+dt, conor+dt, devicetree
In-Reply-To: <a2945037-d8c9-45b5-b161-ac55ac9b0835@kernel.org>
On 14/04/2026 14:53, Dinh Nguyen wrote:
>
>
> On 4/14/26 02:17, Krzysztof Kozlowski wrote:
>> On Mon, Apr 13, 2026 at 09:45:52AM -0500, Dinh Nguyen wrote:
>>> The Agilex7 is a series of devices from Altera that are derived from
>>> the Agilex family.
>>>
>>> The Agilex7F device supports PCIE 4.0 and DDR4. The Agilex7I device supports
>>> PCIE 5.0 and DDR4, while the Agilex7M device supports DDR4, DDR5, LPDDR5
>>> and PCIE 5.0.
>>>
>>> All other peripherals from these devices are the same as the Agilex
>>> device.
>>>
>>> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
>>> ---
>>> Documentation/devicetree/bindings/arm/altera.yaml | 10 ++++++++++
>>> 1 file changed, 10 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
>>> index 206686f3eebc..5ee09f8d4698 100644
>>> --- a/Documentation/devicetree/bindings/arm/altera.yaml
>>> +++ b/Documentation/devicetree/bindings/arm/altera.yaml
>>> @@ -115,6 +115,16 @@ properties:
>>> - intel,socfpga-agilex5-socdk-nand
>>> - const: intel,socfpga-agilex5
>>>
>>> + - description: Agilex7 series F, I and M boards
>>> + items:
>>> + - enum:
>>> + - intel,socfpga-agilex7m-socdk
>>> + - enum:
>>> + - intel,socfpga-agilex7f
>>> + - intel,socfpga-agilex7i
>>> + - intel,socfpga-agilex7m
>>> + - const: intel,socfpga-agilex
>>
>> And separate question - why previous soc "agilex" is used as fallback?
>> Even more confusing.
>>
>
> You're right. Sorry for the confusion. The Agilex7M, I, F devices are
> basically "agilex" devices with some few additions (PCIE, DDR5). Maybe I
> should place the Agilex7M/I/F devices into the "agilex" boards area?
Compatibles should be specific and not based on families, thus what is
"intel,socfpga-agilex"? SoC, right?
Then "intel,socfpga-agilex7f" is a new SoC, no?
Best regards,
Krzysztof
^ permalink raw reply
* RE: [PATCH v7 6/6] docs: iio: adc: ad4691: add driver documentation
From: Sabau, Radu bogdan @ 2026-04-14 12:54 UTC (permalink / raw)
To: David Lechner, Lars-Peter Clausen, Hennerich, Michael,
Jonathan Cameron, Sa, Nuno, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Uwe Kleine-König,
Liam Girdwood, Mark Brown, Linus Walleij, Bartosz Golaszewski,
Philipp Zabel, Jonathan Corbet, Shuah Khan
Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <9c36ee85-12da-41e8-b9ab-e32b7ec29e75@baylibre.com>
> -----Original Message-----
> From: David Lechner <dlechner@baylibre.com>
> Sent: Saturday, April 11, 2026 12:39 AM
...
> > +Buffer data format
> > +==================
> > +
> > +The IIO buffer data format (``in_voltageN_type``) is the same across all
> > +paths: 16-bit unsigned big-endian samples with no shift.
> > +
> > ++-------------------------+-------------+----------+-------+
> > +| Path | storagebits | realbits | shift |
> > ++=========================+=============+==========+=======+
> > +| Triggered buffer | 16 | 16 | 0 |
> > ++-------------------------+-------------+----------+-------+
> > +| CNV Burst offload (DMA) | 16 | 16 | 0 |
> > ++-------------------------+-------------+----------+-------+
> > +| Manual offload (DMA) | 16 | 16 | 0 |
> > ++-------------------------+-------------+----------+-------+
>
> Not sure this table is helpful since all values are the same everywhere.
>
> Also, doesn't SPI offload have storagebits == 32?
I tried using 16 storage bits for offload too, and so use the same channels
macro. For Manual its received in the next transfer and for CNV only the
receive transfers are rx streamed, and so 16 storage bits suffice for both.
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: socfpga: Add the Agilex7 series SoC's
From: Dinh Nguyen @ 2026-04-14 12:53 UTC (permalink / raw)
To: Krzysztof Kozlowski; +Cc: robh, krzk+dt, conor+dt, devicetree
In-Reply-To: <20260414-certain-puffin-from-avalon-29ceeb@quoll>
On 4/14/26 02:17, Krzysztof Kozlowski wrote:
> On Mon, Apr 13, 2026 at 09:45:52AM -0500, Dinh Nguyen wrote:
>> The Agilex7 is a series of devices from Altera that are derived from
>> the Agilex family.
>>
>> The Agilex7F device supports PCIE 4.0 and DDR4. The Agilex7I device supports
>> PCIE 5.0 and DDR4, while the Agilex7M device supports DDR4, DDR5, LPDDR5
>> and PCIE 5.0.
>>
>> All other peripherals from these devices are the same as the Agilex
>> device.
>>
>> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
>> ---
>> Documentation/devicetree/bindings/arm/altera.yaml | 10 ++++++++++
>> 1 file changed, 10 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
>> index 206686f3eebc..5ee09f8d4698 100644
>> --- a/Documentation/devicetree/bindings/arm/altera.yaml
>> +++ b/Documentation/devicetree/bindings/arm/altera.yaml
>> @@ -115,6 +115,16 @@ properties:
>> - intel,socfpga-agilex5-socdk-nand
>> - const: intel,socfpga-agilex5
>>
>> + - description: Agilex7 series F, I and M boards
>> + items:
>> + - enum:
>> + - intel,socfpga-agilex7m-socdk
>> + - enum:
>> + - intel,socfpga-agilex7f
>> + - intel,socfpga-agilex7i
>> + - intel,socfpga-agilex7m
>> + - const: intel,socfpga-agilex
>
> And separate question - why previous soc "agilex" is used as fallback?
> Even more confusing.
>
You're right. Sorry for the confusion. The Agilex7M, I, F devices are
basically "agilex" devices with some few additions (PCIE, DDR5). Maybe I
should place the Agilex7M/I/F devices into the "agilex" boards area?
Thanks,
Dinh
^ permalink raw reply
* Re: [PATCH v2 1/8] dt-bindings: thermal: amlogic: Add support for T7
From: Ronald Claveau @ 2026-04-14 12:33 UTC (permalink / raw)
To: Conor Dooley
Cc: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260413-impose-cartel-bd7d18f91a24@spud>
On 4/13/26 5:42 PM, Conor Dooley wrote:
> On Mon, Apr 13, 2026 at 12:52:42PM +0200, Ronald Claveau wrote:
>> Add the amlogic,t7-thermal compatible for the Amlogic T7 thermal sensor.
>>
>> Unlike existing variants which use a phandle to the ao-secure syscon,
>> the T7 relies on a secure monitor interface described by a phandle and
>> a sensor index argument.
>>
>> The T7 integrates multiple thermal sensors, all accessed through the
>> same SMC call. The sensor index argument is required to identify which
>> sensor's calibration data the secure monitor should return, as a single
>> SM_THERMAL_CALIB_READ command serves all of them.
>>
>> Introduce the amlogic,secure-monitor property as a phandle-array and
>> make amlogic,ao-secure or amlogic,secure-monitor conditionally required
>> depending on the compatible.
>>
>> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
>> ---
>> .../bindings/thermal/amlogic,thermal.yaml | 42 ++++++++++++++++++++--
>> 1 file changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
>> index 70b273271754b..1c096116b2dda 100644
>> --- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
>> +++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
>> @@ -21,7 +21,9 @@ properties:
>> - amlogic,g12a-cpu-thermal
>> - amlogic,g12a-ddr-thermal
>> - const: amlogic,g12a-thermal
>> - - const: amlogic,a1-cpu-thermal
>> + - enum:
>> + - amlogic,a1-cpu-thermal
>> + - amlogic,t7-thermal
>>
>> reg:
>> maxItems: 1
>> @@ -42,12 +44,39 @@ properties:
>> '#thermal-sensor-cells':
>> const: 0
>>
>> + amlogic,secure-monitor:
>> + description: phandle to the secure monitor
>> + $ref: /schemas/types.yaml#/definitions/phandle-array
>> + items:
>> + - items:
>> + - description: phandle to the secure monitor
>> + - description: sensor index to get specific calibration data
>> +
>> required:
>> - compatible
>> - reg
>> - interrupts
>> - clocks
>> - - amlogic,ao-secure
>> +
>> +allOf:
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - amlogic,a1-cpu-thermal
>> + - amlogic,g12a-thermal
>> + then:
>> + required:
>> + - amlogic,ao-secure
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + const: amlogic,t7-thermal
>
> This can just be replaced by a else I think.
>
Thank you for your feedback, I will replace this `if` condition by an
`else`.
>> + then:
>> + required:
>> + - amlogic,secure-monitor
>>
>> unevaluatedProperties: false
>>
>> @@ -62,4 +91,13 @@ examples:
>> #thermal-sensor-cells = <0>;
>> amlogic,ao-secure = <&sec_AO>;
>> };
>> + - |
>> + a73_tsensor: temperature-sensor@20000 {
>
> Can drop the label here, it has no users.
>
Ok, I will remove this label.
> Otherwise, seems fine.
>
> Cheers,
> Conor.
>
> pw-bot: changes-requested
>
>> + compatible = "amlogic,t7-thermal";
>> + reg = <0x0 0x20000 0x0 0x50>;
>> + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&clkc_periphs CLKID_TS>;
>> + #thermal-sensor-cells = <0>;
>> + amlogic,secure-monitor = <&sm 1>;
>> + };
>> ...
>>
>> --
>> 2.49.0
>>
--
Best regards,
Ronald
^ permalink raw reply
* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Andy Shevchenko @ 2026-04-14 12:03 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Manivannan Sadhasivam, Manivannan Sadhasivam, Rob Herring,
Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor, Nicolas Schier,
Hans de Goede, Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Krzysztof Kozlowski, Conor Dooley, Marcel Holtmann,
Luiz Augusto von Dentz, Bartosz Golaszewski, Bartosz Golaszewski,
linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, linux-acpi, Hans de Goede,
Bartosz Golaszewski
In-Reply-To: <CAGXv+5EGe59nJctLweEdZjb3MNmMvjuCHngGSfptzN985OiLdg@mail.gmail.com>
On Tue, Apr 14, 2026 at 06:29:02PM +0800, Chen-Yu Tsai wrote:
> On Tue, Apr 14, 2026 at 4:28 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > On Tue, Apr 14, 2026 at 01:03:19PM +0800, Chen-Yu Tsai wrote:
> > > On Tue, Apr 14, 2026 at 12:08 AM Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > On Mon, Apr 13, 2026 at 07:33:12PM +0530, Manivannan Sadhasivam wrote:
> > > > > On Mon, Apr 13, 2026 at 03:54:59PM +0800, Chen-Yu Tsai wrote:
> > > > > > On Thu, Mar 26, 2026 at 01:36:28PM +0530, Manivannan Sadhasivam wrote:
...
> > > > > > - Given that this connector actually represents two devices, how do I
> > > > > > say I want the BT part to be a wakeup source, but not the WiFi part?
> > > > > > Does wakeup-source even work at this point?
> > > > >
> > > > > You can't use the DT property since the devices are not described in DT
> > > > > statically. But you can still use the per-device 'wakeup' sysfs knob to enable
> > > > > wakeup.
> > >
> > > I see. I think not being able to specify generic properties for the devices
> > > on the connector is going to be a bit problematic.
> >
> > This is nature of the open-connectors, especially on the busses that are
> > hotpluggable, like PCIe. We never know what is connected there _ahead_.
>
> I believe what you mean by "hotpluggable" is "user replaceable".
From the OS perspective it's the same. From platform perspective
there is a difference, granted.
> > In other words you can't describe in DT something that may not exist.
>
> But this is actually doable with the PCIe slot representation. The
> properties are put in the device node for the slot. If no card is
> actually inserted in the slot, then no device is created, and the
> device node is left as not associated with anything.
But you need to list all devices in the world if you want to support this
somehow. Yes, probably many of them (or majority) will be enumerated as is,
but some may need an assistance via (dynamic) properties or similar mechanisms.
> It's just that for this new M.2 E-key connector, there aren't separate
> nodes for each interface. And the system doesn't associate the device
> node with the device, because it's no longer a child node of the
> controller or hierarchy, but connected over the OF graph.
>
> Moving over to the E-key connector representation seems like one step
> forward and one step backward in descriptive ability. We gain proper
> power sequencing, but lose generic properties.
The "key" is property of the connector. Hence if you have an idea what can be
common for ALL "key":s, that's probably can be abstracted. Note, I'm not
familiar with the connector framework in the Linux kernel, perhaps it's already
that kind of abstraction.
> The latter part is solvable, but we likely need child nodes under the
> connector for the different interfaces. Properties that make sense for
> one type might not make sense for another.
>
> P.S. We could also just add child device nodes under the controller to
> put the generic properties, but that's splitting the description into
> multiple parts. Let's not go there if at all possible.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v1 1/4] arm64: dts: qcom: Enable secondary mi2s
From: Konrad Dybcio @ 2026-04-14 11:58 UTC (permalink / raw)
To: Kumar Anurag, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Srinivas Kandagatla,
Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
Cc: linux-arm-msm, devicetree, linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-2-kumar.singh@oss.qualcomm.com>
On 4/13/26 11:19 AM, Kumar Anurag wrote:
> Enable secondary mi2s to support HDMI audio.
>
> Signed-off-by: Kumar Anurag <kumar.singh@oss.qualcomm.com>
> ---
[...]
> +&mi2s1_data0 {
> + drive-strength = <8>;
> + bias-disable;
> +};
> +
> +&mi2s1_mclk {
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
> +};
> +
> +&mi2s1_sclk {
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
> +};
> +
> +&mi2s1_ws {
> + drive-strength = <8>;
> + bias-disable;
> + output-high;
For these pins in their "mission mode" function, do we expect these
pincfg settings to ever change (i.e. across boards, will the drive-strength/
bias/output properties differ?)
Konrad
^ permalink raw reply
* Re: [PATCH v3 1/5] arm64: dts: qcom: sm8550: add PCIe MHI register regions
From: Konrad Dybcio @ 2026-04-14 11:53 UTC (permalink / raw)
To: jsandom, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260409-rb5gen2-dts-v3-1-be736355d4b4@axon.com>
On 4/9/26 5:26 PM, Joe Sandom via B4 Relay wrote:
> From: Joe Sandom <jsandom@axon.com>
>
> Add the MHI register regions to the pcie0 and pcie1 controller nodes
> to expose link power state transition counters (L0s/L1/L1.1/L1.2/L2)
> via debugfs. The PCIe host driver uses this region to read the
> link_transition_count from the MHI registers.
>
> Signed-off-by: Joe Sandom <jsandom@axon.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* [PATCH 3/3] arm64: dts: mediatek: mt8395-genio-common: add MT6360 PMIC supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
The Mediatek Genio 1200-EVK board has a MT6360 PMIC, powered by the
board system power rail (VSYS) and an additional system power rail
(VSYS_BUCK).
In the board devicetree, the power supply inputs for its buck and ldo
regulators are either incorrect (LDO_VIN3) or missing (LDO_VIN1/2,
BUCK_VIN1/2).
So, add VSYS_BUCK regulator node and the proper supply inputs for this
PMIC.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
index 01e153137a6f..21dbcabe5e72 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
@@ -209,6 +209,14 @@ reg_vsys: regulator-vsys {
regulator-always-on;
regulator-boot-on;
};
+
+ reg_vsys_buck: regulator-vsys-buck {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_buck";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <®_vsys>;
+ };
};
&adsp {
@@ -486,7 +494,11 @@ otg_vbus_regulator: usb-otg-vbus-regulator {
regulator {
compatible = "mediatek,mt6360-regulator";
- LDO_VIN3-supply = <&mt6360_buck2>;
+ BUCK1_VIN-supply = <®_vsys>;
+ BUCK2_VIN-supply = <®_vsys>;
+ LDO_VIN1-supply = <®_vsys_buck>;
+ LDO_VIN2-supply = <®_vsys_buck>;
+ LDO_VIN3-supply = <®_vsys>;
mt6360_buck1: buck1 {
regulator-name = "emi_vdd2";
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] arm64: dts: mediatek: mt8395-genio-common: add MT6315 PMIC supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
Mediatek Genio 1200-EVK board has two MT6315 PMICs, powered by the
board system power rail (VSYS) and connected to the SPMI interface.
Add VSYS regulator node for system power rail and the supply inputs of
these two PMICs.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
index 62c336e21500..01e153137a6f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
@@ -201,6 +201,14 @@ wifi_fixed_3v3: regulator-2 {
enable-active-high;
regulator-always-on;
};
+
+ /* system wide 4.2V power rail */
+ reg_vsys: regulator-vsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&adsp {
@@ -1238,6 +1246,11 @@ mt6315_6: pmic@6 {
compatible = "mediatek,mt6315-regulator";
reg = <0x6 SPMI_USID>;
+ pvdd1-supply = <®_vsys>;
+ pvdd2-supply = <®_vsys>;
+ pvdd3-supply = <®_vsys>;
+ pvdd4-supply = <®_vsys>;
+
regulators {
mt6315_6_vbuck1: vbuck1 {
regulator-name = "Vbcpu";
@@ -1254,6 +1267,11 @@ mt6315_7: pmic@7 {
compatible = "mediatek,mt6315-regulator";
reg = <0x7 SPMI_USID>;
+ pvdd1-supply = <®_vsys>;
+ pvdd2-supply = <®_vsys>;
+ pvdd3-supply = <®_vsys>;
+ pvdd4-supply = <®_vsys>;
+
regulators {
mt6315_7_vbuck1: vbuck1 {
regulator-name = "Vgpu";
--
2.53.0
^ permalink raw reply related
* [PATCH 1/3] regulator: dt-bindings: mt6360: add buck regulator supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
MT6360 PMIC provides 2 buck and 6 ldo regulators, that have each one a
separate supply.
Currently, the supplies for the ldo regulators are described in the
dt-bindings but the ones for the buck regulators are not.
Add the descriptions for these missing supplies.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
index 9c879bc3c360..cbb74e8e875d 100644
--- a/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
@@ -17,6 +17,10 @@ properties:
compatible:
const: mediatek,mt6360-regulator
+ BUCK1_VIN-supply:
+ description: Input supply phandle(s) for BUCK1
+ BUCK2_VIN-supply:
+ description: Input supply phandle(s) for BUCK2
LDO_VIN1-supply:
description: Input supply phandle(s) for LDO1/2/3
LDO_VIN2-supply:
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] Mediatek Genio 1200-EVK: MT6315/MT6360 PMIC regulator supply cleanup
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
This series goal is to cleanup the power supplies of MT6315 and MT6360
PMIC regulators, that are either missing or incorrect in the Mediatek
Genio 1200-EVK board devicetree.
Patch 1 completes the MT6360 dt-bindings by adding the missing power
supply descriptions for its buck regulators, that already handled by
the mt6360 regulator driver.
Patch 2 adds for the board the MT6315 regulator supply properties, that
were added in the dt-bindings by [1].
Patch 3 adds for the board the MT6360 regulator supply properties and
fixes the existing one.
The series has been tested on Genio 1200-EVK board with a kernel based
on linux-next (tag: next-20260410).
[1]: https://lore.kernel.org/linux-mediatek/20260326081050.1115201-1-wenst@chromium.org/
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Louis-Alexis Eyraud (3):
regulator: dt-bindings: mt6360: add buck regulator supplies
arm64: dts: mediatek: mt8395-genio-common: add MT6315 PMIC supplies
arm64: dts: mediatek: mt8395-genio-common: add MT6360 PMIC supplies
.../bindings/regulator/mt6360-regulator.yaml | 4 +++
.../boot/dts/mediatek/mt8395-genio-common.dtsi | 32 +++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
---
base-commit: f244905cd8cff7a7249cd3dac8a366e02d61ad4f
change-id: 20260413-mtk-g1200-pmic-cleanup-666643b85b52
Best regards,
--
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
^ permalink raw reply
* Re: [PATCH v1 4/4] ASoC: qcom: sc8280xp: don't force S16_LE in hw_params fixup
From: Mark Brown @ 2026-04-14 11:40 UTC (permalink / raw)
To: Kumar Anurag
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, linux-arm-msm, devicetree, linux-kernel,
linux-sound
In-Reply-To: <20260413091937.134469-5-kumar.singh@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 872 bytes --]
On Mon, Apr 13, 2026 at 02:19:37AM -0700, Kumar Anurag wrote:
> The machine driver was unconditionally forcing S16_LE in
> sc8280xp_be_hw_params_fixup(), which prevents links (e.g. HDMI bridges)
> that require 32-bit formats from working. Drop the format override and
> keep only the fixed rate/channels constraints.
> struct snd_interval *channels = hw_param_interval(params,
> SNDRV_PCM_HW_PARAM_CHANNELS);
> - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
>
> rate->min = rate->max = 48000;
> - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
This breaks compressed playback, for compressed streams we need to
override the format since the DSP will be converting an input compressed
stream to a PCM one. See 9565c9d53c5b (ASoC: qcom: sc8280xp: explicitly
set S16LE format in sc8280xp_be_hw_params_fixup()).
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox