linux/drivers/rtc/rtc-ds3232.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * RTC client/driver for the Maxim/Dallas DS3232/DS3234 Real-Time Clock
   4 *
   5 * Copyright (C) 2009-2011 Freescale Semiconductor.
   6 * Author: Jack Lan <jack.lan@freescale.com>
   7 * Copyright (C) 2008 MIMOMax Wireless Ltd.
   8 */
   9
  10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/interrupt.h>
  15#include <linux/i2c.h>
  16#include <linux/spi/spi.h>
  17#include <linux/rtc.h>
  18#include <linux/bcd.h>
  19#include <linux/slab.h>
  20#include <linux/regmap.h>
  21#include <linux/hwmon.h>
  22
  23#define DS3232_REG_SECONDS      0x00
  24#define DS3232_REG_MINUTES      0x01
  25#define DS3232_REG_HOURS        0x02
  26#define DS3232_REG_AMPM         0x02
  27#define DS3232_REG_DAY          0x03
  28#define DS3232_REG_DATE         0x04
  29#define DS3232_REG_MONTH        0x05
  30#define DS3232_REG_CENTURY      0x05
  31#define DS3232_REG_YEAR         0x06
  32#define DS3232_REG_ALARM1       0x07       /* Alarm 1 BASE */
  33#define DS3232_REG_ALARM2       0x0B       /* Alarm 2 BASE */
  34#define DS3232_REG_CR           0x0E       /* Control register */
  35#       define DS3232_REG_CR_nEOSC   0x80
  36#       define DS3232_REG_CR_INTCN   0x04
  37#       define DS3232_REG_CR_A2IE    0x02
  38#       define DS3232_REG_CR_A1IE    0x01
  39
  40#define DS3232_REG_SR           0x0F       /* control/status register */
  41#       define DS3232_REG_SR_OSF     0x80
  42#       define DS3232_REG_SR_BSY     0x04
  43#       define DS3232_REG_SR_A2F     0x02
  44#       define DS3232_REG_SR_A1F     0x01
  45
  46#define DS3232_REG_TEMPERATURE  0x11
  47#define DS3232_REG_SRAM_START   0x14
  48#define DS3232_REG_SRAM_END     0xFF
  49
  50#define DS3232_REG_SRAM_SIZE    236
  51
  52struct ds3232 {
  53        struct device *dev;
  54        struct regmap *regmap;
  55        int irq;
  56        struct rtc_device *rtc;
  57
  58        bool suspended;
  59};
  60
  61static int ds3232_check_rtc_status(struct device *dev)
  62{
  63        struct ds3232 *ds3232 = dev_get_drvdata(dev);
  64        int ret = 0;
  65        int control, stat;
  66
  67        ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
  68        if (ret)
  69                return ret;
  70
  71        if (stat & DS3232_REG_SR_OSF)
  72                dev_warn(dev,
  73                                "oscillator discontinuity flagged, "
  74                                "time unreliable\n");
  75
  76        stat &= ~(DS3232_REG_SR_OSF | DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
  77
  78        ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
  79        if (ret)
  80                return ret;
  81
  82        /* If the alarm is pending, clear it before requesting
  83         * the interrupt, so an interrupt event isn't reported
  84         * before everything is initialized.
  85         */
  86
  87        ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
  88        if (ret)
  89                return ret;
  90
  91        control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
  92        control |= DS3232_REG_CR_INTCN;
  93
  94        return regmap_write(ds3232->regmap, DS3232_REG_CR, control);
  95}
  96
  97static int ds3232_read_time(struct device *dev, struct rtc_time *time)
  98{
  99        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 100        int ret;
 101        u8 buf[7];
 102        unsigned int year, month, day, hour, minute, second;
 103        unsigned int week, twelve_hr, am_pm;
 104        unsigned int century, add_century = 0;
 105
 106        ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
 107        if (ret)
 108                return ret;
 109
 110        second = buf[0];
 111        minute = buf[1];
 112        hour = buf[2];
 113        week = buf[3];
 114        day = buf[4];
 115        month = buf[5];
 116        year = buf[6];
 117
 118        /* Extract additional information for AM/PM and century */
 119
 120        twelve_hr = hour & 0x40;
 121        am_pm = hour & 0x20;
 122        century = month & 0x80;
 123
 124        /* Write to rtc_time structure */
 125
 126        time->tm_sec = bcd2bin(second);
 127        time->tm_min = bcd2bin(minute);
 128        if (twelve_hr) {
 129                /* Convert to 24 hr */
 130                if (am_pm)
 131                        time->tm_hour = bcd2bin(hour & 0x1F) + 12;
 132                else
 133                        time->tm_hour = bcd2bin(hour & 0x1F);
 134        } else {
 135                time->tm_hour = bcd2bin(hour);
 136        }
 137
 138        /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
 139        time->tm_wday = bcd2bin(week) - 1;
 140        time->tm_mday = bcd2bin(day);
 141        /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
 142        time->tm_mon = bcd2bin(month & 0x7F) - 1;
 143        if (century)
 144                add_century = 100;
 145
 146        time->tm_year = bcd2bin(year) + add_century;
 147
 148        return 0;
 149}
 150
 151static int ds3232_set_time(struct device *dev, struct rtc_time *time)
 152{
 153        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 154        u8 buf[7];
 155
 156        /* Extract time from rtc_time and load into ds3232*/
 157
 158        buf[0] = bin2bcd(time->tm_sec);
 159        buf[1] = bin2bcd(time->tm_min);
 160        buf[2] = bin2bcd(time->tm_hour);
 161        /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */
 162        buf[3] = bin2bcd(time->tm_wday + 1);
 163        buf[4] = bin2bcd(time->tm_mday); /* Date */
 164        /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */
 165        buf[5] = bin2bcd(time->tm_mon + 1);
 166        if (time->tm_year >= 100) {
 167                buf[5] |= 0x80;
 168                buf[6] = bin2bcd(time->tm_year - 100);
 169        } else {
 170                buf[6] = bin2bcd(time->tm_year);
 171        }
 172
 173        return regmap_bulk_write(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
 174}
 175
 176/*
 177 * DS3232 has two alarm, we only use alarm1
 178 * According to linux specification, only support one-shot alarm
 179 * no periodic alarm mode
 180 */
 181static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 182{
 183        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 184        int control, stat;
 185        int ret;
 186        u8 buf[4];
 187
 188        ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
 189        if (ret)
 190                goto out;
 191        ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
 192        if (ret)
 193                goto out;
 194        ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
 195        if (ret)
 196                goto out;
 197
 198        alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
 199        alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
 200        alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
 201        alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
 202
 203        alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
 204        alarm->pending = !!(stat & DS3232_REG_SR_A1F);
 205
 206        ret = 0;
 207out:
 208        return ret;
 209}
 210
 211/*
 212 * linux rtc-module does not support wday alarm
 213 * and only 24h time mode supported indeed
 214 */
 215static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 216{
 217        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 218        int control, stat;
 219        int ret;
 220        u8 buf[4];
 221
 222        if (ds3232->irq <= 0)
 223                return -EINVAL;
 224
 225        buf[0] = bin2bcd(alarm->time.tm_sec);
 226        buf[1] = bin2bcd(alarm->time.tm_min);
 227        buf[2] = bin2bcd(alarm->time.tm_hour);
 228        buf[3] = bin2bcd(alarm->time.tm_mday);
 229
 230        /* clear alarm interrupt enable bit */
 231        ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
 232        if (ret)
 233                goto out;
 234        control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
 235        ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
 236        if (ret)
 237                goto out;
 238
 239        /* clear any pending alarm flag */
 240        ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
 241        if (ret)
 242                goto out;
 243        stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
 244        ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
 245        if (ret)
 246                goto out;
 247
 248        ret = regmap_bulk_write(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
 249        if (ret)
 250                goto out;
 251
 252        if (alarm->enabled) {
 253                control |= DS3232_REG_CR_A1IE;
 254                ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
 255        }
 256out:
 257        return ret;
 258}
 259
 260static int ds3232_update_alarm(struct device *dev, unsigned int enabled)
 261{
 262        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 263        int control;
 264        int ret;
 265
 266        ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
 267        if (ret)
 268                return ret;
 269
 270        if (enabled)
 271                /* enable alarm1 interrupt */
 272                control |= DS3232_REG_CR_A1IE;
 273        else
 274                /* disable alarm1 interrupt */
 275                control &= ~(DS3232_REG_CR_A1IE);
 276        ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
 277
 278        return ret;
 279}
 280
 281/*
 282 * Temperature sensor support for ds3232/ds3234 devices.
 283 * A user-initiated temperature conversion is not started by this function,
 284 * so the temperature is updated once every 64 seconds.
 285 */
 286static int ds3232_hwmon_read_temp(struct device *dev, long int *mC)
 287{
 288        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 289        u8 temp_buf[2];
 290        s16 temp;
 291        int ret;
 292
 293        ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_TEMPERATURE, temp_buf,
 294                               sizeof(temp_buf));
 295        if (ret < 0)
 296                return ret;
 297
 298        /*
 299         * Temperature is represented as a 10-bit code with a resolution of
 300         * 0.25 degree celsius and encoded in two's complement format.
 301         */
 302        temp = (temp_buf[0] << 8) | temp_buf[1];
 303        temp >>= 6;
 304        *mC = temp * 250;
 305
 306        return 0;
 307}
 308
 309static umode_t ds3232_hwmon_is_visible(const void *data,
 310                                       enum hwmon_sensor_types type,
 311                                       u32 attr, int channel)
 312{
 313        if (type != hwmon_temp)
 314                return 0;
 315
 316        switch (attr) {
 317        case hwmon_temp_input:
 318                return 0444;
 319        default:
 320                return 0;
 321        }
 322}
 323
 324static int ds3232_hwmon_read(struct device *dev,
 325                             enum hwmon_sensor_types type,
 326                             u32 attr, int channel, long *temp)
 327{
 328        int err;
 329
 330        switch (attr) {
 331        case hwmon_temp_input:
 332                err = ds3232_hwmon_read_temp(dev, temp);
 333                break;
 334        default:
 335                err = -EOPNOTSUPP;
 336                break;
 337        }
 338
 339        return err;
 340}
 341
 342static u32 ds3232_hwmon_chip_config[] = {
 343        HWMON_C_REGISTER_TZ,
 344        0
 345};
 346
 347static const struct hwmon_channel_info ds3232_hwmon_chip = {
 348        .type = hwmon_chip,
 349        .config = ds3232_hwmon_chip_config,
 350};
 351
 352static u32 ds3232_hwmon_temp_config[] = {
 353        HWMON_T_INPUT,
 354        0
 355};
 356
 357static const struct hwmon_channel_info ds3232_hwmon_temp = {
 358        .type = hwmon_temp,
 359        .config = ds3232_hwmon_temp_config,
 360};
 361
 362static const struct hwmon_channel_info *ds3232_hwmon_info[] = {
 363        &ds3232_hwmon_chip,
 364        &ds3232_hwmon_temp,
 365        NULL
 366};
 367
 368static const struct hwmon_ops ds3232_hwmon_hwmon_ops = {
 369        .is_visible = ds3232_hwmon_is_visible,
 370        .read = ds3232_hwmon_read,
 371};
 372
 373static const struct hwmon_chip_info ds3232_hwmon_chip_info = {
 374        .ops = &ds3232_hwmon_hwmon_ops,
 375        .info = ds3232_hwmon_info,
 376};
 377
 378static void ds3232_hwmon_register(struct device *dev, const char *name)
 379{
 380        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 381        struct device *hwmon_dev;
 382
 383        if (!IS_ENABLED(CONFIG_RTC_DRV_DS3232_HWMON))
 384                return;
 385
 386        hwmon_dev = devm_hwmon_device_register_with_info(dev, name, ds3232,
 387                                                        &ds3232_hwmon_chip_info,
 388                                                        NULL);
 389        if (IS_ERR(hwmon_dev)) {
 390                dev_err(dev, "unable to register hwmon device %ld\n",
 391                        PTR_ERR(hwmon_dev));
 392        }
 393}
 394
 395static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
 396{
 397        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 398
 399        if (ds3232->irq <= 0)
 400                return -EINVAL;
 401
 402        return ds3232_update_alarm(dev, enabled);
 403}
 404
 405static irqreturn_t ds3232_irq(int irq, void *dev_id)
 406{
 407        struct device *dev = dev_id;
 408        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 409        struct mutex *lock = &ds3232->rtc->ops_lock;
 410        int ret;
 411        int stat, control;
 412
 413        mutex_lock(lock);
 414
 415        ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
 416        if (ret)
 417                goto unlock;
 418
 419        if (stat & DS3232_REG_SR_A1F) {
 420                ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
 421                if (ret) {
 422                        dev_warn(ds3232->dev,
 423                                 "Read Control Register error %d\n", ret);
 424                } else {
 425                        /* disable alarm1 interrupt */
 426                        control &= ~(DS3232_REG_CR_A1IE);
 427                        ret = regmap_write(ds3232->regmap, DS3232_REG_CR,
 428                                           control);
 429                        if (ret) {
 430                                dev_warn(ds3232->dev,
 431                                         "Write Control Register error %d\n",
 432                                         ret);
 433                                goto unlock;
 434                        }
 435
 436                        /* clear the alarm pend flag */
 437                        stat &= ~DS3232_REG_SR_A1F;
 438                        ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
 439                        if (ret) {
 440                                dev_warn(ds3232->dev,
 441                                         "Write Status Register error %d\n",
 442                                         ret);
 443                                goto unlock;
 444                        }
 445
 446                        rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
 447                }
 448        }
 449
 450unlock:
 451        mutex_unlock(lock);
 452
 453        return IRQ_HANDLED;
 454}
 455
 456static const struct rtc_class_ops ds3232_rtc_ops = {
 457        .read_time = ds3232_read_time,
 458        .set_time = ds3232_set_time,
 459        .read_alarm = ds3232_read_alarm,
 460        .set_alarm = ds3232_set_alarm,
 461        .alarm_irq_enable = ds3232_alarm_irq_enable,
 462};
 463
 464static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
 465                             size_t bytes)
 466{
 467        struct regmap *ds3232_regmap = (struct regmap *)priv;
 468
 469        return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset,
 470                                val, bytes);
 471}
 472
 473static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
 474                              size_t bytes)
 475{
 476        struct regmap *ds3232_regmap = (struct regmap *)priv;
 477
 478        return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset,
 479                                 val, bytes);
 480}
 481
 482static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
 483                        const char *name)
 484{
 485        struct ds3232 *ds3232;
 486        int ret;
 487        struct nvmem_config nvmem_cfg = {
 488                .name = "ds3232_sram",
 489                .stride = 1,
 490                .size = DS3232_REG_SRAM_SIZE,
 491                .word_size = 1,
 492                .reg_read = ds3232_nvmem_read,
 493                .reg_write = ds3232_nvmem_write,
 494                .priv = regmap,
 495                .type = NVMEM_TYPE_BATTERY_BACKED
 496        };
 497
 498        ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
 499        if (!ds3232)
 500                return -ENOMEM;
 501
 502        ds3232->regmap = regmap;
 503        ds3232->irq = irq;
 504        ds3232->dev = dev;
 505        dev_set_drvdata(dev, ds3232);
 506
 507        ret = ds3232_check_rtc_status(dev);
 508        if (ret)
 509                return ret;
 510
 511        if (ds3232->irq > 0)
 512                device_init_wakeup(dev, 1);
 513
 514        ds3232_hwmon_register(dev, name);
 515
 516        ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
 517                                                THIS_MODULE);
 518        if (IS_ERR(ds3232->rtc))
 519                return PTR_ERR(ds3232->rtc);
 520
 521        ret = rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
 522        if(ret)
 523                return ret;
 524
 525        if (ds3232->irq > 0) {
 526                ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
 527                                                ds3232_irq,
 528                                                IRQF_SHARED | IRQF_ONESHOT,
 529                                                name, dev);
 530                if (ret) {
 531                        device_set_wakeup_capable(dev, 0);
 532                        ds3232->irq = 0;
 533                        dev_err(dev, "unable to request IRQ\n");
 534                }
 535        }
 536
 537        return 0;
 538}
 539
 540#ifdef CONFIG_PM_SLEEP
 541static int ds3232_suspend(struct device *dev)
 542{
 543        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 544
 545        if (device_may_wakeup(dev)) {
 546                if (enable_irq_wake(ds3232->irq))
 547                        dev_warn_once(dev, "Cannot set wakeup source\n");
 548        }
 549
 550        return 0;
 551}
 552
 553static int ds3232_resume(struct device *dev)
 554{
 555        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 556
 557        if (device_may_wakeup(dev))
 558                disable_irq_wake(ds3232->irq);
 559
 560        return 0;
 561}
 562#endif
 563
 564static const struct dev_pm_ops ds3232_pm_ops = {
 565        SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
 566};
 567
 568#if IS_ENABLED(CONFIG_I2C)
 569
 570static int ds3232_i2c_probe(struct i2c_client *client,
 571                            const struct i2c_device_id *id)
 572{
 573        struct regmap *regmap;
 574        static const struct regmap_config config = {
 575                .reg_bits = 8,
 576                .val_bits = 8,
 577                .max_register = DS3232_REG_SRAM_END,
 578        };
 579
 580        regmap = devm_regmap_init_i2c(client, &config);
 581        if (IS_ERR(regmap)) {
 582                dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
 583                        __func__, PTR_ERR(regmap));
 584                return PTR_ERR(regmap);
 585        }
 586
 587        return ds3232_probe(&client->dev, regmap, client->irq, client->name);
 588}
 589
 590static const struct i2c_device_id ds3232_id[] = {
 591        { "ds3232", 0 },
 592        { }
 593};
 594MODULE_DEVICE_TABLE(i2c, ds3232_id);
 595
 596static const struct of_device_id ds3232_of_match[] = {
 597        { .compatible = "dallas,ds3232" },
 598        { }
 599};
 600MODULE_DEVICE_TABLE(of, ds3232_of_match);
 601
 602static struct i2c_driver ds3232_driver = {
 603        .driver = {
 604                .name = "rtc-ds3232",
 605                .of_match_table = of_match_ptr(ds3232_of_match),
 606                .pm     = &ds3232_pm_ops,
 607        },
 608        .probe = ds3232_i2c_probe,
 609        .id_table = ds3232_id,
 610};
 611
 612static int ds3232_register_driver(void)
 613{
 614        return i2c_add_driver(&ds3232_driver);
 615}
 616
 617static void ds3232_unregister_driver(void)
 618{
 619        i2c_del_driver(&ds3232_driver);
 620}
 621
 622#else
 623
 624static int ds3232_register_driver(void)
 625{
 626        return 0;
 627}
 628
 629static void ds3232_unregister_driver(void)
 630{
 631}
 632
 633#endif
 634
 635#if IS_ENABLED(CONFIG_SPI_MASTER)
 636
 637static int ds3234_probe(struct spi_device *spi)
 638{
 639        int res;
 640        unsigned int tmp;
 641        static const struct regmap_config config = {
 642                .reg_bits = 8,
 643                .val_bits = 8,
 644                .max_register = DS3232_REG_SRAM_END,
 645                .write_flag_mask = 0x80,
 646        };
 647        struct regmap *regmap;
 648
 649        regmap = devm_regmap_init_spi(spi, &config);
 650        if (IS_ERR(regmap)) {
 651                dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
 652                        __func__, PTR_ERR(regmap));
 653                return PTR_ERR(regmap);
 654        }
 655
 656        spi->mode = SPI_MODE_3;
 657        spi->bits_per_word = 8;
 658        spi_setup(spi);
 659
 660        res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
 661        if (res)
 662                return res;
 663
 664        /* Control settings
 665         *
 666         * CONTROL_REG
 667         * BIT 7        6       5       4       3       2       1       0
 668         *     EOSC     BBSQW   CONV    RS2     RS1     INTCN   A2IE    A1IE
 669         *
 670         *     0        0       0       1       1       1       0       0
 671         *
 672         * CONTROL_STAT_REG
 673         * BIT 7        6       5       4       3       2       1       0
 674         *     OSF      BB32kHz CRATE1  CRATE0  EN32kHz BSY     A2F     A1F
 675         *
 676         *     1        0       0       0       1       0       0       0
 677         */
 678        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 679        if (res)
 680                return res;
 681        res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
 682        if (res)
 683                return res;
 684
 685        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 686        if (res)
 687                return res;
 688        res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
 689        if (res)
 690                return res;
 691
 692        /* Print our settings */
 693        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 694        if (res)
 695                return res;
 696        dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
 697
 698        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 699        if (res)
 700                return res;
 701        dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
 702
 703        return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
 704}
 705
 706static struct spi_driver ds3234_driver = {
 707        .driver = {
 708                .name    = "ds3234",
 709        },
 710        .probe   = ds3234_probe,
 711};
 712
 713static int ds3234_register_driver(void)
 714{
 715        return spi_register_driver(&ds3234_driver);
 716}
 717
 718static void ds3234_unregister_driver(void)
 719{
 720        spi_unregister_driver(&ds3234_driver);
 721}
 722
 723#else
 724
 725static int ds3234_register_driver(void)
 726{
 727        return 0;
 728}
 729
 730static void ds3234_unregister_driver(void)
 731{
 732}
 733
 734#endif
 735
 736static int __init ds323x_init(void)
 737{
 738        int ret;
 739
 740        ret = ds3232_register_driver();
 741        if (ret) {
 742                pr_err("Failed to register ds3232 driver: %d\n", ret);
 743                return ret;
 744        }
 745
 746        ret = ds3234_register_driver();
 747        if (ret) {
 748                pr_err("Failed to register ds3234 driver: %d\n", ret);
 749                ds3232_unregister_driver();
 750        }
 751
 752        return ret;
 753}
 754module_init(ds323x_init)
 755
 756static void __exit ds323x_exit(void)
 757{
 758        ds3234_unregister_driver();
 759        ds3232_unregister_driver();
 760}
 761module_exit(ds323x_exit)
 762
 763MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
 764MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
 765MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
 766MODULE_LICENSE("GPL");
 767MODULE_ALIAS("spi:ds3234");
 768