diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f927053df95d6d3fc498dfe743808899bb0..644c445693b740936d43e8d1c6e5cfec5451ab03 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
 	char *s;
 	char temp[6][200];
 
-	m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+	m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+			NULL, NULL);
 
 	for (i = 0; display->menulist[i]; i++) {
 		sprintf(key, "%d", i + 1);
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db96853345f503a5b569ff720caf0a49712c..2dbd49cbd6641352786a24110e0d3646f66f7dfc 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
 	/*
 	 * Create a menu and add items for all the labels.
 	 */
-	m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+	m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+			NULL, NULL);
 
 	if (!m)
 		return NULL;
diff --git a/common/menu.c b/common/menu.c
index 6b2a2db3e0acae40f1332a349057de8ab96b161c..322b75e62f27e23d433c7504fc072502e651f33c 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
 	char *title;
 	int prompt;
 	void (*item_data_print)(void *);
+	char *(*item_choice)(void *);
+	void *item_choice_data;
 	struct list_head items;
 };
 
@@ -204,18 +206,26 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
 
 		menu_display(m);
 
-		readret = readline_into_buffer("Enter choice: ", cbuf,
-				m->timeout / 10);
+		if (!m->item_choice) {
+			readret = readline_into_buffer("Enter choice: ", cbuf,
+					m->timeout / 10);
 
-		if (readret >= 0) {
-			choice_item = menu_item_by_key(m, cbuf);
-
-			if (!choice_item) {
-				printf("%s not found\n", cbuf);
-				m->timeout = 0;
+			if (readret >= 0) {
+				choice_item = menu_item_by_key(m, cbuf);
+				if (!choice_item)
+					printf("%s not found\n", cbuf);
+			} else {
+				return menu_default_choice(m, choice);
 			}
-		} else
-			return menu_default_choice(m, choice);
+		} else {
+			char *key = m->item_choice(m->item_choice_data);
+
+			if (key)
+				choice_item = menu_item_by_key(m, key);
+		}
+
+		if (!choice_item)
+			m->timeout = 0;
 	}
 
 	*choice = choice_item->data;
@@ -348,11 +358,19 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
  * what must be entered to select an item, the item_data_print function should
  * make it obvious what the key for each entry is.
  *
+ * item_choice - If not NULL, will be called when asking the user to choose an
+ * item. Returns a key string corresponding to the choosen item or NULL if
+ * no item has been selected.
+ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
  * Returns a pointer to the menu if successful, or NULL if there is
  * insufficient memory available to create the menu.
  */
 struct menu *menu_create(char *title, int timeout, int prompt,
-				void (*item_data_print)(void *))
+				void (*item_data_print)(void *),
+				char *(*item_choice)(void *),
+				void *item_choice_data)
 {
 	struct menu *m;
 
@@ -365,6 +383,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
 	m->prompt = prompt;
 	m->timeout = timeout;
 	m->item_data_print = item_data_print;
+	m->item_choice = item_choice;
+	m->item_choice_data = item_choice_data;
 
 	if (title) {
 		m->title = strdup(title);
diff --git a/doc/README.menu b/doc/README.menu
index 6ce6bbab80728db810d75196e0c5615b4e9efb0a..c9493984cada06c01ab256fc1867d478354e98a6 100644
--- a/doc/README.menu
+++ b/doc/README.menu
@@ -51,7 +51,9 @@ struct menu;
  * menu_create() - Creates a menu handle with default settings
  */
 struct menu *menu_create(char *title, int timeout, int prompt,
-				void (*item_data_print)(void *));
+				void (*item_data_print)(void *),
+				char *(*item_choice)(void *),
+				void *item_choice_data);
 
 /*
  * menu_item_add() - Adds or replaces a menu item
diff --git a/include/menu.h b/include/menu.h
index 7af5fdb0edfa4302b3162f75518d02c63921ddb3..f4dd5af165f10b2d9c0988762f14bfbbdae61c72 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,7 +21,9 @@
 struct menu;
 
 struct menu *menu_create(char *title, int timeout, int prompt,
-				void (*item_data_print)(void *));
+				void (*item_data_print)(void *),
+				char *(*item_choice)(void *),
+				void *item_choice_data);
 int menu_default_set(struct menu *m, char *item_key);
 int menu_get_choice(struct menu *m, void **choice);
 int menu_item_add(struct menu *m, char *item_key, void *item_data);