diff --git a/arch/sandbox/dts/cedit.dtsi b/arch/sandbox/dts/cedit.dtsi index 9bd84e62936..facd7a49bef 100644 --- a/arch/sandbox/dts/cedit.dtsi +++ b/arch/sandbox/dts/cedit.dtsi @@ -39,6 +39,9 @@ /* IDs for the menu items */ item-id = ; + + /* values for the menu items */ + item-value = <0 3 6>; }; power-loss { diff --git a/boot/expo_build.c b/boot/expo_build.c index a4df798adeb..fece3ea67f9 100644 --- a/boot/expo_build.c +++ b/boot/expo_build.c @@ -227,10 +227,10 @@ static void list_strings(struct build_info *info) static int menu_build(struct build_info *info, ofnode node, struct scene *scn, uint id, struct scene_obj **objp) { + const u32 *item_ids, *item_values; struct scene_obj_menu *menu; + int ret, size, i, num_items; uint title_id, menu_id; - const u32 *item_ids; - int ret, size, i; const char *name; name = ofnode_get_name(node); @@ -254,9 +254,15 @@ static int menu_build(struct build_info *info, ofnode node, struct scene *scn, return log_msg_ret("itm", -EINVAL); if (!size || size % sizeof(u32)) return log_msg_ret("isz", -EINVAL); - size /= sizeof(u32); + num_items = size / sizeof(u32); - for (i = 0; i < size; i++) { + item_values = ofnode_read_prop(node, "item-value", &size); + if (item_values) { + if (size != num_items * sizeof(u32)) + return log_msg_ret("vsz", -EINVAL); + } + + for (i = 0; i < num_items; i++) { struct scene_menitem *item; uint label, key, desc; @@ -280,6 +286,8 @@ static int menu_build(struct build_info *info, ofnode node, struct scene *scn, desc, 0, 0, &item); if (ret < 0) return log_msg_ret("mi", ret); + if (item_values) + item->value = fdt32_to_cpu(item_values[i]); } *objp = &menu->obj; diff --git a/boot/scene_internal.h b/boot/scene_internal.h index be25f6a8b96..ec9008ea593 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -281,6 +281,16 @@ struct scene_menitem *scene_menuitem_find(const struct scene_obj_menu *menu, struct scene_menitem *scene_menuitem_find_seq(const struct scene_obj_menu *menu, uint seq); +/** + * scene_menuitem_find_val() - Find the menu item with a given value + * + * @menu: Menu to check + * @find_val: Value to look for + * Return: menu item if found, else NULL + */ +struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu, + int val); + /** * scene_bbox_union() - update bouding box with the demensions of an object * diff --git a/boot/scene_menu.c b/boot/scene_menu.c index c331f6670cc..04ff1590bc1 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -61,6 +61,22 @@ struct scene_menitem *scene_menuitem_find_seq(const struct scene_obj_menu *menu, return NULL; } +struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu, + int val) +{ + struct scene_menitem *item; + uint i; + + i = 0; + list_for_each_entry(item, &menu->item_head, sibling) { + if (item->value == val) + return item; + i++; + } + + return NULL; +} + /** * update_pointers() - Update the pointer object and handle highlights * @@ -416,6 +432,7 @@ int scene_menuitem(struct scene *scn, uint menu_id, const char *name, uint id, item->desc_id = desc_id; item->preview_id = preview_id; item->flags = flags; + item->value = INT_MAX; list_add_tail(&item->sibling, &menu->item_head); if (itemp) diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst index d8115c463c1..cc7c36173db 100644 --- a/doc/develop/expo.rst +++ b/doc/develop/expo.rst @@ -361,6 +361,13 @@ item-id Specifies the ID for each menu item. These are used for checking which item has been selected. +item-value + type: u32 list, optional + + Specifies the value for each menu item. These are used for saving and + loading. If this is omitted the value is its position in the menu (0..n-1). + Valid values are positive and negative integers INT_MIN...(INT_MAX - 1). + item-label / item-label-id type: string list / u32 list, required @@ -474,6 +481,9 @@ strings are provided inline in the nodes where they are used. /* IDs for the menu items */ item-id = ; + + /* values for the menu items */ + item-value = <(-1) 3 6>; }; power-loss { diff --git a/include/expo.h b/include/expo.h index d6e2ccee41b..acff98ea65b 100644 --- a/include/expo.h +++ b/include/expo.h @@ -330,6 +330,7 @@ enum scene_menuitem_flags_t { * @desc_id: ID of text object to use as the description text * @preview_id: ID of the preview object, or 0 if none * @flags: Flags for this item + * @value: Value for this item, or INT_MAX to use sequence * @sibling: Node to link this item to its siblings */ struct scene_menitem { @@ -340,6 +341,7 @@ struct scene_menitem { uint desc_id; uint preview_id; uint flags; + int value; struct list_head sibling; }; diff --git a/test/boot/expo.c b/test/boot/expo.c index b0bf2988bf0..1c2e746decc 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -717,6 +717,7 @@ static int expo_test_build(struct unit_test_state *uts) ut_asserteq(0, item->desc_id); ut_asserteq(0, item->preview_id); ut_asserteq(0, item->flags); + ut_asserteq(0, item->value); txt = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE); ut_asserteq_str("2 GHz", expo_get_str(exp, txt->str_id)); diff --git a/test/boot/files/expo_layout.dts b/test/boot/files/expo_layout.dts index bed552288f4..ebe5adb27bb 100644 --- a/test/boot/files/expo_layout.dts +++ b/test/boot/files/expo_layout.dts @@ -39,6 +39,9 @@ item-id = ; + /* values for the menu items */ + item-value = <(-1) 3 6>; + start-bit = <0x400>; bit-length = <2>; };