- support DS3231 ( more or less a DS3232 without NVRAM it seems )
- support the DS3231's temperature sensor
This commit is contained in:
parent
ee606c7e62
commit
a4800d0d68
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ds1307.c,v 1.18 2014/07/25 08:10:37 dholland Exp $ */
|
||||
/* $NetBSD: ds1307.c,v 1.19 2014/10/12 01:23:23 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.18 2014/07/25 08:10:37 dholland Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.19 2014/10/12 01:23:23 macallan Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.18 2014/07/25 08:10:37 dholland Exp $")
|
||||
|
||||
#include <dev/i2c/i2cvar.h>
|
||||
#include <dev/i2c/ds1307reg.h>
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
struct dsrtc_model {
|
||||
uint16_t dm_model;
|
||||
@ -63,6 +64,7 @@ struct dsrtc_model {
|
||||
uint8_t dm_flags;
|
||||
#define DSRTC_FLAG_CLOCK_HOLD 1
|
||||
#define DSRTC_FLAG_BCD 2
|
||||
#define DSRTC_FLAG_TEMP 4
|
||||
};
|
||||
|
||||
static const struct dsrtc_model dsrtc_models[] = {
|
||||
@ -85,6 +87,16 @@ static const struct dsrtc_model dsrtc_models[] = {
|
||||
.dm_rtc_start = DS1672_RTC_START,
|
||||
.dm_rtc_size = DS1672_RTC_SIZE,
|
||||
.dm_flags = 0,
|
||||
}, {
|
||||
.dm_model = 3231,
|
||||
.dm_rtc_start = DS3232_RTC_START,
|
||||
.dm_rtc_size = DS3232_RTC_SIZE,
|
||||
/*
|
||||
* XXX
|
||||
* the DS3232 likely has the temperature sensor too but I can't
|
||||
* easily verify or test that right now
|
||||
*/
|
||||
.dm_flags = DSRTC_FLAG_BCD | DSRTC_FLAG_TEMP,
|
||||
}, {
|
||||
.dm_model = 3232,
|
||||
.dm_rtc_start = DS3232_RTC_START,
|
||||
@ -102,6 +114,8 @@ struct dsrtc_softc {
|
||||
bool sc_open;
|
||||
struct dsrtc_model sc_model;
|
||||
struct todr_chip_handle sc_todr;
|
||||
struct sysmon_envsys *sc_sme;
|
||||
envsys_data_t sc_sensor;
|
||||
};
|
||||
|
||||
static void dsrtc_attach(device_t, device_t, void *);
|
||||
@ -141,6 +155,9 @@ static int dsrtc_settime_timeval(struct todr_chip_handle *, struct timeval *);
|
||||
static int dsrtc_clock_read_timeval(struct dsrtc_softc *, time_t *);
|
||||
static int dsrtc_clock_write_timeval(struct dsrtc_softc *, time_t);
|
||||
|
||||
static int dsrtc_read_temp(struct dsrtc_softc *, uint32_t *);
|
||||
static void dsrtc_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
static const struct dsrtc_model *
|
||||
dsrtc_model(u_int model)
|
||||
{
|
||||
@ -202,6 +219,35 @@ dsrtc_attach(device_t parent, device_t self, void *arg)
|
||||
sc->sc_todr.todr_setwen = NULL;
|
||||
|
||||
todr_attach(&sc->sc_todr);
|
||||
if ((sc->sc_model.dm_flags & DSRTC_FLAG_TEMP) != 0) {
|
||||
int error;
|
||||
|
||||
sc->sc_sme = sysmon_envsys_create();
|
||||
sc->sc_sme->sme_name = device_xname(self);
|
||||
sc->sc_sme->sme_cookie = sc;
|
||||
sc->sc_sme->sme_refresh = dsrtc_refresh;
|
||||
|
||||
sc->sc_sensor.units = ENVSYS_STEMP;
|
||||
sc->sc_sensor.state = ENVSYS_SINVALID;
|
||||
sc->sc_sensor.flags = 0;
|
||||
(void)strlcpy(sc->sc_sensor.desc, "temperature",
|
||||
sizeof(sc->sc_sensor.desc));
|
||||
|
||||
if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor)) {
|
||||
aprint_error_dev(self, "unable to attach sensor\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = sysmon_envsys_register(sc->sc_sme);
|
||||
if (error) {
|
||||
aprint_error_dev(self,
|
||||
"error %d registering with sysmon\n", error);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
return;
|
||||
bad:
|
||||
sysmon_envsys_destroy(sc->sc_sme);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
@ -624,3 +670,56 @@ dsrtc_clock_write_timeval(struct dsrtc_softc *sc, time_t t)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
dsrtc_read_temp(struct dsrtc_softc *sc, uint32_t *temp)
|
||||
{
|
||||
int error, tc;
|
||||
uint8_t reg = DS3232_TEMP_MSB;
|
||||
uint8_t buf[2];
|
||||
|
||||
if ((sc->sc_model.dm_flags & DSRTC_FLAG_TEMP) == 0)
|
||||
return ENOTSUP;
|
||||
|
||||
if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"%s: failed to acquire I2C bus: %d\n",
|
||||
__func__, error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read temperature registers: */
|
||||
error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address,
|
||||
®, 1, buf, 2, I2C_F_POLL);
|
||||
|
||||
/* Done with I2C */
|
||||
iic_release_bus(sc->sc_tag, I2C_F_POLL);
|
||||
|
||||
if (error != 0) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"%s: failed to read temperature: %d\n",
|
||||
__func__, error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert to microkelvin */
|
||||
tc = buf[0] * 1000000 + (buf[1] >> 6) * 250000;
|
||||
*temp = tc + 273150000;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dsrtc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
struct dsrtc_softc *sc = sme->sme_cookie;
|
||||
uint32_t temp;
|
||||
|
||||
if (dsrtc_read_temp(sc, &temp) == 0) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
edata->value_cur = temp;
|
||||
|
||||
edata->state = ENVSYS_SVALID;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ds1307reg.h,v 1.4 2012/02/23 20:59:19 matt Exp $ */
|
||||
/* $NetBSD: ds1307reg.h,v 1.5 2014/10/12 01:23:23 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
@ -81,6 +81,8 @@
|
||||
#define DS3232_CSR 0x0f
|
||||
#define DS3232_RTC_START 0
|
||||
#define DS3232_RTC_SIZE DSXXXX_RTC_SIZE
|
||||
#define DS3232_TEMP_MSB 0x11
|
||||
#define DS3232_TEMP_LSB 0x12
|
||||
#define DS3232_NVRAM_START 0x14
|
||||
#define DS3232_NVRAM_SIZE 0xec
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user