Skip to contentSkip to conversation

2.6 I2C epson 8564 RTC chip

PATCH In review [email protected] 5 participants 15 messages Apr 29, 2004 – May 2, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.6 I2C epson 8564 RTC chip

Hi,
this is my second try to send this patch, in the previous attempts I goofed up somehow and mail got duplicated. That's my first patch to LKML, so please bear with me ;)

The patch attached adds support for the Epson 8564 RTC chip. This is a RTC chip sitting on the I2C bus. AFAIK the chip's address is hardcoded in silicon.

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

I CC Greg KH because its I2C, as Andrew Morton told me to do.

The patch is against 2.6.6-rc3, but should apply cleanly to other 2.6 kernels.

Please comment,
Stefan E.

Signature · 3 lines
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de

Add support for the Epson 8564 RTC chip.

#
# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
#

drivers/i2c/chips/rtc8564.c new file +404 -0
@@ -0,0 +1,404 @@
+/*
+ *  linux/drivers/i2c/chips/rtc8564.c
+ *
+ *  Copyright (C) 2002-2004 Stefan Eletzhofer
+ *
+ *	based on linux/drivers/acron/char/pcf8583.c
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for system3's EPSON RTC 8564 chip
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/rtc.h>			/* get the user-level API */
+#include <linux/init.h>
+#include <linux/init.h>
+
+#include "rtc8564.h"
+
+#ifdef DEBUG
+# define _DBG( x, fmt, args... ) do{ if ( debug>=x ) printk( KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args ); } while(0);
+#else
+# define _DBG( x, fmt, args... ) do { } while(0);
+#endif
+
+#define _DBGRTCTM( x, rtctm ) if (debug>=x) printk( "%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
+			"mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
+			(rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
+			(rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl );
+
+struct rtc8564_data {
+	struct i2c_client client;
+	u16 ctrl;
+};
+
+static inline u8 _rtc8564_ctrl1( struct i2c_client *client )
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	return data->ctrl & 0xff;
+}
+static inline u8 _rtc8564_ctrl2( struct i2c_client *client )
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	return (data->ctrl & 0xff00) >>8;
+}
+#define CTRL1(c) _rtc8564_ctrl1( c )
+#define CTRL2(c) _rtc8564_ctrl2( c )
+
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static int debug = 0;
+MODULE_PARM(debug, "i");
+
+static struct i2c_driver rtc8564_driver;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+	.normal_i2c	= normal_addr,
+	.normal_i2c_range = ignore,
+	.probe		= ignore,
+	.probe_range	= ignore,
+	.ignore		= ignore,
+	.ignore_range	= ignore,
+	.force		= ignore,
+};
+
+static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
+static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
+
+static int rtc8564_read(struct i2c_client *client, unsigned char adr, unsigned char *buf, unsigned char len)
+{
+	int ret = -EIO;
+	unsigned char addr[1] = { adr };
+	struct i2c_msg msgs[2] = {
+		{ client->addr, 0,        1, addr },
+		{ client->addr, I2C_M_RD, len, buf  }
+	};
+
+	_DBG( 1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len );
+
+	if ( !buf || !client ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	if ( ret == 2 ) {
+		ret = 0;
+	}
+
+DONE:
+	return ret;
+}
+
+static int rtc8564_write(struct i2c_client *client, unsigned char adr, unsigned char *data, unsigned char len )
+{
+	int ret = 0;
+	unsigned char _data[ 16 ];
+	struct i2c_msg wr;
+	int i;
+
+	if ( !client || !data || len>15 ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	_DBG( 1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len );
+
+	_data[0]=adr;
+	for ( i=0; i<len; i++ ) {
+		_data[i+1]=data[i];
+		_DBG( 5, "data[%d] = 0x%02x (%d)", i, data[i], data[i] );
+	}
+
+	wr.addr = client->addr;
+	wr.flags = 0;
+	wr.len = len+1;
+	wr.buf=_data;
+
+	ret = i2c_transfer(client->adapter, &wr, 1);
+	if ( ret == 1 ) {
+		ret = 0;
+	}
+		
+DONE:
+	return ret;
+}
+
+static int
+rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+	int ret;
+	struct i2c_client *new_client;
+	struct rtc8564_data *d;
+	unsigned char data[10];
+	unsigned char ad[1] = { 0 };
+	struct i2c_msg ctrl_wr[1] = {
+		{ addr, 0, 2, data  }
+	};
+	struct i2c_msg ctrl_rd[2] = {
+		{ addr, 0,        1, ad },
+		{ addr, I2C_M_RD, 2, data  }
+	};
+
+	d = kmalloc( sizeof( struct rtc8564_data), GFP_KERNEL);
+	if (!d) {
+		ret = -ENOMEM;
+		goto DONE;
+	}
+	memset( d, 0, sizeof( struct rtc8564_data) );
+	new_client = &d->client;
+
+	strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
+	i2c_set_clientdata( new_client, d );
+	new_client->id		= rtc8564_driver.id;
+	new_client->flags	= I2C_CLIENT_ALLOW_USE|I2C_DF_NOTIFY;
+	new_client->addr	= addr;
+	new_client->adapter	= adap;
+	new_client->driver	= &rtc8564_driver;
+
+	_DBG( 1, "client=%p", new_client );
+	_DBG( 1, "client.id=%d", new_client->id );
+
+	/* init ctrl1 reg */
+	data[0]=0;
+	data[1]=0;
+	ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
+	if ( ret != 1 ) {
+		printk(KERN_INFO"rtc8564: cant init ctrl1\n" );
+		ret = -ENODEV;
+		goto DONE;
+	}
+
+	/* read back ctrl1 and ctrl2 */
+	ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
+	if ( ret != 2 ) {
+		printk(KERN_INFO"rtc8564: cant read ctrl\n" );
+		ret = -ENODEV;
+		goto DONE;
+	}
+
+	d->ctrl = data[0] | (data[1] << 8);
+
+	_DBG( 1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
+			data[0],
+			data[1] );
+
+	ret = i2c_attach_client(new_client);
+DONE:
+	if ( ret ) {
+		if ( d ) kfree( d );
+	}
+	return ret;
+}
+
+static int
+rtc8564_probe(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, rtc8564_attach);
+}
+
+static int
+rtc8564_detach(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int
+rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
+{
+	int ret = -EIO;
+	unsigned char buf[15];
+
+	_DBG( 1, "client=%p, dt=%p", client, dt );
+
+	if ( !dt || !client )
+		return -EINVAL;
+
+	memset(buf, 0, sizeof(buf));
+
+	ret = rtc8564_read(client, 0, buf, 15);
+	if ( ret )
+		return ret;
+
+	/* century stored in minute alarm reg */
+	dt->year	= BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
+	dt->year	+= 100*BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
+	dt->mday	= BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
+	dt->wday	= BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
+	dt->mon		= BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
+
+	dt->secs	= BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
+	dt->vl		= (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
+	dt->mins	= BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
+	dt->hours	= BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
+
+	_DBGRTCTM( 2, *dt );
+
+	return 0;
+}
+
+static int
+rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
+{
+	int ret, len = 5;
+	unsigned char buf[15];
+
+	_DBG( 1, "client=%p, dt=%p", client, dt );
+
+	if ( !dt || !client )
+		return -EINVAL;
+
+	_DBGRTCTM( 2, *dt );
+
+	buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
+	buf[RTC8564_REG_CTRL2] = CTRL2(client);
+	buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
+	buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
+	buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
+
+	if (datetoo) {
+		len += 5;
+		buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
+		buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
+		buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon)&0x1f;
+		/* century stored in minute alarm reg */
+		buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year%100);
+		buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year/100);
+	}
+
+	ret = rtc8564_write(client, 0, buf, len);
+	if (ret) {
+		_DBG( 1, "error writing data! %d", ret );
+	}
+
+
+	buf[RTC8564_REG_CTRL1] = CTRL1(client);
+	ret = rtc8564_write(client, 0, buf, 1);
+	if (ret) {
+		_DBG( 1, "error writing data! %d", ret );
+	}
+
+	return ret;
+}
+
+static int
+rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+
+	if ( !ctrl || !client )
+		return -1;
+
+	*ctrl = data->ctrl;
+	return 0;
+}
+
+static int
+rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	unsigned char buf[2];
+
+
+	if ( !ctrl || !client )
+		return -1;
+
+	buf[0] = *ctrl & 0xff;
+	buf[1] = (*ctrl & 0xff00) >> 8;
+	data->ctrl = *ctrl;
+
+	return rtc8564_write(client, 0, buf, 2);
+}
+
+static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
+{
+
+	if ( !mem || !client )
+		return -EINVAL;
+
+	return rtc8564_read( client, mem->loc, mem->data, mem->nr );
+}
+
+static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
+{
+
+
+	if ( !mem || !client )
+		return -EINVAL;
+
+	return rtc8564_write( client, mem->loc, mem->data, mem->nr );
+}
+
+static int
+rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+
+	_DBG( 1, "cmd=%d", cmd );
+
+	switch (cmd) {
+		case RTC_GETDATETIME:
+			return rtc8564_get_datetime(client, arg);
+
+		case RTC_SETTIME:
+			return rtc8564_set_datetime(client, arg, 0);
+
+		case RTC_SETDATETIME:
+			return rtc8564_set_datetime(client, arg, 1);
+
+		case RTC_GETCTRL:
+			return rtc8564_get_ctrl(client, arg);
+
+		case RTC_SETCTRL:
+			return rtc8564_set_ctrl(client, arg);
+
+		case MEM_READ:
+			return rtc8564_read_mem(client, arg);
+
+		case MEM_WRITE:
+			return rtc8564_write_mem(client, arg);
+
+		default:
+			return -EINVAL;
+	}
+}
+
+static struct i2c_driver rtc8564_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "RTC8564",
+	.id		= I2C_DRIVERID_RTC8564,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= rtc8564_probe,
+	.detach_client	= rtc8564_detach,
+	.command	= rtc8564_command
+};
+
+static __init int rtc8564_init(void)
+{
+	return i2c_add_driver(&rtc8564_driver);
+}
+
+static __exit void rtc8564_exit(void)
+{
+	i2c_del_driver(&rtc8564_driver);
+}
+
+MODULE_AUTHOR("Stefan Eletzhofer <[email protected]>");
+MODULE_DESCRIPTION("EPSON RTC8564 Driver");
+MODULE_LICENSE("GPL");
+
+
+module_init(rtc8564_init);
+module_exit(rtc8564_exit);
drivers/i2c/chips/rtc8564.h new file +78 -0

