in rtc-ds1307.c [319:411]
static int ds1307_set_time(struct device *dev, struct rtc_time *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
const struct chip_desc *chip = &chips[ds1307->type];
int result;
int tmp;
u8 regs[7];
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"write", t->tm_sec, t->tm_min,
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
if (t->tm_year < 100)
return -EINVAL;
#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
if (t->tm_year > (chip->century_bit ? 299 : 199))
return -EINVAL;
#else
if (t->tm_year > 199)
return -EINVAL;
#endif
regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
/* rx8130 is bit position, not BCD */
if (ds1307->type == rx_8130)
regs[DS1307_REG_WDAY] = 1 << t->tm_wday;
else
regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
regs[DS1307_REG_YEAR] = bin2bcd(tmp);
if (chip->century_enable_bit)
regs[chip->century_reg] |= chip->century_enable_bit;
if (t->tm_year > 199 && chip->century_bit)
regs[chip->century_reg] |= chip->century_bit;
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 ds_1388:
regmap_update_bits(ds1307->regmap, DS1388_REG_FLAG,
DS1388_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
* regsfer out to the device.
*/
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);
result = regmap_bulk_write(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (result) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
}
if (ds1307->type == rx_8130) {
/* clear Voltage Loss Flag as data is available now */
result = regmap_write(ds1307->regmap, RX8130_REG_FLAG,
~(u8)RX8130_REG_FLAG_VLF);
if (result) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
}
}
return 0;
}