svn commit: r210397 - head/sys/arm/s3c2xx0

Andrew Turner andrew at FreeBSD.org
Thu Jul 22 23:23:40 UTC 2010


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


More information about the svn-src-head mailing list