예제 #1
0
void
sh_rtc_set(void *cookie, struct clock_ymdhms *dt)
{
	uint8_t r;

	/* stop clock */
	r = _reg_read_1(SH_(RCR2));
	r |= SH_RCR2_RESET;
	r &= ~SH_RCR2_START;
	_reg_write_1(SH_(RCR2), r);

	/* set time */
	if (CPU_IS_SH3)
		_reg_write_1(SH3_RYRCNT, TOBCD(dt->dt_year % 100));
	else
		_reg_write_2(SH4_RYRCNT, TOBCD(dt->dt_year % 100));
#define	RTCSET(x, y)	_reg_write_1(SH_(R ## x ## CNT), TOBCD(dt->dt_ ## y))
	RTCSET(MON, mon);
	RTCSET(WK, wday);
	RTCSET(DAY, day);
	RTCSET(HR, hour);
	RTCSET(MIN, min);
	RTCSET(SEC, sec);
#undef RTCSET
	/* start clock */
	_reg_write_1(SH_(RCR2), r | SH_RCR2_START);
}
예제 #2
0
static int
pcfrtc_clock_write(struct pcfrtc_softc *sc, struct clock_ymdhms *dt,
    uint8_t centi)
{
	uint8_t bcd[10], cmdbuf[2];
	int i, err;

	/*
	 * Convert our time representation into something the PCF8583
	 * can understand.
	 */
	bcd[PCF8583_REG_CENTI]    = centi;
	bcd[PCF8583_REG_SEC]      = TOBCD(dt->dt_sec);
	bcd[PCF8583_REG_MIN]      = TOBCD(dt->dt_min);
	bcd[PCF8583_REG_HOUR]     = TOBCD(dt->dt_hour) & PCF8583_HOUR_MASK;
	bcd[PCF8583_REG_YEARDATE] = TOBCD(dt->dt_day) |
	    ((dt->dt_year % 4) << PCF8583_YEAR_SHIFT);
	bcd[PCF8583_REG_WKDYMON]  = TOBCD(dt->dt_mon) |
	    ((dt->dt_wday % 4) << PCF8583_WKDY_SHIFT);
	bcd[8]                    = dt->dt_year % 100;
	bcd[9]                    = dt->dt_year / 100;

	if ((err = iic_acquire_bus(sc->sc_tag, I2C_F_POLL))) {
		aprint_error_dev(sc->sc_dev,
		    "pcfrtc_clock_write: failed to acquire I2C bus\n");
		return err;
	}

	for (i = 1; i < 10; i++) {
		cmdbuf[0] = pcf8583_rtc_offset[i];
		if ((err = iic_exec(sc->sc_tag,
			     i != 9 ? I2C_OP_WRITE : I2C_OP_WRITE_WITH_STOP,
			     sc->sc_address, cmdbuf, 1,
			     &bcd[i], 1, I2C_F_POLL))) {
			iic_release_bus(sc->sc_tag, I2C_F_POLL);
			aprint_error_dev(sc->sc_dev,
			    "pcfrtc_clock_write: failed to write rtc "
			    " at 0x%x\n",
			    pcf8583_rtc_offset[i]);
			return err;
		}
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return 0;
}
예제 #3
0
파일: rtc.c 프로젝트: edgar-pek/PerspicuOS
static int
mv_rtc_settime(device_t dev, struct timespec *ts)
{
	struct clocktime ct;
	struct mv_rtc_softc *sc;
	uint32_t val;

	sc = device_get_softc(dev);

	/* Resolution: 1 sec */
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);

	val = TOBCD(ct.sec) | (TOBCD(ct.min) << 8) |
	    (TOBCD(ct.hour) << 16) | (TOBCD( ct.dow + 1) << 24);
	mv_rtc_reg_write(sc, MV_RTC_TIME_REG, val);

	val = TOBCD(ct.day) | (TOBCD(ct.mon) << 8) |
	    (TOBCD(ct.year - YEAR_BASE) << 16);
	mv_rtc_reg_write(sc, MV_RTC_DATE_REG, val);

	return (0);
}
예제 #4
0
static int
omaprtc_settime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
	struct omaprtc_softc *sc = tch->cookie;
	int s;

	s = disable_interrupts(I32_bit);

	while (rtc_is_busy()) {
		;
	}

	/* It's ok to write these without stopping the
	 * RTC, because the BUSY mechanism lets us guarantee
	 * that we're not in the middle of, e.g., rolling
	 * seconds into minutes.
	 */

	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  YEARS_REG, TOBCD(dt->dt_year - BASEYEAR));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  MONTHS_REG, TOBCD(dt->dt_mon));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  WEEKS_REG, TOBCD(dt->dt_wday & 0x0f));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  DAYS_REG, TOBCD(dt->dt_day));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  SECONDS_REG, TOBCD(dt->dt_sec));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  HOURS_REG, TOBCD(dt->dt_hour));
	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
			  MINUTES_REG, TOBCD(dt->dt_min));
	restore_interrupts(s);
        return 0;
}
예제 #5
0
static int
pcf8563rtc_clock_write(struct pcf8563rtc_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[PCF8563_NREGS];
	uint8_t reg = PCF8563_R_SECOND;

	bcd[PCF8563_R_SECOND] = TOBCD(dt->dt_sec);
	bcd[PCF8563_R_MINUTE] = TOBCD(dt->dt_min);
	bcd[PCF8563_R_HOUR] = TOBCD(dt->dt_hour);
	bcd[PCF8563_R_DAY] = TOBCD(dt->dt_day);
	bcd[PCF8563_R_WEEKDAY] = TOBCD(dt->dt_wday);
	bcd[PCF8563_R_MONTH] = TOBCD(dt->dt_mon);
	bcd[PCF8563_R_YEAR] = TOBCD(dt->dt_year % 100);

	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
		device_printf(sc->sc_dev, "acquire bus for write failed\n");
		return 0;
	}

	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, &reg, 1,
		     &bcd[reg], PCF8563_R_YEAR - reg + 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		device_printf(sc->sc_dev, "write failed\n");
		return 0;
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return 1;
}
예제 #6
0
int
ricohrtc_clock_write(struct ricohrtc_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[RICOHRTC_NRTC_REGS];
	uint8_t cmd;

	/*
	 * Convert our time representation into something the RICOHRTC
	 * can understand.
	 */
	bcd[RICOHRTC_SECONDS] = TOBCD(dt->dt_sec);
	bcd[RICOHRTC_MINUTES] = TOBCD(dt->dt_min);
	bcd[RICOHRTC_HOURS] = TOBCD(dt->dt_hour);
	bcd[RICOHRTC_DATE] = TOBCD(dt->dt_day);
	bcd[RICOHRTC_DAY] = TOBCD(dt->dt_wday);
	bcd[RICOHRTC_MONTH] = TOBCD(dt->dt_mon);
	bcd[RICOHRTC_YEAR] = TOBCD(dt->dt_year - POSIX_BASE_YEAR);

	iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
	cmd = (RICOHRTC_SECONDS << 4);
	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address,
	    &cmd, sizeof cmd, bcd, RICOHRTC_NRTC_REGS, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		printf("%s: ricohrtc_clock_write: failed to write rtc\n",
		    sc->sc_dev.dv_xname);
		return (0);
	}
	iic_release_bus(sc->sc_tag, I2C_F_POLL);
	return (1);
}
예제 #7
0
/*
 * Reset the TODR based on the time value.
 */