78 lines not on this page · raw message

drivers/i2c/chips/Makefile renamed from drivers/i2c/chips/Makefile~i2c-rtc8564 +1 -0
@@ -21,6 +21,7 @@
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 
drivers/i2c/chips/Kconfig renamed from drivers/i2c/chips/Kconfig~i2c-rtc8564 +10 -0
@@ -230,4 +230,14 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called pcf8591.
 
+config SENSORS_RTC8564
+	tristate "Epson 8564 RTC chip"
+	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the Epson 8564 RTC chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-rtc8564.
+
 endmenu
#1 lore raw

Hi Stefan,

Quoted 2 lines

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

I have a patch (attached, it could do with cleaning up) for the Dallas DS1307 I2C RTC which I ported from the 2.4 rmk patch, originally written by Intrinsyc. Currently it includes both the I2C and the RTC bits in the same driver.

Do you think it is realistic/possible to have the same generic RTC driver speak to multiple I2C devices, from what I can see in your driver the two chips seem pretty similar and the differences could probably be abstracted away. Perhaps that is your intention from the start?

I guess I will wait until you post the RTC misc driver and try and make the DS1307 one work with that before I submit it.

Ian.

Signature · 10 lines
Ian Campbell, Senior Design Engineer
                                        Web: http://www.arcom.com
