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);
    }
Beispiel #2
0
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);
}
Beispiel #4
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);
}
Beispiel #5
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));

}
Beispiel #6
0
static	unsigned
cmos(unsigned i) {
	unsigned temp;

	_disable();		
	chip_write8(0,i);
	temp = chip_read8(1);
	_enable();		
	return(temp);
}
Beispiel #7
0
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));
}
Beispiel #8
0
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);
}
Beispiel #10
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);
}
Beispiel #11
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));
}
Beispiel #12
0
static int
rdcmos(unsigned i) {
	chip_write8(0, i);			//CMOS addr reg
	return(chip_read8(1));		//CMOS data reg
}