162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * arch/m68k/sun3/intersil.c
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * basic routines for accessing the intersil clock within the sun3 machines
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * started 11/12/1999 Sam Creasey
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
962306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
1062306a36Sopenharmony_ci * for more details.
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/rtc.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <asm/errno.h>
1762306a36Sopenharmony_ci#include <asm/intersil.h>
1862306a36Sopenharmony_ci#include <asm/machdep.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* bits to set for start/run of the intersil */
2262306a36Sopenharmony_ci#define STOP_VAL (INTERSIL_STOP | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE)
2362306a36Sopenharmony_ci#define START_VAL (INTERSIL_RUN | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* get/set hwclock */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciint sun3_hwclk(int set, struct rtc_time *t)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	volatile struct intersil_dt *todintersil;
3062306a36Sopenharmony_ci	unsigned long flags;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci        todintersil = (struct intersil_dt *) &intersil_clock->counter;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	local_irq_save(flags);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	intersil_clock->cmd_reg = STOP_VAL;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	/* set or read the clock */
3962306a36Sopenharmony_ci	if(set) {
4062306a36Sopenharmony_ci		todintersil->csec = 0;
4162306a36Sopenharmony_ci		todintersil->hour = t->tm_hour;
4262306a36Sopenharmony_ci		todintersil->minute = t->tm_min;
4362306a36Sopenharmony_ci		todintersil->second = t->tm_sec;
4462306a36Sopenharmony_ci		todintersil->month = t->tm_mon + 1;
4562306a36Sopenharmony_ci		todintersil->day = t->tm_mday;
4662306a36Sopenharmony_ci		todintersil->year = (t->tm_year - 68) % 100;
4762306a36Sopenharmony_ci		todintersil->weekday = t->tm_wday;
4862306a36Sopenharmony_ci	} else {
4962306a36Sopenharmony_ci		/* read clock */
5062306a36Sopenharmony_ci		t->tm_sec = todintersil->csec;
5162306a36Sopenharmony_ci		t->tm_hour = todintersil->hour;
5262306a36Sopenharmony_ci		t->tm_min = todintersil->minute;
5362306a36Sopenharmony_ci		t->tm_sec = todintersil->second;
5462306a36Sopenharmony_ci		t->tm_mon = todintersil->month - 1;
5562306a36Sopenharmony_ci		t->tm_mday = todintersil->day;
5662306a36Sopenharmony_ci		t->tm_year = todintersil->year + 68;
5762306a36Sopenharmony_ci		t->tm_wday = todintersil->weekday;
5862306a36Sopenharmony_ci		if (t->tm_year < 70)
5962306a36Sopenharmony_ci			t->tm_year += 100;
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	intersil_clock->cmd_reg = START_VAL;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	local_irq_restore(flags);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	return 0;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
70