Arcom, Clifton Road, 			Direct: +44 (0)1223 403 465
Cambridge CB1 7EA, United Kingdom	Phone:  +44 (0)1223 411 200


_____________________________________________________________________
The message in this transmission is sent in confidence for the attention of the addressee only and should not be disclosed to any other party. Unauthorised recipients are requested to preserve this confidentiality. Please advise the sender if the addressee is not resident at the receiving end.  Email to and from Arcom is automatically monitored for operational and lawful business reasons.

This message has been virus scanned by MessageLabs.
drivers/i2c/chips/Kconfig +4 -0
Index: linux-2.6-bkpxa/drivers/i2c/chips/Kconfig
===================================================================
@@ -230,4 +230,8 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called pcf8591.
 
+config DS1307
+	tristate "Dallas Semiconductor DS1307 Real-Time Clock"
+	depends on I2C
+
 endmenu
drivers/i2c/chips/Makefile +2 -0
Index: linux-2.6-bkpxa/drivers/i2c/chips/Makefile
===================================================================
@@ -24,6 +24,8 @@
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 
+obj-$(CONFIG_DS1307)	 	+= ds1307.o
+
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
 endif
drivers/i2c/chips/ds1307.c +602 -0

602 lines not on this page · raw message

drivers/i2c/chips/ds1307.h +52 -0

52 lines not on this page · raw message

#2 lore raw
Quoted 9 lines · Ian Campbell

Hi Stefan,

Quoted 2 lines

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

I have a patch (attached, it could do with cleaning up) for the Dallas DS1307 I2C RTC which I ported from the 2.4 rmk patch, originally written by Intrinsyc. Currently it includes both the I2C and the RTC bits in the same driver.

Have a look at drivers/acorn/char/{i2c,pcf8583}.[ch]

Quoted 7 lines

Do you think it is realistic/possible to have the same generic RTC driver speak to multiple I2C devices, from what I can see in your driver the two chips seem pretty similar and the differences could probably be abstracted away. Perhaps that is your intention from the start?

