From: Philip Richard Oberfichtner <pro@denx.de>
To: u-boot@lists.denx.de
Cc: hs@denx.de, sjg@chromium.org, trini@konsulko.com,
Philip Richard Oberfichtner <pro@denx.de>
Subject: [PATCH 2/2] bootcount: Add driver model I2C driver
Date: Fri, 13 Oct 2023 11:43:02 +0200 [thread overview]
Message-ID: <20231013094302.28944-3-pro@denx.de> (raw)
In-Reply-To: <20231013094302.28944-1-pro@denx.de>
This adds a generic I2C bootcounter adhering to driver model to replace
the previously removed legacy implementation.
There is no change in functionality, it can be used on any I2C device.
The device tree configuration may look like this for example:
bootcount {
compatible = "u-boot,bootcount-i2c";
i2c-bus = <&i2c1>;
address = <0x52>;
offset = <0x11>;
};
Signed-off-by: Philip Richard Oberfichtner <pro@denx.de>
---
drivers/bootcount/Kconfig | 10 +++
drivers/bootcount/Makefile | 1 +
drivers/bootcount/bootcount_dm_i2c.c | 126 +++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
create mode 100644 drivers/bootcount/bootcount_dm_i2c.c
diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index 7a2548ace2..1cf1de2b6d 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -109,6 +109,16 @@ config DM_BOOTCOUNT_RTC
Accesses to the backing store are performed using the write16
and read16 ops of DM RTC devices.
+config DM_BOOTCOUNT_I2C
+ bool "Driver Model boot counter on I2C device"
+ depends on DM_I2C
+ help
+ Enable support for the bootcounter on a generic i2c device, like a
+ RTC or PMIC. This requires an 'i2c-bus', the i2c chip 'address' and
+ the 'offset' to read to and write from. All of the three settings are
+ defined as device tree properties using the "u-boot,bootcount-i2c"
+ compatible string.
+
config DM_BOOTCOUNT_I2C_EEPROM
bool "Support i2c eeprom devices as a backing store for bootcount"
depends on I2C_EEPROM
diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
index d6d2389c16..e7771f5b36 100644
--- a/drivers/bootcount/Makefile
+++ b/drivers/bootcount/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_DM_BOOTCOUNT) += bootcount-uclass.o
obj-$(CONFIG_DM_BOOTCOUNT_PMIC_PFUZE100) += pmic_pfuze100.o
obj-$(CONFIG_DM_BOOTCOUNT_RTC) += rtc.o
obj-$(CONFIG_DM_BOOTCOUNT_I2C_EEPROM) += i2c-eeprom.o
+obj-$(CONFIG_DM_BOOTCOUNT_I2C) += bootcount_dm_i2c.o
obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH) += spi-flash.o
obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o
diff --git a/drivers/bootcount/bootcount_dm_i2c.c b/drivers/bootcount/bootcount_dm_i2c.c
new file mode 100644
index 0000000000..227641f77e
--- /dev/null
+++ b/drivers/bootcount/bootcount_dm_i2c.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023
+ * Philip Richard Oberfichtner <pro@denx.de>
+ *
+ * Based on previous work from Heiko Schocher (legacy bootcount_i2c.c driver)
+ */
+
+#include <bootcount.h>
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+
+#define BC_MAGIC 0x55
+
+struct bootcount_i2c_priv {
+ struct udevice *chip;
+ unsigned int offset;
+};
+
+static int bootcount_i2c_set(struct udevice *dev, const u32 val)
+{
+ int ret;
+ struct bootcount_i2c_priv *priv = dev_get_priv(dev);
+
+ ret = dm_i2c_reg_write(priv->chip, priv->offset, BC_MAGIC);
+ if (ret < 0)
+ goto err_exit;
+
+ ret = dm_i2c_reg_write(priv->chip, priv->offset + 1, val & 0xff);
+ if (ret < 0)
+ goto err_exit;
+
+ return 0;
+
+err_exit:
+ log_debug("%s: Error writing to I2C device (%d)\n", __func__, ret);
+ return ret;
+}
+
+static int bootcount_i2c_get(struct udevice *dev, u32 *val)
+{
+ int ret;
+ struct bootcount_i2c_priv *priv = dev_get_priv(dev);
+
+ ret = dm_i2c_reg_read(priv->chip, priv->offset);
+ if (ret < 0)
+ goto err_exit;
+
+ if ((ret & 0xff) != BC_MAGIC) {
+ log_debug("%s: Invalid Magic, reset bootcounter.\n", __func__);
+ *val = 0;
+ return bootcount_i2c_set(dev, 0);
+ }
+
+ ret = dm_i2c_reg_read(priv->chip, priv->offset + 1);
+ if (ret < 0)
+ goto err_exit;
+
+ *val = ret;
+ return 0;
+
+err_exit:
+ log_debug("%s: Error reading from I2C device (%d)\n", __func__, ret);
+ return ret;
+}
+
+static int bootcount_i2c_probe(struct udevice *dev)
+{
+ struct bootcount_i2c_priv *priv = dev_get_priv(dev);
+ struct ofnode_phandle_args phandle_args;
+ struct udevice *bus;
+ unsigned int addr;
+ int ret;
+
+ ret = dev_read_u32(dev, "offset", &priv->offset);
+ if (ret) {
+ log_debug("%s: Unable to get offset\n", __func__);
+ return ret;
+ }
+
+ ret = dev_read_u32(dev, "address", &addr);
+ if (ret) {
+ log_debug("%s: Unable to get chip address\n", __func__);
+ return ret;
+ }
+
+ ret = dev_read_phandle_with_args(dev, "i2c-bus", NULL, 0, 0, &phandle_args);
+ if (ret) {
+ log_debug("%s: Unable to get phandle\n", __func__);
+ return ret;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_I2C, phandle_args.node, &bus);
+ if (ret) {
+ log_debug("%s: Unable to get i2c bus\n", __func__);
+ return ret;
+ }
+
+ ret = i2c_get_chip(bus, addr, 1, &priv->chip);
+ if (ret) {
+ log_debug("%s: Unable to get i2c chip\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct bootcount_ops bootcount_i2c_ops = {
+ .get = bootcount_i2c_get,
+ .set = bootcount_i2c_set,
+};
+
+static const struct udevice_id bootcount_i2c_ids[] = {
+ { .compatible = "u-boot,bootcount-i2c" },
+ { }
+};
+
+U_BOOT_DRIVER(bootcount_i2c) = {
+ .name = "bootcount-i2c",
+ .id = UCLASS_BOOTCOUNT,
+ .priv_auto = sizeof(struct bootcount_i2c_priv),
+ .probe = bootcount_i2c_probe,
+ .of_match = bootcount_i2c_ids,
+ .ops = &bootcount_i2c_ops,
+};
--
2.42.0
next prev parent reply other threads:[~2023-10-13 9:46 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-13 9:43 [PATCH 0/2] bootcount: Replace I2C legacy implementation by driver model Philip Richard Oberfichtner
2023-10-13 9:43 ` [PATCH 1/2] bootcount: Remove legacy I2C driver Philip Richard Oberfichtner
2023-10-13 11:21 ` Heiko Schocher
2023-10-13 11:35 ` Philip Oberfichtner
2023-10-13 12:10 ` Heiko Schocher
2023-10-13 9:43 ` Philip Richard Oberfichtner [this message]
2023-10-13 11:28 ` [PATCH 2/2] bootcount: Add driver model " Heiko Schocher
2023-10-13 12:58 ` Philip Oberfichtner
2023-10-17 12:55 ` Philip Oberfichtner
2023-10-18 3:33 ` Simon Glass
2023-10-18 4:31 ` Heiko Schocher
2023-10-18 10:58 ` Philip Oberfichtner
2023-10-18 16:10 ` Simon Glass
2023-10-20 3:18 ` Heiko Schocher
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231013094302.28944-3-pro@denx.de \
--to=pro@denx.de \
--cc=hs@denx.de \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox