in rtc-rs5c372.c [615:732]
static int rs5c372_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err = 0;
int smbus_mode = 0;
struct rs5c372 *rs5c372;
dev_dbg(&client->dev, "%s\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) {
/*
* If we don't have any master mode adapter, try breaking
* it down in to the barest of capabilities.
*/
if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK))
smbus_mode = 1;
else {
/* Still no good, give up */
err = -ENODEV;
goto exit;
}
}
rs5c372 = devm_kzalloc(&client->dev, sizeof(struct rs5c372),
GFP_KERNEL);
if (!rs5c372) {
err = -ENOMEM;
goto exit;
}
rs5c372->client = client;
i2c_set_clientdata(client, rs5c372);
if (client->dev.of_node)
rs5c372->type = (enum rtc_type)
of_device_get_match_data(&client->dev);
else
rs5c372->type = id->driver_data;
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
rs5c372->regs = &rs5c372->buf[1];
rs5c372->smbus = smbus_mode;
err = rs5c_get_regs(rs5c372);
if (err < 0)
goto exit;
/* clock may be set for am/pm or 24 hr time */
switch (rs5c372->type) {
case rtc_rs5c372a:
case rtc_rs5c372b:
/* alarm uses ALARM_A; and nINTRA on 372a, nINTR on 372b.
* so does periodic irq, except some 327a modes.
*/
if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24)
rs5c372->time24 = 1;
break;
case rtc_r2025sd:
case rtc_r2221tl:
case rtc_rv5c386:
case rtc_rv5c387a:
if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24)
rs5c372->time24 = 1;
/* alarm uses ALARM_W; and nINTRB for alarm and periodic
* irq, on both 386 and 387
*/
break;
default:
dev_err(&client->dev, "unknown RTC type\n");
goto exit;
}
/* if the oscillator lost power and no other software (like
* the bootloader) set it up, do it here.
*
* The R2025S/D does this a little differently than the other
* parts, so we special case that..
*/
err = rs5c_oscillator_setup(rs5c372);
if (unlikely(err < 0)) {
dev_err(&client->dev, "setup error\n");
goto exit;
}
dev_info(&client->dev, "%s found, %s\n",
({ char *s; switch (rs5c372->type) {
case rtc_r2025sd: s = "r2025sd"; break;
case rtc_r2221tl: s = "r2221tl"; break;
case rtc_rs5c372a: s = "rs5c372a"; break;
case rtc_rs5c372b: s = "rs5c372b"; break;
case rtc_rv5c386: s = "rv5c386"; break;
case rtc_rv5c387a: s = "rv5c387a"; break;
default: s = "chip"; break;
}; s;}),
rs5c372->time24 ? "24hr" : "am/pm"
);
/* REVISIT use client->irq to register alarm irq ... */
rs5c372->rtc = devm_rtc_device_register(&client->dev,
rs5c372_driver.driver.name,
&rs5c372_rtc_ops, THIS_MODULE);
if (IS_ERR(rs5c372->rtc)) {
err = PTR_ERR(rs5c372->rtc);
goto exit;
}
err = rs5c_sysfs_register(&client->dev);
if (err)
goto exit;
return 0;
exit:
return err;
}