Skip to content

Commit 4a75a93

Browse files
JarmouniAkartben
authored andcommitted
modules: lvgl: add multi-display input support
Add support for binding LV input devs to multiple displays Signed-off-by: Abderrahmane JARMOUNI <git@jarmouni.me>
1 parent 0be9445 commit 4a75a93

File tree

6 files changed

+53
-5
lines changed

6 files changed

+53
-5
lines changed

dts/bindings/input/zephyr,lvgl-common-input.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright 2023 Fabian Blatz <fabianblatz@gmail.com>
2+
# Copyright 2025 Abderrahmane JARMOUNI
23
# SPDX-License-Identifier: Apache-2.0
34

45
# Common fields for input lvgl pseudo devices
@@ -8,3 +9,8 @@ properties:
89
type: phandle
910
description: |
1011
Input device phandle.
12+
display:
13+
type: phandle
14+
description: |
15+
Phandle of the display device to pass input commands to.
16+
Used in multi-display setup.

modules/lvgl/include/lvgl_common_input.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern "C" {
1717

1818
struct lvgl_common_input_config {
1919
struct k_msgq *event_msgq;
20+
const struct device *display_dev;
2021
};
2122

2223
struct lvgl_common_input_data {

modules/lvgl/input/lvgl_common_input.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
/*
22
* Copyright 2023 Fabian Blatz <fabianblatz@gmail.com>
3+
* Copyright 2025 Abderrahmane JARMOUNI
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
67
#include "lvgl_common_input.h"
78

89
#include <zephyr/device.h>
910
#include <zephyr/kernel.h>
10-
#include <zephyr/logging/log.h>
1111
#include <lvgl_input_device.h>
12+
#include <lvgl_display.h>
13+
#include <zephyr/logging/log.h>
1214
#include "lvgl_pointer_input.h"
1315
#include "lvgl_button_input.h"
1416
#include "lvgl_encoder_input.h"
@@ -42,13 +44,42 @@ static void lvgl_input_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
4244
data->continue_reading = k_msgq_num_used_get(cfg->event_msgq) > 0;
4345
}
4446

47+
static lv_display_t *lvgl_input_get_display(const struct device *dev)
48+
{
49+
const struct lvgl_common_input_config *cfg = dev->config;
50+
const struct device *disp_dev = cfg->display_dev;
51+
struct lvgl_disp_data *lv_disp_data;
52+
lv_display_t *lv_disp = NULL;
53+
54+
if (disp_dev == NULL) {
55+
return NULL;
56+
}
57+
58+
for (int i = 0; i < DT_ZEPHYR_DISPLAYS_COUNT; i++) {
59+
lv_disp = lv_display_get_next(lv_disp);
60+
if (lv_disp == NULL) {
61+
LOG_ERR("Could not find LV display objects of all Zephyr displays");
62+
break;
63+
}
64+
lv_disp_data = (struct lvgl_disp_data *)lv_display_get_user_data(lv_disp);
65+
if (disp_dev == lv_disp_data->display_dev) {
66+
return lv_disp;
67+
}
68+
}
69+
70+
LOG_ERR("LV display corresponding to display device %s not found", disp_dev->name);
71+
__ASSERT_NO_MSG(false);
72+
73+
return NULL;
74+
}
75+
4576
int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device *dev)
4677
{
47-
/* Currently no indev binding has its dedicated data
48-
* if that ever changes ensure that `lvgl_common_input_data`
49-
* remains the first member
78+
/* Ensure that `lvgl_common_input_data` remains the first member
79+
* of indev dedicated data
5080
*/
5181
struct lvgl_common_input_data *common_data = dev->data;
82+
lv_display_t *disp;
5283

5384
if (common_data == NULL) {
5485
return -EINVAL;
@@ -64,6 +95,9 @@ int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device *
6495
lv_indev_set_read_cb(common_data->indev, lvgl_input_read_cb);
6596
lv_indev_set_user_data(common_data->indev, (void *)dev);
6697

98+
disp = lvgl_input_get_display(dev);
99+
lv_indev_set_display(common_data->indev, disp);
100+
67101
return 0;
68102
}
69103

modules/lvgl/input/lvgl_encoder_input.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ int lvgl_encoder_input_init(const struct device *dev)
6565
lvgl_encoder_process_event); \
6666
static const struct lvgl_encoder_input_config lvgl_encoder_input_config_##inst = { \
6767
.common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, encoder), \
68+
.common_config.display_dev = \
69+
DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, display)), \
6870
.rotation_input_code = ROTATION_CODE(inst), \
6971
.button_input_code = BUTTON_CODE(inst), \
7072
}; \

modules/lvgl/input/lvgl_keypad_input.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ int lvgl_keypad_input_init(const struct device *dev)
6363
static const uint16_t lvgl_keypad_lvgl_codes_##inst[] = DT_INST_PROP(inst, lvgl_codes); \
6464
static const struct lvgl_keypad_input_config lvgl_keypad_input_config_##inst = { \
6565
.common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, keypad), \
66+
.common_config.display_dev = \
67+
DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, display)), \
6668
.input_codes = lvgl_keypad_input_codes_##inst, \
6769
.lvgl_codes = lvgl_keypad_lvgl_codes_##inst, \
6870
.num_codes = DT_INST_PROP_LEN(inst, input_codes), \

modules/lvgl/input/lvgl_pointer_input.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright 2023 Fabian Blatz <fabianblatz@gmail.com>
3+
* Copyright 2025 Abderrahmane JARMOUNI
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -32,7 +33,7 @@ static void lvgl_pointer_process_event(struct input_event *evt, void *user_data)
3233
const struct device *dev = user_data;
3334
const struct lvgl_pointer_input_config *cfg = dev->config;
3435
struct lvgl_pointer_input_data *data = dev->data;
35-
lv_display_t *disp = lv_display_get_default();
36+
lv_display_t *disp = lv_indev_get_display(data->common_data.indev);
3637
struct lvgl_disp_data *disp_data = (struct lvgl_disp_data *)lv_display_get_user_data(disp);
3738
struct display_capabilities *cap = &disp_data->cap;
3839
lv_point_t *point = &data->common_data.pending_event.point;
@@ -137,6 +138,8 @@ int lvgl_pointer_input_init(const struct device *dev)
137138
lvgl_pointer_process_event); \
138139
static const struct lvgl_pointer_input_config lvgl_pointer_input_config_##inst = { \
139140
.common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, pointer), \
141+
.common_config.display_dev = \
142+
DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, display)), \
140143
.swap_xy = DT_INST_PROP(inst, swap_xy), \
141144
.invert_x = DT_INST_PROP(inst, invert_x), \
142145
.invert_y = DT_INST_PROP(inst, invert_y), \

0 commit comments

Comments
 (0)