linux/drivers/rtc/rtc-ds3232.c
<<
>>
Prefs
   1/*
   2 * RTC client/driver for the Maxim/Dallas DS3232/DS3234 Real-Time Clock
   3 *
   4 * Copyright (C) 2009-2011 Freescale Semiconductor.
   5 * Author: Jack Lan <jack.lan@freescale.com>
   6 * Copyright (C) 2008 MIMOMax Wireless Ltd.
   7 *
   8 * This program is free software; you can redistribute  it and/or modify it
   9 * under  the terms of  the GNU General  Public License as published by the
  10 * Free Software Foundation;  either version 2 of the  License, or (at your
  11 * option) any later version.
  12 */
  13
  14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/interrupt.h>
  19#include <linux/i2c.h>
  20#include <linux/spi/spi.h>
  21#include <linux/rtc.h>
  22#include <linux/bcd.h>
  23#include <linux/slab.h>
  24#include <linux/regmap.h>
  25#include <linux/hwmon.h>
  26
  27#define DS3232_REG_SECONDS      0x00
  28#define DS3232_REG_MINUTES      0x01
  29#define DS3232_REG_HOURS        0x02
  30#define DS3232_REG_AMPM         0x02
  31#define DS3232_REG_DAY          0x03
  32#define DS3232_REG_DATE         0x04
  33#define DS3232_REG_MONTH        0x05
  34#define DS3232_REG_CENTURY      0x05
  35#define DS3232_REG_YEAR         0x06
  36#define DS3232_REG_ALARM1       0x07       /* Alarm 1 BASE */
  37#define DS3232_REG_ALARM2       0x0B       /* Alarm 2 BASE */
  38#define DS3232_REG_CR           0x0E       /* Control register */
  39#       define DS3232_REG_CR_nEOSC   0x80
  40#       define DS3232_REG_CR_INTCN   0x04
  41#       define DS3232_REG_CR_A2IE    0x02
  42#       define DS3232_REG_CR_A1IE    0x01
  43
  44#define DS3232_REG_SR           0x0F       /* control/status register */
  45#       define DS3232_REG_SR_OSF     0x80
  46#       define DS3232_REG_SR_BSY     0x04
  47#       define DS3232_REG_SR_A2F     0x02
  48#       define DS3232_REG_SR_A1F     0x01
  49
  50#define DS3232_REG_TEMPERATURE  0x11
  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_probe(struct device *dev, struct regmap *regmap, int irq,
 465                        const char *name)
 466{
 467        struct ds3232 *ds3232;
 468        int ret;
 469
 470        ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
 471        if (!ds3232)
 472                return -ENOMEM;
 473
 474        ds3232->regmap = regmap;
 475        ds3232->irq = irq;
 476        ds3232->dev = dev;
 477        dev_set_drvdata(dev, ds3232);
 478
 479        ret = ds3232_check_rtc_status(dev);
 480        if (ret)
 481                return ret;
 482
 483        if (ds3232->irq > 0)
 484                device_init_wakeup(dev, 1);
 485
 486        ds3232_hwmon_register(dev, name);
 487
 488        ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
 489                                                THIS_MODULE);
 490        if (IS_ERR(ds3232->rtc))
 491                return PTR_ERR(ds3232->rtc);
 492
 493        if (ds3232->irq > 0) {
 494                ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
 495                                                ds3232_irq,
 496                                                IRQF_SHARED | IRQF_ONESHOT,
 497                                                name, dev);
 498                if (ret) {
 499                        device_set_wakeup_capable(dev, 0);
 500                        ds3232->irq = 0;
 501                        dev_err(dev, "unable to request IRQ\n");
 502                }
 503        }
 504
 505        return 0;
 506}
 507
 508#ifdef CONFIG_PM_SLEEP
 509static int ds3232_suspend(struct device *dev)
 510{
 511        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 512
 513        if (device_may_wakeup(dev)) {
 514                if (enable_irq_wake(ds3232->irq))
 515                        dev_warn_once(dev, "Cannot set wakeup source\n");
 516        }
 517
 518        return 0;
 519}
 520
 521static int ds3232_resume(struct device *dev)
 522{
 523        struct ds3232 *ds3232 = dev_get_drvdata(dev);
 524
 525        if (device_may_wakeup(dev))
 526                disable_irq_wake(ds3232->irq);
 527
 528        return 0;
 529}
 530#endif
 531
 532static const struct dev_pm_ops ds3232_pm_ops = {
 533        SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
 534};
 535
 536#if IS_ENABLED(CONFIG_I2C)
 537
 538static int ds3232_i2c_probe(struct i2c_client *client,
 539                            const struct i2c_device_id *id)
 540{
 541        struct regmap *regmap;
 542        static const struct regmap_config config = {
 543                .reg_bits = 8,
 544                .val_bits = 8,
 545                .max_register = 0x13,
 546        };
 547
 548        regmap = devm_regmap_init_i2c(client, &config);
 549        if (IS_ERR(regmap)) {
 550                dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
 551                        __func__, PTR_ERR(regmap));
 552                return PTR_ERR(regmap);
 553        }
 554
 555        return ds3232_probe(&client->dev, regmap, client->irq, client->name);
 556}
 557
 558static const struct i2c_device_id ds3232_id[] = {
 559        { "ds3232", 0 },
 560        { }
 561};
 562MODULE_DEVICE_TABLE(i2c, ds3232_id);
 563
 564static const struct of_device_id ds3232_of_match[] = {
 565        { .compatible = "dallas,ds3232" },
 566        { }
 567};
 568MODULE_DEVICE_TABLE(of, ds3232_of_match);
 569
 570static struct i2c_driver ds3232_driver = {
 571        .driver = {
 572                .name = "rtc-ds3232",
 573                .of_match_table = of_match_ptr(ds3232_of_match),
 574                .pm     = &ds3232_pm_ops,
 575        },
 576        .probe = ds3232_i2c_probe,
 577        .id_table = ds3232_id,
 578};
 579
 580static int ds3232_register_driver(void)
 581{
 582        return i2c_add_driver(&ds3232_driver);
 583}
 584
 585static void ds3232_unregister_driver(void)
 586{
 587        i2c_del_driver(&ds3232_driver);
 588}
 589
 590#else
 591
 592static int ds3232_register_driver(void)
 593{
 594        return 0;
 595}
 596
 597static void ds3232_unregister_driver(void)
 598{
 599}
 600
 601#endif
 602
 603#if IS_ENABLED(CONFIG_SPI_MASTER)
 604
 605static int ds3234_probe(struct spi_device *spi)
 606{
 607        int res;
 608        unsigned int tmp;
 609        static const struct regmap_config config = {
 610                .reg_bits = 8,
 611                .val_bits = 8,
 612                .max_register = 0x13,
 613                .write_flag_mask = 0x80,
 614        };
 615        struct regmap *regmap;
 616
 617        regmap = devm_regmap_init_spi(spi, &config);
 618        if (IS_ERR(regmap)) {
 619                dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
 620                        __func__, PTR_ERR(regmap));
 621                return PTR_ERR(regmap);
 622        }
 623
 624        spi->mode = SPI_MODE_3;
 625        spi->bits_per_word = 8;
 626        spi_setup(spi);
 627
 628        res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
 629        if (res)
 630                return res;
 631
 632        /* Control settings
 633         *
 634         * CONTROL_REG
 635         * BIT 7        6       5       4       3       2       1       0
 636         *     EOSC     BBSQW   CONV    RS2     RS1     INTCN   A2IE    A1IE
 637         *
 638         *     0        0       0       1       1       1       0       0
 639         *
 640         * CONTROL_STAT_REG
 641         * BIT 7        6       5       4       3       2       1       0
 642         *     OSF      BB32kHz CRATE1  CRATE0  EN32kHz BSY     A2F     A1F
 643         *
 644         *     1        0       0       0       1       0       0       0
 645         */
 646        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 647        if (res)
 648                return res;
 649        res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
 650        if (res)
 651                return res;
 652
 653        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 654        if (res)
 655                return res;
 656        res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
 657        if (res)
 658                return res;
 659
 660        /* Print our settings */
 661        res = regmap_read(regmap, DS3232_REG_CR, &tmp);
 662        if (res)
 663                return res;
 664        dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
 665
 666        res = regmap_read(regmap, DS3232_REG_SR, &tmp);
 667        if (res)
 668                return res;
 669        dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
 670
 671        return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
 672}
 673
 674static struct spi_driver ds3234_driver = {
 675        .driver = {
 676                .name    = "ds3234",
 677        },
 678        .probe   = ds3234_probe,
 679};
 680
 681static int ds3234_register_driver(void)
 682{
 683        return spi_register_driver(&ds3234_driver);
 684}
 685
 686static void ds3234_unregister_driver(void)
 687{
 688        spi_unregister_driver(&ds3234_driver);
 689}
 690
 691#else
 692
 693static int ds3234_register_driver(void)
 694{
 695        return 0;
 696}
 697
 698static void ds3234_unregister_driver(void)
 699{
 700}
 701
 702#endif
 703
 704static int __init ds323x_init(void)
 705{
 706        int ret;
 707
 708        ret = ds3232_register_driver();
 709        if (ret) {
 710                pr_err("Failed to register ds3232 driver: %d\n", ret);
 711                return ret;
 712        }
 713
 714        ret = ds3234_register_driver();
 715        if (ret) {
 716                pr_err("Failed to register ds3234 driver: %d\n", ret);
 717                ds3232_unregister_driver();
 718        }
 719
 720        return ret;
 721}
 722module_init(ds323x_init)
 723
 724static void __exit ds323x_exit(void)
 725{
 726        ds3234_unregister_driver();
 727        ds3232_unregister_driver();
 728}
 729module_exit(ds323x_exit)
 730
 731MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
 732MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
 733MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
 734MODULE_LICENSE("GPL");
 735MODULE_ALIAS("spi:ds3234");
 736