summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sandbox/dts/cedit.dtsi3
-rw-r--r--boot/expo_build.c16
-rw-r--r--boot/scene_internal.h10
-rw-r--r--boot/scene_menu.c17
-rw-r--r--doc/develop/expo.rst10
-rw-r--r--include/expo.h2
-rw-r--r--test/boot/expo.c1
-rw-r--r--test/boot/files/expo_layout.dts3
8 files changed, 58 insertions, 4 deletions
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 = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+
+ /* 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
@@ -282,6 +282,16 @@ 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
*
* Updates @bbox so that it encompasses the bounding box of object @id
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 = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+
+ /* 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 = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+ /* values for the menu items */
+ item-value = <(-1) 3 6>;
+
start-bit = <0x400>;
bit-length = <2>;
};