summaryrefslogtreecommitdiff
path: root/board/freescale/common/recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/freescale/common/recovery.c')
-rw-r--r--board/freescale/common/recovery.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/board/freescale/common/recovery.c b/board/freescale/common/recovery.c
new file mode 100644
index 0000000..d133a9d
--- /dev/null
+++ b/board/freescale/common/recovery.c
@@ -0,0 +1,103 @@
+/*
+ * Freescale Android Recovery mode checking routing
+
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ */
+#include <common.h>
+#include <malloc.h>
+#include "recovery.h"
+
+#ifndef CONFIG_MXC_KPD
+#error "error! keypad must be configured to support recovery"
+#endif
+#include <mxc_keyb.h>
+
+#define PRESSED_HOME 0x01
+#define PRESSED_POWER 0x02
+#define RECOVERY_KEY_MASK (PRESSED_HOME | PRESSED_POWER)
+
+extern int check_recovery_cmd_file(void);
+extern enum boot_device get_boot_device(void);
+
+inline int test_key(int value, struct kpp_key_info *ki)
+{
+ return (ki->val == value) && (ki->evt == KDepress);
+}
+
+int check_key_pressing(void)
+{
+ struct kpp_key_info *key_info;
+ int state = 0, keys, i;
+
+ mxc_kpp_init();
+
+ puts("Detecting HOME+POWER key for recovery ...\n");
+
+ /* Check for home + power */
+ keys = mxc_kpp_getc(&key_info);
+ if (keys < 2)
+ return 0;
+
+ for (i = 0; i < keys; i++) {
+ if (test_key(CONFIG_POWER_KEY, &key_info[i]))
+ state |= PRESSED_HOME;
+ else if (test_key(CONFIG_HOME_KEY, &key_info[i]))
+ state |= PRESSED_POWER;
+ }
+
+ free(key_info);
+
+ if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK)
+ return 1;
+
+ return 0;
+}
+
+extern struct reco_envs supported_reco_envs[];
+
+void setup_recovery_env(void)
+{
+ char *env, *boot_args, *boot_cmd;
+ int bootdev = get_boot_device();
+
+ boot_cmd = supported_reco_envs[bootdev].cmd;
+ boot_args = supported_reco_envs[bootdev].args;
+
+ if (boot_cmd == NULL) {
+ printf("Unsupported bootup device for recovery\n");
+ return;
+ }
+
+ printf("setup env for recovery..\n");
+
+ env = getenv("bootargs_android_recovery");
+ /* Set env to recovery mode */
+ if (!env)
+ setenv("bootargs_android", boot_args);
+ else
+ setenv("bootargs_android", env);
+
+ env = getenv("bootcmd_android_recovery");
+ if (!env)
+ setenv("bootcmd_android", boot_cmd);
+ else
+ setenv("bootcmd_android", env);
+ setenv("bootcmd", "run bootcmd_android");
+
+}
+
+/* export to lib_arm/board.c */
+void check_recovery_mode(void)
+{
+ if (check_key_pressing())
+ setup_recovery_env();
+ else if (check_recovery_cmd_file()) {
+ puts("Recovery command file founded!\n");
+ setup_recovery_env();
+ }
+}