I guess I will wait until you post the RTC misc driver and try and make the DS1307 one work with that before I submit it.

If you look at the last 2.6-rmk patch, you'll notice that it contains an abstracted RTC driver - I got peed off with writing the same code to support the user interfaces to the variety of RTCs over and over again. (Ones which are simple 32-bit second counters with alarms through to ones which return D/M/Y H:M:S.C format.)

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#3 lore raw
Quoted 18 lines · Russell King
Quoted 9 lines · Ian Campbell

Hi Stefan,

Quoted 2 lines

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

I have a patch (attached, it could do with cleaning up) for the Dallas DS1307 I2C RTC which I ported from the 2.4 rmk patch, originally written by Intrinsyc. Currently it includes both the I2C and the RTC bits in the same driver.

Have a look at drivers/acorn/char/{i2c,pcf8583}.[ch]

Quoted 5 lines

Do you think it is realistic/possible to have the same generic RTC driver speak to multiple I2C devices, from what I can see in your driver the two chips seem pretty similar and the differences could probably be abstracted away. Perhaps that is your intention from the start?

Quoted 8 lines
Quoted 2 lines

I guess I will wait until you post the RTC misc driver and try and make the DS1307 one work with that before I submit it.

If you look at the last 2.6-rmk patch, you'll notice that it contains an abstracted RTC driver - I got peed off with writing the same code to support the user interfaces to the variety of RTCs over and over again. (Ones which are simple 32-bit second counters with alarms through to ones which return D/M/Y H:M:S.C format.)

Oh, I wasn't aware of that. I assume that one is not in linus bk tree already?

Quoted 11 lines
Signature · 10 lines
-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Signature · 3 lines
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de
#4 lore raw
Quoted 8 lines · On Thu, 2004-04-29 at 14:58, [email protected] wrote:
Quoted 5 lines · Russell King

If you look at the last 2.6-rmk patch, you'll notice that it contains an abstracted RTC driver - I got peed off with writing the same code to support the user interfaces to the variety of RTCs over and over again. (Ones which are simple 32-bit second counters with alarms through to ones which return D/M/Y H:M:S.C format.)

Oh, I wasn't aware of that. I assume that one is not in linus bk tree already?

I don't think so. I found it in patch-2.6.0-test9-rmk1. In particular arch/arm/common/rtctime.c and include/asm-arm/rtc.h which implement the generic RTC bit. drivers/char/sa1100-rtc.c and linux/arch/arm/mach-integrator/time.c have been ported to use it.

It looks very useful, and it would be pretty easy to make an i2c RTC use it as well.

Ian.

Signature · 10 lines
Ian Campbell, Senior Design Engineer
                                        Web: http://www.arcom.com
Arcom, Clifton Road, 			Direct: +44 (0)1223 403 465
Cambridge CB1 7EA, United Kingdom	Phone:  +44 (0)1223 411 200


_____________________________________________________________________
The message in this transmission is sent in confidence for the attention of the addressee only and should not be disclosed to any other party. Unauthorised recipients are requested to preserve this confidentiality. Please advise the sender if the addressee is not resident at the receiving end.  Email to and from Arcom is automatically monitored for operational and lawful business reasons.

This message has been virus scanned by MessageLabs.
#5 lore raw
Quoted 10 lines · Ian Campbell
Quoted 8 lines · On Thu, 2004-04-29 at 14:58, [email protected] wrote:
Quoted 5 lines · Russell King

If you look at the last 2.6-rmk patch, you'll notice that it contains an abstracted RTC driver - I got peed off with writing the same code to support the user interfaces to the variety of RTCs over and over again. (Ones which are simple 32-bit second counters with alarms through to ones which return D/M/Y H:M:S.C format.)

Oh, I wasn't aware of that. I assume that one is not in linus bk tree already?

Quoted 7 lines

I don't think so. I found it in patch-2.6.0-test9-rmk1. In particular arch/arm/common/rtctime.c and include/asm-arm/rtc.h which implement the generic RTC bit. drivers/char/sa1100-rtc.c and linux/arch/arm/mach-integrator/time.c have been ported to use it.

It looks very useful, and it would be pretty easy to make an i2c RTC use it as well.

Ah, haven't had a look at 2.6.0-test9 for some time now. I'll try to check these and maybe I'll port my rtc driver over to it. Maybe these files sould be moved out of the arm tree, though? It may well be that other platforms are interested it (at last I've found a drivers/char/genrtc.c ...).

Quoted 18 lines

Ian.

Signature · 15 lines
Ian Campbell, Senior Design Engineer
                                        Web: http://www.arcom.com
