]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - common/cmd_i2c.c
edid: Add I2C command for printing the EDID
[people/ms/u-boot.git] / common / cmd_i2c.c
index 82e63e13224cb6c45d129585a4dd3de59f69ae2c..438079447479773abab4b615894a0d69c9a216b4 100644 (file)
 
 #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 */
-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 */
-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")));
 
-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;
@@ -1376,10 +1574,8 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 }
 
 /***************************************************/
-
-U_BOOT_CMD(
-       i2c, 6, 1, do_i2c,
-       "I2C sub-system",
+#ifdef CONFIG_SYS_LONGHELP
+static char i2c_help_text[] =
 #if defined(CONFIG_I2C_MUX)
        "bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
 #endif  /* CONFIG_I2C_MUX */
@@ -1387,6 +1583,9 @@ U_BOOT_CMD(
 #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"
@@ -1399,7 +1598,13 @@ U_BOOT_CMD(
 #if defined(CONFIG_CMD_SDRAM)
        "i2c sdram chip - print SDRAM configuration information\n"
 #endif
-       "i2c speed [speed] - show or set I2C bus speed"
+       "i2c speed [speed] - show or set I2C bus speed";
+#endif
+
+U_BOOT_CMD(
+       i2c, 6, 1, do_i2c,
+       "I2C sub-system",
+       i2c_help_text
 );
 
 #if defined(CONFIG_I2C_MUX)