Merge tag 'rtc-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "A quiet cycle this time. - ds1307: properly handle oscillator failure flags - imx-sc: alarm support - pcf2123: alarm support, correct offset handling - sun6i: add R40 support - simplify getting the adapter of an i2c client" * tag 'rtc-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (37 commits) rtc: wm831x: Add IRQF_ONESHOT flag rtc: stm32: remove one condition check in stm32_rtc_set_alarm() rtc: pcf2123: Fix build error rtc: interface: Change type of 'count' from int to u64 rtc: pcf8563: Clear event flags and disable interrupts before requesting irq rtc: pcf8563: Fix interrupt trigger method rtc: pcf2123: fix negative offset rounding rtc: pcf2123: add alarm support rtc: pcf2123: use %ptR rtc: pcf2123: port to regmap rtc: pcf2123: remove sysfs register view rtc: rx8025: simplify getting the adapter of a client rtc: rx8010: simplify getting the adapter of a client rtc: rv8803: simplify getting the adapter of a client rtc: m41t80: simplify getting the adapter of a client rtc: fm3130: simplify getting the adapter of a client rtc: tegra: Drop MODULE_ALIAS rtc: sun6i: Add R40 compatible dt-bindings: rtc: sun6i: Add the R40 RTC compatible dt-bindings: rtc: Convert Allwinner A31 RTC to a schema ...
This commit is contained in:
@@ -222,6 +222,45 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
|
||||
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 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;
|
||||
@@ -286,7 +325,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
|
||||
if (t->tm_year > 199 && chip->century_bit)
|
||||
regs[chip->century_reg] |= chip->century_bit;
|
||||
|
||||
if (ds1307->type == mcp794xx) {
|
||||
switch (ds1307->type) {
|
||||
case ds_1308:
|
||||
case ds_1338:
|
||||
regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL,
|
||||
DS1338_BIT_OSF, 0);
|
||||
break;
|
||||
case ds_1340:
|
||||
regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG,
|
||||
DS1340_BIT_OSF, 0);
|
||||
break;
|
||||
case mcp794xx:
|
||||
/*
|
||||
* these bits were cleared when preparing the date/time
|
||||
* values and need to be set again before writing the
|
||||
@@ -294,6 +343,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
|
||||
*/
|
||||
regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
|
||||
regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: %7ph\n", "write", regs);
|
||||
@@ -1702,7 +1754,6 @@ static int ds1307_probe(struct i2c_client *client,
|
||||
break;
|
||||
}
|
||||
|
||||
read_rtc:
|
||||
/* read RTC registers */
|
||||
err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
|
||||
sizeof(regs));
|
||||
@@ -1711,75 +1762,11 @@ read_rtc:
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* minimal sanity checking; some chips (like DS1340) don't
|
||||
* specify the extra bits as must-be-zero, but there are
|
||||
* still a few values that are clearly out-of-range.
|
||||
*/
|
||||
tmp = regs[DS1307_REG_SECS];
|
||||
switch (ds1307->type) {
|
||||
case ds_1307:
|
||||
case m41t0:
|
||||
case m41t00:
|
||||
case m41t11:
|
||||
/* clock halted? turn it on, so clock can tick. */
|
||||
if (tmp & DS1307_BIT_CH) {
|
||||
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
|
||||
dev_warn(ds1307->dev, "SET TIME!\n");
|
||||
goto read_rtc;
|
||||
}
|
||||
break;
|
||||
case ds_1308:
|
||||
case ds_1338:
|
||||
/* clock halted? turn it on, so clock can tick. */
|
||||
if (tmp & DS1307_BIT_CH)
|
||||
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
|
||||
|
||||
/* oscillator fault? clear flag, and warn */
|
||||
if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
|
||||
regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
|
||||
regs[DS1307_REG_CONTROL] &
|
||||
~DS1338_BIT_OSF);
|
||||
dev_warn(ds1307->dev, "SET TIME!\n");
|
||||
goto read_rtc;
|
||||
}
|
||||
break;
|
||||
case ds_1340:
|
||||
/* clock halted? turn it on, so clock can tick. */
|
||||
if (tmp & DS1340_BIT_nEOSC)
|
||||
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
|
||||
|
||||
err = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
|
||||
if (err) {
|
||||
dev_dbg(ds1307->dev, "read error %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* oscillator fault? clear flag, and warn */
|
||||
if (tmp & DS1340_BIT_OSF) {
|
||||
regmap_write(ds1307->regmap, DS1340_REG_FLAG, 0);
|
||||
dev_warn(ds1307->dev, "SET TIME!\n");
|
||||
}
|
||||
break;
|
||||
case mcp794xx:
|
||||
/* make sure that the backup battery is enabled */
|
||||
if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
|
||||
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
|
||||
regs[DS1307_REG_WDAY] |
|
||||
MCP794XX_BIT_VBATEN);
|
||||
}
|
||||
|
||||
/* clock halted? turn it on, so clock can tick. */
|
||||
if (!(tmp & MCP794XX_BIT_ST)) {
|
||||
regmap_write(ds1307->regmap, DS1307_REG_SECS,
|
||||
MCP794XX_BIT_ST);
|
||||
dev_warn(ds1307->dev, "SET TIME!\n");
|
||||
goto read_rtc;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (ds1307->type == mcp794xx &&
|
||||
!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
|
||||
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
|
||||
regs[DS1307_REG_WDAY] |
|
||||
MCP794XX_BIT_VBATEN);
|
||||
}
|
||||
|
||||
tmp = regs[DS1307_REG_HOUR];
|
||||
|
Reference in New Issue
Block a user