Re: [U-Boot] [RFC PATCH 04/12] dm: i2c: Implement driver model support in the i2c command

2014-11-09 Thread Heiko Schocher

Hello Simon,

Am 13.10.2014 07:39, schrieb Simon Glass:

The concept of a 'current bus' is now implemented in the command line
rather than in the uclass. Also the address length does not need to
be specified with each command - really we should consider dropping
this from most commands but it works OK for now.

Signed-off-by: Simon Glass s...@chromium.org
---

  common/cmd_i2c.c | 312 +++
  1 file changed, 267 insertions(+), 45 deletions(-)

diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index c266b88..6766856 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -69,8 +69,10 @@
  #include bootretry.h
  #include cli.h
  #include command.h
+#include dm.h
  #include edid.h
  #include environment.h
+#include errno.h
  #include i2c.h
  #include malloc.h
  #include asm/byteorder.h
@@ -117,6 +119,60 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;

  #define DISP_LINE_LEN 16

+/*
+ * Default for driver model is to use the chip's existing address length.
+ * For legacy code, this is not stored, so we need to use a suitable
+ * default.
+ */
+#ifdef CONFIG_DM_I2C
+#define DEFAULT_ADDR_LEN   (-1)
+#else
+#define DEFAULT_ADDR_LEN   1
+#endif
+
+#ifdef CONFIG_DM_I2C
+static struct udevice *i2c_cur_bus;
+
+static int i2c_set_bus_num(unsigned int busnum)
+{
+   struct udevice *bus;
+   int ret;
+
+   ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, bus);
+   if (ret) {
+   debug(%s: No bus %d\n, __func__, busnum);
+   return ret;
+   }
+   i2c_cur_bus = bus;
+
+   return 0;
+}
+
+static int i2c_get_cur_bus(struct udevice **busp)
+{
+   if (!i2c_cur_bus) {
+   puts(No I2C bus selected\n);
+   return -ENODEV;
+   }
+   *busp = i2c_cur_bus;
+
+   return 0;
+}
+
+static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
+{
+   struct udevice *bus;
+   int ret;
+
+   ret = i2c_get_cur_bus(bus);
+   if (ret)
+   return ret;
+
+   return i2c_get_chip(bus, chip_addr, devp);
+}
+
+#endif
+
  /**
   * i2c_init_board() - Board-specific I2C bus init
   *
@@ -143,7 +199,7 @@ void i2c_init_board(void)
   *
   * Returns I2C bus speed in Hz.
   */
-#if !defined(CONFIG_SYS_I2C)
+#if !defined(CONFIG_SYS_I2C)  !defined(CONFIG_DM_I2C)
  /*
   * TODO: Implement architecture-specific get/set functions
   * Should go away, if we switched completely to new multibus support
@@ -182,12 +238,12 @@ int i2c_set_bus_speed(unsigned int speed)
   *
   * Returns the address length.
   */
-static uint get_alen(char *arg)
+static uint get_alen(char *arg, int default_len)
  {
int j;
int alen;

-   alen = 1;
+   alen = default_len;
for (j = 0; j  8; j++) {
if (arg[j] == '.') {
alen = arg[j+1] - '0';
@@ -229,6 +285,10 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
u_char  chip;
uintdevaddr, alen, length;
u_char  *memaddr;
+   int ret;
+#ifdef CONFIG_DM_I2C
+   struct udevice *dev;
+#endif

if (argc != 5)
return CMD_RET_USAGE;
@@ -243,7 +303,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
 * 2 bytes long.  Some day it might be 3 bytes long :-).
 */
devaddr = simple_strtoul(argv[2], NULL, 16);
-   alen = get_alen(argv[2]);
+   alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
if (alen  3)
return CMD_RET_USAGE;

@@ -257,10 +317,18 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
 */
memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);

-   if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
-   i2c_report_err(-1, I2C_ERR_READ);
-   return 1;
-   }
+#ifdef CONFIG_DM_I2C
+   ret = i2c_get_cur_bus_chip(chip, dev);
+   if (!ret  alen != -1)
+   ret = i2c_set_addr_len(dev, alen);
+   if (!ret)
+   ret = i2c_read(dev, devaddr, memaddr, length);
+#else
+   ret = i2c_read(chip, devaddr, alen, memaddr, length);
+#endif
+   if (ret)
+   return i2c_report_err(ret, I2C_ERR_READ);
+
return 0;
  }

