Date: Thu, 22 Jul 2010 23:23:39 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r210397 - head/sys/arm/s3c2xx0 Message-ID: <201007222323.o6MNNdKY097246@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andrew Date: Thu Jul 22 23:23:39 2010 New Revision: 210397 URL: http://svn.freebsd.org/changeset/base/210397 Log: Add the s3c24x0 real time clock driver Approved by: imp (mentor) Added: head/sys/arm/s3c2xx0/s3c24x0_rtc.c (contents, props changed) Modified: head/sys/arm/s3c2xx0/files.s3c2xx0 head/sys/arm/s3c2xx0/s3c24x0.c head/sys/arm/s3c2xx0/s3c24x0reg.h Modified: head/sys/arm/s3c2xx0/files.s3c2xx0 ============================================================================== --- head/sys/arm/s3c2xx0/files.s3c2xx0 Thu Jul 22 23:12:19 2010 (r210396) +++ head/sys/arm/s3c2xx0/files.s3c2xx0 Thu Jul 22 23:23:39 2010 (r210397) @@ -2,6 +2,7 @@ arm/arm/cpufunc_asm_arm9.S standard arm/arm/irq_dispatch.S standard arm/s3c2xx0/board_ln2410sbc.c optional board_ln2410sbc +arm/s3c2xx0/s3c24x0_rtc.c standard arm/s3c2xx0/s3c24x0_machdep.c standard arm/s3c2xx0/s3c24x0.c standard arm/s3c2xx0/s3c2xx0_space.c standard Modified: head/sys/arm/s3c2xx0/s3c24x0.c ============================================================================== --- head/sys/arm/s3c2xx0/s3c24x0.c Thu Jul 22 23:12:19 2010 (r210396) +++ head/sys/arm/s3c2xx0/s3c24x0.c Thu Jul 22 23:23:39 2010 (r210397) @@ -80,6 +80,10 @@ static struct { u_long count; } res[2]; } s3c24x0_children[] = { + { "rtc", 0, -1, { + { SYS_RES_IOPORT, S3C24X0_RTC_PA_BASE, S3C24X0_RTC_SIZE }, + { 0 }, + } }, { "timer", 0, -1, { { 0 }, } }, { "uart", 1, 0, { { SYS_RES_IRQ, S3C24X0_INT_UART0, 1 }, Added: head/sys/arm/s3c2xx0/s3c24x0_rtc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/s3c2xx0/s3c24x0_rtc.c Thu Jul 22 23:23:39 2010 (r210397) @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2010 Andrew Turner + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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> +__FBSDID("$FreeBSD$"); +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/time.h> +#include <sys/clock.h> +#include <sys/resource.h> +#include <sys/systm.h> +#include <sys/rman.h> +#include <sys/kernel.h> +#include <sys/module.h> + +#include <machine/bus.h> + +#include <arm/s3c2xx0/s3c24x0reg.h> + +#include "clock_if.h" + +#define YEAR_BASE 2000 + +struct s3c2xx0_rtc_softc { + struct resource *mem_res; +}; + +static int +s3c2xx0_rtc_probe(device_t dev) +{ + + device_set_desc(dev, "Samsung Integrated RTC"); + return (0); +} + +static int +s3c2xx0_rtc_attach(device_t dev) +{ + struct s3c2xx0_rtc_softc *sc; + int error, rid; + + sc = device_get_softc(dev); + error = 0; + + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) { + error = ENOMEM; + goto out; + } + + bus_write_1(sc->mem_res, RTC_RTCCON, RTCCON_RTCEN); + clock_register(dev, 1000000); + +out: + return (error); +} + +static int +s3c2xx0_rtc_gettime(device_t dev, struct timespec *ts) +{ + struct s3c2xx0_rtc_softc *sc; + struct clocktime ct; + +#define READ_TIME() do { \ + ct.year = YEAR_BASE + FROMBCD(bus_read_1(sc->mem_res, RTC_BCDYEAR)); \ + ct.mon = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDMON)); \ + ct.dow = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDDAY)); \ + ct.day = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDDATE)); \ + ct.hour = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDHOUR)); \ + ct.min = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDMIN)); \ + ct.sec = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDSEC)); \ +} while (0) + + sc = device_get_softc(dev); + + ct.nsec = 0; + READ_TIME(); + /* + * Check if we could have read incorrect values + * as the values could have changed. + */ + if (ct.sec == 0) { + READ_TIME(); + } + + ct.dow = -1; + +#undef READ_TIME + return (clock_ct_to_ts(&ct, ts)); +} + +static int +s3c2xx0_rtc_settime(device_t dev, struct timespec *ts) +{ + struct s3c2xx0_rtc_softc *sc; + struct clocktime ct; + + sc = device_get_softc(dev); + + /* Resolution: 1 sec */ + if (ts->tv_nsec >= 500000000) + ts->tv_sec++; + ts->tv_nsec = 0; + clock_ts_to_ct(ts, &ct); + + bus_write_1(sc->mem_res, RTC_BCDSEC, TOBCD(ct.sec)); + bus_write_1(sc->mem_res, RTC_BCDMIN, TOBCD(ct.min)); + bus_write_1(sc->mem_res, RTC_BCDHOUR, TOBCD(ct.hour)); + bus_write_1(sc->mem_res, RTC_BCDDATE, TOBCD(ct.day)); + bus_write_1(sc->mem_res, RTC_BCDDAY, TOBCD(ct.dow)); + bus_write_1(sc->mem_res, RTC_BCDMON, TOBCD(ct.mon)); + bus_write_1(sc->mem_res, RTC_BCDYEAR, TOBCD(ct.year - YEAR_BASE)); + + return (0); +} + +static device_method_t s3c2xx0_rtc_methods[] = { + DEVMETHOD(device_probe, s3c2xx0_rtc_probe), + DEVMETHOD(device_attach, s3c2xx0_rtc_attach), + + DEVMETHOD(clock_gettime, s3c2xx0_rtc_gettime), + DEVMETHOD(clock_settime, s3c2xx0_rtc_settime), + + { 0, 0 }, +}; + +static driver_t s3c2xx0_rtc_driver = { + "rtc", + s3c2xx0_rtc_methods, + sizeof(struct s3c2xx0_rtc_softc), +}; +static devclass_t s3c2xx0_rtc_devclass; + +DRIVER_MODULE(s3c2xx0_rtc, s3c24x0, s3c2xx0_rtc_driver, s3c2xx0_rtc_devclass, + 0, 0); + Modified: head/sys/arm/s3c2xx0/s3c24x0reg.h ============================================================================== --- head/sys/arm/s3c2xx0/s3c24x0reg.h Thu Jul 22 23:12:19 2010 (r210396) +++ head/sys/arm/s3c2xx0/s3c24x0reg.h Thu Jul 22 23:23:39 2010 (r210397) @@ -99,6 +99,9 @@ #define S3C24X0_IIS_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_IIS_PA_BASE) #define S3C24X0_GPIO_PA_BASE 0x56000000 #define S3C24X0_GPIO_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_GPIO_PA_BASE) +#define S3C24X0_RTC_PA_BASE 0x57000000 +#define S3C24X0_RTC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_RTC_PA_BASE) +#define S3C24X0_RTC_SIZE 0x8C #define S3C24X0_ADC_PA_BASE 0x58000000 #define S3C24X0_ADC_BASE S3C24X0_DEV_PA_TO_VA(S3C24X0_ADC_PA_BASE) #define S3C24X0_SPI0_PA_BASE 0x59000000 @@ -642,7 +645,30 @@ #define ADCDAT_DATAMASK 0x3ff -/* RTC */ /* XXX */ +/* RTC */ +#define RTC_RTCCON 0x40 +#define RTCCON_RTCEN (1<<0) +#define RTCCON_CLKSEL (1<<1) +#define RTCCON_CNTSEL (1<<2) +#define RTCCON_CLKRST (1<<3) +#define RTC_TICNT0 0x44 +/* TICNT1 on 2440 */ +#define RTC_RTCALM 0x50 +#define RTC_ALMSEC 0x54 +#define RTC_ALMMIN 0x58 +#define RTC_ALMHOUR 0x5C +#define RTC_ALMDATE 0x60 +#define RTC_ALMMON 0x64 +#define RTC_ALMYEAR 0x68 +/* RTCRST on 2410 */ +#define RTC_BCDSEC 0x70 +#define RTC_BCDMIN 0x74 +#define RTC_BCDHOUR 0x78 +#define RTC_BCDDATE 0x7C +#define RTC_BCDDAY 0x80 +#define RTC_BCDMON 0x84 +#define RTC_BCDYEAR 0x88 + /* SPI */ #define S3C24X0_SPI_SIZE 0x20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007222323.o6MNNdKY097246>