mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 18:35:42 +01:00 
			
		
		
		
	This fixes: cmd_bc3450.c:55:0: warning: "CONFIG_SYS_CPU" redefined [enabled by default] Signed-off-by: Wolfgang Denk <wd@denx.de> Cc: Detlev Zundel <dzu@denx.de>
		
			
				
	
	
		
			822 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			822 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * (C) Copyright 2005
 | |
|  * Stefan Strobl, GERSYS GmbH, stefan.strobl@gersys.de
 | |
|  *
 | |
|  * (C) Copyright 2005
 | |
|  * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de.
 | |
|  *
 | |
|  * See file CREDITS for list of people who contributed to this
 | |
|  * project.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU General Public License as
 | |
|  * published by the Free Software Foundation; either version 2 of
 | |
|  * the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program; if not, write to the Free Software
 | |
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 | |
|  * MA 02111-1307 USA
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <command.h>
 | |
| 
 | |
| /*
 | |
|  * BC3450 specific commands
 | |
|  */
 | |
| #if defined(CONFIG_CMD_BSP)
 | |
| 
 | |
| /*
 | |
|  * Definitions for DS1620 chip
 | |
|  */
 | |
| #define THERM_START_CONVERT	0xee
 | |
| #define THERM_RESET		0xaf
 | |
| #define THERM_READ_CONFIG	0xac
 | |
| #define THERM_READ_TEMP		0xaa
 | |
| #define THERM_READ_TL		0xa2
 | |
| #define THERM_READ_TH		0xa1
 | |
| #define THERM_WRITE_CONFIG	0x0c
 | |
| #define THERM_WRITE_TL		0x02
 | |
| #define THERM_WRITE_TH		0x01
 | |
| 
 | |
| #define CONFIG_SYS_1SHOT		1
 | |
| #define CONFIG_SYS_STANDALONE		0
 | |
| 
 | |
