diff options
Diffstat (limited to 'common/cmd_i2c.c')
| -rw-r--r-- | common/cmd_i2c.c | 249 | 
1 files changed, 225 insertions, 24 deletions
| diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 4438db594..438079447 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -78,10 +78,12 @@  #include <common.h>  #include <command.h> +#include <edid.h>  #include <environment.h>  #include <i2c.h>  #include <malloc.h>  #include <asm/byteorder.h> +#include <linux/compiler.h>  /* Display values from last command.   * Memory modify remembered values are different from display memory. @@ -132,35 +134,65 @@ DECLARE_GLOBAL_DATA_PTR;  #define DISP_LINE_LEN	16 -/* implement possible board specific board init */ -static void __def_i2c_init_board(void) +/** + * i2c_init_board() - Board-specific I2C bus init + * + * This function is the default no-op implementation of I2C bus + * initialization. This function can be overriden by board-specific + * implementation if needed. + */ +__weak +void i2c_init_board(void)  {  	return;  } -void i2c_init_board(void) -	__attribute__((weak, alias("__def_i2c_init_board")));  /* TODO: Implement architecture-specific get/set functions */ -static unsigned int __def_i2c_get_bus_speed(void) + +/** + * i2c_get_bus_speed() - Return I2C bus speed + * + * This function is the default implementation of function for retrieveing + * the current I2C bus speed in Hz. + * + * A driver implementing runtime switching of I2C bus speed must override + * this function to report the speed correctly. Simple or legacy drivers + * can use this fallback. + * + * Returns I2C bus speed in Hz. + */ +__weak +unsigned int i2c_get_bus_speed(void)  {  	return CONFIG_SYS_I2C_SPEED;  } -unsigned int i2c_get_bus_speed(void) -	__attribute__((weak, alias("__def_i2c_get_bus_speed"))); -static int __def_i2c_set_bus_speed(unsigned int speed) +/** + * i2c_set_bus_speed() - Configure I2C bus speed + * @speed:	Newly set speed of the I2C bus in Hz + * + * This function is the default implementation of function for setting + * the I2C bus speed in Hz. + * + * A driver implementing runtime switching of I2C bus speed must override + * this function to report the speed correctly. Simple or legacy drivers + * can use this fallback. + * + * Returns zero on success, negative value on error. + */ +__weak +int i2c_set_bus_speed(unsigned int speed)  {  	if (speed != CONFIG_SYS_I2C_SPEED)  		return -1;  	return 0;  } -int i2c_set_bus_speed(unsigned int) -	__attribute__((weak, alias("__def_i2c_set_bus_speed"))); -/* - * get_alen: small parser helper function to get address length - * returns the address length +/** + * get_alen() - Small parser helper function to get address length + * + * Returns the address length.   */  static uint get_alen(char *arg)  { @@ -178,11 +210,19 @@ static uint get_alen(char *arg)  	return alen;  } -/* +/** + * do_i2c_read() - Handle the "i2c read" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + *   * Syntax:   *	i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}   */ -  static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	u_char	chip; @@ -271,7 +311,16 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[  	return 0;  } -/* +/** + * do_i2c_md() - Handle the "i2c md" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + *   * Syntax:   *	i2c md {i2c_chip} {addr}{.0, .1, .2} {len}   */ @@ -363,8 +412,15 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  	return 0;  } - -/* Write (fill) memory +/** + * do_i2c_mw() - Handle the "i2c mw" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error.   *   * Syntax:   *	i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] @@ -421,10 +477,20 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  #endif  	} -	return (0); +	return 0;  } -/* Calculate a CRC on memory +/** + * do_i2c_crc() - Handle the "i2c crc32" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Calculate a CRC on memory + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error.   *   * Syntax:   *	i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} @@ -481,13 +547,22 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  	return 0;  } -/* Modify memory. +/** + * mod_i2c_mem() - Handle the "i2c mm" and "i2c nm" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Modify memory. + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error.   *   * Syntax:   *	i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}   *	i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}   */ -  static int  mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])  { @@ -603,7 +678,16 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg  	return 0;  } -/* +/** + * do_i2c_probe() - Handle the "i2c probe" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + *   * Syntax:   *	i2c probe {addr}   * @@ -657,7 +741,16 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv  	return (0 == found);  } -/* +/** + * do_i2c_loop() - Handle the "i2c loop" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + *   * Syntax:   *	i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]   *	{length} - Number of bytes to read @@ -718,6 +811,8 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  /*   * The SDRAM command is separately configured because many   * (most?) embedded boards don't use SDRAM DIMMs. + * + * FIXME: Document and probably move elsewhere!   */  #if defined(CONFIG_CMD_SDRAM)  static void print_ddr2_tcyc (u_char const b) @@ -1246,7 +1341,48 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  }  #endif +/* + * Syntax: + *	i2c edid {i2c_chip} + */ +#if defined(CONFIG_I2C_EDID) +int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	u_char chip; +	struct edid1_info edid; + +	if (argc < 2) { +		cmd_usage(cmdtp); +		return 1; +	} + +	chip = simple_strtoul(argv[1], NULL, 16); +	if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) { +		puts("Error reading EDID content.\n"); +		return 1; +	} + +	if (edid_check_info(&edid)) { +		puts("Content isn't valid EDID.\n"); +		return 1; +	} + +	edid_print_info(&edid); +	return 0; + +} +#endif /* CONFIG_I2C_EDID */ +  #if defined(CONFIG_I2C_MUX) +/** + * do_i2c_add_bus() - Handle the "i2c bus" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero always. + */  static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	int ret=0; @@ -1276,6 +1412,16 @@ static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar  #endif  /* CONFIG_I2C_MUX */  #if defined(CONFIG_I2C_MULTI_BUS) +/** + * do_i2c_bus_num() - Handle the "i2c dev" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */  static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	int bus_idx, ret=0; @@ -1294,6 +1440,16 @@ static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar  }  #endif  /* CONFIG_I2C_MULTI_BUS */ +/** + * do_i2c_bus_speed() - Handle the "i2c speed" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */  static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	int speed, ret=0; @@ -1311,16 +1467,45 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const  	return ret;  } +/** + * do_i2c_mm() - Handle the "i2c mm" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */  static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	return mod_i2c_mem (cmdtp, 1, flag, argc, argv);  } +/** + * do_i2c_nm() - Handle the "i2c nm" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */  static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	return mod_i2c_mem (cmdtp, 0, flag, argc, argv);  } +/** + * do_i2c_reset() - Handle the "i2c reset" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero always. + */  static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); @@ -1335,6 +1520,9 @@ static cmd_tbl_t cmd_i2c_sub[] = {  #if defined(CONFIG_I2C_MULTI_BUS)  	U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),  #endif  /* CONFIG_I2C_MULTI_BUS */ +#if defined(CONFIG_I2C_EDID) +	U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", ""), +#endif  /* CONFIG_I2C_EDID */  	U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""),  	U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""),  	U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""), @@ -1356,6 +1544,16 @@ void i2c_reloc(void) {  }  #endif +/** + * do_i2c() - Handle the "i2c" command-line command + * @cmdtp:	Command data struct pointer + * @flag:	Command flag + * @argc:	Command-line argument count + * @argv:	Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */  static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  {  	cmd_tbl_t *c; @@ -1385,6 +1583,9 @@ static char i2c_help_text[] =  #if defined(CONFIG_I2C_MULTI_BUS)  	"i2c dev [dev] - show or set current I2C bus\n"  #endif  /* CONFIG_I2C_MULTI_BUS */ +#if defined(CONFIG_I2C_EDID) +	"i2c edid chip - print EDID configuration information\n" +#endif  /* CONFIG_I2C_EDID */  	"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"  	"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"  	"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" |