in rtc-ds1307.c [208:317]
static int ds1307_get_time(struct device *dev, struct rtc_time *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
int tmp, ret;
const struct chip_desc *chip = &chips[ds1307->type];
u8 regs[7];
if (ds1307->type == rx_8130) {
unsigned int regflag;
ret = regmap_read(ds1307->regmap, RX8130_REG_FLAG, ®flag);
if (ret) {
dev_err(dev, "%s error %d\n", "read", ret);
return ret;
}
if (regflag & RX8130_REG_FLAG_VLF) {
dev_warn_once(dev, "oscillator failed, set time!\n");
return -EINVAL;
}
}
/* read the RTC date and time registers all at once */
ret = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (ret) {
dev_err(dev, "%s error %d\n", "read", ret);
return ret;
}
dev_dbg(dev, "%s: %7ph\n", "read", regs);
/* if oscillator fail bit is set, no data can be trusted */
if (ds1307->type == m41t0 &&
regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
dev_warn_once(dev, "oscillator failed, set time!\n");
return -EINVAL;
}
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
case m41t00:
case m41t11:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
break;
case ds_1308:
case ds_1338:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &tmp);
if (ret)
return ret;
if (tmp & DS1338_BIT_OSF)
return -EINVAL;
break;
case ds_1340:
if (tmp & DS1340_BIT_nEOSC)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
if (ret)
return ret;
if (tmp & DS1340_BIT_OSF)
return -EINVAL;
break;
case ds_1388:
ret = regmap_read(ds1307->regmap, DS1388_REG_FLAG, &tmp);
if (ret)
return ret;
if (tmp & DS1388_BIT_OSF)
return -EINVAL;
break;
case mcp794xx:
if (!(tmp & MCP794XX_BIT_ST))
return -EINVAL;
break;
default:
break;
}
t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
tmp = regs[DS1307_REG_HOUR] & 0x3f;
t->tm_hour = bcd2bin(tmp);
/* rx8130 is bit position, not BCD */
if (ds1307->type == rx_8130)
t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f);
else
t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
tmp = regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
t->tm_year = bcd2bin(regs[DS1307_REG_YEAR]) + 100;
if (regs[chip->century_reg] & chip->century_bit &&
IS_ENABLED(CONFIG_RTC_DRV_DS1307_CENTURY))
t->tm_year += 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"read", t->tm_sec, t->tm_min,
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
return 0;
}