aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/iicbus
diff options
context:
space:
mode:
authorJustin Hibbits <jhibbits@FreeBSD.org>2016-04-05 03:27:33 +0000
committerJustin Hibbits <jhibbits@FreeBSD.org>2016-04-05 03:27:33 +0000
commitcc8a3448d9f88b9d22eae8f0f1bf504ec7b73589 (patch)
tree6a6c17a5ff994d2ac3eaa760d050fb88409b0224 /sys/dev/iicbus
parent2db664d7b55f259a39e616637c41d84864ac260b (diff)
downloadsrc-cc8a3448d9f88b9d22eae8f0f1bf504ec7b73589.tar.gz
src-cc8a3448d9f88b9d22eae8f0f1bf504ec7b73589.zip
Add support for the Microchip mcp7941x.
This is compatible with the ds1307, but comparing the mcp7941x datasheet vs the ds1307 code, appears there is one bit placement difference, so that is now accounted for. Relnotes: yes
Notes
Notes: svn path=/head/; revision=297573
Diffstat (limited to 'sys/dev/iicbus')
-rw-r--r--sys/dev/iicbus/ds1307.c41
-rw-r--r--sys/dev/iicbus/ds1307reg.h1
2 files changed, 34 insertions, 8 deletions
diff --git a/sys/dev/iicbus/ds1307.c b/sys/dev/iicbus/ds1307.c
index 9c7cd65171ce..987db0d0e75b 100644
--- a/sys/dev/iicbus/ds1307.c
+++ b/sys/dev/iicbus/ds1307.c
@@ -60,10 +60,20 @@ struct ds1307_softc {
struct intr_config_hook enum_hook;
uint16_t sc_addr; /* DS1307 slave address. */
uint8_t sc_ctrl;
+ int sc_mcp7941x;
};
static void ds1307_start(void *);
+#ifdef FDT
+static const struct ofw_compat_data ds1307_compat_data[] = {
+ {"dallas,ds1307", (uintptr_t)"Maxim DS1307 RTC"},
+ {"maxim,ds1307", (uintptr_t)"Maxim DS1307 RTC"},
+ {"microchip,mcp7941x", (uintptr_t)"Microchip MCP7941x RTC"},
+ { NULL, 0 }
+};
+#endif
+
static int
ds1307_read(device_t dev, uint16_t addr, uint8_t reg, uint8_t *data, size_t len)
{
@@ -167,21 +177,25 @@ ds1307_set_24hrs_mode(struct ds1307_softc *sc)
static int
ds1307_sqwe_sysctl(SYSCTL_HANDLER_ARGS)
{
- int sqwe, error, newv;
+ int sqwe, error, newv, sqwe_bit;
struct ds1307_softc *sc;
sc = (struct ds1307_softc *)arg1;
error = ds1307_ctrl_read(sc);
if (error != 0)
return (error);
- sqwe = newv = (sc->sc_ctrl & DS1307_CTRL_SQWE) ? 1 : 0;
+ if (sc->sc_mcp7941x)
+ sqwe_bit = MCP7941X_CTRL_SQWE;
+ else
+ sqwe_bit = DS1307_CTRL_SQWE;
+ sqwe = newv = (sc->sc_ctrl & sqwe_bit) ? 1 : 0;
error = sysctl_handle_int(oidp, &newv, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
if (sqwe != newv) {
- sc->sc_ctrl &= ~DS1307_CTRL_SQWE;
+ sc->sc_ctrl &= ~sqwe_bit;
if (newv)
- sc->sc_ctrl |= DS1307_CTRL_SQWE;
+ sc->sc_ctrl |= sqwe_bit;
error = ds1307_ctrl_write(sc);
if (error != 0)
return (error);
@@ -252,17 +266,25 @@ ds1307_sqw_out_sysctl(SYSCTL_HANDLER_ARGS)
static int
ds1307_probe(device_t dev)
{
-
#ifdef FDT
+ const struct ofw_compat_data *compat;
+
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- if (!ofw_bus_is_compatible(dev, "dallas,ds1307") &&
- !ofw_bus_is_compatible(dev, "maxim,ds1307"))
+
+ compat = ofw_bus_search_compatible(dev, ds1307_compat_data);
+
+ if (compat == NULL)
return (ENXIO);
-#endif
+
+ device_set_desc(dev, (const char *)compat->ocd_data);
+
+ return (BUS_PROBE_DEFAULT);
+#else
device_set_desc(dev, "Maxim DS1307 RTC");
return (BUS_PROBE_DEFAULT);
+#endif
}
static int
@@ -277,6 +299,9 @@ ds1307_attach(device_t dev)
sc->enum_hook.ich_func = ds1307_start;
sc->enum_hook.ich_arg = dev;
+ if (ofw_bus_is_compatible(dev, "microchip,mcp7941x"))
+ sc->sc_mcp7941x = 1;
+
/*
* We have to wait until interrupts are enabled. Usually I2C read
* and write only works when the interrupts are available.
diff --git a/sys/dev/iicbus/ds1307reg.h b/sys/dev/iicbus/ds1307reg.h
index 0c7c356c7492..ddad40b2417c 100644
--- a/sys/dev/iicbus/ds1307reg.h
+++ b/sys/dev/iicbus/ds1307reg.h
@@ -50,6 +50,7 @@
#define DS1307_YEAR_MASK 0xff
#define DS1307_CONTROL 0x07
#define DS1307_CTRL_OUT (1 << 7)
+#define MCP7941X_CTRL_SQWE (1 << 6)
#define DS1307_CTRL_SQWE (1 << 4)
#define DS1307_CTRL_RS1 (1 << 1)
#define DS1307_CTRL_RS0 (1 << 0)