diff mbox series

[U-Boot,v2,07/11] sandbox: Rewrite i2c_pmic_emul.c to support PMIC with 3 bytes transmission

Message ID 20180506202608.5899-8-lukma@denx.de
State Superseded
Delegated to: Lukasz Majewski
Headers show
Series pmic: sandbox: Add support for MC34709 PMIC | expand

Commit Message

Lukasz Majewski May 6, 2018, 8:26 p.m. UTC
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>

---

Changes in v2:
- New patch

 drivers/power/pmic/i2c_pmic_emul.c | 45 ++++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 14 deletions(-)

Comments

Simon Glass May 13, 2018, 10:02 p.m. UTC | #1
Hi Lukasz,

On 7 May 2018 at 06:26, Lukasz Majewski <lukma@denx.de> wrote:
> 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>
>
> ---
>
> Changes in v2:
> - New patch
>
>  drivers/power/pmic/i2c_pmic_emul.c | 45 ++++++++++++++++++++++++++------------
>  1 file changed, 31 insertions(+), 14 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Comments below

>
> diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
> index c58ebb8825..6f227a92f3 100644
> --- a/drivers/power/pmic/i2c_pmic_emul.c
> +++ b/drivers/power/pmic/i2c_pmic_emul.c
> @@ -19,8 +19,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,
> @@ -28,16 +31,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);

Why change this?

>
>         return 0;
>  }
> @@ -54,9 +57,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)
> @@ -65,12 +69,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);

and this?

>
>         return 0;
>  }
> @@ -101,20 +105,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 dm_pmic_info *pmic_info = 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 = pmic_info->trans_len;
> +       plat->buf_size = plat->reg_count * plat->trans_len;
> +
> +       plat->reg = calloc(1, plat->buf_size);
> +       if (!plat->reg) {
> +               pr_err("Canot allocate memory (%d B) for PMIC I2C emulation!\n",
> +                      plat->buf_size);

debug()

> +               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;
>  }
> --
> 2.11.0
>

Regards,
Simon
Lukasz Majewski May 14, 2018, 10:46 a.m. UTC | #2
Hi Simon,

> Hi Lukasz,
> 
> On 7 May 2018 at 06:26, Lukasz Majewski <lukma@denx.de> wrote:
> > 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>
> >
> > ---
> >
> > Changes in v2:
> > - New patch
> >
> >  drivers/power/pmic/i2c_pmic_emul.c | 45
> > ++++++++++++++++++++++++++------------ 1 file changed, 31
> > insertions(+), 14 deletions(-)  
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> Comments below
> 
> >
> > diff --git a/drivers/power/pmic/i2c_pmic_emul.c
> > b/drivers/power/pmic/i2c_pmic_emul.c index c58ebb8825..6f227a92f3
> > 100644 --- a/drivers/power/pmic/i2c_pmic_emul.c
> > +++ b/drivers/power/pmic/i2c_pmic_emul.c
> > @@ -19,8 +19,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, @@ -28,16 +31,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);  
> 
> Why change this?

For the sandbox_pmic(), which emulates single byte transmission, the
number of registers (rw_reg) is also the index in the pool emulating
the device.

With support for devices having 3 bytes sent at once, the register
number (rw_req) cannot be used as index anymore.

> 
> >
> >         return 0;
> >  }
> > @@ -54,9 +57,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)
> > @@ -65,12 +69,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);  
> 
> and this?
> 
> >
> >         return 0;
> >  }
> > @@ -101,20 +105,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 dm_pmic_info *pmic_info =
> > 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 = pmic_info->trans_len;
> > +       plat->buf_size = plat->reg_count * plat->trans_len;
> > +
> > +       plat->reg = calloc(1, plat->buf_size);
> > +       if (!plat->reg) {
> > +               pr_err("Canot allocate memory (%d B) for PMIC I2C
> > emulation!\n",
> > +                      plat->buf_size);  
> 
> debug()

Ok

> 
> > +               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;
> >  }
> > --
> > 2.11.0
> >  
> 
> Regards,
> Simon




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
diff mbox series

Patch

diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index c58ebb8825..6f227a92f3 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -19,8 +19,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,
@@ -28,16 +31,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;
 }
@@ -54,9 +57,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)
@@ -65,12 +69,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;
 }
@@ -101,20 +105,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 dm_pmic_info *pmic_info = 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 = pmic_info->trans_len;
+	plat->buf_size = plat->reg_count * plat->trans_len;
+
+	plat->reg = calloc(1, plat->buf_size);
+	if (!plat->reg) {
+		pr_err("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;
 }