Arcom, Clifton Road, 			Direct: +44 (0)1223 403 465
Cambridge CB1 7EA, United Kingdom	Phone:  +44 (0)1223 411 200


_____________________________________________________________________
The message in this transmission is sent in confidence for the attention of the addressee only and should not be disclosed to any other party. Unauthorised recipients are requested to preserve this confidentiality. Please advise the sender if the addressee is not resident at the receiving end.  Email to and from Arcom is automatically monitored for operational and lawful business reasons.

This message has been virus scanned by MessageLabs.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Signature · 3 lines
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de
#6 lore raw
In reply to Russell King
Quoted 18 lines · Russell King
Quoted 9 lines · Ian Campbell

Hi Stefan,

Quoted 2 lines

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

I have a patch (attached, it could do with cleaning up) for the Dallas DS1307 I2C RTC which I ported from the 2.4 rmk patch, originally written by Intrinsyc. Currently it includes both the I2C and the RTC bits in the same driver.

Have a look at drivers/acorn/char/{i2c,pcf8583}.[ch]

Quoted 5 lines

Do you think it is realistic/possible to have the same generic RTC driver speak to multiple I2C devices, from what I can see in your driver the two chips seem pretty similar and the differences could probably be abstracted away. Perhaps that is your intention from the start?

Quoted 8 lines
Quoted 2 lines

I guess I will wait until you post the RTC misc driver and try and make the DS1307 one work with that before I submit it.

If you look at the last 2.6-rmk patch, you'll notice that it contains an abstracted RTC driver - I got peed off with writing the same code to support the user interfaces to the variety of RTCs over and over again. (Ones which are simple 32-bit second counters with alarms through to ones which return D/M/Y H:M:S.C format.)

A generic one for i2c rtcs or another generic rtc driver? There's already drivers/char/genrtc.c...

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#7 lore raw
Quoted 2 lines · Tom Rini

A generic one for i2c rtcs or another generic rtc driver? There's already drivers/char/genrtc.c...

genrtc.c lacks several features ARM needs, the big one being wakeup timers. It also only provides either (configurable) emulation or no support of various RTC features, rather than allowing a real RTC to provide them if it can - and you need to know the details of your RTC at kernel configuration time.

It provides no support for translating "RTC" time into seconds and vice versa which is needed for second-counter based RTCs found in PXA, StrongARM, and other ARM SoC platforms.

IOW, its fairly restrictive in what it provides and what it allows architectures to provide.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#8 lore raw
Quoted 9 lines · Russell King
Quoted 2 lines · Tom Rini

A generic one for i2c rtcs or another generic rtc driver? There's already drivers/char/genrtc.c...

genrtc.c lacks several features ARM needs, the big one being wakeup timers. It also only provides either (configurable) emulation or no support of various RTC features, rather than allowing a real RTC to provide them if it can - and you need to know the details of your RTC at kernel configuration time.

Having hacked at this, and just not having had the time to clean it up a bit more yet, did you try adding it to genrtc at least?

Quoted 3 lines

It provides no support for translating "RTC" time into seconds and vice versa which is needed for second-counter based RTCs found in PXA, StrongARM, and other ARM SoC platforms.

It couldn't be added in?

Quoted 2 lines

IOW, its fairly restrictive in what it provides and what it allows architectures to provide.

Either way, I'd like to not have 2 generic rtc drivers if at all possible...

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#9 lore raw
Quoted 2 lines · Tom Rini

Either way, I'd like to not have 2 generic rtc drivers if at all possible...

So would I...

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#10 lore raw
In reply to [email protected]
Quoted 2 lines · On Thu, 2004-04-29 at 13:02, [email protected] wrote:

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

By the way -- I notice you have said you need i2c_get_client for your RTC driver to locate the i2c chip it wants to work with.

Just a thought -- perhaps it would make sense to reverse the roles and for the rtc driver to export a 'register_rtc_device' type call which the specific i2c chip driver could then call to hook itself up to /dev/rtc

Ian.

Signature · 10 lines
Ian Campbell, Senior Design Engineer
                                        Web: http://www.arcom.com
Arcom, Clifton Road, 			Direct: +44 (0)1223 403 465
Cambridge CB1 7EA, United Kingdom	Phone:  +44 (0)1223 411 200


_____________________________________________________________________
The message in this transmission is sent in confidence for the attention of the addressee only and should not be disclosed to any other party. Unauthorised recipients are requested to preserve this confidentiality. Please advise the sender if the addressee is not resident at the receiving end.  Email to and from Arcom is automatically monitored for operational and lawful business reasons.

This message has been virus scanned by MessageLabs.
#11 lore raw
Quoted 6 lines · Ian Campbell
Quoted 2 lines · On Thu, 2004-04-29 at 13:02, [email protected] wrote:

This driver only does the low-level I2C stuff, the rtc misc device driver is a separate driver module which I will send a patch for soon.

By the way -- I notice you have said you need i2c_get_client for your RTC driver to locate the i2c chip it wants to work with.

Correct. I'll send a patch which re-adds this call to 2.6.6-rcx.

Quoted 4 lines

Just a thought -- perhaps it would make sense to reverse the roles and for the rtc driver to export a 'register_rtc_device' type call which the specific i2c chip driver could then call to hook itself up to /dev/rtc

The problem with this approach is IHMO that you need the i2c_client struct in I2C chrip driver as well (to call the i2c access primitives). You'd need to store the pointer to the client somewhere in the driver itself. What if we have more than one client per driver?

IMHO the call i2c_get_client() is nice and clean. One could wish another call like
int i2c_command( struct i2c_client *c, long cmd, void *arg );
whcih does a
client->driver->command( client, cmd, arg );
internally.

Quoted 19 lines

Ian.

Signature · 15 lines
Ian Campbell, Senior Design Engineer
                                        Web: http://www.arcom.com
Arcom, Clifton Road, 			Direct: +44 (0)1223 403 465
Cambridge CB1 7EA, United Kingdom	Phone:  +44 (0)1223 411 200


_____________________________________________________________________
The message in this transmission is sent in confidence for the attention of the addressee only and should not be disclosed to any other party. Unauthorised recipients are requested to preserve this confidentiality. Please advise the sender if the addressee is not resident at the receiving end.  Email to and from Arcom is automatically monitored for operational and lawful business reasons.

This message has been virus scanned by MessageLabs.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Signature · 3 lines
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de
#12 lore raw
In reply to [email protected]

drivers/i2c/chips/rtc8564.c line 90

