lkml.org 
[lkml]   [2008]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH 5/6] RTC: SMBus support for the M41T80, etc. driver (#2)
Hi Maciej,

On Tue, 13 May 2008 04:27:30 +0100 (BST), Maciej W. Rozycki wrote:
> The BCM1250A SOC which is used on the SWARM board utilising an M41T81
> chip only supports pure I2C in the raw bit-banged mode. Nobody sane
> really wants to use it unless absolutely necessary and the M41T80, etc.
> chips work just fine with an SMBus adapter which is what the standard mode
> of operation of the BCM1250A. The only drawback of byte accesses with the
> M41T80 is the chip only latches clock data registers for the duration of
> an I2C transaction which works fine with a block transfers, but not
> byte-wise accesses.
>
> The driver currently requires an I2C adapter providing both SMBus and raw
> I2C access. This is a set of changes to make it work with any SMBus
> adapter providing at least read byte and write byte protocols.
> Additionally, if a given SMBus adapter supports I2C block read and/or
> write protocols (a common extension beyond the SMBus spec), they are used
> as well. The problem of unlatched clock data if SMBus byte transactions
> are used is resolved in the standard way. For raw I2C controllers this
> functionality is provided by the I2C core as SMBus emulation in a
> transparent way.
>
> Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>

The I2C part of the changes look OK to me. With one comment below:

> +static int m41t80_get_datetime(struct i2c_client *client, struct rtc_time *tm)
> +{
> + u8 buf[M41T80_DATETIME_REG_SIZE];
> + int loops = 2;
> + int sec0, sec1;
> +
> + /*
> + * Time registers are latched by this chip if an I2C block
> + * transfer is used, but with SMBus-style byte accesses
> + * this is not the case, so check seconds for a wraparound.
> + */
> + do {
> + if (m41t80_read_block_data(client, M41T80_REG_SEC,
> + M41T80_DATETIME_REG_SIZE -
> + M41T80_REG_SEC,
> + buf + M41T80_REG_SEC) < 0) {
> + dev_err(&client->dev, "read error\n");
> + return -EIO;
> + }
> + sec0 = buf[M41T80_REG_SEC];
>
> - tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f);
> + sec1 = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
> + if (sec1 < 0) {
> + dev_err(&client->dev, "read error\n");
> + return -EIO;
> + }
> +
> + sec0 = BCD2BIN(sec0 & 0x7f);
> + sec1 = BCD2BIN(sec1 & 0x7f);
> + } while (sec1 < sec0 && --loops);

You will do this even if all the registers were read as a block and the
RTC latched the register values so they have to be correct. Isn't it a
bit unfair / inefficient? If client->adapter has the
I2C_FUNC_SMBUS_READ_I2C_BLOCK functionality you can skip the comparison
and retry mechanism completely, saving some time and CPU cycles.

--
Jean Delvare


\
 
 \ /
  Last update: 2008-05-13 14:07    [W:0.067 / U:0.168 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site