diff for duplicates of <4378960F.8030800@varma-el.com> diff --git a/a/1.txt b/N1/1.txt index d60592f..f036a35 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -10,429 +10,3 @@ Regards Andrey Volkov P.S. Please CC to me directly, I'm not in lm-sensors@lm-sensors.org list. --------------- next part -------------- -Added support of ST M41T85 RTC - -Signed-off-By: Andrey Volkov <avolkov@varma-el.com> ---- - - drivers/i2c/chips/Kconfig | 88 ++++++++++++++ - drivers/i2c/chips/Makefile | 1 - drivers/i2c/chips/m41t85.c | 285 ++++++++++++++++++++++++++++++++++++++++++++ - include/linux/i2c-id.h | 1 - 4 files changed, 375 insertions(+), 0 deletions(-) - -diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig -index f9fae28..6593fc5 100644 ---- a/drivers/i2c/chips/Kconfig -+++ b/drivers/i2c/chips/Kconfig -@@ -111,6 +111,94 @@ config SENSORS_M41T00 - This driver can also be built as a module. If so, the module - will be called m41t00. - -+config SENSORS_M41T85 -+ tristate "ST M41T85 RTC chip" -+ depends on I2C -+ help -+ If you say yes here you get support for the ST M41T85 RTC chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called m41t85. -+ -+config SENSORS_M41T85_SQW_FRQ_ENABLE -+ depends on SENSORS_M41T85 -+ bool "Square Wave Output" -+ help -+ If you say yes here, then m41t85 will generate clocks on it -+ SQW pin at frequency which you are select below. -+ -+choice -+ prompt "SQW frequincy" -+ depends on SENSORS_M41T85_SQW_FRQ_ENABLE -+ default SENSORS_M41T85_SQW_FRQ_32KHZ -+ -+config SENSORS_M41T85_SQW_FRQ_32KHZ -+ bool "32.768 kHz" -+ -+config SENSORS_M41T85_SQW_FRQ_8KHZ -+ bool "8 kHz" -+ -+config SENSORS_M41T85_SQW_FRQ_4KHZ -+ bool "4 kHz" -+ -+config SENSORS_M41T85_SQW_FRQ_2KHZ -+ bool "2 kHz" -+ -+config SENSORS_M41T85_SQW_FRQ_1KHZ -+ bool "1 kHz" -+ -+config SENSORS_M41T85_SQW_FRQ_512HZ -+ bool "512 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_256HZ -+ bool "256 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_128HZ -+ bool "128 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_64HZ -+ bool "64 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_32HZ -+ bool "32 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_16HZ -+ bool "16 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_8HZ -+ bool "8 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_4HZ -+ bool "4 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_2HZ -+ bool "2 Hz" -+ -+config SENSORS_M41T85_SQW_FRQ_1HZ -+ bool "1 Hz" -+ -+endchoice -+ -+config SENSORS_M41T85_SQW_FRQ -+ int -+ depends on SENSORS_M41T85_SQW_FRQ_ENABLE -+ default "1" if SENSORS_M41T85_SQW_FRQ_32KHZ -+ default "2" if SENSORS_M41T85_SQW_FRQ_8KHZ -+ default "3" if SENSORS_M41T85_SQW_FRQ_4KHZ -+ default "4" if SENSORS_M41T85_SQW_FRQ_2KHZ -+ default "5" if SENSORS_M41T85_SQW_FRQ_1KHZ -+ default "6" if SENSORS_M41T85_SQW_FRQ_512HZ -+ default "7" if SENSORS_M41T85_SQW_FRQ_256HZ -+ default "8" if SENSORS_M41T85_SQW_FRQ_128HZ -+ default "9" if SENSORS_M41T85_SQW_FRQ_64HZ -+ default "10" if SENSORS_M41T85_SQW_FRQ_32HZ -+ default "11" if SENSORS_M41T85_SQW_FRQ_16HZ -+ default "12" if SENSORS_M41T85_SQW_FRQ_8HZ -+ default "13" if SENSORS_M41T85_SQW_FRQ_4HZ -+ default "14" if SENSORS_M41T85_SQW_FRQ_2HZ -+ default "15" if SENSORS_M41T85_SQW_FRQ_1HZ -+ -+ - config SENSORS_MAX6875 - tristate "Maxim MAX6875 Power supply supervisor" - depends on I2C && EXPERIMENTAL -diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile -index 46178b5..5637881 100644 ---- a/drivers/i2c/chips/Makefile -+++ b/drivers/i2c/chips/Makefile -@@ -14,6 +14,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_SENSORS_M41T85) += m41t85.o - - ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) - EXTRA_CFLAGS += -DDEBUG -diff --git a/drivers/i2c/chips/m41t85.c b/drivers/i2c/chips/m41t85.c -new file mode 100644 -index 0000000..f26a115 ---- /dev/null -+++ b/drivers/i2c/chips/m41t85.c -@@ -0,0 +1,285 @@ -+/* -+ * drivers/i2c/chips/m41t85.c -+ * -+ * DESCRIPTION: -+ * I2C client/driver for the ST M41T85 Real-Time Clock chip. -+ * -+ * AUTHOR: -+ * Andrey Volkov <avolkov@varma-el.com> -+ * -+ * COPYRIGHT: -+ * 2005, Varma Electronics Oy -+ * -+ * Based on driver for ST M41T00 by Mark A. Greer <mgreer@mvista.com> -+ * (see m41t00.c for copyright) -+ * -+ * LICENCE: -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License version 2. See the file COPYING in the main directory of this archive -+ * for more details. -+ * -+ * HISTORY: -+ * 2005-10-12 Created -+ */ -+ -+/* -+ * 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/config.h> -+#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 <asm/time.h> -+#include <asm/rtc.h> -+ -+#define M41T85_DRV_NAME "m41t85" -+ -+#define RTC_CSEC_ADDR 0x00 -+#define RTC_SEC_ADDR 0x01 -+#define RTC_MIN_ADDR 0x02 -+#define RTC_HOUR_ADDR 0x03 -+#define RTC_WDAY_ADDR 0x04 -+#define RTC_DAY_ADDR 0x05 -+#define RTC_MONTH_ADDR 0x06 -+#define RTC_YEARS_ADDR 0x07 -+#define RTC_CONTROL_ADDR 0x08 -+#define RTC_WATCHDOG_ADDR 0x09 -+#define RTC_ALARM_MONTH_ADDR 0x0a -+#define RTC_ALARM_DATE_ADDR 0x0b -+#define RTC_ALARM_HOUR_ADDR 0x0c -+#define RTC_ALARM_MIN_ADDR 0x0d -+#define RTC_ALARM_SEC_ADDR 0x0e -+#define RTC_WDF_ADDR 0x0f -+#define RTC_SQW_ADDR 0x13 -+ -+ -+static DECLARE_MUTEX(m41t85_mutex); -+ -+static struct i2c_driver m41t85_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 -+m41t85_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; -+ -+ down(&m41t85_mutex); -+ do { -+ -+ if (((sec = i2c_smbus_read_byte_data(save_client, RTC_SEC_ADDR)) >= 0) -+ && ((min = i2c_smbus_read_byte_data(save_client, RTC_MIN_ADDR)) -+ >= 0) -+ && ((hour = i2c_smbus_read_byte_data(save_client, RTC_HOUR_ADDR)) -+ >= 0) -+ && ((day = i2c_smbus_read_byte_data(save_client, RTC_DAY_ADDR)) -+ >= 0) -+ && ((mon = i2c_smbus_read_byte_data(save_client, RTC_MONTH_ADDR)) -+ >= 0) -+ && ((year = i2c_smbus_read_byte_data(save_client, RTC_YEARS_ADDR)) -+ >= 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); -+ up(&m41t85_mutex); -+ -+ if (limit = 0) { -+ dev_warn(&save_client->dev, -+ "m41t85: can't read rtc chip\n"); -+ sec = min = hour = day = mon = year = 0; -+ } -+ -+ sec = BCD2BIN(sec & 0x7f); -+ min = BCD2BIN(min & 0x7f); -+ hour = BCD2BIN(hour & 0x3f); -+ day = BCD2BIN(day & 0x3f); -+ mon = BCD2BIN(mon & 0x1f); -+ year = BCD2BIN(year & 0xff); -+ -+ year += 1900; -+ if (year < 1970) -+ year += 100; -+ -+ return mktime(year, mon, day, hour, min, sec); -+} -+ -+static void -+m41t85_set_tlet(ulong arg) -+{ -+ struct rtc_time tm; -+ ulong nowtime = *(ulong *)arg; -+ -+ to_tm(nowtime, &tm); -+ tm.tm_year = (tm.tm_year - 1900) % 100; -+ -+ tm.tm_sec = BIN2BCD(tm.tm_sec); -+ tm.tm_min = BIN2BCD(tm.tm_min); -+ tm.tm_hour = BIN2BCD(tm.tm_hour); -+ tm.tm_mon = BIN2BCD(tm.tm_mon); -+ tm.tm_mday = BIN2BCD(tm.tm_mday); -+ tm.tm_year = BIN2BCD(tm.tm_year); -+ -+ down(&m41t85_mutex); -+ if ((i2c_smbus_write_byte_data(save_client, RTC_SEC_ADDR, tm.tm_sec & 0x7f) < 0) -+ || (i2c_smbus_write_byte_data(save_client, RTC_MIN_ADDR, tm.tm_min & 0x7f) -+ < 0) -+ || (i2c_smbus_write_byte_data(save_client, RTC_HOUR_ADDR, tm.tm_hour & 0x7f) -+ < 0) -+ || (i2c_smbus_write_byte_data(save_client, RTC_DAY_ADDR, tm.tm_mday & 0x7f) -+ < 0) -+ || (i2c_smbus_write_byte_data(save_client, RTC_MONTH_ADDR, tm.tm_mon & 0x7f) -+ < 0) -+ || (i2c_smbus_write_byte_data(save_client, RTC_YEARS_ADDR, tm.tm_year & 0x7f) -+ < 0)) -+ -+ dev_warn(&save_client->dev,"m41t85: can't write to rtc chip\n"); -+ -+ up(&m41t85_mutex); -+ return; -+} -+ -+static ulong new_time; -+ -+DECLARE_TASKLET_DISABLED(m41t85_tasklet, m41t85_set_tlet, (ulong)&new_time); -+ -+int -+m41t85_set_rtc_time(ulong nowtime) -+{ -+ new_time = nowtime; -+ -+ if (in_interrupt()) -+ tasklet_schedule(&m41t85_tasklet); -+ else -+ m41t85_set_tlet((ulong)&new_time); -+ -+ return 0; -+} -+ -+/* -+ ***************************************************************************** -+ * -+ * Driver Interface -+ * -+ ***************************************************************************** -+ */ -+static int -+m41t85_probe(struct i2c_adapter *adap, int addr, int kind) -+{ -+ struct i2c_client *client; -+ int ret; -+ s32 reg; -+ -+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); -+ if (!client) -+ return -ENOMEM; -+ -+ strncpy(client->name, M41T85_DRV_NAME, I2C_NAME_SIZE); -+ client->addr = addr; -+ client->adapter = adap; -+ client->driver = &m41t85_driver; -+ -+ if ((ret = i2c_attach_client(client)) != 0) { -+ kfree(client); -+ return ret; -+ } -+ -+ #if defined (CONFIG_SENSORS_M41T85_SQW_FRQ) -+ reg = i2c_smbus_read_byte_data(client, RTC_ALARM_MONTH_ADDR); -+ if (reg >=0 && (reg & 0x40) = 0) { -+ ret = i2c_smbus_write_byte_data(client, RTC_SQW_ADDR, CONFIG_SENSORS_M41T85_SQW_FRQ); -+ if(ret = 0) -+ i2c_smbus_write_byte_data(client, RTC_ALARM_MONTH_ADDR, reg | 0x40); -+ } -+ #endif -+ /* Check if ST flag set, and if yes, then clear it */ -+ reg = i2c_smbus_read_byte_data(client, RTC_SEC_ADDR); -+ if (reg >=0 && (reg & 0x80) != 0) -+ i2c_smbus_write_byte_data(client, RTC_SEC_ADDR, reg & ~0x80); -+ -+ /* Check if HT flag set, and if yes, then clear it */ -+ reg = i2c_smbus_read_byte_data(client, RTC_ALARM_HOUR_ADDR); -+ if (reg >=0 && (reg & 0x40) != 0) -+ i2c_smbus_write_byte_data(client, RTC_ALARM_HOUR_ADDR, reg & ~0x40); -+ -+ save_client = client; -+ return 0; -+} -+ -+static int -+m41t85_attach(struct i2c_adapter *adap) -+{ -+ return i2c_probe(adap, &addr_data, m41t85_probe); -+} -+ -+static int -+m41t85_detach(struct i2c_client *client) -+{ -+ int rc; -+ -+ if ((rc = i2c_detach_client(client)) = 0) { -+ kfree(client); -+ tasklet_kill(&m41t85_tasklet); -+ } -+ return rc; -+} -+ -+static struct i2c_driver m41t85_driver = { -+ .owner = THIS_MODULE, -+ .name = M41T85_DRV_NAME, -+ .id = I2C_DRIVERID_STM41T85, -+ .flags = I2C_DF_NOTIFY, -+ .attach_adapter = m41t85_attach, -+ .detach_client = m41t85_detach, -+}; -+ -+static int __init -+m41t85_init(void) -+{ -+ return i2c_add_driver(&m41t85_driver); -+} -+ -+static void __exit -+m41t85_exit(void) -+{ -+ i2c_del_driver(&m41t85_driver); -+ return; -+} -+ -+module_init(m41t85_init); -+module_exit(m41t85_exit); -+ -+MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>"); -+MODULE_DESCRIPTION("ST Microelectronics M41T85 RTC I2C Client Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h -index 5c05f52..ac8ffcd 100644 ---- a/include/linux/i2c-id.h -+++ b/include/linux/i2c-id.h -@@ -108,6 +108,7 @@ - #define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ - #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ - #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ -+#define I2C_DRIVERID_STM41T85 75 /* real time clock */ - - #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ - #define I2C_DRIVERID_EXP1 0xF1 diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..3697b7c --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,5 @@ +Content-Type: text/plain; + name="m41t85_rtc.diff" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="m41t85_rtc.diff" diff --git a/N1/2.txt b/N1/2.txt new file mode 100644 index 0000000..2ed0198 --- /dev/null +++ b/N1/2.txt @@ -0,0 +1,425 @@ +Added support of ST M41T85 RTC + +Signed-off-By: Andrey Volkov <avolkov@varma-el.com> +--- + + drivers/i2c/chips/Kconfig | 88 ++++++++++++++ + drivers/i2c/chips/Makefile | 1 + drivers/i2c/chips/m41t85.c | 285 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/i2c-id.h | 1 + 4 files changed, 375 insertions(+), 0 deletions(-) + +diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig +index f9fae28..6593fc5 100644 +--- a/drivers/i2c/chips/Kconfig ++++ b/drivers/i2c/chips/Kconfig +@@ -111,6 +111,94 @@ config SENSORS_M41T00 + This driver can also be built as a module. If so, the module + will be called m41t00. + ++config SENSORS_M41T85 ++ tristate "ST M41T85 RTC chip" ++ depends on I2C ++ help ++ If you say yes here you get support for the ST M41T85 RTC chip. ++ ++ This driver can also be built as a module. If so, the module ++ will be called m41t85. ++ ++config SENSORS_M41T85_SQW_FRQ_ENABLE ++ depends on SENSORS_M41T85 ++ bool "Square Wave Output" ++ help ++ If you say yes here, then m41t85 will generate clocks on it ++ SQW pin at frequency which you are select below. ++ ++choice ++ prompt "SQW frequincy" ++ depends on SENSORS_M41T85_SQW_FRQ_ENABLE ++ default SENSORS_M41T85_SQW_FRQ_32KHZ ++ ++config SENSORS_M41T85_SQW_FRQ_32KHZ ++ bool "32.768 kHz" ++ ++config SENSORS_M41T85_SQW_FRQ_8KHZ ++ bool "8 kHz" ++ ++config SENSORS_M41T85_SQW_FRQ_4KHZ ++ bool "4 kHz" ++ ++config SENSORS_M41T85_SQW_FRQ_2KHZ ++ bool "2 kHz" ++ ++config SENSORS_M41T85_SQW_FRQ_1KHZ ++ bool "1 kHz" ++ ++config SENSORS_M41T85_SQW_FRQ_512HZ ++ bool "512 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_256HZ ++ bool "256 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_128HZ ++ bool "128 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_64HZ ++ bool "64 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_32HZ ++ bool "32 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_16HZ ++ bool "16 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_8HZ ++ bool "8 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_4HZ ++ bool "4 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_2HZ ++ bool "2 Hz" ++ ++config SENSORS_M41T85_SQW_FRQ_1HZ ++ bool "1 Hz" ++ ++endchoice ++ ++config SENSORS_M41T85_SQW_FRQ ++ int ++ depends on SENSORS_M41T85_SQW_FRQ_ENABLE ++ default "1" if SENSORS_M41T85_SQW_FRQ_32KHZ ++ default "2" if SENSORS_M41T85_SQW_FRQ_8KHZ ++ default "3" if SENSORS_M41T85_SQW_FRQ_4KHZ ++ default "4" if SENSORS_M41T85_SQW_FRQ_2KHZ ++ default "5" if SENSORS_M41T85_SQW_FRQ_1KHZ ++ default "6" if SENSORS_M41T85_SQW_FRQ_512HZ ++ default "7" if SENSORS_M41T85_SQW_FRQ_256HZ ++ default "8" if SENSORS_M41T85_SQW_FRQ_128HZ ++ default "9" if SENSORS_M41T85_SQW_FRQ_64HZ ++ default "10" if SENSORS_M41T85_SQW_FRQ_32HZ ++ default "11" if SENSORS_M41T85_SQW_FRQ_16HZ ++ default "12" if SENSORS_M41T85_SQW_FRQ_8HZ ++ default "13" if SENSORS_M41T85_SQW_FRQ_4HZ ++ default "14" if SENSORS_M41T85_SQW_FRQ_2HZ ++ default "15" if SENSORS_M41T85_SQW_FRQ_1HZ ++ ++ + config SENSORS_MAX6875 + tristate "Maxim MAX6875 Power supply supervisor" + depends on I2C && EXPERIMENTAL +diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile +index 46178b5..5637881 100644 +--- a/drivers/i2c/chips/Makefile ++++ b/drivers/i2c/chips/Makefile +@@ -14,6 +14,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_SENSORS_M41T85) += m41t85.o + + ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) + EXTRA_CFLAGS += -DDEBUG +diff --git a/drivers/i2c/chips/m41t85.c b/drivers/i2c/chips/m41t85.c +new file mode 100644 +index 0000000..f26a115 +--- /dev/null ++++ b/drivers/i2c/chips/m41t85.c +@@ -0,0 +1,285 @@ ++/* ++ * drivers/i2c/chips/m41t85.c ++ * ++ * DESCRIPTION: ++ * I2C client/driver for the ST M41T85 Real-Time Clock chip. ++ * ++ * AUTHOR: ++ * Andrey Volkov <avolkov@varma-el.com> ++ * ++ * COPYRIGHT: ++ * 2005, Varma Electronics Oy ++ * ++ * Based on driver for ST M41T00 by Mark A. Greer <mgreer@mvista.com> ++ * (see m41t00.c for copyright) ++ * ++ * LICENCE: ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License version 2. See the file COPYING in the main directory of this archive ++ * for more details. ++ * ++ * HISTORY: ++ * 2005-10-12 Created ++ */ ++ ++/* ++ * 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/config.h> ++#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 <asm/time.h> ++#include <asm/rtc.h> ++ ++#define M41T85_DRV_NAME "m41t85" ++ ++#define RTC_CSEC_ADDR 0x00 ++#define RTC_SEC_ADDR 0x01 ++#define RTC_MIN_ADDR 0x02 ++#define RTC_HOUR_ADDR 0x03 ++#define RTC_WDAY_ADDR 0x04 ++#define RTC_DAY_ADDR 0x05 ++#define RTC_MONTH_ADDR 0x06 ++#define RTC_YEARS_ADDR 0x07 ++#define RTC_CONTROL_ADDR 0x08 ++#define RTC_WATCHDOG_ADDR 0x09 ++#define RTC_ALARM_MONTH_ADDR 0x0a ++#define RTC_ALARM_DATE_ADDR 0x0b ++#define RTC_ALARM_HOUR_ADDR 0x0c ++#define RTC_ALARM_MIN_ADDR 0x0d ++#define RTC_ALARM_SEC_ADDR 0x0e ++#define RTC_WDF_ADDR 0x0f ++#define RTC_SQW_ADDR 0x13 ++ ++ ++static DECLARE_MUTEX(m41t85_mutex); ++ ++static struct i2c_driver m41t85_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 ++m41t85_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; ++ ++ down(&m41t85_mutex); ++ do { ++ ++ if (((sec = i2c_smbus_read_byte_data(save_client, RTC_SEC_ADDR)) >= 0) ++ && ((min = i2c_smbus_read_byte_data(save_client, RTC_MIN_ADDR)) ++ >= 0) ++ && ((hour = i2c_smbus_read_byte_data(save_client, RTC_HOUR_ADDR)) ++ >= 0) ++ && ((day = i2c_smbus_read_byte_data(save_client, RTC_DAY_ADDR)) ++ >= 0) ++ && ((mon = i2c_smbus_read_byte_data(save_client, RTC_MONTH_ADDR)) ++ >= 0) ++ && ((year = i2c_smbus_read_byte_data(save_client, RTC_YEARS_ADDR)) ++ >= 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); ++ up(&m41t85_mutex); ++ ++ if (limit == 0) { ++ dev_warn(&save_client->dev, ++ "m41t85: can't read rtc chip\n"); ++ sec = min = hour = day = mon = year = 0; ++ } ++ ++ sec = BCD2BIN(sec & 0x7f); ++ min = BCD2BIN(min & 0x7f); ++ hour = BCD2BIN(hour & 0x3f); ++ day = BCD2BIN(day & 0x3f); ++ mon = BCD2BIN(mon & 0x1f); ++ year = BCD2BIN(year & 0xff); ++ ++ year += 1900; ++ if (year < 1970) ++ year += 100; ++ ++ return mktime(year, mon, day, hour, min, sec); ++} ++ ++static void ++m41t85_set_tlet(ulong arg) ++{ ++ struct rtc_time tm; ++ ulong nowtime = *(ulong *)arg; ++ ++ to_tm(nowtime, &tm); ++ tm.tm_year = (tm.tm_year - 1900) % 100; ++ ++ tm.tm_sec = BIN2BCD(tm.tm_sec); ++ tm.tm_min = BIN2BCD(tm.tm_min); ++ tm.tm_hour = BIN2BCD(tm.tm_hour); ++ tm.tm_mon = BIN2BCD(tm.tm_mon); ++ tm.tm_mday = BIN2BCD(tm.tm_mday); ++ tm.tm_year = BIN2BCD(tm.tm_year); ++ ++ down(&m41t85_mutex); ++ if ((i2c_smbus_write_byte_data(save_client, RTC_SEC_ADDR, tm.tm_sec & 0x7f) < 0) ++ || (i2c_smbus_write_byte_data(save_client, RTC_MIN_ADDR, tm.tm_min & 0x7f) ++ < 0) ++ || (i2c_smbus_write_byte_data(save_client, RTC_HOUR_ADDR, tm.tm_hour & 0x7f) ++ < 0) ++ || (i2c_smbus_write_byte_data(save_client, RTC_DAY_ADDR, tm.tm_mday & 0x7f) ++ < 0) ++ || (i2c_smbus_write_byte_data(save_client, RTC_MONTH_ADDR, tm.tm_mon & 0x7f) ++ < 0) ++ || (i2c_smbus_write_byte_data(save_client, RTC_YEARS_ADDR, tm.tm_year & 0x7f) ++ < 0)) ++ ++ dev_warn(&save_client->dev,"m41t85: can't write to rtc chip\n"); ++ ++ up(&m41t85_mutex); ++ return; ++} ++ ++static ulong new_time; ++ ++DECLARE_TASKLET_DISABLED(m41t85_tasklet, m41t85_set_tlet, (ulong)&new_time); ++ ++int ++m41t85_set_rtc_time(ulong nowtime) ++{ ++ new_time = nowtime; ++ ++ if (in_interrupt()) ++ tasklet_schedule(&m41t85_tasklet); ++ else ++ m41t85_set_tlet((ulong)&new_time); ++ ++ return 0; ++} ++ ++/* ++ ***************************************************************************** ++ * ++ * Driver Interface ++ * ++ ***************************************************************************** ++ */ ++static int ++m41t85_probe(struct i2c_adapter *adap, int addr, int kind) ++{ ++ struct i2c_client *client; ++ int ret; ++ s32 reg; ++ ++ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); ++ if (!client) ++ return -ENOMEM; ++ ++ strncpy(client->name, M41T85_DRV_NAME, I2C_NAME_SIZE); ++ client->addr = addr; ++ client->adapter = adap; ++ client->driver = &m41t85_driver; ++ ++ if ((ret = i2c_attach_client(client)) != 0) { ++ kfree(client); ++ return ret; ++ } ++ ++ #if defined (CONFIG_SENSORS_M41T85_SQW_FRQ) ++ reg = i2c_smbus_read_byte_data(client, RTC_ALARM_MONTH_ADDR); ++ if (reg >=0 && (reg & 0x40) == 0) { ++ ret = i2c_smbus_write_byte_data(client, RTC_SQW_ADDR, CONFIG_SENSORS_M41T85_SQW_FRQ); ++ if(ret == 0) ++ i2c_smbus_write_byte_data(client, RTC_ALARM_MONTH_ADDR, reg | 0x40); ++ } ++ #endif ++ /* Check if ST flag set, and if yes, then clear it */ ++ reg = i2c_smbus_read_byte_data(client, RTC_SEC_ADDR); ++ if (reg >=0 && (reg & 0x80) != 0) ++ i2c_smbus_write_byte_data(client, RTC_SEC_ADDR, reg & ~0x80); ++ ++ /* Check if HT flag set, and if yes, then clear it */ ++ reg = i2c_smbus_read_byte_data(client, RTC_ALARM_HOUR_ADDR); ++ if (reg >=0 && (reg & 0x40) != 0) ++ i2c_smbus_write_byte_data(client, RTC_ALARM_HOUR_ADDR, reg & ~0x40); ++ ++ save_client = client; ++ return 0; ++} ++ ++static int ++m41t85_attach(struct i2c_adapter *adap) ++{ ++ return i2c_probe(adap, &addr_data, m41t85_probe); ++} ++ ++static int ++m41t85_detach(struct i2c_client *client) ++{ ++ int rc; ++ ++ if ((rc = i2c_detach_client(client)) == 0) { ++ kfree(client); ++ tasklet_kill(&m41t85_tasklet); ++ } ++ return rc; ++} ++ ++static struct i2c_driver m41t85_driver = { ++ .owner = THIS_MODULE, ++ .name = M41T85_DRV_NAME, ++ .id = I2C_DRIVERID_STM41T85, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = m41t85_attach, ++ .detach_client = m41t85_detach, ++}; ++ ++static int __init ++m41t85_init(void) ++{ ++ return i2c_add_driver(&m41t85_driver); ++} ++ ++static void __exit ++m41t85_exit(void) ++{ ++ i2c_del_driver(&m41t85_driver); ++ return; ++} ++ ++module_init(m41t85_init); ++module_exit(m41t85_exit); ++ ++MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>"); ++MODULE_DESCRIPTION("ST Microelectronics M41T85 RTC I2C Client Driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h +index 5c05f52..ac8ffcd 100644 +--- a/include/linux/i2c-id.h ++++ b/include/linux/i2c-id.h +@@ -108,6 +108,7 @@ + #define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ + #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ + #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ ++#define I2C_DRIVERID_STM41T85 75 /* real time clock */ + + #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ + #define I2C_DRIVERID_EXP1 0xF1 diff --git a/a/content_digest b/N1/content_digest index b9c2096..021c5c9 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,10 +1,10 @@ - "From\0avolkov@varma-el.com (Andrey Volkov)\0" - "Subject\0[lm-sensors] [PATCH 1/1] Added support of ST m41t85 rtc chip\0" - "Date\0Mon, 14 Nov 2005 14:51:25 +0000\0" + "From\0Andrey Volkov <avolkov@varma-el.com>\0" + "Subject\0[PATCH 1/1] Added support of ST m41t85 rtc chip\0" + "Date\0Mon, 14 Nov 2005 16:50:07 +0300\0" "To\0khali@linux-fr.org\0" "Cc\0lm-sensors@lm-sensors.org" " linux-kernel@vger.kernel.org\0" - "\00:1\0" + "\01:1\0" "b\0" "Hello Jean,\n" "\n" @@ -17,8 +17,10 @@ "Regards\n" "Andrey Volkov\n" "\n" - "P.S. Please CC to me directly, I'm not in lm-sensors@lm-sensors.org list.\n" - "-------------- next part --------------\n" + P.S. Please CC to me directly, I'm not in lm-sensors@lm-sensors.org list. + "\01:2\0" + "fn\0m41t85_rtc.diff\0" + "b\0" "Added support of ST M41T85 RTC\n" "\n" "Signed-off-By: Andrey Volkov <avolkov@varma-el.com>\n" @@ -249,9 +251,9 @@ "+\t\t\t\t>= 0)\n" "+\t\t\t&& ((year = i2c_smbus_read_byte_data(save_client, RTC_YEARS_ADDR))\n" "+\t\t\t\t>= 0)\n" - "+\t\t\t&& ((sec = sec1) && (min = min1) && (hour = hour1)\n" - "+\t\t\t\t&& (day = day1) && (mon = mon1)\n" - "+\t\t\t\t&& (year = year1)))\n" + "+\t\t\t&& ((sec == sec1) && (min == min1) && (hour == hour1)\n" + "+\t\t\t\t&& (day == day1) && (mon == mon1)\n" + "+\t\t\t\t&& (year == year1)))\n" "+\n" "+\t\t\t\tbreak;\n" "+\n" @@ -264,7 +266,7 @@ "+\t} while (--limit > 0);\n" "+\tup(&m41t85_mutex);\n" "+\n" - "+\tif (limit = 0) {\n" + "+\tif (limit == 0) {\n" "+\t\tdev_warn(&save_client->dev,\n" "+\t\t\t\"m41t85: can't read rtc chip\\n\");\n" "+\t\tsec = min = hour = day = mon = year = 0;\n" @@ -366,9 +368,9 @@ "+\n" "+\t#if defined (CONFIG_SENSORS_M41T85_SQW_FRQ)\n" "+\treg = i2c_smbus_read_byte_data(client, RTC_ALARM_MONTH_ADDR);\n" - "+\tif (reg >=0 && (reg & 0x40) = 0) { \n" + "+\tif (reg >=0 && (reg & 0x40) == 0) { \n" "+\t\tret = i2c_smbus_write_byte_data(client, RTC_SQW_ADDR, CONFIG_SENSORS_M41T85_SQW_FRQ);\n" - "+\t\tif(ret = 0)\n" + "+\t\tif(ret == 0)\n" "+\t\t\ti2c_smbus_write_byte_data(client, RTC_ALARM_MONTH_ADDR, reg | 0x40);\n" "+\t}\n" "+\t#endif\n" @@ -397,7 +399,7 @@ "+{\n" "+\tint\trc;\n" "+\n" - "+\tif ((rc = i2c_detach_client(client)) = 0) {\n" + "+\tif ((rc = i2c_detach_client(client)) == 0) {\n" "+\t\tkfree(client);\n" "+\t\ttasklet_kill(&m41t85_tasklet);\n" "+\t}\n" @@ -445,4 +447,4 @@ " #define I2C_DRIVERID_EXP0\t0xF0\t/* experimental use id's\t*/\n" " #define I2C_DRIVERID_EXP1\t0xF1" -996646deb6fc748a549a18fc548cc721ff617a5577beb95ddf8062080d1e8758 +cdfcb4e88e18b27bda83bc0e67369e0e0bc09aafe73c556963ce6cfc041c239f
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.