| /* | 
 |  * amirix.c: ppcboot platform support for AMIRIX board | 
 |  * | 
 |  * Copyright 2002 Mind NV | 
 |  * Copyright 2003 AMIRIX Systems Inc. | 
 |  * | 
 |  * http://www.mind.be/ | 
 |  * http://www.amirix.com/ | 
 |  * | 
 |  * Author : Peter De Schrijver (p2@mind.be) | 
 |  *          Frank Smith (smith@amirix.com) | 
 |  * | 
 |  * Derived from : Other platform support files in this tree, ml2 | 
 |  * | 
 |  * This software may be used and distributed according to the terms of | 
 |  * the GNU General Public License (GPL) version 2, incorporated herein by | 
 |  * reference. Drivers based on or derived from this code fall under the GPL | 
 |  * and must retain the authorship, copyright and this license notice. This | 
 |  * file is not a complete program and may only be used when the entire | 
 |  * program is licensed under the GPL. | 
 |  * | 
 |  */ | 
 |  | 
 | #include <common.h> | 
 | #include <command.h> | 
 | #include <asm/processor.h> | 
 |  | 
 | #include "powerspan.h" | 
 | #include "ap1000.h" | 
 |  | 
 | int board_pre_init (void) | 
 | { | 
 | 	return 0; | 
 | } | 
 |  | 
 | /** serial number and platform display at startup */ | 
 | int checkboard (void) | 
 | { | 
 | 	char *s = getenv ("serial#"); | 
 | 	char *e; | 
 |  | 
 | 	/* After a loadace command, the SystemAce control register is left in a wonky state. */ | 
 | 	/* this code did not work in board_pre_init */ | 
 | 	unsigned char *p = (unsigned char *) AP1000_SYSACE_REGBASE; | 
 |  | 
 | 	p[SYSACE_CTRLREG0] = 0x0; | 
 |  | 
 | 	/* add platform and device to banner */ | 
 | 	switch (get_device ()) { | 
 | 	case AP1xx_AP107_TARGET: | 
 | 		puts (AP1xx_AP107_TARGET_STR); | 
 | 		break; | 
 | 	case AP1xx_AP120_TARGET: | 
 | 		puts (AP1xx_AP120_TARGET_STR); | 
 | 		break; | 
 | 	case AP1xx_AP130_TARGET: | 
 | 		puts (AP1xx_AP130_TARGET_STR); | 
 | 		break; | 
 | 	case AP1xx_AP1070_TARGET: | 
 | 		puts (AP1xx_AP1070_TARGET_STR); | 
 | 		break; | 
 | 	case AP1xx_AP1100_TARGET: | 
 | 		puts (AP1xx_AP1100_TARGET_STR); | 
 | 		break; | 
 | 	default: | 
 | 		puts (AP1xx_UNKNOWN_STR); | 
 | 		break; | 
 | 	} | 
 | 	puts (AP1xx_TARGET_STR); | 
 | 	puts (" with "); | 
 |  | 
 | 	switch (get_platform ()) { | 
 | 	case AP100_BASELINE_PLATFORM: | 
 | 	case AP1000_BASELINE_PLATFORM: | 
 | 		puts (AP1xx_BASELINE_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_QUADGE_PLATFORM: | 
 | 		puts (AP1xx_QUADGE_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_MGT_REF_PLATFORM: | 
 | 		puts (AP1xx_MGT_REF_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_STANDARD_PLATFORM: | 
 | 		puts (AP1xx_STANDARD_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_DUAL_PLATFORM: | 
 | 		puts (AP1xx_DUAL_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_BASE_SRAM_PLATFORM: | 
 | 		puts (AP1xx_BASE_SRAM_PLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_PCI_PCB_TESTPLATFORM: | 
 | 	case AP1000_PCI_PCB_TESTPLATFORM: | 
 | 		puts (AP1xx_PCI_PCB_TESTPLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM: | 
 | 		puts (AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR); | 
 | 		break; | 
 | 	case AP1xx_SFP_MEZZ_TESTPLATFORM: | 
 | 		puts (AP1xx_SFP_MEZZ_TESTPLATFORM_STR); | 
 | 		break; | 
 | 	default: | 
 | 		puts (AP1xx_UNKNOWN_STR); | 
 | 		break; | 
 | 	} | 
 |  | 
 | 	if ((get_platform () & AP1xx_TESTPLATFORM_MASK) != 0) { | 
 | 		puts (AP1xx_TESTPLATFORM_STR); | 
 | 	} else { | 
 | 		puts (AP1xx_PLATFORM_STR); | 
 | 	} | 
 |  | 
 | 	putc ('\n'); | 
 |  | 
 | 	puts ("Serial#: "); | 
 |  | 
 | 	if (!s) { | 
 | 		printf ("### No HW ID - assuming AMIRIX"); | 
 | 	} else { | 
 | 		for (e = s; *e; ++e) { | 
 | 			if (*e == ' ') | 
 | 				break; | 
 | 		} | 
 |  | 
 | 		for (; s < e; ++s) { | 
 | 			putc (*s); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	putc ('\n'); | 
 |  | 
 | 	return (0); | 
 | } | 
 |  | 
 |  | 
 | long int initdram (int board_type) | 
 | { | 
 | 	char *s = getenv ("dramsize"); | 
 |  | 
 | 	if (s != NULL) { | 
 | 		if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) { | 
 | 			s += 2; | 
 | 		} | 
 | 		return (long int)simple_strtoul (s, NULL, 16); | 
 | 	} else { | 
 | 		/* give all 64 MB */ | 
 | 		return 64 * 1024 * 1024; | 
 | 	} | 
 | } | 
 |  | 
 | unsigned int get_platform (void) | 
 | { | 
 | 	unsigned int *revision_reg_ptr = (unsigned int *) AP1xx_FPGA_REV_ADDR; | 
 |  | 
 | 	return (*revision_reg_ptr & AP1xx_PLATFORM_MASK); | 
 | } | 
 |  | 
 | unsigned int get_device (void) | 
 | { | 
 | 	unsigned int *revision_reg_ptr = (unsigned int *) AP1xx_FPGA_REV_ADDR; | 
 |  | 
 | 	return (*revision_reg_ptr & AP1xx_TARGET_MASK); | 
 | } | 
 |  | 
 | #if 0				/* loadace is not working; it appears to be a hardware issue with the system ace. */ | 
 | /* | 
 |    This function loads FPGA configurations from the SystemACE CompactFlash | 
 | */ | 
 | int do_loadace (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 
 | { | 
 | 	unsigned char *p = (unsigned char *) AP1000_SYSACE_REGBASE; | 
 | 	int cfg; | 
 |  | 
 | 	if ((p[SYSACE_STATREG0] & 0x10) == 0) { | 
 | 		p[SYSACE_CTRLREG0] = 0x80; | 
 | 		printf ("\nNo CompactFlash Detected\n\n"); | 
 | 		p[SYSACE_CTRLREG0] = 0x00; | 
 | 		return 1; | 
 | 	} | 
 |  | 
 | 	/* reset configuration controller: |  0x80 */ | 
 | 	/* select cpflash                  & ~0x40 */ | 
 | 	/* cfg start                       |  0x20 */ | 
 | 	/* wait for cfgstart               & ~0x10 */ | 
 | 	/* force cfgmode:                  |  0x08 */ | 
 | 	/* do no force cfgaddr:            & ~0x04 */ | 
 | 	/* clear mpulock:                  & ~0x02 */ | 
 | 	/* do not force lock request       & ~0x01 */ | 
 |  | 
 | 	p[SYSACE_CTRLREG0] = 0x80 | 0x20 | 0x08; | 
 | 	p[SYSACE_CTRLREG1] = 0x00; | 
 |  | 
 | 	/* force config address if arg2 exists */ | 
 | 	if (argc == 2) { | 
 | 		cfg = simple_strtoul (argv[1], NULL, 10); | 
 |  | 
 | 		if (cfg > 7) { | 
 | 			printf ("\nInvalid Configuration\n\n"); | 
 | 			p[SYSACE_CTRLREG0] = 0x00; | 
 | 			return 1; | 
 | 		} | 
 | 		/* Set config address */ | 
 | 		p[SYSACE_CTRLREG1] = (cfg << 5); | 
 | 		/* force cfgaddr */ | 
 | 		p[SYSACE_CTRLREG0] |= 0x04; | 
 |  | 
 | 	} else { | 
 | 		cfg = (p[SYSACE_STATREG1] & 0xE0) >> 5; | 
 | 	} | 
 |  | 
 | 	/* release configuration controller */ | 
 | 	printf ("\nLoading V2PRO with config %d...\n", cfg); | 
 | 	p[SYSACE_CTRLREG0] &= ~0x80; | 
 |  | 
 |  | 
 | 	while ((p[SYSACE_STATREG1] & 0x01) == 0) { | 
 |  | 
 | 		if (p[SYSACE_ERRREG0] & 0x80) { | 
 | 			/* attempting to load an invalid configuration makes the cpflash */ | 
 | 			/* appear to be removed. Reset here to avoid that problem */ | 
 | 			p[SYSACE_CTRLREG0] = 0x80; | 
 | 			printf ("\nConfiguration %d Read Error\n\n", cfg); | 
 | 			p[SYSACE_CTRLREG0] = 0x00; | 
 | 			return 1; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	p[SYSACE_CTRLREG0] |= 0x20; | 
 |  | 
 | 	return 0; | 
 | } | 
 | #endif | 
 |  | 
 | /** Console command to display and set the software reconfigure byte | 
 |   * <pre> | 
 |   * swconfig        - display the current value of the software reconfigure byte | 
 |   * swconfig [#]    - change the software reconfigure byte to # | 
 |   * </pre> | 
 |   * @param  *cmdtp  [IN] as passed by run_command (ignored) | 
 |   * @param  flag    [IN] as passed by run_command (ignored) | 
 |   * @param  argc    [IN] as passed by run_command if 1, display, if 2 change | 
 |   * @param  *argv[] [IN] contains the parameters to use | 
 |   * @return | 
 |   * <pre> | 
 |   *      0 if passed | 
 |   *     -1 if failed | 
 |   * </pre> | 
 |   */ | 
 | int do_swconfigbyte (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 
 | { | 
 | 	unsigned char *sector_buffer = NULL; | 
 | 	unsigned char input_char; | 
 | 	int write_result; | 
 | 	unsigned int input_uint; | 
 |  | 
 | 	/* display value if no argument */ | 
 | 	if (argc < 2) { | 
 | 		printf ("Software configuration byte is currently: 0x%02x\n", | 
 | 			*((unsigned char *) (SW_BYTE_SECTOR_ADDR + | 
 | 					     SW_BYTE_SECTOR_OFFSET))); | 
 | 		return 0; | 
 | 	} else if (argc > 3) { | 
 | 		printf ("Too many arguments\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	/* if 3 arguments, 3rd argument is the address to use */ | 
 | 	if (argc == 3) { | 
 | 		input_uint = simple_strtoul (argv[1], NULL, 16); | 
 | 		sector_buffer = (unsigned char *) input_uint; | 
 | 	} else { | 
 | 		sector_buffer = (unsigned char *) DEFAULT_TEMP_ADDR; | 
 | 	} | 
 |  | 
 | 	input_char = simple_strtoul (argv[1], NULL, 0); | 
 | 	if ((input_char & ~SW_BYTE_MASK) != 0) { | 
 | 		printf ("Input of 0x%02x will be masked to 0x%02x\n", | 
 | 			input_char, (input_char & SW_BYTE_MASK)); | 
 | 		input_char = input_char & SW_BYTE_MASK; | 
 | 	} | 
 |  | 
 | 	memcpy (sector_buffer, (void *) SW_BYTE_SECTOR_ADDR, | 
 | 		SW_BYTE_SECTOR_SIZE); | 
 | 	sector_buffer[SW_BYTE_SECTOR_OFFSET] = input_char; | 
 |  | 
 |  | 
 | 	printf ("Erasing Flash..."); | 
 | 	if (flash_sect_erase | 
 | 	    (SW_BYTE_SECTOR_ADDR, | 
 | 	     (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))) { | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	printf ("Writing to Flash... "); | 
 | 	write_result = | 
 | 		flash_write ((char *)sector_buffer, SW_BYTE_SECTOR_ADDR, | 
 | 			     SW_BYTE_SECTOR_SIZE); | 
 | 	if (write_result != 0) { | 
 | 		flash_perror (write_result); | 
 | 		return -1; | 
 | 	} else { | 
 | 		printf ("done\n"); | 
 | 		printf ("Software configuration byte is now: 0x%02x\n", | 
 | 			*((unsigned char *) (SW_BYTE_SECTOR_ADDR + | 
 | 					     SW_BYTE_SECTOR_OFFSET))); | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | #define ONE_SECOND 1000000 | 
 |  | 
 | int do_pause (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 
 | { | 
 | 	int pause_time; | 
 | 	unsigned int delay_time; | 
 | 	int break_loop = 0; | 
 |  | 
 | 	/* display value if no argument */ | 
 | 	if (argc < 2) { | 
 | 		pause_time = 1; | 
 | 	} | 
 |  | 
 | 	else if (argc > 2) { | 
 | 		printf ("Too many arguments\n"); | 
 | 		return -1; | 
 | 	} else { | 
 | 		pause_time = simple_strtoul (argv[1], NULL, 0); | 
 | 	} | 
 |  | 
 | 	printf ("Pausing with a poll time of %d, press any key to reactivate\n", pause_time); | 
 | 	delay_time = pause_time * ONE_SECOND; | 
 | 	while (break_loop == 0) { | 
 | 		udelay (delay_time); | 
 | 		if (serial_tstc () != 0) { | 
 | 			break_loop = 1; | 
 | 			/* eat user key presses */ | 
 | 			while (serial_tstc () != 0) { | 
 | 				serial_getc (); | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | int do_swreconfig (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 
 | { | 
 | 	printf ("Triggering software reconfigure (software config byte is 0x%02x)...\n", | 
 | 		*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))); | 
 | 	udelay (1000); | 
 | 	*((unsigned char *) AP1000_CPLD_BASE) = 1; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | #define GET_DECIMAL(low_byte) ((low_byte >> 5) * 125) | 
 | #define TEMP_BUSY_BIT   0x80 | 
 | #define TEMP_LHIGH_BIT  0x40 | 
 | #define TEMP_LLOW_BIT   0x20 | 
 | #define TEMP_EHIGH_BIT  0x10 | 
 | #define TEMP_ELOW_BIT   0x08 | 
 | #define TEMP_OPEN_BIT   0x04 | 
 | #define TEMP_ETHERM_BIT 0x02 | 
 | #define TEMP_LTHERM_BIT 0x01 | 
 |  | 
 | int do_temp_sensor (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | 
 | { | 
 | 	char cmd; | 
 | 	int ret_val = 0; | 
 | 	unsigned char temp_byte; | 
 | 	int temp; | 
 | 	int temp_low; | 
 | 	int low; | 
 | 	int low_low; | 
 | 	int high; | 
 | 	int high_low; | 
 | 	int therm; | 
 | 	unsigned char user_data[4] = { 0 }; | 
 | 	int user_data_count = 0; | 
 | 	int ii; | 
 |  | 
 | 	if (argc > 1) { | 
 | 		cmd = argv[1][0]; | 
 | 	} else { | 
 | 		cmd = 's';	/* default to status */ | 
 | 	} | 
 |  | 
 | 	user_data_count = argc - 2; | 
 | 	for (ii = 0; ii < user_data_count; ii++) { | 
 | 		user_data[ii] = simple_strtoul (argv[2 + ii], NULL, 0); | 
 | 	} | 
 | 	switch (cmd) { | 
 | 	case 's': | 
 | 		if (I2CAccess | 
 | 		    (0x2, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Status    : 0x%02x  ", temp_byte); | 
 | 		if (temp_byte & TEMP_BUSY_BIT) | 
 | 			printf ("BUSY "); | 
 |  | 
 | 		if (temp_byte & TEMP_LHIGH_BIT) | 
 | 			printf ("LHIGH "); | 
 |  | 
 | 		if (temp_byte & TEMP_LLOW_BIT) | 
 | 			printf ("LLOW "); | 
 |  | 
 | 		if (temp_byte & TEMP_EHIGH_BIT) | 
 | 			printf ("EHIGH "); | 
 |  | 
 | 		if (temp_byte & TEMP_ELOW_BIT) | 
 | 			printf ("ELOW "); | 
 |  | 
 | 		if (temp_byte & TEMP_OPEN_BIT) | 
 | 			printf ("OPEN "); | 
 |  | 
 | 		if (temp_byte & TEMP_ETHERM_BIT) | 
 | 			printf ("ETHERM "); | 
 |  | 
 | 		if (temp_byte & TEMP_LTHERM_BIT) | 
 | 			printf ("LTHERM"); | 
 |  | 
 | 		printf ("\n"); | 
 |  | 
 | 		if (I2CAccess | 
 | 		    (0x3, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Config    : 0x%02x  ", temp_byte); | 
 |  | 
 | 		if (I2CAccess | 
 | 		    (0x4, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			printf ("\n"); | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Conversion: 0x%02x\n", temp_byte); | 
 | 		if (I2CAccess | 
 | 		    (0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Cons Alert: 0x%02x  ", temp_byte); | 
 |  | 
 | 		if (I2CAccess | 
 | 		    (0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			printf ("\n"); | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Therm Hyst: %d\n", temp_byte); | 
 |  | 
 | 		if (I2CAccess | 
 | 		    (0x0, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		temp = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x6, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		low = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x5, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		high = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		therm = temp_byte; | 
 | 		printf ("Local Temp: %2d     Low: %2d     High: %2d     THERM: %2d\n", temp, low, high, therm); | 
 |  | 
 | 		if (I2CAccess | 
 | 		    (0x1, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		temp = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x10, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		temp_low = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x8, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		low = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x14, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		low_low = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x7, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		high = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x13, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		high_low = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		therm = temp_byte; | 
 | 		if (I2CAccess | 
 | 		    (0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &temp_byte, I2C_READ) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 | 		printf ("Ext Temp  : %2d.%03d Low: %2d.%03d High: %2d.%03d THERM: %2d Offset: %2d\n", temp, GET_DECIMAL (temp_low), low, GET_DECIMAL (low_low), high, GET_DECIMAL (high_low), therm, temp_byte); | 
 | 		break; | 
 | 	case 'l':		/* alter local limits : low, high, therm */ | 
 | 		if (argc < 3) { | 
 | 			goto usage; | 
 | 		} | 
 |  | 
 | 		/* low */ | 
 | 		if (I2CAccess | 
 | 		    (0xC, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &user_data[0], I2C_WRITE) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 1) { | 
 | 			/* high */ | 
 | 			if (I2CAccess | 
 | 			    (0xB, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 			     &user_data[1], I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 2) { | 
 | 			/* therm */ | 
 | 			if (I2CAccess | 
 | 			    (0x20, I2C_SENSOR_DEV, | 
 | 			     I2C_SENSOR_CHIP_SEL, &user_data[2], | 
 | 			     I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 | 		break; | 
 | 	case 'e':		/* alter external limits: low, high, therm, offset */ | 
 | 		if (argc < 3) { | 
 | 			goto usage; | 
 | 		} | 
 |  | 
 | 		/* low */ | 
 | 		if (I2CAccess | 
 | 		    (0xE, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &user_data[0], I2C_WRITE) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 1) { | 
 | 			/* high */ | 
 | 			if (I2CAccess | 
 | 			    (0xD, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 			     &user_data[1], I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 2) { | 
 | 			/* therm */ | 
 | 			if (I2CAccess | 
 | 			    (0x19, I2C_SENSOR_DEV, | 
 | 			     I2C_SENSOR_CHIP_SEL, &user_data[2], | 
 | 			     I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 3) { | 
 | 			/* offset */ | 
 | 			if (I2CAccess | 
 | 			    (0x11, I2C_SENSOR_DEV, | 
 | 			     I2C_SENSOR_CHIP_SEL, &user_data[3], | 
 | 			     I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 | 		break; | 
 | 	case 'c':		/* alter config settings: config, conv, cons alert, therm hyst */ | 
 | 		if (argc < 3) { | 
 | 			goto usage; | 
 | 		} | 
 |  | 
 | 		/* config */ | 
 | 		if (I2CAccess | 
 | 		    (0x9, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 		     &user_data[0], I2C_WRITE) != 0) { | 
 | 			goto fail; | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 1) { | 
 | 			/* conversion */ | 
 | 			if (I2CAccess | 
 | 			    (0xA, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, | 
 | 			     &user_data[1], I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 2) { | 
 | 			/* cons alert */ | 
 | 			if (I2CAccess | 
 | 			    (0x22, I2C_SENSOR_DEV, | 
 | 			     I2C_SENSOR_CHIP_SEL, &user_data[2], | 
 | 			     I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (user_data_count > 3) { | 
 | 			/* therm hyst */ | 
 | 			if (I2CAccess | 
 | 			    (0x21, I2C_SENSOR_DEV, | 
 | 			     I2C_SENSOR_CHIP_SEL, &user_data[3], | 
 | 			     I2C_WRITE) != 0) { | 
 | 				goto fail; | 
 | 			} | 
 | 		} | 
 | 		break; | 
 | 	default: | 
 | 		goto usage; | 
 | 	} | 
 |  | 
 | 	goto done; | 
 | fail: | 
 | 	printf ("Access to sensor failed\n"); | 
 | 	ret_val = -1; | 
 | 	goto done; | 
 | usage: | 
 | 	printf ("Usage:\n%s\n", cmdtp->help); | 
 |  | 
 | done: | 
 | 	return ret_val; | 
 | } | 
 |  | 
 | U_BOOT_CMD (temp, 6, 0, do_temp_sensor, | 
 | 	    "temp    - interact with the temperature sensor\n", | 
 | 	    "temp [s]\n" | 
 | 	    "        - Show status.\n" | 
 | 	    "temp l LOW [HIGH] [THERM]\n" | 
 | 	    "        - Set local limits.\n" | 
 | 	    "temp e LOW [HIGH] [THERM] [OFFSET]\n" | 
 | 	    "        - Set external limits.\n" | 
 | 	    "temp c CONFIG [CONVERSION] [CONS. ALERT] [THERM HYST]\n" | 
 | 	    "        - Set config options.\n" | 
 | 	    "\n" | 
 | 	    "All values can be decimal or hex (hex preceded with 0x).\n" | 
 | 	    "Only whole numbers are supported for external limits.\n"); | 
 |  | 
 | #if 0 | 
 | U_BOOT_CMD (loadace, 2, 0, do_loadace, | 
 | 	    "loadace - load fpga configuration from System ACE compact flash\n", | 
 | 	    "N\n" | 
 | 	    "    - Load configuration N (0-7) from System ACE compact flash\n" | 
 | 	    "loadace\n" "    - loads default configuration\n"); | 
 | #endif | 
 |  | 
 | U_BOOT_CMD (swconfig, 2, 0, do_swconfigbyte, | 
 | 	    "swconfig- display or modify the software configuration byte\n", | 
 | 	    "N [ADDRESS]\n" | 
 | 	    "    - set software configuration byte to N, optionally use ADDRESS as\n" | 
 | 	    "      location of buffer for flash copy\n" | 
 | 	    "swconfig\n" "    - display software configuration byte\n"); | 
 |  | 
 | U_BOOT_CMD (pause, 2, 0, do_pause, | 
 | 	    "pause   - sleep processor until any key is pressed with poll time of N seconds\n", | 
 | 	    "N\n" | 
 | 	    "    - sleep processor until any key is pressed with poll time of N seconds\n" | 
 | 	    "pause\n" | 
 | 	    "    - sleep processor until any key is pressed with poll time of 1 second\n"); | 
 |  | 
 | U_BOOT_CMD (swrecon, 1, 0, do_swreconfig, | 
 | 	    "swrecon - trigger a board reconfigure to the software selected configuration\n", | 
 | 	    "\n" | 
 | 	    "    - trigger a board reconfigure to the software selected configuration\n"); |