xref: /OK3568_Linux_fs/u-boot/board/samsung/common/misc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2013 Samsung Electronics
3*4882a593Smuzhiyun  * Przemyslaw Marczak <p.marczak@samsung.com>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <lcd.h>
10*4882a593Smuzhiyun #include <libtizen.h>
11*4882a593Smuzhiyun #include <samsung/misc.h>
12*4882a593Smuzhiyun #include <errno.h>
13*4882a593Smuzhiyun #include <version.h>
14*4882a593Smuzhiyun #include <malloc.h>
15*4882a593Smuzhiyun #include <memalign.h>
16*4882a593Smuzhiyun #include <linux/sizes.h>
17*4882a593Smuzhiyun #include <asm/arch/cpu.h>
18*4882a593Smuzhiyun #include <asm/gpio.h>
19*4882a593Smuzhiyun #include <linux/input.h>
20*4882a593Smuzhiyun #include <dm.h>
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * Use #ifdef to work around conflicting headers while we wait for this to be
23*4882a593Smuzhiyun  * converted to driver model.
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun #ifdef CONFIG_DM_PMIC_MAX77686
26*4882a593Smuzhiyun #include <power/max77686_pmic.h>
27*4882a593Smuzhiyun #endif
28*4882a593Smuzhiyun #ifdef CONFIG_DM_PMIC_MAX8998
29*4882a593Smuzhiyun #include <power/max8998_pmic.h>
30*4882a593Smuzhiyun #endif
31*4882a593Smuzhiyun #ifdef CONFIG_PMIC_MAX8997
32*4882a593Smuzhiyun #include <power/max8997_pmic.h>
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun #include <power/pmic.h>
35*4882a593Smuzhiyun #include <mmc.h>
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #ifdef CONFIG_SET_DFU_ALT_INFO
set_dfu_alt_info(char * interface,char * devstr)40*4882a593Smuzhiyun void set_dfu_alt_info(char *interface, char *devstr)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	size_t buf_size = CONFIG_SET_DFU_ALT_BUF_LEN;
43*4882a593Smuzhiyun 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, buf_size);
44*4882a593Smuzhiyun 	char *alt_info = "Settings not found!";
45*4882a593Smuzhiyun 	char *status = "error!\n";
46*4882a593Smuzhiyun 	char *alt_setting;
47*4882a593Smuzhiyun 	char *alt_sep;
48*4882a593Smuzhiyun 	int offset = 0;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	puts("DFU alt info setting: ");
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	alt_setting = get_dfu_alt_boot(interface, devstr);
53*4882a593Smuzhiyun 	if (alt_setting) {
54*4882a593Smuzhiyun 		env_set("dfu_alt_boot", alt_setting);
55*4882a593Smuzhiyun 		offset = snprintf(buf, buf_size, "%s", alt_setting);
56*4882a593Smuzhiyun 	}
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	alt_setting = get_dfu_alt_system(interface, devstr);
59*4882a593Smuzhiyun 	if (alt_setting) {
60*4882a593Smuzhiyun 		if (offset)
61*4882a593Smuzhiyun 			alt_sep = ";";
62*4882a593Smuzhiyun 		else
63*4882a593Smuzhiyun 			alt_sep = "";
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 		offset += snprintf(buf + offset, buf_size - offset,
66*4882a593Smuzhiyun 				    "%s%s", alt_sep, alt_setting);
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	if (offset) {
70*4882a593Smuzhiyun 		alt_info = buf;
71*4882a593Smuzhiyun 		status = "done\n";
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	env_set("dfu_alt_info", alt_info);
75*4882a593Smuzhiyun 	puts(status);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun #endif
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info(void)80*4882a593Smuzhiyun void set_board_info(void)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	char info[64];
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	snprintf(info, ARRAY_SIZE(info), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4,
85*4882a593Smuzhiyun 		 s5p_cpu_rev & 0xf);
86*4882a593Smuzhiyun 	env_set("soc_rev", info);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);
89*4882a593Smuzhiyun 	env_set("soc_id", info);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #ifdef CONFIG_REVISION_TAG
92*4882a593Smuzhiyun 	snprintf(info, ARRAY_SIZE(info), "%x", get_board_rev());
93*4882a593Smuzhiyun 	env_set("board_rev", info);
94*4882a593Smuzhiyun #endif
95*4882a593Smuzhiyun #ifdef CONFIG_OF_LIBFDT
96*4882a593Smuzhiyun 	const char *bdtype = "";
97*4882a593Smuzhiyun 	const char *bdname = CONFIG_SYS_BOARD;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #ifdef CONFIG_BOARD_TYPES
100*4882a593Smuzhiyun 	bdtype = get_board_type();
101*4882a593Smuzhiyun 	if (!bdtype)
102*4882a593Smuzhiyun 		bdtype = "";
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	sprintf(info, "%s%s", bdname, bdtype);
105*4882a593Smuzhiyun 	env_set("boardname", info);
106*4882a593Smuzhiyun #endif
107*4882a593Smuzhiyun 	snprintf(info, ARRAY_SIZE(info),  "%s%x-%s%s.dtb",
108*4882a593Smuzhiyun 		 CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype);
109*4882a593Smuzhiyun 	env_set("fdtfile", info);
110*4882a593Smuzhiyun #endif
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun #endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun #ifdef CONFIG_LCD_MENU
power_key_pressed(u32 reg)115*4882a593Smuzhiyun static int power_key_pressed(u32 reg)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
118*4882a593Smuzhiyun 	struct pmic *pmic;
119*4882a593Smuzhiyun 	u32 status;
120*4882a593Smuzhiyun 	u32 mask;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	pmic = pmic_get(KEY_PWR_PMIC_NAME);
123*4882a593Smuzhiyun 	if (!pmic) {
124*4882a593Smuzhiyun 		printf("%s: Not found\n", KEY_PWR_PMIC_NAME);
125*4882a593Smuzhiyun 		return 0;
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	if (pmic_probe(pmic))
129*4882a593Smuzhiyun 		return 0;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	if (reg == KEY_PWR_STATUS_REG)
132*4882a593Smuzhiyun 		mask = KEY_PWR_STATUS_MASK;
133*4882a593Smuzhiyun 	else
134*4882a593Smuzhiyun 		mask = KEY_PWR_INTERRUPT_MASK;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (pmic_reg_read(pmic, reg, &status))
137*4882a593Smuzhiyun 		return 0;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	return !!(status & mask);
140*4882a593Smuzhiyun #else
141*4882a593Smuzhiyun 	return 0;
142*4882a593Smuzhiyun #endif
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
key_pressed(int key)145*4882a593Smuzhiyun static int key_pressed(int key)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	int value;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	switch (key) {
150*4882a593Smuzhiyun 	case KEY_POWER:
151*4882a593Smuzhiyun 		value = power_key_pressed(KEY_PWR_INTERRUPT_REG);
152*4882a593Smuzhiyun 		break;
153*4882a593Smuzhiyun 	case KEY_VOLUMEUP:
154*4882a593Smuzhiyun 		value = !gpio_get_value(KEY_VOL_UP_GPIO);
155*4882a593Smuzhiyun 		break;
156*4882a593Smuzhiyun 	case KEY_VOLUMEDOWN:
157*4882a593Smuzhiyun 		value = !gpio_get_value(KEY_VOL_DOWN_GPIO);
158*4882a593Smuzhiyun 		break;
159*4882a593Smuzhiyun 	default:
160*4882a593Smuzhiyun 		value = 0;
161*4882a593Smuzhiyun 		break;
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	return value;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun #ifdef CONFIG_LCD
check_keys(void)168*4882a593Smuzhiyun static int check_keys(void)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun 	int keys = 0;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	if (key_pressed(KEY_POWER))
173*4882a593Smuzhiyun 		keys += KEY_POWER;
174*4882a593Smuzhiyun 	if (key_pressed(KEY_VOLUMEUP))
175*4882a593Smuzhiyun 		keys += KEY_VOLUMEUP;
176*4882a593Smuzhiyun 	if (key_pressed(KEY_VOLUMEDOWN))
177*4882a593Smuzhiyun 		keys += KEY_VOLUMEDOWN;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	return keys;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /*
183*4882a593Smuzhiyun  * 0 BOOT_MODE_INFO
184*4882a593Smuzhiyun  * 1 BOOT_MODE_THOR
185*4882a593Smuzhiyun  * 2 BOOT_MODE_UMS
186*4882a593Smuzhiyun  * 3 BOOT_MODE_DFU
187*4882a593Smuzhiyun  * 4 BOOT_MODE_EXIT
188*4882a593Smuzhiyun  */
189*4882a593Smuzhiyun static char *
190*4882a593Smuzhiyun mode_name[BOOT_MODE_EXIT + 1][2] = {
191*4882a593Smuzhiyun 	{"DEVICE", ""},
192*4882a593Smuzhiyun 	{"THOR", "thor"},
193*4882a593Smuzhiyun 	{"UMS", "ums"},
194*4882a593Smuzhiyun 	{"DFU", "dfu"},
195*4882a593Smuzhiyun 	{"GPT", "gpt"},
196*4882a593Smuzhiyun 	{"ENV", "env"},
197*4882a593Smuzhiyun 	{"EXIT", ""},
198*4882a593Smuzhiyun };
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun static char *
201*4882a593Smuzhiyun mode_info[BOOT_MODE_EXIT + 1] = {
202*4882a593Smuzhiyun 	"info",
203*4882a593Smuzhiyun 	"downloader",
204*4882a593Smuzhiyun 	"mass storage",
205*4882a593Smuzhiyun 	"firmware update",
206*4882a593Smuzhiyun 	"restore",
207*4882a593Smuzhiyun 	"default",
208*4882a593Smuzhiyun 	"and run normal boot"
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun static char *
212*4882a593Smuzhiyun mode_cmd[BOOT_MODE_EXIT + 1] = {
213*4882a593Smuzhiyun 	"",
214*4882a593Smuzhiyun 	"thor 0 mmc 0",
215*4882a593Smuzhiyun 	"ums 0 mmc 0",
216*4882a593Smuzhiyun 	"dfu 0 mmc 0",
217*4882a593Smuzhiyun 	"gpt write mmc 0 $partitions",
218*4882a593Smuzhiyun 	"env default -a; saveenv",
219*4882a593Smuzhiyun 	"",
220*4882a593Smuzhiyun };
221*4882a593Smuzhiyun 
display_board_info(void)222*4882a593Smuzhiyun static void display_board_info(void)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun #ifdef CONFIG_MMC
225*4882a593Smuzhiyun 	struct mmc *mmc = find_mmc_device(0);
226*4882a593Smuzhiyun #endif
227*4882a593Smuzhiyun 	vidinfo_t *vid = &panel_info;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	lcd_position_cursor(4, 4);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	lcd_printf("%s\n\t", U_BOOT_VERSION);
232*4882a593Smuzhiyun 	lcd_puts("\n\t\tBoard Info:\n");
233*4882a593Smuzhiyun #ifdef CONFIG_SYS_BOARD
234*4882a593Smuzhiyun 	lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
235*4882a593Smuzhiyun #endif
236*4882a593Smuzhiyun #ifdef CONFIG_REVISION_TAG
237*4882a593Smuzhiyun 	lcd_printf("\tBoard rev: %u\n", get_board_rev());
238*4882a593Smuzhiyun #endif
239*4882a593Smuzhiyun 	lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
240*4882a593Smuzhiyun 	lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun #ifdef CONFIG_MMC
243*4882a593Smuzhiyun 	if (mmc) {
244*4882a593Smuzhiyun 		if (!mmc->capacity)
245*4882a593Smuzhiyun 			mmc_init(mmc);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 		lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
248*4882a593Smuzhiyun 	}
249*4882a593Smuzhiyun #endif
250*4882a593Smuzhiyun 	if (vid)
251*4882a593Smuzhiyun 		lcd_printf("\tDisplay resolution: %u x % u\n",
252*4882a593Smuzhiyun 			   vid->vl_col, vid->vl_row);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun #endif
257*4882a593Smuzhiyun 
mode_leave_menu(int mode)258*4882a593Smuzhiyun static int mode_leave_menu(int mode)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun #ifdef CONFIG_LCD
261*4882a593Smuzhiyun 	char *exit_option;
262*4882a593Smuzhiyun 	char *exit_reset = "reset";
263*4882a593Smuzhiyun 	char *exit_back = "back";
264*4882a593Smuzhiyun 	cmd_tbl_t *cmd;
265*4882a593Smuzhiyun 	int cmd_result;
266*4882a593Smuzhiyun 	int leave;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	lcd_clear();
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	switch (mode) {
271*4882a593Smuzhiyun 	case BOOT_MODE_EXIT:
272*4882a593Smuzhiyun 		return 1;
273*4882a593Smuzhiyun 	case BOOT_MODE_INFO:
274*4882a593Smuzhiyun 		display_board_info();
275*4882a593Smuzhiyun 		exit_option = exit_back;
276*4882a593Smuzhiyun 		leave = 0;
277*4882a593Smuzhiyun 		break;
278*4882a593Smuzhiyun 	default:
279*4882a593Smuzhiyun 		cmd = find_cmd(mode_name[mode][1]);
280*4882a593Smuzhiyun 		if (cmd) {
281*4882a593Smuzhiyun 			printf("Enter: %s %s\n", mode_name[mode][0],
282*4882a593Smuzhiyun 			       mode_info[mode]);
283*4882a593Smuzhiyun 			lcd_printf("\n\n\t%s %s\n", mode_name[mode][0],
284*4882a593Smuzhiyun 				   mode_info[mode]);
285*4882a593Smuzhiyun 			lcd_puts("\n\tDo not turn off device before finish!\n");
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 			cmd_result = run_command(mode_cmd[mode], 0);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 			if (cmd_result == CMD_RET_SUCCESS) {
290*4882a593Smuzhiyun 				printf("Command finished\n");
291*4882a593Smuzhiyun 				lcd_clear();
292*4882a593Smuzhiyun 				lcd_printf("\n\n\t%s finished\n",
293*4882a593Smuzhiyun 					   mode_name[mode][0]);
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 				exit_option = exit_reset;
296*4882a593Smuzhiyun 				leave = 1;
297*4882a593Smuzhiyun 			} else {
298*4882a593Smuzhiyun 				printf("Command error\n");
299*4882a593Smuzhiyun 				lcd_clear();
300*4882a593Smuzhiyun 				lcd_printf("\n\n\t%s command error\n",
301*4882a593Smuzhiyun 					   mode_name[mode][0]);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 				exit_option = exit_back;
304*4882a593Smuzhiyun 				leave = 0;
305*4882a593Smuzhiyun 			}
306*4882a593Smuzhiyun 		} else {
307*4882a593Smuzhiyun 			lcd_puts("\n\n\tThis mode is not supported.\n");
308*4882a593Smuzhiyun 			exit_option = exit_back;
309*4882a593Smuzhiyun 			leave = 0;
310*4882a593Smuzhiyun 		}
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	/* Clear PWR button Rising edge interrupt status flag */
316*4882a593Smuzhiyun 	power_key_pressed(KEY_PWR_INTERRUPT_REG);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	/* Wait for PWR key */
319*4882a593Smuzhiyun 	while (!key_pressed(KEY_POWER))
320*4882a593Smuzhiyun 		mdelay(1);
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	lcd_clear();
323*4882a593Smuzhiyun 	return leave;
324*4882a593Smuzhiyun #else
325*4882a593Smuzhiyun 	return 0;
326*4882a593Smuzhiyun #endif
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun #ifdef CONFIG_LCD
display_download_menu(int mode)330*4882a593Smuzhiyun static void display_download_menu(int mode)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	char *selection[BOOT_MODE_EXIT + 1];
333*4882a593Smuzhiyun 	int i;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	for (i = 0; i <= BOOT_MODE_EXIT; i++)
336*4882a593Smuzhiyun 		selection[i] = "[  ]";
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	selection[mode] = "[=>]";
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	lcd_clear();
341*4882a593Smuzhiyun 	lcd_printf("\n\n\t\tDownload Mode Menu\n\n");
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	for (i = 0; i <= BOOT_MODE_EXIT; i++)
344*4882a593Smuzhiyun 		lcd_printf("\t%s  %s - %s\n\n", selection[i],
345*4882a593Smuzhiyun 			   mode_name[i][0], mode_info[i]);
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun #endif
348*4882a593Smuzhiyun 
download_menu(void)349*4882a593Smuzhiyun static void download_menu(void)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun #ifdef CONFIG_LCD
352*4882a593Smuzhiyun 	int mode = 0;
353*4882a593Smuzhiyun 	int last_mode = 0;
354*4882a593Smuzhiyun 	int run;
355*4882a593Smuzhiyun 	int key = 0;
356*4882a593Smuzhiyun 	int timeout = 15; /* sec */
357*4882a593Smuzhiyun 	int i;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	display_download_menu(mode);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	lcd_puts("\n");
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	/* Start count if no key is pressed */
364*4882a593Smuzhiyun 	while (check_keys())
365*4882a593Smuzhiyun 		continue;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	while (timeout--) {
368*4882a593Smuzhiyun 		lcd_printf("\r\tNormal boot will start in: %2.d seconds.",
369*4882a593Smuzhiyun 			   timeout);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 		/* about 1000 ms in for loop */
372*4882a593Smuzhiyun 		for (i = 0; i < 10; i++) {
373*4882a593Smuzhiyun 			mdelay(100);
374*4882a593Smuzhiyun 			key = check_keys();
375*4882a593Smuzhiyun 			if (key)
376*4882a593Smuzhiyun 				break;
377*4882a593Smuzhiyun 		}
378*4882a593Smuzhiyun 		if (key)
379*4882a593Smuzhiyun 			break;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	if (!key) {
383*4882a593Smuzhiyun 		lcd_clear();
384*4882a593Smuzhiyun 		return;
385*4882a593Smuzhiyun 	}
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	while (1) {
388*4882a593Smuzhiyun 		run = 0;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		if (mode != last_mode)
391*4882a593Smuzhiyun 			display_download_menu(mode);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 		last_mode = mode;
394*4882a593Smuzhiyun 		mdelay(200);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 		key = check_keys();
397*4882a593Smuzhiyun 		switch (key) {
398*4882a593Smuzhiyun 		case KEY_POWER:
399*4882a593Smuzhiyun 			run = 1;
400*4882a593Smuzhiyun 			break;
401*4882a593Smuzhiyun 		case KEY_VOLUMEUP:
402*4882a593Smuzhiyun 			if (mode > 0)
403*4882a593Smuzhiyun 				mode--;
404*4882a593Smuzhiyun 			break;
405*4882a593Smuzhiyun 		case KEY_VOLUMEDOWN:
406*4882a593Smuzhiyun 			if (mode < BOOT_MODE_EXIT)
407*4882a593Smuzhiyun 				mode++;
408*4882a593Smuzhiyun 			break;
409*4882a593Smuzhiyun 		default:
410*4882a593Smuzhiyun 			break;
411*4882a593Smuzhiyun 		}
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		if (run) {
414*4882a593Smuzhiyun 			if (mode_leave_menu(mode))
415*4882a593Smuzhiyun 				run_command("reset", 0);
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 			display_download_menu(mode);
418*4882a593Smuzhiyun 		}
419*4882a593Smuzhiyun 	}
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	lcd_clear();
422*4882a593Smuzhiyun #endif
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun 
check_boot_mode(void)425*4882a593Smuzhiyun void check_boot_mode(void)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun 	int pwr_key;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
430*4882a593Smuzhiyun 	if (!pwr_key)
431*4882a593Smuzhiyun 		return;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	/* Clear PWR button Rising edge interrupt status flag */
434*4882a593Smuzhiyun 	power_key_pressed(KEY_PWR_INTERRUPT_REG);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	if (key_pressed(KEY_VOLUMEUP))
437*4882a593Smuzhiyun 		download_menu();
438*4882a593Smuzhiyun 	else if (key_pressed(KEY_VOLUMEDOWN))
439*4882a593Smuzhiyun 		mode_leave_menu(BOOT_MODE_THOR);
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun 
keys_init(void)442*4882a593Smuzhiyun void keys_init(void)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun 	/* Set direction to input */
445*4882a593Smuzhiyun 	gpio_request(KEY_VOL_UP_GPIO, "volume-up");
446*4882a593Smuzhiyun 	gpio_request(KEY_VOL_DOWN_GPIO, "volume-down");
447*4882a593Smuzhiyun 	gpio_direction_input(KEY_VOL_UP_GPIO);
448*4882a593Smuzhiyun 	gpio_direction_input(KEY_VOL_DOWN_GPIO);
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun #endif /* CONFIG_LCD_MENU */
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun #ifdef CONFIG_CMD_BMP
draw_logo(void)453*4882a593Smuzhiyun void draw_logo(void)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	int x, y;
456*4882a593Smuzhiyun 	ulong addr;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	addr = panel_info.logo_addr;
459*4882a593Smuzhiyun 	if (!addr) {
460*4882a593Smuzhiyun 		pr_err("There is no logo data.");
461*4882a593Smuzhiyun 		return;
462*4882a593Smuzhiyun 	}
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	if (panel_info.vl_width >= panel_info.logo_width) {
465*4882a593Smuzhiyun 		x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
466*4882a593Smuzhiyun 		x += panel_info.logo_x_offset; /* For X center align */
467*4882a593Smuzhiyun 	} else {
468*4882a593Smuzhiyun 		x = 0;
469*4882a593Smuzhiyun 		printf("Warning: image width is bigger than display width\n");
470*4882a593Smuzhiyun 	}
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	if (panel_info.vl_height >= panel_info.logo_height) {
473*4882a593Smuzhiyun 		y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
474*4882a593Smuzhiyun 		y += panel_info.logo_y_offset; /* For Y center align */
475*4882a593Smuzhiyun 	} else {
476*4882a593Smuzhiyun 		y = 0;
477*4882a593Smuzhiyun 		printf("Warning: image height is bigger than display height\n");
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	bmp_display(addr, x, y);
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun #endif /* CONFIG_CMD_BMP */
483