mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-13 20:36:02 +01:00
rtc: Drop old and unused drivers
These drivers are not used and have not been converted to driver model. Drop them and references to the non-existent CONFIG options they use. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
ba9bb035a9
commit
2cf16adac9
@ -6,49 +6,35 @@
|
||||
|
||||
obj-$(CONFIG_$(SPL_TPL_)DM_RTC) += rtc-uclass.o
|
||||
|
||||
obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
|
||||
obj-$(CONFIG_RTC_ARMADA38X) += armada38x.o
|
||||
obj-$(CONFIG_RTC_DAVINCI) += davinci.o
|
||||
obj-$(CONFIG_RTC_DS1302) += ds1302.o
|
||||
obj-$(CONFIG_RTC_DS1306) += ds1306.o
|
||||
obj-$(CONFIG_RTC_DS1307) += ds1307.o
|
||||
obj-$(CONFIG_RTC_DS1338) += ds1307.o
|
||||
obj-$(CONFIG_RTC_DS1339) += ds1307.o
|
||||
obj-$(CONFIG_RTC_DS1337) += ds1337.o
|
||||
obj-$(CONFIG_RTC_DS1374) += ds1374.o
|
||||
obj-$(CONFIG_RTC_DS1388) += ds1337.o
|
||||
obj-$(CONFIG_RTC_DS3231) += ds3231.o
|
||||
obj-$(CONFIG_RTC_DS3232) += ds3232.o
|
||||
obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o
|
||||
obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o
|
||||
obj-$(CONFIG_RTC_HT1380) += ht1380.o
|
||||
obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o
|
||||
obj-$(CONFIG_RTC_IMXDI) += imxdi.o
|
||||
obj-$(CONFIG_RTC_ISL1208) += isl1208.o
|
||||
obj-$(CONFIG_RTC_M41T62) += m41t62.o
|
||||
obj-$(CONFIG_RTC_MAX6900) += max6900.o
|
||||
obj-$(CONFIG_RTC_MC13XXX) += mc13xxx-rtc.o
|
||||
obj-$(CONFIG_RTC_MC146818) += mc146818.o
|
||||
obj-$(CONFIG_RTC_MCP79411) += ds1307.o
|
||||
obj-$(CONFIG_MCFRTC) += mcfrtc.o
|
||||
obj-$(CONFIG_RTC_MK48T59) += mk48t59.o
|
||||
obj-$(CONFIG_RTC_MV) += mvrtc.o
|
||||
obj-$(CONFIG_RTC_MX27) += mx27rtc.o
|
||||
obj-$(CONFIG_RTC_MXS) += mxsrtc.o
|
||||
obj-$(CONFIG_RTC_PCF8563) += pcf8563.o
|
||||
obj-$(CONFIG_RTC_PCF2127) += pcf2127.o
|
||||
obj-$(CONFIG_RTC_PL031) += pl031.o
|
||||
obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o
|
||||
obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
|
||||
obj-$(CONFIG_RTC_RV3028) += rv3028.o
|
||||
obj-$(CONFIG_RTC_RV3029) += rv3029.o
|
||||
obj-$(CONFIG_RTC_RV8803) += rv8803.o
|
||||
obj-$(CONFIG_RTC_RX8025) += rx8025.o
|
||||
obj-$(CONFIG_RTC_RX8010SJ) += rx8010sj.o
|
||||
obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o
|
||||
obj-$(CONFIG_RTC_S35392A) += s35392a.o
|
||||
obj-$(CONFIG_RTC_STM32) += stm32_rtc.o
|
||||
obj-$(CONFIG_SANDBOX) += sandbox_rtc.o
|
||||
obj-$(CONFIG_RTC_X1205) += x1205.o
|
||||
obj-$(CONFIG_RTC_ABX80X) += abx80x.o
|
||||
obj-$(CONFIG_RTC_ZYNQMP) += zynqmp_rtc.o
|
||||
|
@ -1,78 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2010
|
||||
* Reinhard Meyer, reinhard.meyer@emk-elektronik.de
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the internal Real-time Timer
|
||||
* of AT91SAM9260 and compatibles.
|
||||
* Compatible with the LinuX rtc driver workaround:
|
||||
* The RTT cannot be written to, but only reset.
|
||||
* The actual time is the sum of RTT and one of
|
||||
* the four GPBR registers.
|
||||
*
|
||||
* The at91sam9260 has 4 GPBR (0-3).
|
||||
* For their typical use see at91_gpbr.h !
|
||||
*
|
||||
* make sure u-boot and kernel use the same GPBR !
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/at91_rtt.h>
|
||||
#include <asm/arch/at91_gpbr.h>
|
||||
|
||||
int rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
|
||||
at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
|
||||
ulong tim;
|
||||
ulong tim2;
|
||||
ulong off;
|
||||
|
||||
do {
|
||||
tim = readl(&rtt->vr);
|
||||
tim2 = readl(&rtt->vr);
|
||||
} while (tim!=tim2);
|
||||
off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
|
||||
/* off==0 means time is invalid, but we ignore that */
|
||||
rtc_to_tm(tim+off, tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
|
||||
at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
|
||||
ulong tim;
|
||||
|
||||
tim = rtc_mktime(tmp);
|
||||
|
||||
/* clear alarm, set prescaler to 32768, clear counter */
|
||||
writel(32768+AT91_RTT_RTTRST, &rtt->mr);
|
||||
writel(~0, &rtt->ar);
|
||||
writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
|
||||
/* wait for counter clear to happen, takes less than a 1/32768th second */
|
||||
while (readl(&rtt->vr) != 0)
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
|
||||
at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
|
||||
|
||||
/* clear alarm, set prescaler to 32768, clear counter */
|
||||
writel(32768+AT91_RTT_RTTRST, &rtt->mr);
|
||||
writel(~0, &rtt->ar);
|
||||
writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
|
||||
/* wait for counter clear to happen, takes less than a 1/32768th second */
|
||||
while (readl(&rtt->vr) != 0)
|
||||
;
|
||||
}
|
@ -1,329 +0,0 @@
|
||||
/*
|
||||
* ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
|
||||
*
|
||||
* Rex G. Feany <rfeany@zumanetworks.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
/* GPP Pins */
|
||||
#define DATA 0x200
|
||||
#define SCLK 0x400
|
||||
#define RST 0x800
|
||||
|
||||
/* Happy Fun Defines(tm) */
|
||||
#define RESET rtc_go_low(RST), rtc_go_low(SCLK)
|
||||
#define N_RESET rtc_go_high(RST), rtc_go_low(SCLK)
|
||||
|
||||
#define CLOCK_HIGH rtc_go_high(SCLK)
|
||||
#define CLOCK_LOW rtc_go_low(SCLK)
|
||||
|
||||
#define DATA_HIGH rtc_go_high(DATA)
|
||||
#define DATA_LOW rtc_go_low(DATA)
|
||||
#define DATA_READ (GTREGREAD(GPP_VALUE) & DATA)
|
||||
|
||||
#undef RTC_DEBUG
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
# define DPRINTF(x,args...) printf("ds1302: " x , ##args)
|
||||
static inline void DUMP(const char *ptr, int num)
|
||||
{
|
||||
while (num--) printf("%x ", *ptr++);
|
||||
printf("]\n");
|
||||
}
|
||||
#else
|
||||
# define DPRINTF(x,args...)
|
||||
# define DUMP(ptr, num)
|
||||
#endif
|
||||
|
||||
/* time data format for DS1302 */
|
||||
struct ds1302_st
|
||||
{
|
||||
unsigned char CH:1; /* clock halt 1=stop 0=start */
|
||||
unsigned char sec10:3;
|
||||
unsigned char sec:4;
|
||||
|
||||
unsigned char zero0:1;
|
||||
unsigned char min10:3;
|
||||
unsigned char min:4;
|
||||
|
||||
unsigned char fmt:1; /* 1=12 hour 0=24 hour */
|
||||
unsigned char zero1:1;
|
||||
unsigned char hr10:2; /* 10 (0-2) or am/pm (am/pm, 0-1) */
|
||||
unsigned char hr:4;
|
||||
|
||||
unsigned char zero2:2;
|
||||
unsigned char date10:2;
|
||||
unsigned char date:4;
|
||||
|
||||
unsigned char zero3:3;
|
||||
unsigned char month10:1;
|
||||
unsigned char month:4;
|
||||
|
||||
unsigned char zero4:5;
|
||||
unsigned char day:3; /* day of week */
|
||||
|
||||
unsigned char year10:4;
|
||||
unsigned char year:4;
|
||||
|
||||
unsigned char WP:1; /* write protect 1=protect 0=unprot */
|
||||
unsigned char zero5:7;
|
||||
};
|
||||
|
||||
static int ds1302_initted=0;
|
||||
|
||||
/* Pin control */
|
||||
static inline void
|
||||
rtc_go_high(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_VALUE) | mask;
|
||||
|
||||
GT_REG_WRITE(GPP_VALUE, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_low(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
|
||||
|
||||
GT_REG_WRITE(GPP_VALUE, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_input(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
|
||||
|
||||
GT_REG_WRITE(GPP_IO_CONTROL, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_output(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
|
||||
|
||||
GT_REG_WRITE(GPP_IO_CONTROL, f);
|
||||
}
|
||||
|
||||
/* Access data in RTC */
|
||||
|
||||
static void
|
||||
write_byte(unsigned char b)
|
||||
{
|
||||
int i;
|
||||
unsigned char mask=1;
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
CLOCK_LOW; /* Lower clock */
|
||||
(b&mask)?DATA_HIGH:DATA_LOW; /* set data */
|
||||
udelay(1);
|
||||
CLOCK_HIGH; /* latch data with rising clock */
|
||||
udelay(1);
|
||||
mask=mask<<1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
read_byte(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char mask=1;
|
||||
unsigned char b=0;
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
CLOCK_LOW;
|
||||
udelay(1);
|
||||
if (DATA_READ) b|=mask; /* if this bit is high, set in b */
|
||||
CLOCK_HIGH; /* clock out next bit */
|
||||
udelay(1);
|
||||
mask=mask<<1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
read_ser_drv(unsigned char addr, unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
#ifdef RTC_DEBUG
|
||||
char *foo = buf;
|
||||
#endif
|
||||
|
||||
DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
|
||||
|
||||
addr|=1; /* READ */
|
||||
N_RESET;
|
||||
udelay(4);
|
||||
write_byte(addr);
|
||||
rtc_go_input(DATA); /* Put gpp pin into input mode */
|
||||
udelay(1);
|
||||
for(i=0;i<count;i++) *(buf++)=read_byte();
|
||||
RESET;
|
||||
rtc_go_output(DATA);/* Reset gpp for output */
|
||||
udelay(4);
|
||||
|
||||
DUMP(foo, count);
|
||||
}
|
||||
|
||||
static void
|
||||
write_ser_drv(unsigned char addr, unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
|
||||
DUMP(buf, count);
|
||||
|
||||
addr&=~1; /* WRITE */
|
||||
N_RESET;
|
||||
udelay(4);
|
||||
write_byte(addr);
|
||||
for(i=0;i<count;i++) write_byte(*(buf++));
|
||||
RESET;
|
||||
udelay(4);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
rtc_init(void)
|
||||
{
|
||||
struct ds1302_st bbclk;
|
||||
unsigned char b;
|
||||
int mod;
|
||||
|
||||
DPRINTF("init\n");
|
||||
|
||||
rtc_go_output(DATA|SCLK|RST);
|
||||
|
||||
/* disable write protect */
|
||||
b = 0;
|
||||
write_ser_drv(0x8e,&b,1);
|
||||
|
||||
/* enable trickle */
|
||||
b = 0xa5; /* 1010.0101 */
|
||||
write_ser_drv(0x90,&b,1);
|
||||
|
||||
/* read burst */
|
||||
read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
|
||||
|
||||
/* Sanity checks */
|
||||
mod = 0;
|
||||
if (bbclk.CH) {
|
||||
printf("ds1302: Clock was halted, starting clock\n");
|
||||
bbclk.CH=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
if (bbclk.fmt) {
|
||||
printf("ds1302: Clock was in 12 hour mode, fixing\n");
|
||||
bbclk.fmt=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
if (bbclk.year>9) {
|
||||
printf("ds1302: Year was corrupted, fixing\n");
|
||||
bbclk.year10=100/10; /* 2000 - why not? ;) */
|
||||
bbclk.year=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
/* Write out the changes if needed */
|
||||
if (mod) {
|
||||
/* enable write protect */
|
||||
bbclk.WP = 1;
|
||||
write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
|
||||
} else {
|
||||
/* Else just turn write protect on */
|
||||
b = 0x80;
|
||||
write_ser_drv(0x8e,&b,1);
|
||||
}
|
||||
DPRINTF("init done\n");
|
||||
|
||||
ds1302_initted=1;
|
||||
}
|
||||
|
||||
void
|
||||
rtc_reset(void)
|
||||
{
|
||||
if(!ds1302_initted) rtc_init();
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
int
|
||||
rtc_get(struct rtc_time *tmp)
|
||||
{
|
||||
int rel = 0;
|
||||
struct ds1302_st bbclk;
|
||||
|
||||
if(!ds1302_initted) rtc_init();
|
||||
|
||||
read_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* read burst */
|
||||
|
||||
if (bbclk.CH) {
|
||||
printf("ds1302: rtc_get: Clock was halted, clock probably "
|
||||
"corrupt\n");
|
||||
rel = -1;
|
||||
}
|
||||
|
||||
tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
|
||||
tmp->tm_min=10*bbclk.min10+bbclk.min;
|
||||
tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
|
||||
tmp->tm_wday=bbclk.day;
|
||||
tmp->tm_mday=10*bbclk.date10+bbclk.date;
|
||||
tmp->tm_mon=10*bbclk.month10+bbclk.month;
|
||||
tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
|
||||
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
int rtc_set(struct rtc_time *tmp)
|
||||
{
|
||||
struct ds1302_st bbclk;
|
||||
unsigned char b=0;
|
||||
|
||||
if(!ds1302_initted) rtc_init();
|
||||
|
||||
DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
memset(&bbclk,0,sizeof(bbclk));
|
||||
bbclk.CH=0; /* dont halt */
|
||||
bbclk.WP=1; /* write protect when we're done */
|
||||
|
||||
bbclk.sec10=tmp->tm_sec/10;
|
||||
bbclk.sec=tmp->tm_sec%10;
|
||||
|
||||
bbclk.min10=tmp->tm_min/10;
|
||||
bbclk.min=tmp->tm_min%10;
|
||||
|
||||
bbclk.hr10=tmp->tm_hour/10;
|
||||
bbclk.hr=tmp->tm_hour%10;
|
||||
|
||||
bbclk.day=tmp->tm_wday;
|
||||
|
||||
bbclk.date10=tmp->tm_mday/10;
|
||||
bbclk.date=tmp->tm_mday%10;
|
||||
|
||||
bbclk.month10=tmp->tm_mon/10;
|
||||
bbclk.month=tmp->tm_mon%10;
|
||||
|
||||
tmp->tm_year -= 1900;
|
||||
bbclk.year10=tmp->tm_year/10;
|
||||
bbclk.year=tmp->tm_year%10;
|
||||
|
||||
write_ser_drv(0x8e,&b,1); /* disable write protect */
|
||||
write_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* write burst */
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,438 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2002 SIXNET, dge@sixnetio.com.
|
||||
*
|
||||
* (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
|
||||
* Stephan Linz <linz@li-pro.net>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for DS1306 RTC using SPI:
|
||||
*
|
||||
* - SXNI855T: it uses its own soft SPI here in this file
|
||||
* - all other: use the external spi_xfer() function
|
||||
* (see include/spi.h)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <spi.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define RTC_SECONDS 0x00
|
||||
#define RTC_MINUTES 0x01
|
||||
#define RTC_HOURS 0x02
|
||||
#define RTC_DAY_OF_WEEK 0x03
|
||||
#define RTC_DATE_OF_MONTH 0x04
|
||||
#define RTC_MONTH 0x05
|
||||
#define RTC_YEAR 0x06
|
||||
|
||||
#define RTC_SECONDS_ALARM0 0x07
|
||||
#define RTC_MINUTES_ALARM0 0x08
|
||||
#define RTC_HOURS_ALARM0 0x09
|
||||
#define RTC_DAY_OF_WEEK_ALARM0 0x0a
|
||||
|
||||
#define RTC_SECONDS_ALARM1 0x0b
|
||||
#define RTC_MINUTES_ALARM1 0x0c
|
||||
#define RTC_HOURS_ALARM1 0x0d
|
||||
#define RTC_DAY_OF_WEEK_ALARM1 0x0e
|
||||
|
||||
#define RTC_CONTROL 0x0f
|
||||
#define RTC_STATUS 0x10
|
||||
#define RTC_TRICKLE_CHARGER 0x11
|
||||
|
||||
#define RTC_USER_RAM_BASE 0x20
|
||||
|
||||
/* ************************************************************************* */
|
||||
#ifdef CONFIG_SXNI855T /* !!! SHOULD BE CHANGED TO NEW CODE !!! */
|
||||
|
||||
static void soft_spi_send (unsigned char n);
|
||||
static unsigned char soft_spi_read (void);
|
||||
static void init_spi (void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Definitions
|
||||
*/
|
||||
|
||||
#define PB_SPISCK 0x00000002 /* PB 30 */
|
||||
#define PB_SPIMOSI 0x00000004 /* PB 29 */
|
||||
#define PB_SPIMISO 0x00000008 /* PB 28 */
|
||||
#define PB_SPI_CE 0x00010000 /* PB 15 */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* read clock time from DS1306 and return it in *tmp */
|
||||
int rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
unsigned char spi_byte; /* Data Byte */
|
||||
|
||||
init_spi (); /* set port B for software SPI */
|
||||
|
||||
/* Now we can enable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE;
|
||||
udelay(10);
|
||||
|
||||
/* Shift out the address (0) of the time in the Clock Chip */
|
||||
soft_spi_send (0);
|
||||
|
||||
/* Put the clock readings into the rtc_time structure */
|
||||
tmp->tm_sec = bcd2bin (soft_spi_read ()); /* Read seconds */
|
||||
tmp->tm_min = bcd2bin (soft_spi_read ()); /* Read minutes */
|
||||
|
||||
/* Hours are trickier */
|
||||
spi_byte = soft_spi_read (); /* Read Hours into temporary value */
|
||||
if (spi_byte & 0x40) {
|
||||
/* 12 hour mode bit is set (time is in 1-12 format) */
|
||||
if (spi_byte & 0x20) {
|
||||
/* since PM we add 11 to get 0-23 for hours */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
|
||||
} else {
|
||||
/* since AM we subtract 1 to get 0-23 for hours */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
|
||||
}
|
||||
} else {
|
||||
/* Otherwise, 0-23 hour format */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
|
||||
}
|
||||
|
||||
soft_spi_read (); /* Read and discard Day of week */
|
||||
tmp->tm_mday = bcd2bin (soft_spi_read ()); /* Read Day of the Month */
|
||||
tmp->tm_mon = bcd2bin (soft_spi_read ()); /* Read Month */
|
||||
|
||||
/* Read Year and convert to this century */
|
||||
tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
|
||||
|
||||
/* Now we can disable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay(10);
|
||||
|
||||
rtc_calc_weekday(tmp); /* Determine the day of week */
|
||||
|
||||
debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* set clock time in DS1306 RTC and in MPC8xx RTC */
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
init_spi (); /* set port B for software SPI */
|
||||
|
||||
/* Now we can enable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
|
||||
udelay(10);
|
||||
|
||||
/* First disable write protect in the clock chip control register */
|
||||
soft_spi_send (0x8F); /* send address of the control register */
|
||||
soft_spi_send (0x00); /* send control register contents */
|
||||
|
||||
/* Now disable the DS1306 to terminate the write */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
|
||||
udelay(10);
|
||||
|
||||
/* Now enable the DS1306 to initiate a new write */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE;
|
||||
udelay(10);
|
||||
|
||||
/* Next, send the address of the clock time write registers */
|
||||
soft_spi_send (0x80); /* send address of the first time register */
|
||||
|
||||
/* Use Burst Mode to send all of the time data to the clock */
|
||||
bin2bcd (tmp->tm_sec);
|
||||
soft_spi_send (bin2bcd (tmp->tm_sec)); /* Send Seconds */
|
||||
soft_spi_send (bin2bcd (tmp->tm_min)); /* Send Minutes */
|
||||
soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */
|
||||
soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */
|
||||
soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */
|
||||
soft_spi_send (bin2bcd (tmp->tm_mon)); /* Send Month */
|
||||
soft_spi_send (bin2bcd (tmp->tm_year - 2000)); /* Send Year */
|
||||
|
||||
/* Now we can disable the Clock chip to terminate the burst write */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay(10);
|
||||
|
||||
/* Now we can enable the Clock chip to initiate a new write */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
|
||||
udelay(10);
|
||||
|
||||
/* First we Enable write protect in the clock chip control register */
|
||||
soft_spi_send (0x8F); /* send address of the control register */
|
||||
soft_spi_send (0x40); /* send out Control Register contents */
|
||||
|
||||
/* Now disable the DS1306 */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay(10);
|
||||
|
||||
/* Set standard MPC8xx clock to the same time so Linux will
|
||||
* see the time even if it doesn't have a DS1306 clock driver.
|
||||
* This helps with experimenting with standard kernels.
|
||||
*/
|
||||
{
|
||||
ulong tim;
|
||||
|
||||
tim = rtc_mktime(tmp);
|
||||
|
||||
immap->im_sitk.sitk_rtck = KAPWR_KEY;
|
||||
immap->im_sit.sit_rtc = tim;
|
||||
}
|
||||
|
||||
debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Initialize Port B for software SPI */
|
||||
static void init_spi (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
/* Force output pins to begin at logic 0 */
|
||||
immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
|
||||
|
||||
/* Set these 3 signals as outputs */
|
||||
immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
|
||||
|
||||
immap->im_cpm.cp_pbdir &= ~PB_SPIMISO; /* Make MISO pin an input */
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
|
||||
static void soft_spi_send (unsigned char n)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
unsigned char bitpos; /* bit position to receive */
|
||||
unsigned char i; /* Loop Control */
|
||||
|
||||
/* bit position to send, start with most significant bit */
|
||||
bitpos = 0x80;
|
||||
|
||||
/* Send 8 bits to software SPI */
|
||||
for (i = 0; i < 8; i++) { /* Loop for 8 bits */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
|
||||
|
||||
if (n & bitpos)
|
||||
immap->im_cpm.cp_pbdat |= PB_SPIMOSI; /* Set MOSI to 1 */
|
||||
else
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI; /* Set MOSI to 0 */
|
||||
udelay(10);
|
||||
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
|
||||
udelay(10);
|
||||
|
||||
bitpos >>= 1; /* Shift for next bit position */
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
|
||||
static unsigned char soft_spi_read (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
unsigned char spi_byte = 0; /* Return value, assume success */
|
||||
unsigned char bitpos; /* bit position to receive */
|
||||
unsigned char i; /* Loop Control */
|
||||
|
||||
/* bit position to receive, start with most significant bit */
|
||||
bitpos = 0x80;
|
||||
|
||||
/* Read 8 bits here */
|
||||
for (i = 0; i < 8; i++) { /* Do 8 bits in loop */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
|
||||
udelay(10);
|
||||
if (immap->im_cpm.cp_pbdat & PB_SPIMISO) /* Get a bit of data */
|
||||
spi_byte |= bitpos; /* Set data accordingly */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
|
||||
udelay(10);
|
||||
bitpos >>= 1; /* Shift for next bit position */
|
||||
}
|
||||
|
||||
return spi_byte; /* Return the byte read */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
return; /* nothing to do */
|
||||
}
|
||||
|
||||
#else /* not CONFIG_SXNI855T */
|
||||
/* ************************************************************************* */
|
||||
|
||||
static unsigned char rtc_read (unsigned char reg);
|
||||
static void rtc_write (unsigned char reg, unsigned char val);
|
||||
|
||||
static struct spi_slave *slave;
|
||||
|
||||
/* read clock time from DS1306 and return it in *tmp */
|
||||
int rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
/*
|
||||
* Assuming Vcc = 2.0V (lowest speed)
|
||||
*
|
||||
* REVISIT: If we add an rtc_init() function we can do this
|
||||
* step just once.
|
||||
*/
|
||||
if (!slave) {
|
||||
slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
|
||||
SPI_MODE_3 | SPI_CS_HIGH);
|
||||
if (!slave)
|
||||
return;
|
||||
}
|
||||
|
||||
if (spi_claim_bus(slave))
|
||||
return;
|
||||
|
||||
sec = rtc_read (RTC_SECONDS);
|
||||
min = rtc_read (RTC_MINUTES);
|
||||
hour = rtc_read (RTC_HOURS);
|
||||
mday = rtc_read (RTC_DATE_OF_MONTH);
|
||||
wday = rtc_read (RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read (RTC_MONTH);
|
||||
year = rtc_read (RTC_YEAR);
|
||||
|
||||
spi_release_bus(slave);
|
||||
|
||||
debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday, hour, min, sec);
|
||||
debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_DAY_OF_WEEK_ALARM0),
|
||||
rtc_read (RTC_HOURS_ALARM0),
|
||||
rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
|
||||
debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_DAY_OF_WEEK_ALARM1),
|
||||
rtc_read (RTC_HOURS_ALARM1),
|
||||
rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F); /* convert Seconds */
|
||||
tmp->tm_min = bcd2bin (min & 0x7F); /* convert Minutes */
|
||||
|
||||
/* convert Hours */
|
||||
tmp->tm_hour = (hour & 0x40)
|
||||
? ((hour & 0x20) /* 12 hour mode */
|
||||
? bcd2bin (hour & 0x1F) + 11 /* PM */
|
||||
: bcd2bin (hour & 0x1F) - 1 /* AM */
|
||||
)
|
||||
: bcd2bin (hour & 0x3F); /* 24 hour mode */
|
||||
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F); /* convert Day of the Month */
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F); /* convert Month */
|
||||
tmp->tm_year = bcd2bin (year) + 2000; /* convert Year */
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07) - 1; /* convert Day of the Week */
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst = 0;
|
||||
|
||||
debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* set clock time from *tmp in DS1306 RTC */
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
/* Assuming Vcc = 2.0V (lowest speed) */
|
||||
if (!slave) {
|
||||
slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
|
||||
SPI_MODE_3 | SPI_CS_HIGH);
|
||||
if (!slave)
|
||||
return;
|
||||
}
|
||||
|
||||
if (spi_claim_bus(slave))
|
||||
return;
|
||||
|
||||
debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
|
||||
rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
|
||||
rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
|
||||
rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
|
||||
rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
|
||||
rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
|
||||
|
||||
spi_release_bus(slave);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* reset the DS1306 */
|
||||
void rtc_reset (void)
|
||||
{
|
||||
/* Assuming Vcc = 2.0V (lowest speed) */
|
||||
if (!slave) {
|
||||
slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
|
||||
SPI_MODE_3 | SPI_CS_HIGH);
|
||||
if (!slave)
|
||||
return;
|
||||
}
|
||||
|
||||
if (spi_claim_bus(slave))
|
||||
return;
|
||||
|
||||
/* clear the control register */
|
||||
rtc_write (RTC_CONTROL, 0x00); /* 1st step: reset WP */
|
||||
rtc_write (RTC_CONTROL, 0x00); /* 2nd step: reset 1Hz, AIE1, AIE0 */
|
||||
|
||||
/* reset all alarms */
|
||||
rtc_write (RTC_SECONDS_ALARM0, 0x00);
|
||||
rtc_write (RTC_SECONDS_ALARM1, 0x00);
|
||||
rtc_write (RTC_MINUTES_ALARM0, 0x00);
|
||||
rtc_write (RTC_MINUTES_ALARM1, 0x00);
|
||||
rtc_write (RTC_HOURS_ALARM0, 0x00);
|
||||
rtc_write (RTC_HOURS_ALARM1, 0x00);
|
||||
rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
|
||||
rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
|
||||
|
||||
spi_release_bus(slave);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static unsigned char rtc_read (unsigned char reg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_w8r8(slave, reg);
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void rtc_write (unsigned char reg, unsigned char val)
|
||||
{
|
||||
unsigned char dout[2]; /* SPI Output Data Bytes */
|
||||
unsigned char din[2]; /* SPI Input Data Bytes */
|
||||
|
||||
dout[0] = 0x80 | reg;
|
||||
dout[1] = val;
|
||||
|
||||
spi_xfer (slave, 16, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
|
||||
}
|
||||
|
||||
#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
|
@ -1,122 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Faraday FTRTC010 Real Time Clock
|
||||
*
|
||||
* (C) Copyright 2009 Faraday Technology
|
||||
* Po-Yu Chuang <ratbert@faraday-tech.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <log.h>
|
||||
#include <rtc.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct ftrtc010 {
|
||||
unsigned int sec; /* 0x00 */
|
||||
unsigned int min; /* 0x04 */
|
||||
unsigned int hour; /* 0x08 */
|
||||
unsigned int day; /* 0x0c */
|
||||
unsigned int alarm_sec; /* 0x10 */
|
||||
unsigned int alarm_min; /* 0x14 */
|
||||
unsigned int alarm_hour; /* 0x18 */
|
||||
unsigned int record; /* 0x1c */
|
||||
unsigned int cr; /* 0x20 */
|
||||
unsigned int wsec; /* 0x24 */
|
||||
unsigned int wmin; /* 0x28 */
|
||||
unsigned int whour; /* 0x2c */
|
||||
unsigned int wday; /* 0x30 */
|
||||
unsigned int intr; /* 0x34 */
|
||||
unsigned int div; /* 0x38 */
|
||||
unsigned int rev; /* 0x3c */
|
||||
};
|
||||
|
||||
/*
|
||||
* RTC Control Register
|
||||
*/
|
||||
#define FTRTC010_CR_ENABLE (1 << 0)
|
||||
#define FTRTC010_CR_INTERRUPT_SEC (1 << 1) /* per second irq */
|
||||
#define FTRTC010_CR_INTERRUPT_MIN (1 << 2) /* per minute irq */
|
||||
#define FTRTC010_CR_INTERRUPT_HR (1 << 3) /* per hour irq */
|
||||
#define FTRTC010_CR_INTERRUPT_DAY (1 << 4) /* per day irq */
|
||||
|
||||
static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE;
|
||||
|
||||
static void ftrtc010_enable(void)
|
||||
{
|
||||
writel(FTRTC010_CR_ENABLE, &rtc->cr);
|
||||
}
|
||||
|
||||
/*
|
||||
* return current time in seconds
|
||||
*/
|
||||
static unsigned long ftrtc010_time(void)
|
||||
{
|
||||
unsigned long day;
|
||||
unsigned long hour;
|
||||
unsigned long minute;
|
||||
unsigned long second;
|
||||
unsigned long second2;
|
||||
|
||||
do {
|
||||
second = readl(&rtc->sec);
|
||||
day = readl(&rtc->day);
|
||||
hour = readl(&rtc->hour);
|
||||
minute = readl(&rtc->min);
|
||||
second2 = readl(&rtc->sec);
|
||||
} while (second != second2);
|
||||
|
||||
return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
|
||||
int rtc_get(struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long now;
|
||||
|
||||
debug("%s(): record register: %x\n",
|
||||
__func__, readl(&rtc->record));
|
||||
|
||||
#ifdef CFG_FTRTC010_PCLK
|
||||
now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT;
|
||||
#else /* CFG_FTRTC010_EXTCLK */
|
||||
now = ftrtc010_time() + readl(&rtc->record);
|
||||
#endif
|
||||
|
||||
rtc_to_tm(now, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
int rtc_set(struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long new;
|
||||
unsigned long now;
|
||||
|
||||
debug("%s(): DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
__func__,
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
new = rtc_mktime(tmp);
|
||||
|
||||
now = ftrtc010_time();
|
||||
|
||||
debug("%s(): write %lx to record register\n", __func__, new - now);
|
||||
|
||||
writel(new - now, &rtc->record);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset(void)
|
||||
{
|
||||
debug("%s()\n", __func__);
|
||||
ftrtc010_enable();
|
||||
}
|
@ -1,223 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2009-2012 ADVANSEE
|
||||
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||
*
|
||||
* Based on the Linux rtc-imxdi.c driver, which is:
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2010 Orex Computed Radiography
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for Freescale i.MX DryIce RTC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <linux/compat.h>
|
||||
#include <rtc.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
/* DryIce Register Definitions */
|
||||
|
||||
struct imxdi_regs {
|
||||
u32 dtcmr; /* Time Counter MSB Reg */
|
||||
u32 dtclr; /* Time Counter LSB Reg */
|
||||
u32 dcamr; /* Clock Alarm MSB Reg */
|
||||
u32 dcalr; /* Clock Alarm LSB Reg */
|
||||
u32 dcr; /* Control Reg */
|
||||
u32 dsr; /* Status Reg */
|
||||
u32 dier; /* Interrupt Enable Reg */
|
||||
};
|
||||
|
||||
#define DCAMR_UNSET 0xFFFFFFFF /* doomsday - 1 sec */
|
||||
|
||||
#define DCR_TCE (1 << 3) /* Time Counter Enable */
|
||||
|
||||
#define DSR_WBF (1 << 10) /* Write Busy Flag */
|
||||
#define DSR_WNF (1 << 9) /* Write Next Flag */
|
||||
#define DSR_WCF (1 << 8) /* Write Complete Flag */
|
||||
#define DSR_WEF (1 << 7) /* Write Error Flag */
|
||||
#define DSR_CAF (1 << 4) /* Clock Alarm Flag */
|
||||
#define DSR_NVF (1 << 1) /* Non-Valid Flag */
|
||||
#define DSR_SVF (1 << 0) /* Security Violation Flag */
|
||||
|
||||
#define DIER_WNIE (1 << 9) /* Write Next Interrupt Enable */
|
||||
#define DIER_WCIE (1 << 8) /* Write Complete Interrupt Enable */
|
||||
#define DIER_WEIE (1 << 7) /* Write Error Interrupt Enable */
|
||||
#define DIER_CAIE (1 << 4) /* Clock Alarm Interrupt Enable */
|
||||
|
||||
/* Driver Private Data */
|
||||
|
||||
struct imxdi_data {
|
||||
struct imxdi_regs __iomem *regs;
|
||||
int init_done;
|
||||
};
|
||||
|
||||
static struct imxdi_data data;
|
||||
|
||||
/*
|
||||
* This function attempts to clear the dryice write-error flag.
|
||||
*
|
||||
* A dryice write error is similar to a bus fault and should not occur in
|
||||
* normal operation. Clearing the flag requires another write, so the root
|
||||
* cause of the problem may need to be fixed before the flag can be cleared.
|
||||
*/
|
||||
static void clear_write_error(void)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
puts("### Warning: RTC - Register write error!\n");
|
||||
|
||||
/* clear the write error flag */
|
||||
__raw_writel(DSR_WEF, &data.regs->dsr);
|
||||
|
||||
/* wait for it to take effect */
|
||||
for (cnt = 0; cnt < 1000; cnt++) {
|
||||
if ((__raw_readl(&data.regs->dsr) & DSR_WEF) == 0)
|
||||
return;
|
||||
udelay(10);
|
||||
}
|
||||
puts("### Error: RTC - Cannot clear write-error flag!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a dryice register and wait until it completes.
|
||||
*
|
||||
* Use interrupt flags to determine when the write has completed.
|
||||
*/
|
||||
#define DI_WRITE_WAIT(val, reg) \
|
||||
( \
|
||||
/* do the register write */ \
|
||||
__raw_writel((val), &data.regs->reg), \
|
||||
\
|
||||
di_write_wait((val), #reg) \
|
||||
)
|
||||
static int di_write_wait(u32 val, const char *reg)
|
||||
{
|
||||
int cnt;
|
||||
int ret = 0;
|
||||
int rc = 0;
|
||||
|
||||
/* wait for the write to finish */
|
||||
for (cnt = 0; cnt < 100; cnt++) {
|
||||
if ((__raw_readl(&data.regs->dsr) & (DSR_WCF | DSR_WEF)) != 0) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
udelay(10);
|
||||
}
|
||||
if (ret == 0)
|
||||
printf("### Warning: RTC - Write-wait timeout "
|
||||
"val = 0x%.8x reg = %s\n", val, reg);
|
||||
|
||||
/* check for write error */
|
||||
if (__raw_readl(&data.regs->dsr) & DSR_WEF) {
|
||||
clear_write_error();
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize dryice hardware
|
||||
*/
|
||||
static int di_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
data.regs = (struct imxdi_regs __iomem *)IMX_DRYICE_BASE;
|
||||
|
||||
/* mask all interrupts */
|
||||
__raw_writel(0, &data.regs->dier);
|
||||
|
||||
/* put dryice into valid state */
|
||||
if (__raw_readl(&data.regs->dsr) & DSR_NVF) {
|
||||
rc = DI_WRITE_WAIT(DSR_NVF | DSR_SVF, dsr);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* initialize alarm */
|
||||
rc = DI_WRITE_WAIT(DCAMR_UNSET, dcamr);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = DI_WRITE_WAIT(0, dcalr);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
/* clear alarm flag */
|
||||
if (__raw_readl(&data.regs->dsr) & DSR_CAF) {
|
||||
rc = DI_WRITE_WAIT(DSR_CAF, dsr);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* the timer won't count if it has never been written to */
|
||||
if (__raw_readl(&data.regs->dtcmr) == 0) {
|
||||
rc = DI_WRITE_WAIT(0, dtcmr);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* start keeping time */
|
||||
if (!(__raw_readl(&data.regs->dcr) & DCR_TCE)) {
|
||||
rc = DI_WRITE_WAIT(__raw_readl(&data.regs->dcr) | DCR_TCE, dcr);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
data.init_done = 1;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rtc_get(struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long now;
|
||||
int rc = 0;
|
||||
|
||||
if (!data.init_done) {
|
||||
rc = di_init();
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
now = __raw_readl(&data.regs->dtcmr);
|
||||
rtc_to_tm(now, tmp);
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rtc_set(struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long now;
|
||||
int rc;
|
||||
|
||||
if (!data.init_done) {
|
||||
rc = di_init();
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
now = rtc_mktime(tmp);
|
||||
/* zero the fractional part first */
|
||||
rc = DI_WRITE_WAIT(0, dtclr);
|
||||
if (rc == 0)
|
||||
rc = DI_WRITE_WAIT(now, dtcmr);
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void rtc_reset(void)
|
||||
{
|
||||
di_init();
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for MAXIM MAX6900 RTC
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifndef CFG_SYS_I2C_RTC_ADDR
|
||||
#define CFG_SYS_I2C_RTC_ADDR 0x50
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_SYS_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_SYS_I2C_RTC_ADDR, reg, val);
|
||||
udelay(2500);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon, cent, year;
|
||||
int retry = 1;
|
||||
|
||||
do {
|
||||
sec = rtc_read (0x80);
|
||||
min = rtc_read (0x82);
|
||||
hour = rtc_read (0x84);
|
||||
mday = rtc_read (0x86);
|
||||
mon = rtc_read (0x88);
|
||||
wday = rtc_read (0x8a);
|
||||
year = rtc_read (0x8c);
|
||||
cent = rtc_read (0x92);
|
||||
/*
|
||||
* Check for seconds rollover
|
||||
*/
|
||||
if ((sec != 59) || (rtc_read(0x80) == sec)){
|
||||
retry = 0;
|
||||
}
|
||||
} while (retry);
|
||||
|
||||
debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, cent, mday, wday,
|
||||
hour, min, sec );
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
|
||||
debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
rtc_write (0x9E, 0x00);
|
||||
rtc_write (0x80, 0); /* Clear seconds to ensure no rollover */
|
||||
rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
|
||||
rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (0x8a, bin2bcd(tmp->tm_wday));
|
||||
rtc_write (0x88, bin2bcd(tmp->tm_mon));
|
||||
rtc_write (0x86, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (0x84, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (0x82, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (0x80, bin2bcd(tmp->tm_sec ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Andreas Heppel <aheppel@sysgo.de>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the MK48T59 RTC
|
||||
*/
|
||||
|
||||
#undef RTC_DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <config.h>
|
||||
#include <rtc.h>
|
||||
#include <mk48t59.h>
|
||||
|
||||
#if defined(CONFIG_BAB7xx)
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
out8(RTC_PORT_ADDR0, reg & 0xFF);
|
||||
out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
|
||||
return in8(RTC_PORT_DATA);
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out8(RTC_PORT_ADDR0, reg & 0xFF);
|
||||
out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
|
||||
out8(RTC_PORT_DATA, val);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_EVAL5200)
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
return in8(RTC(reg));
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out8(RTC(reg),val);
|
||||
}
|
||||
|
||||
#else
|
||||
# error Board specific rtc access functions should be supplied
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void *nvram_read(void *dest, const short src, size_t count)
|
||||
{
|
||||
uchar *d = (uchar *) dest;
|
||||
short s = src;
|
||||
|
||||
while (count--)
|
||||
*d++ = rtc_read(s++);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void nvram_write(short dest, const void *src, size_t count)
|
||||
{
|
||||
short d = dest;
|
||||
uchar *s = (uchar *) src;
|
||||
|
||||
while (count--)
|
||||
rtc_write(d++, *s++);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar save_ctrl_a;
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
/* Simple: freeze the clock, read it and allow updates again */
|
||||
save_ctrl_a = rtc_read(RTC_CONTROLA);
|
||||
|
||||
/* Set the register to read the value. */
|
||||
save_ctrl_a |= RTC_CA_READ;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a);
|
||||
|
||||
sec = rtc_read (RTC_SECONDS);
|
||||
min = rtc_read (RTC_MINUTES);
|
||||
hour = rtc_read (RTC_HOURS);
|
||||
mday = rtc_read (RTC_DAY_OF_MONTH);
|
||||
wday = rtc_read (RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read (RTC_MONTH);
|
||||
year = rtc_read (RTC_YEAR);
|
||||
|
||||
/* re-enable update */
|
||||
save_ctrl_a &= ~RTC_CA_READ;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday,
|
||||
hour, min, sec );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year);
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
if(tmp->tm_year<70)
|
||||
tmp->tm_year+=2000;
|
||||
else
|
||||
tmp->tm_year+=1900;
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar save_ctrl_a;
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
#endif
|
||||
save_ctrl_a = rtc_read(RTC_CONTROLA);
|
||||
|
||||
save_ctrl_a |= RTC_CA_WRITE;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
|
||||
|
||||
rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
|
||||
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
|
||||
rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
|
||||
|
||||
save_ctrl_a &= ~RTC_CA_WRITE;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar control_b;
|
||||
|
||||
/*
|
||||
* Start oscillator here.
|
||||
*/
|
||||
control_b = rtc_read(RTC_CONTROLB);
|
||||
|
||||
control_b &= ~RTC_CB_STOP;
|
||||
rtc_write(RTC_CONTROLB, control_b);
|
||||
}
|
||||
|
||||
void rtc_set_watchdog(short multi, short res)
|
||||
{
|
||||
uchar wd_value;
|
||||
|
||||
wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
|
||||
rtc_write(RTC_WATCHDOG, wd_value);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Freescale i.MX27 RTC Driver
|
||||
*
|
||||
* Copyright (C) 2012 Philippe Reynes <tremyfr@yahoo.fr>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <rtc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#define HOUR_SHIFT 8
|
||||
#define HOUR_MASK 0x1f
|
||||
#define MIN_SHIFT 0
|
||||
#define MIN_MASK 0x3f
|
||||
|
||||
int rtc_get(struct rtc_time *time)
|
||||
{
|
||||
struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE;
|
||||
uint32_t day, hour, min, sec;
|
||||
|
||||
day = readl(&rtc_regs->dayr);
|
||||
hour = readl(&rtc_regs->hourmin);
|
||||
sec = readl(&rtc_regs->seconds);
|
||||
|
||||
min = (hour >> MIN_SHIFT) & MIN_MASK;
|
||||
hour = (hour >> HOUR_SHIFT) & HOUR_MASK;
|
||||
|
||||
sec += min * 60 + hour * 3600 + day * 24 * 3600;
|
||||
|
||||
rtc_to_tm(sec, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set(struct rtc_time *time)
|
||||
{
|
||||
struct rtc_regs *rtc_regs = (struct rtc_regs *)IMX_RTC_BASE;
|
||||
uint32_t day, hour, min, sec;
|
||||
|
||||
sec = rtc_mktime(time);
|
||||
|
||||
day = sec / (24 * 3600);
|
||||
sec = sec % (24 * 3600);
|
||||
hour = sec / 3600;
|
||||
sec = sec % 3600;
|
||||
min = sec / 60;
|
||||
sec = sec % 60;
|
||||
|
||||
hour = (hour & HOUR_MASK) << HOUR_SHIFT;
|
||||
hour |= (min & MIN_MASK) << MIN_SHIFT;
|
||||
|
||||
writel(day, &rtc_regs->dayr);
|
||||
writel(hour, &rtc_regs->hourmin);
|
||||
writel(sec, &rtc_regs->seconds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset(void)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
/*
|
||||
* rs5c372.c
|
||||
*
|
||||
* Device driver for Ricoh's Real Time Controller RS5C372A.
|
||||
*
|
||||
* Copyright (C) 2004 Gary Jennejohn garyj@denx.de
|
||||
*
|
||||
* Based in part in ds1307.c -
|
||||
* (C) Copyright 2001, 2002, 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Keith Outwater, keith_outwater@mvis.com`
|
||||
* Steven Scholz, steven.scholz@imc-berlin.de
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
/*
|
||||
* Reads are always done starting with register 15, which requires some
|
||||
* jumping-through-hoops to access the data correctly.
|
||||
*
|
||||
* Writes are always done starting with register 0.
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
static unsigned int rtc_debug = DEBUG;
|
||||
#else
|
||||
#define rtc_debug 0 /* gcc will remove all the debug code for us */
|
||||
#endif
|
||||
|
||||
#ifndef CFG_SYS_I2C_RTC_ADDR
|
||||
#define CFG_SYS_I2C_RTC_ADDR 0x32
|
||||
#endif
|
||||
|
||||
#define RS5C372_RAM_SIZE 0x10
|
||||
#define RATE_32000HZ 0x80 /* Rate Select 32.000KHz */
|
||||
#define RATE_32768HZ 0x00 /* Rate Select 32.768KHz */
|
||||
|
||||
#define STATUS_XPT 0x10 /* data invalid because voltage was 0 */
|
||||
|
||||
#define USE_24HOUR_MODE 0x20
|
||||
#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
|
||||
#define HOURS_AP(n) (((n) >> 5) & 1)
|
||||
#define HOURS_12(n) bcd2bin((n) & 0x1F)
|
||||
#define HOURS_24(n) bcd2bin((n) & 0x3F)
|
||||
|
||||
|
||||
static int setup_done = 0;
|
||||
|
||||
static int
|
||||
rs5c372_readram(unsigned char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_read(CFG_SYS_I2C_RTC_ADDR, 0, 0, buf, len);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed to read\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (buf[0] & STATUS_XPT)
|
||||
printf("### Warning: RTC lost power\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
rs5c372_enable(void)
|
||||
{
|
||||
unsigned char buf[RS5C372_RAM_SIZE + 1];
|
||||
int ret;
|
||||
|
||||
/* note that this returns reg. 15 in buf[1] */
|
||||
ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
/* we want to start writing at register 0 so we have to copy the */
|
||||
/* register contents up one slot */
|
||||
for (ret = 2; ret < 9; ret++)
|
||||
buf[ret - 1] = buf[ret];
|
||||
/* registers 0 to 6 (time values) are not touched */
|
||||
buf[8] = RATE_32768HZ; /* reg. 7 */
|
||||
buf[9] = 0; /* reg. 8 */
|
||||
buf[10] = 0; /* reg. 9 */
|
||||
buf[11] = 0; /* reg. 10 */
|
||||
buf[12] = 0; /* reg. 11 */
|
||||
buf[13] = 0; /* reg. 12 */
|
||||
buf[14] = 0; /* reg. 13 */
|
||||
buf[15] = 0; /* reg. 14 */
|
||||
buf[16] = USE_24HOUR_MODE; /* reg. 15 */
|
||||
ret = i2c_write(CFG_SYS_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
setup_done = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
|
||||
{
|
||||
/* buf[0] is register 15 */
|
||||
dt->tm_sec = bcd2bin(buf[1]);
|
||||
dt->tm_min = bcd2bin(buf[2]);
|
||||
|
||||
if (TWELVE_HOUR_MODE(buf[0])) {
|
||||
dt->tm_hour = HOURS_12(buf[3]);
|
||||
if (HOURS_AP(buf[3])) /* PM */
|
||||
dt->tm_hour += 12;
|
||||
} else /* 24-hour-mode */
|
||||
dt->tm_hour = HOURS_24(buf[3]);
|
||||
|
||||
dt->tm_mday = bcd2bin(buf[5]);
|
||||
dt->tm_mon = bcd2bin(buf[6]);
|
||||
dt->tm_year = bcd2bin(buf[7]);
|
||||
if (dt->tm_year >= 70)
|
||||
dt->tm_year += 1900;
|
||||
else
|
||||
dt->tm_year += 2000;
|
||||
/* 0 is Sunday */
|
||||
dt->tm_wday = bcd2bin(buf[4] & 0x07);
|
||||
dt->tm_yday = 0;
|
||||
dt->tm_isdst= 0;
|
||||
|
||||
if(rtc_debug > 2) {
|
||||
printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
|
||||
printf("rs5c372_convert_to_time: mon = %d\n", dt->tm_mon);
|
||||
printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
|
||||
printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
|
||||
printf("rs5c372_convert_to_time: min = %d\n", dt->tm_min);
|
||||
printf("rs5c372_convert_to_time: sec = %d\n", dt->tm_sec);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
int
|
||||
rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char buf[RS5C372_RAM_SIZE];
|
||||
int ret;
|
||||
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
|
||||
if (!setup_done)
|
||||
return -1;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* note that this returns reg. 15 in buf[0] */
|
||||
ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rs5c372_convert_to_time(tmp, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
int rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char buf[8], reg15;
|
||||
int ret;
|
||||
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
|
||||
if (!setup_done)
|
||||
return -1;
|
||||
|
||||
if(rtc_debug > 2) {
|
||||
printf("rtc_set: tm_year = %d\n", tmp->tm_year);
|
||||
printf("rtc_set: tm_mon = %d\n", tmp->tm_mon);
|
||||
printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
|
||||
printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
|
||||
printf("rtc_set: tm_min = %d\n", tmp->tm_min);
|
||||
printf("rtc_set: tm_sec = %d\n", tmp->tm_sec);
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* only read register 15 */
|
||||
ret = i2c_read(CFG_SYS_I2C_RTC_ADDR, 0, 0, buf, 1);
|
||||
|
||||
if (ret == 0) {
|
||||
/* need to save register 15 */
|
||||
reg15 = buf[0];
|
||||
buf[0] = 0; /* register address on RS5C372 */
|
||||
buf[1] = bin2bcd(tmp->tm_sec);
|
||||
buf[2] = bin2bcd(tmp->tm_min);
|
||||
/* need to handle 12 hour mode */
|
||||
if (TWELVE_HOUR_MODE(reg15)) {
|
||||
if (tmp->tm_hour >= 12) { /* PM */
|
||||
/* 12 PM is a special case */
|
||||
if (tmp->tm_hour == 12)
|
||||
buf[3] = bin2bcd(tmp->tm_hour);
|
||||
else
|
||||
buf[3] = bin2bcd(tmp->tm_hour - 12);
|
||||
buf[3] |= 0x20;
|
||||
}
|
||||
} else {
|
||||
buf[3] = bin2bcd(tmp->tm_hour);
|
||||
}
|
||||
|
||||
buf[4] = bin2bcd(tmp->tm_wday);
|
||||
buf[5] = bin2bcd(tmp->tm_mday);
|
||||
buf[6] = bin2bcd(tmp->tm_mon);
|
||||
if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
|
||||
printf("WARNING: year should be between 1970 and 2069!\n");
|
||||
buf[7] = bin2bcd(tmp->tm_year % 100);
|
||||
|
||||
ret = i2c_write(CFG_SYS_I2C_RTC_ADDR, 0, 0, buf, 8);
|
||||
if (ret != 0) {
|
||||
printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the RTC.
|
||||
*/
|
||||
void
|
||||
rtc_reset (void)
|
||||
{
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the built-in Samsung S3C24X0 RTC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
|
||||
#include <rtc.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
typedef enum {
|
||||
RTC_ENABLE,
|
||||
RTC_DISABLE
|
||||
} RTC_ACCESS;
|
||||
|
||||
|
||||
static inline void SetRTC_Access(RTC_ACCESS a)
|
||||
{
|
||||
struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
|
||||
|
||||
switch (a) {
|
||||
case RTC_ENABLE:
|
||||
writeb(readb(&rtc->rtccon) | 0x01, &rtc->rtccon);
|
||||
break;
|
||||
|
||||
case RTC_DISABLE:
|
||||
writeb(readb(&rtc->rtccon) & ~0x01, &rtc->rtccon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int rtc_get(struct rtc_time *tmp)
|
||||
{
|
||||
struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
__maybe_unused uchar a_sec, a_min, a_hour, a_date,
|
||||
a_mon, a_year, a_armed;
|
||||
|
||||
/* enable access to RTC registers */
|
||||
SetRTC_Access(RTC_ENABLE);
|
||||
|
||||
/* read RTC registers */
|
||||
do {
|
||||
sec = readb(&rtc->bcdsec);
|
||||
min = readb(&rtc->bcdmin);
|
||||
hour = readb(&rtc->bcdhour);
|
||||
mday = readb(&rtc->bcddate);
|
||||
wday = readb(&rtc->bcdday);
|
||||
mon = readb(&rtc->bcdmon);
|
||||
year = readb(&rtc->bcdyear);
|
||||
} while (sec != readb(&rtc->bcdsec));
|
||||
|
||||
/* read ALARM registers */
|
||||
a_sec = readb(&rtc->almsec);
|
||||
a_min = readb(&rtc->almmin);
|
||||
a_hour = readb(&rtc->almhour);
|
||||
a_date = readb(&rtc->almdate);
|
||||
a_mon = readb(&rtc->almmon);
|
||||
a_year = readb(&rtc->almyear);
|
||||
a_armed = readb(&rtc->rtcalm);
|
||||
|
||||
/* disable access to RTC registers */
|
||||
SetRTC_Access(RTC_DISABLE);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday, hour, min, sec);
|
||||
printf("Alarms: %02x: year: %02x month: %02x date: %02x hour: "
|
||||
"%02x min: %02x sec: %02x\n",
|
||||
a_armed, a_year, a_mon, a_date, a_hour, a_min, a_sec);
|
||||
#endif
|
||||
|
||||
tmp->tm_sec = bcd2bin(sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin(min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin(hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin(mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin(mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin(year);
|
||||
tmp->tm_wday = bcd2bin(wday & 0x07);
|
||||
if (tmp->tm_year < 70)
|
||||
tmp->tm_year += 2000;
|
||||
else
|
||||
tmp->tm_year += 1900;
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst = 0;
|
||||
#ifdef RTC_DEBUG
|
||||
printf("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set(struct rtc_time *tmp)
|
||||
{
|
||||
struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
#endif
|
||||
year = bin2bcd(tmp->tm_year % 100);
|
||||
mon = bin2bcd(tmp->tm_mon);
|
||||
wday = bin2bcd(tmp->tm_wday);
|
||||
mday = bin2bcd(tmp->tm_mday);
|
||||
hour = bin2bcd(tmp->tm_hour);
|
||||
min = bin2bcd(tmp->tm_min);
|
||||
sec = bin2bcd(tmp->tm_sec);
|
||||
|
||||
/* enable access to RTC registers */
|
||||
SetRTC_Access(RTC_ENABLE);
|
||||
|
||||
/* write RTC registers */
|
||||
writeb(sec, &rtc->bcdsec);
|
||||
writeb(min, &rtc->bcdmin);
|
||||
writeb(hour, &rtc->bcdhour);
|
||||
writeb(mday, &rtc->bcddate);
|
||||
writeb(wday, &rtc->bcdday);
|
||||
writeb(mon, &rtc->bcdmon);
|
||||
writeb(year, &rtc->bcdyear);
|
||||
|
||||
/* disable access to RTC registers */
|
||||
SetRTC_Access(RTC_DISABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset(void)
|
||||
{
|
||||
struct s3c24x0_rtc *rtc = s3c24x0_get_base_rtc();
|
||||
|
||||
writeb((readb(&rtc->rtccon) & ~0x06) | 0x08, &rtc->rtccon);
|
||||
writeb(readb(&rtc->rtccon) & ~(0x08 | 0x01), &rtc->rtccon);
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* based on a the Linux rtc-x1207.c driver which is:
|
||||
* Copyright 2004 Karen Spearel
|
||||
* Copyright 2005 Alessandro Zummo
|
||||
*
|
||||
* Information and datasheet:
|
||||
* http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for Xicor/Intersil X1205 RTC
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <log.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#define CCR_SEC 0
|
||||
#define CCR_MIN 1
|
||||
#define CCR_HOUR 2
|
||||
#define CCR_MDAY 3
|
||||
#define CCR_MONTH 4
|
||||
#define CCR_YEAR 5
|
||||
#define CCR_WDAY 6
|
||||
#define CCR_Y2K 7
|
||||
|
||||
#define X1205_REG_SR 0x3F /* status register */
|
||||
#define X1205_REG_Y2K 0x37
|
||||
#define X1205_REG_DW 0x36
|
||||
#define X1205_REG_YR 0x35
|
||||
#define X1205_REG_MO 0x34
|
||||
#define X1205_REG_DT 0x33
|
||||
#define X1205_REG_HR 0x32
|
||||
#define X1205_REG_MN 0x31
|
||||
#define X1205_REG_SC 0x30
|
||||
#define X1205_REG_DTR 0x13
|
||||
#define X1205_REG_ATR 0x12
|
||||
#define X1205_REG_INT 0x11
|
||||
#define X1205_REG_0 0x10
|
||||
#define X1205_REG_Y2K1 0x0F
|
||||
#define X1205_REG_DWA1 0x0E
|
||||
#define X1205_REG_YRA1 0x0D
|
||||
#define X1205_REG_MOA1 0x0C
|
||||
#define X1205_REG_DTA1 0x0B
|
||||
#define X1205_REG_HRA1 0x0A
|
||||
#define X1205_REG_MNA1 0x09
|
||||
#define X1205_REG_SCA1 0x08
|
||||
#define X1205_REG_Y2K0 0x07
|
||||
#define X1205_REG_DWA0 0x06
|
||||
#define X1205_REG_YRA0 0x05
|
||||
#define X1205_REG_MOA0 0x04
|
||||
#define X1205_REG_DTA0 0x03
|
||||
#define X1205_REG_HRA0 0x02
|
||||
#define X1205_REG_MNA0 0x01
|
||||
#define X1205_REG_SCA0 0x00
|
||||
|
||||
#define X1205_CCR_BASE 0x30 /* Base address of CCR */
|
||||
#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
|
||||
|
||||
#define X1205_SR_RTCF 0x01 /* Clock failure */
|
||||
#define X1205_SR_WEL 0x02 /* Write Enable Latch */
|
||||
#define X1205_SR_RWEL 0x04 /* Register Write Enable */
|
||||
|
||||
#define X1205_DTR_DTR0 0x01
|
||||
#define X1205_DTR_DTR1 0x02
|
||||
#define X1205_DTR_DTR2 0x04
|
||||
|
||||
#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
|
||||
|
||||
static void rtc_write(int reg, u8 val)
|
||||
{
|
||||
i2c_write(CFG_SYS_I2C_RTC_ADDR, reg, 2, &val, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the routines that deal directly with the x1205 hardware, we use
|
||||
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
|
||||
* Epoch is initialized as 2000. Time is set to UTC.
|
||||
*/
|
||||
int rtc_get(struct rtc_time *tm)
|
||||
{
|
||||
u8 buf[8];
|
||||
|
||||
i2c_read(CFG_SYS_I2C_RTC_ADDR, X1205_CCR_BASE, 2, buf, 8);
|
||||
|
||||
debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
|
||||
"mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
|
||||
__FUNCTION__,
|
||||
buf[0], buf[1], buf[2], buf[3],
|
||||
buf[4], buf[5], buf[6], buf[7]);
|
||||
|
||||
tm->tm_sec = bcd2bin(buf[CCR_SEC]);
|
||||
tm->tm_min = bcd2bin(buf[CCR_MIN]);
|
||||
tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
|
||||
tm->tm_mday = bcd2bin(buf[CCR_MDAY]);
|
||||
tm->tm_mon = bcd2bin(buf[CCR_MONTH]); /* mon is 0-11 */
|
||||
tm->tm_year = bcd2bin(buf[CCR_YEAR])
|
||||
+ (bcd2bin(buf[CCR_Y2K]) * 100);
|
||||
tm->tm_wday = buf[CCR_WDAY];
|
||||
|
||||
debug("%s: tm is secs=%d, mins=%d, hours=%d, "
|
||||
"mday=%d, mon=%d, year=%d, wday=%d\n",
|
||||
__FUNCTION__,
|
||||
tm->tm_sec, tm->tm_min, tm->tm_hour,
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set(struct rtc_time *tm)
|
||||
{
|
||||
int i;
|
||||
u8 buf[8];
|
||||
|
||||
debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
buf[CCR_SEC] = bin2bcd(tm->tm_sec);
|
||||
buf[CCR_MIN] = bin2bcd(tm->tm_min);
|
||||
|
||||
/* set hour and 24hr bit */
|
||||
buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
|
||||
|
||||
buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
|
||||
|
||||
/* month, 1 - 12 */
|
||||
buf[CCR_MONTH] = bin2bcd(tm->tm_mon);
|
||||
|
||||
/* year, since the rtc epoch*/
|
||||
buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
|
||||
buf[CCR_WDAY] = tm->tm_wday & 0x07;
|
||||
buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
|
||||
|
||||
/* this sequence is required to unlock the chip */
|
||||
rtc_write(X1205_REG_SR, X1205_SR_WEL);
|
||||
rtc_write(X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL);
|
||||
|
||||
/* write register's data */
|
||||
for (i = 0; i < 8; i++)
|
||||
rtc_write(X1205_CCR_BASE + i, buf[i]);
|
||||
|
||||
rtc_write(X1205_REG_SR, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtc_reset(void)
|
||||
{
|
||||
/*
|
||||
* Nothing to do
|
||||
*/
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user