summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-05-08 18:35:14 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-05-08 18:35:14 +0000
commit6f1d708b3a7d567472c652e52d351aa08f113b0b (patch)
tree7f9e72d7008e7e93bff70680232859f418d49bb3 /sys/arch/sgi/dev
parent91fff480ee3773616bb312d1e45b471dc619b801 (diff)
IP30 Dallas clock runs in non-BCD mode, so make sure to check which mode
the chip is in, and honour it.
Diffstat (limited to 'sys/arch/sgi/dev')
-rw-r--r--sys/arch/sgi/dev/dsrtc.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/sys/arch/sgi/dev/dsrtc.c b/sys/arch/sgi/dev/dsrtc.c
index 6d9e7036ec8..7bb27e719df 100644
--- a/sys/arch/sgi/dev/dsrtc.c
+++ b/sys/arch/sgi/dev/dsrtc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsrtc.c,v 1.3 2009/04/20 20:31:06 miod Exp $ */
+/* $OpenBSD: dsrtc.c,v 1.4 2009/05/08 18:35:13 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -79,17 +79,17 @@ void ip30_dsrtc_write(struct dsrtc_softc *, int, int);
void ds1687_get(void *, time_t, struct tod_time *);
void ds1687_set(void *, struct tod_time *);
-static inline int frombcd(int);
-static inline int tobcd(int);
+static inline int frombcd(int, int);
+static inline int tobcd(int, int);
static inline int
-frombcd(int x)
+frombcd(int x, int binary)
{
- return (x >> 4) * 10 + (x & 0xf);
+ return binary ? x : (x >> 4) * 10 + (x & 0xf);
}
static inline int
-tobcd(int x)
+tobcd(int x, int binary)
{
- return (x / 10 * 16) + (x % 10);
+ return binary ? x : (x / 10 * 16) + (x % 10);
}
int
@@ -248,24 +248,27 @@ void
ds1687_get(void *v, time_t base, struct tod_time *ct)
{
struct dsrtc_softc *sc = v;
- int ctrl, century;
+ int ctrl, century, dm;
/* Select bank 1. */
ctrl = (*sc->read)(sc, DS1687_CTRL_A);
(*sc->write)(sc, DS1687_CTRL_A, ctrl | DS1687_BANK_1);
+ /* Figure out which data mode to use. */
+ dm = (*sc->read)(sc, DS1687_CTRL_B) & DS1687_DM_1;
+
/* Wait for no update in progress. */
while ((*sc->read)(sc, DS1687_CTRL_A) & DS1687_UIP)
/* Do nothing. */;
/* Read the RTC. */
- ct->sec = frombcd((*sc->read)(sc, DS1687_SEC));
- ct->min = frombcd((*sc->read)(sc, DS1687_MIN));
- ct->hour = frombcd((*sc->read)(sc, DS1687_HOUR));
- ct->day = frombcd((*sc->read)(sc, DS1687_DAY));
- ct->mon = frombcd((*sc->read)(sc, DS1687_MONTH));
- ct->year = frombcd((*sc->read)(sc, DS1687_YEAR));
- century = frombcd((*sc->read)(sc, DS1687_CENTURY));
+ ct->sec = frombcd((*sc->read)(sc, DS1687_SEC), dm);
+ ct->min = frombcd((*sc->read)(sc, DS1687_MIN), dm);
+ ct->hour = frombcd((*sc->read)(sc, DS1687_HOUR), dm);
+ ct->day = frombcd((*sc->read)(sc, DS1687_DAY), dm);
+ ct->mon = frombcd((*sc->read)(sc, DS1687_MONTH), dm);
+ ct->year = frombcd((*sc->read)(sc, DS1687_YEAR), dm);
+ century = frombcd((*sc->read)(sc, DS1687_CENTURY), dm);
ct->year += 100 * (century - 19);
}
@@ -274,7 +277,7 @@ void
ds1687_set(void *v, struct tod_time *ct)
{
struct dsrtc_softc *sc = v;
- int year, century, ctrl;
+ int year, century, ctrl, dm;
century = ct->year / 100 + 19;
year = ct->year % 100;
@@ -283,24 +286,24 @@ ds1687_set(void *v, struct tod_time *ct)
ctrl = (*sc->read)(sc, DS1687_CTRL_A);
(*sc->write)(sc, DS1687_CTRL_A, ctrl | DS1687_BANK_1);
- /* Select data mode 0 (BCD) and 24 hour time. */
+ /* Figure out which data mode to use, and select 24 hour time. */
ctrl = (*sc->read)(sc, DS1687_CTRL_B);
- (*sc->write)(sc, DS1687_CTRL_B,
- (ctrl & ~DS1687_DM_1) | DS1687_24_HR);
+ dm = ctrl & DS1687_DM_1;
+ (*sc->write)(sc, DS1687_CTRL_B, ctrl | DS1687_24_HR);
/* Prevent updates. */
ctrl = (*sc->read)(sc, DS1687_CTRL_B);
(*sc->write)(sc, DS1687_CTRL_B, ctrl | DS1687_SET_CLOCK);
/* Update the RTC. */
- (*sc->write)(sc, DS1687_SEC, tobcd(ct->sec));
- (*sc->write)(sc, DS1687_MIN, tobcd(ct->min));
- (*sc->write)(sc, DS1687_HOUR, tobcd(ct->hour));
- (*sc->write)(sc, DS1687_DOW, tobcd(ct->dow));
- (*sc->write)(sc, DS1687_DAY, tobcd(ct->day));
- (*sc->write)(sc, DS1687_MONTH, tobcd(ct->mon));
- (*sc->write)(sc, DS1687_YEAR, tobcd(year));
- (*sc->write)(sc, DS1687_CENTURY, tobcd(century));
+ (*sc->write)(sc, DS1687_SEC, tobcd(ct->sec, dm));
+ (*sc->write)(sc, DS1687_MIN, tobcd(ct->min, dm));
+ (*sc->write)(sc, DS1687_HOUR, tobcd(ct->hour, dm));
+ (*sc->write)(sc, DS1687_DOW, tobcd(ct->dow, dm));
+ (*sc->write)(sc, DS1687_DAY, tobcd(ct->day, dm));
+ (*sc->write)(sc, DS1687_MONTH, tobcd(ct->mon, dm));
+ (*sc->write)(sc, DS1687_YEAR, tobcd(year, dm));
+ (*sc->write)(sc, DS1687_CENTURY, tobcd(century, dm));
/* Enable updates. */
(*sc->write)(sc, DS1687_CTRL_B, ctrl);