public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: Jean Delvare <khali@linux-fr.org>
To: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: David Brownell <david-b@pacbell.net>,
	Alessandro Zummo <a.zummo@towertech.it>,
	Alexander Bigga <ab@mycable.de>,
	Atsushi Nemoto <anemo@mba.ocn.ne.jp>,
	i2c@lm-sensors.org, rtc-linux@googlegroups.com,
	linux-mips@linux-mips.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC][PATCH 4/4] RTC: SMBus support for the M41T80
Date: Sat, 10 May 2008 10:35:44 +0200	[thread overview]
Message-ID: <20080510103544.701c7b3f@hyperion.delvare> (raw)
In-Reply-To: <Pine.LNX.4.55.0805100116290.10552@cliff.in.clinika.pl>

Hi Maciej,

On Sat, 10 May 2008 02:35:18 +0100 (BST), Maciej W. Rozycki wrote:
> > >  Ah, I see -- I must have missed it from documentation or perhaps it is
> > > somewhat unclear.  You mean our I2C API implies a driver for a
> > 
> > It's documented in Documentation/i2c/functionality. If something is
> > unclear, please let me know and/or send a patch.
> 
>  Well, I had a look at this file while writing my changes and this is the 
> very thing that is unclear.  The only place the description refers to 
> emulation is the I2C_FUNC_SMBUS_EMUL flag and there is nothing said
> about any other I2C_FUNC_SMBUS_* flag in the context of emulation.  The 
> rest of the file refers to functionality provided by the adapter, which 
> can be reasonably assumed to be such provided directly by hardware.

OK, I've just spent some time trying to improve this piece of
documentation. I'll send it to you and the i2c list in a moment, to not
overload this thread. Please tell me if my proposed changes make the
document clearer.

> (...)
>  Will see.  For now here is a new version of the change -- aside taking 
> your and other people's comments into account I have improved the logic 
> behind required bus adapter's feature determination.

Only commenting on the i2c bits...

> -static int m41t80_get_datetime(struct i2c_client *client,
> -			       struct rtc_time *tm)
> +
> +static int m41t80_transfer(struct i2c_client *client, int write,
> +			   u8 reg, u8 num, u8 *buf)
>  {
> -	u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
> -	struct i2c_msg msgs[] = {
> -		{
> -			.addr	= client->addr,
> -			.flags	= 0,
> -			.len	= 1,
> -			.buf	= dt_addr,
> -		},
> -		{
> -			.addr	= client->addr,
> -			.flags	= I2C_M_RD,
> -			.len	= M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
> -			.buf	= buf + M41T80_REG_SEC,
> -		},
> -	};
> +	int i, rc;
>  
> -	if (i2c_transfer(client->adapter, msgs, 2) < 0) {
> -		dev_err(&client->dev, "read error\n");
> -		return -EIO;
> +	if (write) {
> +		if (i2c_check_functionality(client->adapter,
> +					    I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
> +			i = i2c_smbus_write_i2c_block_data(client,
> +							   reg, num, buf);
> +		} else {
> +			for (i = 0; i < num; i++) {
> +				rc = i2c_smbus_write_byte_data(client, reg + i,
> +							       buf[i]);
> +				if (rc < 0) {
> +					i = rc;
> +					goto out;
> +				}
> +			}
> +		}
> +	} else {
> +		if (i2c_check_functionality(client->adapter,
> +					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> +			i = i2c_smbus_read_i2c_block_data(client,
> +							  reg, num, buf);
> +		} else {
> +			for (i = 0; i < num; i++) {
> +				rc = i2c_smbus_read_byte_data(client, reg + i);
> +				if (rc < 0) {
> +					i = rc;
> +					goto out;
> +				}
> +				buf[i] = rc;
> +			}
> +		}
>  	}
> +out:
> +	return i;
> +}

I don't understand why you insist on having a single m41t80_transfer()
function for read and write transactions, when the read and write cases
share zero code. Separate functions would perform better.

> (...)
> -	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
> -				     | I2C_FUNC_SMBUS_BYTE_DATA)) {
> +	func = i2c_get_functionality(client->adapter);
> +	if (!(func & (I2C_FUNC_SMBUS_READ_I2C_BLOCK |
> +		      I2C_FUNC_SMBUS_READ_BYTE)) ||
> +	    !(func & (I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
> +		      I2C_FUNC_SMBUS_WRITE_BYTE))) {
>  		rc = -ENODEV;
>  		goto exit;
>  	}

Still not correct, sorry. The driver is still making unconditional
calls to i2c_smbus_read_byte_data() and i2c_smbus_write_byte_data(), so
the underlying adapter _must_ support I2C_FUNC_SMBUS_READ_BYTE_DATA and
I2C_FUNC_SMBUS_WRITE_BYTE_DATA (i.e. I2C_FUNC_SMBUS_BYTE_DATA), even if
it also supports the block transactions. Also, you don't have to check
for the availability of these block transactions at this point, because
you test for them at run-time in m41t80_transfer(), and the driver will
work find without them.

So the proper test here would simply be:

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_BYTE_DATA)) {
 		rc = -ENODEV;
 		goto exit;
 	}

