Lines Matching +full:report +full:- +full:rate +full:- +full:hz

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
30 * Driver for NXP real-time clock/calendar chips:
31 * - PCF8563 = low power, countdown timer
32 * - PCA8565 = like PCF8563, automotive temperature range
33 * - PCF8523 = low power, countdown timer, oscillator freq tuning, 2 timers
34 * - PCF2127 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, 512B ram
35 * - PCA2129 = like PCF8523, automotive, tcxo, tamper/ts, i2c & spi, (note 1)
36 * - PCF2129 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, (note 1)
100 * PCF2127-specific registers, bits, and masks.
107 #define PCF2127_B_TMR_64HZ 0x01 /* Timer frequency 64Hz */
115 * PCA/PCF2129-specific registers, bits, and masks.
117 #define PCF2129_B_CS1_12HR 0x04 /* Use 12-hour (AM/PM) mode bit */
122 * PCF8523-specific registers, bits, and masks.
134 #define PCF8523_B_CS1_12HR 0x08 /* Use 12-hour (AM/PM) mode bit */
137 #define PCF8523_B_TMR_A_64HZ 0x01 /* Timer A freq 64Hz */
146 * PCF8563-specific registers, bits, and masks.
158 #define PCF8563_B_TMR_64HZ 0x01 /* Timer frequency 64Hz */
163 * We use the countdown timer for fractional seconds. We program it for 64 Hz,
164 * the fastest available rate that doesn't roll over in less than a second.
222 * iicbus_acquire_bus() calls with a non-recursive wait at the entry of our API
229 * We use the compat_data table to look up hint strings in the non-FDT case, so
267 * write the address-within-device, then we read from the device. This in nxprtc_readfrom()
269 * chips we service don't support i2c repeat-start operations (grrrrr) in nxprtc_readfrom()
294 return (nxprtc_readfrom(sc->dev, reg, val, sizeof(*val), WAITFLAGS)); in read_reg()
301 return (iicdev_writeto(sc->dev, reg, &val, sizeof(val), WAITFLAGS)); in write_reg()
317 if (sc->use_timer) { in read_timeregs()
318 if ((err = read_reg(sc, sc->secaddr, &sec)) != 0) in read_timeregs()
320 if ((err = read_reg(sc, sc->tmcaddr, &tmr1)) != 0) in read_timeregs()
322 if ((err = read_reg(sc, sc->tmcaddr, &tmr2)) != 0) in read_timeregs()
327 if ((err = nxprtc_readfrom(sc->dev, sc->secaddr, tregs, in read_timeregs()
330 } while (sc->use_timer && tregs->sec != sec); in read_timeregs()
333 * If the timer value is greater than our hz rate (or is zero), in read_timeregs()
336 * the offset calc below, the zero turns into 32, the mid-second point, in read_timeregs()
338 * to do if we don't have fine-grained time. in read_timeregs()
340 if (!sc->use_timer || tmr1 > TMR_TICKS_SEC) in read_timeregs()
345 * and rolls over at mid-second, so add half a second worth of ticks to in read_timeregs()
348 *tmr = (TMR_TICKS_SEC - tmr1 + TMR_TICKS_HALFSEC) % TMR_TICKS_SEC; in read_timeregs()
357 return (iicdev_writeto(sc->dev, sc->secaddr, tregs, in write_timeregs()
369 /* PPM range [-7,8] maps to reg value range [0,15] */ in freqadj_sysctl()
370 freqppm = newppm = 8 - sc->freqadj; in freqadj_sysctl()
373 if (err != 0 || req->newptr == NULL) in freqadj_sysctl()
376 if (newppm < -7 || newppm > 8) in freqadj_sysctl()
378 sc->freqadj = 8 - newppm; in freqadj_sysctl()
379 err = write_reg(sc, PCF2127_R_AGING_OFFSET, sc->freqadj); in freqadj_sysctl()
394 if (ts.tv_sec < sc->bat_time) in pcf8523_battery_check()
396 sc->bat_time = ts.tv_sec + (60 * 60 * 24); in pcf8523_battery_check()
403 * battery twice as fast" mode. So, we run the chip in direct-switching in pcf8523_battery_check()
407 * battery monitor and using direct-switch mode are required to get the in pcf8523_battery_check()
412 * voltage, then return to the low-power monitor-disabled mode. in pcf8523_battery_check()
416 device_printf(sc->dev, "cannot write CS3 reg\n"); in pcf8523_battery_check()
421 device_printf(sc->dev, "cannot read CS3 reg\n"); in pcf8523_battery_check()
426 device_printf(sc->dev, "cannot write CS3 reg\n"); in pcf8523_battery_check()
431 device_printf(sc->dev, "WARNING: RTC battery is low\n"); in pcf8523_battery_check()
451 if ((err = nxprtc_readfrom(sc->dev, PCF85xx_R_CS1, &csr, in pcf8523_start()
453 device_printf(sc->dev, "cannot read RTC control regs\n"); in pcf8523_start()
459 * - The chip power manager is in battery-disable mode. in pcf8523_start()
460 * - The OS (oscillator stopped) bit is set (all power was lost). in pcf8523_start()
461 * - The clock-increment STOP flag is set (this is just insane). in pcf8523_start()
465 device_printf(sc->dev, in pcf8523_start()
470 * - Turn off the POR-Override bit (used for mfg test only), in pcf8523_start()
472 * - Turn off the timestamp option to save the power used to in pcf8523_start()
474 * - Trigger OTP refresh by forcing the OTPR bit to zero then in pcf8523_start()
477 if (sc->is212x) { in pcf8523_start()
480 device_printf(sc->dev, in pcf8523_start()
487 device_printf(sc->dev, in pcf8523_start()
498 device_printf(sc->dev, in pcf8523_start()
506 /* All chips: set clock output pin to high-z to save power */ in pcf8523_start()
508 device_printf(sc->dev, "cannot write CLKOUT control\n"); in pcf8523_start()
514 * Check the battery voltage and report if it's low. This also has the in pcf8523_start()
515 * side effect of (re-)initializing the power manager to low-power mode in pcf8523_start()
522 * 24-hour mode, but if we're co-existing with some other OS that in pcf8523_start()
528 if (sc->is212x) { in pcf8523_start()
530 sc->use_ampm = true; in pcf8523_start()
534 device_printf(sc->dev, in pcf8523_start()
538 sc->freqadj = (int8_t)freqadj; in pcf8523_start()
540 ctx = device_get_sysctl_ctx(sc->dev); in pcf8523_start()
541 tree = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)); in pcf8523_start()
545 freqadj_sysctl, "I", "Frequency adjust in PPM, range [-7,+8]"); in pcf8523_start()
548 sc->use_ampm = true; in pcf8523_start()
575 if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0) in pcf8523_start_timer()
604 if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0) in pcf2127_start_timer()
623 if ((err = nxprtc_readfrom(sc->dev, PCF85xx_R_CS1, &csr, in pcf8563_start()
625 device_printf(sc->dev, "cannot read RTC control regs\n"); in pcf8563_start()
631 * - The OS (oscillator stopped) bit is set (all power was lost). This in pcf8563_start()
633 * - The clock-increment STOP flag is set (this is just insane). in pcf8563_start()
636 device_printf(sc->dev, in pcf8563_start()
639 * - Turn off the POR-Override bit (used for mfg test only), by in pcf8563_start()
641 * - Turn off the clock output pin (to save battery power), by in pcf8563_start()
645 device_printf(sc->dev, "cannot write CS1 reg\n"); in pcf8563_start()
650 device_printf(sc->dev, "cannot write CS1 reg\n"); in pcf8563_start()
671 if ((err = write_reg(sc, sc->tmcaddr, 0)) != 0) in pcf8563_start_timer()
686 config_intrhook_disestablish(&sc->config_hook); in nxprtc_start()
688 /* First do chip-specific inits. */ in nxprtc_start()
689 switch (sc->chiptype) { in nxprtc_start()
693 sc->is212x = true; in nxprtc_start()
697 device_printf(sc->dev, "cannot set up timer\n"); in nxprtc_start()
705 device_printf(sc->dev, "cannot set up timer\n"); in nxprtc_start()
714 device_printf(sc->dev, "cannot set up timer\n"); in nxprtc_start()
719 device_printf(sc->dev, "missing init code for this chiptype\n"); in nxprtc_start()
730 * to the mid-second point when you set the time and it takes about 5ms in nxprtc_start()
733 resolution = sc->use_timer ? 1000000 / TMR_TICKS_SEC : 1000000 / 2; in nxprtc_start()
735 clock_register_flags(sc->dev, resolution, clockflags); in nxprtc_start()
736 clock_schedule(sc->dev, 495000000); in nxprtc_start()
751 * Read the time, but before using it, validate that the oscillator- in nxprtc_gettime()
752 * stopped/power-fail bit is not set, and that the time-increment STOP in nxprtc_gettime()
756 if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) == 0) { in nxprtc_gettime()
760 iicbus_release_bus(sc->busdev, sc->dev); in nxprtc_gettime()
770 if (sc->use_ampm) in nxprtc_gettime()
787 * but we may co-exist with other OSes sharing the hardware. Determine in nxprtc_gettime()
790 if (sc->chiptype == TYPE_PCF8563) { in nxprtc_gettime()
793 sc->flags |= SC_F_CPOL; in nxprtc_gettime()
795 sc->flags |= SC_F_CPOL; in nxprtc_gettime()
798 clock_dbgprint_bcd(sc->dev, CLOCK_DBG_READ, &bct); in nxprtc_gettime()
799 err = clock_bcd_to_ts(&bct, ts, sc->use_ampm); in nxprtc_gettime()
800 ts->tv_sec += utc_offset(); in nxprtc_gettime()
826 if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) != 0) in nxprtc_settime()
834 /* Grab a fresh post-sleep idea of what time it is. */ in nxprtc_settime()
836 ts->tv_sec -= utc_offset(); in nxprtc_settime()
837 ts->tv_nsec = 0; in nxprtc_settime()
838 clock_ts_to_bcd(ts, &bct, sc->use_ampm); in nxprtc_settime()
839 clock_dbgprint_bcd(sc->dev, CLOCK_DBG_WRITE, &bct); in nxprtc_settime()
843 if (sc->chiptype == TYPE_PCF8563) { in nxprtc_settime()
844 if ((sc->flags & SC_F_CPOL) != 0) { in nxprtc_settime()
865 if ((err = write_reg(sc, sc->tmcaddr, TMR_TICKS_SEC)) != 0) in nxprtc_settime()
872 * Check for battery-low. The actual check is throttled to only occur in nxprtc_settime()
879 iicbus_release_bus(sc->busdev, sc->dev); in nxprtc_settime()
892 return (ofw_bus_search_compatible(dev, compat_data)->ocd_data); in nxprtc_get_chiptype()
905 for (cdata = compat_data; cdata->ocd_str != NULL; ++cdata) { in nxprtc_get_chiptype()
906 if (strcmp(htype, cdata->ocd_str) == 0) in nxprtc_get_chiptype()
909 chiptype = cdata->ocd_data; in nxprtc_get_chiptype()
914 * On non-FDT systems the historical behavior of this driver was to in nxprtc_get_chiptype()
949 sc->dev = dev; in nxprtc_attach()
950 sc->busdev = device_get_parent(dev); in nxprtc_attach()
953 sc->chiptype = nxprtc_get_chiptype(dev); in nxprtc_attach()
956 switch (sc->chiptype) { in nxprtc_attach()
961 sc->secaddr = PCF8523_R_SECOND; in nxprtc_attach()
962 sc->tmcaddr = PCF8523_R_TMR_A_COUNT; in nxprtc_attach()
963 sc->use_timer = true; in nxprtc_attach()
967 sc->secaddr = PCF8563_R_SECOND; in nxprtc_attach()
968 sc->tmcaddr = PCF8563_R_TMR_COUNT; in nxprtc_attach()
969 sc->use_timer = true; in nxprtc_attach()
980 sc->config_hook.ich_func = nxprtc_start; in nxprtc_attach()
981 sc->config_hook.ich_arg = dev; in nxprtc_attach()
982 if (config_intrhook_establish(&sc->config_hook) != 0) in nxprtc_attach()