void init_8250(unsigned channel, const char *init, const char *defaults) { unsigned long baud; unsigned long div; unsigned long clk; paddr_t base; unsigned shift; baud = 0; parse_line(channel, defaults, &baud, &clk, &div); parse_line(channel, init, &baud, &clk, &div); base = dbg_device[channel].base; shift = dbg_device[channel].shift; chip_access(base, shift, 0, REG_MS); // Wait for all pending characters to be output... do { } while(!(chip_read8(REG_LS) & LSR_TSRE)); if(baud != 0) { unsigned count = clk / (baud * div); // Program divisor latch chip_write8(REG_LC, LCR_DLAB); chip_write8(REG_DL0, count & 0xff); chip_write8(REG_DL1, count >> 8); chip_write8(REG_LC, 0x03); }
static void cmos_set(unsigned i, unsigned d) { _disable(); chip_write8(0,i); chip_write8(1,d); _enable(); }
int RTCFUNC(get,ds1386)(struct tm *tm, int cent_reg) { unsigned cent; unsigned sec; unsigned min; unsigned hour; unsigned mday; unsigned mon; unsigned year; if(!(chip_read8(CMD_REG) & TRANSFER_ENABLE)) { struct timespec cur; chip_write8(CMD_REG, chip_read8(CMD_REG) | TRANSFER_ENABLE); cur.tv_sec = 0; cur.tv_nsec = 10000000; nanosleep(&cur, NULL); /* wait 0.01 sec for update */ } chip_write8(CMD_REG, chip_read8(CMD_REG) & ~TRANSFER_ENABLE); // convert BCD to binary sec = chip_read8(1); // seconds min = chip_read8(2); // minutes hour = chip_read8(4) & 0x3f; // hours mday = chip_read8(8); // day mon = chip_read8(9) & 0x3f; // month year = chip_read8(10); // year tm->tm_sec = BCD2BIN(sec); tm->tm_min = BCD2BIN(min); tm->tm_hour = BCD2BIN(hour); tm->tm_mday = BCD2BIN(mday); tm->tm_mon = BCD2BIN(mon) - 1; tm->tm_year = BCD2BIN(year); if(cent_reg >= 0) { cent = chip_read8(cent_reg); // century cent = BCD2BIN(cent); if(cent == 20) tm->tm_year += 100; } else if(tm->tm_year < 70) { tm->tm_year += 100; } chip_write8(CMD_REG, chip_read8(CMD_REG) | TRANSFER_ENABLE); #ifdef DIAG fprintf(stderr,"rtc read: cent=%d; year=%d\n",cent,tm->tm_year); #endif return(0); }
int RTCFUNC(get,ds15x1)(struct tm *tm, int cent_reg) { unsigned cent; unsigned sec; unsigned min; unsigned hour; unsigned mday; unsigned mon; unsigned year; unsigned ctrlb; ctrlb = chip_read8(DS15x1_CONTROLB); if (!(ctrlb & TRANSFER_ENABLE)) { struct timespec cur; chip_write8(DS15x1_CONTROLB, ctrlb | TRANSFER_ENABLE); cur.tv_sec = 0; cur.tv_nsec = 10000000; nanosleep(&cur, NULL); /* wait 0.01 sec for update */ } chip_write8(DS15x1_CONTROLB, ctrlb & ~TRANSFER_ENABLE); /* convert BCD to binary */ sec = chip_read8(0); min = chip_read8(1); hour = chip_read8(2); mday = chip_read8(4); mon = chip_read8(5) & 0x1F; year = chip_read8(6); tm->tm_sec = BCD2BIN(sec); tm->tm_min = BCD2BIN(min); tm->tm_hour = BCD2BIN(hour); tm->tm_mday = BCD2BIN(mday); tm->tm_mon = BCD2BIN(mon) - 1; tm->tm_year = BCD2BIN(year); if (cent_reg >= 0) { cent = chip_read8(cent_reg); /* century */ if (cent == 0x20) tm->tm_year += 100; } else if (tm->tm_year < 70) tm->tm_year += 100; chip_write8(DS15x1_CONTROLB, ctrlb | TRANSFER_ENABLE); #ifdef DIAG fprintf(stderr,"rtc read: cent=%d; year=%d\n",cent,tm->tm_year); #endif return(0); }
unsigned long rtc_time_s3c2410(unsigned base) { struct tm tm; hwi_add_device(HWI_ITEM_BUS_UNKNOWN, HWI_ITEM_DEVCLASS_RTC, "s3c2410", 0); hwi_add_location(base, S3C2410_RTC_SIZE, 0, hwi_find_as(base, 1)); // get the current time from the RTC, and convert it to seconds since epoch chip_access(base, 0, 0, S3C2410_RTC_SIZE); // enable RTC chip_write8(S3C2410_RTCCON, chip_read8(S3C2410_RTCCON) | 1); // convert BCD to binary tm.tm_sec = bcd2bin(chip_read8(S3C2410_BCDSEC) & 0xff); // seconds tm.tm_min = bcd2bin(chip_read8(S3C2410_BCDMIN) & 0xff); // minutes tm.tm_hour = bcd2bin(chip_read8(S3C2410_BCDHOUR) & 0xff); // hours tm.tm_mday = bcd2bin(chip_read8(S3C2410_BCDDAY) & 0xff); // day tm.tm_mon = bcd2bin(chip_read8(S3C2410_BCDMON) & 0xff) -1; // month tm.tm_year = (bcd2bin(chip_read8(S3C2410_BCDYEAR) & 0xff))+100; // year chip_done(); return(calc_time_t(&tm)); }
static unsigned cmos(unsigned i) { unsigned temp; _disable(); chip_write8(0,i); temp = chip_read8(1); _enable(); return(temp); }
unsigned long rtc_time_ds1743(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned cent; unsigned reg; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("ds1743", base, reg_shift, DS1743_YEAR+1, mmap, -1); chip_access(base, reg_shift, mmap, DS1743_YEAR+1); // Stop the chip from updating chip_write8(DS1743_CONTROL, chip_read8(DS1743_CONTROL) | DS1743_CONTROL_R); reg = chip_read8(DS1743_SECONDS); if(reg & DS1743_SECONDS_OSC) { // clock oscillator not running chip_write8(DS1743_SECONDS, reg & ~DS1743_SECONDS_OSC); } reg = chip_read8(DS1743_DAY); if(reg & DS1743_DAY_FT) { // need to turn off frequency test mode chip_write8(DS1743_DAY, reg & ~DS1743_DAY_FT); } // convert BCD to binary tm.tm_sec = bcd2bin(chip_read8(DS1743_SECONDS) & DS1743_SECONDS_MASK); tm.tm_min = bcd2bin(chip_read8(DS1743_MINUTES) & DS1743_MINUTES_MASK); tm.tm_hour = bcd2bin(chip_read8(DS1743_HOUR) & DS1743_HOUR_MASK); tm.tm_mday = bcd2bin(chip_read8(DS1743_DATE) & DS1743_DATE_MASK); tm.tm_mon = bcd2bin(chip_read8(DS1743_MONTH) & DS1743_MONTH_MASK) - 1; tm.tm_year = bcd2bin(chip_read8(DS1743_YEAR)); cent = bcd2bin(chip_read8(DS1743_CONTROL) & DS1743_CONTROL_CENT_MASK); // Start the chip updating again chip_write8(DS1743_CONTROL, chip_read8(DS1743_CONTROL) & ~DS1743_CONTROL_R); tm.tm_year += (cent-19) * 100; chip_done(); return(calc_time_t(&tm)); }
int RTCFUNC(set,ds15x1)(struct tm *tm, int cent_reg) { unsigned seconds; unsigned minutes; unsigned hours; unsigned day; unsigned month; unsigned year; unsigned cent; unsigned ctrlb; /* convert binary to BCD */ seconds = BIN2BCD(tm->tm_sec); minutes = BIN2BCD(tm->tm_min); hours = BIN2BCD(tm->tm_hour); day = BIN2BCD(tm->tm_mday); month = BIN2BCD(tm->tm_mon + 1); year = BIN2BCD(tm->tm_year % 100); cent = BIN2BCD((tm->tm_year / 100) + 19); #ifdef DIAG fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year); #endif month |= chip_read8(5) & 0xE0; /* EOSC#/E32K#/BB32 */ ctrlb = chip_read8(DS15x1_CONTROLB); chip_write8(DS15x1_CONTROLB, ctrlb & ~TRANSFER_ENABLE); chip_write8(0, seconds); chip_write8(1, minutes); chip_write8(2, hours); chip_write8(3, tm->tm_wday + 1); chip_write8(4, day); chip_write8(5, month); chip_write8(6, year); if (cent_reg >= 0) chip_write8(cent_reg, cent); chip_write8(DS15x1_CONTROLB, ctrlb | TRANSFER_ENABLE); return (0); }
int RTCFUNC(set,ds1386)(struct tm *tm, int cent_reg) { unsigned seconds; unsigned minutes; unsigned hours; unsigned day; unsigned month; unsigned year; unsigned cent; // convert binary to BCD seconds = BIN2BCD(tm->tm_sec); minutes = BIN2BCD(tm->tm_min); hours = BIN2BCD(tm->tm_hour); day = BIN2BCD(tm->tm_mday); month = BIN2BCD(tm->tm_mon + 1); year = BIN2BCD(tm->tm_year % 100); cent = BIN2BCD((tm->tm_year / 100) + 19); #ifdef DIAG fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year); #endif month |= chip_read8(9) & 0x40; /* ESQW# */ chip_write8(9, 0); /* turn off clock */ chip_write8(0, 0); //hundredth's of second chip_write8(1, seconds); chip_write8(2, minutes); chip_write8(4, hours | MILTIME); chip_write8(6, tm->tm_wday + 1); chip_write8(8, day); chip_write8(10, year); if(cent_reg >= 0) { chip_write8(cent_reg, cent); } chip_write8(9, month & 0x5f); /* EOSC# low to start clock */ chip_write8(CMD_REG, chip_read8(CMD_REG) | TRANSFER_ENABLE); return(0); }
int RTCFUNC(get,mc146818)(struct tm *tm, int cent_reg) { unsigned x = 0; unsigned count; unsigned clk_buf[2][7]; int z; x = cmos(REG_A); if ((x & 0x60) != 0x20) { chip_write8 (1, (x | 0x60)); //Check for ATI IXP200 RTC - these bits are reserved if ((cmos(REG_A) & 0x60) != 0) { chip_write8 (1, x); //restore old value return(-1); } } memset(clk_buf, 0, sizeof(clk_buf)); //Make sure the UIP turns on at some time. for(x = 0, z = 1 ; (z <= 2) && !(x & 0x0080) ; z++) { for(count=CMOS_CNT ; !(x & 0x0080) && count ; count--) { x = cmos(REG_A); } } for( ;; ) { //Make sure the UIP bit is off. for(x=0x080, count = CMOS_CNT ; (x & 0x0080) && count ; count--) { x = cmos(REG_A); } if(count == 0) { fprintf( stderr, "RTC: cannot read AT clock\n"); return(-1); } clk_buf[0][0] = cmos(0); /* seconds */ clk_buf[0][1] = cmos(2); /* minutes */ clk_buf[0][2] = cmos(4); /* hours */ clk_buf[0][3] = cmos(7); /* day */ clk_buf[0][4] = cmos(8); /* month */ clk_buf[0][5] = cmos(9); /* year */ if (cent_reg >= 0) { clk_buf[0][6] = cmos(cent_reg); /* century */ } x = cmos(REG_B); if(memcmp(clk_buf[0], clk_buf[1], sizeof(clk_buf[0])) == 0) break; memcpy(clk_buf[1], clk_buf[0], sizeof(clk_buf[0])); } if(!(x & BIN)) { clk_buf[0][0] = BCD2BIN(clk_buf[0][0]); clk_buf[0][1] = BCD2BIN(clk_buf[0][1]); clk_buf[0][2] = BCD2BIN(clk_buf[0][2] & 0x7f); clk_buf[0][3] = BCD2BIN(clk_buf[0][3]); clk_buf[0][4] = BCD2BIN(clk_buf[0][4]); clk_buf[0][5] = BCD2BIN(clk_buf[0][5]); clk_buf[0][6] = BCD2BIN(clk_buf[0][6]); } tm->tm_sec = clk_buf[0][0]; tm->tm_min = clk_buf[0][1]; tm->tm_hour = clk_buf[0][2] & 0x7f; if (!(x & H2412) && (clk_buf[1][2] & 0x80)) { /* 12 hour format, PM */ tm->tm_hour += 12; } tm->tm_mday = clk_buf[0][3]; tm->tm_mon = clk_buf[0][4] - 1; tm->tm_year = clk_buf[0][5]; #ifdef VERBOSE_SUPPORTED /* print diagnostics on read if double -v (-vv) specified */ if (verbose>1) { fprintf(stdout,"cmos(0) seconds=%d\n",tm->tm_sec); fprintf(stdout,"cmos(2) minutes=%d\n",tm->tm_min); fprintf(stdout,"cmos(4) hour =%d\n",tm->tm_hour); fprintf(stdout,"cmos(7) day =%d\n",tm->tm_mday); fprintf(stdout,"cmos(8) month =%d\n",tm->tm_mon + 1); fprintf(stdout,"cmos(9) year =%d\n",tm->tm_year); fprintf(stdout,"(unused: cmos(50) century = %d)\n",clk_buf[0][6]); } #endif if (cent_reg >= 0) { if ( clk_buf[0][6] ) tm->tm_year += 100; } else if (tm->tm_year < 70) { tm->tm_year += 100; } return(0); }
unsigned long rtc_time_mc146818(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned save_hour; unsigned reg_b; unsigned cent; unsigned char sra; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("mc146818", base, reg_shift, 2, mmap, cent_reg); chip_access(base, reg_shift, mmap, 2); // bail if the clock is not running. sra = rdcmos(MC146818_SRA); if ((sra & 0x60) != 0x20) { chip_write8 (1, (sra | 0x60)); //Check for ATI IXP200 RTC - these bits are reserved if ((rdcmos(MC146818_SRA) & 0x60) != 0) { chip_write8 (1, sra); //restore old value return(0L); } } reg_b = rdcmos(MC146818_SRB); do { tm.tm_sec = rdcmos(0); tm.tm_min = rdcmos(2); tm.tm_hour = rdcmos(4); tm.tm_mday = rdcmos(7); tm.tm_mon = rdcmos(8); tm.tm_year = rdcmos(9); //Loop while time inconsistent } while(tm.tm_sec != rdcmos(0)); chip_done(); save_hour = tm.tm_hour; tm.tm_hour &= ~0x80; if(!(reg_b & MC146818_SRB_DM)) { tm.tm_sec = bcd2bin(tm.tm_sec); tm.tm_min = bcd2bin(tm.tm_min); tm.tm_hour = bcd2bin(tm.tm_hour); tm.tm_mday = bcd2bin(tm.tm_mday); tm.tm_mon = bcd2bin(tm.tm_mon); tm.tm_year = bcd2bin(tm.tm_year); } if(!(reg_b & MC146818_SRB_24_12) && (save_hour & 0x80)) { //12 hour format & past 12pm tm.tm_hour += 12; } tm.tm_mon -= 1; if(cent_reg >= 0) { cent = rdcmos(cent_reg); //century if(!(reg_b & MC146818_SRB_DM)) { cent = bcd2bin(cent_reg); } if(cent == 20) tm.tm_year += 100; } else if(tm.tm_year < 70) { tm.tm_year += 100; //21st century. } return(calc_time_t(&tm)); }
static int rdcmos(unsigned i) { chip_write8(0, i); //CMOS addr reg return(chip_read8(1)); //CMOS data reg }