Module Name: src Committed By: rkujawa Date: Wed Nov 14 01:52:48 UTC 2012
Added Files: src/sys/dev/ic: msm6242b.c msm6242breg.h msm6242bvar.h Log Message: Add MI OKI MSM6242B RTC driver. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/dev/ic/msm6242b.c src/sys/dev/ic/msm6242breg.h \ src/sys/dev/ic/msm6242bvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/sys/dev/ic/msm6242b.c diff -u /dev/null src/sys/dev/ic/msm6242b.c:1.1 --- /dev/null Wed Nov 14 01:52:48 2012 +++ src/sys/dev/ic/msm6242b.c Wed Nov 14 01:52:48 2012 @@ -0,0 +1,245 @@ +/* $NetBSD: msm6242b.c,v 1.1 2012/11/14 01:52:48 rkujawa Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Radoslaw Kujawa. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/bus.h> + +#include <dev/clock_subr.h> + +#include <dev/ic/msm6242bvar.h> +#include <dev/ic/msm6242breg.h> + +/* #define MSM6242B_DEBUG 1 */ + +static int msm6242b_gettime_ymdhms(todr_chip_handle_t, struct clock_ymdhms *); +int msm6242b_settime_ymdhms(todr_chip_handle_t, struct clock_ymdhms *); + +bool msm6242b_hold(struct msm6242b_softc *sc); +void msm6242b_free(struct msm6242b_softc *sc); +static uint8_t msm6242b_read(struct msm6242b_softc *, uint8_t); +static void msm6242b_write(struct msm6242b_softc *, uint8_t, uint8_t); +static void msm6242b_set(struct msm6242b_softc *, uint8_t, uint8_t); +static void msm6242b_unset(struct msm6242b_softc *, uint8_t, uint8_t); + +void +msm6242b_attach(struct msm6242b_softc *sc) +{ + struct clock_ymdhms dt; + + todr_chip_handle_t handle; + aprint_normal(": OKI MSM6242B\n"); + + handle = &sc->sc_handle; + handle->cookie = sc; + handle->todr_gettime = NULL; + handle->todr_settime = NULL; + handle->todr_gettime_ymdhms = msm6242b_gettime_ymdhms; + handle->todr_settime_ymdhms = msm6242b_settime_ymdhms; + handle->todr_setwen = NULL; + + if (msm6242b_gettime_ymdhms(handle, &dt) != 0) { + aprint_error_dev(sc->sc_dev, "RTC does not work correctly\n"); + return; + } + +#ifdef MSM6242B_DEBUG + aprint_normal_dev(sc->sc_dev, "the time is %d %d %d %d %d %d\n", + dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec); +#endif +/* MSM6242B_DEBUG */ + todr_attach(handle); +} + +static int +msm6242b_gettime_ymdhms(todr_chip_handle_t handle, struct clock_ymdhms *dt) +{ + struct msm6242b_softc *sc; + + sc = handle->cookie; + /* XXX: splsched(); */ + + if(!msm6242b_hold(sc)) + return (ENXIO); + + dt->dt_sec = msm6242b_read(sc, MSM6242B_10SECOND) * 10 + + msm6242b_read(sc, MSM6242B_1SECOND); + dt->dt_min = msm6242b_read(sc, MSM6242B_10MINUTE) * 10 + + msm6242b_read(sc, MSM6242B_1MINUTE); + dt->dt_hour = (msm6242b_read(sc, MSM6242B_10HOUR_PMAM) & + MSM6242B_10HOUR_MASK) * 10 + msm6242b_read(sc, MSM6242B_1HOUR); + dt->dt_day = msm6242b_read(sc, MSM6242B_10DAY) * 10 + + msm6242b_read(sc, MSM6242B_1DAY); + dt->dt_mon = msm6242b_read(sc, MSM6242B_10MONTH) * 10 + + msm6242b_read(sc, MSM6242B_1MONTH); + dt->dt_year = msm6242b_read(sc, MSM6242B_10YEAR) * 10 + + msm6242b_read(sc, MSM6242B_1YEAR); + dt->dt_wday = msm6242b_read(sc, MSM6242B_WEEK); + +#ifdef MSM6242B_DEBUG + aprint_normal_dev(sc->sc_dev, "the time is %d %d %d %d %d %d\n", + dt->dt_year, dt->dt_mon, dt->dt_day, dt->dt_hour, dt->dt_min, dt->dt_sec); +#endif + + /* handle 12h mode */ + if ((msm6242b_read(sc, MSM6242B_CONTROL_F) & + MSM6242B_CONTROL_F_24H) == 0) { + if ((msm6242b_read(sc, MSM6242B_10HOUR_PMAM) & + MSM6242B_PMAM_BIT) == 0 && dt->dt_hour == 12) + dt->dt_hour = 0; + else if ((msm6242b_read(sc, MSM6242B_10HOUR_PMAM) & + MSM6242B_PMAM_BIT) && dt->dt_hour != 12); + dt->dt_hour += 12; + } + + msm6242b_free(sc); + + dt->dt_year += MSM6242B_BASE_YEAR; + if (dt->dt_year < POSIX_BASE_YEAR) + dt->dt_year += 100; + + if ((dt->dt_hour > 23) || + (dt->dt_day > 31) || + (dt->dt_mon > 12) || + (dt->dt_year > 2036)) + return (EINVAL); + + return 0; +} + +bool +msm6242b_hold(struct msm6242b_softc *sc) +{ + int try; + +#define TRY_MAX 10 + for (try = 0; try < TRY_MAX; try++) { + msm6242b_set(sc, MSM6242B_CONTROL_D, MSM6242B_CONTROL_D_HOLD); + if (msm6242b_read(sc, MSM6242B_CONTROL_D) + & MSM6242B_CONTROL_D_BUSY) { + aprint_normal_dev(sc->sc_dev, "gotta idle\n"); + msm6242b_unset(sc, MSM6242B_CONTROL_D, + MSM6242B_CONTROL_D_HOLD); + delay(70); + } else { + aprint_normal_dev(sc->sc_dev, "not busy\n"); + break; + } + } + + if (try == TRY_MAX) { + aprint_error_dev(sc->sc_dev, "can't hold the chip\n"); + return false; + } + return true; +} + +void +msm6242b_free(struct msm6242b_softc *sc) +{ + msm6242b_unset(sc, MSM6242B_CONTROL_D, MSM6242B_CONTROL_D_HOLD); +} + +static uint8_t +msm6242b_read(struct msm6242b_softc *sc, uint8_t reg) +{ + uint8_t r; + r = bus_space_read_1(sc->sc_iot, sc->sc_ioh, reg) & MSM6242B_MASK; + return r; +} + +static void +msm6242b_write(struct msm6242b_softc *sc, uint8_t reg, uint8_t val) +{ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val); +} + +static void +msm6242b_set(struct msm6242b_softc *sc, uint8_t reg, uint8_t bits) +{ + uint8_t v; + v = msm6242b_read(sc, reg) | bits; + msm6242b_write(sc, reg, v); +} + +static void +msm6242b_unset(struct msm6242b_softc *sc, uint8_t reg, uint8_t bits) +{ + uint8_t v; + v = msm6242b_read(sc, reg) & ~bits; + msm6242b_write(sc, reg, v); +} + +int +msm6242b_settime_ymdhms(todr_chip_handle_t handle, struct clock_ymdhms *dt) +{ + struct msm6242b_softc *sc; + int ampm; + /* XXX: splsched(); */ + + sc = handle->cookie; + + if(!msm6242b_hold(sc)) + return (ENXIO); + + ampm = 0; + if ((msm6242b_read(sc, MSM6242B_CONTROL_F) & + MSM6242B_CONTROL_F_24H) == 0) { + if (dt->dt_hour >= 12) { + ampm = MSM6242B_CONTROL_F_24H; + if (dt->dt_hour != 12) + dt->dt_hour -= 12; + } else if (dt->dt_hour == 0) { + dt->dt_hour = 12; + } + } + + msm6242b_write(sc, MSM6242B_10HOUR_PMAM, (dt->dt_hour / 10) | ampm); + msm6242b_write(sc, MSM6242B_1HOUR, dt->dt_hour % 10); + msm6242b_write(sc, MSM6242B_10SECOND, dt->dt_sec / 10); + msm6242b_write(sc, MSM6242B_1SECOND, dt->dt_sec % 10); + msm6242b_write(sc, MSM6242B_10MINUTE, dt->dt_min / 10); + msm6242b_write(sc, MSM6242B_1MINUTE, dt->dt_min % 10); + msm6242b_write(sc, MSM6242B_10DAY, dt->dt_day / 10); + msm6242b_write(sc, MSM6242B_1DAY, dt->dt_day % 10); + msm6242b_write(sc, MSM6242B_10MONTH, dt->dt_mon / 10); + msm6242b_write(sc, MSM6242B_1MONTH, dt->dt_mon % 10); + msm6242b_write(sc, MSM6242B_10YEAR, (dt->dt_mon / 10) % 10); + msm6242b_write(sc, MSM6242B_1YEAR, dt->dt_mon % 10); + msm6242b_write(sc, MSM6242B_WEEK, dt->dt_wday); + + msm6242b_free(sc); + + return 0; +} + Index: src/sys/dev/ic/msm6242breg.h diff -u /dev/null src/sys/dev/ic/msm6242breg.h:1.1 --- /dev/null Wed Nov 14 01:52:48 2012 +++ src/sys/dev/ic/msm6242breg.h Wed Nov 14 01:52:48 2012 @@ -0,0 +1,70 @@ +/* $NetBSD: msm6242breg.h,v 1.1 2012/11/14 01:52:48 rkujawa Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Radoslaw Kujawa. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MSM6242BREG_H_ +#define _MSM6242BREG_H_ + +#define MSM6242B_1SECOND 0x0 +#define MSM6242B_10SECOND 0x1 +#define MSM6242B_1MINUTE 0x2 +#define MSM6242B_10MINUTE 0x3 +#define MSM6242B_1HOUR 0x4 + +#define MSM6242B_10HOUR_PMAM 0x5 +#define MSM6242B_10HOUR_MASK 0x3 +#define MSM6242B_PMAM_BIT __BIT(2) + +#define MSM6242B_1DAY 0x6 +#define MSM6242B_10DAY 0x7 +#define MSM6242B_1MONTH 0x8 +#define MSM6242B_10MONTH 0x9 +#define MSM6242B_1YEAR 0xA +#define MSM6242B_10YEAR 0xB +#define MSM6242B_WEEK 0xC + +#define MSM6242B_CONTROL_D 0xD +#define MSM6242B_CONTROL_D_HOLD __BIT(0) +#define MSM6242B_CONTROL_D_BUSY __BIT(1) +#define MSM6242B_CONTROL_D_IRQF __BIT(2) +#define MSM6242B_CONTROL_D_30SECADJ __BIT(3) + +#define MSM6242B_CONTROL_E 0xE + +#define MSM6242B_CONTROL_F 0xF +#define MSM6242B_CONTROL_F_24H __BIT(3) + +#define MSM6242B_MASK 0xF /* 4 significant bits only */ +#define MSM6242B_SIZE 0x10 + +#define MSM6242B_BASE_YEAR 1900 + +#endif /* _MSM6242BREG_H_ */ + Index: src/sys/dev/ic/msm6242bvar.h diff -u /dev/null src/sys/dev/ic/msm6242bvar.h:1.1 --- /dev/null Wed Nov 14 01:52:48 2012 +++ src/sys/dev/ic/msm6242bvar.h Wed Nov 14 01:52:48 2012 @@ -0,0 +1,47 @@ +/* $NetBSD: msm6242bvar.h,v 1.1 2012/11/14 01:52:48 rkujawa Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Radoslaw Kujawa. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MSM6242BVAR_H_ +#define _MSM6242BVAR_H_ + +struct msm6242b_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + struct todr_chip_handle sc_handle; +}; + +void msm6242b_attach(struct msm6242b_softc *); + +#endif /* _MSM6242BVAR_H_ */ +