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        int ret;
 410        int stat, control;
 411
 412        rtc_lock(ds3232->rtc);
 413
 414        ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
 415        if (ret)
 416                goto unlock;
 417
 418        if (stat & DS3232_REG_SR_A1F) {
 419                ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
 420                if (ret) {
 421                        dev_warn(ds3232->dev,
 422                                 "Read Control Register error %d\n", ret);
 423                } else {
 424                        /* disable alarm1 interrupt */
 425                        control &= ~(DS3232_REG_CR_A1IE);
 426                        ret = regmap_write(ds3232->regmap, DS3232_REG_CR,
 427                                           control);
 428                        if (ret) {
 429                                dev_warn(ds3232->dev,
 430                                         "Write Control Register error %d\n",
 431                                         ret);
 432                                goto unlock;
 433                        }
 434
 435                        /* clear the alarm pend flag */
 436                        stat &= ~DS3232_REG_SR_A1F;
 437                        ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
 438                        if (ret) {
 439                                dev_warn(ds3232->dev,
 440                                         "Write Status Register error %d\n",
 441                                         ret);
 442                                goto unlock;
 443                        }
 444
 445                        rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
 446                }
 447        }
 448
 449unlock:
 450        rtc_unlock(ds3232->rtc);
 451
 452        return IRQ_HANDLED;
 453}
 454
 455static const struct rtc_class_ops ds3232_rtc_ops = {
 456        .read_time = ds3232_read_time,
 457        .set_time = ds3232_set_time,
 458        .read_alarm = ds3232_read_alarm,
 459        .set_alarm = ds3232_set_alarm,
 460        .alarm_irq_enable = ds3232_alarm_irq_enable,
 461};
 462
 463static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
 464                             size_t bytes)
 465{
 466        struct regmap *ds3232_regmap = (struct regmap *)priv;
 467
 468        return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset,
 469                                val, bytes);
 470}
 471
 472static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
 473                              size_t bytes)
 474{
 475        struct regmap *ds3232_regmap = (struct regmap *)priv;
 476
 477        return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset,
 478                                 val, bytes);
 479}
 480
 481static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
 482                        const char *name)
 483{
 484        struct ds3232 *ds3232;
 485        int ret;
 486        struct nvmem_config nvmem_cfg = {
 487                .name = "ds3232_sram",
 488                .stride = 1,
 489                .size = DS3232_REG_SRAM_SIZE,
 490                .word_size = 1,
 491                .reg_read = ds3232_nvmem_read,
 492                .reg_write = ds3232_nvmem_write,
 493                .priv = regmap,
 494                .type = NVMEM_TYPE_BATTERY_BACKED
 495        };
 496
 497        ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
 498        if (!ds3232)
 499                return -ENOMEM;
 500
 501        ds3232->regmap = regmap;
 502        ds3232->irq = irq;
 503        ds3232->dev = dev;
 504        dev_set_drvdata(dev, ds3232);
 505
 506        ret = ds3232_check_rtc_status(dev);
 507        if (ret)
 508                return ret;
 509
 510        if (ds3232->irq > 0)
 511                device_init_wakeup(dev, 1);
 512
 513        ds3232_hwmon_register(dev, name);
 514
 515        ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
 516                                                THIS_MODULE);
 517        if (IS_ERR(ds3232->rtc))
 518                return PTR_ERR(ds3232->rtc);
 519
 520        ret = devm_rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
 521        if(ret)
 522                return ret;
 523
 524        if (ds3232->irq > 0) {
 525                ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
 526                                                ds3232_irq,
 527                                                IRQF_SHARED | IRQF_ONESHOT,
 528                                                name, dev);
 529                if (ret) {
 530                        device_set_wakeup_capable(dev, 0);
 531                        ds3232->irq = 0;
 532                        dev_err(dev, "unable to request IRQ\n");
 533                }
 534        }
 535
 536        return 0;
 537}
 538
 539#ifdef CONFIG_PM_SLEEP
 540static int ds3232_suspend(struct device *dev)
 541{
 542        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 543
 544        if (device_may_wakeup(dev)) {
 545                if (enable_irq_wake(ds3232->irq))
 546                        dev_warn_once(dev, "Cannot set wakeup source\n");
 547        }
 548
 549        return 0;
 550}
 551
 552static int ds3232_resume(struct device *dev)
 553{
 554        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 555
 556        if (device_may_wakeup(dev))
 557                disable_irq_wake(ds3232->irq);
 558
 559        return 0;
 560}
 561#endif
 562
 563static const struct dev_pm_ops ds3232_pm_ops = {
 564        SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
 565};
 566
 567#if IS_ENABLED(CONFIG_I2C)
 568
 569static int ds3232_i2c_probe(struct i2c_client *client,
 570                            const struct i2c_device_id *id)
 571{
 572        struct regmap *regmap;
 573        static const struct regmap_config config = {
 574                .reg_bits = 8,
 575                .val_bits = 8,
 576                .max_register = DS3232_REG_SRAM_END,
 577        };
 578
 579        regmap = devm_regmap_init_i2c(client, &config);
 580        if (IS_ERR(regmap)) {
 581                dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
 582                        __func__, PTR_ERR(regmap));
 583                return PTR_ERR(regmap);
 584        }
 585
 586        return ds3232_probe(&client->dev, regmap, client->irq, client->name);
 587}
 588
 589static const struct i2c_device_id ds3232_id[] = {
 590        { "ds3232", 0 },
 591        { }
 592};
 593MODULE_DEVICE_TABLE(i2c, ds3232_id);
 594
 595static const  __maybe_unused struct of_device_id ds3232_of_match[] = {
 596        { .compatible = "dallas,ds3232" },
 597        { }
 598};
 599MODULE_DEVICE_TABLE(of, ds3232_of_match);
 600
 601static struct i2c_driver ds3232_driver = {
 602        .driver = {
 603                .name = "rtc-ds3232",
 604                .of_match_table = of_match_ptr(ds3232_of_match),
 605                .pm     = &ds3232_pm_ops,
 606        },
 607        .probe = ds3232_i2c_probe,
 608        .id_table = ds3232_id,
 609};
 610
 611static int ds3232_register_driver(void)
 612{
 613        return i2c_add_driver(&ds3232_driver);
 614}
 615
 616static void ds3232_unregister_driver(void)
 617{
 618        i2c_del_driver(&ds3232_driver);
 619}
 620
 621#else
 622
 623static int ds3232_register_driver(void)
 624{
 625        return 0;
 626}
 627
 628static void ds3232_unregister_driver(void)
 629{
 630}
 631
 632#endif
 633
 634#if IS_ENABLED(CONFIG_SPI_MASTER)
 635
 636static int ds3234_probe(struct spi_device *spi)
 637{
 638        int res;
 639        unsigned int tmp;
 640        static const struct regmap_config config = {
 641                .reg_bits = 8,
 642                .val_bits = 8,
 643                .max_register = DS3232_REG_SRAM_END,
 644                .write_flag_mask = 0x80,
 645        };
 646        struct regmap *regmap;
 647
 648        regmap = devm_regmap_init_spi(spi, &config);
 649        if (IS_ERR(regmap)) {
 650                dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
 651                        __func__, PTR_ERR(regmap));
 652                return PTR_ERR(regmap);
 653        }
 654
 655        spi->mode = SPI_MODE_3;
 656        spi->bits_per_word = 8;
 657        spi_setup(spi);
 658
 659        res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
 660        if (res)
 661                return res;
 662
 663        /* Control settings
 664         *
 665         * CONTROL_REG
 666         * BIT 7        6       5       4       3       2       1       0
 667         *     EOSC     BBSQW   CONV    RS2     RS1     INTCN   A2IE    A1IE
 668         *
 669         *     0        0       0       1       1       1       0       0
 670         *
 671         * CONTROL_STAT_REG
 672         * BIT 7        6       5       4       3       2       1       0
 673         *     OSF      BB32kHz CRATE1  CRATE0  EN32kHz BSY     A2F     A1F
 674         *
 675         *     1        0       0       0       1       0       0       0
 676         */
 677        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 678        if (res)
 679                return res;
 680        res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
 681        if (res)
 682                return res;
 683
 684        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 685        if (res)
 686                return res;
 687        res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
 688        if (res)
 689                return res;
 690
 691        /* Print our settings */
 692        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 693        if (res)
 694                return res;
 695        dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
 696
 697        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 698        if (res)
 699                return res;
 700        dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
 701
 702        return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
 703}
 704
 705static struct spi_driver ds3234_driver = {
 706        .driver = {
 707                .name    = "ds3234",
 708        },
 709        .probe   = ds3234_probe,
 710};
 711
 712static int ds3234_register_driver(void)
 713{
 714        return spi_register_driver(&ds3234_driver);
 715}
 716
 717static void ds3234_unregister_driver(void)
 718{
 719        spi_unregister_driver(&ds3234_driver);
 720}
 721
 722#else
 723
 724static int ds3234_register_driver(void)
 725{
 726        return 0;
 727}
 728
 729static void ds3234_unregister_driver(void)
 730{
 731}
 732
 733#endif
 734
 735static int __init ds323x_init(void)
 736{
 737        int ret;
 738
 739        ret = ds3232_register_driver();
 740        if (ret) {
 741                pr_err("Failed to register ds3232 driver: %d\n", ret);
 742                return ret;
 743        }
 744
 745        ret = ds3234_register_driver();
 746        if (ret) {
 747                pr_err("Failed to register ds3234 driver: %d\n", ret);
 748                ds3232_unregister_driver();
 749        }
 750
 751        return ret;
 752}
 753module_init(ds323x_init)
 754
 755static void __exit ds323x_exit(void)
 756{
 757        ds3234_unregister_driver();
 758        ds3232_unregister_driver();
 759}
 760module_exit(ds323x_exit)
 761
 762MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
 763MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
 764MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
 765MODULE_LICENSE("GPL");
 766MODULE_ALIAS("spi:ds3234");
 767