static int
dsclock_settime_ymdhms(struct todr_chip_handle *todrch, struct clock_ymdhms *dt)
{
	struct dsclock_softc *sc = todrch->cookie;
	ds1286_todregs regs;
	int s;

	s = splhigh();
	DS1286_GETTOD(sc, &regs);
	splx(s);

	regs[DS1286_SUBSEC] = 0;
	regs[DS1286_SEC] = TOBCD(dt->dt_sec);
	regs[DS1286_MIN] = TOBCD(dt->dt_min);
	regs[DS1286_HOUR] = TOBCD(dt->dt_hour) & DS1286_HOUR_24HR_MASK;
	regs[DS1286_DOW] = TOBCD(dt->dt_wday);
	regs[DS1286_DOM] = TOBCD(dt->dt_day);

	/* Leave wave-generator bits as set originally */
	regs[DS1286_MONTH] &=  ~DS1286_MONTH_MASK;
	regs[DS1286_MONTH] |=  TOBCD(dt->dt_mon) & DS1286_MONTH_MASK;

	regs[DS1286_YEAR] = TOBCD(TO_IRIX_YEAR(dt->dt_year));

	s = splhigh();
	DS1286_PUTTOD(sc, &regs);
	splx(s);

	return 0;
}
예제 #8
0
static int
rs5c313_todr_settime_ymdhms(todr_chip_handle_t todr, struct clock_ymdhms *dt)
{
	struct rs5c313_softc *sc = todr->cookie;
	int retry;
	int t;
	int s;

	s = splhigh();

	rtc_begin(sc);
	for (retry = 10; retry > 0; --retry) {
		rtc_ce(sc, 1);

		rs5c313_write_reg(sc, RS5C313_CTRL, sc->sc_ctrl[0]);
		if ((rs5c313_read_reg(sc, RS5C313_CTRL) & CTRL_BSY) == 0)
			break;

		rtc_ce(sc, 0);
		delay(1);
	}

	if (retry == 0) {
		splx(s);
		return EIO;
	}

#define	RTCSET(x, y)							     \
	do {								     \
		t = TOBCD(dt->dt_ ## y) & 0xff;				     \
		rs5c313_write_reg(sc, RS5C313_ ## x ## 1, t & 0x0f);	     \
		rs5c313_write_reg(sc, RS5C313_ ## x ## 10, (t >> 4) & 0x0f); \
	} while (/* CONSTCOND */0)

	RTCSET(SEC, sec);
	RTCSET(MIN, min);
	RTCSET(HOUR, hour);
	RTCSET(DAY, day);
	RTCSET(MON, mon);

#undef	RTCSET

	t = dt->dt_year % 100;
	t = TOBCD(t);
	rs5c313_write_reg(sc, RS5C313_YEAR1, t & 0x0f);
	rs5c313_write_reg(sc, RS5C313_YEAR10, (t >> 4) & 0x0f);

	rs5c313_write_reg(sc, RS5C313_WDAY, dt->dt_wday);

	rtc_ce(sc, 0);
	splx(s);

	sc->sc_valid = 1;
	return 0;
}
예제 #9
0
파일: ds1307.c 프로젝트: 2asoft/freebsd
static int
ds1307_settime(device_t dev, struct timespec *ts)
{
	int error;
	struct clocktime ct;
	struct ds1307_softc *sc;
	uint8_t data[8];

	sc = device_get_softc(dev);
	/* Accuracy is only one second. */
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);
	memset(data, 0, sizeof(data));
	data[0] = DS1307_SECS;
	data[DS1307_SECS + 1] = TOBCD(ct.sec);
	data[DS1307_MINS + 1] = TOBCD(ct.min);
	data[DS1307_HOUR + 1] = TOBCD(ct.hour);
	data[DS1307_DATE + 1] = TOBCD(ct.day);
	data[DS1307_WEEKDAY + 1] = ct.dow;
	data[DS1307_MONTH + 1] = TOBCD(ct.mon);
	data[DS1307_YEAR + 1] = TOBCD(ct.year % 100);
	/* Write the time back to RTC. */
	error = ds1307_write(dev, sc->sc_addr, data, sizeof(data));
	if (error != 0)
		device_printf(dev, "cannot write to RTC.\n");

	return (error);
}
예제 #10
0
static int
pcf2123_rtc_settime(device_t dev, struct timespec *ts)
{
    struct clocktime ct;
    struct pcf2123_rtc_softc *sc;
    struct spi_command cmd;
    unsigned char rxTimedate[8];
    unsigned char txTimedate[8];
    int err;

    sc = device_get_softc(dev);

    /* Resolution: 1 sec */
    if (ts->tv_nsec >= 500000000)
        ts->tv_sec++;
    ts->tv_nsec = 0;
    clock_ts_to_ct(ts, &ct);

    memset(&cmd, 0, sizeof(cmd));
    memset(rxTimedate, 0, sizeof(rxTimedate));
    memset(txTimedate, 0, sizeof(txTimedate));

    /* Start reading from seconds */
    cmd.rx_cmd = rxTimedate;
    cmd.tx_cmd = txTimedate;
    cmd.rx_cmd_sz = sizeof(rxTimedate);
    cmd.tx_cmd_sz = sizeof(txTimedate);

    /*
     * Counter is stopped when access to time registers is in progress
     * So there is no need to stop/start counter
     */
    txTimedate[0] = PCF2123_WRITE(PCF2123_REG_SECONDS);
    txTimedate[1] = TOBCD(ct.sec);
    txTimedate[2] = TOBCD(ct.min);
    txTimedate[3] = TOBCD(ct.hour);
    txTimedate[4] = TOBCD(ct.day);
    txTimedate[5] = TOBCD(ct.dow);
    txTimedate[6] = TOBCD(ct.mon);
    txTimedate[7] = TOBCD(ct.year - YEAR_BASE);

    err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd);
    DELAY(PCF2123_DELAY);

    return (err);
}
예제 #11
0
/*
 * Set the time of day clock based on the value of the struct timespec arg.
 * Return 0 on success, an error number otherwise.
 */
int
ds1553_settime(device_t dev, struct timespec *ts)
{
	struct clocktime ct;
	struct ds1553_softc *sc;
	uint8_t control;

	sc = device_get_softc(dev);
	bzero(&ct, sizeof(struct clocktime));

	/* Accuracy is only one second. */
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);

	ct.year -= sc->year_offset;

	mtx_lock_spin(&sc->sc_mtx);

	/* Halt updates to external registers */
	control = (*sc->sc_read)(dev, DS1553_OFF_CONTROL) | DS1553_BIT_WRITE;
	(*sc->sc_write)(dev, DS1553_OFF_CONTROL, control);

	(*sc->sc_write)(dev, DS1553_OFF_SECONDS, TOBCD(ct.sec) &
	    DS1553_MASK_SECONDS);
	(*sc->sc_write)(dev, DS1553_OFF_MINUTES, TOBCD(ct.min) &
	    DS1553_MASK_MINUTES);
	(*sc->sc_write)(dev, DS1553_OFF_HOURS, TOBCD(ct.hour) &
	    DS1553_MASK_HOUR);
	(*sc->sc_write)(dev, DS1553_OFF_DAYOFWEEK, TOBCD(ct.dow + 1) &
	    DS1553_MASK_DAYOFWEEK);
	(*sc->sc_write)(dev, DS1553_OFF_DATE, TOBCD(ct.day) &
	    DS1553_MASK_DATE);
	(*sc->sc_write)(dev, DS1553_OFF_MONTH, TOBCD(ct.mon) &
	    DS1553_MASK_MONTH);
	(*sc->sc_write)(dev, DS1553_OFF_YEAR, TOBCD(ct.year));

	/* Resume updates to external registers */
	control &= ~DS1553_BIT_WRITE;
	(*sc->sc_write)(dev, DS1553_OFF_CONTROL, control);

	mtx_unlock_spin(&sc->sc_mtx);

	return (0);
}
예제 #12
0
파일: mcclock_mace.c 프로젝트: MarginC/kame
static void
mcclock_mace_set(struct device *dev, struct clock_ymdhms *dt)
{
	struct mcclock_mace_softc *sc = (struct mcclock_mace_softc *)dev;
	ds1687_todregs regs;
	int s;

	memset(&regs, 0, sizeof(regs));

	regs[DS1687_SOFT_SEC] = TOBCD(dt->dt_sec);
	regs[DS1687_SOFT_MIN] = TOBCD(dt->dt_min);
	regs[DS1687_SOFT_HOUR] = TOBCD(dt->dt_hour);
	regs[DS1687_SOFT_DOW] = TOBCD(dt->dt_wday);
	regs[DS1687_SOFT_DOM] = TOBCD(dt->dt_day);
	regs[DS1687_SOFT_MONTH] = TOBCD(dt->dt_mon);
	regs[DS1687_SOFT_YEAR] = TOBCD(dt->dt_year % 100);
	regs[DS1687_SOFT_CENTURY] = TOBCD(dt->dt_year / 100);
	s = splhigh();
	DS1687_PUTTOD(sc, &regs);
	splx(s);
}
예제 #13
0
static int
mcclock_mace_settime_ymdhms(todr_chip_handle_t todrch, struct clock_ymdhms *dt)
{
	struct mcclock_mace_softc *sc = todrch->cookie;
	ds1687_todregs regs;
	int s;

	memset(&regs, 0, sizeof(regs));

	regs[DS1687_SOFT_SEC] = TOBCD(dt->dt_sec);
	regs[DS1687_SOFT_MIN] = TOBCD(dt->dt_min);
	regs[DS1687_SOFT_HOUR] = TOBCD(dt->dt_hour);
	regs[DS1687_SOFT_DOW] = TOBCD(dt->dt_wday);
	regs[DS1687_SOFT_DOM] = TOBCD(dt->dt_day);
	regs[DS1687_SOFT_MONTH] = TOBCD(dt->dt_mon);
	regs[DS1687_SOFT_YEAR] = TOBCD(dt->dt_year % 100);
	regs[DS1687_SOFT_CENTURY] = TOBCD(dt->dt_year / 100);
	s = splhigh();
	DS1687_PUTTOD(sc, &regs);
	splx(s);

	return 0;
}
예제 #14
0
static int
dsrtc_write(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
	struct dsrtc_softc *sc = tch->cookie;
	u_char key;

	key = ds1743_lock(sc, DS_CTL_W);
	
	ds1743_write(sc, DS_SECONDS, TOBCD(dt->dt_sec) & 0x7f);
	ds1743_write(sc, DS_MINUTES, TOBCD(dt->dt_min) & 0x7f);
	ds1743_write(sc, DS_HOURS, TOBCD(dt->dt_hour)  & 0x3f);
	ds1743_write(sc, DS_DATE, TOBCD(dt->dt_day)    & 0x3f);
	ds1743_write(sc, DS_MONTH, TOBCD(dt->dt_mon)   & 0x1f);
	ds1743_write(sc, DS_YEAR, TOBCD(dt->dt_year % 100));
	ds1743_write(sc, DS_CENTURY, ((ds1743_read(sc, DS_CENTURY) & DS_CTL_RW)
				      | TOBCD(dt->dt_year / 100)));

	ds1743_unlock(sc, key);
	return(0);
}
예제 #15
0
/*
 * Set the time-of-day clock based on the value of the `struct timeval' arg.
 * Return 0 on success; an error number otherwise.
 */
