All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Marko <robert.marko@sartura.hr>
To: Guenter Roeck <linux@roeck-us.net>
Cc: jdelvare@suse.com, corbet@lwn.net, linux-hwmon@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	Luka Perkov <luka.perkov@sartura.hr>,
	jmp@epiphyte.org, Paul Menzel <pmenzel@molgen.mpg.de>,
	Donald Buczek <buczek@molgen.mpg.de>
Subject: Re: [PATCH 1/3] hwmon: (pmbus) Add driver for Delta DPS-920AB PSU
Date: Thu, 27 May 2021 21:43:33 +0200	[thread overview]
Message-ID: <CA+HBbNHsgS_ZTf5_n0LDSv=6ztUHJ4sweWJL7=AGeR5nhu6Zrw@mail.gmail.com> (raw)
In-Reply-To: <20210527192657.GA3454023@roeck-us.net>

On Thu, May 27, 2021 at 9:27 PM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Thu, May 27, 2021 at 09:14:03PM +0200, Robert Marko wrote:
> > On Thu, May 27, 2021 at 6:37 PM Guenter Roeck <linux@roeck-us.net> wrote:
> > >
> > > On 5/27/21 7:58 AM, Robert Marko wrote:
> > > [ ... ]
> > >
> > > >>>>>> I tried applying the block support for mv64xx as well:
> > > >>>>>> https://patchwork.ozlabs.org/project/linux-i2c/patch/20200118115820.9080-1-fuga@studiofuga.com/
> > > >>>>
> > > >>>> That patch would be needed, but it looks buggy to me. This chunk:
> > > >>>>
> > > >>>> +               drv_data->effective_length = data+1;
> > > >>>> +               drv_data->bytes_left = data+1;
> > > >>>> +               drv_data->msg->len = data+1;
> > > >>>>
> > > >>>> should be:
> > > >>>>
> > > >>>> +               drv_data->effective_length = data+1;
> > > >>>> +               drv_data->bytes_left = data;
> > > >>>> +               drv_data->msg->len = data+1;
> > > >>>>
> > > >>>> It should also make sure that 'data' is not larger than I2C_SMBUS_BLOCK_MAX,
> > > >>>> and bail out if it isn't.
> > > >>>
> > > >>> Yeah, I did not check the contents, I just saw 2 reviews and tested it
> > > >>> since it can't hurt.
> > > >>
> > > >> That patch doesn't work at all. Make the above change, and also change
> > > >> the type of effective_length from u32 to int, and try again.
> > > >
> > > > I was just looking and it, and doing the changes you recommended make
> > > > no difference at all.
> > > >
> > >
> > > Is the i2c controller compatible with marvell,mv78230-i2c ?
> > > The block transfers would not work in that case. Let me know
> > > and I'll send you a patch that might fix it.
> >
> > Yes, the CPU is Armada 7040 and I can see that compatible is
> > marvell,mv78230-i2c indeed.
> >
> > It would be great if you have the patch,
>
> See below.

I can confirm that this does indeed enable block reads and
i2c_smbus_read_block_data()
works now.

PMBUS_MFR_ID and PMBUS_MFR_MODEL are indeed populated.

Regards,
Robert

>
> Guenter
>
> ---
> From 41f6113560e3082293cef6e8f2013e70ee8f54db Mon Sep 17 00:00:00 2001
> From: Federico Fuga <fuga@studiofuga.com>
> Date: Sat, 18 Jan 2020 12:58:20 +0100
> Subject: [PATCH] i2c: mv64xxx: Implement I2C_M_RECV_LEN and
>  I2C_FUNC_SMBUS_READ_BLOCK_DATA
>
> The i2c_mv64xxx driver doesn't implement the I2C_M_REC_LEN function
> essential to allow blocks with variable length to be read from an i2c
>  slave.
> This is needed to implement the SMBus Read Block Data function.
>
> This patch implements the function by changing the bytes_left and
> msg len on the fly if the flag is specified.
>
> It has been successfully tested on Allwinner A33 with a special
> i2c chip that returns variable length blocks on reading.
>
> Signed-off-by: Federico Fuga <fuga@studiofuga.com>
> Acked-by: Gregory CLEMENT <gregory.clement@bootlin.com>
> Link: https://lore.kernel.org/r/20200118115820.9080-1-fuga@studiofuga.com
> [groeck: Various fixes]
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/i2c/busses/i2c-mv64xxx.c | 75 ++++++++++++++++++++++++++------
>  1 file changed, 61 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index 5c8e94b6cdb5..9dda90359966 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -341,7 +341,17 @@ static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data)
>  {
>         drv_data->msg = drv_data->msgs;
>         drv_data->byte_posn = 0;
> -       drv_data->bytes_left = drv_data->msg->len;
> +
> +       /*
> +        * If we should retrieve the length from the buffer, make sure
> +        * to read enough bytes to avoid sending the STOP bit after
> +        * the read if the first byte
> +        */
> +       if (drv_data->msg->flags & I2C_M_RECV_LEN)
> +               drv_data->bytes_left = 3;
> +       else
> +               drv_data->bytes_left = drv_data->msg->len;
> +
>         drv_data->aborting = 0;
>         drv_data->rc = 0;
>
> @@ -350,6 +360,47 @@ static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data)
>                drv_data->reg_base + drv_data->reg_offsets.control);
>  }
>
> +static void
> +mv64xxx_i2c_do_send_stop(struct mv64xxx_i2c_data *drv_data)
> +{
> +       drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
> +       writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
> +              drv_data->reg_base + drv_data->reg_offsets.control);
> +       drv_data->block = 0;
> +       if (drv_data->errata_delay)
> +               udelay(5);
> +
> +       wake_up(&drv_data->waitq);
> +}
> +
> +static void
> +mv64xxx_i2c_do_read_data(struct mv64xxx_i2c_data *drv_data)
> +{
> +       u8 data;
> +
> +       data = readl(drv_data->reg_base + drv_data->reg_offsets.data);
> +       drv_data->msg->buf[drv_data->byte_posn++] = data;
> +
> +       if (drv_data->msg->flags & I2C_M_RECV_LEN) {
> +               if (!data || data > I2C_SMBUS_BLOCK_MAX) {
> +                       /*
> +                        * FIXME
> +                        * Abort and report error. Needs to be
> +                        * verified/tested on real hardware.
> +                        */
> +                       drv_data->rc = -EPROTO;
> +                       mv64xxx_i2c_do_send_stop(drv_data);
> +                       return;
> +               }
> +               drv_data->msg->flags &= ~I2C_M_RECV_LEN;
> +               drv_data->bytes_left = data;
> +               drv_data->msg->len = data + 1;
> +       }
> +
> +       writel(drv_data->cntl_bits,
> +              drv_data->reg_base + drv_data->reg_offsets.control);
> +}
> +
>  static void
>  mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  {
> @@ -400,23 +451,13 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>                 break;
>
>         case MV64XXX_I2C_ACTION_RCV_DATA:
> -               drv_data->msg->buf[drv_data->byte_posn++] =
> -                       readl(drv_data->reg_base + drv_data->reg_offsets.data);
> -               writel(drv_data->cntl_bits,
> -                       drv_data->reg_base + drv_data->reg_offsets.control);
> +               mv64xxx_i2c_do_read_data(drv_data);
>                 break;
>
>         case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
>                 drv_data->msg->buf[drv_data->byte_posn++] =
>                         readl(drv_data->reg_base + drv_data->reg_offsets.data);
> -               drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
> -               writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
> -                       drv_data->reg_base + drv_data->reg_offsets.control);
> -               drv_data->block = 0;
> -               if (drv_data->errata_delay)
> -                       udelay(5);
> -
> -               wake_up(&drv_data->waitq);
> +               mv64xxx_i2c_do_send_stop(drv_data);
>                 break;
>
>         case MV64XXX_I2C_ACTION_INVALID:
> @@ -680,6 +721,10 @@ mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data)
>         if (!drv_data->offload_enabled)
>                 return false;
>
> +       /* Offload not supported for block data transfers */
> +       if (msgs[0].flags & I2C_M_RECV_LEN)
> +               return false;
> +
>         /*
>          * We can offload a transaction consisting of a single
>          * message, as long as the message has a length between 1 and
> @@ -697,6 +742,7 @@ mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data)
>             mv64xxx_i2c_valid_offload_sz(msgs) &&
>             mv64xxx_i2c_valid_offload_sz(msgs + 1) &&
>             !(msgs[0].flags & I2C_M_RD) &&
> +           !(msgs[1].flags & I2C_M_RECV_LEN) &&
>             msgs[1].flags & I2C_M_RD)
>                 return true;
>
> @@ -713,7 +759,8 @@ mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data)
>  static u32
>  mv64xxx_i2c_functionality(struct i2c_adapter *adap)
>  {
> -       return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
> +       return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
> +               I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_EMUL;
>  }
>
>  static int
> --
> 2.25.1
>


-- 
Robert Marko
Staff Embedded Linux Engineer
Sartura Ltd.
Lendavska ulica 16a
10000 Zagreb, Croatia
Email: robert.marko@sartura.hr
Web: www.sartura.hr

  reply	other threads:[~2021-05-27 19:43 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-30 13:27 [PATCH 1/3] hwmon: (pmbus) Add driver for Delta DPS-920AB PSU Robert Marko
2021-04-30 13:27 ` [PATCH 2/3] dt-bindings: hwmon: pmbus: Add Delta DPS920AB PSU driver bindings Robert Marko
2021-04-30 13:48   ` Guenter Roeck
2021-04-30 13:27 ` [PATCH 3/3] MAINTAINERS: Add Delta DPS920AB PSU driver Robert Marko
2021-04-30 13:48 ` [PATCH 1/3] hwmon: (pmbus) Add driver for Delta DPS-920AB PSU Guenter Roeck
2021-05-19 12:38   ` Robert Marko
2021-05-19 13:19     ` Guenter Roeck
2021-05-21  8:36       ` Robert Marko
2021-05-21 10:56         ` Guenter Roeck
2021-05-21 11:56           ` Robert Marko
2021-05-21 14:46             ` Guenter Roeck
2021-05-24 12:21               ` Robert Marko
2021-05-24 13:47                 ` Guenter Roeck
2021-05-27 10:22                   ` Robert Marko
2021-05-27 10:59                     ` Robert Marko
2021-05-27 14:03                       ` Guenter Roeck
2021-05-27 14:17                         ` Robert Marko
2021-05-27 14:50                           ` Guenter Roeck
2021-05-27 14:58                             ` Robert Marko
2021-05-27 16:37                               ` Guenter Roeck
2021-05-27 19:14                                 ` Robert Marko
2021-05-27 19:26                                   ` Guenter Roeck
2021-05-27 19:43                                     ` Robert Marko [this message]
2021-05-27 20:23                                       ` Guenter Roeck
2021-05-27 22:11                                       ` Guenter Roeck
2021-05-21 11:41         ` Guenter Roeck
2021-05-21 12:33           ` Robert Marko
2021-05-21 14:27             ` Guenter Roeck

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='CA+HBbNHsgS_ZTf5_n0LDSv=6ztUHJ4sweWJL7=AGeR5nhu6Zrw@mail.gmail.com' \
    --to=robert.marko@sartura.hr \
    --cc=buczek@molgen.mpg.de \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=jdelvare@suse.com \
    --cc=jmp@epiphyte.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=luka.perkov@sartura.hr \
    --cc=pmenzel@molgen.mpg.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.