]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
expo: Allow menu items to have values
authorSimon Glass <sjg@chromium.org>
Mon, 14 Oct 2024 22:31:58 +0000 (16:31 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 18 Oct 2024 20:10:22 +0000 (14:10 -0600)
At present menu items are stored according to their sequence number in
the menu. In some cases we may want to have holes in that sequence, or
not use a sequence at all.

Add a new 'value' property for menu items. This will be used for
reading and writing, if present. If there is no 'value' property, then
the normal sequence number will be used instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/sandbox/dts/cedit.dtsi
boot/expo_build.c
boot/scene_internal.h
boot/scene_menu.c
doc/develop/expo.rst
include/expo.h
test/boot/expo.c
test/boot/files/expo_layout.dts

index 9bd84e62936745e04915a8c57e1dfded1d455482..facd7a49befcca6b7ef96c6fa7ec151abc7b90ee 100644 (file)
@@ -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 {
index a4df798adebd474a48281fa10bf74716aec59a9c..fece3ea67f913026a9b6e1e9b557002db40b0e4e 100644 (file)
@@ -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;
 
index be25f6a8b967f9ee285ef4f40b257f41e2909d34..ec9008ea593b3872434be19ea1ccedb20cd159b1 100644 (file)
@@ -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
  *
index c331f6670cce510e26dbab4a53af6943c2bd861a..04ff1590bc1bced9cad8cdec86b35dcdbc0048d6 100644 (file)
@@ -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)
index d8115c463c1b07affeb6bb18e80aa149307635e5..cc7c36173dbe929f77a87f040f3deacbf2eb8a97 100644 (file)
@@ -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 {
index d6e2ccee41bfc686c259dea421caf90da7c2da50..acff98ea65ba3b6530aba94521ca12e68d26037e 100644 (file)
@@ -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;
 };
 
index b0bf2988bf0dfa7fa4da3a5a76f2cdf2db73ecbc..1c2e746deccc60f0cdc0369a08cd6a0632a0294a 100644 (file)
@@ -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));
index bed552288f4cd49fd4186e5ac9839fe3ffd401bd..ebe5adb27bbea5d8e5c2d61312108b1059a6fd74 100644 (file)
@@ -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>;
                        };