// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * * Author: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com> * * RTC clock driver for the RTC part of the AB8500 Power management chip. * Based on RTC clock driver for the AB3100 Analog Baseband Chip by * Linus Walleij <linus.walleij@stericsson.com>
*/
/* Request a data read */
retval = abx500_set_register_interruptible(dev,
AB8500_RTC, AB8500_RTC_READ_REQ_REG, RTC_READ_REQUEST); if (retval < 0) return retval;
/* Wait for some cycles after enabling the rtc read in ab8500 */ while (time_before(jiffies, timeout)) {
retval = abx500_get_register_interruptible(dev,
AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); if (retval < 0) return retval;
if (!(value & RTC_READ_REQUEST)) break;
usleep_range(1000, 5000);
}
/* Read the Watchtime registers */ for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
retval = abx500_get_register_interruptible(dev,
AB8500_RTC, ab8500_rtc_time_regs[i], &value); if (retval < 0) return retval;
buf[i] = value;
}
/* Check if the alarm is enabled or not */
retval = abx500_get_register_interruptible(dev, AB8500_RTC,
AB8500_RTC_STAT_REG, &rtc_ctrl); if (retval < 0) return retval;
/* Set the alarm time */ for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
retval = abx500_set_register_interruptible(dev, AB8500_RTC,
ab8500_rtc_alarm_regs[i], buf[i]); if (retval < 0) return retval;
}
staticint ab8500_rtc_set_calibration(struct device *dev, int calibration)
{ int retval;
u8 rtccal = 0;
/* * Check that the calibration value (which is in units of 0.5 * parts-per-million) is in the AB8500's range for RtcCalibration * register. -128 (0x80) is not permitted because the AB8500 uses * a sign-bit rather than two's complement, so 0x80 is just another * representation of zero.
*/ if ((calibration < -127) || (calibration > 127)) {
dev_err(dev, "RtcCalibration value outside permitted range\n"); return -EINVAL;
}
/* * The AB8500 uses sign (in bit7) and magnitude (in bits0-7) * so need to convert to this sort of representation before writing * into RtcCalibration register...
*/ if (calibration >= 0)
rtccal = 0x7F & calibration; else
rtccal = ~(calibration - 1) | 0x80;
staticint ab8500_rtc_get_calibration(struct device *dev, int *calibration)
{ int retval;
u8 rtccal = 0;
retval = abx500_get_register_interruptible(dev, AB8500_RTC,
AB8500_RTC_CALIB_REG, &rtccal); if (retval >= 0) { /* * The AB8500 uses sign (in bit7) and magnitude (in bits0-7) * so need to convert value from RtcCalibration register into * a two's complement signed value...
*/ if (rtccal & 0x80)
*calibration = 0 - (rtccal & 0x7F); else
*calibration = 0x7F & rtccal;
}
return retval;
}
static ssize_t ab8500_sysfs_store_rtc_calibration(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ int retval; int calibration = 0;
if (sscanf(buf, " %i ", &calibration) != 1) {
dev_err(dev, "Failed to store RTC calibration attribute\n"); return -EINVAL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.