
This change enables support for MC34708 PMIC in sandbox. Now we can emulate the I2C transfers larger than 1 byte.
Notable changes for this driver:
- From now on the register number is not equal to index in the buffer, which emulates the PMIC registers
- The PMIC register's pool is now dynamically allocated up till 64 regs * 3 bytes each = 192 B
Signed-off-by: Lukasz Majewski lukma@denx.de Reviewed-by: Simon Glass sjg@chromium.org
---
Changes in v3: - Replace pr_err() with debug() - dm_pmic_info -> uc_pmic_priv
Changes in v2: - New patch
drivers/power/pmic/i2c_pmic_emul.c | 45 ++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c index c0b53091cc..61fa76a561 100644 --- a/drivers/power/pmic/i2c_pmic_emul.c +++ b/drivers/power/pmic/i2c_pmic_emul.c @@ -18,8 +18,11 @@ * @reg: PMICs registers array */ struct sandbox_i2c_pmic_plat_data { - u8 rw_reg; - u8 reg[SANDBOX_PMIC_REG_COUNT]; + u8 rw_reg, rw_idx; + u8 reg_count; + u8 trans_len; + u8 buf_size; + u8 *reg; };
static int sandbox_i2c_pmic_read_data(struct udevice *emul, uchar chip, @@ -27,16 +30,16 @@ static int sandbox_i2c_pmic_read_data(struct udevice *emul, uchar chip, { struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul);
- if (plat->rw_reg + len > SANDBOX_PMIC_REG_COUNT) { + if (plat->rw_idx + len > plat->buf_size) { pr_err("Request exceeds PMIC register range! Max register: %#x", - SANDBOX_PMIC_REG_COUNT); + plat->reg_count); return -EFAULT; }
- debug("Read PMIC: %#x at register: %#x count: %d\n", - (unsigned)chip & 0xff, plat->rw_reg, len); + debug("Read PMIC: %#x at register: %#x idx: %#x count: %d\n", + (unsigned int)chip & 0xff, plat->rw_reg, plat->rw_idx, len);
- memcpy(buffer, &plat->reg[plat->rw_reg], len); + memcpy(buffer, plat->reg + plat->rw_idx, len);
return 0; } @@ -53,9 +56,10 @@ static int sandbox_i2c_pmic_write_data(struct udevice *emul, uchar chip,
/* Set PMIC register for I/O */ plat->rw_reg = *buffer; + plat->rw_idx = plat->rw_reg * plat->trans_len;
- debug("Write PMIC: %#x at register: %#x count: %d\n", - (unsigned)chip & 0xff, plat->rw_reg, len); + debug("Write PMIC: %#x at register: %#x idx: %#x count: %d\n", + (unsigned int)chip & 0xff, plat->rw_reg, plat->rw_idx, len);
/* For read operation, set (write) only chip reg */ if (next_is_read) @@ -64,12 +68,12 @@ static int sandbox_i2c_pmic_write_data(struct udevice *emul, uchar chip, buffer++; len--;
- if (plat->rw_reg + len > SANDBOX_PMIC_REG_COUNT) { + if (plat->rw_idx + len > plat->buf_size) { pr_err("Request exceeds PMIC register range! Max register: %#x", - SANDBOX_PMIC_REG_COUNT); + plat->reg_count); }
- memcpy(&plat->reg[plat->rw_reg], buffer, len); + memcpy(plat->reg + plat->rw_idx, buffer, len);
return 0; } @@ -100,20 +104,33 @@ static int sandbox_i2c_pmic_xfer(struct udevice *emul, struct i2c_msg *msg, static int sandbox_i2c_pmic_ofdata_to_platdata(struct udevice *emul) { struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul); + struct udevice *pmic_dev = dev_get_parent(emul); + struct uc_pmic_priv *priv = dev_get_uclass_priv(pmic_dev); const u8 *reg_defaults;
debug("%s:%d Setting PMIC default registers\n", __func__, __LINE__); + plat->reg_count = pmic_reg_count(pmic_dev); + plat->trans_len = priv->trans_len; + plat->buf_size = plat->reg_count * plat->trans_len; + + plat->reg = calloc(1, plat->buf_size); + if (!plat->reg) { + debug("Canot allocate memory (%d B) for PMIC I2C emulation!\n", + plat->buf_size); + return -ENOMEM; + }
reg_defaults = dev_read_u8_array_ptr(emul, "reg-defaults", - SANDBOX_PMIC_REG_COUNT); + plat->buf_size);
if (!reg_defaults) { pr_err("Property "reg-defaults" not found for device: %s!", emul->name); + free(plat->reg); return -EINVAL; }
- memcpy(&plat->reg, reg_defaults, SANDBOX_PMIC_REG_COUNT); + memcpy(plat->reg, reg_defaults, plat->buf_size);
return 0; }