Skip to contentSkip to conversation

I2C: Add MAX6900 I2C RTC support

PATCH New Stefan Roese 2 participants 8 messages Nov 23, 2005 – Jun 30, 2006

lore
Share & tools
lore
#1 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support

Hi Stefan,

Quoted 1 line · Stefan Roese

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

-ENOPATCH
Try again with the proper attachement type.

Back in March 2004, Anthony Petillo told us he was working on a MAX6900 driver for Linux 2.4. We never heard back as far as I remember (but I have a bad memory). Does your own driver has anything to do with Anthony's work?

Can you check whether sensors-detect finds your MAX6900 chip?

What hardware do you have a MAX6900 chip on?

--
Jean Delvare

#2 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support

In reply to Stefan Roese

Hi Jean,

Quoted 5 lines · Jean Delvare
Quoted 1 line · Stefan Roese

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

-ENOPATCH
Try again with the proper attachement type.

Hmmm. All other mailinglists seem to have no problem with ".patch" as file extension. Here another try with ".diff".

Quoted 4 lines

Back in March 2004, Anthony Petillo told us he was working on a MAX6900 driver for Linux 2.4. We never heard back as far as I remember (but I have a bad memory). Does your own driver has anything to do with Anthony's work?

No. I also found this refenrence, but no driver.

Quoted 1 line

Can you check whether sensors-detect finds your MAX6900 chip?

Sorry, but I didn't check and I am bit short in time. Is this a requirement?

Quoted 1 line

What hardware do you have a MAX6900 chip on?

It's used on the Prodrive P3P440, a PPC440GP based PMC module. I commited it's platform support yesterday to the ppc community.

Best regards,
Stefan

#3 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support

In reply to Stefan Roese
Quoted 11 lines · Stefan Roese

Hi Jean,

Quoted 5 lines · Jean Delvare
Quoted 1 line · Stefan Roese

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

-ENOPATCH
Try again with the proper attachement type.

Hmmm. All other mailinglists seem to have no problem with ".patch" as file extension. Here another try with ".diff".

Now (hopefully) the last try. This time inline. Hopefully without linewrapping in the patch...

Best regards,
Stefan

[PATCH] I2C: Add MAX6900 I2C RTC support

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

---
commit 0d044398ada37f988e6cc66e4ba6098496e95e83
tree 208e9a654a95916056a319f45fa0d297580360a9
parent 35a9f654b2fce7fd545afbf497962c3b299838fc
author Stefan Roese <[email protected]> Tue, 22 Nov 2005 15:09:54 +0100 committer Stefan Roese <[email protected]> Tue, 22 Nov 2005 15:09:54 +0100

 drivers/i2c/chips/Kconfig   |   14 +
 drivers/i2c/chips/Makefile  |    1 
 drivers/i2c/chips/max6900.c |  447 
+++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/chips/max6900.h |   79 ++++++++
 4 files changed, 539 insertions(+), 2 deletions(-)
drivers/i2c/chips/Kconfig +12 -2
index 09226e4..7ec4f05 100644
@@ -36,11 +36,21 @@ config SENSORS_EEPROM
 	  This driver can also be built as a module.  If so, the module
 	  will be called eeprom.
 
+config SENSORS_MAX6900
+	tristate "Maxim MAX6900 Real Time Clock"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for Maxim MAX6900
+	  real-time clock chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max6900.
+
 config SENSORS_PCF8574
 	tristate "Philips PCF8574 and PCF8574A"
 	depends on I2C && EXPERIMENTAL
 	help
-	  If you say yes here you get support for Philips PCF8574 and 
+	  If you say yes here you get support for Philips PCF8574 and
 	  PCF8574A chips.
 
 	  This driver can also be built as a module.  If so, the module
@@ -91,7 +101,7 @@ config ISP1301_OMAP
 	  USB-On-The-Go transceiver working with the OMAP OTG controller.
 	  The ISP1301 is used in products including H2 and H3 development
 	  boards for Texas Instruments OMAP processors.
-	  
+
 	  This driver can also be built as a module.  If so, the module
 	  will be called isp1301_omap.
 
drivers/i2c/chips/Makefile +1 -0
index e37835a..b77786d 100644
@@ -6,6 +6,7 @@ obj-$(CONFIG_SENSORS_DS1337)	+= ds1337.o
 obj-$(CONFIG_SENSORS_DS1374)	+= ds1374.o
 obj-$(CONFIG_SENSORS_EEPROM)	+= eeprom.o
 obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