| struct therm {
 | |
| 	int hi;
 | |
| 	int lo;
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * SM501 Register
 | |
|  */
 | |
| #define SM501_GPIO_CTRL_LOW		0x00000008UL	/* gpio pins 0..31  */
 | |
| #define SM501_GPIO_CTRL_HIGH		0x0000000CUL	/* gpio pins 32..63 */
 | |
| #define SM501_POWER_MODE0_GATE		0x00000040UL
 | |
| #define SM501_POWER_MODE1_GATE		0x00000048UL
 | |
| #define POWER_MODE_GATE_GPIO_PWM_I2C	0x00000040UL
 | |
| #define SM501_GPIO_DATA_LOW		0x00010000UL
 | |
| #define SM501_GPIO_DATA_HIGH		0x00010004UL
 | |
| #define SM501_GPIO_DATA_DIR_LOW		0x00010008UL
 | |
| #define SM501_GPIO_DATA_DIR_HIGH	0x0001000CUL
 | |
| #define SM501_PANEL_DISPLAY_CONTROL	0x00080000UL
 | |
| #define SM501_CRT_DISPLAY_CONTROL	0x00080200UL
 | |
| 
 | |
| /* SM501 CRT Display Control Bits */
 | |
| #define SM501_CDC_SEL			(1 << 9)
 | |
| #define SM501_CDC_TE			(1 << 8)
 | |
| #define SM501_CDC_E			(1 << 2)
 | |
| 
 | |
| /* SM501 Panel Display Control Bits */
 | |
| #define SM501_PDC_FPEN			(1 << 27)
 | |
| #define SM501_PDC_BIAS			(1 << 26)
 | |
| #define SM501_PDC_DATA			(1 << 25)
 | |
| #define SM501_PDC_VDDEN			(1 << 24)
 | |
| 
 | |
| /* SM501 GPIO Data LOW Bits */
 | |
| #define SM501_GPIO24			0x01000000
 | |
| #define SM501_GPIO25			0x02000000
 | |
| #define SM501_GPIO26			0x04000000
 | |
| #define SM501_GPIO27			0x08000000
 | |
| #define SM501_GPIO28			0x10000000
 | |
| #define SM501_GPIO29			0x20000000
 | |
| #define SM501_GPIO30			0x40000000
 | |
| #define SM501_GPIO31			0x80000000
 | |
| 
 | |
| /* SM501 GPIO Data HIGH Bits */
 | |
| #define SM501_GPIO46			0x00004000
 | |
| #define SM501_GPIO47			0x00008000
 | |
| #define SM501_GPIO48			0x00010000
 | |
| #define SM501_GPIO49			0x00020000
 | |
| #define SM501_GPIO50			0x00040000
 | |
| #define SM501_GPIO51			0x00080000
 | |
| 
 | |
| /* BC3450 GPIOs @ SM501 Data LOW */
 | |
| #define DIP				(SM501_GPIO24 | SM501_GPIO25 | SM501_GPIO26 | SM501_GPIO27)
 | |
| #define DS1620_DQ			SM501_GPIO29	/* I/O             */
 | |
| #define DS1620_CLK			SM501_GPIO30	/* High active O/P */
 | |
| #define DS1620_RES			SM501_GPIO31	/* Low active O/P  */
 | |
| /* BC3450 GPIOs @ SM501 Data HIGH */
 | |
| #define BUZZER				SM501_GPIO47	/* Low active O/P  */
 | |
| #define DS1620_TLOW			SM501_GPIO48	/* High active I/P */
 | |
| #define PWR_OFF				SM501_GPIO49	/* Low active O/P  */
 | |
| #define FP_DATA_TRI			SM501_GPIO50	/* High active O/P */
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Initialise GPIO on SM501
 | |
|  *
 | |
|  * This function may be called from several other functions.
 | |
|  * Yet, the initialisation sequence is executed only the first
 | |
|  * time the function is called.
 | |
|  */
 | |
| int sm501_gpio_init (void)
 | |
| {
 | |
| 	static int init_done = 0;
 | |
| 
 | |
| 	if (init_done) {
 | |
| 		debug("sm501_gpio_init: nothing to be done.\n");
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	/* enable SM501 GPIO control (in both power modes) */
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_POWER_MODE0_GATE) |=
 | |
| 		POWER_MODE_GATE_GPIO_PWM_I2C;
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_POWER_MODE1_GATE) |=
 | |
| 		POWER_MODE_GATE_GPIO_PWM_I2C;
 | |
| 
 | |
| 	/* set up default O/Ps */
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &=
 | |
| 		~(DS1620_RES | DS1620_CLK);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_DQ;
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &=
 | |
| 		~(FP_DATA_TRI);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) |=
 | |
| 		(BUZZER | PWR_OFF);
 | |
| 
 | |
| 	/* configure directions for SM501 GPIO pins */
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_CTRL_LOW) &= ~(0xFF << 24);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_CTRL_HIGH) &=
 | |
| 		~(0x3F << 14);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) &=
 | |
| 		~(DIP | DS1620_DQ);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) |=
 | |
| 		(DS1620_RES | DS1620_CLK);
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_HIGH) &=
 | |
| 		~DS1620_TLOW;
 | |
| 	*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_HIGH) |=
 | |
| 		(PWR_OFF | BUZZER | FP_DATA_TRI);
 | |
| 
 | |
| 	init_done = 1;
 | |
| 	debug("sm501_gpio_init: done.\n");
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * dip - read Config Inputs
 | |
|  *
 | |
|  * read and prints the dip switch
 | |
|  * and/or external config inputs (4bits) 0...0x0F
 | |
|  */
 | |