@@ -269,6 +337,10 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[
u_char  chip;
uintdevaddr, alen, length;
u_char  *memaddr;
+   int ret;
+#ifdef CONFIG_DM_I2C
+   struct udevice *dev;
+#endif

if (argc != 5)
return cmd_usage(cmdtp);
@@ -288,7 +360,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[
 * 2 bytes long.  Some day it might be 3 bytes long :-).
 */
devaddr = simple_strtoul(argv[3], NULL, 16);
-   alen = get_alen(argv[3]);
+   alen = get_alen(argv[3], DEFAULT_ADDR_LEN);
if 

[U-Boot] [RFC PATCH 04/12] dm: i2c: Implement driver model support in the i2c command

2014-10-12 Thread Simon Glass
The concept of a 'current bus' is now implemented in the command line
rather than in the uclass. Also the address length does not need to
be specified with each command - really we should consider dropping
this from most commands but it works OK for now.

Signed-off-by: Simon Glass s...@chromium.org
---

 common/cmd_i2c.c | 312 +++
 1 file changed, 267 insertions(+), 45 deletions(-)

diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index c266b88..6766856 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -69,8 +69,10 @@
 #include bootretry.h
 #include cli.h
 #include command.h
+#include dm.h
 #include edid.h
 #include environment.h
+#include errno.h
 #include i2c.h
 #include malloc.h
 #include asm/byteorder.h
@@ -117,6 +119,60 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
 
 #define DISP_LINE_LEN  16
 
+/*
+ * Default for driver model is to use the chip's existing address length.
+ * For legacy code, this is not stored, so we need to use a suitable
+ * default.
+ */
+#ifdef CONFIG_DM_I2C
+#define DEFAULT_ADDR_LEN   (-1)
+#else
+#define DEFAULT_ADDR_LEN   1
+#endif
+
+#ifdef CONFIG_DM_I2C
+static struct udevice *i2c_cur_bus;
+
+static int i2c_set_bus_num(unsigned int busnum)
+{
+   struct udevice *bus;
+   int ret;
+
+   ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, bus);
+   if (ret) {
+   debug(%s: No bus %d\n, __func__, busnum);
+   return ret;
+   }
+   i2c_cur_bus = bus;
+
+   return 0;
+}
+
+static int i2c_get_cur_bus(struct udevice **busp)
+{
+   if (!i2c_cur_bus) {
+   puts(No I2C bus selected\n);
+   return -ENODEV;
+   }
+   *busp = i2c_cur_bus;
+
+   return 0;
+}
+
+static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
+{
+   struct udevice *bus;
+   int ret;
+
+   ret = i2c_get_cur_bus(bus);
+   if (ret)
+   return ret;
+
+   return i2c_get_chip(bus, chip_addr, devp);
+}
+
+#endif
+
 /**
  * i2c_init_board() - Board-specific I2C bus init
  *
@@ -143,7 +199,7 @@ void i2c_init_board(void)
  *
  * Returns I2C bus speed in Hz.
  */
-#if !defined(CONFIG_SYS_I2C)
+#if !defined(CONFIG_SYS_I2C)  !defined(CONFIG_DM_I2C)
 /*
  * TODO: Implement architecture-specific get/set functions
  * Should go away, if we switched completely to new multibus support
@@ -182,12 +238,12 @@ int i2c_set_bus_speed(unsigned int speed)
  *
  * Returns the address length.
  */
-static uint get_alen(char *arg)
+static uint get_alen(char *arg, int default_len)
 {
int j;
int alen;
 
-   alen = 1;
+   alen = default_len;
for (j = 0; j  8; j++) {
if (arg[j] == '.') {
alen = arg[j+1] - '0';
@@ -229,6 +285,10 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
u_char  chip;
uintdevaddr, alen, length;
u_char  *memaddr;
+   int ret;
+#ifdef CONFIG_DM_I2C
+   struct udevice *dev;
+#endif
 
if (argc != 5)
return CMD_RET_USAGE;
@@ -243,7 +303,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
 * 2 bytes long.  Some day it might be 3 bytes long :-).
 */
devaddr = simple_strtoul(argv[2], NULL, 16);
-   alen = get_alen(argv[2]);
+   alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
if (alen  3)
return CMD_RET_USAGE;
 
@@ -257,10 +317,18 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv
 */
memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
 
-   if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
-   i2c_report_err(-1, I2C_ERR_READ);
-   return 1;
-   }
+#ifdef CONFIG_DM_I2C
+   ret = i2c_get_cur_bus_chip(chip, dev);
+   if (!ret  alen != -1)
+   ret = i2c_set_addr_len(dev, alen);
+   if (!ret)
+   ret = i2c_read(dev, devaddr, memaddr, length);
+#else
+   ret = i2c_read(chip, devaddr, alen, memaddr, length);
+#endif
+   if (ret)
+   return i2c_report_err(ret, I2C_ERR_READ);
+
return 0;
 }
 
@@ -269,6 +337,10 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[
u_char  chip;
uintdevaddr, alen, length;
u_char  *memaddr;
+   int ret;
+#ifdef CONFIG_DM_I2C
+   struct udevice *dev;
+#endif
 
if (argc != 5)
return cmd_usage(cmdtp);
@@ -288,7 +360,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[
 * 2 bytes long.  Some day it might be 3 bytes long :-).
 */
devaddr = simple_strtoul(argv[3], NULL, 16);
-   alen = get_alen(argv[3]);
+   alen = get_alen(argv[3], DEFAULT_ADDR_LEN);
if (alen  3)
return cmd_usage(cmdtp);
 
@@ -297,10 +369,22 @@