static int ds1307_get_time()

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, &regflag);
		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;
}