Quoted 1 line · On Thu, Apr 29, 2004 at 02:02:50PM +0200, [email protected] wrote:
drivers/i2c/chips/rtc8564.c new file +1 -0
+	if ( !buf || !client ) {

Can you clean up your exuberant use of spaces in 'if' statements, and function calls? It's not the proper kernel style.

Quoted 1 line

+DONE:

Lowercase please

drivers/i2c/chips/rtc8564.c line 200

Quoted 2 lines
drivers/i2c/chips/rtc8564.c new file +2 -0
+	if ( ret ) {
+		if ( d ) kfree( d );

No need to check a pointer before sending it to kfree.

thanks,

greg k-h

#13 lore raw
Quoted 6 lines · Greg KH

Review

Quoted 1 line · On Thu, Apr 29, 2004 at 02:02:50PM +0200, [email protected] wrote:
(quoted diff) +1 -0
+	if ( !buf || !client ) {

Can you clean up your exuberant use of spaces in 'if' statements, and function calls? It's not the proper kernel style.

Quoted 8 lines
Quoted 1 line

+DONE:

Lowercase please

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if ( ret ) {
+		if ( d ) kfree( d );

No need to check a pointer before sending it to kfree.

Ok, that should be it. I've also ran the source through Lindent, which fixed some further things. I've reverted the indention change for labels, though. I think labels should be at level zero, should they?

thanks,
Stefan E.

Quoted 9 lines

thanks,

greg k-h
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Signature · 3 lines
Eletztrick Computing - Customized Linux Development
Stefan Eletzhofer, Marktstrasse 43, DE-88214 Ravensburg
http://www.eletztrick.de

Add support for the Epson 8564 RTC chip.

#
# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
#

drivers/i2c/chips/rtc8564.c new file +396 -0
@@ -0,0 +1,396 @@
+/*
+ *  linux/drivers/i2c/chips/rtc8564.c
+ *
+ *  Copyright (C) 2002-2004 Stefan Eletzhofer
+ *
+ *	based on linux/drivers/acron/char/pcf8583.c
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for system3's EPSON RTC 8564 chip
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/rtc.h>		/* get the user-level API */
+#include <linux/init.h>
+#include <linux/init.h>
+
+#include "rtc8564.h"
+
+#ifdef DEBUG
+# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
+#else
+# define _DBG(x, fmt, args...) do { } while(0);
+#endif
+
+#define _DBGRTCTM(x, rtctm) if (debug>=x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
+			"mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \
+			(rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \
+			(rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl);
+
+struct rtc8564_data {
+	struct i2c_client client;
+	u16 ctrl;
+};
+
+static inline u8 _rtc8564_ctrl1(struct i2c_client *client)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	return data->ctrl & 0xff;
+}
+static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	return (data->ctrl & 0xff00) >> 8;
+}
+
+#define CTRL1(c) _rtc8564_ctrl1(c)
+#define CTRL2(c) _rtc8564_ctrl2(c)
+
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static int debug = 0;
+MODULE_PARM(debug, "i");
+
+static struct i2c_driver rtc8564_driver;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+	.normal_i2c		= normal_addr,
+	.normal_i2c_range	= ignore,
+	.probe			= ignore,
+	.probe_range		= ignore,
+	.ignore			= ignore,
+	.ignore_range		= ignore,
+	.force			= ignore,
+};
+
+static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem);
+static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem);
+
+static int rtc8564_read(struct i2c_client *client, unsigned char adr,
+			unsigned char *buf, unsigned char len)
+{
+	int ret = -EIO;
+	unsigned char addr[1] = { adr };
+	struct i2c_msg msgs[2] = {
+		{client->addr, 0, 1, addr},
+		{client->addr, I2C_M_RD, len, buf}
+	};
+
+	_DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len);
+
+	if (!buf || !client) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	if (ret == 2) {
+		ret = 0;
+	}
+
+done:
+	return ret;
+}
+
+static int rtc8564_write(struct i2c_client *client, unsigned char adr,
+			 unsigned char *data, unsigned char len)
+{
+	int ret = 0;
+	unsigned char _data[16];
+	struct i2c_msg wr;
+	int i;
+
+	if (!client || !data || len > 15) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	_DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
+
+	_data[0] = adr;
+	for (i = 0; i < len; i++) {
+		_data[i + 1] = data[i];
+		_DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
+	}
+
+	wr.addr = client->addr;
+	wr.flags = 0;
+	wr.len = len + 1;
+	wr.buf = _data;
+
+	ret = i2c_transfer(client->adapter, &wr, 1);
+	if (ret == 1) {
+		ret = 0;
+	}
+
+done:
+	return ret;
+}
+
+static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+	int ret;
+	struct i2c_client *new_client;
+	struct rtc8564_data *d;
+	unsigned char data[10];
+	unsigned char ad[1] = { 0 };
+	struct i2c_msg ctrl_wr[1] = {
+		{addr, 0, 2, data}
+	};
+	struct i2c_msg ctrl_rd[2] = {
+		{addr, 0, 1, ad},
+		{addr, I2C_M_RD, 2, data}
+	};
+
+	d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
+	if (!d) {
+		ret = -ENOMEM;
+		goto done;
+	}
+	memset(d, 0, sizeof(struct rtc8564_data));
+	new_client = &d->client;
+
+	strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
+	i2c_set_clientdata(new_client, d);
+	new_client->id = rtc8564_driver.id;
+	new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY;
+	new_client->addr = addr;
+	new_client->adapter = adap;
+	new_client->driver = &rtc8564_driver;
+
+	_DBG(1, "client=%p", new_client);
+	_DBG(1, "client.id=%d", new_client->id);
+
+	/* init ctrl1 reg */
+	data[0] = 0;
+	data[1] = 0;
+	ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
+	if (ret != 1) {
+		printk(KERN_INFO "rtc8564: cant init ctrl1\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	/* read back ctrl1 and ctrl2 */
+	ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
+	if (ret != 2) {
+		printk(KERN_INFO "rtc8564: cant read ctrl\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	d->ctrl = data[0] | (data[1] << 8);
+
+	_DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
+	     data[0], data[1]);
+
+	ret = i2c_attach_client(new_client);
+done:
+	if (ret) {
+		kfree(d);
+	}
+	return ret;
+}
+
+static int rtc8564_probe(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, rtc8564_attach);
+}
+
+static int rtc8564_detach(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
+{
+	int ret = -EIO;
+	unsigned char buf[15];
+
+	_DBG(1, "client=%p, dt=%p", client, dt);
+
+	if (!dt || !client)
+		return -EINVAL;
+
+	memset(buf, 0, sizeof(buf));
+
+	ret = rtc8564_read(client, 0, buf, 15);
+	if (ret)
+		return ret;
+
+	/* century stored in minute alarm reg */
+	dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
+	dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
+	dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
+	dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
+	dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
+
+	dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
+	dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
+	dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
+	dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
+
+	_DBGRTCTM(2, *dt);
+
+	return 0;
+}
+
+static int
+rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
+{
+	int ret, len = 5;
+	unsigned char buf[15];
+
+	_DBG(1, "client=%p, dt=%p", client, dt);
+
+	if (!dt || !client)
+		return -EINVAL;
+
+	_DBGRTCTM(2, *dt);
+
+	buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
+	buf[RTC8564_REG_CTRL2] = CTRL2(client);
+	buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
+	buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
+	buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
+
+	if (datetoo) {
+		len += 5;
+		buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
+		buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
+		buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f;
+		/* century stored in minute alarm reg */
+		buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100);
+		buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100);
+	}
+
+	ret = rtc8564_write(client, 0, buf, len);
+	if (ret) {
+		_DBG(1, "error writing data! %d", ret);
+	}
+
+	buf[RTC8564_REG_CTRL1] = CTRL1(client);
+	ret = rtc8564_write(client, 0, buf, 1);
+	if (ret) {
+		_DBG(1, "error writing data! %d", ret);
+	}
+
+	return ret;
+}
+
+static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+
+	if (!ctrl || !client)
+		return -1;
+
+	*ctrl = data->ctrl;
+	return 0;
+}
+
+static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+	struct rtc8564_data *data = i2c_get_clientdata(client);
+	unsigned char buf[2];
+
+	if (!ctrl || !client)
+		return -1;
+
+	buf[0] = *ctrl & 0xff;
+	buf[1] = (*ctrl & 0xff00) >> 8;
+	data->ctrl = *ctrl;
+
+	return rtc8564_write(client, 0, buf, 2);
+}
+
+static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem)
+{
+
+	if (!mem || !client)
+		return -EINVAL;
+
+	return rtc8564_read(client, mem->loc, mem->data, mem->nr);
+}
+
+static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem)
+{
+
+	if (!mem || !client)
+		return -EINVAL;
+
+	return rtc8564_write(client, mem->loc, mem->data, mem->nr);
+}
+
+static int
+rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+
+	_DBG(1, "cmd=%d", cmd);
+
+	switch (cmd) {
+	case RTC_GETDATETIME:
+		return rtc8564_get_datetime(client, arg);
+
+	case RTC_SETTIME:
+		return rtc8564_set_datetime(client, arg, 0);
+
+	case RTC_SETDATETIME:
+		return rtc8564_set_datetime(client, arg, 1);
+
+	case RTC_GETCTRL:
+		return rtc8564_get_ctrl(client, arg);
+
+	case RTC_SETCTRL:
+		return rtc8564_set_ctrl(client, arg);
+
+	case MEM_READ:
+		return rtc8564_read_mem(client, arg);
+
+	case MEM_WRITE:
+		return rtc8564_write_mem(client, arg);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct i2c_driver rtc8564_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "RTC8564",
+	.id		= I2C_DRIVERID_RTC8564,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter = rtc8564_probe,
+	.detach_client	= rtc8564_detach,
+	.command	= rtc8564_command
+};
+
+static __init int rtc8564_init(void)
+{
+	return i2c_add_driver(&rtc8564_driver);
+}
+
+static __exit void rtc8564_exit(void)
+{
+	i2c_del_driver(&rtc8564_driver);
+}
+
+MODULE_AUTHOR("Stefan Eletzhofer <[email protected]>");
+MODULE_DESCRIPTION("EPSON RTC8564 Driver");
+MODULE_LICENSE("GPL");
+
+module_init(rtc8564_init);
+module_exit(rtc8564_exit);
drivers/i2c/chips/rtc8564.h new file +78 -0

78 lines not on this page · raw message

drivers/i2c/chips/Makefile renamed from drivers/i2c/chips/Makefile~i2c-rtc8564 +1 -0
@@ -21,6 +21,7 @@
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 
drivers/i2c/chips/Kconfig renamed from drivers/i2c/chips/Kconfig~i2c-rtc8564 +10 -0
@@ -230,4 +230,14 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called pcf8591.
 
+config SENSORS_RTC8564
+	tristate "Epson 8564 RTC chip"
+	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the Epson 8564 RTC chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-rtc8564.
+
 endmenu
#14 lore raw
Quoted 16 lines · On Sat, May 01, 2004 at 11:26:04AM +0200, [email protected] wrote:
Quoted 6 lines · Greg KH

Review

Quoted 1 line · On Thu, Apr 29, 2004 at 02:02:50PM +0200, [email protected] wrote:
(quoted diff) +1 -0
+	if ( !buf || !client ) {

Can you clean up your exuberant use of spaces in 'if' statements, and function calls? It's not the proper kernel style.

Quoted 8 lines
Quoted 1 line

+DONE:

Lowercase please

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if ( ret ) {
+		if ( d ) kfree( d );

No need to check a pointer before sending it to kfree.

Quoted 4 lines

Ok, that should be it. I've also ran the source through Lindent, which fixed some further things. I've reverted the indention change for labels, though. I think labels should be at level zero, should they?

Looks good, applied, thanks.

greg k-h