dm: Add I2C support and convert sandbox, tegra
Subsystems (7)
v2 cover dm: Add I2C support and convert sandbox, tegra
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct dm_i2c_chip which is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would be cumbersome to look up in every call.
Secondly there is no concept of a 'current' I2C bus so all associated logic is removed. With driver model i2c_set_bus_num() and i2c_get_bus_num() are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.
Thirdly initialisation is handled by driver model's normal probe() method on each device so there should be no need for i2c_init_all(), i2c_init(), i2c_init_board(), i2c_board_late_init() and board_i2c_init().
I2C muxes are not yet supported. To support these we will need to maintain state of the current mux settings to avoid resetting every mux every time. Probably we need to add a sandbox I2C mux driver to permit testing of this. This can probably be done later.
Platform data is not yet supported either, only device tree. The U_BOOT_I2C_MKENT_COMPLETE() and U_BOOT_I2C_ADAP_COMPLETE() macros are not used. Also struct i2c_adapter is not defined anymore. This will need to be addressed, perhaps as part of converting over a board that does not use device tree, assuming that we want to support this.
The following I2C CONFIGs are no-longer needed when driver model is used:
CONFIG_SYS_I2C_INIT_BOARD - each I2C bus is inited in its probe() method
CONFIG_I2C_MULTI_BUS - we always support multi-bus with driver model CONFIG_SYS_MAX_I2C_BUS - the device tree aliases define available buses CONFIG_SYS_I2C_SPEED - the device tree specifies the speed for each bus CONFIG_SYS_I2C - this is the 'new old' API, now deprecated
There are a few SPI patches included here due to a dependency on a new device binding function.
This series is available at u-boot-dm/i2c-working.
Changes in v2:
- Add a suitable commit message
- Add new patch to correct handling of aliases with embedded digits
- Add new patch to add a function to bind a device by driver name
- Add new patches to adjust SPI to use device_bind_driver()
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device from i2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
- Change alen to int so that it can be -1 (this was a bug)
- Call the deblock() method for 'i2c reset'
- Update commit message for EEPROM driver
- Add a test for automatic binding of generic I2C devices
- Add a new asm/test.h header for tests in sandbox
- Adjust tegra_i2c_child_pre_probe() to permit generic I2C devices
- Correct the compatible strings for I2C buses
- Don't init if the speed is 0, since this breaks the controller
- Expand coverage to all Tegra boards
Simon Glass (17):
dm: i2c: Move error reporting into a common function
dm: core: Allow access to the device's driver_id data
dm: core: Add functions to find parent and OF data
dm: fdt: Correct handling of aliases with embedded digits
dm: Add a function to bind a device by driver name
dm: spi: Correct handling of SPI chip selects in sandbox
dm: spi: Use device_bind_driver() instead of our own function
dm: i2c: Add a uclass for I2C
dm: i2c: Implement driver model support in the i2c command
dm: i2c: Add I2C emulation driver for sandbox
dm: i2c: Add a sandbox I2C driver
dm: i2c: Add an I2C EEPROM simulator
dm: i2c: config: Enable I2C for sandbox using driver model
dm: i2c: dts: Add an I2C bus for sandbox
dm: Add a simple EEPROM driver
dm: i2c: Add tests for I2C
dm: i2c: tegra: Convert to driver model
arch/arm/cpu/tegra20-common/pmu.c | 21 +- arch/arm/dts/tegra124-jetson-tk1.dts | 1 - arch/arm/dts/tegra124-norrin.dts | 1 - arch/arm/dts/tegra30-tec-ng.dts | 4 + arch/arm/include/asm/arch-tegra/tegra_i2c.h | 2 +- arch/sandbox/dts/sandbox.dts | 17 ++ arch/sandbox/include/asm/test.h | 15 ++ board/avionic-design/common/tamonten-ng.c | 12 +- board/nvidia/cardhu/cardhu.c | 13 +- board/nvidia/common/board.c | 4 - board/nvidia/dalmore/dalmore.c | 21 +- board/nvidia/whistler/whistler.c | 29 ++- board/toradex/apalis_t30/apalis_t30.c | 19 +- common/cmd_i2c.c | 350 +++++++++++++++++++++++----- drivers/core/device.c | 10 + drivers/core/lists.c | 38 ++- drivers/i2c/Makefile | 2 + drivers/i2c/i2c-emul-uclass.c | 14 ++ drivers/i2c/i2c-uclass.c | 275 ++++++++++++++++++++++ drivers/i2c/sandbox_i2c.c | 156 +++++++++++++ drivers/i2c/tegra_i2c.c | 320 ++++++++++--------------- drivers/misc/Makefile | 4 + drivers/misc/i2c_eeprom.c | 51 ++++ drivers/misc/i2c_eeprom_emul.c | 108 +++++++++ drivers/mtd/spi/sandbox.c | 4 +- drivers/power/tps6586x.c | 27 +-- drivers/spi/spi-uclass.c | 34 +-- include/config_fallbacks.h | 6 + include/configs/apalis_t30.h | 3 - include/configs/beaver.h | 3 - include/configs/cardhu.h | 5 - include/configs/colibri_t30.h | 3 - include/configs/dalmore.h | 5 - include/configs/jetson-tk1.h | 5 - include/configs/norrin.h | 5 - include/configs/sandbox.h | 6 + include/configs/seaboard.h | 3 - include/configs/tec-ng.h | 5 - include/configs/tegra-common.h | 1 + include/configs/tegra114-common.h | 3 - include/configs/tegra124-common.h | 3 - include/configs/tegra20-common.h | 3 - include/configs/tegra30-common.h | 3 - include/configs/trimslice.h | 3 - include/configs/venice2.h | 5 - include/configs/whistler.h | 3 - include/dm/device.h | 19 ++ include/dm/lists.h | 13 ++ include/dm/uclass-id.h | 4 + include/i2c.h | 288 +++++++++++++++++++++++ include/i2c_eeprom.h | 19 ++ include/spi.h | 14 +- include/tps6586x.h | 4 +- lib/fdtdec.c | 6 +- test/dm/Makefile | 1 + test/dm/i2c.c | 112 +++++++++ test/dm/test.dts | 17 ++ 57 files changed, 1690 insertions(+), 432 deletions(-) create mode 100644 arch/sandbox/include/asm/test.h create mode 100644 drivers/i2c/i2c-emul-uclass.c create mode 100644 drivers/i2c/i2c-uclass.c create mode 100644 drivers/i2c/sandbox_i2c.c create mode 100644 drivers/misc/i2c_eeprom.c create mode 100644 drivers/misc/i2c_eeprom_emul.c create mode 100644 include/i2c_eeprom.h create mode 100644 test/dm/i2c.c
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 1/17 dm: i2c: Move error reporting into a common function
Factor out the common code to make it easier to adjust it.
---
Changes in v2:
- Add a suitable commit message
common/cmd_i2c.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
common/cmd_i2c.c +22 -10
@@ -198,6 +198,19 @@ static uint get_alen(char *arg)return alen; } +enum i2c_err_op { +I2C_ERR_READ , +I2C_ERR_WRITE , +}; + +static int i2c_report_err (int ret,enum i2c_err_op op) +{ +printf ("Error %s the chip: %d\n" , + op ==I2C_ERR_READ ?"reading" :"writing" , ret); + +return CMD_RET_FAILURE ; +} +/** * do_i2c_read() - Handle the "i2c read" command-line command * @cmdtp: Command data struct pointer
@@ -245,7 +258,7 @@ 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 ) { -puts ("Error reading the chip.\n" ); +i2c_report_err (-1 ,I2C_ERR_READ );return 1 ; }return 0 ;
@@ -286,8 +299,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[while (length-- >0 ) {if (i2c_write (chip, devaddr++, alen, memaddr++,1 ) !=0 ) { -puts ("Error writing to the chip.\n" ); -return 1 ; +return i2c_report_err (-1 ,I2C_ERR_WRITE ); }/* * No write delay with FRAM devices.
@@ -370,7 +382,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] linebytes = (nbytes >DISP_LINE_LEN ) ?DISP_LINE_LEN : nbytes;if (i2c_read (chip, addr, alen, linebuf, linebytes) !=0 ) -puts ("Error reading the chip.\n" ); +i2c_report_err (-1 ,I2C_ERR_READ );else {printf ("%04x:" , addr); cp = linebuf;
@@ -452,7 +464,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]while (count-- >0 ) {if (i2c_write (chip, addr++, alen, &byte,1 ) !=0 ) -puts ("Error writing the chip.\n" ); +i2c_report_err (-1 ,I2C_ERR_WRITE );/* * Wait for the write to complete. The write can take * up to 10mSec (we allow a little more time).
@@ -528,7 +540,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] addr++; }if (err >0 ) -puts ("Error reading the chip,\n" ); +i2c_report_err (-1 ,I2C_ERR_READ );else printf ("%08lx\n" , crc);
@@ -601,7 +613,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg do { printf("%08lx:", addr); if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) - puts ("\nError reading the chip,\n"); + i2c_report_err(-1, I2C_ERR_READ); else { data = cpu_to_be32(data); if (size == 1)
@@ -644,7 +656,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg*/ bootretry_reset_cmd_timeout ();if (i2c_write (chip, addr, alen, (uchar *)&data, size) !=0 ) -puts ("Error writing the chip.\n" ); +i2c_report_err (-1 ,I2C_ERR_WRITE );#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS udelay (CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS *1000 );#endif
@@ -783,7 +795,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]*/ while (1 ) {if (i2c_read (chip, addr, alen, bytes, length) !=0 ) -puts ("Error reading the chip.\n" ); +i2c_report_err (-1 ,I2C_ERR_READ );udelay (delay); }
@@ -1341,7 +1353,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) chip =simple_strtoul (argv[1 ],NULL ,16 );if (i2c_read (chip,0 ,1 , (uchar *)&edid,sizeof (edid)) !=0 ) { -puts ("Error reading EDID content.\n" ); +i2c_report_err (-1 ,I2C_ERR_READ );return 1 ; }
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 1/17 dm: i2c: Move error reporting into a common function
Quoted 3 lines · Simon Glass
Factor out the common code to make it easier to adjust it.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/5b2656cc/attachment.pgp>
PATCH v2 1/17 dm: i2c: Move error reporting into a common function
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
Factor out the common code to make it easier to adjust it.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add a suitable commit messagecommon/cmd_i2c.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 1/17 dm: i2c: Move error reporting into a common function
Quoted 9 lines · Heiko Schocher
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 6 lines
Factor out the common code to make it easier to adjust it.
Signed-off-by Simon Glass <[email protected]>---
Quoted 8 lines
Quoted 5 lines
Changes in v2:
- Add a suitable commit messagecommon/cmd_i2c.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)Acked-by Heiko Schocher <[email protected]>
Applied to u-boot-dm.
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
In reply to Simon GlassWhen the device is created from a device tree node, it matches a compatible string. Allow access to that string and the associated data.
---
Changes in v2: None
drivers/core/device.c | 5 +++++ drivers/core/lists.c | 17 ++++++++++++----- include/dm/device.h | 11 +++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-)
drivers/core/device.c +5 -0
@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}
drivers/core/lists.c +12 -5
@@ -89,22 +89,26 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)* tree error */ static int driver_check_compatible (const void *blob,int offset, -const struct udevice_id *of_match) +const struct udevice_id *of_match, +const struct udevice_id **of_idp) {int ret; + *of_idp =NULL ;if (!of_match)return -ENOENT ;while (of_match->compatible) { ret =fdt_node_check_compatible (blob, offset, of_match->compatible); -if (!ret) +if (!ret) { + *of_idp = of_match;return 0 ; -else if (ret == -FDT_ERR_NOTFOUND ) + }else if (ret == -FDT_ERR_NOTFOUND ) {return -ENODEV ; -else if (ret <0 ) + }else if (ret <0 ) {return -EINVAL ; + } of_match++; }
@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;
@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;
@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id; found = true;if (devp) *devp = dev;
include/dm/device.h +11 -0
@@ -47,6 +47,7 @@ struct driver_info;* @name: Name of device, typically the FDT node name * @platdata: Configuration data for this device * @of_offset: Device tree node offset for this device (- for none) +* @of_id: Pointer to the udevice_id structure which created the device * @parent: Parent of this device, or NULL for the top level device * @priv: Private data for this device * @uclass: Pointer to uclass for this device
@@ -65,6 +66,7 @@ struct udevice {const char *name;void *platdata;int of_offset; +const struct udevice_id *of_id;struct udevice *parent;void *priv;struct uclass *uclass;
@@ -206,6 +208,15 @@ void *dev_get_parentdata(struct udevice *dev);void *dev_get_priv (struct udevice *dev);/** +* dev_get_of_data() - get the device tree data used to bind a device +* +* When a device is bound using a device tree node, it matches a +* particular compatible string as in struct udevice_id. This function +* returns the associated data value for that compatible string +*/ +ulong dev_get_of_data (struct udevice *dev); + +/** * device_get_child() - Get the child of a device by index * * Returns the numbered child, 0 being the first. This does not use
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
Quoted 4 lines · Simon Glass
When the device is created from a device tree node, it matches a compatible string. Allow access to that string and the associated data.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/1f1ade33/attachment.pgp>
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
When the device is created from a device tree node, it matches a compatible string. Allow access to that string and the associated data.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
---
Changes in v2: None
drivers/core/device.c | 5 +++++ drivers/core/lists.c | 17 ++++++++++++----- include/dm/device.h | 11 +++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
In reply to Simon GlassHi Simon,
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 555
Quoted 13 lines · On Tue, 11 Nov 2014 10:46:18 -0700 Simon Glass <[email protected]> wrote:
drivers/core/device.c +5
-0@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}
Since this function is short enough, perhaps you might want to define it as "static inline" in the header file include/dm/device.h
Quoted 24 lines
drivers/core/lists.c +5
-2@@ -89,22 +89,26 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)* tree error */ static int driver_check_compatible (const void *blob,int offset, -const struct udevice_id *of_match) +const struct udevice_id *of_match, +const struct udevice_id **of_idp) {int ret; + *of_idp =NULL ;if (!of_match)return -ENOENT ;while (of_match->compatible) { ret =fdt_node_check_compatible (blob, offset, of_match->compatible); -if (!ret) +if (!ret) { + *of_idp = of_match;
drivers/core/lists.c int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) · line 113
Quoted 10 lines
drivers/core/lists.c +3
-2return 0 ; - else if (ret == -FDT_ERR_NOTFOUND) + }else if (ret == -FDT_ERR_NOTFOUND ) {return -ENODEV ; - else if (ret < 0) + }else if (ret <0 ) {return -EINVAL ; + } of_match++; }
I think you are making things more complicated than is needed. I guess what you want to do in this patch is just to set "dev->of_id".
Why do you need to touch this function? (Please see below)
Quoted 19 lines
drivers/core/lists.c +3
-1@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;
drivers/core/lists.c int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, · line 156
Quoted 4 lines
drivers/core/lists.c +1
-0@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id;
Instead of all the chages above, only one line change,
dev->of_id = entry->of_match
Does this work for you?
Best Regards
Masahiro Yamada
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
Hi Masahiro,
Quoted 13 lines · Masahiro Yamada
Hi Simon,
Quoted 6 lines · On Tue, 11 Nov 2014 10:46:18 -0700 Simon Glass <[email protected]> wrote:
drivers/core/device.c +0
-0@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)
Quoted 13 lines
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 555
Quoted 7 lines
drivers/core/device.c +5
-0return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}Since this function is short enough, perhaps you might want to define it as "static inline" in the header file
include/dm/device.h
Thanks for looking at this series.
The background here is that I'm quite worried about all the pointers in driver model. It might be quite easy to use the wrong one and get confused. So my plan is to add code to check that the pointers are what we think they are, like:
DM_CHECK_PTR(dev, "udevice");
or similar. Then that code would compile to nothing unless it is enabled with a CONFIG_DM_CHECK_PTRS or whatever. That's the reason for accessors.
Quoted 43 lines
Quoted 27 lines
drivers/core/lists.c +5
-2@@ -89,22 +89,26 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)* tree error */ static int driver_check_compatible (const void *blob,int offset, -const struct udevice_id *of_match) +const struct udevice_id *of_match, +const struct udevice_id **of_idp) {int ret; + *of_idp =NULL ;if (!of_match)return -ENOENT ;while (of_match->compatible) { ret =fdt_node_check_compatible (blob, offset, of_match->compatible); -if (!ret) +if (!ret) { + *of_idp = of_match;drivers/core/lists.c int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) · line 113
Quoted 10 lines
drivers/core/lists.c +3
-2return 0 ; - else if (ret == -FDT_ERR_NOTFOUND) + }else if (ret == -FDT_ERR_NOTFOUND ) {return -ENODEV ; - else if (ret < 0) + }else if (ret <0 ) {return -EINVAL ; + } of_match++; }I think you are making things more complicated than is needed. I guess what you want to do in this patch is just to set "
dev->of_id".
Quoted 3 lines
Why do you need to touch this function? (Please see below)
See below.
Quoted 31 lines
Quoted 23 lines
drivers/core/lists.c +3
-1@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;drivers/core/lists.c int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, · line 156
Quoted 4 lines
drivers/core/lists.c +1
-0@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id;Instead of all the chages above, only one line change,
Quoted 7 lines
dev->of_id = entry->of_matchDoes this work for you?
entry->of_match is the first element in an array of records. I want to know exactly which one matches, so I can't just use the first one.
Regards,
Simon
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
Hi Simon,
Quoted 30 lines · On Wed, 19 Nov 2014 09:35:54 +0000 Simon Glass <[email protected]> wrote:
Hi Masahiro,
Quoted 13 lines · Masahiro Yamada
Hi Simon,
Quoted 6 lines · On Tue, 11 Nov 2014 10:46:18 -0700 Simon Glass <[email protected]> wrote:
drivers/core/device.c +0
-0@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)Quoted 13 lines
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 555
Quoted 7 lines
drivers/core/device.c +5
-0return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}Since this function is short enough, perhaps you might want to define it as "static inline" in the header file
include/dm/device.h
Quoted 5 lines
Thanks for looking at this series.
The background here is that I'm quite worried about all the pointers in driver model. It might be quite easy to use the wrong one and get confused.
Me too.
Quoted 9 lines
So my plan is to add code to check that the pointers are what we think they are, like:
DM_CHECK_PTR(dev, "udevice");or similar. Then that code would compile to nothing unless it is enabled with a
CONFIG_DM_CHECK_PTRSor whatever. That's the reason for accessors.
Sounds good!
Quoted 32 lines
Quoted 32 lines
Quoted 20 lines
drivers/core/device.c +3
-1@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;drivers/core/device.c int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, · line 156
Quoted 4 lines
drivers/core/device.c +1
-0@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id;Instead of all the chages above, only one line change,
dev->of_id = entry->of_match
Quoted 7 lines
Quoted 3 lines
Does this work for you?
entry->of_matchis the first element in an array of records. I want to know exactly which one matches, so I can't just use the first one.
Sorry, it was my misunderstanding.
Thanks for explaining this.
Could you update the comment block of driver_check_compatible?
/**
* driver_check_compatible() - Check if a driver is compatible with this node *
* @param blob: Device tree pointer
* @param offset: Offset of node in device tree
* @param of_matchL List of compatible strings to match
* @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node
* does not have a compatible string, other error <0 if there is a device
* tree error
*/
- Add description of "@param of_idp"
- Fix "of_matchL" -> "of_match"
Best Regards
Masahiro Yamada
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
Hi Masahiro,
Quoted 100 lines · Masahiro Yamada
Hi Simon,
Quoted 30 lines · On Wed, 19 Nov 2014 09:35:54 +0000 Simon Glass <[email protected]> wrote:
Hi Masahiro,
Quoted 13 lines · Masahiro Yamada
Hi Simon,
Quoted 6 lines · On Tue, 11 Nov 2014 10:46:18 -0700 Simon Glass <[email protected]> wrote:
drivers/core/device.c +0
-0@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)Quoted 13 lines
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 555
Quoted 7 lines
drivers/core/device.c +5
-0return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}Since this function is short enough, perhaps you might want to define it as "static inline" in the header file
include/dm/device.hQuoted 5 lines
Thanks for looking at this series.
The background here is that I'm quite worried about all the pointers in driver model. It might be quite easy to use the wrong one and get confused.
Me too.
Quoted 9 lines
So my plan is to add code to check that the pointers are what we think they are, like:
DM_CHECK_PTR(dev, "udevice");or similar. Then that code would compile to nothing unless it is enabled with a
CONFIG_DM_CHECK_PTRSor whatever. That's the reason for accessors.Sounds good!
Quoted 32 lines
Quoted 32 lines
Quoted 20 lines
drivers/core/device.c +3
-1@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;drivers/core/device.c int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, · line 156
Quoted 4 lines
drivers/core/device.c +1
-0@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id;Instead of all the chages above, only one line change,
dev->of_id = entry->of_matchQuoted 7 lines
Quoted 3 lines
Does this work for you?
entry->of_matchis the first element in an array of records. I want to know exactly which one matches, so I can't just use the first one.
Quoted 6 lines
Sorry, it was my misunderstanding.
Thanks for explaining this.Could you update the comment block of
driver_check_compatible?
OK
Quoted 9 lines
/**
*driver_check_compatible()- Check if a driver is compatible with this node ** @param blob: Device tree pointer * @param offset: Offset of node in device tree * @param of_matchL List of compatible strings to match
Quoted 8 lines
* @return 0 if there is a match,
-ENOENTif no match,-ENODEVif the node
* does not have a compatible string, other error <0 if there is a device
* tree error
*/- Add description of "@param
of_idp"
- Fix "of_matchL" -> "of_match"
Will fix.
Regards,
Simon
PATCH v2 2/17 dm: core: Allow access to the device's driver_id data
Quoted 127 lines · Simon Glass
Hi Masahiro,
Quoted 100 lines · Masahiro Yamada
Hi Simon,
Quoted 30 lines · On Wed, 19 Nov 2014 09:35:54 +0000 Simon Glass <[email protected]> wrote:
Hi Masahiro,
Quoted 13 lines · Masahiro Yamada
Hi Simon,
Quoted 6 lines · On Tue, 11 Nov 2014 10:46:18 -0700 Simon Glass <[email protected]> wrote:
drivers/core/device.c +0
-0@@ -548,3 +548,8 @@ int device_find_next_child(struct udevice **devp)Quoted 13 lines
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 555
Quoted 7 lines
drivers/core/device.c +5
-0return 0 ; } + +ulong dev_get_of_data (struct udevice *dev) +{ +return dev->of_id->data; +}Since this function is short enough, perhaps you might want to define it as "static inline" in the header file
include/dm/device.hQuoted 5 lines
Thanks for looking at this series.
The background here is that I'm quite worried about all the pointers in driver model. It might be quite easy to use the wrong one and get confused.
Me too.
Quoted 9 lines
So my plan is to add code to check that the pointers are what we think they are, like:
DM_CHECK_PTR(dev, "udevice");or similar. Then that code would compile to nothing unless it is enabled with a
CONFIG_DM_CHECK_PTRSor whatever. That's the reason for accessors.Sounds good!
Quoted 32 lines
Quoted 32 lines
Quoted 20 lines
drivers/core/device.c +3
-1@@ -116,6 +120,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, { struct driver *driver = ll_entry_start(struct driver, driver); const int n_ents = ll_entry_count(struct driver, driver); +const struct udevice_id *id;struct driver *entry;struct udevice *dev;bool found = false;@@ -127,7 +132,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,if (devp) *devp =NULL ;for (entry = driver; entry != driver + n_ents; entry++) { - ret =driver_check_compatible (blob, offset, entry->of_match); + ret =driver_check_compatible (blob, offset, entry->of_match, + &id); name =fdt_get_name (blob, offset,NULL );if (ret == -ENOENT ) {continue ;drivers/core/device.c int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, · line 156
Quoted 4 lines
drivers/core/device.c +1
-0@@ -147,6 +153,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,dm_warn ("Error binding driver '%s'\n" , entry->name);return ret; }else { + dev->of_id = id;Instead of all the chages above, only one line change,
dev->of_id = entry->of_matchQuoted 7 lines
Quoted 3 lines
Does this work for you?
entry->of_matchis the first element in an array of records. I want to know exactly which one matches, so I can't just use the first one.Quoted 6 lines
Sorry, it was my misunderstanding.
Thanks for explaining this.Could you update the comment block of
driver_check_compatible?OK
Quoted 15 lines
/**
*driver_check_compatible()- Check if a driver is compatible with this node ** @param blob: Device tree pointer * @param offset: Offset of node in device tree * @param of_matchL List of compatible strings to match* @return 0 if there is a match,
-ENOENTif no match,-ENODEVif the node
* does not have a compatible string, other error <0 if there is a device
* tree error
*/
Quoted 4 lines
Quoted 2 lines
- Add description of "@param
of_idp"
- Fix "of_matchL" -> "of_match"Will fix.
Fixed these and:
Applied to u-boot-dm.
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
In reply to Simon GlassAdd dev_get_parent() as a convenience to obtain the parent of a device.
---
Changes in v2: None
drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ 2 files changed, 13 insertions(+)
drivers/core/device.c +5 -0
@@ -549,6 +549,11 @@ int device_find_next_child(struct udevice **devp)return 0 ; } +struct udevice *dev_get_parent (struct udevice *child) +{ +return child->parent; +} +ulong dev_get_of_data (struct udevice *dev) {return dev->of_id->data;
include/dm/device.h +8 -0
@@ -208,6 +208,14 @@ void *dev_get_parentdata(struct udevice *dev);void *dev_get_priv (struct udevice *dev);/** +* struct dev_get_parent() - Get the parent of a device +* +* @child: Child to check +* @return parent of child, or NULL if this is the root device +*/ +struct udevice *dev_get_parent (struct udevice *child); + +/** * dev_get_of_data() - get the device tree data used to bind a device * * When a device is bound using a device tree node, it matches a
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
Quoted 3 lines · Simon Glass
Add
dev_get_parent()as a convenience to obtain the parent of a device.Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/9180fbd5/attachment.pgp>
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
Add
dev_get_parent()as a convenience to obtain the parent of a device.Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ 2 files changed, 13 insertions(+)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
In reply to Simon GlassQuoted 16 lines · On Tue, 11 Nov 2014 10:46:19 -0700 Simon Glass <[email protected]> wrote:
Add
dev_get_parent()as a convenience to obtain the parent of a device.Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ 2 files changed, 13 insertions(+)drivers/core/device.c +0
-0
drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 556
Quoted 8 lines
drivers/core/device.c +5
-0@@ -549,6 +549,11 @@ int device_find_next_child(struct udevice **devp)return 0 ; } +struct udevice *dev_get_parent (struct udevice *child) +{ +return child->parent; +} +
Why do you want this? "dev_get_parent(dev)" is longer than "dev->parent".
I am not sure if this helper function is useful, but if really necessary, static inline or macro ??
Perhaps, "struct udevice *dev" rather than "struct udevice *child" for consistency?
Best Regards
Masahiro Yamada
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
Hi Masahiro,
Quoted 31 lines · Masahiro Yamada
Quoted 16 lines · On Tue, 11 Nov 2014 10:46:19 -0700 Simon Glass <[email protected]> wrote:
Add
dev_get_parent()as a convenience to obtain the parent of a device.Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ 2 files changed, 13 insertions(+)drivers/core/device.c +0
-0drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 556
Quoted 8 lines
drivers/core/device.c +5
-0@@ -549,6 +549,11 @@ int device_find_next_child(struct udevice **devp)return 0 ; } +struct udevice *dev_get_parent (struct udevice *child) +{ +return child->parent; +} +Why do you want this? "
dev_get_parent(dev)" is longer than "dev->parent".
Quoted 2 lines
I am not sure if this helper function is useful, but if really necessary, static inline or macro ??
See my comment on the other patch.
Quoted 4 lines
Perhaps, "struct udevice *dev" rather than "struct udevice *child" for consistency?
Maybe, but I feel this is clearer even if it is inconsistent. I try to use 'bus' instead of dev when there is a bus too, to help with understanding.
Regards,
Simon
PATCH v2 3/17 dm: core: Add functions to find parent and OF data
Quoted 44 lines · Simon Glass
Hi Masahiro,
Quoted 31 lines · Masahiro Yamada
Quoted 16 lines · On Tue, 11 Nov 2014 10:46:19 -0700 Simon Glass <[email protected]> wrote:
Add
dev_get_parent()as a convenience to obtain the parent of a device.Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ 2 files changed, 13 insertions(+)drivers/core/device.c +0
-0drivers/core/device.c int device_find_next_child(struct udevice **devp) · line 556
Quoted 8 lines
drivers/core/device.c +5
-0@@ -549,6 +549,11 @@ int device_find_next_child(struct udevice **devp)return 0 ; } +struct udevice *dev_get_parent (struct udevice *child) +{ +return child->parent; +} +Why do you want this? "
dev_get_parent(dev)" is longer than "dev->parent".Quoted 2 lines
I am not sure if this helper function is useful, but if really necessary, static inline or macro ??
See my comment on the other patch.
Quoted 4 lines
Perhaps, "struct udevice *dev" rather than "struct udevice *child" for consistency?
Quoted 6 lines
Maybe, but I feel this is clearer even if it is inconsistent. I try to use 'bus' instead of dev when there is a bus too, to help with understanding.
Regards,
Simon
Applied to u-boot-dm.
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
In reply to Simon GlassSince we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
---
Changes in v2:
- Add new patch to correct handling of aliases with embedded digits
lib/fdtdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
lib/fdtdec.c +3 -3
@@ -355,9 +355,9 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset, slash =strrchr (prop,'/' );if (strcmp (slash +1 , find_name))continue ; -for (p = name; *p; p++) { -if (isdigit (*p)) { - *seqp =simple_strtoul (p,NULL ,10 ); +for (p = name +strlen (name) -1 ; p > name; p--) { +if (!isdigit (*p)) { + *seqp =simple_strtoul (p +1 ,NULL ,10 );debug ("Found seq %d\n" , *seqp);return 0 ; }
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
Quoted 5 lines · Simon Glass
Since we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
Signed-off-by Simon Glass <[email protected]>
How about i2c10 ? I assume you see where I'm worried about here..
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/360cafca/attachment.pgp>
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
Hi Tom,
Quoted 10 lines · Tom Rini
Quoted 5 lines · Simon Glass
Since we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
Signed-off-by Simon Glass <[email protected]>How about i2c10 ? I assume you see where I'm worried about here..
It goes back to the first non-digit, so will produce 10 in this case as expected.
Regards,
Simon
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
Quoted 10 lines · Simon Glass
Hi Tom,
Quoted 7 lines · Tom Rini
Quoted 4 lines · Simon Glass
Since we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Simon Glass <[email protected]>How about i2c10 ? I assume you see where I'm worried about here..
It goes back to the first non-digit, so will produce 10 in this case as expected.
Oh good.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141117/d2ca9c0b/attachment.pgp>
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
Quoted 13 lines · Tom Rini
Quoted 12 lines · Simon Glass
Hi Tom,
Quoted 9 lines · Tom Rini
Quoted 5 lines · Simon Glass
Since we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
How about i2c10 ? I assume you see where I'm worried about here..
It goes back to the first non-digit, so will produce 10 in this case as expected.
Oh good.
Reviewed-by Tom Rini <[email protected]>
Applied to u-boot-dm.
PATCH v2 4/17 dm: fdt: Correct handling of aliases with embedded digits
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
Since we scan from left to right looking for the first digit, "i2c0" returns 2 instead of 0 for the alias number. Adjust the code to scan from right to left instead.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add new patch to correct handling of aliases with embedded digitslib/fdtdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 5/17 dm: Add a function to bind a device by driver name
In reply to Simon GlassIn some cases we need to manually bind a device to a particular driver. Add a function to do this.
---
Changes in v2:
- Add new patch to add a function to bind a device by driver name
drivers/core/lists.c | 21 +++++++++++++++++++++ include/dm/lists.h | 13 +++++++++++++ 2 files changed, 34 insertions(+)
drivers/core/lists.c +21 -0
@@ -77,6 +77,27 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)return result; } +int device_bind_driver (struct udevice *parent,const char *drv_name, +const char *dev_name,struct udevice **devp) +{ +struct driver *drv; +int ret; + + drv =lists_driver_lookup_name (drv_name); +if (!drv) { +printf ("Cannot find driver '%s'\n" , drv_name); +return -ENOENT ; + } + ret =device_bind (parent, drv, dev_name,NULL ,-1 , devp); +if (ret) { +printf ("Cannot create device named '%s' (err=%d)\n" , + dev_name, ret); +return ret; + } + +return 0 ; +} +#ifdef CONFIG_OF_CONTROL /** * driver_check_compatible() - Check if a driver is compatible with this node
include/dm/lists.h +13 -0
@@ -60,4 +60,17 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);int lists_bind_fdt (struct udevice *parent,const void *blob,int offset,struct udevice **devp); +/** +* device_bind_driver() - bind a device to a driver +* +* This binds a new device to a driver. +* +* @parent: Parent device +* @drv_name: Name of driver to attach to this parent +* @dev_name: Name of the new device thus created +* @devp: Returns the newly bound device +*/ +int device_bind_driver (struct udevice *parent,const char *drv_name, +const char *dev_name,struct udevice **devp); +#endif
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 5/17 dm: Add a function to bind a device by driver name
Quoted 70 lines · Simon Glass
In some cases we need to manually bind a device to a particular driver. Add a function to do this.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add new patch to add a function to bind a device by driver namedrivers/core/lists.c | 21 +++++++++++++++++++++ include/dm/lists.h | 13 +++++++++++++ 2 files changed, 34 insertions(+)drivers/core/lists.c +21
-0@@ -77,6 +77,27 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)return result; } +int device_bind_driver (struct udevice *parent,const char *drv_name, +const char *dev_name,struct udevice **devp) +{ +struct driver *drv; +int ret; + + drv =lists_driver_lookup_name (drv_name); +if (!drv) { +printf ("Cannot find driver '%s'\n" , drv_name); +return -ENOENT ; + } + ret =device_bind (parent, drv, dev_name,NULL ,-1 , devp); +if (ret) { +printf ("Cannot create device named '%s' (err=%d)\n" , + dev_name, ret); +return ret; + } + +return 0 ; +} +#ifdef CONFIG_OF_CONTROL /** * driver_check_compatible() - Check if a driver is compatible with this node include/dm/lists.h +13
-1@@ -60,4 +60,17 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);int lists_bind_fdt (struct udevice *parent,const void *blob,int offset,struct udevice **devp); +/** +* device_bind_driver() - bind a device to a driver +* +* This binds a new device to a driver. +* +* @parent: Parent device +* @drv_name: Name of driver to attach to this parent +* @dev_name: Name of the new device thus created +* @devp: Returns the newly bound device +*/ +int device_bind_driver (struct udevice *parent,const char *drv_name, +const char *dev_name,struct udevice **devp); +#endif --2.1.0.rc2.206.gedb03e5
Quoted 4 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
thanks!
Signature · 1 line
Jagan.
PATCH v2 5/17 dm: Add a function to bind a device by driver name
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
In some cases we need to manually bind a device to a particular driver. Add a function to do this.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
---
Changes in v2:
- Add new patch to add a function to bind a device by driver namedrivers/core/lists.c | 21 +++++++++++++++++++++ include/dm/lists.h | 13 +++++++++++++ 2 files changed, 34 insertions(+)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 5/17 dm: Add a function to bind a device by driver name
Quoted 13 lines · Heiko Schocher
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
In some cases we need to manually bind a device to a particular driver. Add a function to do this.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add new patch to add a function to bind a device by driver name
Quoted 6 lines
Quoted 3 lines
drivers/core/lists.c | 21 +++++++++++++++++++++ include/dm/lists.h | 13 +++++++++++++ 2 files changed, 34 insertions(+)Acked-by Heiko Schocher <[email protected]>
Applied to u-boot-dm.
PATCH v2 6/17 dm: spi: Correct handling of SPI chip selects in sandbox
In reply to Simon GlassThis code was not updated when the chip select handling was adjusted. Fix it to call the correct function.
---
Changes in v2: None
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 11 +---------- include/spi.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-)
drivers/mtd/spi/sandbox.c +1 -1
@@ -602,7 +602,7 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum, spec, ret);return ret; } - ret =device_find_child_by_seq (bus, cs, true, &slave); + ret =spi_find_chip_select (bus, cs, &slave);if (!ret) {printf ("Chip select %d already exists for spec '%s'\n" , cs, spec);
drivers/spi/spi-uclass.c +1 -10
@@ -115,16 +115,7 @@ int spi_chip_select(struct udevice *dev)return slave ? slave->cs : -ENOENT ; } -/** -* spi_find_chip_select() - Find the slave attached to chip select -* -* @bus: SPI bus to search -* @cs: Chip select to look for -* @devp: Returns the slave device if found -* @return 0 if found, -ENODEV on error -*/ -static int spi_find_chip_select (struct udevice *bus,int cs, -struct udevice **devp) +int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp) {struct udevice *dev;
include/spi.h +10 -0
@@ -534,6 +534,16 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,int spi_chip_select (struct udevice *slave);/** +* spi_find_chip_select() - Find the slave attached to chip select +* +* @bus: SPI bus to search +* @cs: Chip select to look for +* @devp: Returns the slave device if found +* @return 0 if found, -ENODEV on error +*/ +int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp); + +/** * spi_bind_device() - bind a device to a bus's chip select * * This binds a new device to an given chip select (which must be unused).
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 6/17 dm: spi: Correct handling of SPI chip selects in sandbox
Quoted 70 lines · Simon Glass
This code was not updated when the chip select handling was adjusted. Fix it to call the correct function.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 11 +---------- include/spi.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-)drivers/mtd/spi/sandbox.c +1
-1@@ -602,7 +602,7 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum, spec, ret);return ret; } - ret =device_find_child_by_seq (bus, cs, true, &slave); + ret =spi_find_chip_select (bus, cs, &slave);if (!ret) {printf ("Chip select %d already exists for spec '%s'\n" , cs, spec);drivers/spi/spi-uclass.c +1
-10@@ -115,16 +115,7 @@ int spi_chip_select(struct udevice *dev)return slave ? slave->cs : -ENOENT ; } -/** -* spi_find_chip_select() - Find the slave attached to chip select -* -* @bus: SPI bus to search -* @cs: Chip select to look for -* @devp: Returns the slave device if found -* @return 0 if found, -ENODEV on error -*/ -static int spi_find_chip_select (struct udevice *bus,int cs, -struct udevice **devp) +int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp) {struct udevice *dev;include/spi.h +10
-1@@ -534,6 +534,16 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,int spi_chip_select (struct udevice *slave);/** +* spi_find_chip_select() - Find the slave attached to chip select +* +* @bus: SPI bus to search +* @cs: Chip select to look for +* @devp: Returns the slave device if found +* @return 0 if found, -ENODEV on error +*/ +int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp); + +/** * spi_bind_device() - bind a device to a bus's chip select * * This binds a new device to an given chip select (which must be unused). --
Quoted 2 lines
2.1.0.rc2.206.gedb03e5
thanks!
Signature · 1 line
Jagan.
PATCH v2 6/17 dm: spi: Correct handling of SPI chip selects in sandbox
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
This code was not updated when the chip select handling was adjusted. Fix it to call the correct function.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
---
Changes in v2: None
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 11 +---------- include/spi.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 6/17 dm: spi: Correct handling of SPI chip selects in sandbox
Quoted 12 lines · Heiko Schocher
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 9 lines
This code was not updated when the chip select handling was adjusted. Fix it to call the correct function.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
Quoted 7 lines
Quoted 4 lines
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 11 +---------- include/spi.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-)Acked-by Heiko Schocher <[email protected]>
Applied to u-boot-dm.
PATCH v2 7/17 dm: spi: Use device_bind_driver() instead of our own function
In reply to Simon GlassThe SPI function does the same thing, so we may as well just use the new generic function. The 'cs' parameter was not actually used, so can be dropped.
---
Changes in v2:
- Add new patches to adjust SPI to use device_bind_driver()
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 23 +---------------------- include/spi.h | 14 -------------- 3 files changed, 2 insertions(+), 37 deletions(-)
drivers/mtd/spi/sandbox.c +1 -1
@@ -609,7 +609,7 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum,return -EEXIST ; } - ret =spi_bind_device (bus, cs,"spi_flash_std" , spec, &slave); + ret =device_bind_driver (bus,"spi_flash_std" , spec, &slave);if (ret)return ret;
drivers/spi/spi-uclass.c +1 -22
@@ -188,27 +188,6 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)return -ENODEV ; } -int spi_bind_device (struct udevice *bus,int cs,const char *drv_name, -const char *dev_name,struct udevice **devp) -{ -struct driver *drv; -int ret; - - drv =lists_driver_lookup_name (drv_name); -if (!drv) { -printf ("Cannot find driver '%s'\n" , drv_name); -return -ENOENT ; - } - ret =device_bind (bus, drv, dev_name,NULL ,-1 , devp); -if (ret) { -printf ("Cannot create device named '%s' (err=%d)\n" , - dev_name, ret); -return ret; - } - -return 0 ; -} -int spi_find_bus_and_cs (int busnum,int cs,struct udevice **busp,struct udevice **devp) {
@@ -255,7 +234,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,if (ret == -ENODEV && drv_name) {debug ("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n" , __func__, dev_name, busnum, cs, drv_name); - ret =spi_bind_device (bus, cs, drv_name, dev_name, &dev); + ret =device_bind_driver (bus, drv_name, dev_name, &dev);if (ret)return ret; created = true;
include/spi.h +0 -14
@@ -544,20 +544,6 @@ int spi_chip_select(struct udevice *slave);int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp);/** -* spi_bind_device() - bind a device to a bus's chip select -* -* This binds a new device to an given chip select (which must be unused). -* -* @bus: SPI bus to search -* @cs: Chip select to attach to -* @drv_name: Name of driver to attach to this chip select -* @dev_name: Name of the new device thus created -* @devp: Returns the newly bound device -*/ -int spi_bind_device (struct udevice *bus,int cs,const char *drv_name, -const char *dev_name,struct udevice **devp); - -/** * spi_ofdata_to_platdata() - decode standard SPI platform data * * This decodes the speed and mode from a device tree node and puts it into
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 7/17 dm: spi: Use device_bind_driver() instead of our own function
Quoted 95 lines · Simon Glass
The SPI function does the same thing, so we may as well just use the new generic function. The 'cs' parameter was not actually used, so can be dropped.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add new patches to adjust SPI to usedevice_bind_driver()drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 23 +---------------------- include/spi.h | 14 -------------- 3 files changed, 2 insertions(+), 37 deletions(-)drivers/mtd/spi/sandbox.c +1
-1@@ -609,7 +609,7 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum,return -EEXIST ; } - ret =spi_bind_device (bus, cs,"spi_flash_std" , spec, &slave); + ret =device_bind_driver (bus,"spi_flash_std" , spec, &slave);if (ret)return ret;drivers/spi/spi-uclass.c +1
-22@@ -188,27 +188,6 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)return -ENODEV ; } -int spi_bind_device (struct udevice *bus,int cs,const char *drv_name, -const char *dev_name,struct udevice **devp) -{ -struct driver *drv; -int ret; - - drv =lists_driver_lookup_name (drv_name); -if (!drv) { -printf ("Cannot find driver '%s'\n" , drv_name); -return -ENOENT ; - } - ret =device_bind (bus, drv, dev_name,NULL ,-1 , devp); -if (ret) { -printf ("Cannot create device named '%s' (err=%d)\n" , - dev_name, ret); -return ret; - } - -return 0 ; -} -int spi_find_bus_and_cs (int busnum,int cs,struct udevice **busp,struct udevice **devp) {@@ -255,7 +234,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,if (ret == -ENODEV && drv_name) {debug ("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n" , __func__, dev_name, busnum, cs, drv_name); - ret =spi_bind_device (bus, cs, drv_name, dev_name, &dev); + ret =device_bind_driver (bus, drv_name, dev_name, &dev);if (ret)return ret; created = true;include/spi.h +0
-15@@ -544,20 +544,6 @@ int spi_chip_select(struct udevice *slave);int spi_find_chip_select (struct udevice *bus,int cs,struct udevice **devp);/** -* spi_bind_device() - bind a device to a bus's chip select -* -* This binds a new device to an given chip select (which must be unused). -* -* @bus: SPI bus to search -* @cs: Chip select to attach to -* @drv_name: Name of driver to attach to this chip select -* @dev_name: Name of the new device thus created -* @devp: Returns the newly bound device -*/ -int spi_bind_device (struct udevice *bus,int cs,const char *drv_name, -const char *dev_name,struct udevice **devp); - -/** * spi_ofdata_to_platdata() - decode standard SPI platform data * * This decodes the speed and mode from a device tree node and puts it into --
Quoted 2 lines
2.1.0.rc2.206.gedb03e5
thanks!
Signature · 1 line
Jagan.
PATCH v2 7/17 dm: spi: Use device_bind_driver() instead of our own function
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 7 lines
The SPI function does the same thing, so we may as well just use the new generic function. The 'cs' parameter was not actually used, so can be dropped.
Signed-off-by Simon Glass <[email protected]>---
Quoted 7 lines
Changes in v2:
- Add new patches to adjust SPI to usedevice_bind_driver()drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 23 +---------------------- include/spi.h | 14 -------------- 3 files changed, 2 insertions(+), 37 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 7/17 dm: spi: Use device_bind_driver() instead of our own function
Quoted 14 lines · Heiko Schocher
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 11 lines
The SPI function does the same thing, so we may as well just use the new generic function. The 'cs' parameter was not actually used, so can be dropped.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add new patches to adjust SPI to usedevice_bind_driver()
Quoted 7 lines
Quoted 4 lines
drivers/mtd/spi/sandbox.c | 2 +- drivers/spi/spi-uclass.c | 23 +---------------------- include/spi.h | 14 -------------- 3 files changed, 2 insertions(+), 37 deletions(-)Acked-by Heiko Schocher <[email protected]>
Applied to u-boot-dm.
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Simon GlassThe uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functions
---
Changes in v2:
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device from i2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
drivers/i2c/Makefile | 1 + drivers/i2c/i2c-uclass.c | 275 +++++++++++++++++++++++++++++++++++++++++++ include/config_fallbacks.h | 6 + include/dm/uclass-id.h | 2 + include/i2c.h | 288 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 572 insertions(+) create mode 100644 drivers/i2c/i2c-uclass.c
drivers/i2c/Makefile +1 -0
@@ -4,6 +4,7 @@ # # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DM_I2C) += i2c-uclass.o obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o
drivers/i2c/i2c-uclass.c new file +275 -0
275 lines not on this page · raw message
include/config_fallbacks.h +6 -0
@@ -87,4 +87,10 @@#undef CONFIG_IMAGE_FORMAT_LEGACY#endif +#ifdef CONFIG_DM_I2C +# ifdef CONFIG_SYS_I2C +# error "Cannot define CONFIG_SYS_I2C when CONFIG_DM_I2C is used" +# endif +#endif +#endif /* __CONFIG_FALLBACKS_H */
include/dm/uclass-id.h +2 -0
@@ -28,6 +28,8 @@ enum uclass_id {UCLASS_SPI_GENERIC ,/* Generic SPI flash target */ UCLASS_SPI_FLASH ,/* SPI flash */ UCLASS_CROS_EC ,/* Chrome OS EC */ +UCLASS_I2C ,/* I2C bus */ +UCLASS_I2C_GENERIC ,/* Generic I2C device */ UCLASS_COUNT , UCLASS_INVALID = -1,
include/i2c.h +288 -0
298 lines not on this page · raw message
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Quoted 9 lines · Simon Glass
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/52510c77/attachment.pgp>
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 20 lines
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>---
Changes in v2:
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device fromi2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
Quoted 7 lines
drivers/i2c/Makefile | 1 + drivers/i2c/i2c-uclass.c | 275 +++++++++++++++++++++++++++++++++++++++++++ include/config_fallbacks.h | 6 + include/dm/uclass-id.h | 2 + include/i2c.h | 288 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 572 insertions(+)create mode 100644
drivers/i2c/i2c-uclass.c
Thanks for your work.
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Simon GlassHi Simon,
Quoted 12 lines · On Tue, 11 Nov 2014 10:46:24 -0700 Simon Glass <[email protected]> wrote:
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>---
drivers/i2c/i2c-uclass.c line 251
Quoted 9 lines
drivers/i2c/i2c-uclass.c new file +9
-0+static int i2c_post_probe (struct udevice *dev) +{ +struct dm_i2c_bus *i2c = dev->uclass_priv; + + i2c->speed_hz =fdtdec_get_int (gd->fdt_blob, dev->of_offset, +"clock-frequency" ,100000 ); + +return i2c_set_bus_speed (dev, i2c->speed_hz); +}
This code in drivers/i2c/i2c-uclass.c seems to highly depends on Device Tree.
I am not sure if I understood correctly, but
does this work on non Device Tree SoCs?
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hello Masahiro,
Am 18.11.2014 13:32, schrieb Masahiro Yamada:
Quoted 30 lines
Hi Simon,
Quoted 12 lines · On Tue, 11 Nov 2014 10:46:24 -0700 Simon Glass <[email protected]> wrote:
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>---
drivers/i2c/i2c-uclass.c line 251
Quoted 9 lines
drivers/i2c/i2c-uclass.c new file +9
-0+static int i2c_post_probe (struct udevice *dev) +{ +struct dm_i2c_bus *i2c = dev->uclass_priv; + + i2c->speed_hz =fdtdec_get_int (gd->fdt_blob, dev->of_offset, +"clock-frequency" ,100000 ); + +return i2c_set_bus_speed (dev, i2c->speed_hz); +}This code in
drivers/i2c/i2c-uclass.cseems to highly depends on Device Tree.
Quoted 2 lines
I am not sure if I understood correctly, but
does this work on non Device Tree SoCs?
No. Devie Model is currently (as I understand) useable with Device Tree ...
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Simon GlassHi Simon,
Quoted 19 lines · On Tue, 11 Nov 2014 10:46:24 -0700 Simon Glass <[email protected]> wrote:
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>---
Changes in v2:
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device fromi2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
[snip]
Quoted 16 lines
drivers/i2c/i2c-uclass.c new file +16
-0+ +int i2c_read (struct udevice *dev,uint addr,uint8_t *buffer,int len) +{ +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct udevice *bus =dev_get_parent (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); + +if (!ops->read) +return -ENOSYS ; + +return ops->read (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len); +} + +int i2c_write (struct udevice *dev,uint addr,const uint8_t *buffer,int len) +{
drivers/i2c/i2c-uclass.c line 43
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct udevice *bus =dev_get_parent (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); + +if (!ops->write) +return -ENOSYS ; + +return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len); +}
This seems inconsistent with "struct dm_i2c_ops".
In this function, the address length(chip->addr_len) is passed to the forth argument of ops->write().
You should compare it with "struct dm_i2c_ops" in include/i2c.h It says that the third argument is alen.
BTW, address_offset within the chip and data are treated in the same way in I2C bus. Should we pass them separately to each driver?
I mean, can we put the offset address and data in the buffer?
Quoted 16 lines
drivers/i2c/i2c-uclass.c new file +16
-0+ +int i2c_get_chip (struct udevice *bus,uint chip_addr,struct udevice **devp) +{ +struct udevice *dev; + +debug ("%s: Searching bus '%s' for address %02x: " , __func__, + bus->name, chip_addr); +for (device_find_first_child (bus, &dev); dev; +device_find_next_child (&dev)) { +struct dm_i2c_chip store; +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +int ret; + +if (!chip) { + chip = &store; + i2c_chip_ofdata_to_platdata(gd->fdt_blob,
drivers/i2c/i2c-uclass.c line 109
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+ dev->of_offset, chip); + } +if (chip->chip_addr == chip_addr) { + ret =device_probe (dev); +debug ("found, ret=%d\n" , ret); +if (ret) +return ret; + *devp = dev; +return 0 ; + }
If "chip" is "NULL", i2c_chip_ofdata_to_platdata() is called to create struct dm_i2c_chip, but it is not thrown away soon. It is not efficient.
If we use device_probe_child() instead of device_probe(), I think we can re-use it.
I mean,
if (chip->chip_addr == chip_addr) {
ret = device_probe_child(dev, chip);Perhaps, we can remove sandbox_i2c_child_pre_probe().
drivers/i2c/i2c-uclass.c line 113
Quoted 4 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}
If no chip-device is found at the specified chip_addr, the last line calls i2c_bind_driver(). Why?
The i2c_bind_driver() tries to create a "generic" chip. What is this "generic" chip?
Besides, i2c_bind_driver() tries to probe the created generic chip, but it always fails in i2c_chip_ofdata_to_platdata() because the generic chip does not have "reg" property
I could not understand at all what this code wants to do.
Quoted 7 lines
drivers/i2c/i2c-uclass.c new file +7
-0+} + +int i2c_probe (struct udevice *bus,uint chip_addr,struct udevice **devp) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +int ret; +
drivers/i2c/i2c-uclass.c line 149
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+ *devp =NULL ; +if (!ops->probe) +return -ENODEV ; + +/* First probe that chip */ + ret = ops->probe (bus, chip_addr); +debug ("%s: bus='%s', address %02x, ret=%d\n" , __func__, bus->name, + chip_addr, ret); +if (ret) +return ret;
Is the "ops->probe" responsible to probe child devices? (At least, sandbox_i2c probes its children)
drivers/i2c/i2c-uclass.c line 158
Quoted 8 lines
drivers/i2c/i2c-uclass.c new file +8
-0+/* The chip was found, see if we have a driver, and probe it */ + ret =i2c_get_chip (bus, chip_addr, devp); +debug ("%s: i2c_get_chip: ret=%d\n" , __func__, ret); +if (!ret || ret != -ENODEV ) +return ret; + +return i2c_bind_driver (bus, chip_addr, devp); +}
If so, why do we need to call i2c_get_chip() and probe it again?
Quoted 40 lines
drivers/i2c/i2c-uclass.c new file +40
-0+int i2c_set_bus_speed (struct udevice *bus,unsigned int speed) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +struct dm_i2c_bus *i2c = bus->uclass_priv; +int ret; + +if (ops->set_bus_speed) { + ret = ops->set_bus_speed (bus, speed); +if (ret) +return ret; + } + i2c->speed_hz = speed; + +return 0 ; +} + +/* +* i2c_get_bus_speed: +* +* Returns speed of selected I2C bus in Hz +*/ +int i2c_get_bus_speed (struct udevice *bus) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +struct dm_i2c_bus *i2c = bus->uclass_priv; + +if (!ops->set_bus_speed) +return i2c->speed_hz; + +return ops->get_bus_speed (bus); +} + +int i2c_set_addr_len (struct udevice *dev,uint addr_len) +{ +struct udevice *bus = dev->parent; +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); +int ret; + +if (addr_len >3 )
drivers/i2c/i2c-uclass.c line 209
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+return -EINVAL ; +if (ops->set_addr_len) { + ret = ops->set_addr_len (dev, addr_len); +if (ret) +return ret; + } + chip->addr_len = addr_len; + +return 0 ; +}
I am not 100% sure, but "addr_len" is a user-configurable parameter?
I think each device has its own fixed address size.
drivers/i2c/i2c-uclass.c line 275
Quoted 9 lines
drivers/i2c/i2c-uclass.c new file +9
-0+UCLASS_DRIVER (i2c_generic) = { + .id =UCLASS_I2C_GENERIC , + .name ="i2c_generic" , +}; + +U_BOOT_DRIVER (i2c_generic_drv) = { + .name ="i2c_generic_drv" , + .id =UCLASS_I2C_GENERIC , +};
Could you explain how "i2c_generic" is used.
Quoted 26 lines
include/i2c.h +26
-0+ +/** +* struct dm_i2c_ops - driver operations for I2C uclass +* +* Drivers should support these operations unless otherwise noted. These +* operations are intended to be used by uclass code, not directly from +* other code. +*/ +struct dm_i2c_ops { +/** +* read() - read from a chip +* +* @bus: Bus to read from +* @chip_addr: Chip address to read from +* @alen: Length of chip address in bytes +* @offset: Offset within chip to start reading +* @buffer: Place to put data +* @len: Number of bytes to read +*/ +int (*read)(struct udevice *bus,uint chip_addr,uint alen, +uint offset,uint8_t *buffer,int len); + +/** +* write() - write bytes to a chip +* +* @dev: Device to write to
include/i2c.h line 190
Quoted 10 lines
include/i2c.h +10
-0+* @chip_addr: Chip address to read from +* @alen: Length of chip address in bytes +* @offset: Offset within chip to start writing +* @buffer: Buffer containing data to write +* @len: Number of bytes to write +* +* @return 0 on success, -ve on failure +*/ +int (*write)(struct udevice *bus,uint chip_addr,uint alen, +uint offset,const uint8_t *buffer,int len);
See. The third argument is address length.
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hi Simon,
Let me correct my question.
(I should have read my mail three times before sending.)
Quoted 24 lines · On Wed, 19 Nov 2014 17:56:34 +0900 Masahiro Yamada <[email protected]>…
Quoted 24 lines
drivers/i2c/i2c-uclass.c new file +22
-0+ +int i2c_get_chip (struct udevice *bus,uint chip_addr,struct udevice **devp) +{ +struct udevice *dev; + +debug ("%s: Searching bus '%s' for address %02x: " , __func__, + bus->name, chip_addr); +for (device_find_first_child (bus, &dev); dev; +device_find_next_child (&dev)) { +struct dm_i2c_chip store; +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +int ret; + +if (!chip) { + chip = &store; +i2c_chip_ofdata_to_platdata (gd->fdt_blob, + dev->of_offset, chip); + } +if (chip->chip_addr == chip_addr) { + ret =device_probe (dev); +debug ("found, ret=%d\n" , ret); +if (ret)
Quoted 8 lines
drivers/i2c/i2c-uclass.c line 109
Quoted 4 lines
drivers/i2c/i2c-uclass.c new file +4
-0+return ret; + *devp = dev; +return 0 ; + }If "chip" is "NULL",
i2c_chip_ofdata_to_platdata()is called to create structdm_i2c_chip, but it is not thrown away soon. It is not efficient.
I mean:
but it *is* thrown away soon.
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Masahiro YamadaHi Masahiro,
Quoted 57 lines · Masahiro Yamada
Hi Simon,
Quoted 19 lines · On Tue, 11 Nov 2014 10:46:24 -0700 Simon Glass <[email protected]> wrote:
The uclass implements the same operations as the current I2C framework but makes some changes to make it fit driver model better:
- Remove the chip address from API calls
- Remove the address length from API calls
- Remove concept of 'current' I2C bus
- Drop all existing init functionsSigned-off-by Simon Glass <[email protected]>---
Changes in v2:
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device fromi2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number[snip]
Quoted 16 lines
drivers/i2c/i2c-uclass.c new file +16
-0+ +int i2c_read (struct udevice *dev,uint addr,uint8_t *buffer,int len) +{ +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct udevice *bus =dev_get_parent (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); + +if (!ops->read) +return -ENOSYS ; + +return ops->read (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len); +} + +int i2c_write (struct udevice *dev,uint addr,const uint8_t *buffer,int len) +{drivers/i2c/i2c-uclass.c line 43
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct udevice *bus =dev_get_parent (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); + +if (!ops->write) +return -ENOSYS ; + +return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len); +}This seems inconsistent with "struct
dm_i2c_ops".
In this function, the addresslength(chip->addr_len)is passed to the forth argument ofops->write().
Quoted 2 lines
You should compare it with "struct
dm_i2c_ops" ininclude/i2c.hIt says that the third argument is alen.
Oh dear that's going to be very very confusing. I'll tidy this up.
Quoted 9 lines
BTW,
address_offsetwithin the chip and data are treated in the same way in I2C bus. Should we pass them separately to each driver?I mean, can we put the offset address and data in the buffer?
I'm not sure what you mean by this sorry.
Quoted 37 lines
Quoted 19 lines
drivers/i2c/i2c-uclass.c new file +16
-0+ +int i2c_get_chip (struct udevice *bus,uint chip_addr,struct udevice **devp) +{ +struct udevice *dev; + +debug ("%s: Searching bus '%s' for address %02x: " , __func__, + bus->name, chip_addr); +for (device_find_first_child (bus, &dev); dev; +device_find_next_child (&dev)) { +struct dm_i2c_chip store; +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +int ret; + +if (!chip) { + chip = &store; + i2c_chip_ofdata_to_platdata(gd->fdt_blob,drivers/i2c/i2c-uclass.c line 109
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+ dev->of_offset, chip); + } +if (chip->chip_addr == chip_addr) { + ret =device_probe (dev); +debug ("found, ret=%d\n" , ret); +if (ret) +return ret; + *devp = dev; +return 0 ; + }If "chip" is "NULL",
i2c_chip_ofdata_to_platdata()is called to create structdm_i2c_chip, but it is not thrown away soon. It is not efficient.If we use
device_probe_child()instead ofdevice_probe(), I think we can re-use it.
Quoted 9 lines
I mean,
if (chip->chip_addr == chip_addr) { ret = device_probe_child(dev, chip);Perhaps, we can remove
sandbox_i2c_child_pre_probe().
Yes that sounds good but the only catch is that i2c drivers may want to have extra information over and above struct dm_i2c_chip.
I'm not terribly happy with how this works (SPI is the same). We are peeking to see the address of a device, then throwing that information away.
For PCI (which I was looking at on a recent flight) it really can't be made to work - in that case devices are configured before they are probed, and it's really helpful to figure out the bus addresses at 'bind' time. So I'm looking at introducing a per-child platdata structure. In that case we wouldn't need to throw the information away, and better, it puts the driver back in control of this decoding.
Quoted 13 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 7 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?
Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple read() and write() only.
Quoted 19 lines
Quoted 19 lines
drivers/i2c/i2c-uclass.c new file +13
-0+} + +int i2c_probe (struct udevice *bus,uint chip_addr,struct udevice **devp) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +int ret; + + *devp =NULL ; +if (!ops->probe) +return -ENODEV ; + +/* First probe that chip */ + ret = ops->probe (bus, chip_addr);
Quoted 8 lines
drivers/i2c/i2c-uclass.c line 149
Quoted 4 lines
drivers/i2c/i2c-uclass.c new file +4
-0+debug ("%s: bus='%s', address %02x, ret=%d\n" , __func__, bus->name, + chip_addr, ret); +if (ret) +return ret;Is the "
ops->probe" responsible to probe child devices? (At least,sandbox_i2cprobes its children)
Yes this is the probe operation, where we ping that address on the bus and see if there is anything there on the bus.
Quoted 16 lines
drivers/i2c/i2c-uclass.c line 158
Quoted 11 lines
drivers/i2c/i2c-uclass.c new file +8
-0+/* The chip was found, see if we have a driver, and probe it */ + ret =i2c_get_chip (bus, chip_addr, devp); +debug ("%s: i2c_get_chip: ret=%d\n" , __func__, ret); +if (!ret || ret != -ENODEV ) +return ret; + +return i2c_bind_driver (bus, chip_addr, devp); +}If so, why do we need to call
i2c_get_chip()and probe it again?
The bus drivers must bind their children. So this function checks if there is a chip at that address and then binds it to the correct driver.
But you are right there is an extra call to i2c_bind_driver(). It won't do anything useful - just return the same error as the first try. I'll remove it.
Quoted 58 lines
Quoted 44 lines
drivers/i2c/i2c-uclass.c new file +40
-0+int i2c_set_bus_speed (struct udevice *bus,unsigned int speed) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +struct dm_i2c_bus *i2c = bus->uclass_priv; +int ret; + +if (ops->set_bus_speed) { + ret = ops->set_bus_speed (bus, speed); +if (ret) +return ret; + } + i2c->speed_hz = speed; + +return 0 ; +} + +/* +* i2c_get_bus_speed: +* +* Returns speed of selected I2C bus in Hz +*/ +int i2c_get_bus_speed (struct udevice *bus) +{ +struct dm_i2c_ops *ops =i2c_get_ops (bus); +struct dm_i2c_bus *i2c = bus->uclass_priv; + +if (!ops->set_bus_speed) +return i2c->speed_hz; + +return ops->get_bus_speed (bus); +} + +int i2c_set_addr_len (struct udevice *dev,uint addr_len) +{ +struct udevice *bus = dev->parent; +struct dm_i2c_chip *chip =dev_get_parentdata (dev); +struct dm_i2c_ops *ops =i2c_get_ops (bus); +int ret; + +if (addr_len >3 )drivers/i2c/i2c-uclass.c line 209
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +10
-0+return -EINVAL ; +if (ops->set_addr_len) { + ret = ops->set_addr_len (dev, addr_len); +if (ret) +return ret; + } + chip->addr_len = addr_len; + +return 0 ; +}I am not 100% sure, but "
addr_len" is a user-configurable parameter?
Quoted 2 lines
I think each device has its own fixed address size.
At the moment only 1 byte (i.e. 7 bits) is supported by the configuration - you need to call i2c_set_addr_len() to change it.
Quoted 11 lines
Quoted 13 lines
drivers/i2c/i2c-uclass.c line 275
Quoted 9 lines
drivers/i2c/i2c-uclass.c new file +9
-0+UCLASS_DRIVER (i2c_generic) = { + .id =UCLASS_I2C_GENERIC , + .name ="i2c_generic" , +}; + +U_BOOT_DRIVER (i2c_generic_drv) = { + .name ="i2c_generic_drv" , + .id =UCLASS_I2C_GENERIC , +};Could you explain how "
i2c_generic" is used.
Explained above.
Quoted 33 lines
Quoted 33 lines
include/i2c.h +31
-0+ +/** +* struct dm_i2c_ops - driver operations for I2C uclass +* +* Drivers should support these operations unless otherwise noted. These +* operations are intended to be used by uclass code, not directly from +* other code. +*/ +struct dm_i2c_ops { +/** +* read() - read from a chip +* +* @bus: Bus to read from +* @chip_addr: Chip address to read from +* @alen: Length of chip address in bytes +* @offset: Offset within chip to start reading +* @buffer: Place to put data +* @len: Number of bytes to read +*/ +int (*read)(struct udevice *bus,uint chip_addr,uint alen, +uint offset,uint8_t *buffer,int len); + +/** +* write() - write bytes to a chip +* +* @dev: Device to write to +* @chip_addr: Chip address to read from +* @alen: Length of chip address in bytes +* @offset: Offset within chip to start writing +* @buffer: Buffer containing data to write +* @len: Number of bytes to write
Quoted 8 lines
include/i2c.h line 190
Quoted 5 lines
include/i2c.h +5
-0+* +* @return 0 on success, -ve on failure +*/ +int (*write)(struct udevice *bus,uint chip_addr,uint alen, +uint offset,const uint8_t *buffer,int len);See. The third argument is address length.
Yes, very confusing! Will fix the order.
Thanks for the close review.
Regards,
Simon
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hi Simon,
Quoted 10 lines · On Wed, 19 Nov 2014 10:24:47 +0000 Simon Glass <[email protected]> wrote:
Quoted 8 lines
BTW,
address_offsetwithin the chip and data are treated in the same way in I2C bus. Should we pass them separately to each driver?I mean, can we put the offset address and data in the buffer?
I'm not sure what you mean by this sorry.
Let's assume we want to write some data to a EEPROM chip connected to i2c bus.
We generally send
[byte 0] SLAVE_ADDR (7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start writing [byte 2] WData0
[byte 3] WData1
...
From the perspective of I2C protocol, [byte 1], [byte 2], [byte 3], ... are all data.
I2C itself deos not (should not) know which byte is the offset_address in the chip and which is the *real* data to be written.
Quoted 2 lines
Quoted 2 lines
drivers/i2c/i2c-uclass.c line 42
Quoted 2 lines
drivers/i2c/i2c-uclass.c new file +2
-0+return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len);
In this implementation, the offset_address is treated with "addr" and the *real* data is handled with "buffer".
It seems odd from the perspective of I2C protocol, I think.
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0] SLAVE_ADDR (7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2] SLAVE_ADDR (7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Quoted 23 lines
Quoted 14 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 8 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
Quoted 8 lines
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple
read()andwrite()only.
Sorry, I could not parse you here.
I2C is not a hot-plugged bus.
I could not understand why such a dummy device is created on run time. Is it related to 'erase' or 'lock' functions?
BTW, sandbox_i2c_read() is 400KHz tolerate:
/* For testing, don't allow reading above 400KHz */ if (i2c->speed_hz > 400000 || alen != 1) return -EINVAL;
but sandbox_i2c_write() only allows 100KHz:
/* For testing, don't allow writing above 100KHz */ if (i2c->speed_hz > 100000 || alen != 1) return -EINVAL;
Because the clock-frequency is set to <400000> in the sandbox DTS, writing to I2C fails unless we change the I2C speed.
Is this intentional?
Personally, I like everthing to work on the mail line.
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
+ A few more people to cc
Hi Masahiro,
Quoted 58 lines · Masahiro Yamada
Hi Simon,
Quoted 10 lines · On Wed, 19 Nov 2014 10:24:47 +0000 Simon Glass <[email protected]> wrote:
Quoted 8 lines
BTW,
address_offsetwithin the chip and data are treated in the same way in I2C bus. Should we pass them separately to each driver?I mean, can we put the offset address and data in the buffer?
I'm not sure what you mean by this sorry.
Let's assume we want to write some data to a EEPROM chip connected to i2c bus.
We generally send
[byte 0]
SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start writing [byte 2] WData0
[byte 3] WData1
...From the perspective of I2C protocol, [byte 1], [byte 2], [byte 3], ... are all data.
I2C itself deos not (should not) know which byte is the
offset_addressin the chip and which is the *real* data to be written.Quoted 2 lines
Quoted 2 lines
drivers/i2c/i2c-uclass.c line 42
Quoted 2 lines
drivers/i2c/i2c-uclass.c new file +2
-0+return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len);In this implementation, the
offset_addressis treated with "addr" and the *real* data is handled with "buffer".It seems odd from the perspective of I2C protocol, I think.
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1
Quoted 6 lines
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
We could certainly change this. I'm not sure that I have a strong opinion either way.
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).
If we want to change it, we should do it now. My question is, what is the point? Will we really want >2 elements in the message array, do we want more control over how transactions are done (repeated start, etc.)? I'm not sure. Still it would be a fairly low-impact change I feel. We are changing the drivers anyway, so changing the uclass-to-driver API would be feasible. One advantage perhaps it that it would match Linux more closely.
Perhaps Heiko can share an opinion here?
Quoted 35 lines
Quoted 25 lines
Quoted 16 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
Quoted 8 lines
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple
read()andwrite()only.
Quoted 6 lines
Sorry, I could not parse you here.
I2C is not a hot-plugged bus.
I could not understand why such a dummy device is created on run time. Is it related to 'erase' or 'lock' functions?
If we cannot write to the chip (i.e. it does not ACK when we send it its address) then we won't be able to talk to it, so there is no point in creating a device.
With driver model / device tree we could just blindly add the device and use it, but I chose to duplicate the current behaviour since this is expected.
Quoted 25 lines
BTW,
sandbox_i2c_read()is 400KHz tolerate:/* For testing, don't allow reading above 400KHz */ if (i2c->speed_hz > 400000 || alen != 1) return -EINVAL;but
sandbox_i2c_write()only allows 100KHz:/* For testing, don't allow writing above 100KHz */ if (i2c->speed_hz > 100000 || alen != 1) return -EINVAL;
Quoted 6 lines
Because the clock-frequency is set to <400000> in the sandbox DTS, writing to I2C fails unless we change the I2C speed.
Is this intentional?
Personally, I like everything to work on the mail line.
This is test code, as it says in the comment. I'm considering splitting sandbox into two boards, one with the test code and one without. But let's see how this develops.
Regards,
Simon
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hello Simon, Masahiro,
Am 20.11.2014 15:04, schrieb Simon Glass:
Quoted 50 lines
+ A few more people to cc
Hi Masahiro,
Quoted 45 lines · Masahiro Yamada
Hi Simon,
Quoted 10 lines · On Wed, 19 Nov 2014 10:24:47 +0000 Simon Glass <[email protected]> wrote:
Quoted 8 lines
BTW,
address_offsetwithin the chip and data are treated in the same way in I2C bus. Should we pass them separately to each driver?I mean, can we put the offset address and data in the buffer?
I'm not sure what you mean by this sorry.
Let's assume we want to write some data to a EEPROM chip connected to i2c bus.
We generally send
[byte 0]
SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start writing [byte 2] WData0
[byte 3] WData1...From the perspective of I2C protocol, [byte 1], [byte 2], [byte 3], ... are all data.
I2C itself deos not (should not) know which byte is the
offset_addressin the chip and which is the *real* data to be written.Quoted 2 lines
Quoted 2 lines
drivers/i2c/i2c-uclass.c line 42
Quoted 2 lines
drivers/i2c/i2c-uclass.c new file +2
-0+return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len);In this implementation, the
offset_addressis treated with "addr" and the *real* data is handled with "buffer".It seems odd from the perspective of I2C protocol, I think.
Yes.
Quoted 13 lines
Quoted 13 lines
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1
Quoted 4 lines
Quoted 4 lines
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Yes, but this changes the current U-Boot API ...
Quoted 6 lines
Quoted 2 lines
We could certainly change this. I'm not sure that I have a strong opinion either way.
Quoted 8 lines
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).If we want to change it, we should do it now. My question is, what is the point? Will we really want >2 elements in the message array, do we
Do we need more than 2 elements? But of course, if we go into this direction we should support n elements ...
Quoted 2 lines
want more control over how transactions are done (repeated start, etc.)? I'm not sure. Still it would be a fairly low-impact change I
Thats the point ... do we need all this stuff in U-Boot?
Quoted 5 lines
feel. We are changing the drivers anyway, so changing the uclass-to-driver API would be feasible. One advantage perhaps it that it would match Linux more closely.
Perhaps Heiko can share an opinion here?
This implements that we must adapt each i2c driver "a little bit more" right? But I think, as we go with this approach more into the linux direction it sounds good to me (maybe we can directly use linux i2c drivers? ... that sounds good, and maybe should be a goal too?). I could not really say how many work this would be, but as we do this change step by step it is worth to go in this direction, as we can cleanup here and there (especially the eeprom driver) some "suboptimal" code ...
Thinking about it ... maybe we start from scratch with i2c drivers for DM and try to use linux i2c drivers?
bye,
Heiko
Quoted 90 lines
Quoted 36 lines
Quoted 26 lines
Quoted 17 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 11 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
Quoted 8 lines
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple
read()andwrite()only.Quoted 6 lines
Sorry, I could not parse you here.
I2C is not a hot-plugged bus.
I could not understand why such a dummy device is created on run time. Is it related to 'erase' or 'lock' functions?If we cannot write to the chip (i.e. it does not ACK when we send it its address) then we won't be able to talk to it, so there is no point in creating a device.
With driver model / device tree we could just blindly add the device and use it, but I chose to duplicate the current behaviour since this is expected.
Quoted 25 lines
BTW,
sandbox_i2c_read()is 400KHz tolerate:/* For testing, don't allow reading above 400KHz */ if (i2c->speed_hz > 400000 || alen != 1) return -EINVAL;but
sandbox_i2c_write()only allows 100KHz:/* For testing, don't allow writing above 100KHz */ if (i2c->speed_hz > 100000 || alen != 1) return -EINVAL;Quoted 6 lines
Because the clock-frequency is set to <400000> in the sandbox DTS, writing to I2C fails unless we change the I2C speed.
Is this intentional?
Personally, I like everything to work on the mail line.
This is test code, as it says in the comment. I'm considering splitting sandbox into two boards, one with the test code and one without. But let's see how this develops.
Regards,
Simon
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hi Heiko, Simon,
Quoted 12 lines · On Fri, 21 Nov 2014 08:24:18 +0100 Heiko Schocher <[email protected]> wrote:
Quoted 12 lines
Quoted 12 lines
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Yes, but this changes the current U-Boot API ...
I am hoping the translation code will be implemented in drivers/i2c/i2c-uclass.c, I think.
Quoted 37 lines
Quoted 6 lines
Quoted 2 lines
We could certainly change this. I'm not sure that I have a strong opinion either way.
Quoted 8 lines
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).If we want to change it, we should do it now. My question is, what is the point? Will we really want >2 elements in the message array, do we
Do we need more than 2 elements? But of course, if we go into this direction we should support n elements ...
Quoted 2 lines
want more control over how transactions are done (repeated start, etc.)? I'm not sure. Still it would be a fairly low-impact change I
Thats the point ... do we need all this stuff in U-Boot?
Quoted 5 lines
feel. We are changing the drivers anyway, so changing the uclass-to-driver API would be feasible. One advantage perhaps it that it would match Linux more closely.
Perhaps Heiko can share an opinion here?
This implements that we must adapt each i2c driver "a little bit more" right? But I think, as we go with this approach more into the linux direction it sounds good to me (maybe we can directly use linux i2c drivers? ... that sounds good, and maybe should be a goal too?). I could not really say how many work this would be, but as we do this change step by step it is worth to go in this direction, as we can cleanup here and there (especially the eeprom driver) some "suboptimal" code ...
Quoted 2 lines
Thinking about it ... maybe we start from scratch with i2c drivers for DM and try to use linux i2c drivers?
Anyway, DM is a giant change. I think it is the best (and perhaps the last) opportunity to implement things correctly.
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hi Masahiro,
Quoted 19 lines · Masahiro Yamada
Hi Heiko, Simon,
Quoted 14 lines · On Fri, 21 Nov 2014 08:24:18 +0100 Heiko Schocher <[email protected]> wrote:
Quoted 14 lines
Quoted 14 lines
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Yes, but this changes the current U-Boot API ...
I am hoping the translation code will be implemented in
drivers/i2c/i2c-uclass.c, I think.
That's right, no change to the U-Boot API.
Quoted 41 lines
Quoted 41 lines
Quoted 10 lines
Quoted 6 lines
We could certainly change this. I'm not sure that I have a strong opinion either way.
Quoted 8 lines
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).If we want to change it, we should do it now. My question is, what is the point? Will we really want >2 elements in the message array, do we
Do we need more than 2 elements? But of course, if we go into this direction we should support n elements ...
Quoted 2 lines
want more control over how transactions are done (repeated start, etc.)? I'm not sure. Still it would be a fairly low-impact change I
Thats the point ... do we need all this stuff in U-Boot?
Quoted 5 lines
feel. We are changing the drivers anyway, so changing the uclass-to-driver API would be feasible. One advantage perhaps it that it would match Linux more closely.
Perhaps Heiko can share an opinion here?
This implements that we must adapt each i2c driver "a little bit more" right? But I think, as we go with this approach more into the linux direction it sounds good to me (maybe we can directly use linux i2c drivers? ... that sounds good, and maybe should be a goal too?). I could not really say how many work this would be, but as we do this change step by step it is worth to go in this direction, as we can cleanup here and there (especially the eeprom driver) some "suboptimal" code ...
Quoted 6 lines
Quoted 2 lines
Thinking about it ... maybe we start from scratch with i2c drivers for DM and try to use linux i2c drivers?
Anyway, DM is a giant change. I think it is the best (and perhaps the last) opportunity to implement things correctly.
OK, any other opinions? I'm leaning towards going with Masahiro's idea.
Regards,
Simon
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
In reply to Simon GlassHi Simon, Heiko,
Quoted 46 lines · On Thu, 20 Nov 2014 14:04:52 +0000 Simon Glass <[email protected]> wrote:
Quoted 39 lines
Let's assume we want to write some data to a EEPROM chip connected to i2c bus.
We generally send
[byte 0]
SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start writing [byte 2] WData0
[byte 3] WData1
...From the perspective of I2C protocol, [byte 1], [byte 2], [byte 3], ... are all data.
I2C itself deos not (should not) know which byte is the
offset_addressin the chip and which is the *real* data to be written.Quoted 2 lines
Quoted 2 lines
drivers/i2c/i2c-uclass.c line 42
Quoted 2 lines
drivers/i2c/i2c-uclass.c new file +2
-0+return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len);In this implementation, the
offset_addressis treated with "addr" and the *real* data is handled with "buffer".It seems odd from the perspective of I2C protocol, I think.
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1Quoted 6 lines
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Quoted 8 lines
We could certainly change this. I'm not sure that I have a strong opinion either way.
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).
Yes, the code of the write (for the address) in the .read() handler would the same as the .write handler.
I thought it would not be a good idea to duplicate the write transaction code in every driver.
If we can accept this change, we only need to implement "write -> restart -> read" code in i2c_read() in i2c-uclass.c. Each driver would be much simpler.
That is the point of my suggestion.
Quoted 42 lines
Quoted 35 lines
Quoted 25 lines
Quoted 16 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 10 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
Quoted 8 lines
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple
read()andwrite()only.Quoted 6 lines
Sorry, I could not parse you here.
I2C is not a hot-plugged bus.
I could not understand why such a dummy device is created on run time. Is it related to 'erase' or 'lock' functions?
Quoted 7 lines
If we cannot write to the chip (i.e. it does not ACK when we send it its address) then we won't be able to talk to it, so there is no point in creating a device.
With driver model / device tree we could just blindly add the device and use it, but I chose to duplicate the current behaviour since this is expected.
Do you mean you implemented the same (similar) behavior as the legacy I2C framework?
Quoted 5 lines
Quoted 5 lines
Because the clock-frequency is set to <400000> in the sandbox DTS, writing to I2C fails unless we change the I2C speed.
Quoted 7 lines
Quoted 3 lines
Is this intentional?
Personally, I like everything to work on the mail line.
This is test code, as it says in the comment. I'm considering splitting sandbox into two boards, one with the test code and one without. But let's see how this develops.
I see.
Best Regards
Masahiro Yamada
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hi Masahiro,
Quoted 66 lines · Masahiro Yamada
Hi Simon, Heiko,
Quoted 46 lines · On Thu, 20 Nov 2014 14:04:52 +0000 Simon Glass <[email protected]> wrote:
Quoted 39 lines
Let's assume we want to write some data to a EEPROM chip connected to i2c bus.
We generally send
[byte 0]
SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start writing [byte 2] WData0
[byte 3] WData1
...From the perspective of I2C protocol, [byte 1], [byte 2], [byte 3], ... are all data.
I2C itself deos not (should not) know which byte is the
offset_addressin the chip and which is the *real* data to be written.Quoted 2 lines
Quoted 2 lines
drivers/i2c/i2c-uclass.c line 42
Quoted 2 lines
drivers/i2c/i2c-uclass.c new file +2
-0+return ops->write (bus, chip->chip_addr, addr, chip->addr_len, buffer, + len);In this implementation, the
offset_addressis treated with "addr" and the *real* data is handled with "buffer".It seems odd from the perspective of I2C protocol, I think.
Likewise, when we read data from a EEPROM chip connected to i2c bus,
We generally send/receive
[byte 0]SLAVE_ADDR(7bit) + W flag
[byte 1] Offset address in EEPROM where you want to start reading [byte 2]SLAVE_ADDR(7bit) + R flag
[byte 3] RData 0
[byte 4] Rdata 1Quoted 6 lines
[byte 1], [byte 3], [byte 4] are data written/read via I2C bus.
In my view, each I2C driver should handle [byte 0] and [byte 1] in its ".write" operation and [byte 2], [byte3], [byte 4], .... in its ".read" operation.
Quoted 8 lines
We could certainly change this. I'm not sure that I have a strong opinion either way.
I haven't to date seen an I2C chip where we don't have an address as the first byte. If we change the API at the driver level, which I think is what we are discussing, then we would need to move to a message array format. The read transaction would become two elements:
a write (for the address) then a read (to get the data).Yes, the code of the write (for the address) in the .read() handler would the same as the .write handler.
I thought it would not be a good idea to duplicate the write transaction code in every driver.
Quoted 5 lines
If we can accept this change, we only need to implement "write -> restart -> read" code in
i2c_read()ini2c-uclass.c. Each driver would be much simpler.That is the point of my suggestion.
I'm not sure we can do that. Some drivers have to do special things to handle the restart and it would not necessarily be a good idea to move that logic to the uclass.
Quoted 48 lines
Quoted 48 lines
Quoted 37 lines
Quoted 27 lines
Quoted 18 lines
drivers/i2c/i2c-uclass.c line 113
Quoted 12 lines
drivers/i2c/i2c-uclass.c new file +4
-0+ } +debug ("not found\n" ); +return i2c_bind_driver (bus, chip_addr, devp); +}If no chip-device is found at the specified
chip_addr, the last line callsi2c_bind_driver(). Why?Quoted 8 lines
The
i2c_bind_driver()tries to create a "generic" chip. What is this "generic" chip?Besides,
i2c_bind_driver()tries to probe the created generic chip, but it always fails ini2c_chip_ofdata_to_platdata()because the generic chip does not have "reg" propertyI could not understand at all what this code wants to do.
Quoted 8 lines
This actually creates the device. A generic I2C device is something that has no specific driver, but you can use read()/write() on it.
As an example, if we have an EEPROM we might add a special driver for it with functions like 'erase' and 'lock'. In that case we would bind the EEPROM driver to this address on the I2C bus. But for many cases we don't have/need a special driver, and can just fall back to one that supports simple
read()andwrite()only.Quoted 6 lines
Sorry, I could not parse you here.
I2C is not a hot-plugged bus.
I could not understand why such a dummy device is created on run time. Is it related to 'erase' or 'lock' functions?If we cannot write to the chip (i.e. it does not ACK when we send it its address) then we won't be able to talk to it, so there is no point in creating a device.
Quoted 6 lines
Quoted 3 lines
With driver model / device tree we could just blindly add the device and use it, but I chose to duplicate the current behaviour since this is expected.
Do you mean you implemented the same (similar) behavior as the legacy I2C framework?
Yes, we need the ability to scan the bus and find which devices are present.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Because the clock-frequency is set to <400000> in the sandbox DTS, writing to I2C fails unless we change the I2C speed.
Is this intentional?
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Personally, I like everything to work on the mail line.
This is test code, as it says in the comment. I'm considering splitting sandbox into two boards, one with the test code and one without. But let's see how this develops.
I see.
Regards,
Simon
PATCH v2 8/17 dm: i2c: Add a uclass for I2C
Hello Simon,
Quoted 3 lines · Simon Glass
Quoted 1 line
Do you mean you implemented the same (similar) behavior as the legacy I2C framework?
Yes, we need the ability to scan the bus and find which devices are present.
Side note: not sure this was touched on, and not sure what the implications are, but let me just mention that some SPLs need this ability too (this causes SPL to grow, which is probably the reason that some ARM boards failed to build once the i2c linker lists were added to the SPL lds file and until some other feature was removed).
Amicalement,
Signature · 1 line
Albert.
PATCH v2 9/17 dm: i2c: Implement driver model support in the i2c command
In reply to Simon GlassThe 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.
---
Changes in v2:
- Change alen to int so that it can be -1 (this was a bug)
- Call the deblock() method for 'i2c reset'
common/cmd_i2c.c | 336 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 284 insertions(+), 52 deletions(-)
common/cmd_i2c.c +284 -52
@@ -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' ;
@@ -227,8 +283,13 @@ static int i2c_report_err(int ret, enum i2c_err_op op)static int do_i2c_read (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {u_char chip; -uint devaddr, alen, length; +uint devaddr, length; +int alen;u_char *memaddr; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc !=5 )return CMD_RET_USAGE ;
@@ -243,7 +304,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,18 +318,31 @@ 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 ; }static int do_i2c_write (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {u_char chip; -uint devaddr, alen, length; +uint devaddr, length; +int alen;u_char *memaddr; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc !=5 )return cmd_usage (cmdtp);
@@ -288,7 +362,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 +371,22 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[*/ length =simple_strtoul (argv[4 ],NULL ,16 ); +#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) +return i2c_report_err (ret,I2C_ERR_WRITE ); +#endif +while (length-- >0 ) { -if (i2c_write (chip, devaddr++, alen, memaddr++,1 ) !=0 ) { -return i2c_report_err (-1 ,I2C_ERR_WRITE ); - } +#ifdef CONFIG_DM_I2C + ret =i2c_write (dev, devaddr++, memaddr++,1 ); +#else + ret =i2c_write (chip, devaddr++, alen, memaddr++,1 ); +#endif +if (ret) +return i2c_report_err (ret,I2C_ERR_WRITE );/* * No write delay with FRAM devices. */
@@ -327,8 +413,13 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[static int do_i2c_md (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {u_char chip; -uint addr, alen, length; +uint addr, length; +int alen;int j, nbytes, linebytes; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif /* We use the last specified parameters, unless new ones are * entered.
@@ -356,7 +447,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]* 2 bytes long. Some day it might be 3 bytes long :-). */ addr =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 ;
@@ -368,6 +459,14 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] length =simple_strtoul (argv[3 ],NULL ,16 ); } +#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) +return i2c_report_err (ret,I2C_ERR_READ ); +#endif +/* * Print the lines. *
@@ -381,8 +480,13 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] linebytes = (nbytes >DISP_LINE_LEN ) ?DISP_LINE_LEN : nbytes; -if (i2c_read (chip, addr, alen, linebuf, linebytes) !=0 ) -i2c_report_err (-1 ,I2C_ERR_READ ); +#ifdef CONFIG_DM_I2C + ret =i2c_read (dev, addr, linebuf, linebytes); +#else + ret =i2c_read (chip, addr, alen, linebuf, linebytes); +#endif +if (ret) +i2c_report_err (ret,I2C_ERR_READ );else {printf ("%04x:" , addr); cp = linebuf;
@@ -429,9 +533,13 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] {uchar chip;ulong addr; -uint alen; +int alen;uchar byte;int count; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if ((argc <4 ) || (argc >5 ))return CMD_RET_USAGE ;
@@ -445,10 +553,17 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]* Address is always specified. */ addr =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 ; +#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) +return i2c_report_err (ret,I2C_ERR_WRITE ); +#endif /* * Value to write is always specified. */
@@ -463,8 +578,13 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] count =1 ;while (count-- >0 ) { -if (i2c_write (chip, addr++, alen, &byte,1 ) !=0 ) -i2c_report_err (-1 ,I2C_ERR_WRITE ); +#ifdef CONFIG_DM_I2C + ret =i2c_write (dev, addr++, &byte,1 ); +#else + ret =i2c_write (chip, addr++, alen, &byte,1 ); +#endif +if (ret) +i2c_report_err (ret,I2C_ERR_WRITE );/* * Wait for the write to complete. The write can take * up to 10mSec (we allow a little more time).
@@ -499,11 +619,15 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] {uchar chip;ulong addr; -uint alen; +int alen;int count;uchar byte;ulong crc;ulong err; +int ret =0 ; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc <4 )return CMD_RET_USAGE ;
@@ -517,10 +641,17 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]* Address is always specified. */ addr =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 ; +#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) +return i2c_report_err (ret,I2C_ERR_READ ); +#endif /* * Count is always specified */
@@ -534,13 +665,18 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] crc =0 ; err =0 ;while (count-- >0 ) { -if (i2c_read (chip, addr, alen, &byte,1 ) !=0 ) +#ifdef CONFIG_DM_I2C + ret =i2c_read (dev, addr, &byte,1 ); +#else + ret =i2c_read (chip, addr, alen, &byte,1 ); +#endif +if (ret) err++; crc =crc32 (crc, &byte,1 ); addr++; }if (err >0 ) -i2c_report_err (-1 ,I2C_ERR_READ ); +i2c_report_err (ret,I2C_ERR_READ );else printf ("%08lx\n" , crc);
@@ -568,10 +704,14 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg {uchar chip;ulong addr; -uint alen; +int alen;ulong data;int size =1 ;int nbytes; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc !=3 )return CMD_RET_USAGE ;
@@ -601,19 +741,32 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg* Address is always specified. */ addr =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 ; } +#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) +return i2c_report_err (ret,I2C_ERR_WRITE ); +#endif +/* * Print the address, followed by value. Then accept input for * the next value. A non-converted value exits. */ do { printf("%08lx:", addr); - if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) - i2c_report_err(-1, I2C_ERR_READ); +#ifdef CONFIG_DM_I2C + ret = i2c_read(dev, addr, (uchar *)&data, size); +#else + ret = i2c_read(chip, addr, alen, (uchar *)&data, size); +#endif + if (ret) + i2c_report_err(ret, I2C_ERR_READ); else { data = cpu_to_be32(data); if (size == 1)
@@ -655,8 +808,15 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg* good enough to not time out */ bootretry_reset_cmd_timeout (); -if (i2c_write (chip, addr, alen, (uchar *)&data, size) !=0 ) -i2c_report_err (-1 ,I2C_ERR_WRITE ); +#ifdef CONFIG_DM_I2C + ret =i2c_write (dev, addr, (uchar *)&data, + size); +#else + ret =i2c_write (chip, addr, alen, + (uchar *)&data, size); +#endif +if (ret) +i2c_report_err (ret,I2C_ERR_WRITE );#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS udelay (CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS *1000 );#endif
@@ -697,6 +857,13 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argvint k, skip;unsigned int bus =GET_BUS_NUM ;#endif /* NOPROBES */ +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *bus, *dev; + +if (i2c_get_cur_bus (&bus)) +return CMD_RET_FAILURE ; +#endif if (argc ==2 ) addr =simple_strtol (argv[1 ],0 ,16 );
@@ -717,7 +884,12 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argvif (skip)continue ;#endif -if (i2c_probe (j) ==0 ) { +#ifdef CONFIG_DM_I2C + ret =i2c_probe (bus, j, &dev); +#else + ret =i2c_probe (j); +#endif +if (ret ==0 ) {printf (" %02X" , j); found++; }
@@ -754,11 +926,15 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argvstatic int do_i2c_loop (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {u_char chip; -ulong alen; +int alen;uint addr;uint length;u_char bytes[16 ];int delay; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc <3 )return CMD_RET_USAGE ;
@@ -772,9 +948,16 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]* Address is always specified. */ addr =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 ; +#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) +return i2c_report_err (ret,I2C_ERR_WRITE ); +#endif /* * Length is the number of objects, not number of bytes.
@@ -794,8 +977,13 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]* Run the loop... */ while (1 ) { -if (i2c_read (chip, addr, alen, bytes, length) !=0 ) -i2c_report_err (-1 ,I2C_ERR_READ ); +#ifdef CONFIG_DM_I2C + ret =i2c_read (dev, addr, bytes, length); +#else + ret =i2c_read (chip, addr, alen, bytes, length); +#endif +if (ret) +i2c_report_err (ret,I2C_ERR_READ );udelay (delay); }
@@ -1345,6 +1533,10 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) {u_char chip;struct edid1_info edid; +int ret; +#ifdef CONFIG_DM_I2C +struct udevice *dev; +#endif if (argc <2 ) {cmd_usage (cmdtp);
@@ -1352,10 +1544,15 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } chip =simple_strtoul (argv[1 ],NULL ,16 ); -if (i2c_read (chip,0 ,1 , (uchar *)&edid,sizeof (edid)) !=0 ) { -i2c_report_err (-1 ,I2C_ERR_READ ); -return 1 ; - } +#ifdef CONFIG_DM_I2C + ret =i2c_get_cur_bus_chip (chip, &dev); +if (!ret) + ret =i2c_read (dev,0 , (uchar *)&edid,sizeof (edid)); +#else + ret =i2c_read (chip,0 ,1 , (uchar *)&edid,sizeof (edid)); +#endif +if (ret) +return i2c_report_err (ret,I2C_ERR_READ );if (edid_check_info (&edid)) {puts ("Content isn't valid EDID.\n" );
@@ -1437,17 +1634,28 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,* Returns zero on success, CMD_RET_USAGE in case of misuse and negative * on error. */ -#if defined(CONFIG_SYS_I2C ) || defined(CONFIG_I2C_MULTI_BUS ) +#if defined(CONFIG_SYS_I2C ) || defined(CONFIG_I2C_MULTI_BUS ) || \ + defined(CONFIG_DM_I2C )static int do_i2c_bus_num (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {int ret =0 ; -unsigned int bus_no; +int bus_no; -if (argc ==1 ) +if (argc ==1 ) {/* querying current setting */ -printf ("Current bus is %d\n" ,i2c_get_bus_num ()); -else { +#ifdef CONFIG_DM_I2C +struct udevice *bus; + +if (!i2c_get_cur_bus (&bus)) + bus_no = bus->seq; +else + bus_no =-1 ; +#else + bus_no =i2c_get_bus_num (); +#endif +printf ("Current bus is %d\n" , bus_no); + }else { bus_no =simple_strtoul (argv[1 ],NULL ,10 );#if defined(CONFIG_SYS_I2C )if (bus_no >=CONFIG_SYS_NUM_I2C_BUSES ) {
@@ -1478,13 +1686,28 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const {int speed, ret=0 ; -if (argc ==1 ) +#ifdef CONFIG_DM_I2C +struct udevice *bus; + +if (i2c_get_cur_bus (&bus)) +return 1 ; +#endif +if (argc ==1 ) { +#ifdef CONFIG_DM_I2C + speed =i2c_get_bus_speed (bus); +#else + speed =i2c_get_bus_speed (); +#endif /* querying current speed */ -printf ("Current bus speed=%d\n" ,i2c_get_bus_speed ()); -else { +printf ("Current bus speed=%d\n" , speed); + }else { speed =simple_strtoul (argv[1 ],NULL ,10 );printf ("Setting bus speed to %d Hz\n" , speed); +#ifdef CONFIG_DM_I2C + ret =i2c_set_bus_speed (bus, speed); +#else ret =i2c_set_bus_speed (speed); +#endif if (ret)printf ("Failure changing bus speed (%d)\n" , ret); }
@@ -1532,7 +1755,16 @@ static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])*/ static int do_i2c_reset (cmd_tbl_t * cmdtp,int flag,int argc,char *const argv[]) { -#if defined(CONFIG_SYS_I2C ) +#if defined(CONFIG_DM_I2C ) +struct udevice *bus; + +if (i2c_get_cur_bus (&bus)) +return CMD_RET_FAILURE ; +if (i2c_deblock (bus)) { +printf ("Error: Not supported by the driver\n" ); +return CMD_RET_FAILURE ; + } +#elif defined(CONFIG_SYS_I2C )i2c_init (I2C_ADAP ->speed,I2C_ADAP ->slaveaddr);#else i2c_init (CONFIG_SYS_I2C_SPEED ,CONFIG_SYS_I2C_SLAVE );
@@ -1546,7 +1778,7 @@ static cmd_tbl_t cmd_i2c_sub[] = {#endif U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),#if defined(CONFIG_SYS_I2C ) || \ - defined(CONFIG_I2C_MULTI_BUS ) + defined(CONFIG_I2C_MULTI_BUS ) || defined(CONFIG_DM_I2C ) U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),#endif /* CONFIG_I2C_MULTI_BUS */ #if defined(CONFIG_I2C_EDID )
@@ -1610,7 +1842,7 @@ static char i2c_help_text[] =#endif "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"#if defined(CONFIG_SYS_I2C ) || \ - defined(CONFIG_I2C_MULTI_BUS ) + defined(CONFIG_I2C_MULTI_BUS ) || defined(CONFIG_DM_I2C ) "i2c dev [dev] - show or set current I2C bus\n"#endif /* CONFIG_I2C_MULTI_BUS */ #if defined(CONFIG_I2C_EDID )
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 9/17 dm: i2c: Implement driver model support in the i2c command
Quoted 6 lines · 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 <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/338af4d5/attachment.pgp>
PATCH v2 9/17 dm: i2c: Implement driver model support in the i2c command
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 6 lines
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 <[email protected]>
Quoted 8 lines
---
Changes in v2:
- Change alen to int so that it can be -1 (this was a bug)
- Call thedeblock()method for 'i2c reset'common/cmd_i2c.c | 336 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 284 insertions(+), 52 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 10/17 dm: i2c: Add I2C emulation driver for sandbox
In reply to Simon GlassIn order to test I2C we need some sort of emulation interface. Add hooks to allow a driver to emulate an I2C device for sandbox.
---
Changes in v2: None
drivers/i2c/Makefile | 1 + drivers/i2c/i2c-emul-uclass.c | 14 ++++++++++++++ include/dm/uclass-id.h | 1 + 3 files changed, 16 insertions(+) create mode 100644 drivers/i2c/i2c-emul-uclass.c
drivers/i2c/Makefile +1 -0
@@ -27,6 +27,7 @@ obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o +obj-$(CONFIG_SYS_I2C_SANDBOX) += i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
drivers/i2c/i2c-emul-uclass.c new file +14 -0
@@ -0,0 +1,14 @@ +/* +* Copyright (c) 2014 Google, Inc +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <dm.h> +#include <i2c.h> + +UCLASS_DRIVER (i2c_emul) = { + .id =UCLASS_I2C_EMUL , + .name ="i2c_emul" , +};
include/dm/uclass-id.h +1 -0
@@ -19,6 +19,7 @@ enum uclass_id {UCLASS_TEST_FDT ,UCLASS_TEST_BUS ,UCLASS_SPI_EMUL ,/* sandbox SPI device emulator */ +UCLASS_I2C_EMUL ,/* sandbox I2C device emulator */ UCLASS_SIMPLE_BUS,/* U-Boot uclasses start here */
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 10/17 dm: i2c: Add I2C emulation driver for sandbox
Quoted 4 lines · Simon Glass
In order to test I2C we need some sort of emulation interface. Add hooks to allow a driver to emulate an I2C device for sandbox.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/d7759095/attachment.pgp>
PATCH v2 10/17 dm: i2c: Add I2C emulation driver for sandbox
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 6 lines
In order to test I2C we need some sort of emulation interface. Add hooks to allow a driver to emulate an I2C device for sandbox.
Signed-off-by Simon Glass <[email protected]>---
Quoted 7 lines
Changes in v2: None
drivers/i2c/Makefile | 1 + drivers/i2c/i2c-emul-uclass.c | 14 ++++++++++++++ include/dm/uclass-id.h | 1 + 3 files changed, 16 insertions(+)create mode 100644
drivers/i2c/i2c-emul-uclass.c
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 11/17 dm: i2c: Add a sandbox I2C driver
In reply to Simon GlassThis driver includes some test features such as only supporting certain bus speeds. It passes its I2C traffic through to an emulator.
---
Changes in v2: None
drivers/i2c/Makefile | 2 +- drivers/i2c/sandbox_i2c.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 drivers/i2c/sandbox_i2c.c
drivers/i2c/Makefile +1 -1
@@ -27,7 +27,7 @@ obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o -obj-$(CONFIG_SYS_I2C_SANDBOX) += i2c-emul-uclass.o +obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
drivers/i2c/sandbox_i2c.c new file +148 -0
148 lines not on this page · raw message
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 11/17 dm: i2c: Add a sandbox I2C driver
Quoted 4 lines · Simon Glass
This driver includes some test features such as only supporting certain bus speeds. It passes its I2C traffic through to an emulator.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/d4165abc/attachment.pgp>
PATCH v2 11/17 dm: i2c: Add a sandbox I2C driver
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
This driver includes some test features such as only supporting certain bus speeds. It passes its I2C traffic through to an emulator.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
---
Changes in v2: None
drivers/i2c/Makefile | 2 +- drivers/i2c/sandbox_i2c.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-)create mode 100644
drivers/i2c/sandbox_i2c.c
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 12/17 dm: i2c: Add an I2C EEPROM simulator
In reply to Simon GlassTo enable testing of I2C, add a simple I2C EEPROM simulator for sandbox. It supports reading and writing from a small data store.
---
Changes in v2: None
drivers/misc/Makefile | 3 ++ drivers/misc/i2c_eeprom_emul.c | 108 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 drivers/misc/i2c_eeprom_emul.c
drivers/misc/Makefile +3 -0
@@ -20,6 +20,9 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NS87308) += ns87308.o obj-$(CONFIG_PDSP188x) += pdsp188x.o +ifdef CONFIG_DM_I2C +obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o +endif obj-$(CONFIG_STATUS_LED) += status_led.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
drivers/misc/i2c_eeprom_emul.c new file +108 -0
108 lines not on this page · raw message
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 12/17 dm: i2c: Add an I2C EEPROM simulator
Quoted 4 lines · Simon Glass
To enable testing of I2C, add a simple I2C EEPROM simulator for sandbox. It supports reading and writing from a small data store.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/3f56a6e1/attachment.pgp>
PATCH v2 12/17 dm: i2c: Add an I2C EEPROM simulator
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 4 lines
To enable testing of I2C, add a simple I2C EEPROM simulator for sandbox. It supports reading and writing from a small data store.
Signed-off-by Simon Glass <[email protected]>
Quoted 8 lines
---
Changes in v2: None
drivers/misc/Makefile | 3 ++ drivers/misc/i2c_eeprom_emul.c | 108 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+)create mode 100644
drivers/misc/i2c_eeprom_emul.c
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 13/17 dm: i2c: config: Enable I2C for sandbox using driver model
In reply to Simon GlassEnable the options to bring up I2C on sandbox. Also enable all the available I2C commands for testing purposes.
---
Changes in v2: None
include/configs/sandbox.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/configs/sandbox.h +6 -0
@@ -110,6 +110,12 @@#define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SPI_FLASH_WINBOND +#define CONFIG_DM_I2C +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C_SANDBOX +#define CONFIG_I2C_EDID +#define CONFIG_I2C_EEPROM +/* Memory things - we don't really want a memory test */ #define CONFIG_SYS_LOAD_ADDR 0x00000000#define CONFIG_SYS_MEMTEST_START 0x00100000
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 13/17 dm: i2c: config: Enable I2C for sandbox using driver model
Quoted 4 lines · Simon Glass
Enable the options to bring up I2C on sandbox. Also enable all the available I2C commands for testing purposes.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/6d200f87/attachment.pgp>
PATCH v2 13/17 dm: i2c: config: Enable I2C for sandbox using driver model
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
Enable the options to bring up I2C on sandbox. Also enable all the available I2C commands for testing purposes.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
include/configs/sandbox.h | 6 ++++++ 1 file changed, 6 insertions(+)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 14/17 dm: i2c: dts: Add an I2C bus for sandbox
In reply to Simon GlassAdd an I2C bus to the device tree, with an EEPROM emulator attached to one of the addresses.
---
Changes in v2: None
arch/sandbox/dts/sandbox.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/sandbox/dts/sandbox.dts +17 -0
@@ -134,6 +134,23 @@ num-gpios = <20>; }; + i2c at 0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <400000>; + eeprom at 2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul { + compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + spi at 0 { #address-cells = <1>; #size-cells = <0>;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 14/17 dm: i2c: dts: Add an I2C bus for sandbox
Quoted 4 lines · Simon Glass
Add an I2C bus to the device tree, with an EEPROM emulator attached to one of the addresses.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/6f0687a7/attachment.pgp>
PATCH v2 14/17 dm: i2c: dts: Add an I2C bus for sandbox
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
Add an I2C bus to the device tree, with an EEPROM emulator attached to one of the addresses.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2: None
arch/sandbox/dts/sandbox.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 14/17 dm: i2c: dts: Add an I2C bus for sandbox
In reply to Simon GlassHi Simon,
Quoted 18 lines · On Tue, 11 Nov 2014 10:46:30 -0700 Simon Glass <[email protected]> wrote:
arch/sandbox/dts/sandbox.dts +10
-0@@ -134,6 +134,23 @@ num-gpios = <20>; }; + i2c at 0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <400000>; + eeprom at 2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul {
arch/sandbox/dts/sandbox.dts line 156
Quoted 10 lines
arch/sandbox/dts/sandbox.dts +7
-0+ compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + spi at 0 { #address-cells = <1>; #size-cells = <0>;
It is not clear to me why "sandbox,i2c-eeprom" is not placed right under "i2c at 0".
What does the intermediate node "eeprom at 2c" do?
I checked drivers/misc/i2c_eeprom.c but it does not seem to do anything.
Best Regards
Masahiro Yamada
PATCH v2 14/17 dm: i2c: dts: Add an I2C bus for sandbox
Hi Masahiro,
Quoted 41 lines · Masahiro Yamada
Hi Simon,
Quoted 18 lines · On Tue, 11 Nov 2014 10:46:30 -0700 Simon Glass <[email protected]> wrote:
arch/sandbox/dts/sandbox.dts +10
-0@@ -134,6 +134,23 @@ num-gpios = <20>; }; + i2c at 0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <400000>; + eeprom at 2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul {arch/sandbox/dts/sandbox.dts line 156
Quoted 10 lines
arch/sandbox/dts/sandbox.dts +7
-0+ compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + spi at 0 { #address-cells = <1>; #size-cells = <0>;It is not clear to me why "sandbox,i2c-eeprom" is not placed right under "i2c at 0".
Quoted 2 lines
What does the intermediate node "eeprom at 2c" do?
I checkeddrivers/misc/i2c_eeprom.cbut it does not seem to do anything.
Yes it doesn't yet, but could do in future.
The intermediate node is for the EEPROM driver, which we can build out as needed. The emul node connects the sandbox EEPROM emulation to the other side of the driver. On real hardware we don't have this, but we must attach emulators to devices (SPI, I2C, etc.) when using sandbox.
Regards,
Simon
PATCH v2 15/17 dm: Add a simple EEPROM driver
In reply to Simon GlassThere seem to be a few EEPROM drivers around - perhaps we should have a single standard one? This simple driver is used for sandbox testing, but could be pressed into more active service.
---
Changes in v2:
- Update commit message for EEPROM driver
drivers/misc/Makefile | 1 + drivers/misc/i2c_eeprom.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/i2c_eeprom.h | 19 ++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 drivers/misc/i2c_eeprom.c create mode 100644 include/i2c_eeprom.h
drivers/misc/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o obj-$(CONFIG_FSL_IIM) += fsl_iim.o obj-$(CONFIG_GPIO_LED) += gpio_led.o +obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
drivers/misc/i2c_eeprom.c new file +51 -0
51 lines not on this page · raw message
include/dm/uclass-id.h +1 -0
@@ -31,6 +31,7 @@ enum uclass_id {UCLASS_CROS_EC ,/* Chrome OS EC */ UCLASS_I2C ,/* I2C bus */ UCLASS_I2C_GENERIC ,/* Generic I2C device */ +UCLASS_I2C_EEPROM ,/* I2C EEPROM device */ UCLASS_COUNT , UCLASS_INVALID = -1,
include/i2c_eeprom.h new file +19 -0
@@ -0,0 +1,19 @@ +/* +* Copyright (c) 2014 Google, Inc +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __I2C_EEPROM +#define __I2C_EEPROM + +struct i2c_eeprom_ops { +int (*read)(struct udevice *dev,int offset,uint8_t *buf,int size); +int (*write)(struct udevice *dev,int offset,const uint8_t *buf, +int size); +}; + +struct i2c_eeprom { +}; + +#endif
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 15/17 dm: Add a simple EEPROM driver
Quoted 5 lines · Simon Glass
There seem to be a few EEPROM drivers around - perhaps we should have a single standard one? This simple driver is used for sandbox testing, but could be pressed into more active service.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/69fba571/attachment.pgp>
PATCH v2 15/17 dm: Add a simple EEPROM driver
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 10 lines
There seem to be a few EEPROM drivers around - perhaps we should have a single standard one? This simple driver is used for sandbox testing, but could be pressed into more active service.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Update commit message for EEPROM driver
Quoted 7 lines
drivers/misc/Makefile | 1 + drivers/misc/i2c_eeprom.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/i2c_eeprom.h | 19 ++++++++++++++++++ 4 files changed, 72 insertions(+)create mode 100644
drivers/misc/i2c_eeprom.c
create mode 100644include/i2c_eeprom.h
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 16/17 dm: i2c: Add tests for I2C
In reply to Simon GlassAdd some basic tests to check that the system works as expected.
---
Changes in v2:
- Add a test for automatic binding of generic I2C devices
- Add a new asm/test.h header for tests in sandbox
arch/sandbox/include/asm/test.h | 15 ++++++ drivers/i2c/sandbox_i2c.c | 8 +++ test/dm/Makefile | 1 + test/dm/i2c.c | 112 ++++++++++++++++++++++++++++++++++++++++ test/dm/test.dts | 17 ++++++ 5 files changed, 153 insertions(+) create mode 100644 arch/sandbox/include/asm/test.h create mode 100644 test/dm/i2c.c
arch/sandbox/include/asm/test.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Test-related constants for sandbox +* +* Copyright (c) 2014 Google, Inc +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __ASM_TEST_H +#define __ASM_TEST_H + +/* The sandbox driver always permits an I2C device with this address */ +#define SANDBOX_I2C_TEST_ADDR 0x59 + +#endif
drivers/i2c/sandbox_i2c.c +8 -0
@@ -11,6 +11,7 @@#include <errno.h> #include <fdtdec.h> #include <i2c.h> +#include <asm/test.h> #include <dm/lists.h> #include <dm/device-internal.h>
@@ -67,6 +68,10 @@ static int sandbox_i2c_probe_chip(struct udevice *bus, uint chip_addr)struct udevice *emul;int ret; +/* Special test code to return success but with no emulation */ +if (chip_addr ==SANDBOX_I2C_TEST_ADDR ) +return 0 ; + ret =get_emul (bus, chip_addr, &emul, &ops);if (ret)return ret;
@@ -129,6 +134,9 @@ static int sandbox_i2c_child_pre_probe(struct udevice *dev) {struct dm_i2c_chip *i2c_chip =dev_get_parentdata (dev); +/* Ignore our test address */ +if (i2c_chip->chip_addr ==SANDBOX_I2C_TEST_ADDR ) +return 0 ;return i2c_chip_ofdata_to_platdata (gd->fdt_blob, dev->of_offset, i2c_chip); }
test/dm/Makefile +1 -0
@@ -20,4 +20,5 @@ ifneq ($(CONFIG_SANDBOX),) obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_SPI) += spi.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o +obj-$(CONFIG_DM_I2C) += i2c.o endif
test/dm/i2c.c new file +112 -0
112 lines not on this page · raw message
test/dm/test.dts +17 -0
@@ -93,6 +93,23 @@ num-gpios = <10>; }; + i2c at 0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <100000>; + eeprom at 2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul { + compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + spi at 0 { #address-cells = <1>; #size-cells = <0>;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 16/17 dm: i2c: Add tests for I2C
Quoted 3 lines · Simon Glass
Add some basic tests to check that the system works as expected.
Signed-off-by Simon Glass <[email protected]>
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141116/6b8e022c/attachment.pgp>
PATCH v2 16/17 dm: i2c: Add tests for I2C
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 9 lines
Add some basic tests to check that the system works as expected.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Add a test for automatic binding of generic I2C devices
- Add a newasm/test.hheader for tests in sandbox
Quoted 8 lines
arch/sandbox/include/asm/test.h | 15 ++++++ drivers/i2c/sandbox_i2c.c | 8 +++ test/dm/Makefile | 1 + test/dm/i2c.c | 112 ++++++++++++++++++++++++++++++++++++++++ test/dm/test.dts | 17 ++++++ 5 files changed, 153 insertions(+)create mode 100644
arch/sandbox/include/asm/test.hcreate mode 100644test/dm/i2c.c
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 17/17 dm: i2c: tegra: Convert to driver model
In reply to Simon GlassThis converts all Tegra boards over to use driver model for I2C. The driver is adjusted to use driver model and the following obsolete CONFIGs are removed:
- CONFIG_SYS_I2C_INIT_BOARD
- CONFIG_I2C_MULTI_BUS
- CONFIG_SYS_MAX_I2C_BUS
- CONFIG_SYS_I2C_SPEED
- CONFIG_SYS_I2C
This has been tested on:
- trimslice (no I2C)
- beaver
- Jetson-TK1
It has not been tested on Tegra 114 as I don't have that board.
---
Changes in v2:
- Adjust tegra_i2c_child_pre_probe() to permit generic I2C devices
- Correct the compatible strings for I2C buses
- Don't init if the speed is 0, since this breaks the controller
- Expand coverage to all Tegra boards
arch/arm/cpu/tegra20-common/pmu.c | 21 +- arch/arm/dts/tegra124-jetson-tk1.dts | 1 - arch/arm/dts/tegra124-norrin.dts | 1 - arch/arm/dts/tegra30-tec-ng.dts | 4 + arch/arm/include/asm/arch-tegra/tegra_i2c.h | 2 +- board/avionic-design/common/tamonten-ng.c | 12 +- board/nvidia/cardhu/cardhu.c | 13 +- board/nvidia/common/board.c | 4 - board/nvidia/dalmore/dalmore.c | 21 +- board/nvidia/whistler/whistler.c | 29 ++- board/toradex/apalis_t30/apalis_t30.c | 19 +- drivers/i2c/tegra_i2c.c | 320 +++++++++++----------------- drivers/power/tps6586x.c | 27 +-- include/configs/apalis_t30.h | 3 - include/configs/beaver.h | 3 - include/configs/cardhu.h | 5 - include/configs/colibri_t30.h | 3 - include/configs/dalmore.h | 5 - include/configs/jetson-tk1.h | 5 - include/configs/norrin.h | 5 - include/configs/seaboard.h | 3 - include/configs/tec-ng.h | 5 - include/configs/tegra-common.h | 1 + include/configs/tegra114-common.h | 3 - include/configs/tegra124-common.h | 3 - include/configs/tegra20-common.h | 3 - include/configs/tegra30-common.h | 3 - include/configs/trimslice.h | 3 - include/configs/venice2.h | 5 - include/configs/whistler.h | 3 - include/tps6586x.h | 4 +- 31 files changed, 211 insertions(+), 328 deletions(-)
arch/arm/cpu/tegra20-common/pmu.c +16 -5
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <i2c.h> #include <tps6586x.h> #include <asm/io.h> #include <asm/arch/tegra.h>
@@ -23,9 +24,13 @@#define VDD_TRANSITION_STEP 0x06/* 150mv */ #define VDD_TRANSITION_RATE 0x06/* 3.52mv/us */ +#define PMI_I2C_ADDRESS 0x34/* chip requires this address */ +int pmu_set_nominal (void ) { -int core, cpu, bus; +struct udevice *bus, *dev; +int core, cpu; +int ret;/* by default, the table has been filled with T25 settings */ switch (tegra_get_chip_sku ()) {
@@ -42,12 +47,18 @@ int pmu_set_nominal(void)return -1 ; } - bus =tegra_i2c_get_dvc_bus_num (); -if (bus ==-1 ) { + ret =tegra_i2c_get_dvc_bus (&bus); +if (ret) {debug ("%s: Cannot find DVC I2C bus\n" , __func__); -return -1 ; +return ret; } -tps6586x_init (bus); + ret =i2c_get_chip (bus,PMI_I2C_ADDRESS , &dev); +if (ret) { +debug ("%s: Cannot find DVC I2C chip\n" , __func__); +return ret; + } + +tps6586x_init (dev);tps6586x_set_pwm_mode (TPS6586X_PWM_SM1 );return tps6586x_adjust_sm0_sm1 (core, cpu,VDD_TRANSITION_STEP ,VDD_TRANSITION_RATE ,VDD_RELATION );
arch/arm/dts/tegra124-jetson-tk1.dts +0 -1
@@ -16,7 +16,6 @@ i2c2 = "/i2c at 7000c400"; i2c3 = "/i2c at 7000c500"; i2c4 = "/i2c at 7000c700"; - i2c5 = "/i2c at 7000d100"; sdhci0 = "/sdhci at 700b0600"; sdhci1 = "/sdhci at 700b0400"; spi0 = "/spi at 7000d400";
arch/arm/dts/tegra124-norrin.dts +0 -1
@@ -13,7 +13,6 @@ i2c2 = "/i2c at 7000c400"; i2c3 = "/i2c at 7000c500"; i2c4 = "/i2c at 7000c700"; - i2c5 = "/i2c at 7000d100"; sdhci0 = "/sdhci at 700b0600"; sdhci1 = "/sdhci at 700b0400"; spi0 = "/spi at 7000d400";
arch/arm/dts/tegra30-tec-ng.dts +4 -0
@@ -6,6 +6,10 @@ model = "Avionic Design Tamonten? NG Evaluation Carrier"; compatible = "ad,tec-ng", "nvidia,tegra30"; + aliases { + i2c0 = "/i2c at 7000c400"; + }; + /* GEN2 */ i2c at 7000c400 { status = "okay";
arch/arm/include/asm/arch-tegra/tegra_i2c.h +1 -1
@@ -167,6 +167,6 @@ struct i2c_ctlr {* * @return number of bus, or -1 if there is no DVC active */ -int tegra_i2c_get_dvc_bus_num (void ); +int tegra_i2c_get_dvc_bus (struct udevice **busp);#endif /* _TEGRA_I2C_H_ */
board/avionic-design/common/tamonten-ng.c +10 -2
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <dm.h> #include <asm/arch/pinmux.h> #include <asm/arch/gp_padctrl.h> #include <asm/arch/gpio.h>
@@ -51,8 +52,15 @@ void gpio_early_init(void)void pmu_write (uchar reg,uchar data) { -i2c_set_bus_num (4 );/* PMU is on bus 4 */ -i2c_write (PMU_I2C_ADDRESS , reg,1 , &data,1 ); +struct udevice *dev; +int ret; + + ret =i2c_get_chip_for_busnum (4 ,PMU_I2C_ADDRESS , &dev); +if (ret) { +debug ("%s: Cannot find PMIC I2C chip\n" , __func__); +return ; + } +i2c_write (dev, reg, &data,1 ); }/*
board/nvidia/cardhu/cardhu.c +10 -3
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <dm.h> #include <asm/arch/pinmux.h> #include <asm/arch/gp_padctrl.h> #include "pinmux-config-cardhu.h"
@@ -37,17 +38,23 @@ void pinmux_init(void)*/ void board_sdmmc_voltage_init (void ) { +struct udevice *dev;uchar reg, data_buffer[1 ]; +int ret;int i; -i2c_set_bus_num (0 );/* PMU is on bus 0 */ + ret =i2c_get_chip_for_busnum (0 ,PMU_I2C_ADDRESS , &dev); +if (ret) { +debug ("%s: Cannot find PMIC I2C chip\n" , __func__); +return ; + }/* TPS659110: LDO5_REG = 3.3v, ACTIVE to SDMMC1 */ data_buffer[0 ] =0x65 ; reg =0x32 ;for (i =0 ; i <MAX_I2C_RETRY ; ++i) { -if (i2c_write (PMU_I2C_ADDRESS , reg,1 , data_buffer,1 )) +if (i2c_write (dev, reg, data_buffer,1 ))udelay (100 ); }
@@ -56,7 +63,7 @@ void board_sdmmc_voltage_init(void) reg =0x67 ;for (i =0 ; i <MAX_I2C_RETRY ; ++i) { -if (i2c_write (PMU_I2C_ADDRESS , reg,1 , data_buffer,1 )) +if (i2c_write (dev, reg, data_buffer,1 ))udelay (100 ); } }
board/nvidia/common/board.c +0 -4
@@ -105,10 +105,6 @@ int board_init(void)power_det_init ();#ifdef CONFIG_SYS_I2C_TEGRA -#ifndef CONFIG_SYS_I2C_INIT_BOARD -#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards" -#endif -i2c_init_board ();# ifdef CONFIG_TEGRA_PMU if (pmu_set_nominal ())debug ("Failed to select nominal voltages\n" );
board/nvidia/dalmore/dalmore.c +15 -6
@@ -15,6 +15,7 @@*/ #include <common.h> +#include <dm.h> #include <asm/arch/pinmux.h> #include <asm/arch/gp_padctrl.h> #include "pinmux-config-dalmore.h"
@@ -50,18 +51,21 @@ void pinmux_init(void)*/ void board_sdmmc_voltage_init (void ) { +struct udevice *dev;uchar reg, data_buffer[1 ];int ret; - ret =i2c_set_bus_num (0 );/* PMU is on bus 0 */ -if (ret) -printf ("%s: i2c_set_bus_num returned %d\n" , __func__, ret); + ret =i2c_get_chip_for_busnum (0 ,PMU_I2C_ADDRESS , &dev); +if (ret) { +debug ("%s: Cannot find PMIC I2C chip\n" , __func__); +return ; + }/* TPS65913: LDO9_VOLTAGE = 3.3V */ data_buffer[0 ] =0x31 ; reg =0x61 ; - ret =i2c_write (PMU_I2C_ADDRESS , reg,1 , data_buffer,1 ); + ret =i2c_write (dev, reg, data_buffer,1 );if (ret)printf ("%s: PMU i2c_write %02X<-%02X returned %d\n" , __func__, reg, data_buffer[0 ], ret);
@@ -70,7 +74,7 @@ void board_sdmmc_voltage_init(void) data_buffer[0 ] =0x01 ; reg =0x60 ; - ret =i2c_write (PMU_I2C_ADDRESS , reg,1 , data_buffer,1 ); + ret =i2c_write (dev, reg, data_buffer,1 );if (ret)printf ("%s: PMU i2c_write %02X<-%02X returned %d\n" , __func__, reg, data_buffer[0 ], ret);
@@ -79,7 +83,12 @@ void board_sdmmc_voltage_init(void) data_buffer[0 ] =0x03 ; reg =0x14 ; - ret =i2c_write (BAT_I2C_ADDRESS , reg,1 , data_buffer,1 ); + ret =i2c_get_chip_for_busnum (0 ,BAT_I2C_ADDRESS , &dev); +if (ret) { +debug ("%s: Cannot find charger I2C chip\n" , __func__); +return ; + } + ret =i2c_write (dev, reg, data_buffer,1 );if (ret)printf ("%s: BAT i2c_write %02X<-%02X returned %d\n" , __func__, reg, data_buffer[0 ], ret);
board/nvidia/whistler/whistler.c +18 -11
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <dm.h> #include <asm/io.h> #include <asm/arch/tegra.h> #include <asm/arch/clock.h>
@@ -21,23 +22,26 @@*/ void pin_mux_mmc (void ) { +struct udevice *dev;uchar val;int ret;/* Turn on MAX8907B LDO12 to 2.8V for J40 power */ - ret =i2c_set_bus_num (0 ); -if (ret) -printf ("i2c_set_bus_num failed: %d\n" , ret); + ret =i2c_get_chip_for_busnum (0 ,0x3c , &dev); +if (ret) { +printf ("%s: Cannot find MAX8907B I2C chip\n" , __func__); +return ; + } val =0x29 ; - ret =i2c_write (0x3c ,0x46 ,1 , &val,1 ); + ret =i2c_write (dev,0x46 , &val,1 );if (ret)printf ("i2c_write 0 0x3c 0x46 failed: %d\n" , ret); val =0x00 ; - ret =i2c_write (0x3c ,0x45 ,1 , &val,1 ); + ret =i2c_write (dev,0x45 , &val,1 );if (ret)printf ("i2c_write 0 0x3c 0x45 failed: %d\n" , ret); val =0x1f ; - ret =i2c_write (0x3c ,0x44 ,1 , &val,1 ); + ret =i2c_write (dev,0x44 , &val,1 );if (ret)printf ("i2c_write 0 0x3c 0x44 failed: %d\n" , ret);
@@ -49,6 +53,7 @@ void pin_mux_mmc(void)/* this is a weak define that we are overriding */ void pin_mux_usb (void ) { +struct udevice *dev;uchar val;int ret;
@@ -59,15 +64,17 @@ void pin_mux_usb(void)*/ /* Turn on TAC6416's GPIO 0+1 for USB1/3's VBUS */ - ret =i2c_set_bus_num (0 ); -if (ret) -printf ("i2c_set_bus_num failed: %d\n" , ret); + ret =i2c_get_chip_for_busnum (0 ,0x20 , &dev); +if (ret) { +printf ("%s: Cannot find TAC6416 I2C chip\n" , __func__); +return ; + } val =0x03 ; - ret =i2c_write (0x20 ,2 ,1 , &val,1 ); + ret =i2c_write (dev,2 , &val,1 );if (ret)printf ("i2c_write 0 0x20 2 failed: %d\n" , ret); val =0xfc ; - ret =i2c_write (0x20 ,6 ,1 , &val,1 ); + ret =i2c_write (dev,6 , &val,1 );if (ret)printf ("i2c_write 0 0x20 6 failed: %d\n" , ret); }
board/toradex/apalis_t30/apalis_t30.c +7 -12
@@ -6,7 +6,7 @@*/ #include <common.h> - +#include <dm.h> #include <asm/arch/gp_padctrl.h> #include <asm/arch/pinmux.h> #include <asm/gpio.h>
@@ -38,23 +38,20 @@ void pinmux_init(void)#ifdef CONFIG_PCI_TEGRA int tegra_pcie_board_init (void ) { -unsigned int old_bus; +struct udevice *dev;u8 addr, data[1 ];int err; - old_bus =i2c_get_bus_num (); - - err =i2c_set_bus_num (0 ); + err =i2c_get_chip_for_busnum (0 ,PMU_I2C_ADDRESS , &dev);if (err) { -debug ("failed to set I2C bus\n" ); +debug ("%s: Cannot find PMIC I2C chip\n" , __func__);return err; } -/* TPS659110: VDD2_OP_REG = 1.05V */ data[0 ] =0x27 ; addr =0x25 ; - err =i2c_write (PMU_I2C_ADDRESS , addr,1 , data,1 ); + err =i2c_write (dev, addr, data,1 );if (err) {debug ("failed to set VDD supply\n" );return err;
@@ -64,7 +61,7 @@ int tegra_pcie_board_init(void) data[0 ] =0x0D ; addr =0x24 ; - err =i2c_write (PMU_I2C_ADDRESS , addr,1 , data,1 ); + err =i2c_write (dev, addr, data,1 );if (err) {debug ("failed to enable VDD supply\n" );return err;
@@ -74,14 +71,12 @@ int tegra_pcie_board_init(void) data[0 ] =0x0D ; addr =0x35 ; - err =i2c_write (PMU_I2C_ADDRESS , addr,1 , data,1 ); + err =i2c_write (dev, addr, data,1 );if (err) {debug ("failed to set AVDD supply\n" );return err; } -i2c_set_bus_num (old_bus); -return 0 ; }
drivers/i2c/tegra_i2c.c +120 -200
502 lines not on this page · raw message
drivers/power/tps6586x.c +7 -20
@@ -10,9 +10,7 @@#include <asm/io.h> #include <i2c.h> -static int bus_num;/* I2C bus we are on */ -#define I2C_ADDRESS 0x34/* chip requires this address */ -static char inited;/* 1 if we have been inited */ +static struct udevice *tps6586x_dev;enum {/* Registers that we access */
@@ -37,13 +35,9 @@ static int tps6586x_read(int reg)int i;uchar data;int retval =-1 ; -int old_bus_num; - - old_bus_num =i2c_get_bus_num (); -i2c_set_bus_num (bus_num);for (i =0 ; i <MAX_I2C_RETRY ; ++i) { -if (!i2c_read (I2C_ADDRESS , reg,1 , &data,1 )) { +if (!i2c_read (tps6586x_dev, reg, &data,1 )) { retval = (int )data; goto exit; }
@@ -53,7 +47,6 @@ static int tps6586x_read(int reg) } exit: -i2c_set_bus_num (old_bus_num);debug ("pmu_read %x=%x\n" , reg, retval);if (retval <0 ) debug("%s: failed to read register %#x: %d\n", __func__, reg,
@@ -65,13 +58,9 @@ static int tps6586x_write(int reg, uchar *data, uint len) {int i;int retval =-1 ; -int old_bus_num; - - old_bus_num =i2c_get_bus_num (); -i2c_set_bus_num (bus_num);for (i =0 ; i <MAX_I2C_RETRY ; ++i) { -if (!i2c_write (I2C_ADDRESS , reg,1 , data, len)) { +if (!i2c_write (tps6586x_dev, reg, data, len)) { retval =0 ; goto exit; }
@@ -81,7 +70,6 @@ static int tps6586x_write(int reg, uchar *data, uint len) } exit: -i2c_set_bus_num (old_bus_num);debug ("pmu_write %x=%x: " , reg, retval);for (i =0 ; i < len; i++)debug ("%x " , data[i]);
@@ -163,7 +151,7 @@ int tps6586x_set_pwm_mode(int mask)uchar val;int ret; -assert (inited); +assert (tps6586x_dev); ret =tps6586x_read (PFM_MODE );if (ret !=-1 ) { val = (uchar )ret;
@@ -184,7 +172,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,int sm0, sm1;int bad; -assert (inited); +assert (tps6586x_dev);/* get current voltage settings */ if (read_voltages (&sm0, &sm1)) {
@@ -255,10 +243,9 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,return bad ?-1 :0 ; } -int tps6586x_init (int bus) +int tps6586x_init (struct udevice *dev) { - bus_num = bus; - inited =1 ; + tps6586x_dev = dev;return 0 ; }
include/configs/apalis_t30.h +0 -3
@@ -26,10 +26,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/beaver.h +0 -3
@@ -40,10 +40,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/cardhu.h +0 -5
@@ -43,12 +43,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/colibri_t30.h +0 -3
@@ -25,10 +25,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/dalmore.h +0 -5
@@ -36,12 +36,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/jetson-tk1.h +0 -5
@@ -25,12 +25,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/norrin.h +0 -5
@@ -25,12 +25,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/seaboard.h +0 -3
@@ -37,10 +37,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/tec-ng.h +0 -5
@@ -23,12 +23,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/tegra-common.h +1 -0
@@ -26,6 +26,7 @@#endif #define CONFIG_DM_SPI #define CONFIG_DM_SPI_FLASH +#define CONFIG_DM_I2C #define CONFIG_SYS_TIMER_RATE 1000000#define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE
include/configs/tegra114-common.h +0 -3
@@ -76,9 +76,6 @@#define CONFIG_SYS_SPL_MALLOC_START 0x80090000#define CONFIG_SPL_STACK 0x800ffffc -/* Total I2C ports on Tegra114 */ -#define TEGRA_I2C_NUM_CONTROLLERS 5 -/* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
include/configs/tegra124-common.h +0 -3
@@ -68,9 +68,6 @@#define CONFIG_SYS_SPL_MALLOC_START 0x80090000#define CONFIG_SPL_STACK 0x800ffffc -/* Total I2C ports on Tegra124 */ -#define TEGRA_I2C_NUM_CONTROLLERS 5 -/* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
include/configs/tegra20-common.h +0 -3
@@ -97,9 +97,6 @@#define CONFIG_EHCI_IS_TDI #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 -/* Total I2C ports on Tegra20 */ -#define TEGRA_I2C_NUM_CONTROLLERS 4 -#define CONFIG_SYS_NAND_SELF_INIT #define CONFIG_SYS_NAND_ONFI_DETECTION
include/configs/tegra30-common.h +0 -3
@@ -73,9 +73,6 @@#define CONFIG_SYS_SPL_MALLOC_START 0x80090000#define CONFIG_SPL_STACK 0x800ffffc -/* Total I2C ports on Tegra30 */ -#define TEGRA_I2C_NUM_CONTROLLERS 5 -/* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
include/configs/trimslice.h +0 -3
@@ -34,10 +34,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/venice2.h +0 -5
@@ -25,12 +25,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/configs/whistler.h +0 -3
@@ -26,10 +26,7 @@/* I2C */ #define CONFIG_SYS_I2C_TEGRA -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C_SPEED 100000#define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C /* SD/MMC */ #define CONFIG_MMC
include/tps6586x.h +2 -2
@@ -44,9 +44,9 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,* Set up the TPS6586X I2C bus number. This will be used for all operations * on the device. This function must be called before using other functions. * -* @param bus I2C bus number containing the TPS6586X chip +* @param bus I2C bus containing the TPS6586X chip * @return 0 (always succeeds) */ -int tps6586x_init (int bus); +int tps6586x_init (struct udevice *bus);#endif /* _TPS6586X_H_ */
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 17/17 dm: i2c: tegra: Convert to driver model
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 50 lines
This converts all Tegra boards over to use driver model for I2C. The driver is adjusted to use driver model and the following obsolete CONFIGs are removed:
-
CONFIG_SYS_I2C_INIT_BOARD
-CONFIG_I2C_MULTI_BUS
-CONFIG_SYS_MAX_I2C_BUS
-CONFIG_SYS_I2C_SPEED
-CONFIG_SYS_I2CThis has been tested on:
- trimslice (no I2C)
- beaver
- Jetson-TK1It has not been tested on Tegra 114 as I don't have that board.
Signed-off-by Simon Glass <[email protected]>---
Changes in v2:
- Adjusttegra_i2c_child_pre_probe()to permit generic I2C devices
- Correct the compatible strings for I2C buses
- Don't init if the speed is 0, since this breaks the controller
- Expand coverage to all Tegra boardsarch/arm/cpu/tegra20-common/pmu.c | 21 +- arch/arm/dts/tegra124-jetson-tk1.dts | 1 - arch/arm/dts/tegra124-norrin.dts | 1 - arch/arm/dts/tegra30-tec-ng.dts | 4 + arch/arm/include/asm/arch-tegra/tegra_i2c.h | 2 +- board/avionic-design/common/tamonten-ng.c | 12 +- board/nvidia/cardhu/cardhu.c | 13 +- board/nvidia/common/board.c | 4 - board/nvidia/dalmore/dalmore.c | 21 +- board/nvidia/whistler/whistler.c | 29 ++- board/toradex/apalis_t30/apalis_t30.c | 19 +- drivers/i2c/tegra_i2c.c | 320 +++++++++++----------------- drivers/power/tps6586x.c | 27 +-- include/configs/apalis_t30.h | 3 - include/configs/beaver.h | 3 - include/configs/cardhu.h | 5 - include/configs/colibri_t30.h | 3 - include/configs/dalmore.h | 5 - include/configs/jetson-tk1.h | 5 - include/configs/norrin.h | 5 - include/configs/seaboard.h | 3 - include/configs/tec-ng.h | 5 - include/configs/tegra-common.h | 1 + include/configs/tegra114-common.h | 3 -
Quoted 8 lines
include/configs/tegra124-common.h | 3 - include/configs/tegra20-common.h | 3 - include/configs/tegra30-common.h | 3 - include/configs/trimslice.h | 3 - include/configs/venice2.h | 5 - include/configs/whistler.h | 3 - include/tps6586x.h | 4 +- 31 files changed, 211 insertions(+), 328 deletions(-)
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
v2 cover dm: Add I2C support and convert sandbox, tegra
In reply to Simon GlassHello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 145 lines
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chipwhich is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic is removed. With driver model
i2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().I2C muxes are not yet supported. To support these we will need to maintain state of the current mux settings to avoid resetting every mux every time. Probably we need to add a sandbox I2C mux driver to permit testing of this. This can probably be done later.
Platform data is not yet supported either, only device tree. The
U_BOOT_I2C_MKENT_COMPLETE()andU_BOOT_I2C_ADAP_COMPLETE()macros are not used. Also structi2c_adapteris not defined anymore. This will need to be addressed, perhaps as part of converting over a board that does not use device tree, assuming that we want to support this.The following I2C CONFIGs are no-longer needed when driver model is used:
CONFIG_SYS_I2C_INIT_BOARD- each I2C bus is inited in itsprobe()methodCONFIG_I2C_MULTI_BUS - we always support multi-bus with driver model CONFIG_SYS_MAX_I2C_BUS - the device tree aliases define available buses CONFIG_SYS_I2C_SPEED - the device tree specifies the speed for each bus CONFIG_SYS_I2C - this is the 'new old' API, now deprecatedThere are a few SPI patches included here due to a dependency on a new device binding function.
This series is available at u-boot-dm/i2c-working.
Changes in v2:
- Add a suitable commit message
- Add new patch to correct handling of aliases with embedded digits
- Add new patch to add a function to bind a device by driver name
- Add new patches to adjust SPI to usedevice_bind_driver()
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device fromi2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
- Change alen to int so that it can be -1 (this was a bug)
- Call thedeblock()method for 'i2c reset'
- Update commit message for EEPROM driver
- Add a test for automatic binding of generic I2C devices
- Add a newasm/test.hheader for tests in sandbox
- Adjusttegra_i2c_child_pre_probe()to permit generic I2C devices
- Correct the compatible strings for I2C buses
- Don't init if the speed is 0, since this breaks the controller
- Expand coverage to all Tegra boardsSimon Glass (17):
dm: i2c: Move error reporting into a common function
dm: core: Allow access to the device'sdriver_iddata
dm: core: Add functions to find parent and OF data
dm: fdt: Correct handling of aliases with embedded digits
dm: Add a function to bind a device by driver name
dm: spi: Correct handling of SPI chip selects in sandbox
dm: spi: Usedevice_bind_driver()instead of our own function
dm: i2c: Add a uclass for I2C
dm: i2c: Implement driver model support in the i2c command
dm: i2c: Add I2C emulation driver for sandbox
dm: i2c: Add a sandbox I2C driver
dm: i2c: Add an I2C EEPROM simulator
dm: i2c: config: Enable I2C for sandbox using driver model
dm: i2c: dts: Add an I2C bus for sandbox
dm: Add a simple EEPROM driver
dm: i2c: Add tests for I2C
dm: i2c: tegra: Convert to driver modelarch/arm/cpu/tegra20-common/pmu.c | 21 +- arch/arm/dts/tegra124-jetson-tk1.dts | 1 - arch/arm/dts/tegra124-norrin.dts | 1 - arch/arm/dts/tegra30-tec-ng.dts | 4 + arch/arm/include/asm/arch-tegra/tegra_i2c.h | 2 +- arch/sandbox/dts/sandbox.dts | 17 ++ arch/sandbox/include/asm/test.h | 15 ++ board/avionic-design/common/tamonten-ng.c | 12 +- board/nvidia/cardhu/cardhu.c | 13 +- board/nvidia/common/board.c | 4 - board/nvidia/dalmore/dalmore.c | 21 +- board/nvidia/whistler/whistler.c | 29 ++- board/toradex/apalis_t30/apalis_t30.c | 19 +- common/cmd_i2c.c | 350 +++++++++++++++++++++++----- drivers/core/device.c | 10 + drivers/core/lists.c | 38 ++- drivers/i2c/Makefile | 2 + drivers/i2c/i2c-emul-uclass.c | 14 ++ drivers/i2c/i2c-uclass.c | 275 ++++++++++++++++++++++ drivers/i2c/sandbox_i2c.c | 156 +++++++++++++ drivers/i2c/tegra_i2c.c | 320 ++++++++++--------------- drivers/misc/Makefile | 4 + drivers/misc/i2c_eeprom.c | 51 ++++ drivers/misc/i2c_eeprom_emul.c | 108 +++++++++ drivers/mtd/spi/sandbox.c | 4 +- drivers/power/tps6586x.c | 27 +-- drivers/spi/spi-uclass.c | 34 +-- include/config_fallbacks.h | 6 + include/configs/apalis_t30.h | 3 - include/configs/beaver.h | 3 - include/configs/cardhu.h | 5 - include/configs/colibri_t30.h | 3 - include/configs/dalmore.h | 5 - include/configs/jetson-tk1.h | 5 - include/configs/norrin.h | 5 - include/configs/sandbox.h | 6 + include/configs/seaboard.h | 3 - include/configs/tec-ng.h | 5 - include/configs/tegra-common.h | 1 + include/configs/tegra114-common.h | 3 - include/configs/tegra124-common.h | 3 - include/configs/tegra20-common.h | 3 - include/configs/tegra30-common.h | 3 - include/configs/trimslice.h | 3 - include/configs/venice2.h | 5 - include/configs/whistler.h | 3 - include/dm/device.h | 19 ++ include/dm/lists.h | 13 ++ include/dm/uclass-id.h | 4 + include/i2c.h | 288 +++++++++++++++++++++++ include/i2c_eeprom.h | 19 ++ include/spi.h | 14 +- include/tps6586x.h | 4 +- lib/fdtdec.c | 6 +- test/dm/Makefile | 1 + test/dm/i2c.c | 112 +++++++++ test/dm/test.dts | 17 ++ 57 files changed, 1690 insertions(+), 432 deletions(-)
Quoted 8 lines
create mode 100644
arch/sandbox/include/asm/test.hcreate mode 100644drivers/i2c/i2c-emul-uclass.ccreate mode 100644drivers/i2c/i2c-uclass.ccreate mode 100644drivers/i2c/sandbox_i2c.ccreate mode 100644drivers/misc/i2c_eeprom.ccreate mode 100644drivers/misc/i2c_eeprom_emul.ccreate mode 100644include/i2c_eeprom.hcreate mode 100644test/dm/i2c.c
Thanks for your great work. I acked all your patches, so from my side, you can push it through your dm tree into mainline. If you want that I pick up your patches please inform me, thanks!
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
v2 cover dm: Add I2C support and convert sandbox, tegra
Hi Heiko,
Quoted 160 lines · Heiko Schocher
Hello Simon,
Am 11.11.2014 18:46, schrieb Simon Glass:
Quoted 145 lines
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chipwhich is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic is removed. With driver model
i2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().I2C muxes are not yet supported. To support these we will need to maintain state of the current mux settings to avoid resetting every mux every time. Probably we need to add a sandbox I2C mux driver to permit testing of this. This can probably be done later.
Platform data is not yet supported either, only device tree. The
U_BOOT_I2C_MKENT_COMPLETE()andU_BOOT_I2C_ADAP_COMPLETE()macros are not used. Also structi2c_adapteris not defined anymore. This will need to be addressed, perhaps as part of converting over a board that does not use device tree, assuming that we want to support this.The following I2C CONFIGs are no-longer needed when driver model is used:
CONFIG_SYS_I2C_INIT_BOARD- each I2C bus is inited in itsprobe()methodCONFIG_I2C_MULTI_BUS - we always support multi-bus with driver model CONFIG_SYS_MAX_I2C_BUS - the device tree aliases define available buses CONFIG_SYS_I2C_SPEED - the device tree specifies the speed for each bus CONFIG_SYS_I2C - this is the 'new old' API, now deprecatedThere are a few SPI patches included here due to a dependency on a new device binding function.
This series is available at u-boot-dm/i2c-working.
Changes in v2:
- Add a suitable commit message
- Add new patch to correct handling of aliases with embedded digits
- Add new patch to add a function to bind a device by driver name
- Add new patches to adjust SPI to usedevice_bind_driver()
- Fix cihp typo
- Implement generic I2C devices to allow 'i2c probe' on unknown devices
- Return the probed device fromi2c_probe()
- Set the bus speed after the bus is probed
- Add some debugging for generic I2C device binding
- Add a 'deblock' method to recover an I2C bus stuck in mid-transaction
- Add a helper function to find a chip on a particular bus number
- Change alen to int so that it can be -1 (this was a bug)
- Call thedeblock()method for 'i2c reset'
- Update commit message for EEPROM driver
- Add a test for automatic binding of generic I2C devices
- Add a newasm/test.hheader for tests in sandbox
- Adjusttegra_i2c_child_pre_probe()to permit generic I2C devices
- Correct the compatible strings for I2C buses
- Don't init if the speed is 0, since this breaks the controller
- Expand coverage to all Tegra boardsSimon Glass (17):
dm: i2c: Move error reporting into a common function
dm: core: Allow access to the device'sdriver_iddata
dm: core: Add functions to find parent and OF data
dm: fdt: Correct handling of aliases with embedded digits
dm: Add a function to bind a device by driver name
dm: spi: Correct handling of SPI chip selects in sandbox
dm: spi: Usedevice_bind_driver()instead of our own function
dm: i2c: Add a uclass for I2C
dm: i2c: Implement driver model support in the i2c command
dm: i2c: Add I2C emulation driver for sandbox
dm: i2c: Add a sandbox I2C driver
dm: i2c: Add an I2C EEPROM simulator
dm: i2c: config: Enable I2C for sandbox using driver model
dm: i2c: dts: Add an I2C bus for sandbox
dm: Add a simple EEPROM driver
dm: i2c: Add tests for I2C
dm: i2c: tegra: Convert to driver modelarch/arm/cpu/tegra20-common/pmu.c | 21 +- arch/arm/dts/tegra124-jetson-tk1.dts | 1 - arch/arm/dts/tegra124-norrin.dts | 1 - arch/arm/dts/tegra30-tec-ng.dts | 4 + arch/arm/include/asm/arch-tegra/tegra_i2c.h | 2 +- arch/sandbox/dts/sandbox.dts | 17 ++ arch/sandbox/include/asm/test.h | 15 ++ board/avionic-design/common/tamonten-ng.c | 12 +- board/nvidia/cardhu/cardhu.c | 13 +- board/nvidia/common/board.c | 4 - board/nvidia/dalmore/dalmore.c | 21 +- board/nvidia/whistler/whistler.c | 29 ++- board/toradex/apalis_t30/apalis_t30.c | 19 +- common/cmd_i2c.c | 350 +++++++++++++++++++++++----- drivers/core/device.c | 10 + drivers/core/lists.c | 38 ++- drivers/i2c/Makefile | 2 + drivers/i2c/i2c-emul-uclass.c | 14 ++ drivers/i2c/i2c-uclass.c | 275 ++++++++++++++++++++++ drivers/i2c/sandbox_i2c.c | 156 +++++++++++++ drivers/i2c/tegra_i2c.c | 320 ++++++++++--------------- drivers/misc/Makefile | 4 + drivers/misc/i2c_eeprom.c | 51 ++++ drivers/misc/i2c_eeprom_emul.c | 108 +++++++++ drivers/mtd/spi/sandbox.c | 4 +- drivers/power/tps6586x.c | 27 +-- drivers/spi/spi-uclass.c | 34 +-- include/config_fallbacks.h | 6 + include/configs/apalis_t30.h | 3 - include/configs/beaver.h | 3 - include/configs/cardhu.h | 5 - include/configs/colibri_t30.h | 3 - include/configs/dalmore.h | 5 - include/configs/jetson-tk1.h | 5 - include/configs/norrin.h | 5 - include/configs/sandbox.h | 6 + include/configs/seaboard.h | 3 - include/configs/tec-ng.h | 5 - include/configs/tegra-common.h | 1 + include/configs/tegra114-common.h | 3 - include/configs/tegra124-common.h | 3 - include/configs/tegra20-common.h | 3 - include/configs/tegra30-common.h | 3 - include/configs/trimslice.h | 3 - include/configs/venice2.h | 5 - include/configs/whistler.h | 3 - include/dm/device.h | 19 ++ include/dm/lists.h | 13 ++ include/dm/uclass-id.h | 4 + include/i2c.h | 288 +++++++++++++++++++++++ include/i2c_eeprom.h | 19 ++ include/spi.h | 14 +- include/tps6586x.h | 4 +- lib/fdtdec.c | 6 +- test/dm/Makefile | 1 + test/dm/i2c.c | 112 +++++++++ test/dm/test.dts | 17 ++ 57 files changed, 1690 insertions(+), 432 deletions(-)Quoted 8 lines
create mode 100644
arch/sandbox/include/asm/test.hcreate mode 100644drivers/i2c/i2c-emul-uclass.ccreate mode 100644drivers/i2c/i2c-uclass.ccreate mode 100644drivers/i2c/sandbox_i2c.ccreate mode 100644drivers/misc/i2c_eeprom.ccreate mode 100644drivers/misc/i2c_eeprom_emul.ccreate mode 100644include/i2c_eeprom.hcreate mode 100644test/dm/i2c.c
Quoted 3 lines
Thanks for your great work. I acked all your patches, so from my side, you can push it through your dm tree into mainline. If you want that I pick up your patches please inform me, thanks!
Thanks. Yes I will pick it up via the DM tree - will just wait a little longer in case Tom or Stephen have tegra comments.
Regards,
Simon
v2 cover dm: Add I2C support and convert sandbox, tegra
In reply to Simon GlassHi Simon,
Quoted 23 lines · On Tue, 11 Nov 2014 10:46:16 -0700 Simon Glass <[email protected]> wrote:
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chipwhich is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic is removed. With driver model
i2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().
Quoted 6 lines
I2C muxes are not yet supported. To support these we will need to maintain state of the current mux settings to avoid resetting every mux every time. Probably we need to add a sandbox I2C mux driver to permit testing of this. This can probably be done later.
Platform data is not yet supported either, only device tree. The
This statement implies that platform data will (should) be supported in the future, I think.
As you know, I have a strong belief that device tree should be left optional.
If platform data is supported someday, that's OK.
Best Regards
Masahiro Yamada
v2 cover dm: Add I2C support and convert sandbox, tegra
Hello Masahiro,
Am 19.11.2014 09:27, schrieb Masahiro Yamada:
Quoted 35 lines
Hi Simon,
Quoted 28 lines · On Tue, 11 Nov 2014 10:46:16 -0700 Simon Glass <[email protected]> wrote:
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chipwhich is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic is removed. With driver model
i2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().I2C muxes are not yet supported. To support these we will need to maintain state of the current mux settings to avoid resetting every mux every time. Probably we need to add a sandbox I2C mux driver to permit testing of this. This can probably be done later.
Quoted 4 lines
Quoted 1 line
Platform data is not yet supported either, only device tree. The
This statement implies that platform data will (should) be supported in the future, I think.
There was a discussion on the ELCE2014 and I think, I thought such a thread also on the list, if we should only support device tree with DM ...
Quoted 1 line
As you know, I have a strong belief that device tree should be left optional.
Yes, I think in this direction too ... as I do not know, if all archs ever support DT ... and in the SPL case we should have a memory friendlier option too ...
Quoted 1 line
If platform data is supported someday, that's OK.
Patches welcome ... I have this on my ToDo list, but find currently no time ...
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
v2 cover dm: Add I2C support and convert sandbox, tegra
Hi Heiko,
Quoted 56 lines · Heiko Schocher
Hello Masahiro,
Am 19.11.2014 09:27, schrieb Masahiro Yamada:
Quoted 41 lines
Hi Simon,
Quoted 34 lines · On Tue, 11 Nov 2014 10:46:16 -0700 Simon Glass <[email protected]> wrote:
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chip
which is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would
be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic
is removed. With driver modeli2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().I2C muxes are not yet supported. To support these we will need to maintain
state of the current mux settings to avoid resetting every mux every time.
Probably we need to add a sandbox I2C mux driver to permit testing of this.
This can probably be done later.Quoted 5 lines
Quoted 1 line
Platform data is not yet supported either, only device tree. The
This statement implies that platform data will (should) be supported in the future, I think.
There was a discussion on the ELCE2014 and I think, I thought such a thread also on the list, if we should only support device tree with DM ...
Quoted 7 lines
Quoted 2 lines
As you know, I have a strong belief that device tree should be left optional.
Yes, I think in this direction too ... as I do not know, if all archs ever support DT ... and in the SPL case we should have a memory friendlier option too ...
My feeling is that if Linux uses FDT for a platform (e.g. ARM) we should do so in U-Boot.
Quoted 6 lines
Quoted 2 lines
If platform data is supported someday, that's OK.
Patches welcome ... I have this on my ToDo list, but find currently no time ...
I'm going to play around with a PPC board at some point, so will see what happens there.
Regards,
Simon
v2 cover dm: Add I2C support and convert sandbox, tegra
Hello Simon,
Am 20.11.2014 18:31, schrieb Simon Glass:
Quoted 63 lines
Hi Heiko,
Quoted 60 lines · Heiko Schocher
Hello Masahiro,
Am 19.11.2014 09:27, schrieb Masahiro Yamada:
Quoted 41 lines
Hi Simon,
Quoted 34 lines · On Tue, 11 Nov 2014 10:46:16 -0700 Simon Glass <[email protected]> wrote:
This series adds I2C support to driver model. It has become apparent that this is a high priority as it is widely used. It follows along to some extent from the SPI conversion.
Several changes are made from the original I2C implementations.
Firstly it is not necessary to specify the chip address with every call, since each chip knows its own address - it is stored in struct
dm_i2c_chip
which is attached to each chip on the I2C bus. However, this information *is* passed to the driver since I presume most drivers need it and it would
be cumbersome to look up in every call.Secondly there is no concept of a 'current' I2C bus so all associated logic
is removed. With driver modeli2c_set_bus_num()andi2c_get_bus_num()are not available. Since the chip device specifies both the bus and the chip address, there is no need for this concept. It also causes problems when one driver changes the current bus and forgets to change it back.Thirdly initialisation is handled by driver model's normal
probe()method on each device so there should be no need fori2c_init_all(),i2c_init(),i2c_init_board(),i2c_board_late_init()andboard_i2c_init().I2C muxes are not yet supported. To support these we will need to maintain
state of the current mux settings to avoid resetting every mux every time.
Probably we need to add a sandbox I2C mux driver to permit testing of this.
This can probably be done later.Quoted 5 lines
Quoted 1 line
Platform data is not yet supported either, only device tree. The
This statement implies that platform data will (should) be supported in the future, I think.
There was a discussion on the ELCE2014 and I think, I thought such a thread also on the list, if we should only support device tree with DM ...
Quoted 2 lines
As you know, I have a strong belief that device tree should be left optional.
Quoted 6 lines
Quoted 3 lines
Yes, I think in this direction too ... as I do not know, if all archs ever support DT ... and in the SPL case we should have a memory friendlier option too ...
My feeling is that if Linux uses FDT for a platform (e.g. ARM) we should do so in U-Boot.
Yes, but we have architectures without FDT support yet ... and we boot also non linux OSes ...
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
If platform data is supported someday, that's OK.
Patches welcome ... I have this on my ToDo list, but find currently no time ...
I'm going to play around with a PPC board at some point, so will see what happens there.
Great, but powerpc should work with DT too...
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany