Re: [RFC] i2c: Combined ST m41txx i2c rtc chip driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jan 25, 2006 at 07:01:33PM -0700, Mark A. Greer wrote:
> Andrey, et. al., how does this look & work?
> Diff'd against linux-2.6.16-rc1-mm2.

Oops, had a minor mess up in the previous patch.  This one replaces that
one.

Mark
---

diff -Nurp linux-2.6.16-rc1-mm2/drivers/i2c/chips/Kconfig linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/Kconfig
--- linux-2.6.16-rc1-mm2/drivers/i2c/chips/Kconfig	2006-01-17 00:44:47.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/Kconfig	2006-01-23 18:35:36.000000000 -0700
@@ -102,15 +102,6 @@ config TPS65010
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps65010.
 
-config SENSORS_M41T00
-	tristate "ST M41T00 RTC chip"
-	depends on I2C && PPC32
-	help
-	  If you say yes here you get support for the ST M41T00 RTC chip.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called m41t00.
-
 config SENSORS_MAX6875
 	tristate "Maxim MAX6875 Power supply supervisor"
 	depends on I2C && EXPERIMENTAL
@@ -135,4 +126,14 @@ config RTC_X1205_I2C
 	  This driver can also be built as a module. If so, the module
 	  will be called x1205.
 
+config RTC_M41TXX_I2C
+	tristate "ST M41TXX Family of I2C RTC chips"
+	depends on I2C
+	help
+	  If you say yes here you get support for the ST M41TXX family
+	  of I2C RTC chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called m41txx.
+
 endmenu
diff -Nurp linux-2.6.16-rc1-mm2/drivers/i2c/chips/m41t00.c linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/m41t00.c
--- linux-2.6.16-rc1-mm2/drivers/i2c/chips/m41t00.c	2006-01-23 15:02:47.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/m41t00.c	1969-12-31 17:00:00.000000000 -0700
@@ -1,241 +0,0 @@
-/*
- * drivers/i2c/chips/m41t00.c
- *
- * I2C client/driver for the ST M41T00 Real-Time Clock chip.
- *
- * Author: Mark A. Greer <[email protected]>
- *
- * 2005 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-/*
- * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
- * interface and the SMBus interface of the i2c subsystem.
- * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
- * recommened in .../Documentation/i2c/writing-clients section
- * "Sending and receiving", using SMBus level communication is preferred.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/mutex.h>
-
-#include <asm/time.h>
-#include <asm/rtc.h>
-
-#define	M41T00_DRV_NAME		"m41t00"
-
-static DEFINE_MUTEX(m41t00_mutex);
-
-static struct i2c_driver m41t00_driver;
-static struct i2c_client *save_client;
-
-static unsigned short ignore[] = { I2C_CLIENT_END };
-static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_addr,
-	.probe			= ignore,
-	.ignore			= ignore,
-};
-
-ulong
-m41t00_get_rtc_time(void)
-{
-	s32	sec, min, hour, day, mon, year;
-	s32	sec1, min1, hour1, day1, mon1, year1;
-	ulong	limit = 10;
-
-	sec = min = hour = day = mon = year = 0;
-	sec1 = min1 = hour1 = day1 = mon1 = year1 = 0;
-
-	mutex_lock(&m41t00_mutex);
-	do {
-		if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0)
-			&& ((min = i2c_smbus_read_byte_data(save_client, 1))
-				>= 0)
-			&& ((hour = i2c_smbus_read_byte_data(save_client, 2))
-				>= 0)
-			&& ((day = i2c_smbus_read_byte_data(save_client, 4))
-				>= 0)
-			&& ((mon = i2c_smbus_read_byte_data(save_client, 5))
-				>= 0)
-			&& ((year = i2c_smbus_read_byte_data(save_client, 6))
-				>= 0)
-			&& ((sec == sec1) && (min == min1) && (hour == hour1)
-				&& (day == day1) && (mon == mon1)
-				&& (year == year1)))
-
-				break;
-
-		sec1 = sec;
-		min1 = min;
-		hour1 = hour;
-		day1 = day;
-		mon1 = mon;
-		year1 = year;
-	} while (--limit > 0);
-	mutex_unlock(&m41t00_mutex);
-
-	if (limit == 0) {
-		dev_warn(&save_client->dev,
-			"m41t00: can't read rtc chip\n");
-		sec = min = hour = day = mon = year = 0;
-	}
-
-	sec &= 0x7f;
-	min &= 0x7f;
-	hour &= 0x3f;
-	day &= 0x3f;
-	mon &= 0x1f;
-	year &= 0xff;
-
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(year);
-
-	year += 1900;
-	if (year < 1970)
-		year += 100;
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-static void
-m41t00_set_tlet(ulong arg)
-{
-	struct rtc_time	tm;
-	ulong	nowtime = *(ulong *)arg;
-
-	to_tm(nowtime, &tm);
-	tm.tm_year = (tm.tm_year - 1900) % 100;
-
-	BIN_TO_BCD(tm.tm_sec);
-	BIN_TO_BCD(tm.tm_min);
-	BIN_TO_BCD(tm.tm_hour);
-	BIN_TO_BCD(tm.tm_mon);
-	BIN_TO_BCD(tm.tm_mday);
-	BIN_TO_BCD(tm.tm_year);
-
-	mutex_lock(&m41t00_mutex);
-	if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0)
-		|| (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f)
-			< 0)
-		|| (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f)
-			< 0)
-		|| (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f)
-			< 0)
-		|| (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f)
-			< 0)
-		|| (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f)
-			< 0))
-
-		dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n");
-
-	mutex_unlock(&m41t00_mutex);
-	return;
-}
-
-static ulong	new_time;
-
-DECLARE_TASKLET_DISABLED(m41t00_tasklet, m41t00_set_tlet, (ulong)&new_time);
-
-int
-m41t00_set_rtc_time(ulong nowtime)
-{
-	new_time = nowtime;
-
-	if (in_interrupt())
-		tasklet_schedule(&m41t00_tasklet);
-	else
-		m41t00_set_tlet((ulong)&new_time);
-
-	return 0;
-}
-
-/*
- *****************************************************************************
- *
- *	Driver Interface
- *
- *****************************************************************************
- */
-static int
-m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
-{
-	struct i2c_client *client;
-	int rc;
-
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-
-	strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE);
-	client->addr = addr;
-	client->adapter = adap;
-	client->driver = &m41t00_driver;
-
-	if ((rc = i2c_attach_client(client)) != 0) {
-		kfree(client);
-		return rc;
-	}
-
-	save_client = client;
-	return 0;
-}
-
-static int
-m41t00_attach(struct i2c_adapter *adap)
-{
-	return i2c_probe(adap, &addr_data, m41t00_probe);
-}
-
-static int
-m41t00_detach(struct i2c_client *client)
-{
-	int	rc;
-
-	if ((rc = i2c_detach_client(client)) == 0) {
-		kfree(client);
-		tasklet_kill(&m41t00_tasklet);
-	}
-	return rc;
-}
-
-static struct i2c_driver m41t00_driver = {
-	.driver = {
-		.name	= M41T00_DRV_NAME,
-	},
-	.id		= I2C_DRIVERID_STM41T00,
-	.attach_adapter	= m41t00_attach,
-	.detach_client	= m41t00_detach,
-};
-
-static int __init
-m41t00_init(void)
-{
-	return i2c_add_driver(&m41t00_driver);
-}
-
-static void __exit
-m41t00_exit(void)
-{
-	i2c_del_driver(&m41t00_driver);
-	return;
-}
-
-module_init(m41t00_init);
-module_exit(m41t00_exit);
-
-MODULE_AUTHOR("Mark A. Greer <[email protected]>");
-MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver");
-MODULE_LICENSE("GPL");
diff -Nurp linux-2.6.16-rc1-mm2/drivers/i2c/chips/m41txx.c linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/m41txx.c
--- linux-2.6.16-rc1-mm2/drivers/i2c/chips/m41txx.c	1969-12-31 17:00:00.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/m41txx.c	2006-01-26 13:19:23.000000000 -0700
@@ -0,0 +1,365 @@
+/*
+ * I2C client/driver for the ST M41Txx family of i2c rtc chips.
+ *
+ * Author: Mark A. Greer <[email protected]>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+/*
+ * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
+ * interface and the SMBus interface of the i2c subsystem.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+#include <linux/m41txx.h>
+#include <linux/bcd.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+
+#include <asm/time.h>
+#include <asm/rtc.h>
+
+static struct work_struct set_rtc_time_task;
+
+static struct i2c_driver m41txx_driver;
+static struct i2c_client *save_client;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { 0, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+	.normal_i2c	= normal_addr,
+	.probe		= ignore,
+	.ignore		= ignore,
+};
+
+struct m41txx_chip_info {
+	u16	type;
+	u16	read_limit;
+	u8	sec;		/* Offsets for chip regs */
+	u8	min;
+	u8	hour;
+	u8	day;
+	u8	mon;
+	u8	year;
+	u8	alarm_mon;
+	u8	alarm_hour;
+	u8	sqw;
+	u32	sqw_freq;
+};
+
+static struct m41txx_chip_info m41txx_chip_info_tbl[] = {
+	{ M41TXX_TYPE_M41T00, 5, 0, 1, 2, 4, 5, 6,   0,   0,    0, 0 },
+	{ M41TXX_TYPE_M41T81, 1, 1, 2, 3, 5, 6, 7, 0xa, 0xc, 0x13, 0 },
+	{ M41TXX_TYPE_M41T85, 1, 1, 2, 3, 5, 6, 7, 0xa, 0xc, 0x13, 0 },
+};
+static struct m41txx_chip_info *m41txx_chip;
+
+unsigned long
+m41txx_get_rtc_time(void)
+{
+	s32 sec, min, hour, day, mon, year;
+	s32 sec1, min1, hour1, day1, mon1, year1;
+	u16 reads = 0;
+	u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */
+	struct i2c_msg msgs[] = {
+		{ save_client->addr, 0, 1, msgbuf },
+		{ save_client->addr, I2C_M_RD, 8, buf }
+	};
+
+	sec = min = hour = day = mon = year = 0;
+
+	do {
+		if (i2c_transfer(save_client->adapter, msgs, 2) < 0)
+			goto read_err;
+
+		sec1  = sec;
+		min1  = min;
+		hour1 = hour;
+		day1  = day;
+		mon1  = mon;
+		year1 = year;
+
+		sec  =  buf[m41txx_chip->sec]  & 0x7f;
+		min  =  buf[m41txx_chip->min]  & 0x7f;
+		hour =  buf[m41txx_chip->hour] & 0x3f;
+		day  =  buf[m41txx_chip->day]  & 0x3f;
+		mon  =  buf[m41txx_chip->mon]  & 0x1f;
+		year =  buf[m41txx_chip->year] & 0xff;
+	} while ((++reads < m41txx_chip->read_limit) && ((sec != sec1)
+			|| (min != min1) || (hour != hour1) || (day != day1)
+			|| (mon != mon1) || (year != year1)));
+
+	if ((m41txx_chip->read_limit > 1) && ((sec != sec1) || (min != min1)
+			|| (hour != hour1) || (day != day1) || (mon != mon1)
+			|| (year != year1)))
+		goto read_err;
+
+	sec  = BCD2BIN(sec);
+	min  = BCD2BIN(min);
+	hour = BCD2BIN(hour);
+	day  = BCD2BIN(day);
+	mon  = BCD2BIN(mon);
+	year = BCD2BIN(year);
+
+	year += 1900;
+	if (year < 1970)
+		year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+
+read_err:
+	dev_err(&save_client->dev, "m41txx_get_rtc_time: Read error\n");
+	return 0;
+}
+
+static void
+m41txx_set(void *arg)
+{
+	struct rtc_time	tm;
+	int nowtime = *(int *)arg;
+	s32 sec, min, hour, day, mon, year;
+	u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 };
+	struct i2c_msg msgs[] = {
+		{ save_client->addr, 0, 1, msgbuf },
+		{ save_client->addr, I2C_M_RD, 8, buf }
+	};
+
+	to_tm(nowtime, &tm);
+	tm.tm_year = (tm.tm_year - 1900) % 100;
+
+	sec  = BIN2BCD(tm.tm_sec);
+	min  = BIN2BCD(tm.tm_min);
+	hour = BIN2BCD(tm.tm_hour);
+	day  = BIN2BCD(tm.tm_mday);
+	mon  = BIN2BCD(tm.tm_mon);
+	year = BIN2BCD(tm.tm_year);
+
+	/* Read reg values into buf[0..7]/wbuf[1..8] */
+	if (i2c_transfer(save_client->adapter, msgs, 2) < 0) {
+		dev_err(&save_client->dev, "m41txx_set: Read error\n");
+		return;
+	}
+
+	wbuf[0] = 0; /* offset into rtc's regs */
+	buf[m41txx_chip->sec]  = (buf[m41txx_chip->sec] & ~0x7f) | (sec & 0x7f);
+	buf[m41txx_chip->min]  = (buf[m41txx_chip->min] & ~0x7f) | (min & 0x7f);
+	buf[m41txx_chip->hour] = (buf[m41txx_chip->hour]& ~0x3f) | (hour& 0x3f);
+	buf[m41txx_chip->day]  = (buf[m41txx_chip->day] & ~0x3f) | (day & 0x3f);
+	buf[m41txx_chip->mon]  = (buf[m41txx_chip->mon] & ~0x1f) | (mon & 0x1f);
+
+	if (i2c_master_send(save_client, wbuf, 9) < 0)
+		dev_err(&save_client->dev, "m41txx_set: Write error\n");
+}
+
+static u32	new_time;
+
+int
+m41txx_set_rtc_time(unsigned long nowtime)
+{
+	new_time = nowtime;
+
+	if (in_interrupt())
+		schedule_work(&set_rtc_time_task);
+	else
+		m41txx_set((void *)&new_time);
+	return 0;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	platform_data Driver Interface
+ *
+ *****************************************************************************
+ */
+static int __init
+m41txx_platform_probe(struct platform_device *pdev)
+{
+	struct m41txx_platform_data *pdata;
+	int i;
+
+	if (pdev && (pdata = pdev->dev.platform_data)) {
+		normal_addr[0] = pdata->i2c_addr;
+
+		for (i=0; i<ARRAY_SIZE(m41txx_chip_info_tbl); i++)
+			if (m41txx_chip_info_tbl[i].type == pdata->type) {
+				m41txx_chip = &m41txx_chip_info_tbl[i];
+				m41txx_chip->sqw_freq = pdata->sqw_freq;
+				return 0;
+			}
+	}
+	return -ENODEV;
+}
+
+static int __exit
+m41txx_platform_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver m41txx_platform_driver = {
+	.probe  = m41txx_platform_probe,
+	.remove = m41txx_platform_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name  = M41TXX_DRV_NAME,
+	},
+};
+
+/*
+ *****************************************************************************
+ *
+ *	Driver Interface
+ *
+ *****************************************************************************
+ */
+static int
+m41txx_probe(struct i2c_adapter *adap, int addr, int kind)
+{
+	struct i2c_client *client;
+	int rc;
+	u8 rbuf[1], wbuf[2], msgbuf[1] = { 0 }; /* offset into rtc's regs */
+	struct i2c_msg msgs[] = {
+		{ 0, 0, 1, msgbuf },
+		{ 0, I2C_M_RD, 1, rbuf }
+	};
+
+	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+
+	strlcpy(client->name, m41txx_driver.driver.name, I2C_NAME_SIZE);
+	client->addr = addr;
+	client->adapter = adap;
+	client->driver = &m41txx_driver;
+
+	if ((rc = i2c_attach_client(client)) != 0)
+		goto attach_err;
+
+	msgs[0].addr = addr;
+	msgs[1].addr = addr;
+
+	if (m41txx_chip->type != M41TXX_TYPE_M41T00) {
+		/* If asked, set SQW frequency & enable */
+		if (m41txx_chip->sqw_freq) {
+			msgbuf[0] = m41txx_chip->alarm_mon;
+			if ((rc = i2c_transfer(client->adapter, msgs, 2)) < 0)
+				goto sqw_err;
+
+			wbuf[0] = m41txx_chip->alarm_mon;
+			wbuf[1] = rbuf[0] & ~0x40;
+			if ((rc = i2c_master_send(client, wbuf, 2)) < 0)
+				goto sqw_err;
+
+			wbuf[0] = m41txx_chip->sqw;
+			wbuf[1] = m41txx_chip->sqw_freq;
+			if ((rc = i2c_master_send(client, wbuf, 2)) < 0)
+				goto sqw_err;
+
+			wbuf[0] = m41txx_chip->alarm_mon;
+			wbuf[1] = rbuf[0] | 0x40;
+			if ((rc = i2c_master_send(client, wbuf, 2)) < 0)
+				goto sqw_err;
+		}
+
+		/* Make sure HT (Halt Update) bit is cleared */
+		msgbuf[0] = m41txx_chip->alarm_hour;
+		if ((rc = i2c_transfer(client->adapter, msgs, 2)) < 0)
+			goto ht_err;
+
+		if (rbuf[0] & 0x40) {
+			wbuf[0] = m41txx_chip->alarm_hour;
+			wbuf[1] = rbuf[0] & ~0x40;
+			if ((rc = i2c_master_send(client, wbuf, 2)) < 0)
+				goto ht_err;
+		}
+	}
+
+	/* Make sure ST (stop) bit is cleared */
+	msgbuf[0] = m41txx_chip->sec;
+	if ((rc = i2c_transfer(client->adapter, msgs, 2)) < 0)
+		goto st_err;
+
+	if (rbuf[0] & 0x80) {
+		wbuf[0] = m41txx_chip->sec;
+		wbuf[1] = rbuf[0] & ~0x80;
+		if ((rc = i2c_master_send(client, wbuf, 2)) < 0)
+			goto st_err;
+	}
+
+	INIT_WORK(&set_rtc_time_task, &m41txx_set, &new_time);
+	save_client = client;
+	return 0;
+
+st_err:
+	dev_err(&client->dev, "m41txx_probe: Can't clear ST bit\n");
+	goto attach_err;
+ht_err:
+	dev_err(&client->dev, "m41txx_probe: Can't clear HT bit\n");
+	goto attach_err;
+sqw_err:
+	dev_err(&client->dev, "m41txx_probe: Can't set SQW Frequency\n");
+attach_err:
+	kfree(client);
+	return rc;
+}
+
+static int
+m41txx_attach(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, m41txx_probe);
+}
+
+static int
+m41txx_detach(struct i2c_client *client)
+{
+	int	rc;
+
+	if ((rc = i2c_detach_client(client)) == 0) {
+		kfree(client);
+		flush_scheduled_work();
+	}
+	return rc;
+}
+
+static struct i2c_driver m41txx_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= M41TXX_DRV_NAME,
+	},
+	.id		= I2C_DRIVERID_STM41TXX,
+	.attach_adapter	= m41txx_attach,
+	.detach_client	= m41txx_detach,
+};
+
+static int __init
+m41txx_init(void)
+{
+	int rc;
+
+	if (!(rc = platform_driver_register(&m41txx_platform_driver)))
+		rc = i2c_add_driver(&m41txx_driver);
+	return rc;
+}
+
+static void __exit
+m41txx_exit(void)
+{
+	i2c_del_driver(&m41txx_driver);
+	platform_driver_unregister(&m41txx_platform_driver);
+}
+
+module_init(m41txx_init);
+module_exit(m41txx_exit);
+
+MODULE_AUTHOR("Mark A. Greer <[email protected]>");
+MODULE_DESCRIPTION("ST Microelectronics M41TXX RTC I2C Client Driver");
+MODULE_LICENSE("GPL");
diff -Nurp linux-2.6.16-rc1-mm2/drivers/i2c/chips/Makefile linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/Makefile
--- linux-2.6.16-rc1-mm2/drivers/i2c/chips/Makefile	2006-01-17 00:44:47.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/drivers/i2c/chips/Makefile	2006-01-23 18:18:26.000000000 -0700
@@ -6,7 +6,6 @@ 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_M41T00)	+= m41t00.o
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
@@ -14,6 +13,7 @@ obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_RTC_X1205_I2C)	+= x1205.o
+obj-$(CONFIG_RTC_M41TXX_I2C)	+= m41txx.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff -Nurp linux-2.6.16-rc1-mm2/include/linux/i2c-id.h linux-2.6.16-rc1-mm2-m41txx/include/linux/i2c-id.h
--- linux-2.6.16-rc1-mm2/include/linux/i2c-id.h	2006-01-17 00:44:47.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/include/linux/i2c-id.h	2006-01-23 18:18:26.000000000 -0700
@@ -79,7 +79,7 @@
 #define I2C_DRIVERID_SAA7114	49	/* video decoder		*/
 #define I2C_DRIVERID_ZR36120	50     /* Zoran 36120 video encoder	*/
 #define I2C_DRIVERID_24LC32A	51	/* Microchip 24LC32A 32k EEPROM	*/
-#define I2C_DRIVERID_STM41T00	52	/* real time clock		*/
+#define I2C_DRIVERID_STM41TXX	52	/* real time clock		*/
 #define I2C_DRIVERID_UDA1342	53	/* UDA1342 audio codec		*/
 #define I2C_DRIVERID_ADV7170	54	/* video encoder		*/
 #define I2C_DRIVERID_RADEON	55	/* I2C bus on Radeon boards	*/
diff -Nurp linux-2.6.16-rc1-mm2/include/linux/m41txx.h linux-2.6.16-rc1-mm2-m41txx/include/linux/m41txx.h
--- linux-2.6.16-rc1-mm2/include/linux/m41txx.h	1969-12-31 17:00:00.000000000 -0700
+++ linux-2.6.16-rc1-mm2-m41txx/include/linux/m41txx.h	2006-01-23 18:39:56.000000000 -0700
@@ -0,0 +1,47 @@
+/*
+ * Definitions for the ST M41Txx family of i2c rtc chips.
+ *
+ * Author: Mark A. Greer <[email protected]>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef _M41TXX_H
+#define _M41TXX_H
+
+#define	M41TXX_DRV_NAME		"m41txx rtc"
+#define	M41TXX_I2C_ADDR		0x68
+
+#define	M41TXX_TYPE_M41T00	0
+#define	M41TXX_TYPE_M41T81	81
+#define	M41TXX_TYPE_M41T85	85
+
+struct m41txx_platform_data {
+	u16	type;
+	u16	i2c_addr;
+	u32	sqw_freq;
+};
+
+/* SQW output disabled, this is default value by power on*/
+#define SQW_FREQ_DISABLE	(0)
+
+#define SQW_FREQ_32KHZ	(1<<4)		/* 32.768 KHz */
+#define SQW_FREQ_8KHZ	(2<<4)		/* 8.192 KHz */
+#define SQW_FREQ_4KHZ	(3<<4)		/* 4.096 KHz */
+#define SQW_FREQ_2KHZ	(4<<4)		/* 2.048 KHz */
+#define SQW_FREQ_1KHZ	(5<<4)		/* 1.024 KHz */
+#define SQW_FREQ_512HZ	(6<<4)		/* 512 Hz */
+#define SQW_FREQ_256HZ	(7<<4)		/* 256 Hz */
+#define SQW_FREQ_128HZ	(8<<4)		/* 128 Hz */
+#define SQW_FREQ_64HZ	(9<<4)		/* 64 Hz */
+#define SQW_FREQ_32HZ	(10<<4)		/* 32 Hz */
+#define SQW_FREQ_16HZ	(11<<4)		/* 16 Hz */
+#define SQW_FREQ_8HZ	(12<<4)		/* 8 Hz */
+#define SQW_FREQ_4HZ	(13<<4)		/* 4 Hz */
+#define SQW_FREQ_2HZ	(14<<4)		/* 2 Hz */
+#define SQW_FREQ_1HZ	(15<<4)		/* 1 Hz */
+
+#endif /* _M41TXX_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/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux