aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-pcf8563.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-pcf8563.c')
-rw-r--r--drivers/rtc/rtc-pcf8563.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 4b72b8ef5d66..038118bbfaea 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -53,6 +53,25 @@ I2C_CLIENT_INSMOD;
53#define PCF8563_SC_LV 0x80 /* low voltage */ 53#define PCF8563_SC_LV 0x80 /* low voltage */
54#define PCF8563_MO_C 0x80 /* century */ 54#define PCF8563_MO_C 0x80 /* century */
55 55
56struct pcf8563 {
57 struct i2c_client client;
58 /*
59 * The meaning of MO_C bit varies by the chip type.
60 * From PCF8563 datasheet: this bit is toggled when the years
61 * register overflows from 99 to 00
62 * 0 indicates the century is 20xx
63 * 1 indicates the century is 19xx
64 * From RTC8564 datasheet: this bit indicates change of
65 * century. When the year digit data overflows from 99 to 00,
66 * this bit is set. By presetting it to 0 while still in the
67 * 20th century, it will be set in year 2000, ...
68 * There seems no reliable way to know how the system use this
69 * bit. So let's do it heuristically, assuming we are live in
70 * 1970...2069.
71 */
72 int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
73};
74
56static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind); 75static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
57static int pcf8563_detach(struct i2c_client *client); 76static int pcf8563_detach(struct i2c_client *client);
58 77
@@ -62,6 +81,7 @@ static int pcf8563_detach(struct i2c_client *client);
62 */ 81 */
63static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) 82static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
64{ 83{
84 struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
65 unsigned char buf[13] = { PCF8563_REG_ST1 }; 85 unsigned char buf[13] = { PCF8563_REG_ST1 };
66 86
67 struct i2c_msg msgs[] = { 87 struct i2c_msg msgs[] = {
@@ -94,8 +114,12 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
94 tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F); 114 tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
95 tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; 115 tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
96 tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ 116 tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
97 tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]) 117 tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]);
98 + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100); 118 if (tm->tm_year < 70)
119 tm->tm_year += 100; /* assume we are in 1970...2069 */
120 /* detect the polarity heuristically. see note above. */
121 pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
122 (tm->tm_year >= 100) : (tm->tm_year < 100);
99 123
100 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 124 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
101 "mday=%d, mon=%d, year=%d, wday=%d\n", 125 "mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -114,6 +138,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
114 138
115static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) 139static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
116{ 140{
141 struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
117 int i, err; 142 int i, err;
118 unsigned char buf[9]; 143 unsigned char buf[9];
119 144
@@ -135,7 +160,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
135 160
136 /* year and century */ 161 /* year and century */
137 buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100); 162 buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
138 if (tm->tm_year < 100) 163 if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
139 buf[PCF8563_REG_MO] |= PCF8563_MO_C; 164 buf[PCF8563_REG_MO] |= PCF8563_MO_C;
140 165
141 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; 166 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
@@ -248,6 +273,7 @@ static struct i2c_driver pcf8563_driver = {
248 273
249static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) 274static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
250{ 275{
276 struct pcf8563 *pcf8563;
251 struct i2c_client *client; 277 struct i2c_client *client;
252 struct rtc_device *rtc; 278 struct rtc_device *rtc;
253 279
@@ -260,11 +286,12 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
260 goto exit; 286 goto exit;
261 } 287 }
262 288
263 if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { 289 if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
264 err = -ENOMEM; 290 err = -ENOMEM;
265 goto exit; 291 goto exit;
266 } 292 }
267 293
294 client = &pcf8563->client;
268 client->addr = address; 295 client->addr = address;
269 client->driver = &pcf8563_driver; 296 client->driver = &pcf8563_driver;
270 client->adapter = adapter; 297 client->adapter = adapter;
@@ -301,7 +328,7 @@ exit_detach:
301 i2c_detach_client(client); 328 i2c_detach_client(client);
302 329
303exit_kfree: 330exit_kfree:
304 kfree(client); 331 kfree(pcf8563);
305 332
306exit: 333exit:
307 return err; 334 return err;
@@ -309,6 +336,7 @@ exit:
309 336
310static int pcf8563_detach(struct i2c_client *client) 337static int pcf8563_detach(struct i2c_client *client)
311{ 338{
339 struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
312 int err; 340 int err;
313 struct rtc_device *rtc = i2c_get_clientdata(client); 341 struct rtc_device *rtc = i2c_get_clientdata(client);
314 342
@@ -318,7 +346,7 @@ static int pcf8563_detach(struct i2c_client *client)
318 if ((err = i2c_detach_client(client))) 346 if ((err = i2c_detach_client(client)))
319 return err; 347 return err;
320 348
321 kfree(client); 349 kfree(pcf8563);
322 350
323 return 0; 351 return 0;
324} 352}