]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.20.2/rtc-pcf8563-detect-polarity-of-century-bit-automatically.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.20.2 / rtc-pcf8563-detect-polarity-of-century-bit-automatically.patch
CommitLineData
40313dc0
GKH
1From stable-bounces@linux.kernel.org Sat Feb 3 06:18:09 2007
2From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
3Date: Sat, 03 Feb 2007 23:16:36 +0900 (JST)
4Subject: rtc-pcf8563: detect polarity of century bit automatically
5To: akpm@linux-foundation.org
6Cc: jean-baptiste.maneyrol@teamlog.com, a.zummo@towertech.it, dbrownell@users.sourceforge.net, torvalds@linux-foundation.org, stable@kernel.org
7Message-ID: <20070203.231636.41198366.anemo@mba.ocn.ne.jp>
8
9
10From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
11
12The usage of the century bit was inverted on 2.6.19 following to PCF8563's
13description, but it was not match to usage suggested by RTC8564's
14datasheet. Anyway what MO_C=1 means can vary on each platform. This patch
15is to detect its polarity in get_datetime routine. The default value of
16c_polarity is 0 (MO_C=1 means 19xx) so that this patch does not change
17current behavior even if get_datetime was not called before set_datetime.
18
19Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
20Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@teamlog.com>
21Cc: David Brownell <dbrownell@users.sourceforge.net>
22Cc: Alessandro Zummo <a.zummo@towertech.it>
23Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
24Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
25
26---
27 drivers/rtc/rtc-pcf8563.c | 40 ++++++++++++++++++++++++++++++++++------
28 1 file changed, 34 insertions(+), 6 deletions(-)
29
30--- linux-2.6.20.1.orig/drivers/rtc/rtc-pcf8563.c
31+++ linux-2.6.20.1/drivers/rtc/rtc-pcf8563.c
32@@ -53,6 +53,25 @@ I2C_CLIENT_INSMOD;
33 #define PCF8563_SC_LV 0x80 /* low voltage */
34 #define PCF8563_MO_C 0x80 /* century */
35
36+struct pcf8563 {
37+ struct i2c_client client;
38+ /*
39+ * The meaning of MO_C bit varies by the chip type.
40+ * From PCF8563 datasheet: this bit is toggled when the years
41+ * register overflows from 99 to 00
42+ * 0 indicates the century is 20xx
43+ * 1 indicates the century is 19xx
44+ * From RTC8564 datasheet: this bit indicates change of
45+ * century. When the year digit data overflows from 99 to 00,
46+ * this bit is set. By presetting it to 0 while still in the
47+ * 20th century, it will be set in year 2000, ...
48+ * There seems no reliable way to know how the system use this
49+ * bit. So let's do it heuristically, assuming we are live in
50+ * 1970...2069.
51+ */
52+ int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
53+};
54+
55 static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
56 static int pcf8563_detach(struct i2c_client *client);
57
58@@ -62,6 +81,7 @@ static int pcf8563_detach(struct i2c_cli
59 */
60 static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
61 {
62+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
63 unsigned char buf[13] = { PCF8563_REG_ST1 };
64
65 struct i2c_msg msgs[] = {
66@@ -94,8 +114,12 @@ static int pcf8563_get_datetime(struct i
67 tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
68 tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
69 tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
70- tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
71- + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
72+ tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]);
73+ if (tm->tm_year < 70)
74+ tm->tm_year += 100; /* assume we are in 1970...2069 */
75+ /* detect the polarity heuristically. see note above. */
76+ pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
77+ (tm->tm_year >= 100) : (tm->tm_year < 100);
78
79 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
80 "mday=%d, mon=%d, year=%d, wday=%d\n",
81@@ -114,6 +138,7 @@ static int pcf8563_get_datetime(struct i
82
83 static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
84 {
85+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
86 int i, err;
87 unsigned char buf[9];
88
89@@ -135,7 +160,7 @@ static int pcf8563_set_datetime(struct i
90
91 /* year and century */
92 buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
93- if (tm->tm_year < 100)
94+ if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
95 buf[PCF8563_REG_MO] |= PCF8563_MO_C;
96
97 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
98@@ -248,6 +273,7 @@ static struct i2c_driver pcf8563_driver
99
100 static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
101 {
102+ struct pcf8563 *pcf8563;
103 struct i2c_client *client;
104 struct rtc_device *rtc;
105
106@@ -260,11 +286,12 @@ static int pcf8563_probe(struct i2c_adap
107 goto exit;
108 }
109
110- if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
111+ if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
112 err = -ENOMEM;
113 goto exit;
114 }
115
116+ client = &pcf8563->client;
117 client->addr = address;
118 client->driver = &pcf8563_driver;
119 client->adapter = adapter;
120@@ -301,7 +328,7 @@ exit_detach:
121 i2c_detach_client(client);
122
123 exit_kfree:
124- kfree(client);
125+ kfree(pcf8563);
126
127 exit:
128 return err;
129@@ -309,6 +336,7 @@ exit:
130
131 static int pcf8563_detach(struct i2c_client *client)
132 {
133+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
134 int err;
135 struct rtc_device *rtc = i2c_get_clientdata(client);
136
137@@ -318,7 +346,7 @@ static int pcf8563_detach(struct i2c_cli
138 if ((err = i2c_detach_client(client)))
139 return err;
140
141- kfree(client);
142+ kfree(pcf8563);
143
144 return 0;
145 }