#ifdef CONFIG_PMIC_STPMIC1
case STM32MP_NVM_BANK:
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stpmic1_nvm),
+ &dev);
+ if (ret)
+ return ret;
*val = 0;
- ret = stpmic1_shadow_read_byte(word, (u8 *)val);
+ ret = misc_read(dev, -word, val, 1);
+ if (ret != 1)
+ ret = -EINVAL;
+ else
+ ret = 0;
break;
#endif /* CONFIG_PMIC_STPMIC1 */
#ifdef CONFIG_PMIC_STPMIC1
case STM32MP_NVM_BANK:
- ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stpmic1_nvm),
+ &dev);
+ if (ret)
+ return ret;
+ ret = misc_write(dev, word, &val, 1);
+ if (ret != 1)
+ ret = -EINVAL;
+ else
+ ret = 0;
break;
#endif /* CONFIG_PMIC_STPMIC1 */
#ifdef CONFIG_PMIC_STPMIC1
case STM32MP_NVM_BANK:
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stpmic1_nvm),
+ &dev);
+ if (ret)
+ return ret;
*val = 0;
- ret = stpmic1_nvm_read_byte(word, (u8 *)val);
+ ret = misc_read(dev, word, val, 1);
+ if (ret != 1)
+ ret = -EINVAL;
+ else
+ ret = 0;
break;
#endif /* CONFIG_PMIC_STPMIC1 */
#ifdef CONFIG_PMIC_STPMIC1
case STM32MP_NVM_BANK:
- ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stpmic1_nvm),
+ &dev);
+ if (ret)
+ return ret;
+ ret = misc_write(dev, -word, &val, 1);
+ if (ret != 1)
+ ret = -EINVAL;
+ else
+ ret = 0;
break;
#endif /* CONFIG_PMIC_STPMIC1 */
#include <dm.h>
#include <errno.h>
#include <i2c.h>
+#include <misc.h>
#include <sysreset.h>
#include <dm/device.h>
#include <dm/lists.h>
static int stpmic1_bind(struct udevice *dev)
{
+ int ret;
#if CONFIG_IS_ENABLED(DM_REGULATOR)
ofnode regulators_node;
int children;
dev_dbg(dev, "no child found\n");
#endif /* DM_REGULATOR */
+ if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
+ ret = device_bind_driver(dev, "stpmic1-nvm",
+ "stpmic1-nvm", NULL);
+ if (ret)
+ return ret;
+ }
+
if (CONFIG_IS_ENABLED(SYSRESET))
return device_bind_driver(dev, "stpmic1-sysreset",
"stpmic1-sysreset", NULL);
};
#ifndef CONFIG_SPL_BUILD
-static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op)
+static int stpmic1_nvm_rw(struct udevice *dev, u8 addr, u8 *buf, int buf_len,
+ enum pmic_nvm_op op)
{
- struct udevice *dev;
unsigned long timeout;
u8 cmd = STPMIC1_NVM_CMD_READ;
- int ret;
-
- ret = uclass_get_device_by_driver(UCLASS_PMIC,
- DM_GET_DRIVER(pmic_stpmic1), &dev);
- if (ret)
- /* No PMIC on power discrete board */
- return -EOPNOTSUPP;
+ int ret, len = buf_len;
if (addr < STPMIC1_NVM_START_ADDRESS)
return -EACCES;
+ if (addr + buf_len > STPMIC1_NVM_START_ADDRESS + STPMIC1_NVM_SIZE)
+ len = STPMIC1_NVM_START_ADDRESS + STPMIC1_NVM_SIZE - addr;
- if (op == SHADOW_READ)
- return pmic_read(dev, addr, buf, buf_len);
+ if (op == SHADOW_READ) {
+ ret = pmic_read(dev, addr, buf, len);
+ if (ret < 0)
+ return ret;
+ else
+ return len;
+ }
- if (op == SHADOW_WRITE)
- return pmic_write(dev, addr, buf, buf_len);
+ if (op == SHADOW_WRITE) {
+ ret = pmic_write(dev, addr, buf, len);
+ if (ret < 0)
+ return ret;
+ else
+ return len;
+ }
if (op == NVM_WRITE) {
cmd = STPMIC1_NVM_CMD_PROGRAM;
- ret = pmic_write(dev, addr, buf, buf_len);
+ ret = pmic_write(dev, addr, buf, len);
if (ret < 0)
return ret;
}
return -ETIMEDOUT;
if (op == NVM_READ) {
- ret = pmic_read(dev, addr, buf, buf_len);
+ ret = pmic_read(dev, addr, buf, len);
if (ret < 0)
return ret;
}
- return 0;
+ return len;
}
-int stpmic1_shadow_read_byte(u8 addr, u8 *buf)
+static int stpmic1_nvm_read(struct udevice *dev, int offset,
+ void *buf, int size)
{
- return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ);
-}
+ enum pmic_nvm_op op = NVM_READ;
-int stpmic1_shadow_write_byte(u8 addr, u8 *buf)
-{
- return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE);
-}
+ if (offset < 0) {
+ op = SHADOW_READ;
+ offset = -offset;
+ }
-int stpmic1_nvm_read_byte(u8 addr, u8 *buf)
-{
- return stpmic1_nvm_rw(addr, buf, 1, NVM_READ);
+ return stpmic1_nvm_rw(dev->parent, offset, buf, size, op);
}
-int stpmic1_nvm_write_byte(u8 addr, u8 *buf)
+static int stpmic1_nvm_write(struct udevice *dev, int offset,
+ const void *buf, int size)
{
- return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE);
-}
+ enum pmic_nvm_op op = NVM_WRITE;
-int stpmic1_nvm_read_all(u8 *buf, int buf_len)
-{
- if (buf_len != STPMIC1_NVM_SIZE)
- return -EINVAL;
+ if (offset < 0) {
+ op = SHADOW_WRITE;
+ offset = -offset;
+ }
- return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
- buf, buf_len, NVM_READ);
+ return stpmic1_nvm_rw(dev->parent, offset, (void *)buf, size, op);
}
-int stpmic1_nvm_write_all(u8 *buf, int buf_len)
-{
- if (buf_len != STPMIC1_NVM_SIZE)
- return -EINVAL;
+static const struct misc_ops stpmic1_nvm_ops = {
+ .read = stpmic1_nvm_read,
+ .write = stpmic1_nvm_write,
+};
- return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
- buf, buf_len, NVM_WRITE);
-}
+U_BOOT_DRIVER(stpmic1_nvm) = {
+ .name = "stpmic1-nvm",
+ .id = UCLASS_MISC,
+ .ops = &stpmic1_nvm_ops,
+};
#endif /* CONFIG_SPL_BUILD */
#ifdef CONFIG_SYSRESET