int
mk48txx_settime_ymdhms(todr_chip_handle_t handle, struct clock_ymdhms *dt)
{
	struct mk48txx_softc *sc;
	bus_size_t clkoff;
	uint8_t csr;
	int year;

	sc = handle->cookie;
	clkoff = sc->sc_clkoffset;

	year = dt->dt_year - sc->sc_year0;
	if (year > 99 &&
	    (sc->sc_flag & MK48TXX_NO_CENT_ADJUST) == 0)
		year -= 100;

	todr_wenable(handle, 1);
	/* enable write */
	csr = (*sc->sc_nvrd)(sc, clkoff + MK48TXX_ICSR);
	csr |= MK48TXX_CSR_WRITE;
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_ICSR, csr);

	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_ISEC, TOBCD(dt->dt_sec));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IMIN, TOBCD(dt->dt_min));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IHOUR, TOBCD(dt->dt_hour));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IWDAY, TOBCD(dt->dt_wday));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IDAY, TOBCD(dt->dt_day));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IMON, TOBCD(dt->dt_mon));
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_IYEAR, TOBCD(year));

	/* load them up */
	csr = (*sc->sc_nvrd)(sc, clkoff + MK48TXX_ICSR);
	csr &= ~MK48TXX_CSR_WRITE;
	(*sc->sc_nvwr)(sc, clkoff + MK48TXX_ICSR, csr);
	todr_wenable(handle, 0);
	return 0;
}
예제 #16
0
static int
rs5c372rtc_clock_write(struct rs5c372rtc_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[RS5C372_NRTC_REGS];
	uint8_t cmdbuf[1];

	/*
	 * Convert our time representation into something the RS5C372
	 * can understand.
	 */
	bcd[RS5C372_SECONDS] = TOBCD(dt->dt_sec);
	bcd[RS5C372_MINUTES] = TOBCD(dt->dt_min);
	bcd[RS5C372_HOURS] = TOBCD(dt->dt_hour);
	bcd[RS5C372_DATE] = TOBCD(dt->dt_day);
	bcd[RS5C372_DAY] = TOBCD(dt->dt_wday);
	bcd[RS5C372_MONTH] = TOBCD(dt->dt_mon);
	bcd[RS5C372_YEAR] = TOBCD(dt->dt_year % 100);

	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
		aprint_error_dev(sc->sc_dev, "rs5c372rtc_clock_write: failed to "
		    "acquire I2C bus\n");
		return (0);
	}

	cmdbuf[0] = (RS5C372_SECONDS << 4);
	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address,
	             cmdbuf, 1, bcd, RS5C372_NRTC_REGS, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "rs5c372rtc_clock_write: failed to write rtc\n");
		return (0);
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return (1);
}
예제 #17
0
static int
s3c2xx0_rtc_settime(device_t dev, struct timespec *ts)
{
	struct s3c2xx0_rtc_softc *sc;
	struct clocktime ct;

	sc = device_get_softc(dev);

	/* Resolution: 1 sec */
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);

	bus_write_1(sc->mem_res, RTC_BCDSEC, TOBCD(ct.sec));
	bus_write_1(sc->mem_res, RTC_BCDMIN, TOBCD(ct.min));
	bus_write_1(sc->mem_res, RTC_BCDHOUR, TOBCD(ct.hour));
	bus_write_1(sc->mem_res, RTC_BCDDATE, TOBCD(ct.day));
	bus_write_1(sc->mem_res, RTC_BCDDAY, TOBCD(ct.dow));
	bus_write_1(sc->mem_res, RTC_BCDMON, TOBCD(ct.mon));
	bus_write_1(sc->mem_res, RTC_BCDYEAR, TOBCD(ct.year - YEAR_BASE));

	return (0);
}
예제 #18
0
파일: pcf8563.c 프로젝트: 2asoft/freebsd
static int
pcf8563_settime(device_t dev, struct timespec *ts)
{
	struct clocktime ct;
	uint8_t val[PCF8563_NCLOCKREGS];
	struct iic_msg msgs[] = {
		{ 0, IIC_M_WR, PCF8563_NCLOCKREGS - 1, &val[PCF8563_R_CS2] }
	};
	struct pcf8563_softc *sc;
	int error;

	sc = device_get_softc(dev);
	val[PCF8563_R_CS2] = PCF8563_R_SECOND;	/* abuse */
	/* Accuracy is only one second. */
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);
	val[PCF8563_R_SECOND] = TOBCD(ct.sec);
	val[PCF8563_R_MINUTE] = TOBCD(ct.min);
	val[PCF8563_R_HOUR] = TOBCD(ct.hour);
	val[PCF8563_R_DAY] = TOBCD(ct.day);
	val[PCF8563_R_WEEKDAY] = ct.dow;
	val[PCF8563_R_MONTH] = TOBCD(ct.mon);
	val[PCF8563_R_YEAR] = TOBCD(ct.year % 100);
	if ((sc->sc_flags & PCF8563_CPOL) != 0) {
		if (ct.year >= 100 + sc->sc_year0)
			val[PCF8563_R_MONTH] |= PCF8563_R_MONTH_C;
	} else if (ct.year < 100 + sc->sc_year0)
			val[PCF8563_R_MONTH] |= PCF8563_R_MONTH_C;

	msgs[0].slave = sc->sc_addr;
	error = iicbus_transfer(dev, msgs, nitems(msgs));
	if (error != 0)
		device_printf(dev, "%s: cannot write RTC\n", __func__);

	return (error);
}
예제 #19
0
파일: llstime.c 프로젝트: doniexun/OrangeC
int __ll_settime(struct tm *tm2)
{
    DPMI_REGS regs;
    int v = tm2->tm_year;
    if (v > 170)
        v -= 100;

      regs.b.dh = TOBCD(tm2->tm_sec) ;
      regs.b.cl = TOBCD(tm2->tm_min) ;
      regs.b.ch = TOBCD(tm2->tm_hour) ;
    regs.b.ah = 3;
    __realint(0x1a,&regs);


      regs.b.dl = TOBCD(tm2->tm_mday);
      regs.b.dh = TOBCD(tm2->tm_mon+1);
      regs.b.cl = TOBCD(v);
    if (tm2->tm_year < 71)
        tm2->tm_year += 100;
    regs.b.ah = 5;
    __realint(0x1a,&regs);
    return 0;
}
예제 #20
0
static int
strtc_clock_write(struct strtc_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[M41ST84_REG_DATE_BYTES], cmdbuf[2];
	int i;

	/*
	 * Convert our time representation into something the M41ST84
	 * can understand.
	 */
	bcd[M41ST84_REG_CSEC] = TOBCD(0);	/* must always write as 0 */
	bcd[M41ST84_REG_SEC] = TOBCD(dt->dt_sec);
	bcd[M41ST84_REG_MIN] = TOBCD(dt->dt_min);
	bcd[M41ST84_REG_CENHR] = TOBCD(dt->dt_hour);
	bcd[M41ST84_REG_DATE] = TOBCD(dt->dt_day);
	bcd[M41ST84_REG_DAY] = TOBCD(dt->dt_wday);
	bcd[M41ST84_REG_MONTH] = TOBCD(dt->dt_mon);
	bcd[M41ST84_REG_YEAR] = TOBCD((dt->dt_year - POSIX_BASE_YEAR) % 100);

	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
		aprint_error_dev(sc->sc_dev,
		    "strtc_clock_write: failed to acquire I2C bus\n");
		return (0);
	}

	/* Stop the clock */
	cmdbuf[0] = M41ST84_REG_SEC;
	cmdbuf[1] = M41ST84_SEC_ST;

	if (iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address,
		     cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "strtc_clock_write: failed to Hold Clock\n");
		return (0);
	}

	/*
	 * Check for the HT bit -- if set, then clock lost power & stopped
	 * If that happened, then clear the bit so that the clock will have
	 * a chance to run again.
	 */
	cmdbuf[0] = M41ST84_REG_AL_HOUR;
	if (iic_exec(sc->sc_tag, I2C_OP_READ, sc->sc_address,
		     cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "strtc_clock_write: failed to read HT\n");
		return (0);
	}
	if (cmdbuf[1] & M41ST84_AL_HOUR_HT) {
		cmdbuf[1] &= ~M41ST84_AL_HOUR_HT;
		if (iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address,
			     cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) {
			iic_release_bus(sc->sc_tag, I2C_F_POLL);
			aprint_error_dev(sc->sc_dev,
			    "strtc_clock_write: failed to reset HT\n");
			return (0);
		}
	}

	/*
	 * Write registers in reverse order. The last write (to the Seconds
	 * register) will undo the Clock Hold, above.
	 */
	for (i = M41ST84_REG_DATE_BYTES - 1; i >= 0; i--) {
		cmdbuf[0] = i;
		if (iic_exec(sc->sc_tag,
			     i ? I2C_OP_WRITE : I2C_OP_WRITE_WITH_STOP,
			     sc->sc_address, cmdbuf, 1, &bcd[i], 1,
			     I2C_F_POLL)) {
			iic_release_bus(sc->sc_tag, I2C_F_POLL);
			aprint_error_dev(sc->sc_dev,
			    "strtc_clock_write: failed to write rtc "
			    " at 0x%x\n", i);
			/* XXX: Clock Hold is likely still asserted! */
			return (0);
		}
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return (1);
}
예제 #21
0
파일: rtc.c 프로젝트: lacombar/netbsd-alc
int
settime_old(todr_chip_handle_t tcr, struct clock_ymdhms *dt)
{
	u_char h;

	/* Stop the clock */
	rtc_write(RTC_CONTROL,rtc_read(RTC_CONTROL) & ~RTC_START);

#ifdef RTC_DEBUG
	printf("Setting RTC to 0x%08x.  Regs before:\n",secs);
	rtc_print();
#endif

	rtc_write(RTC_SEC,TOBCD(dt->dt_sec));
	rtc_write(RTC_MIN,TOBCD(dt->dt_min));
	h = rtc_read(RTC_HRS);
	if (h & 0x80) {		/* time is am/pm format */
		if (dt->dt_hour == 0) {
			rtc_write(RTC_HRS,TOBCD(12)|0x80);
		} else if (dt->dt_hour < 12) {	/* am */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour)|0x80);
		} else if (dt->dt_hour == 12) {
				rtc_write(RTC_HRS,TOBCD(12)|0x80|0x20);
		} else 		/* pm */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour-12)|0x80|0x20);
	} else {	/* time is 24 hour format */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour));
	}
	rtc_write(RTC_DAY,TOBCD(dt->dt_wday));
	rtc_write(RTC_DATE,TOBCD(dt->dt_day));
	rtc_write(RTC_MON,TOBCD(dt->dt_mon));
	rtc_write(RTC_YR,TOBCD(dt->dt_year%100));

