/* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
time->tm_wday = bcd2bin(week) - 1;
time->tm_mday = bcd2bin(day); /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
time->tm_mon = bcd2bin(month & 0x7F) - 1; if (century)
add_century = 100;
/* Extract time from rtc_time and load into ds3232*/
buf[0] = bin2bcd(time->tm_sec);
buf[1] = bin2bcd(time->tm_min);
buf[2] = bin2bcd(time->tm_hour); /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
buf[3] = bin2bcd(time->tm_wday + 1);
buf[4] = bin2bcd(time->tm_mday); /* Date */ /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
buf[5] = bin2bcd(time->tm_mon + 1); if (time->tm_year >= 100) {
buf[5] |= 0x80;
buf[6] = bin2bcd(time->tm_year - 100);
} else {
buf[6] = bin2bcd(time->tm_year);
}
/* * DS3232 has two alarm, we only use alarm1 * According to linux specification, only support one-shot alarm * no periodic alarm mode
*/ staticint ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ struct ds3232 *ds3232 = dev_get_drvdata(dev); int control, stat; int ret;
u8 buf[4];
ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); if (ret) goto out;
ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); if (ret) goto out;
ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_ALARM1, buf, 4); if (ret) goto out;
/* * linux rtc-module does not support wday alarm * and only 24h time mode supported indeed
*/ staticint ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ struct ds3232 *ds3232 = dev_get_drvdata(dev); int control, stat; int ret;
u8 buf[4];
/* clear alarm interrupt enable bit */
ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); if (ret) goto out;
control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control); if (ret) goto out;
/* clear any pending alarm flag */
ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); if (ret) goto out;
stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat); if (ret) goto out;
ret = regmap_bulk_write(ds3232->regmap, DS3232_REG_ALARM1, buf, 4); if (ret) goto out;
if (alarm->enabled) {
control |= DS3232_REG_CR_A1IE;
ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
}
out: return ret;
}
staticint ds3232_update_alarm(struct device *dev, unsignedint enabled)
{ struct ds3232 *ds3232 = dev_get_drvdata(dev); int control; int ret;
ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); if (ret) return ret;
if (enabled) /* enable alarm1 interrupt */
control |= DS3232_REG_CR_A1IE; else /* disable alarm1 interrupt */
control &= ~(DS3232_REG_CR_A1IE);
ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
return ret;
}
/* * Temperature sensor support for ds3232/ds3234 devices. * A user-initiated temperature conversion is not started by this function, * so the temperature is updated once every 64 seconds.
*/ staticint ds3232_hwmon_read_temp(struct device *dev, longint *mC)
{ struct ds3232 *ds3232 = dev_get_drvdata(dev);
u8 temp_buf[2];
s16 temp; int ret;
ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_TEMPERATURE, temp_buf, sizeof(temp_buf)); if (ret < 0) return ret;
/* * Temperature is represented as a 10-bit code with a resolution of * 0.25 degree celsius and encoded in two's complement format.
*/
temp = (temp_buf[0] << 8) | temp_buf[1];
temp >>= 6;
*mC = temp * 250;
return 0;
}
static umode_t ds3232_hwmon_is_visible(constvoid *data, enum hwmon_sensor_types type,
u32 attr, int channel)
{ if (type != hwmon_temp) return 0;
ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); if (ret) goto unlock;
if (stat & DS3232_REG_SR_A1F) {
ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); if (ret) {
dev_warn(ds3232->dev, "Read Control Register error %d\n", ret);
} else { /* disable alarm1 interrupt */
control &= ~(DS3232_REG_CR_A1IE);
ret = regmap_write(ds3232->regmap, DS3232_REG_CR,
control); if (ret) {
dev_warn(ds3232->dev, "Write Control Register error %d\n",
ret); goto unlock;
}
/* clear the alarm pend flag */
stat &= ~DS3232_REG_SR_A1F;
ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat); if (ret) {
dev_warn(ds3232->dev, "Write Status Register error %d\n",
ret); goto unlock;
}
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.