| int cmd_dip (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 | |
| {
 | |
| 	vu_long rc = 0;
 | |
| 
 | |
| 	sm501_gpio_init ();
 | |
| 
 | |
| 	/* read dip switch */
 | |
| 	rc = *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW);
 | |
| 	rc = ~rc;
 | |
| 	rc &= DIP;
 | |
| 	rc = (int) (rc >> 24);
 | |
| 
 | |
| 	/* plausibility check */
 | |
| 	if (rc > 0x0F)
 | |
| 		return -1;
 | |
| 
 | |
| 	printf ("0x%lx\n", rc);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| U_BOOT_CMD (dip, 1, 1, cmd_dip,
 | |
| 	    "read dip switch and config inputs",
 | |
| 	    "\n"
 | |
| 	    "     - prints the state of the dip switch and/or\n"
 | |
| 	    "       external configuration inputs as hex value.\n"
 | |
| 	    "     - \"Config 1\" is the LSB");
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * buz - turns Buzzer on/off
 | |
|  */
 | |
| #ifdef CONFIG_BC3450_BUZZER
 | |
| static int cmd_buz (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 | |
| {
 | |
| 	if (argc != 2) {
 | |
| 		printf ("Usage:\nspecify one argument: \"on\" or \"off\"\n");
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	sm501_gpio_init ();
 | |
| 
 | |
| 	if (strncmp (argv[1], "on", 2) == 0) {
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &=
 | |
| 			~(BUZZER);
 | |
| 		return 0;
 | |
| 	} else if (strncmp (argv[1], "off", 3) == 0) {
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) |=
 | |
| 			BUZZER;
 | |
| 		return 0;
 | |
| 	}
 | |
| 	printf ("Usage:\nspecify one argument: \"on\" or \"off\"\n");
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| U_BOOT_CMD (buz, 2, 1, cmd_buz,
 | |
| 	    "turns buzzer on/off",
 | |
| 	    "\n" "buz <on/off>\n" "     - turns the buzzer on or off");
 | |
| #endif /* CONFIG_BC3450_BUZZER */
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * fp - front panel commands
 | |
|  */
 | |
| static int cmd_fp (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 | |
| {
 | |
| 	sm501_gpio_init ();
 | |
| 
 | |
| 	if (strncmp (argv[1], "on", 2) == 0) {
 | |
| 		/* turn on VDD first */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_VDDEN;
 | |
| 		udelay (1000);
 | |
| 		/* then put data on */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_DATA;
 | |
| 		/* wait some time and enable backlight */
 | |
| 		udelay (1000);
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_BIAS;
 | |
| 		udelay (1000);
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_FPEN;
 | |
| 		return 0;
 | |
| 	} else if (strncmp (argv[1], "off", 3) == 0) {
 | |
| 		/* turn off the backlight first */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_FPEN;
 | |
| 		udelay (1000);
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_BIAS;
 | |
| 		udelay (200000);
 | |
| 		/* wait some time, then remove data */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_DATA;
 | |
| 		udelay (1000);
 | |
| 		/* and remove VDD last */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE +
 | |
| 			      SM501_PANEL_DISPLAY_CONTROL) &=
 | |
| 			~SM501_PDC_VDDEN;
 | |
| 		return 0;
 | |
| 	} else if (strncmp (argv[1], "bl", 2) == 0) {
 | |
| 		/* turn on/off backlight only */
 | |
| 		if (strncmp (argv[2], "on", 2) == 0) {
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_PANEL_DISPLAY_CONTROL) |=
 | |
| 				SM501_PDC_BIAS;
 | |
| 			udelay (1000);
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_PANEL_DISPLAY_CONTROL) |=
 | |
| 				SM501_PDC_FPEN;
 | |
| 			return 0;
 | |
| 		} else if (strncmp (argv[2], "off", 3) == 0) {
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_PANEL_DISPLAY_CONTROL) &=
 | |
| 				~SM501_PDC_FPEN;
 | |
| 			udelay (1000);
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_PANEL_DISPLAY_CONTROL) &=
 | |
| 				~SM501_PDC_BIAS;
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| #ifdef CONFIG_BC3450_CRT
 | |
| 	else if (strncmp (argv[1], "crt", 3) == 0) {
 | |
| 		/* enables/disables the crt output (debug only) */
 | |
| 		if (strncmp (argv[2], "on", 2) == 0) {
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_CRT_DISPLAY_CONTROL) |=
 | |
| 				(SM501_CDC_TE | SM501_CDC_E);
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_CRT_DISPLAY_CONTROL) &=
 | |
| 				~SM501_CDC_SEL;
 | |
| 			return 0;
 | |
| 		} else if (strncmp (argv[2], "off", 3) == 0) {
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_CRT_DISPLAY_CONTROL) &=
 | |
| 				~(SM501_CDC_TE | SM501_CDC_E);
 | |
| 			*(vu_long *) (SM501_MMIO_BASE +
 | |
| 				      SM501_CRT_DISPLAY_CONTROL) |=
 | |
| 				SM501_CDC_SEL;
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| #endif /* CONFIG_BC3450_CRT */
 | |
| 	printf ("Usage:%s\n", cmdtp->help);
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| U_BOOT_CMD (fp, 3, 1, cmd_fp,
 | |
| 	    "front panes access functions",
 | |
| 	    "\n"
 | |
| 	    "fp bl <on/off>\n"
 | |
| 	    "     - turns the CCFL backlight of the display on/off\n"
 | |
| 	    "fp <on/off>\n" "     - turns the whole display on/off"
 | |
| #ifdef CONFIG_BC3450_CRT
 | |
| 	    "\n"
 | |
| 	    "fp crt <on/off>\n"
 | |
| 	    "     - enables/disables the crt output (debug only)"
 | |
| #endif /* CONFIG_BC3450_CRT */
 | |
| 	);
 | |
| 
 | |
| /*
 | |
|  * temp - DS1620 thermometer
 | |
|  */
 | |
| /* GERSYS BC3450 specific functions */
 | |
| static inline void bc_ds1620_set_clk (int clk)
 | |
| {
 | |
| 	if (clk)
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |=
 | |
| 			DS1620_CLK;
 | |
| 	else
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &=
 | |
| 			~DS1620_CLK;
 | |
| }
 | |
| 
 | |
| static inline void bc_ds1620_set_data (int dat)
 | |
| {
 | |
| 	if (dat)
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |=
 | |
| 			DS1620_DQ;
 | |
| 	else
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &=
 | |
| 			~DS1620_DQ;
 | |
| }
 | |
| 
 | |
| static inline int bc_ds1620_get_data (void)
 | |
| {
 | |
| 	vu_long rc;
 | |
| 
 | |
| 	rc = *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW);
 | |
| 	rc &= DS1620_DQ;
 | |
| 	if (rc != 0)
 | |
| 		rc = 1;
 | |
| 	return (int) rc;
 | |
| }
 | |
| 
 | |
| static inline void bc_ds1620_set_data_dir (int dir)
 | |
| {
 | |
| 	if (dir)		/* in */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) &= ~DS1620_DQ;
 | |
| 	else			/* out */
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) |= DS1620_DQ;
 | |
| }
 | |
| 
 | |
| static inline void bc_ds1620_set_reset (int res)
 | |
| {
 | |
| 	if (res)
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_RES;
 | |
| 	else
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &= ~DS1620_RES;
 | |
| }
 | |
| 
 | |
| /* hardware independent functions */
 | |
| static void ds1620_send_bits (int nr, int value)
 | |
| {
 | |
| 	int i;
 | |
| 
 | |
| 	for (i = 0; i < nr; i++) {
 | |
| 		bc_ds1620_set_data (value & 1);
 | |
| 		bc_ds1620_set_clk (0);
 | |
| 		udelay (1);
 | |
| 		bc_ds1620_set_clk (1);
 | |
| 		udelay (1);
 | |
| 
 | |
| 		value >>= 1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static unsigned int ds1620_recv_bits (int nr)
 | |
| {
 | |
| 	unsigned int value = 0, mask = 1;
 | |
| 	int i;
 | |
| 
 | |
| 	bc_ds1620_set_data (0);
 | |
| 
 | |
| 	for (i = 0; i < nr; i++) {
 | |
| 		bc_ds1620_set_clk (0);
 | |
| 		udelay (1);
 | |
| 
 | |
| 		if (bc_ds1620_get_data ())
 | |
| 			value |= mask;
 | |
| 
 | |
| 		mask <<= 1;
 | |
| 
 | |
| 		bc_ds1620_set_clk (1);
 | |
| 		udelay (1);
 | |
| 	}
 | |
| 
 | |
| 	return value;
 | |
| }
 | |
| 
 | |
| static void ds1620_out (int cmd, int bits, int value)
 | |
| {
 | |
| 	bc_ds1620_set_clk (1);
 | |
| 	bc_ds1620_set_data_dir (0);
 | |
| 
 | |
| 	bc_ds1620_set_reset (0);
 | |
| 	udelay (1);
 | |
| 	bc_ds1620_set_reset (1);
 | |
| 
 | |
| 	udelay (1);
 | |
| 
 | |
| 	ds1620_send_bits (8, cmd);
 | |
| 	if (bits)
 | |
| 		ds1620_send_bits (bits, value);
 | |
| 
 | |
| 	udelay (1);
 | |
| 
 | |
| 	/* go stand alone */
 | |
| 	bc_ds1620_set_data_dir (1);
 | |
| 	bc_ds1620_set_reset (0);
 | |
| 	bc_ds1620_set_clk (0);
 | |
| 
 | |
| 	udelay (10000);
 | |
| }
 | |
| 
 | |
| static unsigned int ds1620_in (int cmd, int bits)
 | |
| {
 | |
| 	unsigned int value;
 | |
| 
 | |
| 	bc_ds1620_set_clk (1);
 | |
| 	bc_ds1620_set_data_dir (0);
 | |
| 
 | |
| 	bc_ds1620_set_reset (0);
 | |
| 	udelay (1);
 | |
| 	bc_ds1620_set_reset (1);
 | |
| 
 | |
| 	udelay (1);
 | |
| 
 | |
| 	ds1620_send_bits (8, cmd);
 | |
| 
 | |
| 	bc_ds1620_set_data_dir (1);
 | |
| 	value = ds1620_recv_bits (bits);
 | |
| 
 | |
| 	/* go stand alone */
 | |
| 	bc_ds1620_set_data_dir (1);
 | |
| 	bc_ds1620_set_reset (0);
 | |
| 	bc_ds1620_set_clk (0);
 | |
| 
 | |
| 	return value;
 | |
| }
 | |
| 
 | |
| static int cvt_9_to_int (unsigned int val)
 | |
| {
 | |
| 	if (val & 0x100)
 | |
| 		val |= 0xfffffe00;
 | |
| 
 | |
| 	return val;
 | |
| }
 | |
| 
 | |
| /* set thermostate thresholds */
 | |
| static void ds1620_write_state (struct therm *therm)
 | |
| {
 | |
| 	ds1620_out (THERM_WRITE_TL, 9, therm->lo);
 | |
| 	ds1620_out (THERM_WRITE_TH, 9, therm->hi);
 | |
| 	ds1620_out (THERM_START_CONVERT, 0, 0);
 | |
| }
 | |
| 
 | |
| static int cmd_temp (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 | |
| {
 | |
| 	int i;
 | |
| 	struct therm therm;
 | |
| 
 | |
| 	sm501_gpio_init ();
 | |
| 
 | |
| 	/* print temperature */
 | |
| 	if (argc == 1) {
 | |
| 		i = cvt_9_to_int (ds1620_in (THERM_READ_TEMP, 9));
 | |
| 		printf ("%d.%d C\n", i >> 1, i & 1 ? 5 : 0);
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	/* set to default operation */
 | |
| 	if (strncmp (argv[1], "set", 3) == 0) {
 | |
| 		if (strncmp (argv[2], "default", 3) == 0) {
 | |
| 			therm.hi = +88;
 | |
| 			therm.lo = -20;
 | |
| 			therm.hi <<= 1;
 | |
| 			therm.lo <<= 1;
 | |
| 			ds1620_write_state (&therm);
 | |
| 			ds1620_out (THERM_WRITE_CONFIG, 8, CONFIG_SYS_STANDALONE);
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	printf ("Usage:%s\n", cmdtp->help);
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| U_BOOT_CMD (temp, 3, 1, cmd_temp,
 | |
| 	    "print current temperature",
 | |
| 	    "\n" "temp\n" "     - print current temperature");
 | |
| 
 | |
| #ifdef CONFIG_BC3450_CAN
 | |
| /*
 | |
|  * Initialise CAN interface
 | |
|  *
 | |
|  * return 1 on CAN initialization failure
 | |
|  * return 0 if no failure
 | |
|  */
 | |
| int can_init (void)
 | |
| {
 | |
| 	static int init_done = 0;
 | |
| 	int i;
 | |
| 	struct mpc5xxx_mscan *can1 =
 | |
| 		(struct mpc5xxx_mscan *) (CONFIG_SYS_MBAR + 0x0900);
 | |
| 	struct mpc5xxx_mscan *can2 =
 | |
| 		(struct mpc5xxx_mscan *) (CONFIG_SYS_MBAR + 0x0980);
 | |
| 
 | |
| 	/* GPIO configuration of the CAN pins is done in BC3450.h */
 | |
| 
 | |
| 	if (!init_done) {
 | |
| 		/* init CAN 1 */
 | |
| 		can1->canctl1 |= 0x80;	/* CAN enable */
 | |
| 		udelay (100);
 | |
| 
 | |
| 		i = 0;
 | |
| 		can1->canctl0 |= 0x02;	/* sleep mode */
 | |
| 		/* wait until sleep mode reached */
 | |
| 		while (!(can1->canctl1 & 0x02)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN1 initialize error, "
 | |
| 					"can not enter sleep mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 		i = 0;
 | |
| 		can1->canctl0 = 0x01;	/* enter init mode */
 | |
| 		/* wait until init mode reached */
 | |
| 		while (!(can1->canctl1 & 0x01)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN1 initialize error, "
 | |
| 					"can not enter init mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 		can1->canctl1 = 0x80;
 | |
| 		can1->canctl1 |= 0x40;
 | |
| 		can1->canbtr0 = 0x0F;
 | |
| 		can1->canbtr1 = 0x7F;
 | |
| 		can1->canidac &= ~(0x30);
 | |
| 		can1->canidar1 = 0x00;
 | |
| 		can1->canidar3 = 0x00;
 | |
| 		can1->canidar5 = 0x00;
 | |
| 		can1->canidar7 = 0x00;
 | |
| 		can1->canidmr0 = 0xFF;
 | |
| 		can1->canidmr1 = 0xFF;
 | |
| 		can1->canidmr2 = 0xFF;
 | |
| 		can1->canidmr3 = 0xFF;
 | |
| 		can1->canidmr4 = 0xFF;
 | |
| 		can1->canidmr5 = 0xFF;
 | |
| 		can1->canidmr6 = 0xFF;
 | |
| 		can1->canidmr7 = 0xFF;
 | |
| 
 | |
| 		i = 0;
 | |
| 		can1->canctl0 &= ~(0x01);	/* leave init mode */
 | |
| 		can1->canctl0 &= ~(0x02);
 | |
| 		/* wait until init and sleep mode left */
 | |
| 		while ((can1->canctl1 & 0x01) || (can1->canctl1 & 0x02)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN1 initialize error, "
 | |
| 					"can not leave init/sleep mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/* init CAN 2 */
 | |
| 		can2->canctl1 |= 0x80;	/* CAN enable */
 | |
| 		udelay (100);
 | |
| 
 | |
| 		i = 0;
 | |
| 		can2->canctl0 |= 0x02;	/* sleep mode */
 | |
| 		/* wait until sleep mode reached */
 | |
| 		while (!(can2->canctl1 & 0x02)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN2 initialize error, "
 | |
| 					"can not enter sleep mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 		i = 0;
 | |
| 		can2->canctl0 = 0x01;	/* enter init mode */
 | |
| 		/* wait until init mode reached */
 | |
| 		while (!(can2->canctl1 & 0x01)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN2 initialize error, "
 | |
| 					"can not enter init mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 		can2->canctl1 = 0x80;
 | |
| 		can2->canctl1 |= 0x40;
 | |
| 		can2->canbtr0 = 0x0F;
 | |
| 		can2->canbtr1 = 0x7F;
 | |
| 		can2->canidac &= ~(0x30);
 | |
| 		can2->canidar1 = 0x00;
 | |
| 		can2->canidar3 = 0x00;
 | |
| 		can2->canidar5 = 0x00;
 | |
| 		can2->canidar7 = 0x00;
 | |
| 		can2->canidmr0 = 0xFF;
 | |
| 		can2->canidmr1 = 0xFF;
 | |
| 		can2->canidmr2 = 0xFF;
 | |
| 		can2->canidmr3 = 0xFF;
 | |
| 		can2->canidmr4 = 0xFF;
 | |
| 		can2->canidmr5 = 0xFF;
 | |
| 		can2->canidmr6 = 0xFF;
 | |
| 		can2->canidmr7 = 0xFF;
 | |
| 		can2->canctl0 &= ~(0x01);	/* leave init mode */
 | |
| 		can2->canctl0 &= ~(0x02);
 | |
| 
 | |
| 		i = 0;
 | |
| 		/* wait until init mode left */
 | |
| 		while ((can2->canctl1 & 0x01) || (can2->canctl1 & 0x02)) {
 | |
| 			udelay (10);
 | |
| 			i++;
 | |
| 			if (i == 10) {
 | |
| 				printf ("%s: CAN2 initialize error, "
 | |
| 					"can not leave init/sleep mode!\n",
 | |
| 					__FUNCTION__);
 | |
| 				return 1;
 | |
| 			}
 | |
| 		}
 | |
| 		init_done = 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Do CAN test
 | |
|  * by sending message between CAN1 and CAN2
 | |
|  *
 | |
|  * return 1 on CAN failure
 | |
|  * return 0 if no failure
 | |
|  */
 | |
| int do_can (char * const argv[])
 | |
| {
 | |
| 	int i;
 | |
| 	struct mpc5xxx_mscan *can1 =
 | |
| 		(struct mpc5xxx_mscan *) (CONFIG_SYS_MBAR + 0x0900);
 | |
| 	struct mpc5xxx_mscan *can2 =
 | |
| 		(struct mpc5xxx_mscan *) (CONFIG_SYS_MBAR + 0x0980);
 | |
| 
 | |
| 	/* send a message on CAN1 */
 | |
| 	can1->cantbsel = 0x01;
 | |
| 	can1->cantxfg.idr[0] = 0x55;
 | |
| 	can1->cantxfg.idr[1] = 0x00;
 | |
| 	can1->cantxfg.idr[1] &= ~0x8;
 | |
| 	can1->cantxfg.idr[1] &= ~0x10;
 | |
| 	can1->cantxfg.dsr[0] = 0xCC;
 | |
| 	can1->cantxfg.dlr = 1;
 | |
| 	can1->cantxfg.tbpr = 0;
 | |
| 	can1->cantflg = 0x01;
 | |
| 
 | |
| 	i = 0;
 | |
| 	while ((can1->cantflg & 0x01) == 0) {
 | |
| 		i++;
 | |
| 		if (i == 10) {
 | |
| 			printf ("%s: CAN1 send timeout, "
 | |
| 				"can not send message!\n", __FUNCTION__);
 | |
| 			return 1;
 | |
| 		}
 | |
| 		udelay (1000);
 | |
| 	}
 | |
| 	udelay (1000);
 | |
| 
 | |
| 	i = 0;
 | |
| 	while (!(can2->canrflg & 0x01)) {
 | |
| 		i++;
 | |
| 		if (i == 10) {
 | |
| 			printf ("%s: CAN2 receive timeout, "
 | |
| 				"no message received!\n", __FUNCTION__);
 | |
| 			return 1;
 | |
| 		}
 | |
| 		udelay (1000);
 | |
| 	}
 | |
| 
 | |
| 	if (can2->canrxfg.dsr[0] != 0xCC) {
 | |
| 		printf ("%s: CAN2 receive error, "
 | |
| 			"data mismatch!\n", __FUNCTION__);
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	/* send a message on CAN2 */
 | |
| 	can2->cantbsel = 0x01;
 | |
| 	can2->cantxfg.idr[0] = 0x55;
 | |
| 	can2->cantxfg.idr[1] = 0x00;
 | |
| 	can2->cantxfg.idr[1] &= ~0x8;
 | |
| 	can2->cantxfg.idr[1] &= ~0x10;
 | |
| 	can2->cantxfg.dsr[0] = 0xCC;
 | |
| 	can2->cantxfg.dlr = 1;
 | |
| 	can2->cantxfg.tbpr = 0;
 | |
| 	can2->cantflg = 0x01;
 | |
| 
 | |
| 	i = 0;
 | |
| 	while ((can2->cantflg & 0x01) == 0) {
 | |
| 		i++;
 | |
| 		if (i == 10) {
 | |
| 			printf ("%s: CAN2 send error, "
 | |
| 				"can not send message!\n", __FUNCTION__);
 | |
| 			return 1;
 | |
| 		}
 | |
| 		udelay (1000);
 | |
| 	}
 | |
| 	udelay (1000);
 | |
| 
 | |
| 	i = 0;
 | |
| 	while (!(can1->canrflg & 0x01)) {
 | |
| 		i++;
 | |
| 		if (i == 10) {
 | |
| 			printf ("%s: CAN1 receive timeout, "
 | |
| 				"no message received!\n", __FUNCTION__);
 | |
| 			return 1;
 | |
| 		}
 | |
| 		udelay (1000);
 | |
| 	}
 | |
| 
 | |
| 	if (can1->canrxfg.dsr[0] != 0xCC) {
 | |
| 		printf ("%s: CAN1 receive error 0x%02x\n",
 | |
| 			__FUNCTION__, (can1->canrxfg.dsr[0]));
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| #endif /* CONFIG_BC3450_CAN */
 | |
| 
 | |
| /*
 | |
|  * test - BC3450 HW test routines
 | |
|  */
 | |
| int cmd_test (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 | |
| {
 | |
| #ifdef CONFIG_BC3450_CAN
 | |
| 	int rcode;
 | |
| 
 | |
| 	can_init ();
 | |
| #endif /* CONFIG_BC3450_CAN */
 | |
| 
 | |
| 	sm501_gpio_init ();
 | |
| 
 | |
| 	if (argc != 2) {
 | |
| 		printf ("Usage:%s\n", cmdtp->help);
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	if (strncmp (argv[1], "unit-off", 8) == 0) {
 | |
| 		printf ("waiting 2 seconds...\n");
 | |
| 		udelay (2000000);
 | |
| 		*(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &=
 | |
| 			~PWR_OFF;
 | |
| 		return 0;
 | |
| 	}
 | |
| #ifdef CONFIG_BC3450_CAN
 | |
| 	else if (strncmp (argv[1], "can", 2) == 0) {
 | |
| 		rcode = do_can (argv);
 | |
| 		if (simple_strtoul (argv[2], NULL, 10) == 2) {
 | |
| 			if (rcode == 0)
 | |
| 				printf ("OK\n");
 | |
| 			else
 | |
| 				printf ("Error\n");
 | |
| 		}
 | |
| 		return rcode;
 | |
| 	}
 | |
| #endif /* CONFIG_BC3450_CAN */
 | |
| 
 | |
| 	printf ("Usage:%s\n", cmdtp->help);
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| U_BOOT_CMD (test, 2, 1, cmd_test, "unit test routines", "\n"
 | |
| #ifdef CONFIG_BC3450_CAN
 | |
| 	"test can\n"
 | |
| 	"     - connect CAN1 (X8) with CAN2 (X9) for this test\n"
 | |
| #endif /* CONFIG_BC3450_CAN */
 | |
| 	"test unit-off\n"
 | |
| 	"     - turns off the BC3450 unit\n"
 | |
| 	"       WARNING: Unsaved environment variables will be lost!"
 | |
| );
 | |
| #endif
 |