diff mbox series

bootcount: make i2c version ready for DM driver

Message ID 20200122083327.29691-1-holger.brunck@ch.abb.com
State Superseded
Delegated to: Heiko Schocher
Headers show
Series bootcount: make i2c version ready for DM driver | expand

Commit Message

Holger Brunck Jan. 22, 2020, 8:33 a.m. UTC
If the board already uses DM_I2C we need to use the dm i2c calls.

Signed-off-by: Holger Brunck <holger.brunck@ch.abb.com>
CC: Heiko Schocher <hs@denx.de>
CC: Marek Vasut <marex@denx.de>
---
 drivers/bootcount/bootcount_i2c.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Heiko Schocher Jan. 27, 2020, 6:14 a.m. UTC | #1
Hello Holger,

Am 22.01.2020 um 09:33 schrieb Holger Brunck:
> If the board already uses DM_I2C we need to use the dm i2c calls.
> 
> Signed-off-by: Holger Brunck <holger.brunck@ch.abb.com>
> CC: Heiko Schocher <hs@denx.de>
> CC: Marek Vasut <marex@denx.de>
> ---
>   drivers/bootcount/bootcount_i2c.c | 21 +++++++++++++++++++++
>   1 file changed, 21 insertions(+)
> 
> diff --git a/drivers/bootcount/bootcount_i2c.c b/drivers/bootcount/bootcount_i2c.c
> index 496741d63f..24b9bd2fed 100644
> --- a/drivers/bootcount/bootcount_i2c.c
> +++ b/drivers/bootcount/bootcount_i2c.c
> @@ -14,11 +14,21 @@ void bootcount_store(ulong a)
>   {
>   	unsigned char buf[3];
>   	int ret;
> +#ifdef CONFIG_DM_I2C
> +	struct udevice *eedev = NULL;
> +#endif
>   
>   	buf[0] = BC_MAGIC;
>   	buf[1] = (a & 0xff);
> +#ifdef CONFIG_DM_I2C
> +	ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_RTC_ADDR,
> +				      1, &eedev);

Hmm... with DM/DTS approach I think we should get rid of CONFIG_SYS_I2C_RTC_ADDR
define. Also I can think about i2c bootcounters not on RTC instead on PMIC
(PFUZE100 for example has also embedded memory, if no battery is connected to
the PMIC you can use for bootcounter purposes)

So I thought first to add something like MFD in linux here. A subdevice is
the RTC part the other part is the "memory device" ... and a part of this
memory than gets reserved for the "bootcounter" device. The bootcounter
device itself than only uses mfd->read/write functions or may even better
regmap_read/write ...

This would result in a bootounter device you can use on I2C RTC/PMIC/...
and may SPI based devices which have some memory. May with regmap
approach we can also handle I/O memory based devices ... and have one
DM based bootcount driver. Also this embedded memory in I2C devices can
be used for other purposes in a clean way ...

But this is not a "made in 1 day" change.

And may to much effort for a bootloader ... ?

So simply looked into drivers/bootcounter and found an already DM based
I2C RTC implementation which should fit for you too!

Please look into: u-boot:/drivers/bootcount/rtc.c
u-boot:doc/device-tree-bindings/chosen.txt

/ {
         chosen {
                 u-boot,bootcount-device = &bootcount-rv3029;
         };

         bootcount-rv3029: bootcount@0 {
                 compatible = "u-boot,bootcount-rtc";
                 rtc = &rv3029;
                 offset = <0x38>;
         };

         i2c2 {
                 rv3029: rtc@56 {
                                 compatible = "mc,rv3029";
                                 reg = <0x56>;
                 };
         };
};

If your I2C RTC device driver already supports read8/write8 ops, it
should work out of the box... of course with adapted DTS settings from
above example...

pollux:u-boot hs [master] $ grep -lr write8 drivers/rtc/
drivers/rtc/s35392a.c
drivers/rtc/isl1208.c
drivers/rtc/mc146818.c
drivers/rtc/ds3232.c
drivers/rtc/rx8010sj.c
drivers/rtc/sandbox_rtc.c
drivers/rtc/rv3029.c
drivers/rtc/rtc-uclass.c
pollux:u-boot hs [master] $

If your rtc is in this list, please try above dm based bootcount driver.

Thanks!

bye,
Heiko
diff mbox series

Patch

diff --git a/drivers/bootcount/bootcount_i2c.c b/drivers/bootcount/bootcount_i2c.c
index 496741d63f..24b9bd2fed 100644
--- a/drivers/bootcount/bootcount_i2c.c
+++ b/drivers/bootcount/bootcount_i2c.c
@@ -14,11 +14,21 @@  void bootcount_store(ulong a)
 {
 	unsigned char buf[3];
 	int ret;
+#ifdef CONFIG_DM_I2C
+	struct udevice *eedev = NULL;
+#endif
 
 	buf[0] = BC_MAGIC;
 	buf[1] = (a & 0xff);
+#ifdef CONFIG_DM_I2C
+	ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_RTC_ADDR,
+				      1, &eedev);
+	if (ret == 0)
+		ret = dm_i2c_write(eedev, CONFIG_SYS_BOOTCOUNT_ADDR, buf, 2);
+#else
 	ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, CONFIG_SYS_BOOTCOUNT_ADDR,
 		  CONFIG_BOOTCOUNT_ALEN, buf, 2);
+#endif
 	if (ret != 0)
 		puts("Error writing bootcount\n");
 }
@@ -27,9 +37,20 @@  ulong bootcount_load(void)
 {
 	unsigned char buf[3];
 	int ret;
+#ifdef CONFIG_DM_I2C
+	struct udevice *eedev = NULL;
 
+	ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_RTC_ADDR,
+				      1, &eedev);
+	if (ret) {
+		puts("Error getting i2c bus for bootcount\n");
+		return 0;
+	}
+	ret = dm_i2c_read(eedev, CONFIG_SYS_BOOTCOUNT_ADDR, buf, 2);
+#else
 	ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, CONFIG_SYS_BOOTCOUNT_ADDR,
 		       CONFIG_BOOTCOUNT_ALEN, buf, 2);
+#endif
 	if (ret != 0) {
 		puts("Error loading bootcount\n");
 		return 0;