示例#1
0
void ds3234_read_time(DS3234_TIME *time) {
	_ds3234_slave_select();
	_ds3234_transfer(0x00); //Seconds register
	uint8_t data = _ds3234_transfer(0x00); //Dummy byte to receive seconds register
	time->seconds = BCD_TO_INT(data);
	data = _ds3234_transfer(0x00); //Dummy byte to burst receive minutes register
	time->minutes = BCD_TO_INT(data);
	data = _ds3234_transfer(0x00); //Dummy byte to burst reveive hours register
	if (data & (1 << 6)) {
		//Register is in 12 hour mode
		//If bit 4 is set (10hr bit) increment hour by 10 (Captain Obvious!)
		time->hours = (data & (1 << 4)) ? (data & 0x0F) + 10 : (data & 0x0F);
		time->ampm_mask = 1;
		time->ampm_mask |= (data & (1 << 5) >> 4); //bit 5 (AM/PM) of date shifted to bit 1 of ampm_mask
	} else {
efi_status_t
ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
{
	if (!nvram_base) {
		printk(KERN_CRIT "nvram_base is zero\n");
		return EFI_UNSUPPORTED;
	}

	memset(time, 0, sizeof(*time));

	switch (tod_chip_type) {
	case TOD_SGS_M48T35:
		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);

		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
		time->nanosecond = 0;

		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
		break;

	case TOD_DALLAS_DS1386:
		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);

		time->nanosecond = 0;
		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;

		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
		break;

	default:
		break;
	}

	if (caps) {
		caps->resolution = 50000000;	/*  50PPM */
		caps->accuracy = 1000;		/*  1ms */
		caps->sets_to_zero = 0;
	}

	return EFI_SUCCESS;
}