mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport
This commit is contained in:
parent
e910436a7a
commit
46837ec4c0
9459 changed files with 362648 additions and 116345 deletions
332
common/package/utils/sysupgrade-helper/src/drivers/rtc/ds1302.c
Normal file
332
common/package/utils/sysupgrade-helper/src/drivers/rtc/ds1302.c
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
#if defined(CONFIG_CMD_DATE)
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue