1*ef2ee5d0SMichal Meloun /*- 2*ef2ee5d0SMichal Meloun * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org> 3*ef2ee5d0SMichal Meloun * All rights reserved. 4*ef2ee5d0SMichal Meloun * 5*ef2ee5d0SMichal Meloun * Redistribution and use in source and binary forms, with or without 6*ef2ee5d0SMichal Meloun * modification, are permitted provided that the following conditions 7*ef2ee5d0SMichal Meloun * are met: 8*ef2ee5d0SMichal Meloun * 1. Redistributions of source code must retain the above copyright 9*ef2ee5d0SMichal Meloun * notice, this list of conditions and the following disclaimer. 10*ef2ee5d0SMichal Meloun * 2. Redistributions in binary form must reproduce the above copyright 11*ef2ee5d0SMichal Meloun * notice, this list of conditions and the following disclaimer in the 12*ef2ee5d0SMichal Meloun * documentation and/or other materials provided with the distribution. 13*ef2ee5d0SMichal Meloun * 14*ef2ee5d0SMichal Meloun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*ef2ee5d0SMichal Meloun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*ef2ee5d0SMichal Meloun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*ef2ee5d0SMichal Meloun * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*ef2ee5d0SMichal Meloun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*ef2ee5d0SMichal Meloun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*ef2ee5d0SMichal Meloun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*ef2ee5d0SMichal Meloun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*ef2ee5d0SMichal Meloun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*ef2ee5d0SMichal Meloun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*ef2ee5d0SMichal Meloun * SUCH DAMAGE. 25*ef2ee5d0SMichal Meloun */ 26*ef2ee5d0SMichal Meloun 27*ef2ee5d0SMichal Meloun #include <sys/cdefs.h> 28*ef2ee5d0SMichal Meloun __FBSDID("$FreeBSD$"); 29*ef2ee5d0SMichal Meloun 30*ef2ee5d0SMichal Meloun #include <sys/param.h> 31*ef2ee5d0SMichal Meloun #include <sys/systm.h> 32*ef2ee5d0SMichal Meloun #include <sys/bus.h> 33*ef2ee5d0SMichal Meloun #include <sys/clock.h> 34*ef2ee5d0SMichal Meloun #include <sys/kernel.h> 35*ef2ee5d0SMichal Meloun 36*ef2ee5d0SMichal Meloun #include <dev/ofw/ofw_bus.h> 37*ef2ee5d0SMichal Meloun 38*ef2ee5d0SMichal Meloun #include "clock_if.h" 39*ef2ee5d0SMichal Meloun #include "as3722.h" 40*ef2ee5d0SMichal Meloun 41*ef2ee5d0SMichal Meloun #define AS3722_RTC_START_YEAR 2000 42*ef2ee5d0SMichal Meloun 43*ef2ee5d0SMichal Meloun int 44*ef2ee5d0SMichal Meloun as3722_rtc_gettime(device_t dev, struct timespec *ts) 45*ef2ee5d0SMichal Meloun { 46*ef2ee5d0SMichal Meloun struct as3722_softc *sc; 47*ef2ee5d0SMichal Meloun struct clocktime ct; 48*ef2ee5d0SMichal Meloun uint8_t buf[6]; 49*ef2ee5d0SMichal Meloun int rv; 50*ef2ee5d0SMichal Meloun 51*ef2ee5d0SMichal Meloun sc = device_get_softc(dev); 52*ef2ee5d0SMichal Meloun 53*ef2ee5d0SMichal Meloun rv = as3722_read_buf(sc, AS3722_RTC_SECOND, buf, 6); 54*ef2ee5d0SMichal Meloun if (rv != 0) { 55*ef2ee5d0SMichal Meloun device_printf(sc->dev, "Failed to read RTC data\n"); 56*ef2ee5d0SMichal Meloun return (rv); 57*ef2ee5d0SMichal Meloun } 58*ef2ee5d0SMichal Meloun ct.nsec = 0; 59*ef2ee5d0SMichal Meloun ct.sec = bcd2bin(buf[0] & 0x7F); 60*ef2ee5d0SMichal Meloun ct.min = bcd2bin(buf[1] & 0x7F); 61*ef2ee5d0SMichal Meloun ct.hour = bcd2bin(buf[2] & 0x3F); 62*ef2ee5d0SMichal Meloun ct.day = bcd2bin(buf[3] & 0x3F); 63*ef2ee5d0SMichal Meloun ct.mon = bcd2bin(buf[4] & 0x1F); 64*ef2ee5d0SMichal Meloun ct.year = bcd2bin(buf[5] & 0x7F) + AS3722_RTC_START_YEAR; 65*ef2ee5d0SMichal Meloun ct.dow = -1; 66*ef2ee5d0SMichal Meloun 67*ef2ee5d0SMichal Meloun return clock_ct_to_ts(&ct, ts); 68*ef2ee5d0SMichal Meloun } 69*ef2ee5d0SMichal Meloun 70*ef2ee5d0SMichal Meloun int 71*ef2ee5d0SMichal Meloun as3722_rtc_settime(device_t dev, struct timespec *ts) 72*ef2ee5d0SMichal Meloun { 73*ef2ee5d0SMichal Meloun struct as3722_softc *sc; 74*ef2ee5d0SMichal Meloun struct clocktime ct; 75*ef2ee5d0SMichal Meloun uint8_t buf[6]; 76*ef2ee5d0SMichal Meloun int rv; 77*ef2ee5d0SMichal Meloun 78*ef2ee5d0SMichal Meloun sc = device_get_softc(dev); 79*ef2ee5d0SMichal Meloun clock_ts_to_ct(ts, &ct); 80*ef2ee5d0SMichal Meloun 81*ef2ee5d0SMichal Meloun if (ct.year < AS3722_RTC_START_YEAR) 82*ef2ee5d0SMichal Meloun return (EINVAL); 83*ef2ee5d0SMichal Meloun 84*ef2ee5d0SMichal Meloun buf[0] = bin2bcd(ct.sec); 85*ef2ee5d0SMichal Meloun buf[1] = bin2bcd(ct.min); 86*ef2ee5d0SMichal Meloun buf[2] = bin2bcd(ct.hour); 87*ef2ee5d0SMichal Meloun buf[3] = bin2bcd(ct.day); 88*ef2ee5d0SMichal Meloun buf[4] = bin2bcd(ct.mon); 89*ef2ee5d0SMichal Meloun buf[5] = bin2bcd(ct.year - AS3722_RTC_START_YEAR); 90*ef2ee5d0SMichal Meloun 91*ef2ee5d0SMichal Meloun rv = as3722_write_buf(sc, AS3722_RTC_SECOND, buf, 6); 92*ef2ee5d0SMichal Meloun if (rv != 0) { 93*ef2ee5d0SMichal Meloun device_printf(sc->dev, "Failed to write RTC data\n"); 94*ef2ee5d0SMichal Meloun return (rv); 95*ef2ee5d0SMichal Meloun } 96*ef2ee5d0SMichal Meloun return (0); 97*ef2ee5d0SMichal Meloun } 98*ef2ee5d0SMichal Meloun 99*ef2ee5d0SMichal Meloun int 100*ef2ee5d0SMichal Meloun as3722_rtc_attach(struct as3722_softc *sc, phandle_t node) 101*ef2ee5d0SMichal Meloun { 102*ef2ee5d0SMichal Meloun int rv; 103*ef2ee5d0SMichal Meloun 104*ef2ee5d0SMichal Meloun /* Enable RTC, set 24 hours mode and alarms */ 105*ef2ee5d0SMichal Meloun rv = RM1(sc, AS3722_RTC_CONTROL, 106*ef2ee5d0SMichal Meloun AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN | AS3722_RTC_AM_PM_MODE, 107*ef2ee5d0SMichal Meloun AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN); 108*ef2ee5d0SMichal Meloun if (rv < 0) { 109*ef2ee5d0SMichal Meloun device_printf(sc->dev, "Failed to initialize RTC controller\n"); 110*ef2ee5d0SMichal Meloun return (ENXIO); 111*ef2ee5d0SMichal Meloun } 112*ef2ee5d0SMichal Meloun clock_register(sc->dev, 1000000); 113*ef2ee5d0SMichal Meloun 114*ef2ee5d0SMichal Meloun return (0); 115*ef2ee5d0SMichal Meloun } 116