* [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits
@ 2026-04-01 7:26 Dmitry Baryshkov
2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov
` (18 more replies)
0 siblings, 19 replies; 52+ messages in thread
From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw)
To: Neil Armstrong, 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
Cc: dri-devel, devicetree, linux-kernel, linux-gpio
The Waveshare DSI TOUCH family of DSI panel kits feature different DSI
video-mode panels, bundled with the separate controlling circuit,
produing necessary voltages from the 3.3V and 5V supplies. Extend panel
drivers to support those Waveshare panels and also add GPIO driver for
the onboard control circuitry.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (19):
dt-bindings: display/panel: himax,hx83102: describe Waveshare panel
dt-bindings: display/panel: himax,hx8394: describe Waveshare panel
dt-bindings: display/panel: jadard,jd9365da-h3: describe Waveshare panel
dt-bindings: display/panel: ilitek,ili9881c: describe Waveshare panel
dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B
drm/of: add helper to count data-lanes on a remote endpoint
drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel
drm/panel: himax-hx8394: set prepare_prev_first
drm/panel: himax-hx8394: simplify hx8394_enable()
drm/panel: himax-hx8394: support Waveshare DSI panels
drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed
drm/panel: jadard-jd9365da-h3: support variable DSI configuration
drm/panel: jadard-jd9365da-h3: set prepare_prev_first
drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels
drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel
drm/panel: add devm_drm_panel_add() helper
drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel
dt-bindings: gpio: describe Waveshare GPIO controller
gpio: add GPIO controller found on Waveshare DSI TOUCH panels
.../bindings/display/panel/focaltech,ota7290b.yaml | 70 +
.../bindings/display/panel/himax,hx83102.yaml | 2 +
.../bindings/display/panel/himax,hx8394.yaml | 2 +
.../bindings/display/panel/ilitek,ili9881c.yaml | 2 +
.../bindings/display/panel/jadard,jd9365da-h3.yaml | 6 +
.../bindings/gpio/waveshare,dsi-touch-gpio.yaml | 100 ++
drivers/gpio/Kconfig | 10 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-waveshare-dsi.c | 220 +++
drivers/gpu/drm/drm_of.c | 34 +
drivers/gpu/drm/drm_panel.c | 23 +
drivers/gpu/drm/panel/Kconfig | 13 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-focaltech-ota7290b.c | 208 +++
drivers/gpu/drm/panel/panel-himax-hx83102.c | 144 +-
drivers/gpu/drm/panel/panel-himax-hx8394.c | 279 +++-
drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 251 +++-
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 1563 ++++++++++++++++++--
include/drm/drm_of.h | 13 +
include/drm/drm_panel.h | 1 +
20 files changed, 2813 insertions(+), 130 deletions(-)
---
base-commit: 3b058d1aeeeff27a7289529c4944291613b364e9
change-id: 20260401-waveshare-dsi-touch-e1717a1ffc40
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 52+ messages in thread* [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:50 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: " Dmitry Baryshkov ` (17 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Describe Waveshare 12.3-DSI-TOUCH-A panel which allegedly uses HX83102 as a panel controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml index 66404b425af3..7667428bf9a8 100644 --- a/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml +++ b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml @@ -30,6 +30,8 @@ properties: - starry,2082109qfh040022-50e # STARRY himax83102-j02 10.51" WUXGA TFT LCD panel - starry,himax83102-j02 + # Waveshare 12.3-DSI-TOUCH-A panel + - waveshare,12.3-dsi-touch-a - const: himax,hx83102 reg: -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov @ 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:38 ` Linus Walleij 2026-04-07 9:50 ` Krzysztof Kozlowski 1 sibling, 1 reply; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-02 8:30 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 01, 2026 at 10:26:20AM +0300, Dmitry Baryshkov wrote: > Describe Waveshare 12.3-DSI-TOUCH-A panel which allegedly uses HX83102 > as a panel controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml > index 66404b425af3..7667428bf9a8 100644 > --- a/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml > +++ b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml > @@ -30,6 +30,8 @@ properties: > - starry,2082109qfh040022-50e > # STARRY himax83102-j02 10.51" WUXGA TFT LCD panel > - starry,himax83102-j02 > + # Waveshare 12.3-DSI-TOUCH-A panel > + - waveshare,12.3-dsi-touch-a I don't think we use '.' in compatibles, so waveshare,12-3-dsi-touch-a Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel 2026-04-02 8:30 ` Krzysztof Kozlowski @ 2026-04-07 9:38 ` Linus Walleij 2026-04-07 9:49 ` Krzysztof Kozlowski 0 siblings, 1 reply; 52+ messages in thread From: Linus Walleij @ 2026-04-07 9:38 UTC (permalink / raw) To: Krzysztof Kozlowski Cc: Dmitry Baryshkov, Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Thu, Apr 2, 2026 at 10:30 AM Krzysztof Kozlowski <krzk@kernel.org> wrote: > On Wed, Apr 01, 2026 at 10:26:20AM +0300, Dmitry Baryshkov wrote: > > + # Waveshare 12.3-DSI-TOUCH-A panel > > + - waveshare,12.3-dsi-touch-a > > I don't think we use '.' in compatibles, so waveshare,12-3-dsi-touch-a Qualcomm happen to use periods in similar cases for their "qualcomm universal peripheral": Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml I don't know if the policy changed since, but that's a big and widespread platform and I never saw it challenged so I think it's kind of established that we do. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel 2026-04-07 9:38 ` Linus Walleij @ 2026-04-07 9:49 ` Krzysztof Kozlowski 0 siblings, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-07 9:49 UTC (permalink / raw) To: Linus Walleij Cc: Dmitry Baryshkov, Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On 07/04/2026 11:38, Linus Walleij wrote: > On Thu, Apr 2, 2026 at 10:30 AM Krzysztof Kozlowski <krzk@kernel.org> wrote: >> On Wed, Apr 01, 2026 at 10:26:20AM +0300, Dmitry Baryshkov wrote: > >>> + # Waveshare 12.3-DSI-TOUCH-A panel >>> + - waveshare,12.3-dsi-touch-a >> >> I don't think we use '.' in compatibles, so waveshare,12-3-dsi-touch-a > > Qualcomm happen to use periods in similar cases for their > "qualcomm universal peripheral": > Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml > > I don't know if the policy changed since, but that's a big and widespread > platform and I never saw it challenged so I think it's kind of established > that we do. That example is ancient, but you are right that this is widespread pattern. I wonder why this 'dot' here felt odd - assumed that 'dot' in version is something else than 'dot' in other place.. dunno, it's fine. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski @ 2026-04-07 9:50 ` Krzysztof Kozlowski 1 sibling, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-07 9:50 UTC (permalink / raw) To: Dmitry Baryshkov, Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio On 01/04/2026 09:26, Dmitry Baryshkov wrote: > Describe Waveshare 12.3-DSI-TOUCH-A panel which allegedly uses HX83102 > as a panel controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml | 2 ++ Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: describe Waveshare panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:50 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: " Dmitry Baryshkov ` (16 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Describe Waveshare 5" and 5" DSI panels which use HX9365-E as a panel controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml index 84e840e0224f..83c343b02835 100644 --- a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml +++ b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml @@ -23,6 +23,8 @@ properties: - hannstar,hsd060bhw4 - microchip,ac40t08a-mipi-panel - powkiddy,x55-panel + - waveshare,5.0-dsi-touch-a + - waveshare,5.5-dsi-touch-a - const: himax,hx8394 - items: - enum: -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: " Dmitry Baryshkov @ 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:50 ` Krzysztof Kozlowski 1 sibling, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-02 8:30 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 01, 2026 at 10:26:21AM +0300, Dmitry Baryshkov wrote: > Describe Waveshare 5" and 5" DSI panels which use HX9365-E as a panel > controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml > index 84e840e0224f..83c343b02835 100644 > --- a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml > +++ b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml > @@ -23,6 +23,8 @@ properties: > - hannstar,hsd060bhw4 > - microchip,ac40t08a-mipi-panel > - powkiddy,x55-panel > + - waveshare,5.0-dsi-touch-a > + - waveshare,5.5-dsi-touch-a Same comment about style. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: " Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski @ 2026-04-07 9:50 ` Krzysztof Kozlowski 1 sibling, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-07 9:50 UTC (permalink / raw) To: Dmitry Baryshkov, Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio On 01/04/2026 09:26, Dmitry Baryshkov wrote: > Describe Waveshare 5" and 5" DSI panels which use HX9365-E as a panel > controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml | 2 ++ > 1 file changed, 2 insertions(+) > Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: describe Waveshare panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: " Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-07 10:46 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: " Dmitry Baryshkov ` (15 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Describe Waveshare DSI panels which use JD9365 as a panel controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- .../devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml b/Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml index e39efb44ed42..4eae802de9fd 100644 --- a/Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml +++ b/Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml @@ -24,6 +24,12 @@ properties: - radxa,display-10hd-ad001 - radxa,display-8hd-ad002 - taiguanck,xti05101-01a + - waveshare,3.4-dsi-touch-c + - waveshare,4.0-dsi-touch-c + - waveshare,8.0-dsi-touch-a + - waveshare,9.0-dsi-touch-b + - waveshare,10.1-dsi-touch-a + - waveshare,10.1-dsi-touch-b - const: jadard,jd9365da-h3 reg: -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: " Dmitry Baryshkov @ 2026-04-07 10:46 ` Krzysztof Kozlowski 0 siblings, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-07 10:46 UTC (permalink / raw) To: Dmitry Baryshkov, Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio On 01/04/2026 09:26, Dmitry Baryshkov wrote: > Describe Waveshare DSI panels which use JD9365 as a panel controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > .../devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml | 6 ++++++ > 1 file changed, 6 insertions(+) Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: describe Waveshare panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (2 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: " Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-02 8:33 ` Krzysztof Kozlowski 2026-04-07 10:46 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B Dmitry Baryshkov ` (14 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Describe Waveshare 7" DSI panel which uses ILI9881 as a panel controller. This panel requires two voltags supplies, so add separate iovcc supply. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml index d979701a00a8..42e35986fbf6 100644 --- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml @@ -24,6 +24,7 @@ properties: - raspberrypi,dsi-7inch - startek,kd050hdfia020 - tdo,tl050hdv35 + - waveshare,7.0-dsi-touch-a - wanchanglong,w552946aaa - wanchanglong,w552946aba - const: ilitek,ili9881c @@ -34,6 +35,7 @@ properties: backlight: true port: true power-supply: true + iovcc-supply: true reset-gpios: true rotation: true -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: " Dmitry Baryshkov @ 2026-04-02 8:33 ` Krzysztof Kozlowski 2026-04-07 10:46 ` Krzysztof Kozlowski 1 sibling, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-02 8:33 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 01, 2026 at 10:26:23AM +0300, Dmitry Baryshkov wrote: > Describe Waveshare 7" DSI panel which uses ILI9881 as a panel > controller. This panel requires two voltags supplies, so add separate typo, voltage supplies > iovcc supply. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > index d979701a00a8..42e35986fbf6 100644 > --- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > @@ -24,6 +24,7 @@ properties: > - raspberrypi,dsi-7inch > - startek,kd050hdfia020 > - tdo,tl050hdv35 > + - waveshare,7.0-dsi-touch-a > - wanchanglong,w552946aaa > - wanchanglong,w552946aba > - const: ilitek,ili9881c > @@ -34,6 +35,7 @@ properties: > backlight: true > port: true > power-supply: true > + iovcc-supply: true > reset-gpios: true > rotation: true Move the allOf to place before additional/unevaluatedProps and disallow it for other variants. Unless you assume that all other devices also could have iovcc, but then please mention it in the commit msg. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: describe Waveshare panel 2026-04-01 7:26 ` [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: " Dmitry Baryshkov 2026-04-02 8:33 ` Krzysztof Kozlowski @ 2026-04-07 10:46 ` Krzysztof Kozlowski 1 sibling, 0 replies; 52+ messages in thread From: Krzysztof Kozlowski @ 2026-04-07 10:46 UTC (permalink / raw) To: Dmitry Baryshkov, Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio On 01/04/2026 09:26, Dmitry Baryshkov wrote: > > diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > index d979701a00a8..42e35986fbf6 100644 > --- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml > @@ -24,6 +24,7 @@ properties: > - raspberrypi,dsi-7inch > - startek,kd050hdfia020 > - tdo,tl050hdv35 > + - waveshare,7.0-dsi-touch-a > - wanchanglong,w552946aaa One more thing, this looks misplace/unsorted. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (3 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: " Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-01 8:52 ` Rob Herring (Arm) 2026-04-01 7:26 ` [PATCH 06/19] drm/of: add helper to count data-lanes on a remote endpoint Dmitry Baryshkov ` (13 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Add schema for the panels using Focaltech OTA7290B controller. For now there is only one such panel, from the Waveshare 8.8 DSI TOUCH-A kit. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- .../bindings/display/panel/focaltech,ota7290b.yaml | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml b/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml new file mode 100644 index 000000000000..da5237404dc5 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/focaltech,ota7290b.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Focaltech OTA7290B DSI panels + +maintainers: + - Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + - const: waveshare,8.88-dsi-touch-a + + reg: + maxItems: 1 + + vdd-supply: + description: supply regulator for VDD, usually 3.3V + + vdda-supply: + description: supply regulator for VDDA, 7-10V + + vcc-supply: + description: supply regulator for VCCIO, usually 1.5V + + reset-gpios: true + backlight: true + rotation: true + port: true + +required: + - compatible + - reg + - vdd-supply + - vccio-supply + - reset-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "waveshare,8.8-dsi-touch-a"; + reg = <0>; + vdd-supply = <&vdd>; + vccio-supply = <&vccio>; + reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; + backlight = <&backlight>; + + port { + endpoint { + remote-endpoint = <&mipi_out_panel>; + }; + }; + }; + }; + +... + -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B 2026-04-01 7:26 ` [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B Dmitry Baryshkov @ 2026-04-01 8:52 ` Rob Herring (Arm) 0 siblings, 0 replies; 52+ messages in thread From: Rob Herring (Arm) @ 2026-04-01 8:52 UTC (permalink / raw) To: Dmitry Baryshkov Cc: devicetree, Thomas Zimmermann, linux-kernel, Linus Walleij, linux-gpio, Krzysztof Kozlowski, Jessica Zhang, Liam Girdwood, Javier Martinez Canillas, Maarten Lankhorst, Cong Yang, David Airlie, dri-devel, Ondrej Jirman, Conor Dooley, Mark Brown, Simona Vetter, Neil Armstrong, Maxime Ripard, Bartosz Golaszewski, Jagan Teki On Wed, 01 Apr 2026 10:26:24 +0300, Dmitry Baryshkov wrote: > Add schema for the panels using Focaltech OTA7290B controller. For now > there is only one such panel, from the Waveshare 8.8 DSI TOUCH-A kit. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > .../bindings/display/panel/focaltech,ota7290b.yaml | 70 ++++++++++++++++++++++ > 1 file changed, 70 insertions(+) > My bot found errors running 'make dt_binding_check' on your patch: yamllint warnings/errors: dtschema/dtc warnings/errors: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: ignoring, error in schema: properties: compatible /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' from schema $id: http://devicetree.org/meta-schemas/keywords.yaml /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.yaml: properties:compatible: [{'const': 'waveshare,8.88-dsi-touch-a'}] is not of type 'object', 'boolean' Traceback (most recent call last): File "/usr/local/bin/dt-doc-validate", line 8, in <module> sys.exit(main()) ~~~~^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/doc_validate.py", line 66, in main ret |= check_doc(f) ~~~~~~~~~^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/doc_validate.py", line 37, in check_doc dtsch.check_schema_refs() ~~~~~~~~~~~~~~~~~~~~~~~^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 241, in check_schema_refs self._check_schema_refs(resolver, self) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 212, in _check_schema_refs self._check_schema_refs(resolver, v, parent=k, is_common=is_common, ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ has_constraint=has_constraint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 216, in _check_schema_refs self._check_schema_refs(resolver, schema[i], parent=parent, is_common=is_common, ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ has_constraint=has_constraint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 203, in _check_schema_refs ref_sch = resolver.lookup(schema['$ref']).contents ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 682, in lookup retrieved = self._registry.get_or_retrieve(uri) File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 422, in get_or_retrieve registry = self.crawl() File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 500, in crawl id = resource.id() File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 231, in id id = self._specification.id_of(self.contents) File "/usr/local/lib/python3.13/dist-packages/referencing/jsonschema.py", line 50, in _dollar_id return contents.get("$id") ^^^^^^^^^^^^ AttributeError: 'list' object has no attribute 'get' Documentation/devicetree/bindings/display/panel/focaltech,ota7290b.example.dtb: /example-0/dsi/panel@0: failed to match any schema with compatible: ['waveshare,8.8-dsi-touch-a'] doc reference errors (make refcheckdocs): See https://patchwork.kernel.org/project/devicetree/patch/20260401-waveshare-dsi-touch-v1-5-5e9119b5a014@oss.qualcomm.com The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema. ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 06/19] drm/of: add helper to count data-lanes on a remote endpoint 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (4 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel Dmitry Baryshkov ` (12 subsequent siblings) 18 siblings, 0 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio If the DSI panel supports versatile lanes configuration, its driver might require determining the number of DSI data lanes, which is usually specified on the DSI host side of the OF graph. Add new helper as a pair to drm_of_get_data_lanes_count_ep() that lets callers determine number of data-lanes on the remote side of the OF graph. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/drm_of.c | 34 ++++++++++++++++++++++++++++++++++ include/drm/drm_of.h | 13 +++++++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 4f65ce729a47..ef6b09316963 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -558,6 +558,40 @@ int drm_of_get_data_lanes_count_ep(const struct device_node *port, } EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); +/** + * drm_of_get_data_lanes_count_remote - Get DSI/(e)DP data lane count by endpoint + * @port: DT port node of the DSI/(e)DP source or sink + * @port_reg: identifier (value of reg property) of the parent port node + * @reg: identifier (value of reg property) of the endpoint node + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements in the remote endpoint and check for + * validity. This variant uses endpoint specifier. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -EINVAL - the "data-lanes" property is unsupported + * * -ENODEV - the "data-lanes" property is missing + */ +int drm_of_get_data_lanes_count_remote(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max) +{ + struct device_node *endpoint, *remote; + int ret; + + endpoint = of_graph_get_endpoint_by_regs(port, port_reg, reg); + remote = of_graph_get_remote_endpoint(endpoint); + of_node_put(endpoint); + ret = drm_of_get_data_lanes_count(remote, min, max); + of_node_put(remote); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_remote); + #if IS_ENABLED(CONFIG_DRM_MIPI_DSI) /** diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index f2f2bf82eff9..7bcc0ccfe0f4 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -62,6 +62,10 @@ int drm_of_get_data_lanes_count_ep(const struct device_node *port, int port_reg, int reg, const unsigned int min, const unsigned int max); +int drm_of_get_data_lanes_count_remote(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max); #else static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port) @@ -140,6 +144,15 @@ drm_of_get_data_lanes_count_ep(const struct device_node *port, { return -EINVAL; } + +static inline int +drm_of_get_data_lanes_count_remote(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max) +{ + return -EINVAL; +} #endif #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_MIPI_DSI) -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (5 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 06/19] drm/of: add helper to count data-lanes on a remote endpoint Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-07 20:12 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first Dmitry Baryshkov ` (11 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio 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); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel 2026-04-01 7:26 ` [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel Dmitry Baryshkov @ 2026-04-07 20:12 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-07 20:12 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio Hi Dmitry, thanks for your patch! On Wed, Apr 1, 2026 at 9:26 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> 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> (...) > +#define HX83102_UNKNOWN_BB 0xbb (...) > +#define HX83102_UNKNOWN_C2 0xc2 > +#define HX83102_UNKNOWN_C6 0xc6 What I am unable to fathom is why Qualcomm, a fortune 500 company, would be unable to muscle out the datasheet for this display controller from the panel vendor and provide some proper names for these defines. Could you try to ask Waveshare to just share the datasheet so you can say what is going on here. If we have too many *UNKNOWN_NN" it will get hard to see of the same code can be introduced and refactored into other inits without risk of breaking something is my thinking here. If it's like ... really hard for you to achieve this I guess I will grumpily accept it but it'd be nice if you try sending the message that we want to know what these things are. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (6 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:08 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() Dmitry Baryshkov ` (10 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Sending DSI commands from the prepare() callback requires DSI link to be up at that point. For DSI hosts is guaranteed only if the panel driver sets the .prepare_prev_first flag. Set it to let these panels work with the DSI hosts which don't power on the link in their .mode_set callback. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-himax-hx8394.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index c4d3e09a228d..d64f3521eb15 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -792,6 +792,8 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) if (ret) return ret; + ctx->panel.prepare_prev_first = true; + drm_panel_add(&ctx->panel); ret = mipi_dsi_attach(dsi); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first 2026-04-01 7:26 ` [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first Dmitry Baryshkov @ 2026-04-08 8:08 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:08 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Sending DSI commands from the prepare() callback requires DSI link to be > up at that point. For DSI hosts is guaranteed only if the panel driver > sets the .prepare_prev_first flag. Set it to let these panels work with > the DSI hosts which don't power on the link in their .mode_set callback. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (7 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:08 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels Dmitry Baryshkov ` (9 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Simplify hx8394_enable() function by using hx8394_disable() instead of open-coding it and mipi_dsi_msleep() instead of manual checks. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-himax-hx8394.c | 41 ++++++++++-------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index d64f3521eb15..1f23c50b6661 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -618,47 +618,34 @@ static const struct hx8394_panel_desc hl055fhav028c_desc = { .init_sequence = hl055fhav028c_init_sequence, }; -static int hx8394_enable(struct drm_panel *panel) +static int hx8394_disable(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - int ret; - - ctx->desc->init_sequence(&dsi_ctx); - - mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); - - if (dsi_ctx.accum_err) - return dsi_ctx.accum_err; - /* Panel is operational 120 msec after reset */ - msleep(120); - - mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); - if (dsi_ctx.accum_err) - goto sleep_in; - - return 0; - -sleep_in: - ret = dsi_ctx.accum_err; - dsi_ctx.accum_err = 0; - /* This will probably fail, but let's try orderly power off anyway. */ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); - mipi_dsi_msleep(&dsi_ctx, 50); + mipi_dsi_msleep(&dsi_ctx, 50); /* about 3 frames */ - return ret; + return dsi_ctx.accum_err; } -static int hx8394_disable(struct drm_panel *panel) +static int hx8394_enable(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); - mipi_dsi_msleep(&dsi_ctx, 50); /* about 3 frames */ + ctx->desc->init_sequence(&dsi_ctx); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + + /* Panel is operational 120 msec after reset */ + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + if (dsi_ctx.accum_err) + hx8394_disable(panel); return dsi_ctx.accum_err; } -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() 2026-04-01 7:26 ` [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() Dmitry Baryshkov @ 2026-04-08 8:08 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:08 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Simplify hx8394_enable() function by using hx8394_disable() instead of > open-coding it and mipi_dsi_msleep() instead of manual checks. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Excellent, thanks! Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (8 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:10 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed Dmitry Baryshkov ` (8 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Enable support for Waveshare 5.0" and 5.5" DSI TOUCH-A panels. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-himax-hx8394.c | 244 +++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index 1f23c50b6661..bf80354567df 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -44,6 +44,7 @@ #define HX8394_CMD_SETID 0xc3 #define HX8394_CMD_SETDDB 0xc4 #define HX8394_CMD_UNKNOWN2 0xc6 +#define HX8394_CMD_UNKNOWN6 0xc7 #define HX8394_CMD_SETCABC 0xc9 #define HX8394_CMD_SETCABCGAIN 0xca #define HX8394_CMD_SETPANEL 0xcc @@ -618,6 +619,247 @@ static const struct hx8394_panel_desc hl055fhav028c_desc = { .init_sequence = hl055fhav028c_init_sequence, }; +static void waveshare_5_0_inch_a_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) +{ + /* 5.19.8 SETEXTC: Set extension command (B9h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETEXTC, + 0xff, 0x83, 0x94); + + /* 5.19.2 SETPOWER: Set power (B1h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPOWER, + 0x48, 0x0a, 0x6a, 0x09, 0x33, 0x54, 0x71, 0x71, 0x2e, 0x45); + + /* 5.19.9 SETMIPI: Set MIPI control (BAh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETMIPI, + 0x61, 0x03, 0x68, 0x6b, 0xb2, 0xc0); + + /* 5.19.3 SETDISP: Set display related register (B2h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETDISP, + 0x00, 0x80, 0x64, 0x0c, 0x06, 0x2f); + + /* 5.19.4 SETCYC: Set display waveform cycles (B4h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETCYC, + 0x1c, 0x78, 0x1c, 0x78, 0x1c, 0x78, 0x01, 0x0c, 0x86, 0x75, + 0x00, 0x3f, 0x1c, 0x78, 0x1c, 0x78, 0x1c, 0x78, 0x01, 0x0c, + 0x86); + + /* 5.19.19 SETGIP0: Set GIP Option0 (D3h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x32, 0x10, + 0x05, 0x00, 0x05, 0x32, 0x13, 0xc1, 0x00, 0x01, 0x32, 0x10, + 0x08, 0x00, 0x00, 0x37, 0x03, 0x07, 0x07, 0x37, 0x05, 0x05, + 0x37, 0x0c, 0x40); + + /* 5.19.20 Set GIP Option1 (D5h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP1, + 0x18, 0x18, 0x18, 0x18, 0x22, 0x23, 0x20, 0x21, 0x04, 0x05, + 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x19, 0x19, 0x19, 0x19); + + /* 5.19.21 Set GIP Option2 (D6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP2, + 0x18, 0x18, 0x19, 0x19, 0x21, 0x20, 0x23, 0x22, 0x03, 0x02, + 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x19, 0x19, 0x18, 0x18); + + /* 5.19.25 SETGAMMA: Set gamma curve related setting (E0h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGAMMA, + 0x07, 0x08, 0x09, 0x0d, 0x10, 0x14, 0x16, 0x13, 0x24, 0x36, + 0x48, 0x4a, 0x58, 0x6f, 0x76, 0x80, 0x97, 0xa5, 0xa8, 0xb5, + 0xc6, 0x62, 0x63, 0x68, 0x6f, 0x72, 0x78, 0x7f, 0x7f, 0x00, + 0x02, 0x08, 0x0d, 0x0c, 0x0e, 0x0f, 0x10, 0x24, 0x36, 0x48, + 0x4a, 0x58, 0x6f, 0x78, 0x82, 0x99, 0xa4, 0xa0, 0xb1, 0xc0, + 0x5e, 0x5e, 0x64, 0x6b, 0x6c, 0x73, 0x7f, 0x7f); + + /* 5.19.17 SETPANEL (CCh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPANEL, + 0x0b); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN1, + 0x1f, 0x73); + + /* 5.19.5 SETVCOM: Set VCOM voltage (B6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETVCOM, + 0x6b, 0x6b); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN3, + 0x02); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x01); + + /* 5.19.2 SETPOWER: Set power (B1h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPOWER, + 0x00); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x00); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN5, + 0x40, 0x81, 0x50, 0x00, 0x1a, 0xfc, 0x01); +}; + +static const struct drm_display_mode waveshare_5_0_inch_a_mode = { + .clock = 70000, + .hdisplay = 720, + .hsync_start = 720 + 40, + .hsync_end = 720 + 40 + 20, + .htotal = 720 + 40 + 20 + 20, + .vdisplay = 1280, + .vsync_start = 1280 + 30, + .vsync_end = 1280 + 30 + 10, + .vtotal = 1280 + 30 + 10 + 4, + .width_mm = 62, + .height_mm = 110, +}; + +static const struct hx8394_panel_desc waveshare_5_0_inch_a_desc = { + .mode = &waveshare_5_0_inch_a_mode, + .lanes = 2, + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = waveshare_5_0_inch_a_init_sequence, +}; + +static const struct drm_display_mode waveshare_5_5_inch_a_mode = { + .clock = 65000, + .hdisplay = 720, + .hsync_start = 720 + 50, + .hsync_end = 720 + 50 + 50, + .htotal = 720 + 50 + 50 + 10, + .vdisplay = 1280, + .vsync_start = 1280 + 15, + .vsync_end = 1280 + 15 + 12, + .vtotal = 1280 + 15 + 12 + 4, + .width_mm = 62, + .height_mm = 110, +}; + +static void waveshare_5_5_inch_a_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) +{ + /* 5.19.8 SETEXTC: Set extension command (B9h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETEXTC, + 0xff, 0x83, 0x94); + + /* 5.19.9 SETMIPI: Set MIPI control (BAh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETMIPI, + 0x61, 0x03, 0x68, 0x6b, 0xb2, 0xc0); + + /* 5.19.2 SETPOWER: Set power (B1h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPOWER, + 0x48, 0x12, 0x72, 0x09, 0x32, 0x54, 0x71, 0x71, 0x57, 0x47); + + /* 5.19.3 SETDISP: Set display related register (B2h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETDISP, + 0x00, 0x80, 0x64, 0x0c, 0x0d, 0x2f); + + /* 5.19.4 SETCYC: Set display waveform cycles (B4h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETCYC, + 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0c, 0x86, 0x75, + 0x00, 0x3f, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0c, + 0x86); + + /* 5.19.5 SETVCOM: Set VCOM voltage (B6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETVCOM, + 0x86, 0x86); + + /* 5.19.19 SETGIP0: Set GIP Option0 (D3h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP0, + 0x00, 0x00, 0x07, 0x07, 0x40, 0x07, 0x0c, 0x00, 0x08, 0x10, + 0x08, 0x00, 0x08, 0x54, 0x15, 0x0a, 0x05, 0x0a, 0x02, 0x15, + 0x06, 0x05, 0x06, 0x47, 0x44, 0x0a, 0x0a, 0x4b, 0x10, 0x07, + 0x07, 0x0c, 0x40); + + /* 5.19.20 Set GIP Option1 (D5h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP1, + 0x1c, 0x1c, 0x1d, 0x1d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x24, 0x25, 0x18, 0x18, + 0x26, 0x27, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x21, + 0x18, 0x18, 0x18, 0x18); + + /* 5.19.21 Set GIP Option2 (D6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP2, + 0x1c, 0x1c, 0x1d, 0x1d, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, + 0x01, 0x00, 0x0b, 0x0a, 0x09, 0x08, 0x21, 0x20, 0x18, 0x18, + 0x27, 0x26, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x25, 0x24, + 0x18, 0x18, 0x18, 0x18); + + /* 5.19.25 SETGAMMA: Set gamma curve related setting (E0h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGAMMA, + 0x00, 0x13, 0x21, 0x28, 0x2b, 0x2e, 0x32, 0x2f, 0x61, 0x6e, + 0x7e, 0x7b, 0x80, 0x8f, 0x91, 0x93, 0x9d, 0x9d, 0x97, 0xa4, + 0xb1, 0x57, 0x55, 0x58, 0x5d, 0x60, 0x67, 0x74, 0x7f, 0x00, + 0x13, 0x21, 0x28, 0x2b, 0x2e, 0x32, 0x2f, 0x61, 0x6e, 0x7d, + 0x7b, 0x7f, 0x8e, 0x90, 0x93, 0x9c, 0x9d, 0x98, 0xa4, 0xb1, + 0x58, 0x55, 0x59, 0x5e, 0x61, 0x68, 0x76, 0x7f); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN1, + 0x1f, 0x31); + + /* 5.19.17 SETPANEL (CCh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPANEL, + 0x07); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN3, + 0x02); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x02); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN4, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x00); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x01); + + /* 5.19.2 SETPOWER: Set power (B1h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPOWER, + 0x00); + + /* 5.19.11 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x00); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN2, + 0xed); + + /* Unknown command, not listed in the HX8394-F datasheet */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN6, + 0x00, 0xc0); +}; + +static const struct hx8394_panel_desc waveshare_5_5_inch_a_desc = { + .mode = &waveshare_5_5_inch_a_mode, + .lanes = 2, + .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = waveshare_5_5_inch_a_init_sequence, +}; + static int hx8394_disable(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); @@ -815,6 +1057,8 @@ static const struct of_device_id hx8394_of_match[] = { { .compatible = "huiling,hl055fhav028c", .data = &hl055fhav028c_desc }, { .compatible = "powkiddy,x55-panel", .data = &powkiddy_x55_desc }, { .compatible = "microchip,ac40t08a-mipi-panel", .data = &mchp_ac40t08a_desc }, + { .compatible = "waveshare,5.0-dsi-touch-a", .data = &waveshare_5_0_inch_a_desc }, + { .compatible = "waveshare,5.5-dsi-touch-a", .data = &waveshare_5_5_inch_a_desc }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, hx8394_of_match); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels 2026-04-01 7:26 ` [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels Dmitry Baryshkov @ 2026-04-08 8:10 ` Linus Walleij 2026-04-09 0:33 ` Dmitry Baryshkov 0 siblings, 1 reply; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:10 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Enable support for Waveshare 5.0" and 5.5" DSI TOUCH-A panels. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> This looks excellent, good documentation and references to (incomplete...) datasheet. Maybe this datasheet has the defs I was complaining about in the other patch? Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels 2026-04-08 8:10 ` Linus Walleij @ 2026-04-09 0:33 ` Dmitry Baryshkov 0 siblings, 0 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-09 0:33 UTC (permalink / raw) To: Linus Walleij Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 08, 2026 at 10:10:13AM +0200, Linus Walleij wrote: > On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov > <dmitry.baryshkov@oss.qualcomm.com> wrote: > > > Enable support for Waveshare 5.0" and 5.5" DSI TOUCH-A panels. > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > > This looks excellent, good documentation and references to (incomplete...) > datasheet. Maybe this datasheet has the defs I was complaining about > in the other patch? No :-( > Reviewed-by: Linus Walleij <linusw@kernel.org> > > Yours, > Linus Walleij -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (9 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:10 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration Dmitry Baryshkov ` (7 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Use existing helper instead of manually coding it. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/Kconfig | 1 + drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 19 ++----------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index d6863b28ddc5..ba527b4d7737 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -337,6 +337,7 @@ config DRM_PANEL_JADARD_JD9365DA_H3 depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE + select DRM_KMS_HELPER help Say Y here if you want to enable support for Jadard JD9365DA-H3 WXGA MIPI DSI panel. The panel support TFT dot matrix LCD with diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index c33c611e03c0..1884ad2404cd 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -12,6 +12,7 @@ #include <drm/drm_modes.h> #include <drm/drm_panel.h> #include <drm/drm_print.h> +#include <drm/drm_probe_helper.h> #include <linux/gpio/consumer.h> #include <linux/delay.h> @@ -149,24 +150,8 @@ static int jadard_get_modes(struct drm_panel *panel, struct drm_connector *connector) { struct jadard *jadard = panel_to_jadard(panel); - const struct drm_display_mode *desc_mode = &jadard->desc->mode; - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(connector->dev, desc_mode); - if (!mode) { - DRM_DEV_ERROR(&jadard->dsi->dev, "failed to add mode %ux%ux@%u\n", - desc_mode->hdisplay, desc_mode->vdisplay, - drm_mode_vrefresh(desc_mode)); - return -ENOMEM; - } - - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); - - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - return 1; + return drm_connector_helper_get_modes_fixed(connector, &jadard->desc->mode); } static enum drm_panel_orientation jadard_panel_get_orientation(struct drm_panel *panel) -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed 2026-04-01 7:26 ` [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed Dmitry Baryshkov @ 2026-04-08 8:10 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:10 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Use existing helper instead of manually coding it. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (10 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first Dmitry Baryshkov ` (6 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Several panels support attachment either using 4 DSI lanes or just 2. In some cases, this requires a different panel mode to fulfill clock requirements. Extend the driver to handle such cases by letting the panel description to omit lanes specification and parsing number of lanes from the DT. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 32 +++++++++++++++++------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 1884ad2404cd..5d9db2e1f28f 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -10,6 +10,7 @@ #include <drm/drm_mipi_dsi.h> #include <drm/drm_modes.h> +#include <drm/drm_of.h> #include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -23,7 +24,8 @@ struct jadard; struct jadard_panel_desc { - const struct drm_display_mode mode; + const struct drm_display_mode *mode_4ln; + const struct drm_display_mode *mode_2ln; unsigned int lanes; enum mipi_dsi_pixel_format format; int (*init)(struct jadard *jadard); @@ -57,7 +59,10 @@ static void jadard_enable_standard_cmds(struct mipi_dsi_multi_context *dsi_ctx) mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe1, 0x93); mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe2, 0x65); mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xe3, 0xf8); - mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03); + if (dsi_ctx->dsi->lanes == 2) + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x01); + else + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03); } static inline struct jadard *panel_to_jadard(struct drm_panel *panel) @@ -151,7 +156,10 @@ static int jadard_get_modes(struct drm_panel *panel, { struct jadard *jadard = panel_to_jadard(panel); - return drm_connector_helper_get_modes_fixed(connector, &jadard->desc->mode); + if (jadard->dsi->lanes == 2) + return drm_connector_helper_get_modes_fixed(connector, jadard->desc->mode_2ln); + else + return drm_connector_helper_get_modes_fixed(connector, jadard->desc->mode_4ln); } static enum drm_panel_orientation jadard_panel_get_orientation(struct drm_panel *panel) @@ -354,7 +362,7 @@ static int radxa_display_8hd_ad002_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc radxa_display_8hd_ad002_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = 70000, .hdisplay = 800, @@ -586,7 +594,7 @@ static int cz101b4001_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc cz101b4001_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = 70000, .hdisplay = 800, @@ -819,7 +827,7 @@ static int kingdisplay_kd101ne3_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc kingdisplay_kd101ne3_40ti_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000, .hdisplay = 800, @@ -1070,7 +1078,7 @@ static int melfas_lmfbx101117480_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc melfas_lmfbx101117480_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000, .hdisplay = 800, @@ -1326,7 +1334,7 @@ static int anbernic_rgds_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc anbernic_rgds_display_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = (640 + 260 + 220 + 260) * (480 + 10 + 2 + 16) * 60 / 1000, .hdisplay = 640, @@ -1562,7 +1570,7 @@ static int taiguan_xti05101_01a_init_cmds(struct jadard *jadard) }; static const struct jadard_panel_desc taiguan_xti05101_01a_desc = { - .mode = { + .mode_4ln = &(const struct drm_display_mode) { .clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000, .hdisplay = 800, @@ -1614,6 +1622,12 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes; + if (!dsi->lanes) { + dsi->lanes = drm_of_get_data_lanes_count_remote(dsi->dev.of_node, 0, -1, 2, 4); + if (dsi->lanes < 0) + return dsi->lanes; + } + dev_dbg(&dsi->dev, "lanes: %d\n", dsi->lanes); jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(jadard->reset)) -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration 2026-04-01 7:26 ` [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration Dmitry Baryshkov @ 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 1 sibling, 0 replies; 52+ messages in thread From: Riccardo Mereu @ 2026-04-07 12:51 UTC (permalink / raw) To: dmitry.baryshkov Cc: airlied, brgl, broonie, conor+dt, devicetree, dri-devel, jagan, javierm, jesszhan0024, krzk+dt, lgirdwood, linusw, linux-gpio, linux-kernel, maarten.lankhorst, megi, mripard, neil.armstrong, robh, simona, tzimmermann, yangcong5, Riccardo Mereu On Wed, 01 Apr 2026 10:26:31 +0300 Dmitry Baryshkov wrote: >From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> >Several panels support attachment either using 4 DSI lanes or just 2. In >some cases, this requires a different panel mode to fulfill clock >requirements. Extend the driver to handle such cases by letting the >panel description to omit lanes specification and parsing number of >lanes from the DT. > >Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Riccardo Mereu <r.mereu@arduino.cc> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration 2026-04-01 7:26 ` [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu @ 2026-04-08 8:15 ` Linus Walleij 2026-04-09 0:35 ` Dmitry Baryshkov 1 sibling, 1 reply; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:15 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio Hi Dmitry, thanks for your patch! On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Several panels support attachment either using 4 DSI lanes or just 2. In > some cases, this requires a different panel mode to fulfill clock > requirements. Extend the driver to handle such cases by letting the > panel description to omit lanes specification and parsing number of > lanes from the DT. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> (...) > + if (dsi_ctx->dsi->lanes == 2) > + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x01); > + else > + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03); If lanes 2 we do unexplicable magic A else we do unexplicable magic B? Do we know more about what is actually going on here? Can you check the datasheet? The patch is nice anyway and no big deal so, so +/- that fixup: Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration 2026-04-08 8:15 ` Linus Walleij @ 2026-04-09 0:35 ` Dmitry Baryshkov 0 siblings, 0 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-09 0:35 UTC (permalink / raw) To: Linus Walleij Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 08, 2026 at 10:15:13AM +0200, Linus Walleij wrote: > Hi Dmitry, > > thanks for your patch! > > On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov > <dmitry.baryshkov@oss.qualcomm.com> wrote: > > > Several panels support attachment either using 4 DSI lanes or just 2. In > > some cases, this requires a different panel mode to fulfill clock > > requirements. Extend the driver to handle such cases by letting the > > panel description to omit lanes specification and parsing number of > > lanes from the DT. > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > (...) > > > + if (dsi_ctx->dsi->lanes == 2) > > + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x01); > > + else > > + mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x80, 0x03); > > If lanes 2 we do unexplicable magic A else we do unexplicable magic B? > > Do we know more about what is actually going on here? > > Can you check the datasheet? The datasheet (you can find it) is pretty useless here. Unfortunately I don't have a second source of information. As far as I know, this value maps directly to the number of lanes and nothing else. > > The patch is nice anyway and no big deal so, so +/- that fixup: > Reviewed-by: Linus Walleij <linusw@kernel.org> > > Yours, > Linus Walleij -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (11 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels Dmitry Baryshkov ` (5 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Sending DSI commands from the prepare() callback requires DSI link to be up at that point. For DSI hosts is guaranteed only if the panel driver sets the .prepare_prev_first flag. Set it to let these panels work with the DSI hosts which don't power on the link in their .mode_set callback. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 5d9db2e1f28f..11b7e07c1af8 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -1652,6 +1652,8 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) if (ret) return ret; + jadard->panel.prepare_prev_first = true; + drm_panel_add(&jadard->panel); mipi_dsi_set_drvdata(dsi, jadard); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first 2026-04-01 7:26 ` [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first Dmitry Baryshkov @ 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 1 sibling, 0 replies; 52+ messages in thread From: Riccardo Mereu @ 2026-04-07 12:51 UTC (permalink / raw) To: dmitry.baryshkov Cc: airlied, brgl, broonie, conor+dt, devicetree, dri-devel, jagan, javierm, jesszhan0024, krzk+dt, lgirdwood, linusw, linux-gpio, linux-kernel, maarten.lankhorst, megi, mripard, neil.armstrong, robh, simona, tzimmermann, yangcong5, Riccardo Mereu On Wed, 01 Apr 2026 10:26:32 +0300 Dmitry Baryshkov wrote: >From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> >Sending DSI commands from the prepare() callback requires DSI link to be >up at that point. For DSI hosts is guaranteed only if the panel driver >sets the .prepare_prev_first flag. Set it to let these panels work with >the DSI hosts which don't power on the link in their .mode_set callback. > >Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Riccardo Mereu <r.mereu@arduino.cc> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first 2026-04-01 7:26 ` [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu @ 2026-04-08 8:15 ` Linus Walleij 1 sibling, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:15 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Sending DSI commands from the prepare() callback requires DSI link to be > up at that point. For DSI hosts is guaranteed only if the panel driver > sets the .prepare_prev_first flag. Set it to let these panels work with > the DSI hosts which don't power on the link in their .mode_set callback. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (12 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-07 12:53 ` Riccardo Mereu 2026-04-08 8:24 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel Dmitry Baryshkov ` (4 subsequent siblings) 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Add configuration for Waveshare DSI panels using JD9365 controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 1524 ++++++++++++++++++++-- 1 file changed, 1440 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 11b7e07c1af8..e9a461239301 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 { @@ -1599,115 +1601,1469 @@ static const struct jadard_panel_desc taiguan_xti05101_01a_desc = { .enter_sleep_to_reset_down_delay_ms = 100, }; -static int jadard_dsi_probe(struct mipi_dsi_device *dsi) +static int waveshare_3_4_c_init(struct jadard *jadard) { - struct device *dev = &dsi->dev; - const struct jadard_panel_desc *desc; - struct jadard *jadard; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; - jadard = devm_drm_panel_alloc(dev, struct jadard, panel, &jadard_funcs, - DRM_MODE_CONNECTOR_DSI); - if (IS_ERR(jadard)) - return PTR_ERR(jadard); + jd9365da_switch_page(&dsi_ctx, 0x00); + jadard_enable_standard_cmds(&dsi_ctx); - desc = of_device_get_match_data(dev); + 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); - if (desc->mode_flags) - dsi->mode_flags = desc->mode_flags; - else - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | - MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_NO_EOT_PACKET; + 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); - dsi->format = desc->format; - dsi->lanes = desc->lanes; - if (!dsi->lanes) { - dsi->lanes = drm_of_get_data_lanes_count_remote(dsi->dev.of_node, 0, -1, 2, 4); - if (dsi->lanes < 0) - return dsi->lanes; - } - dev_dbg(&dsi->dev, "lanes: %d\n", dsi->lanes); + 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); - jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(jadard->reset)) - return dev_err_probe(&dsi->dev, PTR_ERR(jadard->reset), - "failed to get our reset GPIO\n"); + jd9365da_switch_page(&dsi_ctx, 0x00); - jadard->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(jadard->vdd)) - return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vdd), - "failed to get vdd regulator\n"); + 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); - jadard->vccio = devm_regulator_get(dev, "vccio"); - if (IS_ERR(jadard->vccio)) - return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vccio), - "failed to get vccio regulator\n"); + return dsi_ctx.accum_err; +} - ret = of_drm_get_panel_orientation(dev->of_node, &jadard->orientation); - if (ret < 0) - return dev_err_probe(dev, ret, "failed to get orientation\n"); +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, - ret = drm_panel_of_backlight(&jadard->panel); - if (ret) - return ret; + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 20, + .htotal = 800 + 40 + 20 + 20, - jadard->panel.prepare_prev_first = true; + .vdisplay = 800, + .vsync_start = 800 + 24, + .vsync_end = 800 + 24 + 4, + .vtotal = 800 + 24 + 4 + 12, - drm_panel_add(&jadard->panel); + .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, +}; - mipi_dsi_set_drvdata(dsi, jadard); - jadard->dsi = dsi; - jadard->desc = desc; +static int waveshare_4_0_c_init(struct jadard *jadard) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; - ret = mipi_dsi_attach(dsi); - if (ret < 0) - drm_panel_remove(&jadard->panel); + jd9365da_switch_page(&dsi_ctx, 0x00); + jadard_enable_standard_cmds(&dsi_ctx); - return ret; -} + 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); -static void jadard_dsi_remove(struct mipi_dsi_device *dsi) -{ - struct jadard *jadard = mipi_dsi_get_drvdata(dsi); + 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); - mipi_dsi_detach(dsi); - drm_panel_remove(&jadard->panel); + 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 of_device_id jadard_of_match[] = { - { - .compatible = "anbernic,rg-ds-display-bottom", - .data = &anbernic_rgds_display_desc - }, - { - .compatible = "anbernic,rg-ds-display-top", - .data = &anbernic_rgds_display_desc - }, - { - .compatible = "chongzhou,cz101b4001", - .data = &cz101b4001_desc - }, - { - .compatible = "kingdisplay,kd101ne3-40ti", - .data = &kingdisplay_kd101ne3_40ti_desc - }, - { - .compatible = "melfas,lmfbx101117480", - .data = &melfas_lmfbx101117480_desc - }, - { - .compatible = "radxa,display-10hd-ad001", - .data = &cz101b4001_desc +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, }, - { - .compatible = "radxa,display-8hd-ad002", - .data = &radxa_display_8hd_ad002_desc + .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 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 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, + + .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 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; + const struct jadard_panel_desc *desc; + struct jadard *jadard; + int ret; + + jadard = devm_drm_panel_alloc(dev, struct jadard, panel, &jadard_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(jadard)) + return PTR_ERR(jadard); + + desc = of_device_get_match_data(dev); + + if (desc->mode_flags) + dsi->mode_flags = desc->mode_flags; + else + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET; + + dsi->format = desc->format; + dsi->lanes = desc->lanes; + if (!dsi->lanes) { + dsi->lanes = drm_of_get_data_lanes_count_remote(dsi->dev.of_node, 0, -1, 2, 4); + if (dsi->lanes < 0) + return dsi->lanes; + } + dev_dbg(&dsi->dev, "lanes: %d\n", dsi->lanes); + + jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(jadard->reset)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->reset), + "failed to get our reset GPIO\n"); + + jadard->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(jadard->vdd)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vdd), + "failed to get vdd regulator\n"); + + jadard->vccio = devm_regulator_get(dev, "vccio"); + if (IS_ERR(jadard->vccio)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vccio), + "failed to get vccio regulator\n"); + + ret = of_drm_get_panel_orientation(dev->of_node, &jadard->orientation); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get orientation\n"); + + ret = drm_panel_of_backlight(&jadard->panel); + if (ret) + return ret; + + jadard->panel.prepare_prev_first = true; + + drm_panel_add(&jadard->panel); + + mipi_dsi_set_drvdata(dsi, jadard); + jadard->dsi = dsi; + jadard->desc = desc; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) + drm_panel_remove(&jadard->panel); + + return ret; +} + +static void jadard_dsi_remove(struct mipi_dsi_device *dsi) +{ + struct jadard *jadard = mipi_dsi_get_drvdata(dsi); + + mipi_dsi_detach(dsi); + drm_panel_remove(&jadard->panel); +} + +static const struct of_device_id jadard_of_match[] = { + { + .compatible = "anbernic,rg-ds-display-bottom", + .data = &anbernic_rgds_display_desc + }, + { + .compatible = "anbernic,rg-ds-display-top", + .data = &anbernic_rgds_display_desc + }, + { + .compatible = "chongzhou,cz101b4001", + .data = &cz101b4001_desc + }, + { + .compatible = "kingdisplay,kd101ne3-40ti", + .data = &kingdisplay_kd101ne3_40ti_desc + }, + { + .compatible = "melfas,lmfbx101117480", + .data = &melfas_lmfbx101117480_desc + }, + { + .compatible = "radxa,display-10hd-ad001", + .data = &cz101b4001_desc + }, + { + .compatible = "radxa,display-8hd-ad002", + .data = &radxa_display_8hd_ad002_desc }, { .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 + }, + { + .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); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels 2026-04-01 7:26 ` [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels Dmitry Baryshkov @ 2026-04-07 12:53 ` Riccardo Mereu 2026-04-08 8:24 ` Linus Walleij 1 sibling, 0 replies; 52+ messages in thread From: Riccardo Mereu @ 2026-04-07 12:53 UTC (permalink / raw) To: dmitry.baryshkov Cc: airlied, brgl, broonie, conor+dt, devicetree, dri-devel, jagan, javierm, jesszhan0024, krzk+dt, lgirdwood, linusw, linux-gpio, linux-kernel, maarten.lankhorst, megi, mripard, neil.armstrong, robh, simona, tzimmermann, yangcong5, Riccardo Mereu On Wed, 01 Apr 2026 10:26:33 +0300 Dmitry Baryshkov wrote: >From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> >Add configuration for Waveshare DSI panels using JD9365 controller. > >Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Riccardo Mereu <r.mereu@arduino.cc> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels 2026-04-01 7:26 ` [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels Dmitry Baryshkov 2026-04-07 12:53 ` Riccardo Mereu @ 2026-04-08 8:24 ` Linus Walleij 2026-04-09 0:49 ` Dmitry Baryshkov 1 sibling, 1 reply; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:24 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio Hi Dmitry, thanks for your patch! On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Add configuration for Waveshare DSI panels using JD9365 controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Some more words with details on all the panels added perhaps? > - desc = of_device_get_match_data(dev); > + 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); Predictably I'm not very happy with all the unexplained magic and nonestisting defines used here. Do you have some info/defines? But there is also one more thing, this looks like a big "jam table" with just register+value tuples, so construct something like: struct jadard_jam_tbl_entry { u8 reg; u8 val; }; static const struct jadard_jam_tbl_entry jd_3_4_c_init_jam[] = { {0x00, 0x00}, {0x01, 0x41}, ...}; (Ideas taken from drivers/net/dsa/realtek/rtl8366rb.c, take a look for code and all, you get the picture.) Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels 2026-04-08 8:24 ` Linus Walleij @ 2026-04-09 0:49 ` Dmitry Baryshkov 0 siblings, 0 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-09 0:49 UTC (permalink / raw) To: Linus Walleij Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 08, 2026 at 10:24:17AM +0200, Linus Walleij wrote: > Hi Dmitry, > > thanks for your patch! > > On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov > <dmitry.baryshkov@oss.qualcomm.com> wrote: > > > Add configuration for Waveshare DSI panels using JD9365 controller. > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > > Some more words with details on all the panels added perhaps? :D > > > - desc = of_device_get_match_data(dev); > > + 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); > > Predictably I'm not very happy with all the unexplained magic and nonestisting > defines used here. Do you have some info/defines? No, unfortunately. > > But there is also one more thing, this looks like a big "jam table" > with just register+value tuples, so construct something like: > > struct jadard_jam_tbl_entry { > u8 reg; > u8 val; > }; > > static const struct jadard_jam_tbl_entry jd_3_4_c_init_jam[] = { > {0x00, 0x00}, {0x01, 0x41}, ...}; > > (Ideas taken from drivers/net/dsa/realtek/rtl8366rb.c, take a look > for code and all, you get the picture.) Few months ago the code was moved exactly in the opposite direction. We added all _multi() functions and made shure that the code is as efficient as the register tables. On the other hand, having it as a code allows better control. E.g. handling 2/4 lane case would require extra hacks to the register tables, while the code handles that without extra hacks and without loosing effectiveness. > > Yours, > Linus Walleij -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (13 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:26 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper Dmitry Baryshkov ` (3 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Enable support for Waveshare 7.0" DSI TOUCH-A panel. It requires additional voltage regulator, iovcc. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 251 +++++++++++++++++++++++++- 1 file changed, 249 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index 947b47841b01..0652cdb57d11 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -52,6 +52,7 @@ struct ili9881c { const struct ili9881c_desc *desc; struct regulator *power; + struct regulator *iovcc; struct gpio_desc *reset; enum drm_panel_orientation orientation; @@ -1997,6 +1998,205 @@ static const struct ili9881c_instr bsd1218_a101kl68_init[] = { ILI9881C_COMMAND_INSTR(0xd3, 0x3f), }; +static const struct ili9881c_instr waveshare_7inch_a_init[] = { + ILI9881C_SWITCH_PAGE_INSTR(3), + ILI9881C_COMMAND_INSTR(0x01, 0x00), + ILI9881C_COMMAND_INSTR(0x02, 0x00), + ILI9881C_COMMAND_INSTR(0x03, 0x73), + ILI9881C_COMMAND_INSTR(0x04, 0x00), + ILI9881C_COMMAND_INSTR(0x05, 0x00), + ILI9881C_COMMAND_INSTR(0x06, 0x0a), + ILI9881C_COMMAND_INSTR(0x07, 0x00), + ILI9881C_COMMAND_INSTR(0x08, 0x00), + ILI9881C_COMMAND_INSTR(0x09, 0x61), + ILI9881C_COMMAND_INSTR(0x0a, 0x00), + ILI9881C_COMMAND_INSTR(0x0b, 0x00), + ILI9881C_COMMAND_INSTR(0x0c, 0x01), + ILI9881C_COMMAND_INSTR(0x0d, 0x00), + ILI9881C_COMMAND_INSTR(0x0e, 0x00), + ILI9881C_COMMAND_INSTR(0x0f, 0x61), + ILI9881C_COMMAND_INSTR(0x10, 0x61), + ILI9881C_COMMAND_INSTR(0x11, 0x00), + ILI9881C_COMMAND_INSTR(0x12, 0x00), + ILI9881C_COMMAND_INSTR(0x13, 0x00), + ILI9881C_COMMAND_INSTR(0x14, 0x00), + ILI9881C_COMMAND_INSTR(0x15, 0x00), + ILI9881C_COMMAND_INSTR(0x16, 0x00), + ILI9881C_COMMAND_INSTR(0x17, 0x00), + ILI9881C_COMMAND_INSTR(0x18, 0x00), + ILI9881C_COMMAND_INSTR(0x19, 0x00), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0x40), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), + ILI9881C_COMMAND_INSTR(0x20, 0x06), + ILI9881C_COMMAND_INSTR(0x21, 0x01), + ILI9881C_COMMAND_INSTR(0x22, 0x00), + ILI9881C_COMMAND_INSTR(0x23, 0x00), + ILI9881C_COMMAND_INSTR(0x24, 0x00), + ILI9881C_COMMAND_INSTR(0x25, 0x00), + ILI9881C_COMMAND_INSTR(0x26, 0x00), + ILI9881C_COMMAND_INSTR(0x27, 0x00), + ILI9881C_COMMAND_INSTR(0x28, 0x33), + ILI9881C_COMMAND_INSTR(0x29, 0x03), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), + ILI9881C_COMMAND_INSTR(0x30, 0x00), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x32, 0x00), + ILI9881C_COMMAND_INSTR(0x33, 0x00), + ILI9881C_COMMAND_INSTR(0x34, 0x04), + ILI9881C_COMMAND_INSTR(0x35, 0x00), + ILI9881C_COMMAND_INSTR(0x36, 0x00), + ILI9881C_COMMAND_INSTR(0x37, 0x00), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x00), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x00), + ILI9881C_COMMAND_INSTR(0x41, 0x00), + ILI9881C_COMMAND_INSTR(0x42, 0x00), + ILI9881C_COMMAND_INSTR(0x43, 0x00), + ILI9881C_COMMAND_INSTR(0x44, 0x00), + ILI9881C_COMMAND_INSTR(0x50, 0x10), + ILI9881C_COMMAND_INSTR(0x51, 0x32), + ILI9881C_COMMAND_INSTR(0x52, 0x54), + ILI9881C_COMMAND_INSTR(0x53, 0x76), + ILI9881C_COMMAND_INSTR(0x54, 0x98), + ILI9881C_COMMAND_INSTR(0x55, 0xba), + ILI9881C_COMMAND_INSTR(0x56, 0x10), + ILI9881C_COMMAND_INSTR(0x57, 0x32), + ILI9881C_COMMAND_INSTR(0x58, 0x54), + ILI9881C_COMMAND_INSTR(0x59, 0x76), + ILI9881C_COMMAND_INSTR(0x5a, 0x98), + ILI9881C_COMMAND_INSTR(0x5b, 0xba), + ILI9881C_COMMAND_INSTR(0x5c, 0xdc), + ILI9881C_COMMAND_INSTR(0x5d, 0xfe), + ILI9881C_COMMAND_INSTR(0x5e, 0x00), + ILI9881C_COMMAND_INSTR(0x5f, 0x0e), + ILI9881C_COMMAND_INSTR(0x60, 0x0f), + ILI9881C_COMMAND_INSTR(0x61, 0x0c), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x06), + ILI9881C_COMMAND_INSTR(0x64, 0x07), + ILI9881C_COMMAND_INSTR(0x65, 0x02), + ILI9881C_COMMAND_INSTR(0x66, 0x02), + ILI9881C_COMMAND_INSTR(0x67, 0x02), + ILI9881C_COMMAND_INSTR(0x68, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x01), + ILI9881C_COMMAND_INSTR(0x6a, 0x00), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6d, 0x14), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), + ILI9881C_COMMAND_INSTR(0x70, 0x02), + ILI9881C_COMMAND_INSTR(0x71, 0x02), + ILI9881C_COMMAND_INSTR(0x72, 0x02), + ILI9881C_COMMAND_INSTR(0x73, 0x02), + ILI9881C_COMMAND_INSTR(0x74, 0x02), + ILI9881C_COMMAND_INSTR(0x75, 0x0e), + ILI9881C_COMMAND_INSTR(0x76, 0x0f), + ILI9881C_COMMAND_INSTR(0x77, 0x0c), + ILI9881C_COMMAND_INSTR(0x78, 0x0d), + ILI9881C_COMMAND_INSTR(0x79, 0x06), + ILI9881C_COMMAND_INSTR(0x7a, 0x07), + ILI9881C_COMMAND_INSTR(0x7b, 0x02), + ILI9881C_COMMAND_INSTR(0x7c, 0x02), + ILI9881C_COMMAND_INSTR(0x7d, 0x02), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x01), + ILI9881C_COMMAND_INSTR(0x80, 0x00), + ILI9881C_COMMAND_INSTR(0x81, 0x02), + ILI9881C_COMMAND_INSTR(0x82, 0x14), + ILI9881C_COMMAND_INSTR(0x83, 0x15), + ILI9881C_COMMAND_INSTR(0x84, 0x02), + ILI9881C_COMMAND_INSTR(0x85, 0x02), + ILI9881C_COMMAND_INSTR(0x86, 0x02), + ILI9881C_COMMAND_INSTR(0x87, 0x02), + ILI9881C_COMMAND_INSTR(0x88, 0x02), + ILI9881C_COMMAND_INSTR(0x89, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), + + ILI9881C_SWITCH_PAGE_INSTR(4), + ILI9881C_COMMAND_INSTR(0x38, 0x01), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x2a), + ILI9881C_COMMAND_INSTR(0x6f, 0x33), + ILI9881C_COMMAND_INSTR(0x3a, 0x94), + ILI9881C_COMMAND_INSTR(0x8d, 0x14), + ILI9881C_COMMAND_INSTR(0x87, 0xba), + ILI9881C_COMMAND_INSTR(0x26, 0x76), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), + ILI9881C_COMMAND_INSTR(0xb5, 0x06), + ILI9881C_COMMAND_INSTR(0x3b, 0x98), + + ILI9881C_SWITCH_PAGE_INSTR(1), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x53, 0x71), + ILI9881C_COMMAND_INSTR(0x55, 0x8f), + ILI9881C_COMMAND_INSTR(0x40, 0x33), + ILI9881C_COMMAND_INSTR(0x50, 0x96), + ILI9881C_COMMAND_INSTR(0x51, 0x96), + ILI9881C_COMMAND_INSTR(0x60, 0x23), + ILI9881C_COMMAND_INSTR(0xa0, 0x08), + ILI9881C_COMMAND_INSTR(0xa1, 0x1d), + ILI9881C_COMMAND_INSTR(0xa2, 0x2a), + ILI9881C_COMMAND_INSTR(0xa3, 0x10), + ILI9881C_COMMAND_INSTR(0xa4, 0x15), + ILI9881C_COMMAND_INSTR(0xa5, 0x28), + ILI9881C_COMMAND_INSTR(0xa6, 0x1c), + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), + ILI9881C_COMMAND_INSTR(0xa8, 0x7e), + ILI9881C_COMMAND_INSTR(0xa9, 0x1d), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x6b), + ILI9881C_COMMAND_INSTR(0xac, 0x1a), + ILI9881C_COMMAND_INSTR(0xad, 0x18), + ILI9881C_COMMAND_INSTR(0xae, 0x4b), + ILI9881C_COMMAND_INSTR(0xaf, 0x20), + ILI9881C_COMMAND_INSTR(0xb0, 0x27), + ILI9881C_COMMAND_INSTR(0xb1, 0x50), + ILI9881C_COMMAND_INSTR(0xb2, 0x64), + ILI9881C_COMMAND_INSTR(0xb3, 0x39), + ILI9881C_COMMAND_INSTR(0xc0, 0x08), + ILI9881C_COMMAND_INSTR(0xc1, 0x1d), + ILI9881C_COMMAND_INSTR(0xc2, 0x2a), + ILI9881C_COMMAND_INSTR(0xc3, 0x10), + ILI9881C_COMMAND_INSTR(0xc4, 0x15), + ILI9881C_COMMAND_INSTR(0xc5, 0x28), + ILI9881C_COMMAND_INSTR(0xc6, 0x1c), + ILI9881C_COMMAND_INSTR(0xc7, 0x1d), + ILI9881C_COMMAND_INSTR(0xc8, 0x7e), + ILI9881C_COMMAND_INSTR(0xc9, 0x1d), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x6b), + ILI9881C_COMMAND_INSTR(0xcc, 0x1a), + ILI9881C_COMMAND_INSTR(0xcd, 0x18), + ILI9881C_COMMAND_INSTR(0xce, 0x4b), + ILI9881C_COMMAND_INSTR(0xcf, 0x20), + ILI9881C_COMMAND_INSTR(0xd0, 0x27), + ILI9881C_COMMAND_INSTR(0xd1, 0x50), + ILI9881C_COMMAND_INSTR(0xd2, 0x64), + ILI9881C_COMMAND_INSTR(0xd3, 0x39), + + ILI9881C_SWITCH_PAGE_INSTR(0), + ILI9881C_COMMAND_INSTR(0x3a, 0x77), + ILI9881C_COMMAND_INSTR(0x36, 0x00), +}; + static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel) { return container_of(panel, struct ili9881c, panel); @@ -2035,9 +2235,19 @@ static int ili9881c_prepare(struct drm_panel *panel) int ret; /* Power the panel */ + if (ctx->iovcc) { + ret = regulator_enable(ctx->iovcc); + if (ret) + return ret; + } + + msleep(5); ret = regulator_enable(ctx->power); - if (ret) - return ret; + if (ret) { + mctx.accum_err = ret; + goto disable_iovcc; + } + msleep(5); /* And reset it */ @@ -2074,6 +2284,9 @@ static int ili9881c_prepare(struct drm_panel *panel) disable_power: regulator_disable(ctx->power); +disable_iovcc: + if (ctx->iovcc) + regulator_disable(ctx->iovcc); return mctx.accum_err; } @@ -2085,6 +2298,8 @@ static int ili9881c_unprepare(struct drm_panel *panel) mipi_dsi_dcs_set_display_off_multi(&mctx); mipi_dsi_dcs_enter_sleep_mode_multi(&mctx); regulator_disable(ctx->power); + if (ctx->iovcc) + regulator_disable(ctx->iovcc); gpiod_set_value_cansleep(ctx->reset, 1); return 0; @@ -2260,6 +2475,23 @@ static const struct drm_display_mode bsd1218_a101kl68_default_mode = { .height_mm = 170, }; +static const struct drm_display_mode waveshare_7inch_a_mode = { + .clock = 83333, + + .hdisplay = 720, + .hsync_start = 720 + 120, + .hsync_end = 720 + 120 + 100, + .htotal = 720 + 120 + 100 + 100, + + .vdisplay = 1280, + .vsync_start = 1280 + 10, + .vsync_end = 1280 + 10 + 10, + .vtotal = 1280 + 10 + 10 + 10, + + .width_mm = 85, + .height_mm = 154, +}; + static int ili9881c_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -2329,6 +2561,11 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) return dev_err_probe(&dsi->dev, PTR_ERR(ctx->power), "Couldn't get our power regulator\n"); + ctx->iovcc = devm_regulator_get_optional(&dsi->dev, "iovcc"); + if (IS_ERR(ctx->iovcc)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->iovcc), + "Couldn't get our iovcc regulator\n"); + ctx->reset = devm_gpiod_get_optional(&dsi->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset)) return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset), @@ -2454,6 +2691,15 @@ static const struct ili9881c_desc bsd1218_a101kl68_desc = { .lanes = 4, }; +static const struct ili9881c_desc waveshare_7inch_a_desc = { + .init = waveshare_7inch_a_init, + .init_length = ARRAY_SIZE(waveshare_7inch_a_init), + .mode = &waveshare_7inch_a_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_HSE | + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS, + .lanes = 2, +}; + static const struct of_device_id ili9881c_of_match[] = { { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc }, { .compatible = "bestar,bsd1218-a101kl68", .data = &bsd1218_a101kl68_desc }, @@ -2462,6 +2708,7 @@ static const struct of_device_id ili9881c_of_match[] = { { .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc }, { .compatible = "wanchanglong,w552946aaa", .data = &w552946aaa_desc }, { .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc }, + { .compatible = "waveshare,7.0-dsi-touch-a", .data = &waveshare_7inch_a_desc }, { .compatible = "ampire,am8001280g", .data = &am8001280g_desc }, { .compatible = "raspberrypi,dsi-5inch", &rpi_5inch_desc }, { .compatible = "raspberrypi,dsi-7inch", &rpi_7inch_desc }, -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel 2026-04-01 7:26 ` [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel Dmitry Baryshkov @ 2026-04-08 8:26 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:26 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio Hi Dmitry, thanks for your patch! On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Enable support for Waveshare 7.0" DSI TOUCH-A panel. It requires > additional voltage regulator, iovcc. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> (...) > + ILI9881C_COMMAND_INSTR(0x01, 0x00), > + ILI9881C_COMMAND_INSTR(0x02, 0x00), Same comment about using a jam table here. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (14 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:25 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel Dmitry Baryshkov ` (2 subsequent siblings) 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Add devm_drm_panel_add(), devres-managed version of drm_panel_add(). It's not uncommon for the panel drivers to use devres functions for most of the resources. Provide corresponding replacement for drm_panel_add(). Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/drm_panel.c | 23 +++++++++++++++++++++++ include/drm/drm_panel.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index d1e6598ea3bc..a6029b699b73 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c @@ -101,6 +101,29 @@ void drm_panel_remove(struct drm_panel *panel) } EXPORT_SYMBOL(drm_panel_remove); +static void drm_panel_add_release(void *data) +{ + drm_panel_remove(data); +} + +/** + * devm_drm_panel_add - add a panel to the global registry using devres + * @panel: panel to add + * + * Add a panel to the global registry so that it can be looked + * up by display drivers. The panel to be added must have been + * allocated by devm_drm_panel_alloc(). Unlike drm_panel_add() with this + * function there is no need to call drm_panel_remove(), it will be called + * automatically. + */ +int devm_drm_panel_add(struct device *dev, struct drm_panel *panel) +{ + drm_panel_add(panel); + + return devm_add_action_or_reset(dev, drm_panel_add_release, panel); +} +EXPORT_SYMBOL(devm_drm_panel_add); + /** * drm_panel_prepare - power on a panel * @panel: DRM panel diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 2407bfa60236..1fb9148dd095 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -329,6 +329,7 @@ void drm_panel_put(struct drm_panel *panel); void drm_panel_add(struct drm_panel *panel); void drm_panel_remove(struct drm_panel *panel); +int devm_drm_panel_add(struct device *dev, struct drm_panel *panel); void drm_panel_prepare(struct drm_panel *panel); void drm_panel_unprepare(struct drm_panel *panel); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper 2026-04-01 7:26 ` [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper Dmitry Baryshkov @ 2026-04-08 8:25 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:25 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Add devm_drm_panel_add(), devres-managed version of drm_panel_add(). > It's not uncommon for the panel drivers to use devres functions for most > of the resources. Provide corresponding replacement for drm_panel_add(). > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (15 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-08 8:27 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels Dmitry Baryshkov 18 siblings, 1 reply; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio Add driver for the panel found on Waveshare 8.8" DSI TOUCH-A kit. It uses ota7290b IC as a controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpu/drm/panel/Kconfig | 12 ++ drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-focaltech-ota7290b.c | 208 +++++++++++++++++++++++ 3 files changed, 221 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ba527b4d7737..979109c27b9b 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -144,6 +144,18 @@ config DRM_PANEL_FEIYANG_FY07024DI26A30D Say Y if you want to enable support for panels based on the Feiyang FY07024DI26A30-D MIPI-DSI interface. +config DRM_PANEL_FOCALTECH_OTA7290B + tristate "Focaltech OTA7290B" + depends on DRM_MIPI_DSI + depends on I2C + depends on BACKLIGHT_CLASS_DEVICE + select DRM_KMS_HELPER + help + Enable support for panels using OTA7290B as a controller (for + example, Waveshare 12.3" DSI TOUCH-A panel). Say Y here if you want + to enable support for this panel. To compile this driver as a module, + choose M here. + config DRM_PANEL_DSI_CM tristate "Generic DSI command mode panels" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index a4291dc3905b..0d694acbfbb6 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_DRM_PANEL_EBBG_FT8719) += panel-ebbg-ft8719.o obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o +obj-$(CONFIG_DRM_PANEL_FOCALTECH_OTA7290B) += panel-focaltech-ota7290b.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX8279) += panel-himax-hx8279.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX83102) += panel-himax-hx83102.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX83112A) += panel-himax-hx83112a.o diff --git a/drivers/gpu/drm/panel/panel-focaltech-ota7290b.c b/drivers/gpu/drm/panel/panel-focaltech-ota7290b.c new file mode 100644 index 000000000000..991d6a4caf17 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-focaltech-ota7290b.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Waveshare International Limited + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> + +#include <linux/gpio/consumer.h> +#include <linux/regulator/consumer.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +struct ota7290b { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator *power; + struct gpio_desc *reset; + struct regulator *avdd; + struct regulator *iovcc; + + enum drm_panel_orientation orientation; +}; + +static inline struct ota7290b *panel_to_ota(struct drm_panel *panel) +{ + return container_of(panel, struct ota7290b, panel); +} + +static int ota7290b_prepare(struct drm_panel *panel) +{ + struct ota7290b *ctx = panel_to_ota(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + int ret; + + if (ctx->iovcc) { + ret = regulator_enable(ctx->iovcc); + if (ret) + dev_err(panel->dev, "failed to enable IO regulator: %d\n", ret); + } + + if (ctx->avdd) { + ret = regulator_enable(ctx->avdd); + if (ret) + dev_err(panel->dev, "failed to enable AVDD regulator: %d\n", ret); + } + + if (ctx->reset) { + gpiod_set_value_cansleep(ctx->reset, 0); + msleep(60); + gpiod_set_value_cansleep(ctx->reset, 1); + msleep(60); + gpiod_set_value_cansleep(ctx->reset, 0); + msleep(60); + } + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 50); + + if (dsi_ctx.accum_err < 0) + dev_err(panel->dev, "failed to init panel: %d\n", ret); + + return dsi_ctx.accum_err; +} + +static int ota7290b_unprepare(struct drm_panel *panel) +{ + struct ota7290b *ctx = panel_to_ota(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + + if (ctx->reset) { + gpiod_set_value_cansleep(ctx->reset, 1); + msleep(5); + } + + if (ctx->avdd) + regulator_disable(ctx->avdd); + + if (ctx->iovcc) + regulator_disable(ctx->iovcc); + + return 0; +} + +static const struct drm_display_mode waveshare_dsi_touch_8_8_a_mode = { + .clock = 75000, + + .hdisplay = 480, + .hsync_start = 480 + 50, + .hsync_end = 480 + 50 + 50, + .htotal = 480 + 50 + 50 + 50, + + .vdisplay = 1920, + .vsync_start = 1920 + 20, + .vsync_end = 1920 + 20 + 20, + .vtotal = 1920 + 20 + 20 + 20, + + .width_mm = 68, + .height_mm = 219, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int ota7290b_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &waveshare_dsi_touch_8_8_a_mode); +} + +static enum drm_panel_orientation ota7290b_get_orientation(struct drm_panel *panel) +{ + struct ota7290b *ctx = panel_to_ota(panel); + + return ctx->orientation; +} + +static const struct drm_panel_funcs ota7290b_funcs = { + .prepare = ota7290b_prepare, + .unprepare = ota7290b_unprepare, + .get_modes = ota7290b_get_modes, + .get_orientation = ota7290b_get_orientation, +}; + +static int ota7290b_probe(struct mipi_dsi_device *dsi) +{ + struct ota7290b *ctx; + int ret; + + ctx = devm_drm_panel_alloc(&dsi->dev, struct ota7290b, panel, + &ota7290b_funcs, + DRM_MODE_CONNECTOR_DSI); + if (!ctx) + return -ENOMEM; + mipi_dsi_set_drvdata(dsi, ctx); + ctx->dsi = dsi; + + ctx->reset = devm_gpiod_get_optional(&dsi->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset), + "Couldn't get our reset GPIO\n"); + + ctx->iovcc = devm_regulator_get_optional(&dsi->dev, "iovcc"); + if (IS_ERR(ctx->iovcc)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->iovcc), + "Couldn't get our iovcc supply\n"); + + ctx->avdd = devm_regulator_get_optional(&dsi->dev, "avdd"); + if (IS_ERR(ctx->avdd)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->avdd), + "Couldn't get our avdd supply\n"); + + ret = of_drm_get_panel_orientation( + dsi->dev.of_node, &ctx->orientation); + if (ret) { + dev_err(&dsi->dev, "%pOF: failed to get orientation: %d\n", + dsi->dev.of_node, ret); + return ret; + } + + ret = drm_panel_of_backlight(&ctx->panel); + if (ret) + return ret; + + ctx->panel.prepare_prev_first = true; + + ret = devm_drm_panel_add(&dsi->dev, &ctx->panel); + if (ret) + return ret; + + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_HSE | + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS, + dsi->format = MIPI_DSI_FMT_RGB888, + dsi->lanes = 2; + + return devm_mipi_dsi_attach(&dsi->dev, dsi); +} + +static const struct of_device_id ota7290b_of_match[] = { + { .compatible = "waveshare,8.8-dsi-touch-a", }, + {} +}; +MODULE_DEVICE_TABLE(of, ota7290b_of_match); + +static struct mipi_dsi_driver ota7290b_driver = { + .probe = ota7290b_probe, + .driver = { + .name = "focaltech-ota7290b", + .of_match_table = ota7290b_of_match, + }, +}; +module_mipi_dsi_driver(ota7290b_driver); + +MODULE_DESCRIPTION("Panel driver for Focaltech OTA7290B panels"); +MODULE_LICENSE("GPL"); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel 2026-04-01 7:26 ` [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel Dmitry Baryshkov @ 2026-04-08 8:27 ` Linus Walleij 0 siblings, 0 replies; 52+ messages in thread From: Linus Walleij @ 2026-04-08 8:27 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Neil Armstrong, 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, Bartosz Golaszewski, dri-devel, devicetree, linux-kernel, linux-gpio On Wed, Apr 1, 2026 at 9:27 AM Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> wrote: > Add driver for the panel found on Waveshare 8.8" DSI TOUCH-A kit. It > uses ota7290b IC as a controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (16 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-01 8:52 ` Rob Herring (Arm) 2026-04-07 12:53 ` Riccardo Mereu 2026-04-01 7:26 ` [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels Dmitry Baryshkov 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio The Waveshare DSI TOUCH family of panels has separate on-board GPIO controller, which controls power supplies to the panel and the touch screen and provides reset pins for both the panel and the touchscreen. Also it provides a simple PWM controller for panel backlight. Add bindings for these GPIO controllers. As overall integration might be not very obvious (and it differs significantly from the bindings used by the original drivers), provide complete example with the on-board regulators and the DSI panel. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- .../bindings/gpio/waveshare,dsi-touch-gpio.yaml | 100 +++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.yaml b/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.yaml new file mode 100644 index 000000000000..2e622b668f2f --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/waveshare,dsi-touch-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Waveshare GPIO controller on DSI TOUCH panels + +maintainers: + - Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> + +description: + Waveshare DSI TOUCH panel kits contain separate GPIO controller for toggling + power supplies and panel / touchscreen resets. + +properties: + compatible: + const: waveshare,dsi-touch-gpio + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + wsgpio: gpio@45 { + compatible = "waveshare,dsi-touch-gpio"; + reg = <0x45>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + panel_avdd: regulator-panel-avdd { + compatible = "regulator-fixed"; + regulator-name = "panel-avdd"; + gpios = <&wsgpio 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + panel_iovcc: regulator-panel-iovcc { + compatible = "regulator-fixed"; + regulator-name = "panel-iovcc"; + gpios = <&wsgpio 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + panel_vcc: regulator-panel-vcc { + compatible = "regulator-fixed"; + regulator-name = "panel-vcc"; + gpios = <&wsgpio 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + dsi_panel: dsi_panel@0 { + reg = <0>; + compatible = "waveshare,8.0-dsi-touch-a", "jadard,jd9365da-h3"; + reset-gpio = <&wsgpio 1 GPIO_ACTIVE_LOW>; + vdd-supply = <&panel_avdd>; + iovcc-supply = <&panel_iovcc>; + backlight = <&wsgpio>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + data-lanes = <0 1 2 3>; + remote-endpoint = <&panel_in>; + }; + }; + }; +... -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller 2026-04-01 7:26 ` [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller Dmitry Baryshkov @ 2026-04-01 8:52 ` Rob Herring (Arm) 2026-04-07 12:53 ` Riccardo Mereu 1 sibling, 0 replies; 52+ messages in thread From: Rob Herring (Arm) @ 2026-04-01 8:52 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Javier Martinez Canillas, Jagan Teki, Maarten Lankhorst, Ondrej Jirman, Bartosz Golaszewski, Linus Walleij, Thomas Zimmermann, Krzysztof Kozlowski, Cong Yang, Liam Girdwood, Simona Vetter, David Airlie, Maxime Ripard, Mark Brown, linux-kernel, Conor Dooley, Neil Armstrong, Jessica Zhang, devicetree, linux-gpio, dri-devel On Wed, 01 Apr 2026 10:26:37 +0300, Dmitry Baryshkov wrote: > The Waveshare DSI TOUCH family of panels has separate on-board GPIO > controller, which controls power supplies to the panel and the touch > screen and provides reset pins for both the panel and the touchscreen. > Also it provides a simple PWM controller for panel backlight. > > Add bindings for these GPIO controllers. As overall integration might be > not very obvious (and it differs significantly from the bindings used by > the original drivers), provide complete example with the on-board > regulators and the DSI panel. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > .../bindings/gpio/waveshare,dsi-touch-gpio.yaml | 100 +++++++++++++++++++++ > 1 file changed, 100 insertions(+) > My bot found errors running 'make dt_binding_check' on your patch: yamllint warnings/errors: dtschema/dtc warnings/errors: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.example.dtb: dsi_panel@0 (waveshare,8.0-dsi-touch-a): 'iovcc-supply', 'reset-gpio' do not match any of the regexes: '^pinctrl-[0-9]+$' from schema $id: http://devicetree.org/schemas/display/panel/jadard,jd9365da-h3.yaml /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.example.dtb: dsi_panel@0 (waveshare,8.0-dsi-touch-a): 'vccio-supply' is a required property from schema $id: http://devicetree.org/schemas/display/panel/jadard,jd9365da-h3.yaml /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/gpio/waveshare,dsi-touch-gpio.example.dtb: dsi_panel@0 (waveshare,8.0-dsi-touch-a): 'reset-gpios' is a required property from schema $id: http://devicetree.org/schemas/display/panel/jadard,jd9365da-h3.yaml doc reference errors (make refcheckdocs): See https://patchwork.kernel.org/project/devicetree/patch/20260401-waveshare-dsi-touch-v1-18-5e9119b5a014@oss.qualcomm.com The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema. ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller 2026-04-01 7:26 ` [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller Dmitry Baryshkov 2026-04-01 8:52 ` Rob Herring (Arm) @ 2026-04-07 12:53 ` Riccardo Mereu 1 sibling, 0 replies; 52+ messages in thread From: Riccardo Mereu @ 2026-04-07 12:53 UTC (permalink / raw) To: dmitry.baryshkov Cc: airlied, brgl, broonie, conor+dt, devicetree, dri-devel, jagan, javierm, jesszhan0024, krzk+dt, lgirdwood, linusw, linux-gpio, linux-kernel, maarten.lankhorst, megi, mripard, neil.armstrong, robh, simona, tzimmermann, yangcong5, Riccardo Mereu On Wed, 01 Apr 2026 10:26:37 +0300 Dmitry Baryshkov wrote: >From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> >The Waveshare DSI TOUCH family of panels has separate on-board GPIO >controller, which controls power supplies to the panel and the touch >screen and provides reset pins for both the panel and the touchscreen. >Also it provides a simple PWM controller for panel backlight. > >Add bindings for these GPIO controllers. As overall integration might be >not very obvious (and it differs significantly from the bindings used by >the original drivers), provide complete example with the on-board >regulators and the DSI panel. > >Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Riccardo Mereu <r.mereu@arduino.cc> ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov ` (17 preceding siblings ...) 2026-04-01 7:26 ` [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller Dmitry Baryshkov @ 2026-04-01 7:26 ` Dmitry Baryshkov 2026-04-03 12:30 ` Bartosz Golaszewski 2026-04-07 12:53 ` Riccardo Mereu 18 siblings, 2 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-01 7:26 UTC (permalink / raw) To: Neil Armstrong, 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 Cc: dri-devel, devicetree, linux-kernel, linux-gpio The Waveshare DSI TOUCH family of panels has separate on-board GPIO controller, which controls power supplies to the panel and the touch screen and provides reset pins for both the panel and the touchscreen. Also it provides a simple PWM controller for panel backlight. Add support for this GPIO controller. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> --- drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-waveshare-dsi.c | 220 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4c3f6ec336c1..f0bb5cdebf9b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -804,6 +804,16 @@ config GPIO_VISCONTI help Say yes here to support GPIO on Tohisba Visconti. +config GPIO_WAVESHARE_DSI_TOUCH + tristate "Waveshare GPIO controller for DSI panels" + depends on BACKLIGHT_CLASS_DEVICE + depends on I2C + select REGMAP_I2C + help + Enable support for the GPIO and PWM controller found on Waveshare DSI + TOUCH panel kits. It provides GPIOs (used for regulator control and + resets) and backlight support. + config GPIO_WCD934X tristate "Qualcomm Technologies Inc WCD9340/WCD9341 GPIO controller driver" depends on MFD_WCD934X diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 20d4a57afdaa..75ce89fc3b93 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -207,6 +207,7 @@ obj-$(CONFIG_GPIO_VIRTUSER) += gpio-virtuser.o obj-$(CONFIG_GPIO_VIRTIO) += gpio-virtio.o obj-$(CONFIG_GPIO_VISCONTI) += gpio-visconti.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o +obj-$(CONFIG_GPIO_WAVESHARE_DSI_TOUCH) += gpio-waveshare-dsi.o obj-$(CONFIG_GPIO_WCD934X) += gpio-wcd934x.o obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o diff --git a/drivers/gpio/gpio-waveshare-dsi.c b/drivers/gpio/gpio-waveshare-dsi.c new file mode 100644 index 000000000000..30fe7569c150 --- /dev/null +++ b/drivers/gpio/gpio-waveshare-dsi.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Waveshare International Limited + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/backlight.h> +#include <linux/err.h> +#include <linux/fb.h> +#include <linux/gpio/driver.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> + +/* I2C registers of the microcontroller. */ +#define REG_TP 0x94 +#define REG_LCD 0x95 +#define REG_PWM 0x96 +#define REG_SIZE 0x97 +#define REG_ID 0x98 +#define REG_VERSION 0x99 + +enum { + GPIO_AVDD = 0, + GPIO_PANEL_RESET = 1, + GPIO_BL_ENABLE = 2, + GPIO_IOVCC = 4, + GPIO_VCC = 8, + GPIO_TS_RESET = 9, + NUM_GPIO = 16, +}; + +struct waveshare_gpio { + struct mutex dir_lock; + struct mutex pwr_lock; + struct regmap *regmap; + u16 poweron_state; + + struct gpio_chip gc; +}; + +static const struct regmap_config waveshare_gpio_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_PWM, +}; + +static int waveshare_gpio_get(struct waveshare_gpio *state, unsigned int offset) +{ + u16 pwr_state; + + mutex_lock(&state->pwr_lock); + pwr_state = state->poweron_state & BIT(offset); + mutex_unlock(&state->pwr_lock); + + return !!pwr_state; +} + +static int waveshare_gpio_set(struct waveshare_gpio *state, unsigned int offset, int value) +{ + u16 last_val; + + mutex_lock(&state->pwr_lock); + + last_val = state->poweron_state; + if (value) + last_val |= BIT(offset); + else + last_val &= ~BIT(offset); + + state->poweron_state = last_val; + + regmap_write(state->regmap, REG_TP, last_val >> 8); + regmap_write(state->regmap, REG_LCD, last_val & 0xff); + + mutex_unlock(&state->pwr_lock); + + return 0; +} + +static int waveshare_gpio_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int waveshare_gpio_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct waveshare_gpio *state = gpiochip_get_data(gc); + + return waveshare_gpio_get(state, offset); +} + +static int waveshare_gpio_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct waveshare_gpio *state = gpiochip_get_data(gc); + + return waveshare_gpio_set(state, offset, value); +} + +static int waveshare_gpio_update_status(struct backlight_device *bl) +{ + struct waveshare_gpio *state = bl_get_data(bl); + int brightness = backlight_get_brightness(bl); + + waveshare_gpio_set(state, GPIO_BL_ENABLE, brightness); + + return regmap_write(state->regmap, REG_PWM, brightness); +} + +static const struct backlight_ops waveshare_gpio_bl = { + .update_status = waveshare_gpio_update_status, +}; + +static int waveshare_gpio_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) +{ + int val; + + val = i2c_smbus_read_byte_data(client, reg); + if (val < 0) + return val; + + *buf = val; + + return 0; +} + +static int waveshare_gpio_probe(struct i2c_client *i2c) +{ + struct backlight_properties props = {}; + struct waveshare_gpio *state; + struct device *dev = &i2c->dev; + struct backlight_device *bl; + struct regmap *regmap; + unsigned int data; + int ret; + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + ret = devm_mutex_init(dev, &state->dir_lock); + if (ret) + return ret; + + ret = devm_mutex_init(dev, &state->pwr_lock); + if (ret) + return ret; + + i2c_set_clientdata(i2c, state); + + regmap = devm_regmap_init_i2c(i2c, &waveshare_gpio_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate register map\n"); + + ret = waveshare_gpio_i2c_read(i2c, REG_ID, &data); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read register\n"); + + dev_dbg(dev, "waveshare panel hw id = 0x%x\n", data); + + ret = waveshare_gpio_i2c_read(i2c, REG_SIZE, &data); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read register\n"); + + dev_dbg(dev, "waveshare panel size = %d\n", data); + + ret = waveshare_gpio_i2c_read(i2c, REG_VERSION, &data); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read register\n"); + + dev_dbg(dev, "waveshare panel mcu version = 0x%x\n", data); + + state->poweron_state = BIT(GPIO_TS_RESET); + regmap_write(regmap, REG_TP, state->poweron_state >> 8); + regmap_write(regmap, REG_LCD, state->poweron_state & 0xff); + msleep(20); + + state->regmap = regmap; + state->gc.parent = dev; + state->gc.label = i2c->name; + state->gc.owner = THIS_MODULE; + state->gc.base = -1; + state->gc.ngpio = NUM_GPIO; + + /* it is output only */ + state->gc.get = waveshare_gpio_gpio_get; + state->gc.set = waveshare_gpio_gpio_set; + state->gc.get_direction = waveshare_gpio_gpio_get_direction; + state->gc.can_sleep = true; + + ret = devm_gpiochip_add_data(dev, &state->gc, state); + if (ret) + return dev_err_probe(dev, ret, "Failed to create gpiochip\n"); + + props.type = BACKLIGHT_RAW; + props.max_brightness = 255; + props.brightness = 255; + bl = devm_backlight_device_register(dev, dev_name(dev), dev, state, + &waveshare_gpio_bl, &props); + return PTR_ERR_OR_ZERO(bl); +} + +static const struct of_device_id waveshare_gpio_dt_ids[] = { + { .compatible = "waveshare,dsi-touch-gpio" }, + {}, +}; +MODULE_DEVICE_TABLE(of, waveshare_gpio_dt_ids); + +static struct i2c_driver waveshare_gpio_regulator_driver = { + .driver = { + .name = "waveshare-regulator", + .of_match_table = of_match_ptr(waveshare_gpio_dt_ids), + }, + .probe = waveshare_gpio_probe, +}; + +module_i2c_driver(waveshare_gpio_regulator_driver); + +MODULE_DESCRIPTION("GPIO controller driver for Waveshare DSI touch panels"); +MODULE_LICENSE("GPL"); -- 2.47.3 ^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels 2026-04-01 7:26 ` [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels Dmitry Baryshkov @ 2026-04-03 12:30 ` Bartosz Golaszewski 2026-04-09 1:26 ` Dmitry Baryshkov 2026-04-07 12:53 ` Riccardo Mereu 1 sibling, 1 reply; 52+ messages in thread From: Bartosz Golaszewski @ 2026-04-03 12:30 UTC (permalink / raw) To: Dmitry Baryshkov Cc: dri-devel, devicetree, linux-kernel, linux-gpio, Neil Armstrong, 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 On Wed, 1 Apr 2026 09:26:38 +0200, Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> said: > The Waveshare DSI TOUCH family of panels has separate on-board GPIO > controller, which controls power supplies to the panel and the touch > screen and provides reset pins for both the panel and the touchscreen. > Also it provides a simple PWM controller for panel backlight. Add > support for this GPIO controller. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > --- > drivers/gpio/Kconfig | 10 ++ > drivers/gpio/Makefile | 1 + > drivers/gpio/gpio-waveshare-dsi.c | 220 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 231 insertions(+) > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 4c3f6ec336c1..f0bb5cdebf9b 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -804,6 +804,16 @@ config GPIO_VISCONTI > help > Say yes here to support GPIO on Tohisba Visconti. > > +config GPIO_WAVESHARE_DSI_TOUCH > + tristate "Waveshare GPIO controller for DSI panels" > + depends on BACKLIGHT_CLASS_DEVICE > + depends on I2C > + select REGMAP_I2C > + help > + Enable support for the GPIO and PWM controller found on Waveshare DSI > + TOUCH panel kits. It provides GPIOs (used for regulator control and > + resets) and backlight support. > + > config GPIO_WCD934X > tristate "Qualcomm Technologies Inc WCD9340/WCD9341 GPIO controller driver" > depends on MFD_WCD934X > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index 20d4a57afdaa..75ce89fc3b93 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -207,6 +207,7 @@ obj-$(CONFIG_GPIO_VIRTUSER) += gpio-virtuser.o > obj-$(CONFIG_GPIO_VIRTIO) += gpio-virtio.o > obj-$(CONFIG_GPIO_VISCONTI) += gpio-visconti.o > obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o > +obj-$(CONFIG_GPIO_WAVESHARE_DSI_TOUCH) += gpio-waveshare-dsi.o > obj-$(CONFIG_GPIO_WCD934X) += gpio-wcd934x.o > obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o > obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o > diff --git a/drivers/gpio/gpio-waveshare-dsi.c b/drivers/gpio/gpio-waveshare-dsi.c > new file mode 100644 > index 000000000000..30fe7569c150 > --- /dev/null > +++ b/drivers/gpio/gpio-waveshare-dsi.c > @@ -0,0 +1,220 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2024 Waveshare International Limited > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. > + */ > + > +#include <linux/backlight.h> > +#include <linux/err.h> > +#include <linux/fb.h> > +#include <linux/gpio/driver.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/regmap.h> > + > +/* I2C registers of the microcontroller. */ > +#define REG_TP 0x94 > +#define REG_LCD 0x95 > +#define REG_PWM 0x96 > +#define REG_SIZE 0x97 > +#define REG_ID 0x98 > +#define REG_VERSION 0x99 > + > +enum { > + GPIO_AVDD = 0, > + GPIO_PANEL_RESET = 1, > + GPIO_BL_ENABLE = 2, > + GPIO_IOVCC = 4, > + GPIO_VCC = 8, > + GPIO_TS_RESET = 9, > + NUM_GPIO = 16, Why is this part of an enum? > +}; > + > +struct waveshare_gpio { > + struct mutex dir_lock; > + struct mutex pwr_lock; > + struct regmap *regmap; > + u16 poweron_state; > + > + struct gpio_chip gc; > +}; > + > +static const struct regmap_config waveshare_gpio_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = REG_PWM, > +}; > + > +static int waveshare_gpio_get(struct waveshare_gpio *state, unsigned int offset) > +{ > + u16 pwr_state; > + > + mutex_lock(&state->pwr_lock); > + pwr_state = state->poweron_state & BIT(offset); > + mutex_unlock(&state->pwr_lock); > + > + return !!pwr_state; > +} > + > +static int waveshare_gpio_set(struct waveshare_gpio *state, unsigned int offset, int value) > +{ > + u16 last_val; > + > + mutex_lock(&state->pwr_lock); Can you use guards for locks? > + > + last_val = state->poweron_state; > + if (value) > + last_val |= BIT(offset); > + else > + last_val &= ~BIT(offset); > + > + state->poweron_state = last_val; > + > + regmap_write(state->regmap, REG_TP, last_val >> 8); > + regmap_write(state->regmap, REG_LCD, last_val & 0xff); I2C regmap writes can fail and their return value should be checked. > + > + mutex_unlock(&state->pwr_lock); > + > + return 0; > +} > + > +static int waveshare_gpio_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) > +{ > + return GPIO_LINE_DIRECTION_OUT; > +} > + > +static int waveshare_gpio_gpio_get(struct gpio_chip *gc, unsigned int offset) > +{ > + struct waveshare_gpio *state = gpiochip_get_data(gc); > + > + return waveshare_gpio_get(state, offset); > +} > + > +static int waveshare_gpio_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) > +{ > + struct waveshare_gpio *state = gpiochip_get_data(gc); > + > + return waveshare_gpio_set(state, offset, value); > +} > + > +static int waveshare_gpio_update_status(struct backlight_device *bl) > +{ > + struct waveshare_gpio *state = bl_get_data(bl); > + int brightness = backlight_get_brightness(bl); > + > + waveshare_gpio_set(state, GPIO_BL_ENABLE, brightness); > + > + return regmap_write(state->regmap, REG_PWM, brightness); > +} > + > +static const struct backlight_ops waveshare_gpio_bl = { > + .update_status = waveshare_gpio_update_status, > +}; > + > +static int waveshare_gpio_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) > +{ > + int val; > + > + val = i2c_smbus_read_byte_data(client, reg); > + if (val < 0) > + return val; > + > + *buf = val; > + > + return 0; > +} > + > +static int waveshare_gpio_probe(struct i2c_client *i2c) > +{ > + struct backlight_properties props = {}; > + struct waveshare_gpio *state; > + struct device *dev = &i2c->dev; > + struct backlight_device *bl; > + struct regmap *regmap; > + unsigned int data; > + int ret; > + > + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); > + if (!state) > + return -ENOMEM; > + > + ret = devm_mutex_init(dev, &state->dir_lock); > + if (ret) > + return ret; > + > + ret = devm_mutex_init(dev, &state->pwr_lock); > + if (ret) > + return ret; > + > + i2c_set_clientdata(i2c, state); > + > + regmap = devm_regmap_init_i2c(i2c, &waveshare_gpio_regmap_config); > + if (IS_ERR(regmap)) > + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate register map\n"); > + > + ret = waveshare_gpio_i2c_read(i2c, REG_ID, &data); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to read register\n"); > + > + dev_dbg(dev, "waveshare panel hw id = 0x%x\n", data); > + > + ret = waveshare_gpio_i2c_read(i2c, REG_SIZE, &data); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to read register\n"); > + > + dev_dbg(dev, "waveshare panel size = %d\n", data); > + > + ret = waveshare_gpio_i2c_read(i2c, REG_VERSION, &data); > + if (ret < 0) > + return dev_err_probe(dev, ret, "Failed to read register\n"); > + > + dev_dbg(dev, "waveshare panel mcu version = 0x%x\n", data); > + > + state->poweron_state = BIT(GPIO_TS_RESET); > + regmap_write(regmap, REG_TP, state->poweron_state >> 8); > + regmap_write(regmap, REG_LCD, state->poweron_state & 0xff); > + msleep(20); > + > + state->regmap = regmap; > + state->gc.parent = dev; > + state->gc.label = i2c->name; > + state->gc.owner = THIS_MODULE; > + state->gc.base = -1; > + state->gc.ngpio = NUM_GPIO; > + > + /* it is output only */ > + state->gc.get = waveshare_gpio_gpio_get; > + state->gc.set = waveshare_gpio_gpio_set; > + state->gc.get_direction = waveshare_gpio_gpio_get_direction; > + state->gc.can_sleep = true; > + > + ret = devm_gpiochip_add_data(dev, &state->gc, state); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to create gpiochip\n"); > + This driver looks like it could be easily converted to use gpio-regmap and become much shorter in the process. Could you please take a look at linux/gpio/regmap.h? > + props.type = BACKLIGHT_RAW; > + props.max_brightness = 255; > + props.brightness = 255; > + bl = devm_backlight_device_register(dev, dev_name(dev), dev, state, > + &waveshare_gpio_bl, &props); > + return PTR_ERR_OR_ZERO(bl); > +} > + > +static const struct of_device_id waveshare_gpio_dt_ids[] = { > + { .compatible = "waveshare,dsi-touch-gpio" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, waveshare_gpio_dt_ids); > + > +static struct i2c_driver waveshare_gpio_regulator_driver = { > + .driver = { > + .name = "waveshare-regulator", > + .of_match_table = of_match_ptr(waveshare_gpio_dt_ids), > + }, > + .probe = waveshare_gpio_probe, > +}; > + > +module_i2c_driver(waveshare_gpio_regulator_driver); > + > +MODULE_DESCRIPTION("GPIO controller driver for Waveshare DSI touch panels"); > +MODULE_LICENSE("GPL"); > > -- > 2.47.3 > > Bart ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels 2026-04-03 12:30 ` Bartosz Golaszewski @ 2026-04-09 1:26 ` Dmitry Baryshkov 0 siblings, 0 replies; 52+ messages in thread From: Dmitry Baryshkov @ 2026-04-09 1:26 UTC (permalink / raw) To: Bartosz Golaszewski Cc: dri-devel, devicetree, linux-kernel, linux-gpio, Neil Armstrong, 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 On Fri, Apr 03, 2026 at 08:30:22AM -0400, Bartosz Golaszewski wrote: > On Wed, 1 Apr 2026 09:26:38 +0200, Dmitry Baryshkov > <dmitry.baryshkov@oss.qualcomm.com> said: > > The Waveshare DSI TOUCH family of panels has separate on-board GPIO > > controller, which controls power supplies to the panel and the touch > > screen and provides reset pins for both the panel and the touchscreen. > > Also it provides a simple PWM controller for panel backlight. Add > > support for this GPIO controller. > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > > --- > > drivers/gpio/Kconfig | 10 ++ > > drivers/gpio/Makefile | 1 + > > drivers/gpio/gpio-waveshare-dsi.c | 220 ++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 231 insertions(+) > > > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > > index 4c3f6ec336c1..f0bb5cdebf9b 100644 > > --- a/drivers/gpio/Kconfig > > +++ b/drivers/gpio/Kconfig > > @@ -804,6 +804,16 @@ config GPIO_VISCONTI > > help > > Say yes here to support GPIO on Tohisba Visconti. > > > > +config GPIO_WAVESHARE_DSI_TOUCH > > + tristate "Waveshare GPIO controller for DSI panels" > > + depends on BACKLIGHT_CLASS_DEVICE > > + depends on I2C > > + select REGMAP_I2C > > + help > > + Enable support for the GPIO and PWM controller found on Waveshare DSI > > + TOUCH panel kits. It provides GPIOs (used for regulator control and > > + resets) and backlight support. > > + > > config GPIO_WCD934X > > tristate "Qualcomm Technologies Inc WCD9340/WCD9341 GPIO controller driver" > > depends on MFD_WCD934X > > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > > index 20d4a57afdaa..75ce89fc3b93 100644 > > --- a/drivers/gpio/Makefile > > +++ b/drivers/gpio/Makefile > > @@ -207,6 +207,7 @@ obj-$(CONFIG_GPIO_VIRTUSER) += gpio-virtuser.o > > obj-$(CONFIG_GPIO_VIRTIO) += gpio-virtio.o > > obj-$(CONFIG_GPIO_VISCONTI) += gpio-visconti.o > > obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o > > +obj-$(CONFIG_GPIO_WAVESHARE_DSI_TOUCH) += gpio-waveshare-dsi.o > > obj-$(CONFIG_GPIO_WCD934X) += gpio-wcd934x.o > > obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o > > obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o > > diff --git a/drivers/gpio/gpio-waveshare-dsi.c b/drivers/gpio/gpio-waveshare-dsi.c > > new file mode 100644 > > index 000000000000..30fe7569c150 > > --- /dev/null > > +++ b/drivers/gpio/gpio-waveshare-dsi.c > > @@ -0,0 +1,220 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2024 Waveshare International Limited > > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. > > + */ > > + > > +#include <linux/backlight.h> > > +#include <linux/err.h> > > +#include <linux/fb.h> > > +#include <linux/gpio/driver.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/regmap.h> > > + > > +/* I2C registers of the microcontroller. */ > > +#define REG_TP 0x94 > > +#define REG_LCD 0x95 > > +#define REG_PWM 0x96 > > +#define REG_SIZE 0x97 > > +#define REG_ID 0x98 > > +#define REG_VERSION 0x99 > > + > > +enum { > > + GPIO_AVDD = 0, > > + GPIO_PANEL_RESET = 1, > > + GPIO_BL_ENABLE = 2, > > + GPIO_IOVCC = 4, > > + GPIO_VCC = 8, > > + GPIO_TS_RESET = 9, > > + NUM_GPIO = 16, > > Why is this part of an enum? I'll move this out of the enum. > > > +static int waveshare_gpio_set(struct waveshare_gpio *state, unsigned int offset, int value) > > +{ > > + u16 last_val; > > + > > + mutex_lock(&state->pwr_lock); > > Can you use guards for locks? Yes > > > + > > + last_val = state->poweron_state; > > + if (value) > > + last_val |= BIT(offset); > > + else > > + last_val &= ~BIT(offset); > > + > > + state->poweron_state = last_val; > > + > > + regmap_write(state->regmap, REG_TP, last_val >> 8); > > + regmap_write(state->regmap, REG_LCD, last_val & 0xff); > > I2C regmap writes can fail and their return value should be checked. Ack. > > > + > > + mutex_unlock(&state->pwr_lock); > > + > > + return 0; > > +} > > + [...] > > + > > +static int waveshare_gpio_update_status(struct backlight_device *bl) > > +{ > > + struct waveshare_gpio *state = bl_get_data(bl); > > + int brightness = backlight_get_brightness(bl); > > + > > + waveshare_gpio_set(state, GPIO_BL_ENABLE, brightness); > > + > > + return regmap_write(state->regmap, REG_PWM, brightness); > > +} > > + [...] > > +static int waveshare_gpio_probe(struct i2c_client *i2c) > > +{ [...] > > + > > + dev_dbg(dev, "waveshare panel mcu version = 0x%x\n", data); > > + > > + state->poweron_state = BIT(GPIO_TS_RESET); > > + regmap_write(regmap, REG_TP, state->poweron_state >> 8); > > + regmap_write(regmap, REG_LCD, state->poweron_state & 0xff); And this can become waveshare_gpio_set(). > > + msleep(20); > > + > > + state->regmap = regmap; > > + state->gc.parent = dev; > > + state->gc.label = i2c->name; > > + state->gc.owner = THIS_MODULE; > > + state->gc.base = -1; > > + state->gc.ngpio = NUM_GPIO; > > + > > + /* it is output only */ > > + state->gc.get = waveshare_gpio_gpio_get; > > + state->gc.set = waveshare_gpio_gpio_set; > > + state->gc.get_direction = waveshare_gpio_gpio_get_direction; > > + state->gc.can_sleep = true; > > + > > + ret = devm_gpiochip_add_data(dev, &state->gc, state); > > + if (ret) > > + return dev_err_probe(dev, ret, "Failed to create gpiochip\n"); > > + > > This driver looks like it could be easily converted to use gpio-regmap and > become much shorter in the process. Could you please take a look at > linux/gpio/regmap.h? I took a glance. It is a nice wrapper, but I think being able to call waveshare_gpio_set() internally without extra troubles overweights the bonuses of the wrapper. Also, I'd agree if there were extra complexity here (e.g. the stride or the in/out handling), but having just the out GPIOs doesn't seem to warrant it. An alternative would be to split away the backlight into a separate pwm-backlight device. Then having waveshare_gpio_set() isn't that important and thus I could switch to GPIO_REGMAP. But then... We don't have real control over the PWM. We are really programming some values, with the actual PWM duty cycle calculations being handled internally. With all that in mind, unless you really insist, I'd prefer to leave this part the driver as is. > > > + props.type = BACKLIGHT_RAW; > > + props.max_brightness = 255; > > + props.brightness = 255; > > + bl = devm_backlight_device_register(dev, dev_name(dev), dev, state, > > + &waveshare_gpio_bl, &props); > > + return PTR_ERR_OR_ZERO(bl); > > +} > > + -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels 2026-04-01 7:26 ` [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels Dmitry Baryshkov 2026-04-03 12:30 ` Bartosz Golaszewski @ 2026-04-07 12:53 ` Riccardo Mereu 1 sibling, 0 replies; 52+ messages in thread From: Riccardo Mereu @ 2026-04-07 12:53 UTC (permalink / raw) To: dmitry.baryshkov Cc: airlied, brgl, broonie, conor+dt, devicetree, dri-devel, jagan, javierm, jesszhan0024, krzk+dt, lgirdwood, linusw, linux-gpio, linux-kernel, maarten.lankhorst, megi, mripard, neil.armstrong, robh, simona, tzimmermann, yangcong5, Riccardo Mereu On Wed, 01 Apr 2026 10:26:38 +0300 Dmitry Baryshkov wrote: >From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> >The Waveshare DSI TOUCH family of panels has separate on-board GPIO >controller, which controls power supplies to the panel and the touch >screen and provides reset pins for both the panel and the touchscreen. >Also it provides a simple PWM controller for panel backlight. Add >support for this GPIO controller. > >Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Tested-by: Riccardo Mereu <r.mereu@arduino.cc> ^ permalink raw reply [flat|nested] 52+ messages in thread
end of thread, other threads:[~2026-04-09 1:26 UTC | newest] Thread overview: 52+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-01 7:26 [PATCH 00/19] drm/panel: support Waveshare DSI TOUCH kits Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 01/19] dt-bindings: display/panel: himax,hx83102: describe Waveshare panel Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:38 ` Linus Walleij 2026-04-07 9:49 ` Krzysztof Kozlowski 2026-04-07 9:50 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 02/19] dt-bindings: display/panel: himax,hx8394: " Dmitry Baryshkov 2026-04-02 8:30 ` Krzysztof Kozlowski 2026-04-07 9:50 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 03/19] dt-bindings: display/panel: jadard,jd9365da-h3: " Dmitry Baryshkov 2026-04-07 10:46 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 04/19] dt-bindings: display/panel: ilitek,ili9881c: " Dmitry Baryshkov 2026-04-02 8:33 ` Krzysztof Kozlowski 2026-04-07 10:46 ` Krzysztof Kozlowski 2026-04-01 7:26 ` [PATCH 05/19] dt-bindings: dipslay/panel: describe panels using Focaltech OTA7290B Dmitry Baryshkov 2026-04-01 8:52 ` Rob Herring (Arm) 2026-04-01 7:26 ` [PATCH 06/19] drm/of: add helper to count data-lanes on a remote endpoint Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 07/19] drm/panel: himax-hx83102: support Waveshare 12.3" DSI panel Dmitry Baryshkov 2026-04-07 20:12 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 08/19] drm/panel: himax-hx8394: set prepare_prev_first Dmitry Baryshkov 2026-04-08 8:08 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 09/19] drm/panel: himax-hx8394: simplify hx8394_enable() Dmitry Baryshkov 2026-04-08 8:08 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 10/19] drm/panel: himax-hx8394: support Waveshare DSI panels Dmitry Baryshkov 2026-04-08 8:10 ` Linus Walleij 2026-04-09 0:33 ` Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 11/19] drm/panel: jadard-jd9365da-h3: use drm_connector_helper_get_modes_fixed Dmitry Baryshkov 2026-04-08 8:10 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 12/19] drm/panel: jadard-jd9365da-h3: support variable DSI configuration Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 2026-04-09 0:35 ` Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 13/19] drm/panel: jadard-jd9365da-h3: set prepare_prev_first Dmitry Baryshkov 2026-04-07 12:51 ` Riccardo Mereu 2026-04-08 8:15 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 14/19] drm/panel: jadard-jd9365da-h3: support Waveshare DSI panels Dmitry Baryshkov 2026-04-07 12:53 ` Riccardo Mereu 2026-04-08 8:24 ` Linus Walleij 2026-04-09 0:49 ` Dmitry Baryshkov 2026-04-01 7:26 ` [PATCH 15/19] drm/panel: ilitek-ili9881c: support Waveshare 7.0" DSI panel Dmitry Baryshkov 2026-04-08 8:26 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 16/19] drm/panel: add devm_drm_panel_add() helper Dmitry Baryshkov 2026-04-08 8:25 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 17/19] drm/panel: add driver for Waveshare 8.8" DSI TOUCH-A panel Dmitry Baryshkov 2026-04-08 8:27 ` Linus Walleij 2026-04-01 7:26 ` [PATCH 18/19] dt-bindings: gpio: describe Waveshare GPIO controller Dmitry Baryshkov 2026-04-01 8:52 ` Rob Herring (Arm) 2026-04-07 12:53 ` Riccardo Mereu 2026-04-01 7:26 ` [PATCH 19/19] gpio: add GPIO controller found on Waveshare DSI TOUCH panels Dmitry Baryshkov 2026-04-03 12:30 ` Bartosz Golaszewski 2026-04-09 1:26 ` Dmitry Baryshkov 2026-04-07 12:53 ` Riccardo Mereu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox