From 31445ca4dd06986e4529a65e8e96fcfe33edef27 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Thu, 25 Jan 2024 11:09:06 +0100
Subject: [PATCH 01/15] west.yml: Update lvgl module to v9.2.0

Update the west yaml to point to the new LVGL version.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 west.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/west.yml b/west.yml
index ad307970e74d..560ab03134e3 100644
--- a/west.yml
+++ b/west.yml
@@ -282,7 +282,7 @@ manifest:
       revision: fb00b383072518c918e2258b0916c996f2d4eebe
       path: modules/lib/loramac-node
     - name: lvgl
-      revision: 2b498e6f36d6b82ae1da12c8b7742e318624ecf5
+      revision: 6decbb7f7783f6e48d4591fcb9f7810c2fb08e61
       path: modules/lib/gui/lvgl
     - name: mbedtls
       revision: 4952e1328529ee549d412b498ea71c54f30aa3b1

From a91cc1fcb7cba6dab2000378c2dcd834805b2f6e Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Thu, 25 Jan 2024 11:10:41 +0100
Subject: [PATCH 02/15] samples: modules: lvgl: Update CMakeLists

Update the CMakeLists for LVGL to reflect the changes done in v9.2.0.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 modules/lvgl/CMakeLists.txt               | 332 ++++++++++++++--------
 samples/modules/lvgl/demos/CMakeLists.txt |  17 +-
 samples/modules/lvgl/demos/prj.conf       |   1 +
 samples/subsys/display/lvgl/prj.conf      |   3 -
 4 files changed, 221 insertions(+), 132 deletions(-)

diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt
index 6b00764aecc6..2f9ce0925ce1 100644
--- a/modules/lvgl/CMakeLists.txt
+++ b/modules/lvgl/CMakeLists.txt
@@ -16,140 +16,126 @@ zephyr_include_directories(${LVGL_DIR}/src/)
 zephyr_include_directories(include)
 
 zephyr_compile_definitions(LV_CONF_INCLUDE_SIMPLE=1)
-zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h)
+zephyr_compile_definitions(LV_CONF_PATH="${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h")
 
 zephyr_library_sources(
-    ${LVGL_DIR}/src/core/lv_disp.c
-    ${LVGL_DIR}/src/core/lv_event.c
+
     ${LVGL_DIR}/src/core/lv_group.c
-    ${LVGL_DIR}/src/core/lv_indev.c
-    ${LVGL_DIR}/src/core/lv_indev_scroll.c
     ${LVGL_DIR}/src/core/lv_obj.c
     ${LVGL_DIR}/src/core/lv_obj_class.c
     ${LVGL_DIR}/src/core/lv_obj_draw.c
+    ${LVGL_DIR}/src/core/lv_obj_event.c
+    ${LVGL_DIR}/src/core/lv_obj_id_builtin.c
     ${LVGL_DIR}/src/core/lv_obj_pos.c
+    ${LVGL_DIR}/src/core/lv_obj_property.c
     ${LVGL_DIR}/src/core/lv_obj_scroll.c
     ${LVGL_DIR}/src/core/lv_obj_style.c
     ${LVGL_DIR}/src/core/lv_obj_style_gen.c
     ${LVGL_DIR}/src/core/lv_obj_tree.c
     ${LVGL_DIR}/src/core/lv_refr.c
-    ${LVGL_DIR}/src/core/lv_theme.c
 
-    ${LVGL_DIR}/src/draw/arm2d/lv_gpu_arm2d.c
+    ${LVGL_DIR}/src/display/lv_display.c
+
+    ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d.c
+    ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d_fill.c
+    ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d_img.c
+
     ${LVGL_DIR}/src/draw/lv_draw_arc.c
+    ${LVGL_DIR}/src/draw/lv_draw_buf.c
     ${LVGL_DIR}/src/draw/lv_draw.c
-    ${LVGL_DIR}/src/draw/lv_draw_img.c
+    ${LVGL_DIR}/src/draw/lv_draw_image.c
     ${LVGL_DIR}/src/draw/lv_draw_label.c
-    ${LVGL_DIR}/src/draw/lv_draw_layer.c
     ${LVGL_DIR}/src/draw/lv_draw_line.c
     ${LVGL_DIR}/src/draw/lv_draw_mask.c
     ${LVGL_DIR}/src/draw/lv_draw_rect.c
-    ${LVGL_DIR}/src/draw/lv_draw_transform.c
     ${LVGL_DIR}/src/draw/lv_draw_triangle.c
-    ${LVGL_DIR}/src/draw/lv_img_buf.c
-    ${LVGL_DIR}/src/draw/lv_img_cache.c
-    ${LVGL_DIR}/src/draw/lv_img_decoder.c
-    ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_blend.c
+    ${LVGL_DIR}/src/draw/lv_draw_vector.c
+    ${LVGL_DIR}/src/draw/lv_image_decoder.c
+
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_buf_pxp.c
     ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp.c
-    ${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp.c
-    ${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_fill.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_img.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_layer.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_cfg.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_osa.c
+    ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_utils.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_buf_vglite.c
     ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_arc.c
-    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_blend.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_border.c
     ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_fill.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_img.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_label.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_layer.c
     ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_line.c
-    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_rect.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_triangle.c
     ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_buf.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_matrix.c
+    ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_path.c
     ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_utils.c
-    ${LVGL_DIR}/src/draw/renesas/lv_gpu_d2_draw_label.c
-    ${LVGL_DIR}/src/draw/renesas/lv_gpu_d2_ra6m3.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_arc.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_bg.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_composite.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_img.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_label.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_layer.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_line.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_mask.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_polygon.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_rect.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_stack_blur.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_texture_cache.c
-    ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_utils.c
-    ${LVGL_DIR}/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c
+
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_border.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_image.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_label.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_line.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c
+    ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c
+
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c
+    ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_arc.c
-    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_blend.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_border.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_box_shadow.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw.c
-    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_dither.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_fill.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_gradient.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_img.c
-    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_layer.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_letter.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_line.c
-    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_polygon.c
-    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_rect.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_mask.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_mask_rect.c
     ${LVGL_DIR}/src/draw/sw/lv_draw_sw_transform.c
-    ${LVGL_DIR}/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c
-
-    ${LVGL_DIR}/src/extra/layouts/flex/lv_flex.c
-    ${LVGL_DIR}/src/extra/layouts/grid/lv_grid.c
-    ${LVGL_DIR}/src/extra/libs/bmp/lv_bmp.c
-    ${LVGL_DIR}/src/extra/libs/ffmpeg/lv_ffmpeg.c
-    ${LVGL_DIR}/src/extra/libs/freetype/lv_freetype.c
-    ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_fatfs.c
-    ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_littlefs.c
-    ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_posix.c
-    ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_stdio.c
-    ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_win32.c
-    ${LVGL_DIR}/src/extra/libs/gif/gifdec.c
-    ${LVGL_DIR}/src/extra/libs/gif/lv_gif.c
-    ${LVGL_DIR}/src/extra/libs/png/lodepng.c
-    ${LVGL_DIR}/src/extra/libs/png/lv_png.c
-    ${LVGL_DIR}/src/extra/libs/qrcode/lv_qrcode.c
-    ${LVGL_DIR}/src/extra/libs/qrcode/qrcodegen.c
-    ${LVGL_DIR}/src/extra/libs/rlottie/lv_rlottie.c
-    ${LVGL_DIR}/src/extra/libs/sjpg/lv_sjpg.c
-    ${LVGL_DIR}/src/extra/libs/sjpg/tjpgd.c
-    ${LVGL_DIR}/src/extra/libs/tiny_ttf/lv_tiny_ttf.c
-    ${LVGL_DIR}/src/extra/lv_extra.c
-    ${LVGL_DIR}/src/extra/others/fragment/lv_fragment.c
-    ${LVGL_DIR}/src/extra/others/fragment/lv_fragment_manager.c
-    ${LVGL_DIR}/src/extra/others/gridnav/lv_gridnav.c
-    ${LVGL_DIR}/src/extra/others/ime/lv_ime_pinyin.c
-    ${LVGL_DIR}/src/extra/others/imgfont/lv_imgfont.c
-    ${LVGL_DIR}/src/extra/others/monkey/lv_monkey.c
-    ${LVGL_DIR}/src/extra/others/msg/lv_msg.c
-    ${LVGL_DIR}/src/extra/others/snapshot/lv_snapshot.c
-    ${LVGL_DIR}/src/extra/themes/basic/lv_theme_basic.c
-    ${LVGL_DIR}/src/extra/themes/default/lv_theme_default.c
-    ${LVGL_DIR}/src/extra/themes/mono/lv_theme_mono.c
-    ${LVGL_DIR}/src/extra/widgets/animimg/lv_animimg.c
-    ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar.c
-    ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_arrow.c
-    ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_dropdown.c
-    ${LVGL_DIR}/src/extra/widgets/chart/lv_chart.c
-    ${LVGL_DIR}/src/extra/widgets/colorwheel/lv_colorwheel.c
-    ${LVGL_DIR}/src/extra/widgets/imgbtn/lv_imgbtn.c
-    ${LVGL_DIR}/src/extra/widgets/keyboard/lv_keyboard.c
-    ${LVGL_DIR}/src/extra/widgets/led/lv_led.c
-    ${LVGL_DIR}/src/extra/widgets/list/lv_list.c
-    ${LVGL_DIR}/src/extra/widgets/menu/lv_menu.c
-    ${LVGL_DIR}/src/extra/widgets/meter/lv_meter.c
-    ${LVGL_DIR}/src/extra/widgets/msgbox/lv_msgbox.c
-    ${LVGL_DIR}/src/extra/widgets/span/lv_span.c
-    ${LVGL_DIR}/src/extra/widgets/spinbox/lv_spinbox.c
-    ${LVGL_DIR}/src/extra/widgets/spinner/lv_spinner.c
-    ${LVGL_DIR}/src/extra/widgets/tabview/lv_tabview.c
-    ${LVGL_DIR}/src/extra/widgets/tileview/lv_tileview.c
-    ${LVGL_DIR}/src/extra/widgets/win/lv_win.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_triangle.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_utils.c
+    ${LVGL_DIR}/src/draw/sw/lv_draw_sw_vector.c
+
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_buf_vg_lite.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_arc.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_border.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_fill.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_img.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_label.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_layer.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_line.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_triangle.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_vector.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_decoder.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_grad.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_math.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_path.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_pending.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_stroke.c
+    ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_utils.c
 
+    ${LVGL_DIR}/src/font/lv_binfont_loader.c
     ${LVGL_DIR}/src/font/lv_font.c
     ${LVGL_DIR}/src/font/lv_font_dejavu_16_persian_hebrew.c
     ${LVGL_DIR}/src/font/lv_font_fmt_txt.c
-    ${LVGL_DIR}/src/font/lv_font_loader.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_10.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_12.c
-    ${LVGL_DIR}/src/font/lv_font_montserrat_12_subpx.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_14.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_16.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_18.c
@@ -170,53 +156,159 @@ zephyr_library_sources(
     ${LVGL_DIR}/src/font/lv_font_montserrat_46.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_48.c
     ${LVGL_DIR}/src/font/lv_font_montserrat_8.c
+    ${LVGL_DIR}/src/font/lv_font_simsun_14_cjk.c
     ${LVGL_DIR}/src/font/lv_font_simsun_16_cjk.c
     ${LVGL_DIR}/src/font/lv_font_unscii_16.c
     ${LVGL_DIR}/src/font/lv_font_unscii_8.c
 
-    ${LVGL_DIR}/src/hal/lv_hal_disp.c
-    ${LVGL_DIR}/src/hal/lv_hal_indev.c
-    ${LVGL_DIR}/src/hal/lv_hal_tick.c
+    ${LVGL_DIR}/src/indev/lv_indev.c
+    ${LVGL_DIR}/src/indev/lv_indev_scroll.c
+
+    ${LVGL_DIR}/src/layouts/flex/lv_flex.c
+    ${LVGL_DIR}/src/layouts/grid/lv_grid.c
+    ${LVGL_DIR}/src/layouts/lv_layout.c
+
+    ${LVGL_DIR}/src/libs/barcode/code128.c
+    ${LVGL_DIR}/src/libs/barcode/lv_barcode.c
+    ${LVGL_DIR}/src/libs/bin_decoder/lv_bin_decoder.c
+    ${LVGL_DIR}/src/libs/bmp/lv_bmp.c
+    ${LVGL_DIR}/src/libs/ffmpeg/lv_ffmpeg.c
+    ${LVGL_DIR}/src/libs/freetype/lv_freetype.c
+    ${LVGL_DIR}/src/libs/freetype/lv_freetype_glyph.c
+    ${LVGL_DIR}/src/libs/freetype/lv_freetype_image.c
+    ${LVGL_DIR}/src/libs/freetype/lv_freetype_outline.c
+    ${LVGL_DIR}/src/libs/freetype/lv_ftsystem.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_cbfs.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_fatfs.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_littlefs.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_memfs.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_posix.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_stdio.c
+    ${LVGL_DIR}/src/libs/fsdrv/lv_fs_win32.c
+    ${LVGL_DIR}/src/libs/gif/gifdec.c
+    ${LVGL_DIR}/src/libs/gif/lv_gif.c
+    ${LVGL_DIR}/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c
+    ${LVGL_DIR}/src/libs/libpng/lv_libpng.c
+    ${LVGL_DIR}/src/libs/lodepng/lodepng.c
+    ${LVGL_DIR}/src/libs/lodepng/lv_lodepng.c
+    ${LVGL_DIR}/src/libs/lz4/lz4.c
+    ${LVGL_DIR}/src/libs/qrcode/lv_qrcode.c
+    ${LVGL_DIR}/src/libs/qrcode/qrcodegen.c
+    ${LVGL_DIR}/src/libs/rle/lv_rle.c
+    ${LVGL_DIR}/src/libs/rlottie/lv_rlottie.c
+    ${LVGL_DIR}/src/libs/tiny_ttf/lv_tiny_ttf.c
+    ${LVGL_DIR}/src/libs/tjpgd/lv_tjpgd.c
+    ${LVGL_DIR}/src/libs/tjpgd/tjpgd.c
 
+    ${LVGL_DIR}/src/lv_init.c
+
+    ${LVGL_DIR}/src/misc/cache/lv_cache.c
+    ${LVGL_DIR}/src/misc/cache/lv_cache_entry.c
+    ${LVGL_DIR}/src/misc/cache/lv_cache_lru_rb.c
+    ${LVGL_DIR}/src/misc/cache/lv_image_cache.c
+    ${LVGL_DIR}/src/misc/cache/lv_image_header_cache.c
     ${LVGL_DIR}/src/misc/lv_anim.c
     ${LVGL_DIR}/src/misc/lv_anim_timeline.c
     ${LVGL_DIR}/src/misc/lv_area.c
+    ${LVGL_DIR}/src/misc/lv_array.c
     ${LVGL_DIR}/src/misc/lv_async.c
     ${LVGL_DIR}/src/misc/lv_bidi.c
     ${LVGL_DIR}/src/misc/lv_color.c
+    ${LVGL_DIR}/src/misc/lv_color_op.c
+    ${LVGL_DIR}/src/misc/lv_event.c
     ${LVGL_DIR}/src/misc/lv_fs.c
-    ${LVGL_DIR}/src/misc/lv_gc.c
+    ${LVGL_DIR}/src/misc/lv_iter.c
     ${LVGL_DIR}/src/misc/lv_ll.c
     ${LVGL_DIR}/src/misc/lv_log.c
     ${LVGL_DIR}/src/misc/lv_lru.c
     ${LVGL_DIR}/src/misc/lv_math.c
-    ${LVGL_DIR}/src/misc/lv_mem.c
-    ${LVGL_DIR}/src/misc/lv_printf.c
+    ${LVGL_DIR}/src/misc/lv_matrix.c
+    ${LVGL_DIR}/src/misc/lv_palette.c
+    ${LVGL_DIR}/src/misc/lv_profiler_builtin.c
+    ${LVGL_DIR}/src/misc/lv_rb.c
     ${LVGL_DIR}/src/misc/lv_style.c
     ${LVGL_DIR}/src/misc/lv_style_gen.c
     ${LVGL_DIR}/src/misc/lv_templ.c
+    ${LVGL_DIR}/src/misc/lv_text_ap.c
+    ${LVGL_DIR}/src/misc/lv_text.c
     ${LVGL_DIR}/src/misc/lv_timer.c
-    ${LVGL_DIR}/src/misc/lv_tlsf.c
-    ${LVGL_DIR}/src/misc/lv_txt_ap.c
-    ${LVGL_DIR}/src/misc/lv_txt.c
     ${LVGL_DIR}/src/misc/lv_utils.c
+    ${LVGL_DIR}/src/osal/lv_os.c
+
+    ${LVGL_DIR}/src/others/file_explorer/lv_file_explorer.c
+    ${LVGL_DIR}/src/others/fragment/lv_fragment.c
+    ${LVGL_DIR}/src/others/fragment/lv_fragment_manager.c
+    ${LVGL_DIR}/src/others/gridnav/lv_gridnav.c
+    ${LVGL_DIR}/src/others/ime/lv_ime_pinyin.c
+    ${LVGL_DIR}/src/others/imgfont/lv_imgfont.c
+    ${LVGL_DIR}/src/others/monkey/lv_monkey.c
+    ${LVGL_DIR}/src/others/observer/lv_observer.c
+    ${LVGL_DIR}/src/others/snapshot/lv_snapshot.c
+    ${LVGL_DIR}/src/others/sysmon/lv_sysmon.c
+    ${LVGL_DIR}/src/others/vg_lite_tvg/vg_lite_matrix.c
+
+    ${LVGL_DIR}/src/stdlib/builtin/lv_sprintf_builtin.c
+    ${LVGL_DIR}/src/stdlib/builtin/lv_string_builtin.c
+    ${LVGL_DIR}/src/stdlib/builtin/lv_tlsf.c
+
+    ${LVGL_DIR}/src/stdlib/clib/lv_mem_core_clib.c
+    ${LVGL_DIR}/src/stdlib/clib/lv_sprintf_clib.c
+    ${LVGL_DIR}/src/stdlib/clib/lv_string_clib.c
+
+    ${LVGL_DIR}/src/stdlib/lv_mem.c
+
+    ${LVGL_DIR}/src/themes/default/lv_theme_default.c
+
+    ${LVGL_DIR}/src/themes/lv_theme.c
+    ${LVGL_DIR}/src/themes/mono/lv_theme_mono.c
+    ${LVGL_DIR}/src/themes/simple/lv_theme_simple.c
+
+    ${LVGL_DIR}/src/tick/lv_tick.c
 
-    ${LVGL_DIR}/src/widgets/lv_arc.c
-    ${LVGL_DIR}/src/widgets/lv_bar.c
-    ${LVGL_DIR}/src/widgets/lv_btn.c
-    ${LVGL_DIR}/src/widgets/lv_btnmatrix.c
-    ${LVGL_DIR}/src/widgets/lv_canvas.c
-    ${LVGL_DIR}/src/widgets/lv_checkbox.c
-    ${LVGL_DIR}/src/widgets/lv_dropdown.c
-    ${LVGL_DIR}/src/widgets/lv_img.c
-    ${LVGL_DIR}/src/widgets/lv_label.c
-    ${LVGL_DIR}/src/widgets/lv_line.c
-    ${LVGL_DIR}/src/widgets/lv_objx_templ.c
-    ${LVGL_DIR}/src/widgets/lv_roller.c
-    ${LVGL_DIR}/src/widgets/lv_slider.c
-    ${LVGL_DIR}/src/widgets/lv_switch.c
-    ${LVGL_DIR}/src/widgets/lv_table.c
-    ${LVGL_DIR}/src/widgets/lv_textarea.c
+    ${LVGL_DIR}/src/widgets/animimage/lv_animimage.c
+    ${LVGL_DIR}/src/widgets/arc/lv_arc.c
+    ${LVGL_DIR}/src/widgets/bar/lv_bar.c
+    ${LVGL_DIR}/src/widgets/button/lv_button.c
+    ${LVGL_DIR}/src/widgets/buttonmatrix/lv_buttonmatrix.c
+    ${LVGL_DIR}/src/widgets/calendar/lv_calendar.c
+    ${LVGL_DIR}/src/widgets/calendar/lv_calendar_chinese.c
+    ${LVGL_DIR}/src/widgets/calendar/lv_calendar_header_arrow.c
+    ${LVGL_DIR}/src/widgets/calendar/lv_calendar_header_dropdown.c
+    ${LVGL_DIR}/src/widgets/canvas/lv_canvas.c
+    ${LVGL_DIR}/src/widgets/chart/lv_chart.c
+    ${LVGL_DIR}/src/widgets/checkbox/lv_checkbox.c
+    ${LVGL_DIR}/src/widgets/dropdown/lv_dropdown.c
+    ${LVGL_DIR}/src/widgets/imagebutton/lv_imagebutton.c
+    ${LVGL_DIR}/src/widgets/image/lv_image.c
+    ${LVGL_DIR}/src/widgets/keyboard/lv_keyboard.c
+    ${LVGL_DIR}/src/widgets/label/lv_label.c
+    ${LVGL_DIR}/src/widgets/led/lv_led.c
+    ${LVGL_DIR}/src/widgets/line/lv_line.c
+    ${LVGL_DIR}/src/widgets/list/lv_list.c
+    ${LVGL_DIR}/src/widgets/lottie/lv_lottie.c
+    ${LVGL_DIR}/src/widgets/menu/lv_menu.c
+    ${LVGL_DIR}/src/widgets/msgbox/lv_msgbox.c
+    ${LVGL_DIR}/src/widgets/objx_templ/lv_objx_templ.c
+    ${LVGL_DIR}/src/widgets/property/lv_dropdown_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_image_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_keyboard_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_label_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_obj_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_roller_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_style_properties.c
+    ${LVGL_DIR}/src/widgets/property/lv_textarea_properties.c
+    ${LVGL_DIR}/src/widgets/roller/lv_roller.c
+    ${LVGL_DIR}/src/widgets/scale/lv_scale.c
+    ${LVGL_DIR}/src/widgets/slider/lv_slider.c
+    ${LVGL_DIR}/src/widgets/span/lv_span.c
+    ${LVGL_DIR}/src/widgets/spinbox/lv_spinbox.c
+    ${LVGL_DIR}/src/widgets/spinner/lv_spinner.c
+    ${LVGL_DIR}/src/widgets/switch/lv_switch.c
+    ${LVGL_DIR}/src/widgets/table/lv_table.c
+    ${LVGL_DIR}/src/widgets/tabview/lv_tabview.c
+    ${LVGL_DIR}/src/widgets/textarea/lv_textarea.c
+    ${LVGL_DIR}/src/widgets/tileview/lv_tileview.c
+    ${LVGL_DIR}/src/widgets/win/lv_win.c
 
     lvgl.c
     lvgl_display.c
diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt
index c80e3b4364b1..260150097b9a 100644
--- a/samples/modules/lvgl/demos/CMakeLists.txt
+++ b/samples/modules/lvgl/demos/CMakeLists.txt
@@ -66,16 +66,14 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_MUSIC app PRIVATE
 )
 
 target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE
+    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_avatar.c
+    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_lvgl_logo_argb.c
+    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_lvgl_logo_rgb.c
+    ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_12_compr_az.c.c
+    ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_16_compr_az.c.c
+    ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_28_compr_az.c.c
+    ${LVGL_DIR}/demos/transform/assets/img_transform_avatar_15.c
     ${LVGL_DIR}/demos/benchmark/lv_demo_benchmark.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_indexed16.c
-    ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_28_compr_az.c.c
-    ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_16_compr_az.c.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_argb.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_alpha16.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb.c
-    ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_12_compr_az.c.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_chroma_keyed.c
-    ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb565a8.c
 )
 
 target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE
@@ -85,6 +83,7 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE
 target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE
     ${LVGL_DIR}/demos/widgets/assets/img_clothes.c
     ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c
+    ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_needle.c
     ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c
     ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c
 )
diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf
index 3392d5c4fd31..b977a3d30b42 100644
--- a/samples/modules/lvgl/demos/prj.conf
+++ b/samples/modules/lvgl/demos/prj.conf
@@ -13,6 +13,7 @@ CONFIG_INPUT=y
 CONFIG_LV_FONT_MONTSERRAT_12=y
 CONFIG_LV_FONT_MONTSERRAT_14=y
 CONFIG_LV_FONT_MONTSERRAT_16=y
+CONFIG_LV_FONT_MONTSERRAT_24=y
 
 # Benchmark Demo
 CONFIG_LV_USE_FONT_COMPRESSED=y
diff --git a/samples/subsys/display/lvgl/prj.conf b/samples/subsys/display/lvgl/prj.conf
index 41c0eca6e70f..b3d6db3822b1 100644
--- a/samples/subsys/display/lvgl/prj.conf
+++ b/samples/subsys/display/lvgl/prj.conf
@@ -9,11 +9,8 @@ CONFIG_LOG=y
 CONFIG_SHELL=y
 
 CONFIG_LVGL=y
-CONFIG_LV_MEM_CUSTOM=y
 CONFIG_LV_USE_LOG=y
 CONFIG_LV_USE_LABEL=y
-CONFIG_LV_USE_BTN=y
 CONFIG_LV_USE_ARC=y
-CONFIG_LV_USE_IMG=y
 CONFIG_LV_USE_MONKEY=y
 CONFIG_LV_FONT_MONTSERRAT_14=y

From 2f3279271ab316615002e0258024ba988f233eb6 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Mon, 1 Apr 2024 20:01:16 +0200
Subject: [PATCH 03/15] samples: modules: lvgl: Update Kconfig depedencies

With v9.1.0 the benchmark sample now has a Kconfig depedency on
LV_USE_DEMO_WIDGETS.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/modules/lvgl/demos/Kconfig     | 1 +
 samples/modules/lvgl/demos/sample.yaml | 1 +
 2 files changed, 2 insertions(+)

diff --git a/samples/modules/lvgl/demos/Kconfig b/samples/modules/lvgl/demos/Kconfig
index 6f61694f6518..e3692e02b275 100644
--- a/samples/modules/lvgl/demos/Kconfig
+++ b/samples/modules/lvgl/demos/Kconfig
@@ -16,6 +16,7 @@ config LV_Z_DEMO_MUSIC
 config LV_Z_DEMO_BENCHMARK
 	bool "LVGL benchmark demo"
 	select LV_USE_DEMO_BENCHMARK
+	select LV_USE_DEMO_WIDGETS
 	help
 	  Build benchmarking demo application.
 
diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml
index 40c14a0a085c..2677cab9383a 100644
--- a/samples/modules/lvgl/demos/sample.yaml
+++ b/samples/modules/lvgl/demos/sample.yaml
@@ -27,6 +27,7 @@ tests:
   sample.modules.lvgl.demo_benchmark:
     extra_configs:
       - CONFIG_LV_Z_DEMO_BENCHMARK=y
+      - CONFIG_LV_USE_DEMO_WIDGETS=y
   sample.modules.lvgl.demo_stress:
     extra_configs:
       - CONFIG_LV_Z_DEMO_STRESS=y

From 44ead5f9b2db48fc07c2d5f0629d1eb7536ecfc9 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Mon, 1 Apr 2024 20:10:36 +0200
Subject: [PATCH 04/15] tests: lib: gui: lvgl: Migrate to version 9.2

With the update to v9.2.0 several Kconfig symbols were renamed or removed.
Adjust the test accordingly. Also several constants were renamed, rename
those also.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 tests/lib/gui/lvgl/prj.conf   |  9 +-------
 tests/lib/gui/lvgl/src/img.c  |  7 +++---
 tests/lib/gui/lvgl/src/main.c | 40 +++++++++++++++++++++++++++++------
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/tests/lib/gui/lvgl/prj.conf b/tests/lib/gui/lvgl/prj.conf
index 2667982e6e04..30b8e9b273b6 100644
--- a/tests/lib/gui/lvgl/prj.conf
+++ b/tests/lib/gui/lvgl/prj.conf
@@ -9,20 +9,18 @@ CONFIG_FLASH=y
 CONFIG_FLASH_MAP=y
 CONFIG_FILE_SYSTEM=y
 CONFIG_FILE_SYSTEM_LITTLEFS=y
+CONFIG_LV_Z_AUTO_INIT=n
 
 CONFIG_LVGL=y
 CONFIG_LV_Z_MEM_POOL_SIZE=16384
 CONFIG_LV_Z_USE_FILESYSTEM=y
-CONFIG_LV_MEM_CUSTOM=y
 CONFIG_LV_USE_LOG=y
 CONFIG_LV_COLOR_DEPTH_32=y
-CONFIG_LV_COLOR_SCREEN_TRANSP=y
 CONFIG_LV_USE_BIDI=y
 CONFIG_LV_USE_ARABIC_PERSIAN_CHARS=y
 CONFIG_LV_USE_LABEL=y
 CONFIG_LV_LABEL_TEXT_SELECTION=y
 CONFIG_LV_LABEL_LONG_TXT_HINT=y
-CONFIG_LV_USE_IMG=y
 CONFIG_LV_USE_LINE=y
 CONFIG_LV_USE_ARC=y
 CONFIG_LV_USE_WIN=y
@@ -39,9 +37,6 @@ CONFIG_LV_USE_LED=y
 CONFIG_LV_USE_MSGBOX=y
 CONFIG_LV_USE_TEXTAREA=y
 CONFIG_LV_USE_SPINBOX=y
-CONFIG_LV_USE_BTN=y
-CONFIG_LV_USE_IMGBTN=y
-CONFIG_LV_USE_BTNMATRIX=y
 CONFIG_LV_USE_KEYBOARD=y
 CONFIG_LV_USE_CHECKBOX=y
 CONFIG_LV_USE_LIST=y
@@ -71,10 +66,8 @@ CONFIG_LV_FONT_MONTSERRAT_42=y
 CONFIG_LV_FONT_MONTSERRAT_44=y
 CONFIG_LV_FONT_MONTSERRAT_46=y
 CONFIG_LV_FONT_MONTSERRAT_48=y
-CONFIG_LV_FONT_MONTSERRAT_12_SUBPX=y
 CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED=y
 CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW=y
 CONFIG_LV_FONT_SIMSUN_16_CJK=y
 CONFIG_LV_FONT_UNSCII_8=y
 CONFIG_LV_USE_FONT_COMPRESSED=y
-CONFIG_LV_USE_FONT_SUBPX=y
diff --git a/tests/lib/gui/lvgl/src/img.c b/tests/lib/gui/lvgl/src/img.c
index 004bc670a3ff..04e8ff6776e8 100644
--- a/tests/lib/gui/lvgl/src/img.c
+++ b/tests/lib/gui/lvgl/src/img.c
@@ -120,17 +120,16 @@ static const uint8_t img_data[] = {
 /* 96 */
 };
 
-static lv_img_dsc_t img_dsc = {
-	.header.always_zero = 0,
+static lv_image_dsc_t img_dsc = {
 	.header.w = 96,
 	.header.h = 96,
 	.data_size = sizeof(img_data),
-	.header.cf = LV_IMG_CF_INDEXED_1BIT,
+	.header.cf = LV_COLOR_FORMAT_I1,
 	.data = img_data,
 };
 
 
-const lv_img_dsc_t *get_lvgl_img(void)
+const lv_image_dsc_t *get_lvgl_img(void)
 {
 	return &img_dsc;
 }
diff --git a/tests/lib/gui/lvgl/src/main.c b/tests/lib/gui/lvgl/src/main.c
index 0f59d01bd02f..22aafbc7eba7 100644
--- a/tests/lib/gui/lvgl/src/main.c
+++ b/tests/lib/gui/lvgl/src/main.c
@@ -9,9 +9,11 @@
 
 #include <zephyr/kernel.h>
 #include <zephyr/device.h>
+#include <zephyr/drivers/display.h>
 #include <zephyr/fs/fs.h>
 #include <zephyr/fs/littlefs.h>
 #include <zephyr/ztest.h>
+#include <lvgl_zephyr.h>
 
 #include <lvgl.h>
 
@@ -54,6 +56,8 @@ static struct fs_mount_t mnt = {
 };
 #endif /* CONFIG_FS_LITTLEFS_BLK_DEV */
 
+static const struct device *display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
+
 ZTEST(lvgl_screen, test_get_default_screen)
 {
 	zassert_not_null(lv_scr_act(), "No default screen");
@@ -94,13 +98,37 @@ ZTEST_USER(lvgl_fs, test_add_img)
 	lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
 }
 
+void *setup_lvgl(void)
+{
+	int ret;
+
+#if CONFIG_LV_COLOR_DEPTH_1 == 1
+	display_set_pixel_format(display_dev, PIXEL_FORMAT_MONO10);
+#elif CONFIG_LV_COLOR_DEPTH_8 == 1 || CONFIG_LV_COLOR_DEPTH_24 == 1
+	/* No 8bit display pixel format not supported */
+	display_set_pixel_format(display_dev, PIXEL_FORMAT_RGB_888);
+#elif CONFIG_LV_COLOR_DEPTH_16 == 1
+	display_set_pixel_format(display_dev, PIXEL_FORMAT_RGB_565);
+#elif CONFIG_LV_COLOR_DEPTH_32 == 1
+	display_set_pixel_format(display_dev, PIXEL_FORMAT_ARGB_8888);
+#else
+#error "No display pixel format defined, is your board supported?"
+#endif
+
+	ret = lvgl_init();
+	zassert_equal(ret, 0, "Failed to initialize lvgl");
+
+	return NULL;
+}
 
 void *setup_fs(void)
 {
 	struct fs_file_t img;
 	struct fs_dirent info;
 	int ret;
-	const lv_img_dsc_t *c_img = get_lvgl_img();
+	const lv_image_dsc_t *c_img = get_lvgl_img();
+
+	setup_lvgl();
 
 	ret = fs_mount(&mnt);
 	if (ret < 0) {
@@ -122,7 +150,7 @@ void *setup_fs(void)
 		return NULL;
 	}
 
-	ret = fs_write(&img, &c_img->header, sizeof(lv_img_header_t));
+	ret = fs_write(&img, &c_img->header, sizeof(lv_image_header_t));
 	if (ret < 0) {
 		TC_PRINT("Failed to write image file header: %d\n", ret);
 		ztest_test_fail();
@@ -145,10 +173,10 @@ void *setup_fs(void)
 	return NULL;
 }
 
-void teardown_fs(void *data)
+void teardown_lvgl(void *data)
 {
-	return;
+	lv_deinit();
 }
 
-ZTEST_SUITE(lvgl_screen, NULL, NULL, NULL, NULL, NULL);
-ZTEST_SUITE(lvgl_fs, NULL, setup_fs, NULL, NULL, teardown_fs);
+ZTEST_SUITE(lvgl_screen, NULL, setup_lvgl, NULL, NULL, teardown_lvgl);
+ZTEST_SUITE(lvgl_fs, NULL, setup_fs, NULL, NULL, teardown_lvgl);

From c1b5ff9842198250fe0bf6d43ed385779c200065 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sun, 20 Oct 2024 17:13:47 +0200
Subject: [PATCH 05/15] boards: stm32h7b3i_dk: Rename LVGL DMA2D Kconfig
 symbols

Rename the defaulted DMA2D Kconfig symbols to match the new upstream
nomenclature.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 boards/st/stm32h7b3i_dk/Kconfig.defconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/boards/st/stm32h7b3i_dk/Kconfig.defconfig b/boards/st/stm32h7b3i_dk/Kconfig.defconfig
index 863570e555a1..4c7bf8c81cfb 100644
--- a/boards/st/stm32h7b3i_dk/Kconfig.defconfig
+++ b/boards/st/stm32h7b3i_dk/Kconfig.defconfig
@@ -22,10 +22,10 @@ if LVGL
 config CACHE_MANAGEMENT
 	default y
 
-config LV_USE_GPU_STM32_DMA2D
+config LV_USE_DRAW_DMA2D
 	default y
 
-config LV_GPU_DMA2D_CMSIS_INCLUDE
+config LV_DRAW_DMA2D_HAL_INCLUDE
 	default "stm32h7xx.h"
 
 config STM32_LTDC_FB_NUM

From 478f7ecc4b32aef5bda5dfbecf1423e2b235a313 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Thu, 4 Apr 2024 08:24:26 +0200
Subject: [PATCH 06/15] samples: modules: lvgl: accelerometer_chart: Migrate to
 v9.2

This patch fixes the style size setter usage in the accelerometer_chart
demo since it now expects two dimensions. Also the newly named functions
which are typedefed by the api_map in LVGL are updated to anticipate their
deprecation.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/modules/lvgl/accelerometer_chart/src/main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/samples/modules/lvgl/accelerometer_chart/src/main.c b/samples/modules/lvgl/accelerometer_chart/src/main.c
index 937f4690e79f..cf727fa121fb 100644
--- a/samples/modules/lvgl/accelerometer_chart/src/main.c
+++ b/samples/modules/lvgl/accelerometer_chart/src/main.c
@@ -62,7 +62,7 @@ static void create_accelerometer_chart(lv_obj_t *parent)
 	lv_chart_set_point_count(chart1, CONFIG_SAMPLE_CHART_POINTS_PER_SERIES);
 
 	/* Do not display point markers on the data */
-	lv_obj_set_style_size(chart1, 0, LV_PART_INDICATOR);
+	lv_obj_set_style_size(chart1, 0, 0, LV_PART_INDICATOR);
 }
 
 int main(void)
@@ -81,15 +81,15 @@ int main(void)
 		return -ENODEV;
 	}
 
-	create_accelerometer_chart(lv_scr_act());
+	create_accelerometer_chart(lv_screen_active());
 	sensor_timer = lv_timer_create(sensor_timer_cb,
 					1000 / CONFIG_SAMPLE_ACCEL_SAMPLING_RATE,
 					NULL);
-	lv_task_handler();
+	lv_timer_handler();
 	display_blanking_off(display_dev);
 
 	while (1) {
-		uint32_t sleep_ms = lv_task_handler();
+		uint32_t sleep_ms = lv_timer_handler();
 
 		k_msleep(MIN(sleep_ms, INT32_MAX));
 	}

From c8d3f7e645e798a11191d8f8b57b31c81e9b58d1 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sat, 6 Apr 2024 11:26:13 +0200
Subject: [PATCH 07/15] samples: modules: lvgl: demos: Migrate to v9.2

This patch changes the usage of LVGL functions which are typedefed in the
api map to their new version to anticipate their deprecation.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/modules/lvgl/demos/src/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/samples/modules/lvgl/demos/src/main.c b/samples/modules/lvgl/demos/src/main.c
index 59ed84244a84..19acb9171272 100644
--- a/samples/modules/lvgl/demos/src/main.c
+++ b/samples/modules/lvgl/demos/src/main.c
@@ -38,7 +38,7 @@ int main(void)
 	CONFIG_LV_USE_DEMO_STRESS, or CONFIG_LV_USE_DEMO_WIDGETS
 #endif
 
-	lv_task_handler();
+	lv_timer_handler();
 	display_blanking_off(display_dev);
 #ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
 	lvgl_print_heap_info(false);
@@ -46,7 +46,7 @@ int main(void)
 	printf("lvgl in malloc mode\n");
 #endif
 	while (1) {
-		uint32_t sleep_ms = lv_task_handler();
+		uint32_t sleep_ms = lv_timer_handler();
 
 		k_msleep(MIN(sleep_ms, INT32_MAX));
 	}

From eecd7f542ee6bb899c65aa44101e18da32a7243a Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sat, 6 Apr 2024 11:26:26 +0200
Subject: [PATCH 08/15] samples: subsys: display: lvgl: Migrate to v9.2

This patch changes the functions unsed in the subsys demo that are part of
the api map to anticipate their deprecation.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/subsys/display/lvgl/src/main.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/samples/subsys/display/lvgl/src/main.c b/samples/subsys/display/lvgl/src/main.c
index 9f704eb44230..1865cc44f167 100644
--- a/samples/subsys/display/lvgl/src/main.c
+++ b/samples/subsys/display/lvgl/src/main.c
@@ -99,7 +99,7 @@ int main(void)
 	lv_obj_t *arc;
 	lv_group_t *arc_group;
 
-	arc = lv_arc_create(lv_scr_act());
+	arc = lv_arc_create(lv_screen_active());
 	lv_obj_align(arc, LV_ALIGN_CENTER, 0, -15);
 	lv_obj_set_size(arc, 150, 150);
 
@@ -113,9 +113,9 @@ int main(void)
 	lv_group_t *btn_matrix_group;
 	static const char *const btnm_map[] = {"1", "2", "3", "4", ""};
 
-	btn_matrix = lv_btnmatrix_create(lv_scr_act());
+	btn_matrix = lv_buttonmatrix_create(lv_screen_active());
 	lv_obj_align(btn_matrix, LV_ALIGN_CENTER, 0, 70);
-	lv_btnmatrix_set_map(btn_matrix, (const char **)btnm_map);
+	lv_buttonmatrix_set_map(btn_matrix, (const char **)btnm_map);
 	lv_obj_set_size(btn_matrix, 100, 50);
 
 	btn_matrix_group = lv_group_create();
@@ -126,22 +126,22 @@ int main(void)
 	if (IS_ENABLED(CONFIG_LV_Z_POINTER_INPUT)) {
 		lv_obj_t *hello_world_button;
 
-		hello_world_button = lv_btn_create(lv_scr_act());
+		hello_world_button = lv_button_create(lv_screen_active());
 		lv_obj_align(hello_world_button, LV_ALIGN_CENTER, 0, -15);
 		lv_obj_add_event_cb(hello_world_button, lv_btn_click_callback, LV_EVENT_CLICKED,
 				    NULL);
 		hello_world_label = lv_label_create(hello_world_button);
 	} else {
-		hello_world_label = lv_label_create(lv_scr_act());
+		hello_world_label = lv_label_create(lv_screen_active());
 	}
 
 	lv_label_set_text(hello_world_label, "Hello world!");
 	lv_obj_align(hello_world_label, LV_ALIGN_CENTER, 0, 0);
 
-	count_label = lv_label_create(lv_scr_act());
+	count_label = lv_label_create(lv_screen_active());
 	lv_obj_align(count_label, LV_ALIGN_BOTTOM_MID, 0, 0);
 
-	lv_task_handler();
+	lv_timer_handler();
 	display_blanking_off(display_dev);
 
 	while (1) {
@@ -149,7 +149,7 @@ int main(void)
 			sprintf(count_str, "%d", count/100U);
 			lv_label_set_text(count_label, count_str);
 		}
-		lv_task_handler();
+		lv_timer_handler();
 		++count;
 		k_sleep(K_MSEC(10));
 	}

From 7c7bf42cad67f5e97504ac3b7666f2a8768e4695 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Wed, 3 Apr 2024 20:25:42 +0200
Subject: [PATCH 09/15] modules: lvgl: Update gluecode to v9.2

This patch updates the module gluecode to be compatible with LVGL version
9.2. This includes changes done to display and input driver initialization
  and draw buffer handling.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 modules/lvgl/Kconfig                     |  24 ++-
 modules/lvgl/Kconfig.memory              |  13 +-
 modules/lvgl/include/lv_conf.h           |  42 ++---
 modules/lvgl/include/lvgl_common_input.h |   1 -
 modules/lvgl/include/lvgl_display.h      |  26 +--
 modules/lvgl/include/lvgl_mem.h          |   3 +
 modules/lvgl/include/lvgl_zephyr.h       |  30 ++++
 modules/lvgl/input/lvgl_button_input.c   |   7 +-
 modules/lvgl/input/lvgl_common_input.c   |  16 +-
 modules/lvgl/input/lvgl_encoder_input.c  |   3 +-
 modules/lvgl/input/lvgl_keypad_input.c   |   2 +-
 modules/lvgl/input/lvgl_pointer_input.c  |   6 +-
 modules/lvgl/lvgl.c                      | 204 +++++++++++++----------
 modules/lvgl/lvgl_display.c              |  78 +++++----
 modules/lvgl/lvgl_display_16bit.c        |  16 +-
 modules/lvgl/lvgl_display_24bit.c        |  32 +---
 modules/lvgl/lvgl_display_32bit.c        |  22 +--
 modules/lvgl/lvgl_display_mono.c         | 133 +++++++++------
 modules/lvgl/lvgl_fs.c                   |  38 ++---
 modules/lvgl/lvgl_mem.c                  |  17 ++
 modules/lvgl/lvgl_shell.c                |   4 +-
 21 files changed, 396 insertions(+), 321 deletions(-)
 create mode 100644 modules/lvgl/include/lvgl_zephyr.h

diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig
index d2b76451163a..9f66720eb917 100644
--- a/modules/lvgl/Kconfig
+++ b/modules/lvgl/Kconfig
@@ -77,6 +77,8 @@ choice LV_COLOR_DEPTH
 
 	config LV_COLOR_DEPTH_32
 		bool "32: ARGB8888"
+	config LV_COLOR_DEPTH_24
+		bool "24: RGB888"
 	config LV_COLOR_DEPTH_16
 		bool "16: RGB565"
 	config LV_COLOR_DEPTH_8
@@ -86,7 +88,7 @@ choice LV_COLOR_DEPTH
 endchoice
 
 config LV_COLOR_16_SWAP
-	bool
+	bool "Swap the 2 bytes of RGB565 color."
 	depends on LV_COLOR_DEPTH_16
 
 config LV_Z_FLUSH_THREAD
@@ -128,10 +130,26 @@ config LV_Z_AREA_Y_ALIGNMENT_WIDTH
 	  the current frame dimensions to meet display and/or LCD host
 	  controller requirements. The value must be power of 2.
 
-config LV_USE_GPU_STM32_DMA2D
+config LV_Z_AUTO_INIT
+	bool "Initialize LVGL before application startup"
+	default y
+	help
+	  Configure LVGL callbacks and display initialization before the application starts.
+	  This can be useful to disable if you need to change a display's pixel format
+	  prior to initialization. If using static allocation, ensure that LV_Z_BITS_PER_PIXEL
+	  is set correctly.
+
+config LV_Z_INIT_PRIORITY
+	int "Default init priority for LVGL"
+	default 90
+	depends on LV_Z_AUTO_INIT
+	help
+	  Priority used for the automatic initialization of LVGL.
+
+config LV_USE_DRAW_DMA2D
 	bool
 
-config LV_GPU_DMA2D_CMSIS_INCLUDE
+config LV_DRAW_DMA2D_HAL_INCLUDE
 	string
 	help
 	  Must be defined to include path of CMSIS header of target processor
diff --git a/modules/lvgl/Kconfig.memory b/modules/lvgl/Kconfig.memory
index 4b4eaeefdaf7..f089dbc539eb 100644
--- a/modules/lvgl/Kconfig.memory
+++ b/modules/lvgl/Kconfig.memory
@@ -7,8 +7,12 @@ menu "Memory manager settings"
 config LV_Z_BITS_PER_PIXEL
 	int "Bits per pixel"
 	default 32
+	default 32 if LV_COLOR_DEPTH_32
+	default 24 if LV_COLOR_DEPTH_24
+	default 16 if LV_COLOR_DEPTH_16
+	default 8 if LV_COLOR_DEPTH_8
+	default 1 if LV_COLOR_DEPTH_1
 	range 1 32
-	depends on LV_Z_BUFFER_ALLOC_STATIC
 	help
 	  Number of bits per pixel.
 
@@ -88,6 +92,13 @@ config LV_Z_VBD_CUSTOM_SECTION
 	  rendering buffers to a custom location, such as tightly coupled or
 	  external memory.
 
+config LV_Z_MONOCHROME_CONVERSION_BUFFER
+	bool "Use intermediate conversion buffer for monochrome displays"
+	default y
+	help
+	  When using a monochrome display an intermediate buffer with LV_Z_VDB_SIZE
+	  is needed to perform the conversion.
+
 choice LV_Z_RENDERING_BUFFER_ALLOCATION
 	prompt "Rendering Buffer Allocation"
 	default LV_Z_BUFFER_ALLOC_STATIC
diff --git a/modules/lvgl/include/lv_conf.h b/modules/lvgl/include/lv_conf.h
index a47bcec47d25..2206c8f40a5e 100644
--- a/modules/lvgl/include/lv_conf.h
+++ b/modules/lvgl/include/lv_conf.h
@@ -12,41 +12,33 @@
 
 /* Memory manager settings */
 
-#define LV_MEMCPY_MEMSET_STD 1
-#define LV_MEM_CUSTOM        1
+#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM
 
 #if defined(CONFIG_LV_Z_MEM_POOL_HEAP_LIB_C)
-
-#define LV_MEM_CUSTOM_INCLUDE "stdlib.h"
-#define LV_MEM_CUSTOM_ALLOC   malloc
-#define LV_MEM_CUSTOM_REALLOC realloc
-#define LV_MEM_CUSTOM_FREE    free
-
+#define LV_STDLIB_INCLUDE "stdlib.h"
+#define lv_malloc_core    malloc
+#define lv_realloc_core   realloc
+#define lv_free_core      free
 #else
-
-#define LV_MEM_CUSTOM_INCLUDE "lvgl_mem.h"
-#define LV_MEM_CUSTOM_ALLOC   lvgl_malloc
-#define LV_MEM_CUSTOM_REALLOC lvgl_realloc
-#define LV_MEM_CUSTOM_FREE    lvgl_free
-
+#define LV_STDLIB_INCLUDE "lvgl_mem.h"
+#define lv_malloc_core    lvgl_malloc
+#define lv_realloc_core   lvgl_realloc
+#define lv_free_core      lvgl_free
 #endif
 
-/* HAL settings */
-
-#define LV_TICK_CUSTOM               1
-#define LV_TICK_CUSTOM_INCLUDE       <zephyr/kernel.h>
-#define LV_TICK_CUSTOM_SYS_TIME_EXPR (k_uptime_get_32())
-
 /* Misc settings */
-
-#define LV_SPRINTF_CUSTOM  1
-#define LV_SPRINTF_INCLUDE "stdio.h"
-#define lv_snprintf        snprintf
-#define lv_vsnprintf       vsnprintf
+#define lv_snprintf               snprintf
+#define lv_vsnprintf              vsnprintf
+#define LV_ASSERT_HANDLER         __ASSERT_NO_MSG(false);
+#define LV_ASSERT_HANDLER_INCLUDE "zephyr/sys/__assert.h"
 
 /* Provide definition to align LVGL buffers */
 #define LV_ATTRIBUTE_MEM_ALIGN __aligned(CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE)
 
+#ifdef CONFIG_LV_COLOR_16_SWAP
+#define LV_COLOR_16_SWAP 1
+#endif /* CONFIG_LV_COLOR_16_SWAP */
+
 /*
  * Needed because of a workaround for a GCC bug,
  * see https://github.com/lvgl/lvgl/issues/3078
diff --git a/modules/lvgl/include/lvgl_common_input.h b/modules/lvgl/include/lvgl_common_input.h
index f4aaffae2a2f..72a931a9921f 100644
--- a/modules/lvgl/include/lvgl_common_input.h
+++ b/modules/lvgl/include/lvgl_common_input.h
@@ -20,7 +20,6 @@ struct lvgl_common_input_config {
 };
 
 struct lvgl_common_input_data {
-	lv_indev_drv_t indev_drv;
 	lv_indev_t *indev;
 	lv_indev_data_t pending_event;
 	lv_indev_data_t previous_event;
diff --git a/modules/lvgl/include/lvgl_display.h b/modules/lvgl/include/lvgl_display.h
index 9a0c14c6831d..bbe4a3193b2c 100644
--- a/modules/lvgl/include/lvgl_display.h
+++ b/modules/lvgl/include/lvgl_display.h
@@ -22,35 +22,27 @@ struct lvgl_disp_data {
 };
 
 struct lvgl_display_flush {
-	lv_disp_drv_t *disp_drv;
+	lv_display_t *display;
 	uint16_t x;
 	uint16_t y;
 	struct display_buffer_descriptor desc;
 	void *buf;
 };
 
-void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
-void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
-void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
-void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
+void lvgl_flush_cb_mono(lv_display_t *display, const lv_area_t *area, uint8_t *px_map);
+void lvgl_flush_cb_16bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map);
+void lvgl_flush_cb_24bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map);
+void lvgl_flush_cb_32bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map);
 
-void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			 lv_coord_t y, lv_color_t color, lv_opa_t opa);
-void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa);
-void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa);
-void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa);
+void lvgl_rounder_cb_mono(lv_event_t *e);
+void lvgl_set_mono_conversion_buffer(uint8_t *buffer, uint32_t buffer_size);
 
-void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area);
-
-int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv);
+int set_lvgl_rendering_cb(lv_display_t *display);
 
 void lvgl_flush_display(struct lvgl_display_flush *request);
 
 #ifdef CONFIG_LV_Z_USE_ROUNDER_CB
-void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area);
+void lvgl_rounder_cb(lv_event_t *e);
 #endif
 
 #ifdef __cplusplus
diff --git a/modules/lvgl/include/lvgl_mem.h b/modules/lvgl/include/lvgl_mem.h
index 02dea4537a0d..61ce0ba0d224 100644
--- a/modules/lvgl/include/lvgl_mem.h
+++ b/modules/lvgl/include/lvgl_mem.h
@@ -9,6 +9,7 @@
 
 #include <stdlib.h>
 #include <stdbool.h>
+#include <zephyr/sys/mem_stats.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,8 @@ void lvgl_free(void *ptr);
 
 void lvgl_print_heap_info(bool dump_chunks);
 
+void lvgl_heap_stats(struct sys_memory_stats *stats);
+
 void lvgl_heap_init(void);
 
 #ifdef __cplusplus
diff --git a/modules/lvgl/include/lvgl_zephyr.h b/modules/lvgl/include/lvgl_zephyr.h
new file mode 100644
index 000000000000..28a69f1ce4be
--- /dev/null
+++ b/modules/lvgl/include/lvgl_zephyr.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_MODULES_LVGL_ZEPHYR_H_
+#define ZEPHYR_MODULES_LVGL_ZEPHYR_H_
+
+#include <zephyr/kernel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialize the LittlevGL library
+ *
+ * This function initializes the LittlevGL library and setups the display and input devices.
+ * If `LV_Z_AUTO_INIT` is disabled it must be called before any other LittlevGL function.
+ *
+ * @return 0 on success, negative errno code on failure
+ */
+int lvgl_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZEPHYR_MODULES_LVGL_ZEPHYR_H_ */
diff --git a/modules/lvgl/input/lvgl_button_input.c b/modules/lvgl/input/lvgl_button_input.c
index 9976df48ca77..b5dcd53d7806 100644
--- a/modules/lvgl/input/lvgl_button_input.c
+++ b/modules/lvgl/input/lvgl_button_input.c
@@ -17,7 +17,7 @@ struct lvgl_button_input_config {
 	struct lvgl_common_input_config common_config; /* Needs to be first member */
 	const uint16_t *input_codes;
 	uint8_t num_codes;
-	const lv_coord_t *coordinates;
+	const int32_t *coordinates;
 };
 
 static void lvgl_button_process_event(struct input_event *evt, void *user_data)
@@ -39,7 +39,7 @@ static void lvgl_button_process_event(struct input_event *evt, void *user_data)
 	}
 
 	data->pending_event.btn_id = i;
-	data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+	data->pending_event.state = evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
 
 	if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) {
 		LOG_WRN("Could not put input data into queue");
@@ -72,8 +72,7 @@ int lvgl_button_input_init(const struct device *dev)
 	LVGL_INPUT_DEFINE(inst, button, CONFIG_LV_Z_BUTTON_INPUT_MSGQ_COUNT,                       \
 			  lvgl_button_process_event);                                              \
 	static const uint16_t lvgl_button_input_codes_##inst[] = DT_INST_PROP(inst, input_codes);  \
-	static const lv_coord_t lvgl_button_coordinates_##inst[] =                                 \
-		DT_INST_PROP(inst, coordinates);                                                   \
+	static const int32_t lvgl_button_coordinates_##inst[] = DT_INST_PROP(inst, coordinates);   \
 	static const struct lvgl_button_input_config lvgl_button_input_config_##inst = {           \
 		.common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, button),                  \
 		.input_codes = lvgl_button_input_codes_##inst,                                     \
diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c
index c58d4cb84cd4..487c606d7ad9 100644
--- a/modules/lvgl/input/lvgl_common_input.c
+++ b/modules/lvgl/input/lvgl_common_input.c
@@ -23,15 +23,15 @@ lv_indev_t *lvgl_input_get_indev(const struct device *dev)
 	return common_data->indev;
 }
 
-static void lvgl_input_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data)
+static void lvgl_input_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
 {
-	const struct device *dev = drv->user_data;
+	const struct device *dev = lv_indev_get_user_data(indev);
 	const struct lvgl_common_input_config *cfg = dev->config;
 	struct lvgl_common_input_data *common_data = dev->data;
 
 	if (k_msgq_get(cfg->event_msgq, data, K_NO_WAIT) != 0) {
 		memcpy(data, &common_data->previous_event, sizeof(lv_indev_data_t));
-		if (drv->type == LV_INDEV_TYPE_ENCODER) {
+		if (lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) {
 			data->enc_diff = 0; /* For encoders, clear last movement */
 		}
 		data->continue_reading = false;
@@ -54,16 +54,16 @@ int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device *
 		return -EINVAL;
 	}
 
-	lv_indev_drv_init(&common_data->indev_drv);
-	common_data->indev_drv.type = indev_type;
-	common_data->indev_drv.read_cb = lvgl_input_read_cb;
-	common_data->indev_drv.user_data = (void *)dev;
-	common_data->indev = lv_indev_drv_register(&common_data->indev_drv);
+	common_data->indev = lv_indev_create();
 
 	if (common_data->indev == NULL) {
 		return -EINVAL;
 	}
 
+	lv_indev_set_type(common_data->indev, indev_type);
+	lv_indev_set_read_cb(common_data->indev, lvgl_input_read_cb);
+	lv_indev_set_user_data(common_data->indev, (void *)dev);
+
 	return 0;
 }
 
diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c
index fd32e2b53c09..7d63e2d4e078 100644
--- a/modules/lvgl/input/lvgl_encoder_input.c
+++ b/modules/lvgl/input/lvgl_encoder_input.c
@@ -28,7 +28,8 @@ static void lvgl_encoder_process_event(struct input_event *evt, void *user_data)
 	if (evt->code == cfg->rotation_input_code) {
 		data->pending_event.enc_diff = evt->value;
 	} else if (evt->code == cfg->button_input_code) {
-		data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+		data->pending_event.state =
+			evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
 		data->pending_event.enc_diff = 0;
 		data->pending_event.key = LV_KEY_ENTER;
 	} else {
diff --git a/modules/lvgl/input/lvgl_keypad_input.c b/modules/lvgl/input/lvgl_keypad_input.c
index 963784df0965..77f9eb209226 100644
--- a/modules/lvgl/input/lvgl_keypad_input.c
+++ b/modules/lvgl/input/lvgl_keypad_input.c
@@ -40,7 +40,7 @@ static void lvgl_keypad_process_event(struct input_event *evt, void *user_data)
 		return;
 	}
 
-	data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+	data->pending_event.state = evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
 	if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) {
 		LOG_WRN("Could not put input data into keypad queue");
 	}
diff --git a/modules/lvgl/input/lvgl_pointer_input.c b/modules/lvgl/input/lvgl_pointer_input.c
index 89f35cd04e26..0777ec2bac5f 100644
--- a/modules/lvgl/input/lvgl_pointer_input.c
+++ b/modules/lvgl/input/lvgl_pointer_input.c
@@ -32,8 +32,8 @@ static void lvgl_pointer_process_event(struct input_event *evt, void *user_data)
 	const struct device *dev = user_data;
 	const struct lvgl_pointer_input_config *cfg = dev->config;
 	struct lvgl_pointer_input_data *data = dev->data;
-	lv_disp_t *disp = lv_disp_get_default();
-	struct lvgl_disp_data *disp_data = disp->driver->user_data;
+	lv_display_t *disp = lv_display_get_default();
+	struct lvgl_disp_data *disp_data = (struct lvgl_disp_data *)lv_display_get_user_data(disp);
 	struct display_capabilities *cap = &disp_data->cap;
 	lv_point_t *point = &data->common_data.pending_event.point;
 
@@ -54,7 +54,7 @@ static void lvgl_pointer_process_event(struct input_event *evt, void *user_data)
 		break;
 	case INPUT_BTN_TOUCH:
 		data->common_data.pending_event.state =
-			evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+			evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
 		break;
 	}
 
diff --git a/modules/lvgl/lvgl.c b/modules/lvgl/lvgl.c
index 76df359e7fc7..bec72b9b7355 100644
--- a/modules/lvgl/lvgl.c
+++ b/modules/lvgl/lvgl.c
@@ -9,36 +9,44 @@
 #include <lvgl.h>
 #include "lvgl_display.h"
 #include "lvgl_common_input.h"
+#include "lvgl_zephyr.h"
 #ifdef CONFIG_LV_Z_USE_FILESYSTEM
 #include "lvgl_fs.h"
 #endif
 #ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
 #include "lvgl_mem.h"
 #endif
-#include LV_MEM_CUSTOM_INCLUDE
+#include LV_STDLIB_INCLUDE
 
 #include <zephyr/logging/log.h>
 LOG_MODULE_REGISTER(lvgl, CONFIG_LV_Z_LOG_LEVEL);
 
-static lv_disp_drv_t disp_drv;
+static lv_display_t *display;
 struct lvgl_disp_data disp_data = {
 	.blanking_on = false,
 };
 
-#define DISPLAY_NODE DT_CHOSEN(zephyr_display)
+#define DISPLAY_NODE          DT_CHOSEN(zephyr_display)
+#define IS_MONOCHROME_DISPLAY ((CONFIG_LV_Z_BITS_PER_PIXEL == 1) || (CONFIG_LV_COLOR_DEPTH_1 == 1))
+#define ALLOC_MONOCHROME_CONV_BUFFER                                                               \
+	((IS_MONOCHROME_DISPLAY == 1) && (CONFIG_LV_Z_MONOCHROME_CONVERSION_BUFFER == 1))
 
 #ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC
 
-static lv_disp_draw_buf_t disp_buf;
-
 #define DISPLAY_WIDTH  DT_PROP(DISPLAY_NODE, width)
 #define DISPLAY_HEIGHT DT_PROP(DISPLAY_NODE, height)
 
+#if IS_MONOCHROME_DISPLAY
+/* monochrome buffers are expected to have 8 preceding bytes for the color palette */
+#define BUFFER_SIZE                                                                                \
+	(((CONFIG_LV_Z_VDB_SIZE * ROUND_UP(DISPLAY_WIDTH, 8) * ROUND_UP(DISPLAY_HEIGHT, 8)) /      \
+	  100) / 8 +                                                                               \
+	 8)
+#else
 #define BUFFER_SIZE                                                                                \
 	(CONFIG_LV_Z_BITS_PER_PIXEL *                                                              \
 	 ((CONFIG_LV_Z_VDB_SIZE * DISPLAY_WIDTH * DISPLAY_HEIGHT) / 100) / 8)
-
-#define NBR_PIXELS_IN_BUFFER (BUFFER_SIZE * 8 / CONFIG_LV_Z_BITS_PER_PIXEL)
+#endif /* IS_MONOCHROME_DISPLAY */
 
 /* NOTE: depending on chosen color depth buffer may be accessed using uint8_t *,
  * uint16_t * or uint32_t *, therefore buffer needs to be aligned accordingly to
@@ -58,40 +66,34 @@ static uint8_t buf1[BUFFER_SIZE]
 		__aligned(CONFIG_LV_Z_VDB_ALIGN);
 #endif /* CONFIG_LV_Z_DOUBLE_VDB */
 
+#if ALLOC_MONOCHROME_CONV_BUFFER
+static uint8_t mono_vtile_buf[BUFFER_SIZE]
+#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION
+	Z_GENERIC_SECTION(.lvgl_buf)
+#endif
+		__aligned(CONFIG_LV_Z_VDB_ALIGN);
+#endif /* ALLOC_MONOCHROME_CONV_BUFFER */
+
 #endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */
 
 #if CONFIG_LV_Z_LOG_LEVEL != 0
-/*
- * In LVGLv8 the signature of the logging callback has changes and it no longer
- * takes the log level as an integer argument. Instead, the log level is now
- * already part of the buffer passed to the logging callback. It's not optimal
- * but we need to live with it and parse the buffer manually to determine the
- * level and then truncate the string we actually pass to the logging framework.
- */
-static void lvgl_log(const char *buf)
+static void lvgl_log(lv_log_level_t level, const char *buf)
 {
-	/*
-	 * This is ugly and should be done in a loop or something but as it
-	 * turned out, Z_LOG()'s first argument (that specifies the log level)
-	 * cannot be an l-value...
-	 *
-	 * We also assume lvgl is sane and always supplies the level string.
-	 */
-	switch (buf[1]) {
-	case 'E':
-		LOG_ERR("%s", buf + strlen("[Error] "));
+	switch (level) {
+	case LV_LOG_LEVEL_ERROR:
+		LOG_ERR("%s", buf + (sizeof("[Error] ") - 1));
 		break;
-	case 'W':
-		LOG_WRN("%s", buf + strlen("[Warn] "));
+	case LV_LOG_LEVEL_WARN:
+		LOG_WRN("%s", buf + (sizeof("[Warn] ") - 1));
 		break;
-	case 'I':
-		LOG_INF("%s", buf + strlen("[Info] "));
+	case LV_LOG_LEVEL_INFO:
+		LOG_INF("%s", buf + (sizeof("[Info] ") - 1));
 		break;
-	case 'T':
-		LOG_DBG("%s", buf + strlen("[Trace] "));
+	case LV_LOG_LEVEL_TRACE:
+		LOG_DBG("%s", buf + (sizeof("[Trace] ") - 1));
 		break;
-	case 'U':
-		LOG_INF("%s", buf + strlen("[User] "));
+	case LV_LOG_LEVEL_USER:
+		LOG_INF("%s", buf + (sizeof("[User] ") - 1));
 		break;
 	}
 }
@@ -99,52 +101,39 @@ static void lvgl_log(const char *buf)
 
 #ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC
 
-static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver)
+static int lvgl_allocate_rendering_buffers(lv_display_t *display)
 {
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data;
 	int err = 0;
 
-	if (data->cap.x_resolution <= DISPLAY_WIDTH) {
-		disp_driver->hor_res = data->cap.x_resolution;
-	} else {
-		LOG_ERR("Horizontal resolution is larger than maximum");
-		err = -ENOTSUP;
-	}
-
-	if (data->cap.y_resolution <= DISPLAY_HEIGHT) {
-		disp_driver->ver_res = data->cap.y_resolution;
-	} else {
-		LOG_ERR("Vertical resolution is larger than maximum");
-		err = -ENOTSUP;
-	}
-
-	disp_driver->draw_buf = &disp_buf;
 #ifdef CONFIG_LV_Z_DOUBLE_VDB
-	lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, &buf1, NBR_PIXELS_IN_BUFFER);
+	lv_display_set_buffers(display, &buf0, &buf1, BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
 #else
-	lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, NULL, NBR_PIXELS_IN_BUFFER);
+	lv_display_set_buffers(display, &buf0, NULL, BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
 #endif /* CONFIG_LV_Z_DOUBLE_VDB  */
 
+#if ALLOC_MONOCHROME_CONV_BUFFER
+	lvgl_set_mono_conversion_buffer(mono_vtile_buf, BUFFER_SIZE);
+#endif /* ALLOC_MONOCHROME_CONV_BUFFER */
+
 	return err;
 }
 
 #else
 
-static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver)
+static int lvgl_allocate_rendering_buffers(lv_display_t *display)
 {
 	void *buf0 = NULL;
 	void *buf1 = NULL;
 	uint16_t buf_nbr_pixels;
 	uint32_t buf_size;
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data;
-
-	disp_driver->hor_res = data->cap.x_resolution;
-	disp_driver->ver_res = data->cap.y_resolution;
+	struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display);
+	uint16_t hor_res = lv_display_get_horizontal_resolution(display);
+	uint16_t ver_res = lv_display_get_vertical_resolution(display);
 
-	buf_nbr_pixels = (CONFIG_LV_Z_VDB_SIZE * disp_driver->hor_res * disp_driver->ver_res) / 100;
+	buf_nbr_pixels = (CONFIG_LV_Z_VDB_SIZE * hor_res * ver_res) / 100;
 	/* one horizontal line is the minimum buffer requirement for lvgl */
-	if (buf_nbr_pixels < disp_driver->hor_res) {
-		buf_nbr_pixels = disp_driver->hor_res;
+	if (buf_nbr_pixels < hor_res) {
+		buf_nbr_pixels = hor_res;
 	}
 
 	switch (data->cap.current_pixel_format) {
@@ -159,42 +148,80 @@ static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver)
 		break;
 	case PIXEL_FORMAT_MONO01:
 	case PIXEL_FORMAT_MONO10:
-		buf_size = buf_nbr_pixels / 8;
+		buf_size = buf_nbr_pixels / 8 + 8;
 		buf_size += (buf_nbr_pixels % 8) == 0 ? 0 : 1;
 		break;
 	default:
 		return -ENOTSUP;
 	}
 
-	buf0 = LV_MEM_CUSTOM_ALLOC(buf_size);
+	buf0 = lv_malloc(buf_size);
 	if (buf0 == NULL) {
 		LOG_ERR("Failed to allocate memory for rendering buffer");
 		return -ENOMEM;
 	}
 
 #ifdef CONFIG_LV_Z_DOUBLE_VDB
-	buf1 = LV_MEM_CUSTOM_ALLOC(buf_size);
+	buf1 = lv_malloc(buf_size);
 	if (buf1 == NULL) {
-		LV_MEM_CUSTOM_FREE(buf0);
+		lv_free(buf0);
 		LOG_ERR("Failed to allocate memory for rendering buffer");
 		return -ENOMEM;
 	}
 #endif
 
-	disp_driver->draw_buf = LV_MEM_CUSTOM_ALLOC(sizeof(lv_disp_draw_buf_t));
-	if (disp_driver->draw_buf == NULL) {
-		LV_MEM_CUSTOM_FREE(buf0);
-		LV_MEM_CUSTOM_FREE(buf1);
-		LOG_ERR("Failed to allocate memory to store rendering buffers");
+#if ALLOC_MONOCHROME_CONV_BUFFER
+	void *vtile_buf = lv_malloc(buf_size);
+
+	if (vtile_buf == NULL) {
+		lv_free(buf0);
+		lv_free(buf1);
+		LOG_ERR("Failed to allocate memory for vtile buffer");
 		return -ENOMEM;
 	}
+	lvgl_set_mono_conversion_buffer(vtile_buf, buf_size);
+#endif /* ALLOC_MONOCHROME_CONV_BUFFER */
 
-	lv_disp_draw_buf_init(disp_driver->draw_buf, buf0, buf1, buf_nbr_pixels);
+	lv_display_set_buffers(display, buf0, buf1, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
 	return 0;
 }
 #endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */
 
-static int lvgl_init(void)
+void lv_mem_init(void)
+{
+#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
+	lvgl_heap_init();
+#endif /* CONFIG_LV_Z_MEM_POOL_SYS_HEAP */
+}
+
+void lv_mem_deinit(void)
+{
+	/* Reinitializing the heap clears all allocations, no action needed */
+}
+
+void lv_mem_monitor_core(lv_mem_monitor_t *mon_p)
+{
+	memset(mon_p, 0, sizeof(lv_mem_monitor_t));
+
+#if CONFIG_LV_Z_MEM_POOL_SYS_HEAP
+	struct sys_memory_stats stats;
+
+	lvgl_heap_stats(&stats);
+	mon_p->used_pct =
+		(stats.allocated_bytes * 100) / (stats.allocated_bytes + stats.free_bytes);
+	mon_p->max_used = stats.max_allocated_bytes;
+#else
+	LOG_WRN_ONCE("Memory statistics only supported for CONFIG_LV_Z_MEM_POOL_SYS_HEAP");
+#endif /* CONFIG_LV_Z_MEM_POOL_SYS_HEAP */
+}
+
+lv_result_t lv_mem_test_core(void)
+{
+	/* Not supported for now */
+	return LV_RESULT_OK;
+}
+
+int lvgl_init(void)
 {
 	const struct device *display_dev = DEVICE_DT_GET(DISPLAY_NODE);
 
@@ -205,15 +232,12 @@ static int lvgl_init(void)
 		return -ENODEV;
 	}
 
-#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
-	lvgl_heap_init();
-#endif
-
 #if CONFIG_LV_Z_LOG_LEVEL != 0
 	lv_log_register_print_cb(lvgl_log);
 #endif
 
 	lv_init();
+	lv_tick_set_cb(k_uptime_get_32);
 
 #ifdef CONFIG_LV_Z_USE_FILESYSTEM
 	lvgl_fs_init();
@@ -222,28 +246,26 @@ static int lvgl_init(void)
 	disp_data.display_dev = display_dev;
 	display_get_capabilities(display_dev, &disp_data.cap);
 
-	lv_disp_drv_init(&disp_drv);
-	disp_drv.user_data = (void *)&disp_data;
-
-#ifdef CONFIG_LV_Z_FULL_REFRESH
-	disp_drv.full_refresh = 1;
-#endif
-
-	err = lvgl_allocate_rendering_buffers(&disp_drv);
-	if (err != 0) {
-		return err;
+	display = lv_display_create(disp_data.cap.x_resolution, disp_data.cap.y_resolution);
+	if (!display) {
+		return -ENOMEM;
 	}
+	lv_display_set_user_data(display, &disp_data);
 
-	if (set_lvgl_rendering_cb(&disp_drv) != 0) {
+	if (set_lvgl_rendering_cb(display) != 0) {
 		LOG_ERR("Display not supported.");
 		return -ENOTSUP;
 	}
 
-	if (lv_disp_drv_register(&disp_drv) == NULL) {
-		LOG_ERR("Failed to register display device.");
-		return -EPERM;
+	err = lvgl_allocate_rendering_buffers(display);
+	if (err != 0) {
+		return err;
 	}
 
+#ifdef CONFIG_LV_Z_FULL_REFRESH
+	lv_display_set_render_mode(display, LV_DISPLAY_RENDER_MODE_FULL);
+#endif
+
 	err = lvgl_init_input_devices();
 	if (err < 0) {
 		LOG_ERR("Failed to initialize input devices.");
@@ -253,4 +275,6 @@ static int lvgl_init(void)
 	return 0;
 }
 
-SYS_INIT(lvgl_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
+#ifdef CONFIG_LV_Z_AUTO_INIT
+SYS_INIT(lvgl_init, APPLICATION, CONFIG_LV_Z_INIT_PRIORITY);
+#endif /* CONFIG_LV_Z_AUTO_INIT */
diff --git a/modules/lvgl/lvgl_display.c b/modules/lvgl/lvgl_display.c
index 12f84725008a..72c371cfc84a 100644
--- a/modules/lvgl/lvgl_display.c
+++ b/modules/lvgl/lvgl_display.c
@@ -13,6 +13,8 @@
 #ifdef CONFIG_LV_Z_FLUSH_THREAD
 
 K_SEM_DEFINE(flush_complete, 0, 1);
+/* Needed because the wait callback might be called even if not flush is pending */
+K_SEM_DEFINE(flush_required, 0, 1);
 /* Message queue will only ever need to queue one message */
 K_MSGQ_DEFINE(flush_queue, sizeof(struct lvgl_display_flush), 1, 1);
 
@@ -23,13 +25,11 @@ void lvgl_flush_thread_entry(void *arg1, void *arg2, void *arg3)
 
 	while (1) {
 		k_msgq_get(&flush_queue, &flush, K_FOREVER);
-		data = (struct lvgl_disp_data *)flush.disp_drv->user_data;
+		data = (struct lvgl_disp_data *)lv_display_get_user_data(flush.display);
 
-		flush.desc.frame_incomplete = !lv_disp_flush_is_last(flush.disp_drv);
-		display_write(data->display_dev, flush.x, flush.y, &flush.desc,
-			      flush.buf);
+		flush.desc.frame_incomplete = !lv_display_flush_is_last(flush.display);
+		display_write(data->display_dev, flush.x, flush.y, &flush.desc, flush.buf);
 
-		lv_disp_flush_ready(flush.disp_drv);
 		k_sem_give(&flush_complete);
 	}
 }
@@ -37,17 +37,19 @@ void lvgl_flush_thread_entry(void *arg1, void *arg2, void *arg3)
 K_THREAD_DEFINE(lvgl_flush_thread, CONFIG_LV_Z_FLUSH_THREAD_STACK_SIZE, lvgl_flush_thread_entry,
 		NULL, NULL, NULL, CONFIG_LV_Z_FLUSH_THREAD_PRIORITY, 0, 0);
 
-
-void lvgl_wait_cb(lv_disp_drv_t *disp_drv)
+void lvgl_wait_cb(lv_display_t *display)
 {
-	k_sem_take(&flush_complete, K_FOREVER);
+	if (k_sem_take(&flush_required, K_NO_WAIT) == 0) {
+		k_sem_take(&flush_complete, K_FOREVER);
+	}
 }
 
 #endif /* CONFIG_LV_Z_FLUSH_THREAD */
 
 #ifdef CONFIG_LV_Z_USE_ROUNDER_CB
-void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area)
+void lvgl_rounder_cb(lv_event_t *e)
 {
+	lv_area_t *area = lv_event_get_param(e);
 #if CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH != 1
 	__ASSERT(POPCOUNT(CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH) == 1, "Invalid X alignment width");
 
@@ -65,50 +67,46 @@ void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area)
 #define lvgl_rounder_cb NULL
 #endif
 
-int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv)
+int set_lvgl_rendering_cb(lv_display_t *display)
 {
 	int err = 0;
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
+	struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display);
 
 #ifdef CONFIG_LV_Z_FLUSH_THREAD
-	disp_drv->wait_cb = lvgl_wait_cb;
+	lv_display_set_flush_wait_cb(display, lvgl_wait_cb);
 #endif
 
 	switch (data->cap.current_pixel_format) {
 	case PIXEL_FORMAT_ARGB_8888:
-		disp_drv->flush_cb = lvgl_flush_cb_32bit;
-		disp_drv->rounder_cb = lvgl_rounder_cb;
-#ifdef CONFIG_LV_COLOR_DEPTH_32
-		disp_drv->set_px_cb = NULL;
-#else
-		disp_drv->set_px_cb = lvgl_set_px_cb_32bit;
-#endif
+		lv_display_set_color_format(display, LV_COLOR_FORMAT_ARGB8888);
+		lv_display_set_flush_cb(display, lvgl_flush_cb_32bit);
+		lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA,
+					display);
 		break;
 	case PIXEL_FORMAT_RGB_888:
-		disp_drv->flush_cb = lvgl_flush_cb_24bit;
-		disp_drv->rounder_cb = lvgl_rounder_cb;
-		disp_drv->set_px_cb = lvgl_set_px_cb_24bit;
+		lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB888);
+		lv_display_set_flush_cb(display, lvgl_flush_cb_24bit);
+		lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA,
+					display);
 		break;
 	case PIXEL_FORMAT_RGB_565:
 	case PIXEL_FORMAT_BGR_565:
-		disp_drv->flush_cb = lvgl_flush_cb_16bit;
-		disp_drv->rounder_cb = lvgl_rounder_cb;
-#ifdef CONFIG_LV_COLOR_DEPTH_16
-		disp_drv->set_px_cb = NULL;
-#else
-		disp_drv->set_px_cb = lvgl_set_px_cb_16bit;
-#endif
+		lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565);
+		lv_display_set_flush_cb(display, lvgl_flush_cb_16bit);
+		lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA,
+					display);
 		break;
 	case PIXEL_FORMAT_MONO01:
 	case PIXEL_FORMAT_MONO10:
-		disp_drv->flush_cb = lvgl_flush_cb_mono;
-		disp_drv->rounder_cb = lvgl_rounder_cb_mono;
-		disp_drv->set_px_cb = lvgl_set_px_cb_mono;
+		lv_display_set_color_format(display, LV_COLOR_FORMAT_I1);
+		lv_display_set_flush_cb(display, lvgl_flush_cb_mono);
+		lv_display_add_event_cb(display, lvgl_rounder_cb_mono, LV_EVENT_INVALIDATE_AREA,
+					display);
 		break;
 	default:
-		disp_drv->flush_cb = NULL;
-		disp_drv->rounder_cb = NULL;
-		disp_drv->set_px_cb = NULL;
+		lv_display_set_flush_cb(display, NULL);
+		lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA,
+					display);
 		err = -ENOTSUP;
 		break;
 	}
@@ -125,16 +123,16 @@ void lvgl_flush_display(struct lvgl_display_flush *request)
 	 */
 	k_sem_reset(&flush_complete);
 	k_msgq_put(&flush_queue, request, K_FOREVER);
+	k_sem_give(&flush_required);
 	/* Explicitly yield, in case the calling thread is a cooperative one */
 	k_yield();
 #else
 	/* Write directly to the display */
 	struct lvgl_disp_data *data =
-		(struct lvgl_disp_data *)request->disp_drv->user_data;
+		(struct lvgl_disp_data *)lv_display_get_user_data(request->display);
 
-	request->desc.frame_incomplete = !lv_disp_flush_is_last(request->disp_drv);
-	display_write(data->display_dev, request->x, request->y,
-		      &request->desc, request->buf);
-	lv_disp_flush_ready(request->disp_drv);
+	request->desc.frame_incomplete = !lv_display_flush_is_last(request->display);
+	display_write(data->display_dev, request->x, request->y, &request->desc, request->buf);
+	lv_display_flush_ready(request->display);
 #endif
 }
diff --git a/modules/lvgl/lvgl_display_16bit.c b/modules/lvgl/lvgl_display_16bit.c
index 9e8fa81bdecd..084cce0e3713 100644
--- a/modules/lvgl/lvgl_display_16bit.c
+++ b/modules/lvgl/lvgl_display_16bit.c
@@ -9,28 +9,20 @@
 #include <lvgl.h>
 #include "lvgl_display.h"
 
-void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+void lvgl_flush_cb_16bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
 {
 	uint16_t w = area->x2 - area->x1 + 1;
 	uint16_t h = area->y2 - area->y1 + 1;
 	struct lvgl_display_flush flush;
 
-	flush.disp_drv = disp_drv;
+	flush.display = display;
 	flush.x = area->x1;
 	flush.y = area->y1;
 	flush.desc.buf_size = w * 2U * h;
 	flush.desc.width = w;
 	flush.desc.pitch = w;
 	flush.desc.height = h;
-	flush.buf = (void *)color_p;
-	lvgl_flush_display(&flush);
-}
+	flush.buf = (void *)px_map;
 
-#ifndef CONFIG_LV_COLOR_DEPTH_16
-void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa)
-{
-	uint16_t *buf_xy = (uint16_t *)(buf + x * 2U + y * 2U * buf_w);
-	*buf_xy = lv_color_to16(color);
+	lvgl_flush_display(&flush);
 }
-#endif
diff --git a/modules/lvgl/lvgl_display_24bit.c b/modules/lvgl/lvgl_display_24bit.c
index c8419a69952c..0841655399f0 100644
--- a/modules/lvgl/lvgl_display_24bit.c
+++ b/modules/lvgl/lvgl_display_24bit.c
@@ -9,42 +9,28 @@
 #include <lvgl.h>
 #include "lvgl_display.h"
 
-void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+void lvgl_flush_cb_24bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
 {
 	uint16_t w = area->x2 - area->x1 + 1;
 	uint16_t h = area->y2 - area->y1 + 1;
 	struct lvgl_display_flush flush;
 
-	flush.disp_drv = disp_drv;
+	flush.display = display;
 	flush.x = area->x1;
 	flush.y = area->y1;
 	flush.desc.buf_size = w * 3U * h;
 	flush.desc.width = w;
 	flush.desc.pitch = w;
 	flush.desc.height = h;
-	flush.buf = (void *)color_p;
-	lvgl_flush_display(&flush);
-}
+	flush.buf = (void *)px_map;
 
-void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa)
-{
-	uint8_t *buf_xy = buf + x * 3U + y * 3U * buf_w;
-	lv_color32_t converted_color;
+	/* LVGL assumes BGR byte ordering, convert to RGB */
+	for (size_t i = 0; i < flush.desc.buf_size; i += 3) {
+		uint8_t tmp = px_map[i];
 
-#ifdef CONFIG_LV_COLOR_DEPTH_32
-	if (opa != LV_OPA_COVER) {
-		lv_color_t mix_color;
-
-		mix_color.ch.red = *buf_xy;
-		mix_color.ch.green = *(buf_xy + 1);
-		mix_color.ch.blue = *(buf_xy + 2);
-		color = lv_color_mix(color, mix_color, opa);
+		px_map[i] = px_map[i + 2];
+		px_map[i + 2] = tmp;
 	}
-#endif
 
-	converted_color.full = lv_color_to32(color);
-	*buf_xy = converted_color.ch.red;
-	*(buf_xy + 1) = converted_color.ch.green;
-	*(buf_xy + 2) = converted_color.ch.blue;
+	lvgl_flush_display(&flush);
 }
diff --git a/modules/lvgl/lvgl_display_32bit.c b/modules/lvgl/lvgl_display_32bit.c
index f879d3f6e97e..1a9e11abe4a3 100644
--- a/modules/lvgl/lvgl_display_32bit.c
+++ b/modules/lvgl/lvgl_display_32bit.c
@@ -9,35 +9,19 @@
 #include <lvgl.h>
 #include "lvgl_display.h"
 
-void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+void lvgl_flush_cb_32bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
 {
 	uint16_t w = area->x2 - area->x1 + 1;
 	uint16_t h = area->y2 - area->y1 + 1;
 	struct lvgl_display_flush flush;
 
-	flush.disp_drv = disp_drv;
+	flush.display = display;
 	flush.x = area->x1;
 	flush.y = area->y1;
 	flush.desc.buf_size = w * 4U * h;
 	flush.desc.width = w;
 	flush.desc.pitch = w;
 	flush.desc.height = h;
-	flush.buf = (void *)color_p;
+	flush.buf = (void *)px_map;
 	lvgl_flush_display(&flush);
 }
-
-#ifndef CONFIG_LV_COLOR_DEPTH_32
-void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			  lv_coord_t y, lv_color_t color, lv_opa_t opa)
-{
-	uint32_t *buf_xy = (uint32_t *)(buf + x * 4U + y * 4U * buf_w);
-
-	if (opa == LV_OPA_COVER) {
-		/* Do not mix if not required */
-		*buf_xy = lv_color_to32(color);
-	} else {
-		lv_color_t bg_color = *((lv_color_t *)buf_xy);
-		*buf_xy = lv_color_to32(lv_color_mix(color, bg_color, opa));
-	}
-}
-#endif
diff --git a/modules/lvgl/lvgl_display_mono.c b/modules/lvgl/lvgl_display_mono.c
index b6b766996273..c843cd96b54d 100644
--- a/modules/lvgl/lvgl_display_mono.c
+++ b/modules/lvgl/lvgl_display_mono.c
@@ -6,16 +6,80 @@
 
 #include <zephyr/kernel.h>
 #include <lvgl.h>
+#include <string.h>
 #include "lvgl_display.h"
 
-void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+static uint8_t *mono_conv_buf;
+static uint32_t mono_conv_buf_size;
+
+static ALWAYS_INLINE void set_px_at_pos(uint8_t *dst_buf, uint32_t x, uint32_t y, uint32_t width,
+					const struct display_capabilities *caps)
+{
+	uint8_t bit;
+	uint8_t *buf;
+
+	if (caps->screen_info & SCREEN_INFO_MONO_VTILED) {
+		buf = dst_buf + x + y / 8 * width;
+
+		if (caps->screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
+			bit = 7 - y % 8;
+		} else {
+			bit = y % 8;
+		}
+	} else {
+		buf = dst_buf + x / 8 + y * width / 8;
+
+		if (caps->screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
+			bit = 7 - x % 8;
+		} else {
+			bit = x % 8;
+		}
+	}
+
+	if (caps->current_pixel_format == PIXEL_FORMAT_MONO10) {
+		*buf |= BIT(bit);
+	} else {
+		*buf &= ~BIT(bit);
+	}
+}
+
+static void lvgl_transform_buffer(uint8_t **px_map, uint32_t width, uint32_t height,
+				  const struct display_capabilities *caps)
+{
+	uint8_t clear_color = caps->current_pixel_format == PIXEL_FORMAT_MONO10 ? 0x00 : 0xFF;
+
+	memset(mono_conv_buf, clear_color, mono_conv_buf_size);
+
+	/* Needed because LVGL reserves 2x4 bytes in the buffer for the color palette. */
+	*px_map += 8;
+	uint8_t *src_buf = *px_map;
+	uint32_t stride = (width + CONFIG_LV_DRAW_BUF_STRIDE_ALIGN - 1) &
+			  ~(CONFIG_LV_DRAW_BUF_STRIDE_ALIGN - 1);
+
+	for (uint32_t y = 0; y < height; y++) {
+		for (uint32_t x = 0; x < width; x++) {
+			uint32_t bit_idx = x + y * stride;
+			uint8_t src_bit = (src_buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1;
+
+			if (src_bit) {
+				set_px_at_pos(mono_conv_buf, x, y, width, caps);
+			}
+		}
+	}
+
+	memcpy(src_buf, mono_conv_buf, mono_conv_buf_size);
+}
+
+void lvgl_flush_cb_mono(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
 {
 	uint16_t w = area->x2 - area->x1 + 1;
 	uint16_t h = area->y2 - area->y1 + 1;
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
+	struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display);
 	const struct device *display_dev = data->display_dev;
 	const bool is_epd = data->cap.screen_info & SCREEN_INFO_EPD;
-	const bool is_last = lv_disp_flush_is_last(disp_drv);
+	const bool is_last = lv_display_flush_is_last(display);
+
+	lvgl_transform_buffer(&px_map, w, h, &data->cap);
 
 	if (is_epd && !data->blanking_on && !is_last) {
 		/*
@@ -36,9 +100,9 @@ void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color
 		.frame_incomplete = !is_last,
 	};
 
-	display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p);
+	display_write(display_dev, area->x1, area->y1, &desc, (void *)px_map);
 	if (data->cap.screen_info & SCREEN_INFO_DOUBLE_BUFFER) {
-		display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p);
+		display_write(display_dev, area->x1, area->y1, &desc, (void *)px_map);
 	}
 
 	if (is_epd && is_last && data->blanking_on) {
@@ -50,63 +114,30 @@ void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color
 		data->blanking_on = false;
 	}
 
-	lv_disp_flush_ready(disp_drv);
-}
-
-void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
-			 lv_coord_t y, lv_color_t color, lv_opa_t opa)
-{
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
-	uint8_t *buf_xy;
-	uint8_t bit;
-
-	if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
-		buf_xy = buf + x + y / 8 * buf_w;
-
-		if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
-			bit = 7 - y % 8;
-		} else {
-			bit = y % 8;
-		}
-	} else {
-		buf_xy = buf + x / 8 + y * buf_w / 8;
-
-		if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
-			bit = 7 - x % 8;
-		} else {
-			bit = x % 8;
-		}
-	}
-
-	if (data->cap.current_pixel_format == PIXEL_FORMAT_MONO10) {
-		if (color.full == 0) {
-			*buf_xy &= ~BIT(bit);
-		} else {
-			*buf_xy |= BIT(bit);
-		}
-	} else {
-		if (color.full == 0) {
-			*buf_xy |= BIT(bit);
-		} else {
-			*buf_xy &= ~BIT(bit);
-		}
-	}
+	lv_display_flush_ready(display);
 }
 
-void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area)
+void lvgl_rounder_cb_mono(lv_event_t *e)
 {
-	struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
+	lv_area_t *area = lv_event_get_param(e);
+	lv_display_t *display = lv_event_get_user_data(e);
+	struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display);
 
 	if (data->cap.screen_info & SCREEN_INFO_X_ALIGNMENT_WIDTH) {
 		area->x1 = 0;
 		area->x2 = data->cap.x_resolution - 1;
 	} else {
+		area->x1 &= ~0x7;
+		area->x2 |= 0x7;
 		if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
 			area->y1 &= ~0x7;
 			area->y2 |= 0x7;
-		} else {
-			area->x1 &= ~0x7;
-			area->x2 |= 0x7;
 		}
 	}
 }
+
+void lvgl_set_mono_conversion_buffer(uint8_t *buffer, uint32_t buffer_size)
+{
+	mono_conv_buf = buffer;
+	mono_conv_buf_size = buffer_size;
+}
diff --git a/modules/lvgl/lvgl_fs.c b/modules/lvgl/lvgl_fs.c
index 63a902ea9572..9e1674cf07f9 100644
--- a/modules/lvgl/lvgl_fs.c
+++ b/modules/lvgl/lvgl_fs.c
@@ -9,9 +9,9 @@
 #include <zephyr/fs/fs.h>
 #include "lvgl_fs.h"
 #include "lv_conf.h"
-#include LV_MEM_CUSTOM_INCLUDE
+#include LV_STDLIB_INCLUDE
 
-static bool lvgl_fs_ready(struct _lv_fs_drv_t *drv)
+static bool lvgl_fs_ready(lv_fs_drv_t *drv)
 {
 	return true;
 }
@@ -53,7 +53,7 @@ static lv_fs_res_t errno_to_lv_fs_res(int err)
 	}
 }
 
-static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode)
+static void *lvgl_fs_open(lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode)
 {
 	int err;
 	int zmode = FS_O_CREATE;
@@ -67,7 +67,7 @@ static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode
 	zmode |= (mode & LV_FS_MODE_WR) ? FS_O_WRITE : 0;
 	zmode |= (mode & LV_FS_MODE_RD) ? FS_O_READ : 0;
 
-	file = LV_MEM_CUSTOM_ALLOC(sizeof(struct fs_file_t));
+	file = lv_malloc(sizeof(struct fs_file_t));
 	if (!file) {
 		return NULL;
 	}
@@ -76,24 +76,23 @@ static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode
 
 	err = fs_open((struct fs_file_t *)file, path, zmode);
 	if (err) {
-		LV_MEM_CUSTOM_FREE(file);
+		lv_free(file);
 		return NULL;
 	}
 
 	return file;
 }
 
-static lv_fs_res_t lvgl_fs_close(struct _lv_fs_drv_t *drv, void *file)
+static lv_fs_res_t lvgl_fs_close(lv_fs_drv_t *drv, void *file)
 {
 	int err;
 
 	err = fs_close((struct fs_file_t *)file);
-	LV_MEM_CUSTOM_FREE(file);
+	lv_free(file);
 	return errno_to_lv_fs_res(err);
 }
 
-static lv_fs_res_t lvgl_fs_read(struct _lv_fs_drv_t *drv, void *file, void *buf, uint32_t btr,
-				uint32_t *br)
+static lv_fs_res_t lvgl_fs_read(lv_fs_drv_t *drv, void *file, void *buf, uint32_t btr, uint32_t *br)
 {
 	int err;
 
@@ -109,8 +108,8 @@ static lv_fs_res_t lvgl_fs_read(struct _lv_fs_drv_t *drv, void *file, void *buf,
 	return errno_to_lv_fs_res(err);
 }
 
-static lv_fs_res_t lvgl_fs_write(struct _lv_fs_drv_t *drv, void *file, const void *buf,
-				 uint32_t btw, uint32_t *bw)
+static lv_fs_res_t lvgl_fs_write(lv_fs_drv_t *drv, void *file, const void *buf, uint32_t btw,
+				 uint32_t *bw)
 {
 	int err;
 
@@ -133,8 +132,7 @@ static lv_fs_res_t lvgl_fs_write(struct _lv_fs_drv_t *drv, void *file, const voi
 	return errno_to_lv_fs_res(err);
 }
 
-static lv_fs_res_t lvgl_fs_seek(struct _lv_fs_drv_t *drv, void *file, uint32_t pos,
-				lv_fs_whence_t whence)
+static lv_fs_res_t lvgl_fs_seek(lv_fs_drv_t *drv, void *file, uint32_t pos, lv_fs_whence_t whence)
 {
 	int err, fs_whence;
 
@@ -155,7 +153,7 @@ static lv_fs_res_t lvgl_fs_seek(struct _lv_fs_drv_t *drv, void *file, uint32_t p
 	return errno_to_lv_fs_res(err);
 }
 
-static lv_fs_res_t lvgl_fs_tell(struct _lv_fs_drv_t *drv, void *file, uint32_t *pos_p)
+static lv_fs_res_t lvgl_fs_tell(lv_fs_drv_t *drv, void *file, uint32_t *pos_p)
 {
 	off_t pos;
 
@@ -168,7 +166,7 @@ static lv_fs_res_t lvgl_fs_tell(struct _lv_fs_drv_t *drv, void *file, uint32_t *
 	return LV_FS_RES_OK;
 }
 
-static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path)
+static void *lvgl_fs_dir_open(lv_fs_drv_t *drv, const char *path)
 {
 	void *dir;
 	int err;
@@ -178,7 +176,7 @@ static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path)
 	 */
 	path--;
 
-	dir = LV_MEM_CUSTOM_ALLOC(sizeof(struct fs_dir_t));
+	dir = lv_malloc(sizeof(struct fs_dir_t));
 	if (!dir) {
 		return NULL;
 	}
@@ -186,14 +184,14 @@ static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path)
 	fs_dir_t_init((struct fs_dir_t *)dir);
 	err = fs_opendir((struct fs_dir_t *)dir, path);
 	if (err) {
-		LV_MEM_CUSTOM_FREE(dir);
+		lv_free(dir);
 		return NULL;
 	}
 
 	return dir;
 }
 
-static lv_fs_res_t lvgl_fs_dir_read(struct _lv_fs_drv_t *drv, void *dir, char *fn)
+static lv_fs_res_t lvgl_fs_dir_read(lv_fs_drv_t *drv, void *dir, char *fn, uint32_t fn_len)
 {
 	/* LVGL expects a string as return parameter but the format of the
 	 * string is not documented.
@@ -201,12 +199,12 @@ static lv_fs_res_t lvgl_fs_dir_read(struct _lv_fs_drv_t *drv, void *dir, char *f
 	return LV_FS_RES_NOT_IMP;
 }
 
-static lv_fs_res_t lvgl_fs_dir_close(struct _lv_fs_drv_t *drv, void *dir)
+static lv_fs_res_t lvgl_fs_dir_close(lv_fs_drv_t *drv, void *dir)
 {
 	int err;
 
 	err = fs_closedir((struct fs_dir_t *)dir);
-	LV_MEM_CUSTOM_FREE(dir);
+	lv_free(dir);
 	return errno_to_lv_fs_res(err);
 }
 
diff --git a/modules/lvgl/lvgl_mem.c b/modules/lvgl/lvgl_mem.c
index 03c36146618b..eb7c1ddf1998 100644
--- a/modules/lvgl/lvgl_mem.c
+++ b/modules/lvgl/lvgl_mem.c
@@ -10,6 +10,9 @@
 #include <zephyr/init.h>
 #include <zephyr/sys/sys_heap.h>
 
+#include <zephyr/logging/log.h>
+LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL);
+
 #ifdef CONFIG_LV_Z_MEMORY_POOL_CUSTOM_SECTION
 #define HEAP_MEM_ATTRIBUTES Z_GENERIC_SECTION(.lvgl_heap) __aligned(8)
 #else
@@ -62,6 +65,20 @@ void lvgl_print_heap_info(bool dump_chunks)
 	k_spin_unlock(&lvgl_heap_lock, key);
 }
 
+void lvgl_heap_stats(struct sys_memory_stats *stats)
+{
+#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
+	k_spinlock_key_t key;
+
+	key = k_spin_lock(&lvgl_heap_lock);
+	sys_heap_runtime_stats_get(&lvgl_heap, stats);
+	k_spin_unlock(&lvgl_heap_lock, key);
+#else
+	ARG_UNUSED(stats);
+	LOG_WRN_ONCE("Enable CONFIG_SYS_HEAP_RUNTIME_STATS to use the mem monitor feature");
+#endif /* CONFIG_SYS_HEAP_RUNTIME_STATS */
+}
+
 void lvgl_heap_init(void)
 {
 	sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], CONFIG_LV_Z_MEM_POOL_SIZE);
