0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/i2c.h>
0016 #include <linux/spi/spi.h>
0017 #include <linux/rtc.h>
0018 #include <linux/bcd.h>
0019 #include <linux/slab.h>
0020 #include <linux/regmap.h>
0021 #include <linux/hwmon.h>
0022
0023 #define DS3232_REG_SECONDS 0x00
0024 #define DS3232_REG_MINUTES 0x01
0025 #define DS3232_REG_HOURS 0x02
0026 #define DS3232_REG_AMPM 0x02
0027 #define DS3232_REG_DAY 0x03
0028 #define DS3232_REG_DATE 0x04
0029 #define DS3232_REG_MONTH 0x05
0030 #define DS3232_REG_CENTURY 0x05
0031 #define DS3232_REG_YEAR 0x06
0032 #define DS3232_REG_ALARM1 0x07
0033 #define DS3232_REG_ALARM2 0x0B
0034 #define DS3232_REG_CR 0x0E
0035 # define DS3232_REG_CR_nEOSC 0x80
0036 # define DS3232_REG_CR_INTCN 0x04
0037 # define DS3232_REG_CR_A2IE 0x02
0038 # define DS3232_REG_CR_A1IE 0x01
0039
0040 #define DS3232_REG_SR 0x0F
0041 # define DS3232_REG_SR_OSF 0x80
0042 # define DS3232_REG_SR_BSY 0x04
0043 # define DS3232_REG_SR_A2F 0x02
0044 # define DS3232_REG_SR_A1F 0x01
0045
0046 #define DS3232_REG_TEMPERATURE 0x11
0047 #define DS3232_REG_SRAM_START 0x14
0048 #define DS3232_REG_SRAM_END 0xFF
0049
0050 #define DS3232_REG_SRAM_SIZE 236
0051
0052 struct ds3232 {
0053 struct device *dev;
0054 struct regmap *regmap;
0055 int irq;
0056 struct rtc_device *rtc;
0057
0058 bool suspended;
0059 };
0060
0061 static int ds3232_check_rtc_status(struct device *dev)
0062 {
0063 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0064 int ret = 0;
0065 int control, stat;
0066
0067 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
0068 if (ret)
0069 return ret;
0070
0071 if (stat & DS3232_REG_SR_OSF)
0072 dev_warn(dev,
0073 "oscillator discontinuity flagged, "
0074 "time unreliable\n");
0075
0076 stat &= ~(DS3232_REG_SR_OSF | DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
0077
0078 ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
0079 if (ret)
0080 return ret;
0081
0082
0083
0084
0085
0086
0087 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
0088 if (ret)
0089 return ret;
0090
0091 control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
0092 control |= DS3232_REG_CR_INTCN;
0093
0094 return regmap_write(ds3232->regmap, DS3232_REG_CR, control);
0095 }
0096
0097 static int ds3232_read_time(struct device *dev, struct rtc_time *time)
0098 {
0099 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0100 int ret;
0101 u8 buf[7];
0102 unsigned int year, month, day, hour, minute, second;
0103 unsigned int week, twelve_hr, am_pm;
0104 unsigned int century, add_century = 0;
0105
0106 ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
0107 if (ret)
0108 return ret;
0109
0110 second = buf[0];
0111 minute = buf[1];
0112 hour = buf[2];
0113 week = buf[3];
0114 day = buf[4];
0115 month = buf[5];
0116 year = buf[6];
0117
0118
0119
0120 twelve_hr = hour & 0x40;
0121 am_pm = hour & 0x20;
0122 century = month & 0x80;
0123
0124
0125
0126 time->tm_sec = bcd2bin(second);
0127 time->tm_min = bcd2bin(minute);
0128 if (twelve_hr) {
0129
0130 if (am_pm)
0131 time->tm_hour = bcd2bin(hour & 0x1F) + 12;
0132 else
0133 time->tm_hour = bcd2bin(hour & 0x1F);
0134 } else {
0135 time->tm_hour = bcd2bin(hour);
0136 }
0137
0138
0139 time->tm_wday = bcd2bin(week) - 1;
0140 time->tm_mday = bcd2bin(day);
0141
0142 time->tm_mon = bcd2bin(month & 0x7F) - 1;
0143 if (century)
0144 add_century = 100;
0145
0146 time->tm_year = bcd2bin(year) + add_century;
0147
0148 return 0;
0149 }
0150
0151 static int ds3232_set_time(struct device *dev, struct rtc_time *time)
0152 {
0153 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0154 u8 buf[7];
0155
0156
0157
0158 buf[0] = bin2bcd(time->tm_sec);
0159 buf[1] = bin2bcd(time->tm_min);
0160 buf[2] = bin2bcd(time->tm_hour);
0161
0162 buf[3] = bin2bcd(time->tm_wday + 1);
0163 buf[4] = bin2bcd(time->tm_mday);
0164
0165 buf[5] = bin2bcd(time->tm_mon + 1);
0166 if (time->tm_year >= 100) {
0167 buf[5] |= 0x80;
0168 buf[6] = bin2bcd(time->tm_year - 100);
0169 } else {
0170 buf[6] = bin2bcd(time->tm_year);
0171 }
0172
0173 return regmap_bulk_write(ds3232->regmap, DS3232_REG_SECONDS, buf, 7);
0174 }
0175
0176
0177
0178
0179
0180
0181 static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0182 {
0183 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0184 int control, stat;
0185 int ret;
0186 u8 buf[4];
0187
0188 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
0189 if (ret)
0190 goto out;
0191 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
0192 if (ret)
0193 goto out;
0194 ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
0195 if (ret)
0196 goto out;
0197
0198 alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
0199 alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
0200 alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F);
0201 alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F);
0202
0203 alarm->enabled = !!(control & DS3232_REG_CR_A1IE);
0204 alarm->pending = !!(stat & DS3232_REG_SR_A1F);
0205
0206 ret = 0;
0207 out:
0208 return ret;
0209 }
0210
0211
0212
0213
0214
0215 static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0216 {
0217 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0218 int control, stat;
0219 int ret;
0220 u8 buf[4];
0221
0222 if (ds3232->irq <= 0)
0223 return -EINVAL;
0224
0225 buf[0] = bin2bcd(alarm->time.tm_sec);
0226 buf[1] = bin2bcd(alarm->time.tm_min);
0227 buf[2] = bin2bcd(alarm->time.tm_hour);
0228 buf[3] = bin2bcd(alarm->time.tm_mday);
0229
0230
0231 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
0232 if (ret)
0233 goto out;
0234 control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE);
0235 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
0236 if (ret)
0237 goto out;
0238
0239
0240 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
0241 if (ret)
0242 goto out;
0243 stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F);
0244 ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
0245 if (ret)
0246 goto out;
0247
0248 ret = regmap_bulk_write(ds3232->regmap, DS3232_REG_ALARM1, buf, 4);
0249 if (ret)
0250 goto out;
0251
0252 if (alarm->enabled) {
0253 control |= DS3232_REG_CR_A1IE;
0254 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
0255 }
0256 out:
0257 return ret;
0258 }
0259
0260 static int ds3232_update_alarm(struct device *dev, unsigned int enabled)
0261 {
0262 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0263 int control;
0264 int ret;
0265
0266 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
0267 if (ret)
0268 return ret;
0269
0270 if (enabled)
0271
0272 control |= DS3232_REG_CR_A1IE;
0273 else
0274
0275 control &= ~(DS3232_REG_CR_A1IE);
0276 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
0277
0278 return ret;
0279 }
0280
0281
0282
0283
0284
0285
0286 static int ds3232_hwmon_read_temp(struct device *dev, long int *mC)
0287 {
0288 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0289 u8 temp_buf[2];
0290 s16 temp;
0291 int ret;
0292
0293 ret = regmap_bulk_read(ds3232->regmap, DS3232_REG_TEMPERATURE, temp_buf,
0294 sizeof(temp_buf));
0295 if (ret < 0)
0296 return ret;
0297
0298
0299
0300
0301
0302 temp = (temp_buf[0] << 8) | temp_buf[1];
0303 temp >>= 6;
0304 *mC = temp * 250;
0305
0306 return 0;
0307 }
0308
0309 static umode_t ds3232_hwmon_is_visible(const void *data,
0310 enum hwmon_sensor_types type,
0311 u32 attr, int channel)
0312 {
0313 if (type != hwmon_temp)
0314 return 0;
0315
0316 switch (attr) {
0317 case hwmon_temp_input:
0318 return 0444;
0319 default:
0320 return 0;
0321 }
0322 }
0323
0324 static int ds3232_hwmon_read(struct device *dev,
0325 enum hwmon_sensor_types type,
0326 u32 attr, int channel, long *temp)
0327 {
0328 int err;
0329
0330 switch (attr) {
0331 case hwmon_temp_input:
0332 err = ds3232_hwmon_read_temp(dev, temp);
0333 break;
0334 default:
0335 err = -EOPNOTSUPP;
0336 break;
0337 }
0338
0339 return err;
0340 }
0341
0342 static u32 ds3232_hwmon_chip_config[] = {
0343 HWMON_C_REGISTER_TZ,
0344 0
0345 };
0346
0347 static const struct hwmon_channel_info ds3232_hwmon_chip = {
0348 .type = hwmon_chip,
0349 .config = ds3232_hwmon_chip_config,
0350 };
0351
0352 static u32 ds3232_hwmon_temp_config[] = {
0353 HWMON_T_INPUT,
0354 0
0355 };
0356
0357 static const struct hwmon_channel_info ds3232_hwmon_temp = {
0358 .type = hwmon_temp,
0359 .config = ds3232_hwmon_temp_config,
0360 };
0361
0362 static const struct hwmon_channel_info *ds3232_hwmon_info[] = {
0363 &ds3232_hwmon_chip,
0364 &ds3232_hwmon_temp,
0365 NULL
0366 };
0367
0368 static const struct hwmon_ops ds3232_hwmon_hwmon_ops = {
0369 .is_visible = ds3232_hwmon_is_visible,
0370 .read = ds3232_hwmon_read,
0371 };
0372
0373 static const struct hwmon_chip_info ds3232_hwmon_chip_info = {
0374 .ops = &ds3232_hwmon_hwmon_ops,
0375 .info = ds3232_hwmon_info,
0376 };
0377
0378 static void ds3232_hwmon_register(struct device *dev, const char *name)
0379 {
0380 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0381 struct device *hwmon_dev;
0382
0383 if (!IS_ENABLED(CONFIG_RTC_DRV_DS3232_HWMON))
0384 return;
0385
0386 hwmon_dev = devm_hwmon_device_register_with_info(dev, name, ds3232,
0387 &ds3232_hwmon_chip_info,
0388 NULL);
0389 if (IS_ERR(hwmon_dev)) {
0390 dev_err(dev, "unable to register hwmon device %ld\n",
0391 PTR_ERR(hwmon_dev));
0392 }
0393 }
0394
0395 static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
0396 {
0397 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0398
0399 if (ds3232->irq <= 0)
0400 return -EINVAL;
0401
0402 return ds3232_update_alarm(dev, enabled);
0403 }
0404
0405 static irqreturn_t ds3232_irq(int irq, void *dev_id)
0406 {
0407 struct device *dev = dev_id;
0408 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0409 int ret;
0410 int stat, control;
0411
0412 rtc_lock(ds3232->rtc);
0413
0414 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
0415 if (ret)
0416 goto unlock;
0417
0418 if (stat & DS3232_REG_SR_A1F) {
0419 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
0420 if (ret) {
0421 dev_warn(ds3232->dev,
0422 "Read Control Register error %d\n", ret);
0423 } else {
0424
0425 control &= ~(DS3232_REG_CR_A1IE);
0426 ret = regmap_write(ds3232->regmap, DS3232_REG_CR,
0427 control);
0428 if (ret) {
0429 dev_warn(ds3232->dev,
0430 "Write Control Register error %d\n",
0431 ret);
0432 goto unlock;
0433 }
0434
0435
0436 stat &= ~DS3232_REG_SR_A1F;
0437 ret = regmap_write(ds3232->regmap, DS3232_REG_SR, stat);
0438 if (ret) {
0439 dev_warn(ds3232->dev,
0440 "Write Status Register error %d\n",
0441 ret);
0442 goto unlock;
0443 }
0444
0445 rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
0446 }
0447 }
0448
0449 unlock:
0450 rtc_unlock(ds3232->rtc);
0451
0452 return IRQ_HANDLED;
0453 }
0454
0455 static const struct rtc_class_ops ds3232_rtc_ops = {
0456 .read_time = ds3232_read_time,
0457 .set_time = ds3232_set_time,
0458 .read_alarm = ds3232_read_alarm,
0459 .set_alarm = ds3232_set_alarm,
0460 .alarm_irq_enable = ds3232_alarm_irq_enable,
0461 };
0462
0463 static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
0464 size_t bytes)
0465 {
0466 struct regmap *ds3232_regmap = (struct regmap *)priv;
0467
0468 return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset,
0469 val, bytes);
0470 }
0471
0472 static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
0473 size_t bytes)
0474 {
0475 struct regmap *ds3232_regmap = (struct regmap *)priv;
0476
0477 return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset,
0478 val, bytes);
0479 }
0480
0481 static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
0482 const char *name)
0483 {
0484 struct ds3232 *ds3232;
0485 int ret;
0486 struct nvmem_config nvmem_cfg = {
0487 .name = "ds3232_sram",
0488 .stride = 1,
0489 .size = DS3232_REG_SRAM_SIZE,
0490 .word_size = 1,
0491 .reg_read = ds3232_nvmem_read,
0492 .reg_write = ds3232_nvmem_write,
0493 .priv = regmap,
0494 .type = NVMEM_TYPE_BATTERY_BACKED
0495 };
0496
0497 ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
0498 if (!ds3232)
0499 return -ENOMEM;
0500
0501 ds3232->regmap = regmap;
0502 ds3232->irq = irq;
0503 ds3232->dev = dev;
0504 dev_set_drvdata(dev, ds3232);
0505
0506 ret = ds3232_check_rtc_status(dev);
0507 if (ret)
0508 return ret;
0509
0510 if (ds3232->irq > 0)
0511 device_init_wakeup(dev, 1);
0512
0513 ds3232_hwmon_register(dev, name);
0514
0515 ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
0516 THIS_MODULE);
0517 if (IS_ERR(ds3232->rtc))
0518 return PTR_ERR(ds3232->rtc);
0519
0520 ret = devm_rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
0521 if(ret)
0522 return ret;
0523
0524 if (ds3232->irq > 0) {
0525 ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
0526 ds3232_irq,
0527 IRQF_SHARED | IRQF_ONESHOT,
0528 name, dev);
0529 if (ret) {
0530 device_set_wakeup_capable(dev, 0);
0531 ds3232->irq = 0;
0532 dev_err(dev, "unable to request IRQ\n");
0533 }
0534 }
0535
0536 return 0;
0537 }
0538
0539 #ifdef CONFIG_PM_SLEEP
0540 static int ds3232_suspend(struct device *dev)
0541 {
0542 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0543
0544 if (device_may_wakeup(dev)) {
0545 if (enable_irq_wake(ds3232->irq))
0546 dev_warn_once(dev, "Cannot set wakeup source\n");
0547 }
0548
0549 return 0;
0550 }
0551
0552 static int ds3232_resume(struct device *dev)
0553 {
0554 struct ds3232 *ds3232 = dev_get_drvdata(dev);
0555
0556 if (device_may_wakeup(dev))
0557 disable_irq_wake(ds3232->irq);
0558
0559 return 0;
0560 }
0561 #endif
0562
0563 static const struct dev_pm_ops ds3232_pm_ops = {
0564 SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
0565 };
0566
0567 #if IS_ENABLED(CONFIG_I2C)
0568
0569 static int ds3232_i2c_probe(struct i2c_client *client)
0570 {
0571 struct regmap *regmap;
0572 static const struct regmap_config config = {
0573 .reg_bits = 8,
0574 .val_bits = 8,
0575 .max_register = DS3232_REG_SRAM_END,
0576 };
0577
0578 regmap = devm_regmap_init_i2c(client, &config);
0579 if (IS_ERR(regmap)) {
0580 dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
0581 __func__, PTR_ERR(regmap));
0582 return PTR_ERR(regmap);
0583 }
0584
0585 return ds3232_probe(&client->dev, regmap, client->irq, client->name);
0586 }
0587
0588 static const struct i2c_device_id ds3232_id[] = {
0589 { "ds3232", 0 },
0590 { }
0591 };
0592 MODULE_DEVICE_TABLE(i2c, ds3232_id);
0593
0594 static const __maybe_unused struct of_device_id ds3232_of_match[] = {
0595 { .compatible = "dallas,ds3232" },
0596 { }
0597 };
0598 MODULE_DEVICE_TABLE(of, ds3232_of_match);
0599
0600 static struct i2c_driver ds3232_driver = {
0601 .driver = {
0602 .name = "rtc-ds3232",
0603 .of_match_table = of_match_ptr(ds3232_of_match),
0604 .pm = &ds3232_pm_ops,
0605 },
0606 .probe_new = ds3232_i2c_probe,
0607 .id_table = ds3232_id,
0608 };
0609
0610 static int ds3232_register_driver(void)
0611 {
0612 return i2c_add_driver(&ds3232_driver);
0613 }
0614
0615 static void ds3232_unregister_driver(void)
0616 {
0617 i2c_del_driver(&ds3232_driver);
0618 }
0619
0620 #else
0621
0622 static int ds3232_register_driver(void)
0623 {
0624 return 0;
0625 }
0626
0627 static void ds3232_unregister_driver(void)
0628 {
0629 }
0630
0631 #endif
0632
0633 #if IS_ENABLED(CONFIG_SPI_MASTER)
0634
0635 static int ds3234_probe(struct spi_device *spi)
0636 {
0637 int res;
0638 unsigned int tmp;
0639 static const struct regmap_config config = {
0640 .reg_bits = 8,
0641 .val_bits = 8,
0642 .max_register = DS3232_REG_SRAM_END,
0643 .write_flag_mask = 0x80,
0644 };
0645 struct regmap *regmap;
0646
0647 regmap = devm_regmap_init_spi(spi, &config);
0648 if (IS_ERR(regmap)) {
0649 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
0650 __func__, PTR_ERR(regmap));
0651 return PTR_ERR(regmap);
0652 }
0653
0654 spi->mode = SPI_MODE_3;
0655 spi->bits_per_word = 8;
0656 spi_setup(spi);
0657
0658 res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
0659 if (res)
0660 return res;
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676 res = regmap_read(regmap, DS3232_REG_CR, &tmp);
0677 if (res)
0678 return res;
0679 res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
0680 if (res)
0681 return res;
0682
0683 res = regmap_read(regmap, DS3232_REG_SR, &tmp);
0684 if (res)
0685 return res;
0686 res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
0687 if (res)
0688 return res;
0689
0690
0691 res = regmap_read(regmap, DS3232_REG_CR, &tmp);
0692 if (res)
0693 return res;
0694 dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
0695
0696 res = regmap_read(regmap, DS3232_REG_SR, &tmp);
0697 if (res)
0698 return res;
0699 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
0700
0701 return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
0702 }
0703
0704 static struct spi_driver ds3234_driver = {
0705 .driver = {
0706 .name = "ds3234",
0707 },
0708 .probe = ds3234_probe,
0709 };
0710
0711 static int ds3234_register_driver(void)
0712 {
0713 return spi_register_driver(&ds3234_driver);
0714 }
0715
0716 static void ds3234_unregister_driver(void)
0717 {
0718 spi_unregister_driver(&ds3234_driver);
0719 }
0720
0721 #else
0722
0723 static int ds3234_register_driver(void)
0724 {
0725 return 0;
0726 }
0727
0728 static void ds3234_unregister_driver(void)
0729 {
0730 }
0731
0732 #endif
0733
0734 static int __init ds323x_init(void)
0735 {
0736 int ret;
0737
0738 ret = ds3232_register_driver();
0739 if (ret) {
0740 pr_err("Failed to register ds3232 driver: %d\n", ret);
0741 return ret;
0742 }
0743
0744 ret = ds3234_register_driver();
0745 if (ret) {
0746 pr_err("Failed to register ds3234 driver: %d\n", ret);
0747 ds3232_unregister_driver();
0748 }
0749
0750 return ret;
0751 }
0752 module_init(ds323x_init)
0753
0754 static void __exit ds323x_exit(void)
0755 {
0756 ds3234_unregister_driver();
0757 ds3232_unregister_driver();
0758 }
0759 module_exit(ds323x_exit)
0760
0761 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
0762 MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
0763 MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
0764 MODULE_LICENSE("GPL");
0765 MODULE_ALIAS("spi:ds3234");