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.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index c2ef0a22ee94..96fb32e7d6f8 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -28,6 +28,7 @@
28#define PCF8563_REG_ST2 0x01 28#define PCF8563_REG_ST2 0x01
29#define PCF8563_BIT_AIE (1 << 1) 29#define PCF8563_BIT_AIE (1 << 1)
30#define PCF8563_BIT_AF (1 << 3) 30#define PCF8563_BIT_AF (1 << 3)
31#define PCF8563_BITS_ST2_N (7 << 5)
31 32
32#define PCF8563_REG_SC 0x02 /* datetime */ 33#define PCF8563_REG_SC 0x02 /* datetime */
33#define PCF8563_REG_MN 0x03 34#define PCF8563_REG_MN 0x03
@@ -41,6 +42,13 @@
41 42
42#define PCF8563_REG_CLKO 0x0D /* clock out */ 43#define PCF8563_REG_CLKO 0x0D /* clock out */
43#define PCF8563_REG_TMRC 0x0E /* timer control */ 44#define PCF8563_REG_TMRC 0x0E /* timer control */
45#define PCF8563_TMRC_ENABLE BIT(7)
46#define PCF8563_TMRC_4096 0
47#define PCF8563_TMRC_64 1
48#define PCF8563_TMRC_1 2
49#define PCF8563_TMRC_1_60 3
50#define PCF8563_TMRC_MASK 3
51
44#define PCF8563_REG_TMR 0x0F /* timer */ 52#define PCF8563_REG_TMR 0x0F /* timer */
45 53
46#define PCF8563_SC_LV 0x80 /* low voltage */ 54#define PCF8563_SC_LV 0x80 /* low voltage */
@@ -118,22 +126,21 @@ static int pcf8563_write_block_data(struct i2c_client *client,
118 126
119static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on) 127static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on)
120{ 128{
121 unsigned char buf[2]; 129 unsigned char buf;
122 int err; 130 int err;
123 131
124 err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, buf + 1); 132 err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf);
125 if (err < 0) 133 if (err < 0)
126 return err; 134 return err;
127 135
128 if (on) 136 if (on)
129 buf[1] |= PCF8563_BIT_AIE; 137 buf |= PCF8563_BIT_AIE;
130 else 138 else
131 buf[1] &= ~PCF8563_BIT_AIE; 139 buf &= ~PCF8563_BIT_AIE;
132 140
133 buf[1] &= ~PCF8563_BIT_AF; 141 buf &= ~(PCF8563_BIT_AF | PCF8563_BITS_ST2_N);
134 buf[0] = PCF8563_REG_ST2;
135 142
136 err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, buf + 1); 143 err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf);
137 if (err < 0) { 144 if (err < 0) {
138 dev_err(&client->dev, "%s: write error\n", __func__); 145 dev_err(&client->dev, "%s: write error\n", __func__);
139 return -EIO; 146 return -EIO;
@@ -336,8 +343,8 @@ static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
336 __func__, buf[0], buf[1], buf[2], buf[3]); 343 __func__, buf[0], buf[1], buf[2], buf[3]);
337 344
338 tm->time.tm_min = bcd2bin(buf[0] & 0x7F); 345 tm->time.tm_min = bcd2bin(buf[0] & 0x7F);
339 tm->time.tm_hour = bcd2bin(buf[1] & 0x7F); 346 tm->time.tm_hour = bcd2bin(buf[1] & 0x3F);
340 tm->time.tm_mday = bcd2bin(buf[2] & 0x1F); 347 tm->time.tm_mday = bcd2bin(buf[2] & 0x3F);
341 tm->time.tm_wday = bcd2bin(buf[3] & 0x7); 348 tm->time.tm_wday = bcd2bin(buf[3] & 0x7);
342 tm->time.tm_mon = -1; 349 tm->time.tm_mon = -1;
343 tm->time.tm_year = -1; 350 tm->time.tm_year = -1;
@@ -361,6 +368,14 @@ static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
361 struct i2c_client *client = to_i2c_client(dev); 368 struct i2c_client *client = to_i2c_client(dev);
362 unsigned char buf[4]; 369 unsigned char buf[4];
363 int err; 370 int err;
371 unsigned long alarm_time;
372
373 /* The alarm has no seconds, round up to nearest minute */
374 if (tm->time.tm_sec) {
375 rtc_tm_to_time(&tm->time, &alarm_time);
376 alarm_time += 60-tm->time.tm_sec;
377 rtc_time_to_tm(alarm_time, &tm->time);
378 }
364 379
365 dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d " 380 dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d "
366 "enabled=%d pending=%d\n", __func__, 381 "enabled=%d pending=%d\n", __func__,
@@ -381,6 +396,7 @@ static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
381 396
382static int pcf8563_irq_enable(struct device *dev, unsigned int enabled) 397static int pcf8563_irq_enable(struct device *dev, unsigned int enabled)
383{ 398{
399 dev_dbg(dev, "%s: en=%d\n", __func__, enabled);
384 return pcf8563_set_alarm_mode(to_i2c_client(dev), !!enabled); 400 return pcf8563_set_alarm_mode(to_i2c_client(dev), !!enabled);
385} 401}
386 402
@@ -398,6 +414,8 @@ static int pcf8563_probe(struct i2c_client *client,
398{ 414{
399 struct pcf8563 *pcf8563; 415 struct pcf8563 *pcf8563;
400 int err; 416 int err;
417 unsigned char buf;
418 unsigned char alm_pending;
401 419
402 dev_dbg(&client->dev, "%s\n", __func__); 420 dev_dbg(&client->dev, "%s\n", __func__);
403 421
@@ -415,6 +433,22 @@ static int pcf8563_probe(struct i2c_client *client,
415 pcf8563->client = client; 433 pcf8563->client = client;
416 device_set_wakeup_capable(&client->dev, 1); 434 device_set_wakeup_capable(&client->dev, 1);
417 435
436 /* Set timer to lowest frequency to save power (ref Haoyu datasheet) */
437 buf = PCF8563_TMRC_1_60;
438 err = pcf8563_write_block_data(client, PCF8563_REG_TMRC, 1, &buf);
439 if (err < 0) {
440 dev_err(&client->dev, "%s: write error\n", __func__);
441 return err;
442 }
443
444 err = pcf8563_get_alarm_mode(client, NULL, &alm_pending);
445 if (err < 0) {
446 dev_err(&client->dev, "%s: read error\n", __func__);
447 return err;
448 }
449 if (alm_pending)
450 pcf8563_set_alarm_mode(client, 0);
451
418 pcf8563->rtc = devm_rtc_device_register(&client->dev, 452 pcf8563->rtc = devm_rtc_device_register(&client->dev,
419 pcf8563_driver.driver.name, 453 pcf8563_driver.driver.name,
420 &pcf8563_rtc_ops, THIS_MODULE); 454 &pcf8563_rtc_ops, THIS_MODULE);
@@ -435,6 +469,9 @@ static int pcf8563_probe(struct i2c_client *client,
435 469
436 } 470 }
437 471
472 /* the pcf8563 alarm only supports a minute accuracy */
473 pcf8563->rtc->uie_unsupported = 1;
474
438 return 0; 475 return 0;
439} 476}
440 477