-- 
Jean Delvare

  reply	other threads:[~2008-05-10  8:35 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-07  8:20 [RFC][PATCH 4/4] RTC: SMBus support for the M41T80, David Brownell
     [not found] ` <200805070120.03821.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-05-07 22:28   ` Maciej W. Rozycki
     [not found]     ` <Pine.LNX.4.55.0805072226180.25644-j8+e0ZhYU2SU0huXySazC6sMm+1xrEX8@public.gmane.org>
2008-05-07 23:25       ` David Brownell
     [not found]         ` <200805071625.20430.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-05-08  7:46           ` Jean Delvare
     [not found]             ` <20080508094620.5e6c973b-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-05-09  8:39               ` David Brownell
2008-05-09  0:43         ` Maciej W. Rozycki
2008-05-09  8:08           ` [i2c] " Jean Delvare
2008-05-09 20:55             ` Maciej W. Rozycki
2008-05-09 21:21               ` Jean Delvare
2008-05-10  2:21                 ` Maciej W. Rozycki
2008-05-10  6:53                   ` Jean Delvare
2008-05-10 16:36                     ` David Brownell
2008-05-20  9:20                       ` Jean Delvare
2008-05-09  9:18           ` David Brownell
2008-05-09 21:22             ` Maciej W. Rozycki
2008-05-10  7:08               ` Jean Delvare
2008-05-09 14:17           ` Atsushi Nemoto
2008-05-08  7:34       ` [RFC][PATCH 4/4] RTC: SMBus support for the M41T80 Jean Delvare
     [not found]         ` <20080508093456.340a42b0-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-05-09 19:18           ` Maciej W. Rozycki
     [not found]             ` <Pine.LNX.4.55.0805091917370.10552-j8+e0ZhYU2SU0huXySazC6sMm+1xrEX8@public.gmane.org>
2008-05-09 20:27               ` Jean Delvare
2008-05-10  1:35                 ` Maciej W. Rozycki
2008-05-10  8:35                   ` Jean Delvare [this message]
2008-05-11  1:59                     ` Maciej W. Rozycki
2008-05-11  7:40                       ` Jean Delvare
2008-05-12  2:45                       ` Atsushi Nemoto

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=20080510103544.701c7b3f@hyperion.delvare \
    --to=khali@linux-fr.org \
    --cc=a.zummo@towertech.it \
    --cc=ab@mycable.de \
    --cc=anemo@mba.ocn.ne.jp \
    --cc=david-b@pacbell.net \
    --cc=i2c@lm-sensors.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=macro@linux-mips.org \
    --cc=rtc-linux@googlegroups.com \
    /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