diff --git a/modules/lvgl/lvgl_shell.c b/modules/lvgl/lvgl_shell.c
index 42d5a5e7a2ac..8979c6bc310e 100644
--- a/modules/lvgl/lvgl_shell.c
+++ b/modules/lvgl/lvgl_shell.c
@@ -20,11 +20,11 @@ static const char *lvgl_monkey_indev_as_string(lv_monkey_t *monkey)
 	lv_indev_t *input_device;
 
 	input_device = lv_monkey_get_indev(monkey);
-	if (!input_device || !input_device->driver) {
+	if (!input_device) {
 		return "unknown";
 	}
 
-	switch (input_device->driver->type) {
+	switch (lv_indev_get_type(input_device)) {
 	case LV_INDEV_TYPE_POINTER:
 		return "pointer";
 	case LV_INDEV_TYPE_KEYPAD:

From 829298909d2735cbdde9ebf2a4fd5668fdf44b6e Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Fri, 5 Apr 2024 16:40:28 +0200
Subject: [PATCH 10/15] modules: lvgl: Add zephyr OSAL implementation

This patch adds the OSAL implementation of dynamic thread creation, mutex
and thread syncronization primitive (semaphore) enabling the use of the
parallel rendering architecture provided with LVGL 9.0. To use it, set
`CONFIG_LV_Z_USE_OSAL` and your preferred dynamic thread stack allocation
method (pool or heap).

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 modules/lvgl/CMakeLists.txt             |   2 +
 modules/lvgl/Kconfig                    |   7 ++
 modules/lvgl/include/lv_conf.h          |   5 +
 modules/lvgl/include/lvgl_zephyr_osal.h |  30 +++++
 modules/lvgl/lvgl_zephyr_osal.c         | 151 ++++++++++++++++++++++++
 5 files changed, 195 insertions(+)
 create mode 100644 modules/lvgl/include/lvgl_zephyr_osal.h
 create mode 100644 modules/lvgl/lvgl_zephyr_osal.c

diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt
index 2f9ce0925ce1..5ef568e6b89b 100644
--- a/modules/lvgl/CMakeLists.txt
+++ b/modules/lvgl/CMakeLists.txt
@@ -329,6 +329,8 @@ zephyr_library_sources_ifdef(CONFIG_LV_Z_BUTTON_INPUT input/lvgl_button_input.c)
 zephyr_library_sources_ifdef(CONFIG_LV_Z_ENCODER_INPUT input/lvgl_encoder_input.c)
 zephyr_library_sources_ifdef(CONFIG_LV_Z_KEYPAD_INPUT input/lvgl_keypad_input.c)
 
+zephyr_library_sources_ifdef(CONFIG_LV_Z_USE_OSAL lvgl_zephyr_osal.c)
+
 zephyr_library_link_libraries(LVGL)
 target_link_libraries(LVGL INTERFACE zephyr_interface)
 
diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig
index 9f66720eb917..2c4506095fc5 100644
--- a/modules/lvgl/Kconfig
+++ b/modules/lvgl/Kconfig
@@ -155,6 +155,13 @@ config LV_DRAW_DMA2D_HAL_INCLUDE
 	  Must be defined to include path of CMSIS header of target processor
 	  e.g. "stm32f769xx.h" or "stm32f429xx.h"
 
+config LV_Z_USE_OSAL
+	bool "Use OSAL enabling parallel rendering"
+	depends on DYNAMIC_THREAD
+	help
+	  Use the Zephyr LVGL OSAL to enable parallel rendering
+	  pipelines.
+
 rsource "Kconfig.memory"
 rsource "Kconfig.input"
 rsource "Kconfig.shell"
diff --git a/modules/lvgl/include/lv_conf.h b/modules/lvgl/include/lv_conf.h
index 2206c8f40a5e..8f73f5e87b63 100644
--- a/modules/lvgl/include/lv_conf.h
+++ b/modules/lvgl/include/lv_conf.h
@@ -39,6 +39,11 @@
 #define LV_COLOR_16_SWAP 1
 #endif /* CONFIG_LV_COLOR_16_SWAP */
 
+#ifdef CONFIG_LV_Z_USE_OSAL
+#define LV_USE_OS            LV_OS_CUSTOM
+#define LV_OS_CUSTOM_INCLUDE "lvgl_zephyr_osal.h"
+#endif /* CONFIG_LV_Z_USE_OSAL */
+
 /*
  * Needed because of a workaround for a GCC bug,
  * see https://github.com/lvgl/lvgl/issues/3078
diff --git a/modules/lvgl/include/lvgl_zephyr_osal.h b/modules/lvgl/include/lvgl_zephyr_osal.h
new file mode 100644
index 000000000000..07877741bd87
--- /dev/null
+++ b/modules/lvgl/include/lvgl_zephyr_osal.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_
+#define ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_
+
+#include <zephyr/kernel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	k_tid_t tid;
+	k_thread_stack_t *stack;
+	struct k_thread thread;
+} lv_thread_t;
+
+typedef struct k_mutex lv_mutex_t;
+
+typedef struct k_sem lv_thread_sync_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_ */
diff --git a/modules/lvgl/lvgl_zephyr_osal.c b/modules/lvgl/lvgl_zephyr_osal.c
new file mode 100644
index 000000000000..84c118f0020d
--- /dev/null
+++ b/modules/lvgl/lvgl_zephyr_osal.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "lvgl_zephyr_osal.h"
+#include <lvgl.h>
+
+#include <zephyr/logging/log.h>
+LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL);
+
+typedef void (*lv_thread_entry)(void *);
+static void thread_entry(void *thread, void *cb, void *user_data);
+
+lv_result_t lv_thread_init(lv_thread_t *thread, lv_thread_prio_t prio, void (*callback)(void *),
+			   size_t stack_size, void *user_data)
+{
+	int thread_priority;
+
+	thread->stack = k_thread_stack_alloc(stack_size, 0);
+	if (thread->stack == NULL) {
+		return LV_RESULT_INVALID;
+	}
+
+	thread_priority = (CONFIG_NUM_PREEMPT_PRIORITIES - 1) -
+			  ((prio * (CONFIG_NUM_PREEMPT_PRIORITIES - 1)) / LV_THREAD_PRIO_HIGHEST);
+
+	thread->tid = k_thread_create(&thread->thread, thread->stack, stack_size, thread_entry,
+				      thread, callback, user_data, thread_priority, 0, K_NO_WAIT);
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_delete(lv_thread_t *thread)
+{
+	int ret;
+
+	k_thread_abort(thread->tid);
+	ret = k_thread_stack_free(thread->stack);
+	if (ret < 0) {
+		LOG_ERR("Failled to delete thread: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_mutex_init(lv_mutex_t *mutex)
+{
+	k_mutex_init(mutex);
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_mutex_lock(lv_mutex_t *mutex)
+{
+	int ret;
+
+	ret = k_mutex_lock(mutex, K_FOREVER);
+	if (ret != 0) {
+		LOG_ERR("Failed to lock mutex: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_mutex_lock_isr(lv_mutex_t *mutex)
+{
+	int ret;
+
+	ret = k_mutex_lock(mutex, K_NO_WAIT);
+	if (ret != 0) {
+		LOG_ERR("Failed to lock mutex: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_mutex_unlock(lv_mutex_t *mutex)
+{
+	int ret;
+
+	ret = k_mutex_unlock(mutex);
+	if (ret != 0) {
+		LOG_ERR("Failed to unlock mutex: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_mutex_delete(lv_mutex_t *mutex)
+{
+	ARG_UNUSED(mutex);
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_sync_init(lv_thread_sync_t *sync)
+{
+	int ret;
+
+	ret = k_sem_init(sync, 0, 1);
+	if (ret != 0) {
+		LOG_ERR("Failed to init thread sync: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_sync_wait(lv_thread_sync_t *sync)
+{
+	int ret;
+
+	ret = k_sem_take(sync, K_FOREVER);
+	if (ret < 0) {
+		LOG_ERR("Error waiting on thread sync: %d", ret);
+		return LV_RESULT_INVALID;
+	}
+
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_sync_signal(lv_thread_sync_t *sync)
+{
+	k_sem_give(sync);
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t *sync)
+{
+	k_sem_give(sync);
+	return LV_RESULT_OK;
+}
+
+lv_result_t lv_thread_sync_delete(lv_thread_sync_t *sync)
+{
+	ARG_UNUSED(sync);
+	return LV_RESULT_OK;
+}
+
+void thread_entry(void *thread, void *cb, void *user_data)
+{
+	__ASSERT_NO_MSG(cb != NULL);
+	lv_thread_entry entry_cb = (lv_thread_entry)cb;
+
+	entry_cb(user_data);
+	lv_thread_delete((lv_thread_t *)thread);
+}

From f130a061b71fe457fcb5a0555caa25da6e497279 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sat, 6 Apr 2024 20:39:52 +0200
Subject: [PATCH 11/15] tests: lib: gui: lvgl: Add testcase for OSAL
 implementation

This patch adds a testcase adding the OSAL to ensure the implementation is
built during CI.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 tests/lib/gui/lvgl/testcase.yaml | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tests/lib/gui/lvgl/testcase.yaml b/tests/lib/gui/lvgl/testcase.yaml
index 5cc8e9e1d765..ab4b6be5315d 100644
--- a/tests/lib/gui/lvgl/testcase.yaml
+++ b/tests/lib/gui/lvgl/testcase.yaml
@@ -80,3 +80,15 @@ tests:
       - EXTRA_CONF_FILE=prj_blk.conf
     tags:
       - shield
+  libraries.gui.lvgl.osal:
+    extra_configs:
+      - CONFIG_LV_Z_USE_OSAL=y
+      - CONFIG_DYNAMIC_THREAD=y
+      - CONFIG_DYNAMIC_THREAD_POOL_SIZE=4
+      - CONFIG_DYNAMIC_THREAD_ALLOC=y
+    platform_allow:
+      - native_posix/native/64
+      - native_sim/native/64
+      - native_sim
+    integration_platforms:
+      - native_sim

From 3928523c9f989e62a182c5ad92cef05eb33729d4 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sun, 7 Apr 2024 16:26:00 +0200
Subject: [PATCH 12/15] samples: modules: lvgl: demos: Add new demos

Add the new demos of LVGL 9.2:
- flex_layout
- keypad_and_encoder
- render
- scroll
- multilang

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/modules/lvgl/demos/CMakeLists.txt | 70 ++++++++++++++++++++++-
 samples/modules/lvgl/demos/Kconfig        | 53 ++++++++++++++++-
 samples/modules/lvgl/demos/README.rst     | 50 ++++++++++++++++
 samples/modules/lvgl/demos/prj.conf       |  1 +
 samples/modules/lvgl/demos/sample.yaml    | 16 +++++-
 samples/modules/lvgl/demos/src/main.c     | 41 +++++++++++--
 6 files changed, 222 insertions(+), 9 deletions(-)

diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt
index 260150097b9a..03ff9716abf2 100644
--- a/samples/modules/lvgl/demos/CMakeLists.txt
+++ b/samples/modules/lvgl/demos/CMakeLists.txt
@@ -72,7 +72,6 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE
     ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_12_compr_az.c.c
     ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_16_compr_az.c.c
     ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_28_compr_az.c.c
-    ${LVGL_DIR}/demos/transform/assets/img_transform_avatar_15.c
     ${LVGL_DIR}/demos/benchmark/lv_demo_benchmark.c
 )
 
@@ -87,3 +86,72 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE
     ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c
     ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c
 )
+
+target_sources_ifdef(CONFIG_LV_USE_DEMO_FLEX_LAYOUT app PRIVATE
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_main.c
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view.c
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_flex_loader.c
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view_child_node.c
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view_ctrl_pad.c
+    ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_ctrl_pad.c
+)
+
+target_sources_ifdef(CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER app PRIVATE
+    ${LVGL_DIR}/demos/keypad_encoder/lv_demo_keypad_encoder.c
+)
+
+target_sources_ifdef(CONFIG_LV_USE_DEMO_RENDER app PRIVATE
+    ${LVGL_DIR}/demos/render/assets/img_render_arc_bg.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_argb8888.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_i1.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_l8.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb565.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb565a8.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb888.c
+    ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_xrgb8888.c
+    ${LVGL_DIR}/demos/render/lv_demo_render.c
+)
+
+target_sources_ifdef(CONFIG_LV_USE_DEMO_SCROLL app PRIVATE
+    ${LVGL_DIR}/demos/scroll/lv_demo_scroll.c
+)
+
+target_sources_ifdef(CONFIG_LV_USE_DEMO_MULTILANG app PRIVATE
+    ${LVGL_DIR}/demos/multilang/assets/img_multilang_like.c
+    ${LVGL_DIR}/demos/multilang/assets/fonts/font_multilang_large.c
+    ${LVGL_DIR}/demos/multilang/assets/fonts/font_multilang_small.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_movie_camera.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_flexed_biceps.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_rocket.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_artist_palette.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_deciduous_tree.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_cat_face.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_red_heart.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_camera_with_flash.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_dog_face.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_books.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_earth_globe_europe_africa.c
+    ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_soccer_ball.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_19.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_4.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_8.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_5.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_16.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_22.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_9.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_6.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_18.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_17.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_13.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_2.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_3.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_25.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_14.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_1.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_11.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_7.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_15.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_12.c
+    ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_10.c
+    ${LVGL_DIR}/demos/multilang/lv_demo_multilang.c
+)
diff --git a/samples/modules/lvgl/demos/Kconfig b/samples/modules/lvgl/demos/Kconfig
index e3692e02b275..39d2cb104f5a 100644
--- a/samples/modules/lvgl/demos/Kconfig
+++ b/samples/modules/lvgl/demos/Kconfig
@@ -30,8 +30,59 @@ config LV_Z_DEMO_WIDGETS
 	bool "LVGL widgets demo"
 	select LV_USE_DEMO_WIDGETS
 	help
-	  Build stress testing demo application.
+	  Build widgets demo application.
+
+config LV_Z_DEMO_FLEX_LAYOUT
+	bool "LVGL flex layout demo"
+	select LV_USE_DEMO_FLEX_LAYOUT
+	help
+	  Build flex layout demo application.
+
+config LV_Z_DEMO_KEYPAD_AND_ENCODER
+	bool "LVGL keypad and encoder demo"
+	select LV_USE_DEMO_KEYPAD_AND_ENCODER
+	help
+	  Build keypad and encoder demo application.
+
+config LV_Z_DEMO_RENDER
+	bool "LVGL render demo"
+	select LV_USE_DEMO_RENDER
+	help
+	  Build render demo application.
+
+config LV_Z_DEMO_SCROLL
+	bool "LVGL scroll demo"
+	select LV_USE_DEMO_SCROLL
+	help
+	  Build scroll demo application.
+
+config LV_Z_DEMO_MULTILANG
+	bool "LVGL multilang demo"
+	select LV_USE_DEMO_MULTILANG
+	select LV_USE_IMGFONT
+	help
+	  Build multilang demo application.
 
 endchoice
 
+config LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+	bool "Switch scenes dynamically"
+	help
+	  Switch between scenes to render dynamically.
+
+config LV_Z_DEMO_RENDER_SCENE_INDEX
+	int "Index of the rendered scene"
+	depends on !LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+	default 0
+	range 0 11
+	help
+	  Render scene by its index (refer to lv_demo_render.h)
+
+config LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT
+	int "Seconds each rendered scene is shown"
+	depends on LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+	default 3
+	help
+	  Seconds each rendered scenar is shown
+
 source "Kconfig.zephyr"
diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst
index 8c85495342b0..7124c17a7673 100644
--- a/samples/modules/lvgl/demos/README.rst
+++ b/samples/modules/lvgl/demos/README.rst
@@ -17,6 +17,16 @@ A sample showcasing upstream LVGL demos.
       A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks.
 * Widgets
       Shows how the widgets look like out of the box using the built-in material theme.
+* Flex Layout
+      Showcases the use of the flex layout.
+* Keypad and Encoder
+      Shows how to control widget with a keypad and hardware encoder.
+* Render
+      Collection of multiple rendering tests.
+* Scroll
+      Shows the scroll behaviour of a panel with a large list.
+* Multilang
+      Shows a UI with multilanguage options, supporting unicode characters.
 
 More details can be found in `LVGL demos Readme`_.
 
@@ -72,6 +82,46 @@ These demos can be built for simulated display environment as follows:
    :goals: run
    :compact:
 
+.. zephyr-app-commands::
+   :zephyr-app: samples/modules/lvgl/demos
+   :host-os: unix
+   :board: native_sim
+   :gen-args: -DCONFIG_LV_Z_DEMO_FLEX_LAYOUT=y
+   :goals: run
+   :compact:
+
+.. zephyr-app-commands::
+   :zephyr-app: samples/modules/lvgl/demos
+   :host-os: unix
+   :board: native_sim
+   :gen-args: -DCONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER=y
+   :goals: run
+   :compact:
+
+.. zephyr-app-commands::
+   :zephyr-app: samples/modules/lvgl/demos
+   :host-os: unix
+   :board: native_sim
+   :gen-args: -DCONFIG_LV_Z_DEMO_RENDER=y
+   :goals: run
+   :compact:
+
+.. zephyr-app-commands::
+   :zephyr-app: samples/modules/lvgl/demos
+   :host-os: unix
+   :board: native_sim
+   :gen-args: -DCONFIG_LV_Z_DEMO_SCROLL=y
+   :goals: run
+   :compact:
+
+.. zephyr-app-commands::
+   :zephyr-app: samples/modules/lvgl/demos
+   :host-os: unix
+   :board: native_sim
+   :gen-args: -DCONFIG_LV_Z_DEMO_MULTILANG=y
+   :goals: run
+   :compact:
+
 Alternatively, if building from a 64-bit host machine, the previous target
 board argument may also be replaced by ``native_sim/native/64``.
 
diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf
index b977a3d30b42..aad236d1c362 100644
--- a/samples/modules/lvgl/demos/prj.conf
+++ b/samples/modules/lvgl/demos/prj.conf
@@ -13,6 +13,7 @@ CONFIG_INPUT=y
 CONFIG_LV_FONT_MONTSERRAT_12=y
 CONFIG_LV_FONT_MONTSERRAT_14=y
 CONFIG_LV_FONT_MONTSERRAT_16=y
+CONFIG_LV_FONT_MONTSERRAT_18=y
 CONFIG_LV_FONT_MONTSERRAT_24=y
 
 # Benchmark Demo
diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml
index 2677cab9383a..f092d5a9c7b4 100644
--- a/samples/modules/lvgl/demos/sample.yaml
+++ b/samples/modules/lvgl/demos/sample.yaml
@@ -34,7 +34,21 @@ tests:
   sample.modules.lvgl.demo_widgets:
     extra_configs:
       - CONFIG_LV_Z_DEMO_WIDGETS=y
-
+  sample.modules.lvgl.demo_flex_layout:
+    extra_configs:
+      - CONFIG_LV_Z_DEMO_FLEX_LAYOUT=y
+  sample.modules.lvgl.demo_keypad_encoder:
+    extra_configs:
+      - CONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER=y
+  sample.modules.lvgl.demo_render:
+    extra_configs:
+      - CONFIG_LV_Z_DEMO_RENDER=y
+  sample.modules.lvgl.demo_scroll:
+    extra_configs:
+      - CONFIG_LV_Z_DEMO_SCROLL=y
+  sample.modules.lvgl.demo_multilang:
+    extra_configs:
+      - CONFIG_LV_Z_DEMO_MULTILANG=y
   sample.modules.lvgl.demos.st_b_lcd40_dsi1_mb1166:
     filter: dt_compat_enabled("orisetech,otm8009a")
     platform_allow: stm32h747i_disco/stm32h747xx/m7
diff --git a/samples/modules/lvgl/demos/src/main.c b/samples/modules/lvgl/demos/src/main.c
index 19acb9171272..384888aa254d 100644
--- a/samples/modules/lvgl/demos/src/main.c
+++ b/samples/modules/lvgl/demos/src/main.c
@@ -18,6 +18,10 @@ LOG_MODULE_REGISTER(app);
 int main(void)
 {
 	const struct device *display_dev;
+#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+	k_timepoint_t next_scene_switch;
+	lv_demo_render_scene_t cur_scene = LV_DEMO_RENDER_SCENE_FILL;
+#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */
 
 	display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
 	if (!device_is_ready(display_dev)) {
@@ -25,17 +29,34 @@ int main(void)
 		return 0;
 	}
 
-#if defined(CONFIG_LV_USE_DEMO_MUSIC)
+#if defined(CONFIG_LV_Z_DEMO_MUSIC)
 	lv_demo_music();
-#elif defined(CONFIG_LV_USE_DEMO_BENCHMARK)
+#elif defined(CONFIG_LV_Z_DEMO_BENCHMARK)
 	lv_demo_benchmark();
-#elif defined(CONFIG_LV_USE_DEMO_STRESS)
+#elif defined(CONFIG_LV_Z_DEMO_STRESS)
 	lv_demo_stress();
-#elif defined(CONFIG_LV_USE_DEMO_WIDGETS)
+#elif defined(CONFIG_LV_Z_DEMO_WIDGETS)
 	lv_demo_widgets();
+#elif defined(CONFIG_LV_Z_DEMO_FLEX_LAYOUT)
+	lv_demo_flex_layout();
+#elif defined(CONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER)
+	lv_demo_keypad_encoder();
+#elif defined(CONFIG_LV_Z_DEMO_RENDER)
+
+#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+	lv_demo_render(cur_scene, 255);
+	next_scene_switch =
+		sys_timepoint_calc(K_SECONDS(CONFIG_LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT));
+#else
+	lv_demo_render(CONFIG_LV_Z_DEMO_RENDER_SCENE_INDEX, 255);
+#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */
+
+#elif defined(CONFIG_LV_Z_DEMO_SCROLL)
+	lv_demo_scroll();
+#elif defined(CONFIG_LV_Z_DEMO_MULTILANG)
+	lv_demo_multilang();
 #else
-#error Enable one of the demos CONFIG_LV_USE_DEMO_MUSIC, CONFIG_LV_USE_DEMO_BENCHMARK ,\
-	CONFIG_LV_USE_DEMO_STRESS, or CONFIG_LV_USE_DEMO_WIDGETS
+#error Enable one of the demos CONFIG_LV_Z_DEMO_*
 #endif
 
 	lv_timer_handler();
@@ -49,6 +70,14 @@ int main(void)
 		uint32_t sleep_ms = lv_timer_handler();
 
 		k_msleep(MIN(sleep_ms, INT32_MAX));
+#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC
+		if (sys_timepoint_expired(next_scene_switch)) {
+			cur_scene = (cur_scene + 1) % _LV_DEMO_RENDER_SCENE_NUM;
+			lv_demo_render(cur_scene, 255);
+			next_scene_switch = sys_timepoint_calc(
+				K_SECONDS(CONFIG_LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT));
+		}
+#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */
 	}
 
 	return 0;

From d10c4429ba8e18fee6cb1c3fe51bbbc478c6bec2 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Sat, 27 Jul 2024 20:31:15 +0200
Subject: [PATCH 13/15] modules: lvgl: Add support for NXP PXP engine

Adds support for the NXP PXP engine. LVGL changed
the Kconfig symbol from LV_USE_GPU_NXP_PXP to
LV_USE_PXP, but hal_nxp still relies on
LV_USE_GPU_NXP_PXP, so add a temporary symbol for it.
Additionally the drawing engines need to invalidate
ranges in the dcache, the method needs to be provided
via a lvgl_support.h file.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 modules/lvgl/Kconfig                | 14 ++++++++++++++
 modules/lvgl/include/lvgl_support.h | 17 +++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 modules/lvgl/include/lvgl_support.h

diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig
index 2c4506095fc5..803243fa43e1 100644
--- a/modules/lvgl/Kconfig
+++ b/modules/lvgl/Kconfig
@@ -162,6 +162,20 @@ config LV_Z_USE_OSAL
 	  Use the Zephyr LVGL OSAL to enable parallel rendering
 	  pipelines.
 
+config LV_USE_PXP
+	bool
+
+config LV_USE_GPU_NXP_PXP
+	bool
+	default y if LV_USE_PXP
+
+config LV_Z_PXP_INTERRUPT_PRIORITY
+	int "PXP interrupt priority"
+	depends on LV_USE_PXP
+	default 3
+	help
+	  Sets the interrupt priority for PXP
+
 rsource "Kconfig.memory"
 rsource "Kconfig.input"
 rsource "Kconfig.shell"
diff --git a/modules/lvgl/include/lvgl_support.h b/modules/lvgl/include/lvgl_support.h
new file mode 100644
index 000000000000..7b996773b90f
--- /dev/null
+++ b/modules/lvgl/include/lvgl_support.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2023 Fabian Blatz <fabianblatz@gmail.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_
+#define ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_
+
+#include <zephyr/cache.h>
+
+static ALWAYS_INLINE void DEMO_CleanInvalidateCacheByAddr(void *addr, uint16_t size)
+{
+	sys_cache_data_invd_range(addr, size);
+}
+
+#endif /* ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_ */

From 252860236cb5aec1d4fb46fa44e24165a1dc28cf Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Wed, 16 Oct 2024 08:24:19 +0200
Subject: [PATCH 14/15] samples: drivers: video: capture_to_lvgl: Migrate to
 LVGL v9.2

Adjust the Kconfig symbols of the capture to lvgl sample. LV_MEM_CUSTOM has
been removed in v9.0 and LV_USE_IMG has been changed to LV_USE_IMAGE.
Fix the changed fields for the image descriptor struct.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/drivers/video/capture_to_lvgl/prj.conf   | 3 +--
 samples/drivers/video/capture_to_lvgl/src/main.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/samples/drivers/video/capture_to_lvgl/prj.conf b/samples/drivers/video/capture_to_lvgl/prj.conf
index bd8407787cfd..4a64bbaad53d 100644
--- a/samples/drivers/video/capture_to_lvgl/prj.conf
+++ b/samples/drivers/video/capture_to_lvgl/prj.conf
@@ -11,7 +11,6 @@ CONFIG_DISPLAY_LOG_LEVEL_ERR=y
 
 CONFIG_LVGL=y
 CONFIG_LV_CONF_MINIMAL=y
-CONFIG_LV_MEM_CUSTOM=y
-CONFIG_LV_USE_IMG=y
+CONFIG_LV_USE_IMAGE=y
 CONFIG_LV_Z_MEM_POOL_SIZE=16384
 CONFIG_LV_USE_PERF_MONITOR=y
diff --git a/samples/drivers/video/capture_to_lvgl/src/main.c b/samples/drivers/video/capture_to_lvgl/src/main.c
index 0d0a07e0d553..305c5a8a0f38 100644
--- a/samples/drivers/video/capture_to_lvgl/src/main.c
+++ b/samples/drivers/video/capture_to_lvgl/src/main.c
@@ -131,11 +131,10 @@ int main(void)
 	display_blanking_off(display_dev);
 
 	const lv_img_dsc_t video_img = {
-		.header.always_zero = 0,
 		.header.w = CONFIG_VIDEO_WIDTH,
 		.header.h = CONFIG_VIDEO_HEIGHT,
 		.data_size = CONFIG_VIDEO_WIDTH * CONFIG_VIDEO_HEIGHT * sizeof(lv_color_t),
-		.header.cf = LV_IMG_CF_TRUE_COLOR,
+		.header.cf = LV_COLOR_FORMAT_NATIVE,
 		.data = (const uint8_t *)buffers[0]->buffer,
 	};
 

From 054aa67b57432888141cd780f83f331c339aadd1 Mon Sep 17 00:00:00 2001
From: Fabian Blatz <fabianblatz@gmail.com>
Date: Tue, 19 Nov 2024 17:40:00 +0100
Subject: [PATCH 15/15] samples: modules: lvgl: transparency: Migrate to v9.2

Removes the LV_COLOR_SCREEN_TRANSP Kconfig option as its not part of the
modules Kconfig anymore and renames the functions according to the new v9.2
API.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
---
 samples/modules/lvgl/screen_transparency/prj.conf   |  1 -
 samples/modules/lvgl/screen_transparency/src/main.c | 13 ++++++-------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/samples/modules/lvgl/screen_transparency/prj.conf b/samples/modules/lvgl/screen_transparency/prj.conf
index 7c857deba03f..20856b0155c9 100644
--- a/samples/modules/lvgl/screen_transparency/prj.conf
+++ b/samples/modules/lvgl/screen_transparency/prj.conf
@@ -4,6 +4,5 @@ CONFIG_LOG=y
 CONFIG_LVGL=y
 CONFIG_LV_Z_MEM_POOL_SIZE=16384
 CONFIG_LV_COLOR_DEPTH_32=y
-CONFIG_LV_COLOR_SCREEN_TRANSP=y
 
 CONFIG_DISPLAY=y
diff --git a/samples/modules/lvgl/screen_transparency/src/main.c b/samples/modules/lvgl/screen_transparency/src/main.c
index 64494ffdaed1..b0e6164fc8b9 100644
--- a/samples/modules/lvgl/screen_transparency/src/main.c
+++ b/samples/modules/lvgl/screen_transparency/src/main.c
@@ -21,14 +21,13 @@ static void initialize_gui(void)
 	lv_obj_t *label;
 
 	/* Configure screen and background for transparency */
-	lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_TRANSP, LV_PART_MAIN);
-	lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP);
-	lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x000000), LV_PART_MAIN);
+	lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, LV_PART_MAIN);
+	lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, LV_PART_MAIN);
 
 	/* Create a label, set its text and align it to the center */
-	label = lv_label_create(lv_scr_act());
+	label = lv_label_create(lv_screen_active());
 	lv_label_set_text(label, "Hello, world!");
-	lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xff00ff), LV_PART_MAIN);
+	lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xff00ff), LV_PART_MAIN);
 	lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
 }
 
@@ -60,11 +59,11 @@ int main(void)
 
 	initialize_gui();
 
-	lv_task_handler();
+	lv_timer_handler();
 	display_blanking_off(display_dev);
 
 	while (1) {
-		uint32_t sleep_ms = lv_task_handler();
+		uint32_t sleep_ms = lv_timer_handler();
 
 		k_msleep(MIN(sleep_ms, INT32_MAX));
 	}