in rtc-ds1307.c [1715:2007]
static int ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
const void *match;
int err = -ENODEV;
int tmp;
const struct chip_desc *chip;
bool want_irq;
bool ds1307_can_wakeup_device = false;
unsigned char regs[8];
struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
u8 trickle_charger_setup = 0;
ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
if (!ds1307)
return -ENOMEM;
dev_set_drvdata(&client->dev, ds1307);
ds1307->dev = &client->dev;
ds1307->name = client->name;
ds1307->regmap = devm_regmap_init_i2c(client, ®map_config);
if (IS_ERR(ds1307->regmap)) {
dev_err(ds1307->dev, "regmap allocation failed\n");
return PTR_ERR(ds1307->regmap);
}
i2c_set_clientdata(client, ds1307);
match = device_get_match_data(&client->dev);
if (match) {
ds1307->type = (enum ds_type)match;
chip = &chips[ds1307->type];
} else if (id) {
chip = &chips[id->driver_data];
ds1307->type = id->driver_data;
} else {
return -ENODEV;
}
want_irq = client->irq > 0 && chip->alarm;
if (!pdata)
trickle_charger_setup = ds1307_trickle_init(ds1307, chip);
else if (pdata->trickle_charger_setup)
trickle_charger_setup = pdata->trickle_charger_setup;
if (trickle_charger_setup && chip->trickle_charger_reg) {
dev_dbg(ds1307->dev,
"writing trickle charger info 0x%x to 0x%x\n",
trickle_charger_setup, chip->trickle_charger_reg);
regmap_write(ds1307->regmap, chip->trickle_charger_reg,
trickle_charger_setup);
}
/*
* For devices with no IRQ directly connected to the SoC, the RTC chip
* can be forced as a wakeup source by stating that explicitly in
* the device's .dts file using the "wakeup-source" boolean property.
* If the "wakeup-source" property is set, don't request an IRQ.
* This will guarantee the 'wakealarm' sysfs entry is available on the device,
* if supported by the RTC.
*/
if (chip->alarm && device_property_read_bool(&client->dev, "wakeup-source"))
ds1307_can_wakeup_device = true;
switch (ds1307->type) {
case ds_1337:
case ds_1339:
case ds_1341:
case ds_3231:
/* get registers that the "rtc" read below won't read... */
err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL,
regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (regs[0] & DS1337_BIT_nEOSC)
regs[0] &= ~DS1337_BIT_nEOSC;
/*
* Using IRQ or defined as wakeup-source?
* Disable the square wave and both alarms.
* For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW)
*/
if (want_irq || ds1307_can_wakeup_device) {
regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit;
regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
}
regmap_write(ds1307->regmap, DS1337_REG_CONTROL,
regs[0]);
/* oscillator fault? clear flag, and warn */
if (regs[1] & DS1337_BIT_OSF) {
regmap_write(ds1307->regmap, DS1337_REG_STATUS,
regs[1] & ~DS1337_BIT_OSF);
dev_warn(ds1307->dev, "SET TIME!\n");
}
break;
case rx_8025:
err = regmap_bulk_read(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08, regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (!(regs[1] & RX8025_BIT_XST)) {
regs[1] |= RX8025_BIT_XST;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
regs[1]);
dev_warn(ds1307->dev,
"oscillator stop detected - SET TIME!\n");
}
if (regs[1] & RX8025_BIT_PON) {
regs[1] &= ~RX8025_BIT_PON;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
regs[1]);
dev_warn(ds1307->dev, "power-on detected\n");
}
if (regs[1] & RX8025_BIT_VDET) {
regs[1] &= ~RX8025_BIT_VDET;
regmap_write(ds1307->regmap,
RX8025_REG_CTRL2 << 4 | 0x08,
regs[1]);
dev_warn(ds1307->dev, "voltage drop detected\n");
}
/* make sure we are running in 24hour mode */
if (!(regs[0] & RX8025_BIT_2412)) {
u8 hour;
/* switch to 24 hour mode */
regmap_write(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08,
regs[0] | RX8025_BIT_2412);
err = regmap_bulk_read(ds1307->regmap,
RX8025_REG_CTRL1 << 4 | 0x08,
regs, 2);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* correct hour */
hour = bcd2bin(regs[DS1307_REG_HOUR]);
if (hour == 12)
hour = 0;
if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
hour += 12;
regmap_write(ds1307->regmap,
DS1307_REG_HOUR << 4 | 0x08, hour);
}
break;
case ds_1388:
err = regmap_read(ds1307->regmap, DS1388_REG_CONTROL, &tmp);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (tmp & DS1388_BIT_nEOSC) {
tmp &= ~DS1388_BIT_nEOSC;
regmap_write(ds1307->regmap, DS1388_REG_CONTROL, tmp);
}
break;
default:
break;
}
/* read RTC registers */
err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
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];
switch (ds1307->type) {
case ds_1340:
case m41t0:
case m41t00:
case m41t11:
/*
* NOTE: ignores century bits; fix before deploying
* systems that will run through year 2100.
*/
break;
case rx_8025:
break;
default:
if (!(tmp & DS1307_BIT_12HR))
break;
/*
* Be sure we're in 24 hour mode. Multi-master systems
* take note...
*/
tmp = bcd2bin(tmp & 0x1f);
if (tmp == 12)
tmp = 0;
if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
tmp += 12;
regmap_write(ds1307->regmap, chip->offset + DS1307_REG_HOUR,
bin2bcd(tmp));
}
ds1307->rtc = devm_rtc_allocate_device(ds1307->dev);
if (IS_ERR(ds1307->rtc))
return PTR_ERR(ds1307->rtc);
if (want_irq || ds1307_can_wakeup_device)
device_set_wakeup_capable(ds1307->dev, true);
else
clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
if (ds1307_can_wakeup_device && !want_irq) {
dev_info(ds1307->dev,
"'wakeup-source' is set, request for an IRQ is disabled!\n");
/* We cannot support UIE mode if we do not have an IRQ line */
ds1307->rtc->uie_unsupported = 1;
}
if (want_irq) {
err = devm_request_threaded_irq(ds1307->dev, client->irq, NULL,
chip->irq_handler ?: ds1307_irq,
IRQF_SHARED | IRQF_ONESHOT,
ds1307->name, ds1307);
if (err) {
client->irq = 0;
device_set_wakeup_capable(ds1307->dev, false);
clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
dev_err(ds1307->dev, "unable to request IRQ!\n");
} else {
dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
}
}
ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops;
err = ds1307_add_frequency_test(ds1307);
if (err)
return err;
err = devm_rtc_register_device(ds1307->rtc);
if (err)
return err;
if (chip->nvram_size) {
struct nvmem_config nvmem_cfg = {
.name = "ds1307_nvram",
.word_size = 1,
.stride = 1,
.size = chip->nvram_size,
.reg_read = ds1307_nvram_read,
.reg_write = ds1307_nvram_write,
.priv = ds1307,
};
devm_rtc_nvmem_register(ds1307->rtc, &nvmem_cfg);
}
ds1307_hwmon_register(ds1307);
ds1307_clks_register(ds1307);
ds1307_wdt_register(ds1307);
return 0;
exit:
return err;
}