#ifdef RTC_DEBUG
	printf("Regs after:\n",secs);
	rtc_print();
#endif

	/* restart the clock */
	rtc_write(RTC_CONTROL,rtc_read(RTC_CONTROL) | RTC_START);
	return 0;
}
예제 #22
0
static int
maxrtc_clock_write(struct maxrtc_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[MAX6900_BURST_LEN], cmdbuf[2];
	uint8_t init_seconds, final_seconds;
	int i;

	/*
	 * Convert our time representation into something the MAX6900
	 * can understand.
	 */
	bcd[MAX6900_BURST_SECOND] = TOBCD(dt->dt_sec);
	bcd[MAX6900_BURST_MINUTE] = TOBCD(dt->dt_min);
	bcd[MAX6900_BURST_HOUR] = TOBCD(dt->dt_hour) & MAX6900_HOUR_24MASK;
	bcd[MAX6900_BURST_DATE] = TOBCD(dt->dt_day);
	bcd[MAX6900_BURST_WDAY] = TOBCD(dt->dt_wday);
	bcd[MAX6900_BURST_MONTH] = TOBCD(dt->dt_mon);
	bcd[MAX6900_BURST_YEAR] = TOBCD(dt->dt_year % 100);
		/* century in control slot */
	bcd[MAX6900_BURST_CONTROL] = TOBCD(dt->dt_year / 100);

	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to acquire I2C bus\n");
		return (0);
	}

	/* Start by clearing the control register's write-protect bit. */
	cmdbuf[0] = MAX6900_REG_CONTROL | MAX6900_CMD_WRITE;
	cmdbuf[1] = 0;

	if (iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address,
		     cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to clear WP bit\n");
		return (0);
	}

	/*
	 * The MAX6900 RTC manual recommends ensuring "atomicity" of
	 * a non-burst write by:
	 *
	 *	- writing SECONDS
	 *	- reading back SECONDS, remembering it as "initial seconds"
	 *	- write the remaing RTC registers
	 *	- read back SECONDS as "final seconds"
	 *	- if "initial seconds" == 59, ensure "final seconds" == 59
	 *	- else, ensure "final seconds" is no more than one second
	 *	  beyond "initial seconds".
	 */
 again:
	cmdbuf[0] = MAX6900_REG_SECOND | MAX6900_CMD_WRITE;
	if (iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address,
		     cmdbuf, 1, &bcd[MAX6900_BURST_SECOND], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to write SECONDS\n");
		return (0);
	}

	cmdbuf[0] = MAX6900_REG_SECOND | MAX6900_CMD_READ;
	if (iic_exec(sc->sc_tag, I2C_OP_READ, sc->sc_address,
		     cmdbuf, 1, &init_seconds, 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to read "
		    "INITIAL SECONDS\n");
		return (0);
	}

	for (i = 1; i < MAX6900_BURST_LEN; i++) {
		cmdbuf[0] = max6900_rtc_offset[i] | MAX6900_CMD_WRITE;
		if (iic_exec(sc->sc_tag,
			     i != MAX6900_BURST_LEN - 1 ? I2C_OP_WRITE :
			     I2C_OP_WRITE_WITH_STOP, sc->sc_address,
			     cmdbuf, 1, &bcd[i], 1, I2C_F_POLL)) {
			iic_release_bus(sc->sc_tag, I2C_F_POLL);
			aprint_error_dev(sc->sc_dev,
			    "maxrtc_clock_write: failed to write rtc "
			    " at 0x%x\n",
			    max6900_rtc_offset[i]);
			return (0);
		}
	}

	cmdbuf[0] = MAX6900_REG_SECOND | MAX6900_CMD_READ;
	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address,
		     cmdbuf, 1, &final_seconds, 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to read "
		    "FINAL SECONDS\n");
		return (0);
	}

	if ((init_seconds == 59 && final_seconds != 59) ||
	    (init_seconds != 59 && final_seconds != init_seconds + 1)) {
#if 1
		printf("%s: maxrtc_clock_write: init %d, final %d, try again\n",
		    device_xname(sc->sc_dev), init_seconds, final_seconds);
#endif
		goto again;
	}

	/* Finish by setting the control register's write-protect bit. */
	cmdbuf[0] = MAX6900_REG_CONTROL | MAX6900_CMD_WRITE;
	cmdbuf[1] = MAX6900_CONTROL_WP;

	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address,
		     cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "maxrtc_clock_write: failed to set WP bit\n");
		return (0);
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return (1);
}
예제 #23
0
static int
m41t00_clock_write(struct m41t00_softc *sc, struct clock_ymdhms *dt)
{
	uint8_t bcd[M41T00_DATE_BYTES], cmdbuf[2];
	uint8_t init_seconds, final_seconds;
	int i;

	/*
	 * Convert our time representation into something the MAX6900
	 * can understand.
	 */
	bcd[M41T00_SEC] = TOBCD(dt->dt_sec);
	bcd[M41T00_MIN] = TOBCD(dt->dt_min);
	bcd[M41T00_CENHR] = TOBCD(dt->dt_hour);
	bcd[M41T00_DATE] = TOBCD(dt->dt_day);
	bcd[M41T00_DAY] = TOBCD(dt->dt_wday);
	bcd[M41T00_MONTH] = TOBCD(dt->dt_mon);
	bcd[M41T00_YEAR] = TOBCD(dt->dt_year % 100);

	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
		aprint_error_dev(sc->sc_dev,
		    "m41t00_clock_write: failed to acquire I2C bus\n");
		return 0;
	}

	/*
	 * The MAX6900 RTC manual recommends ensuring "atomicity" of
	 * a non-burst write by:
	 *
	 *	- writing SECONDS
	 *	- reading back SECONDS, remembering it as "initial seconds"
	 *	- write the remaing RTC registers
	 *	- read back SECONDS as "final seconds"
	 *	- if "initial seconds" == 59, ensure "final seconds" == 59
	 *	- else, ensure "final seconds" is no more than one second
	 *	  beyond "initial seconds".
	 *
	 * This sounds reasonable for the M41T00, too.
	 */
 again:
	cmdbuf[0] = M41T00_SEC;
	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address,
		     cmdbuf, 1, &bcd[M41T00_SEC], 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "m41t00_clock_write: failed to write SECONDS\n");
		return 0;
	}

	cmdbuf[0] = M41T00_SEC;
	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address,
		     cmdbuf, 1, &init_seconds, 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "m41t00_clock_write: failed to read "
		    "INITIAL SECONDS\n");
		return 0;
	}
	init_seconds = FROMBCD(init_seconds & M41T00_SEC_MASK);

	for (i = 1; i < M41T00_DATE_BYTES; i++) {
		cmdbuf[0] = m41t00_rtc_offset[i];
		if (iic_exec(sc->sc_tag,
			     I2C_OP_WRITE_WITH_STOP, sc->sc_address,
			     cmdbuf, 1, &bcd[i], 1, I2C_F_POLL)) {
			iic_release_bus(sc->sc_tag, I2C_F_POLL);
			aprint_error_dev(sc->sc_dev,
			    "m41t00_clock_write: failed to write rtc "
			    " at 0x%x\n",
			    m41t00_rtc_offset[i]);
			return 0;
		}
	}

	cmdbuf[0] = M41T00_SEC;
	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address,
		     cmdbuf, 1, &final_seconds, 1, I2C_F_POLL)) {
		iic_release_bus(sc->sc_tag, I2C_F_POLL);
		aprint_error_dev(sc->sc_dev,
		    "m41t00_clock_write: failed to read "
		    "FINAL SECONDS\n");
		return 0;
	}
	final_seconds = FROMBCD(final_seconds & M41T00_SEC_MASK);

	if ((init_seconds != final_seconds) &&
	    (((init_seconds + 1) % 60) != final_seconds)) {
#if 1
		printf("%s: m41t00_clock_write: init %d, final %d, try again\n",
		    device_xname(sc->sc_dev), init_seconds, final_seconds);
#endif
		goto again;
	}

	iic_release_bus(sc->sc_tag, I2C_F_POLL);

	return 1;
}