+obj-$(CONFIG_SENSORS_MAX6900)	+= max6900.o
 obj-$(CONFIG_SENSORS_M41T00)	+= m41t00.o
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
drivers/i2c/chips/max6900.c new file +180 -0

180 lines not on this page · raw message

*dt)
+{
+ int ret = -EIO;
+ unsigned char sec, sec2, min, hour, mday, wday, mon, cent, year;
+
+ _DBG(1, "client=%p, dt=%p", client, dt);
+
+ if (!dt)
+ return -EINVAL;
+
+ do {
+ ret = max6900_read(client, MAX6900_REG_SEC, &sec, 1);

+		ret |= max6900_read(client, MAX6900_REG_MIN, &min, 1);
+		ret |= max6900_read(client, MAX6900_REG_HOUR, &hour, 1);
+		ret |= max6900_read(client, MAX6900_REG_MDAY, &mday, 1);
+		ret |= max6900_read(client, MAX6900_REG_MON, &mon, 1);
+		ret |= max6900_read(client, MAX6900_REG_WDAY, &wday, 1);
+		ret |= max6900_read(client, MAX6900_REG_YEAR, &year, 1);
+		ret |= max6900_read(client, MAX6900_REG_CENT, &cent, 1);

+ if (ret)
+ return ret;
+
+ /*
+ * Check for seconds rollover
+ */
+ ret = max6900_read(client, MAX6900_REG_SEC, &sec2, 1);
+ if ((sec != 59) || (sec2 = sec)){
+ break;
+ }
+ } while (1);
+
+ dt->tm_year = BCD_TO_BIN(year) + BCD_TO_BIN(cent) * 100;
+ dt->tm_mday = BCD_TO_BIN(mday & 0x3f);
+ dt->tm_wday = BCD_TO_BIN(wday & 7);
+ dt->tm_mon = BCD_TO_BIN(mon & 0x1f);
+
+ dt->tm_sec = BCD_TO_BIN(sec & 0x7f);
+ dt->tm_min = BCD_TO_BIN(min & 0x7f);
+ dt->tm_hour = BCD_TO_BIN(hour & 0x3f);
+
+ _DBGRTCTM(2, *dt);
+ return 0;
+}
+
+static int
+max6900_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
+{
+ int ret;
+ unsigned char val;
+ unsigned char sec, min, hour, mday, wday, mon, cent, year;
+
+ _DBG(1, "client=%p, dt=%p", client, dt);
+
+ if (!dt)
+ return -EINVAL;
+
+ val = 0x00;
+ ret = max6900_write(client, 0x9e, &val, 1);
+
+ /* Clear seconds to ensure no rollover */
+ ret |= max6900_write(client, MAX6900_REG_SEC, &val, 1);
+
+ min = BIN_TO_BCD(dt->tm_min);
+ ret |= max6900_write(client, MAX6900_REG_MIN, &min, 1);
+ hour = BIN_TO_BCD(dt->tm_hour);
+ ret |= max6900_write(client, MAX6900_REG_HOUR, &hour, 1);
+
+ if (datetoo) {
+ mday = BIN_TO_BCD(dt->tm_mday);
+ ret |= max6900_write(client, MAX6900_REG_MDAY, &mday, 1);
+ wday = BIN_TO_BCD(dt->tm_wday);
+ ret |= max6900_write(client, MAX6900_REG_WDAY, &wday, 1);
+ mon = BIN_TO_BCD(dt->tm_mon);
+ ret |= max6900_write(client, MAX6900_REG_MON, &mon, 1);
+ year = BIN_TO_BCD(dt->tm_year % 100);
+ ret |= max6900_write(client, MAX6900_REG_YEAR, &year, 1);
+ cent = BIN_TO_BCD(dt->tm_year / 100);
+ ret |= max6900_write(client, MAX6900_REG_CENT, &cent, 1);
+ }
+
+ sec = BIN_TO_BCD(dt->tm_sec);
+ ret |= max6900_write(client, MAX6900_REG_SEC, &sec, 1);
+
+ if (ret) {
+ _DBG(1, "error writing data! %d", ret);
+ }
+
+ return ret;
+}
+
+static int max6900_get_ctrl(struct i2c_client *client, unsigned int *ctrl) +{
+ struct max6900_data *data = i2c_get_clientdata(client);
+
+ if (!ctrl)
+ return -1;
+
+ *ctrl = data->ctrl;
+ return 0;
+}
+
+static int max6900_set_ctrl(struct i2c_client *client, unsigned int *ctrl) +{
+ struct max6900_data *data = i2c_get_clientdata(client);
+ unsigned char buf[2];
+
+ if (!ctrl)
+ return -1;
+
+ buf[0] = *ctrl & 0xff;
+ buf[1] = (*ctrl & 0xff00) >> 8;
+ data->ctrl = *ctrl;
+
+ return max6900_write(client, 0, buf, 2);
+}
+
+static int max6900_read_mem(struct i2c_client *client, struct mem *mem) +{
+
+ if (!mem)
+ return -EINVAL;
+
+ return max6900_read(client, mem->loc, mem->data, mem->nr);
+}
+
+static int max6900_write_mem(struct i2c_client *client, struct mem *mem) +{
+
+ if (!mem)
+ return -EINVAL;
+
+ return max6900_write(client, mem->loc, mem->data, mem->nr);
+}
+
+static int
+max6900_command(struct i2c_client *client, unsigned int cmd, void *arg) +{
+
+ _DBG(1, "cmd=%d", cmd);
+
+ switch (cmd) {
+ case RTC_GETDATETIME:
+ return max6900_get_datetime(client, arg);
+
+ case RTC_SETTIME:
+ return max6900_set_datetime(client, arg, 0);
+
+ case RTC_SETDATETIME:
+ return max6900_set_datetime(client, arg, 1);
+
+ case RTC_GETCTRL:
+ return max6900_get_ctrl(client, arg);
+
+ case RTC_SETCTRL:
+ return max6900_set_ctrl(client, arg);
+
+ case MEM_READ:
+ return max6900_read_mem(client, arg);
+
+ case MEM_WRITE:
+ return max6900_write_mem(client, arg);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Public API for access to specific device. Useful for low-level
+ * RTC access from kernel code.
+ */
+int max6900_do_command(int bus, int cmd, void *arg)
+{
+ struct list_head *walk;
+ struct list_head *tmp;
+ struct max6900_data *data;
+
+ list_for_each_safe(walk, tmp, &max6900_clients) {
+ data = list_entry(walk, struct max6900_data, list);
+ if (data->client.adapter->nr = bus) {
+ return max6900_command(&data->client, cmd, arg);
+ }
+ }
+
+ return -ENODEV;
+}
+ +/***************************************************************************
+ *
+ * get RTC time:
+ */
+unsigned long max6900_get_rtc_time(void)
+{
+ struct rtc_time tm;
+ int result;
+
+ spin_lock(&rtc_lock);
+ result = max6900_do_command(0, RTC_GETDATETIME, &tm);
+ spin_unlock(&rtc_lock);
+
+ if (result = 0)
+ result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min,
tm.tm_sec);
+
+ return result;
+}
+ +/***************************************************************************
+ *
+ * set RTC time:
+ */
+int max6900_set_rtc_time(unsigned long now)
+{
+ struct rtc_time tm;
+ unsigned char century, year, mon, wday, mday, hour, min, sec;
+
+ to_tm (now, &tm);
+
+ _DBG (2, "Set RTC [dec] year=%d mon=%d day=%d hour=%d min=%d
sec=%d\n",
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+

+        century = (tm.tm_year >= 2000) ? 0x80 : 0;
+        year = BIN_TO_BCD (tm.tm_year % 100);
+        mon  = BIN_TO_BCD (tm.tm_mon) | century;
+        wday = BIN_TO_BCD (tm.tm_wday);
+        mday = BIN_TO_BCD (tm.tm_mday);
+        hour = BIN_TO_BCD (tm.tm_hour);
+        min  = BIN_TO_BCD (tm.tm_min);
+        sec  = BIN_TO_BCD (tm.tm_sec);

+
+ _DBG (2, "Set RTC [bcd] year=%X mon=%X day=%X "
+ "hour=%X min=%X sec=%X wday=%X\n",
+ year, mon, mday, hour, min, sec, wday);
+
+ max6900_set_datetime(myclient, &tm, 1);
+
+ return (0);
+}
+
+static struct i2c_driver max6900_driver = {
+ .owner = THIS_MODULE,
+ .name = "MAX6900",
+ .id = I2C_DRIVERID_MAX6900,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = max6900_probe,
+ .detach_client = max6900_detach,
+ .command = max6900_command
+};
+
+static __init int max6900_init(void)
+{
+ return i2c_add_driver(&max6900_driver);
+}
+
+static __exit void max6900_exit(void)
+{
+ ppc_md.set_rtc_time = save_set_rtc_time;
+ ppc_md.get_rtc_time = save_get_rtc_time;
+
+ i2c_del_driver(&max6900_driver);
+}
+
+MODULE_AUTHOR("Stefan Roese <[email protected]>"); +MODULE_DESCRIPTION("Maxim/Dallas MAX6900 RTC I2C Client Driver"); +MODULE_LICENSE("GPL");
+
+module_init(max6900_init);
+module_exit(max6900_exit);

drivers/i2c/chips/max6900.h new file +60 -0

60 lines not on this page · raw message

"\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\n", __FUNCTION__, \
+ (rtctm).tm_sec, (rtctm).tm_min, (rtctm).tm_hour, (rtctm).tm_mday, \
+ (rtctm).tm_mon, (rtctm).tm_year, (rtctm).tm_wday);
+
+struct max6900_data {
+ struct i2c_client client;
+ struct list_head list;
+ u16 ctrl;
+};
+
+static int max6900_read_mem(struct i2c_client *client, struct mem *mem); +static int max6900_write_mem(struct i2c_client *client, struct mem *mem); +unsigned long max6900_get_rtc_time(void);
+int max6900_set_rtc_time(unsigned long now);

!-------------------------------------------------------------flip-

#4 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support (4th try!)

In reply to Stefan Roese

Sorry for this mail flood. Jean assured me, that now my attachment should go through.

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

Best regards,
Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: add-max6900-rtc-support.diff
Type: text/x-diff
Size: 15696 bytes
Desc: not available
Url : http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20051123/51fc84e6/add-max6900-rtc-support.bin

#5 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support (4th try!)

In reply to Stefan Roese

Hi Stefan,

Quoted 6 lines

Sorry for this mail flood. Jean assured me, that now my attachment should go through.

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

Signed-off-by Stefan Roese <sr at denx.de>

Sorry, I didn't have the time to review your driver back then. Now there is a new RTC subsystem where your driver would fit better, so if you are still interested in having your driver merged, please submit it again for inclusion into this subsystem (drivers/rtc). The RTC subsystem is maintained by Alessandro Zummo.

Signature · 1 line
Jean Delvare
#6 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support (4th try!)

In reply to Stefan Roese

Hi Jean,

Quoted 8 lines · Jean Delvare
Quoted 3 lines

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

Signed-off-by Stefan Roese <sr at denx.de>

Sorry, I didn't have the time to review your driver back then. Now there is a new RTC subsystem where your driver would fit better, so if you are still interested in having your driver merged, please submit it again for inclusion into this subsystem (drivers/rtc).

Yes, I will try to find some time in the next weeks to do this.

Quoted 2 lines

The RTC
subsystem is maintained by Alessandro Zummo.

Is the lm-sensors mailinglist the correct list also for this new rtc subsystem?

Best regards,
Stefan

#7 lore raw

PATCH 1/1 I2C: Add MAX6900 I2C RTC support (4th try!)

In reply to Stefan Roese

Stefan,

Quoted 10 lines · Jean Delvare
Quoted 8 lines
Quoted 3 lines

This patch adds support for the Maxim/Dallas MAX6900 I2C RTC.

Signed-off-by Stefan Roese <sr at denx.de>

Sorry, I didn't have the time to review your driver back then. Now there is a new RTC subsystem where your driver would fit better, so if you are still interested in having your driver merged, please submit it again for inclusion into this subsystem (drivers/rtc).

Quoted 7 lines

Yes, I will try to find some time in the next weeks to do this.

Quoted 2 lines

The RTC
subsystem is maintained by Alessandro Zummo.

Is the lm-sensors mailinglist the correct list also for this new rtc subsystem?

No. As there is no dedicated list for the rtc subsystem, that would be LKML, or if there are i2c-related issues, our new i2c list [1].

[1] http://lists.lm-sensors.org/mailman/listinfo/i2c

Thanks,

Signature · 1 line
Jean Delvare