Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: merge ds3232 and ds3234

According to "Feature Comparison of the DS323x Real-Time Clocks"
(http://pdfserv.maximintegrated.com/en/an/AN5143.pdf), DS3232 and
DS3234 are very similar.

This merges rtc-ds3232 and rtc-ds3234 with using regmap.
This change also enables to support alarm for ds3234.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Suggested-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

authored by

Akinobu Mita and committed by
Alexandre Belloni
080481f5 370927c4

+189 -194
+25 -19
drivers/rtc/Kconfig
··· 247 247 This driver can also be built as a module. If so, the module 248 248 will be called rtc-ds1672. 249 249 250 - config RTC_DRV_DS3232 251 - tristate "Dallas/Maxim DS3232" 252 - help 253 - If you say yes here you get support for Dallas Semiconductor 254 - DS3232 real-time clock chips. If an interrupt is associated 255 - with the device, the alarm functionality is supported. 256 - 257 - This driver can also be built as a module. If so, the module 258 - will be called rtc-ds3232. 259 - 260 250 config RTC_DRV_HYM8563 261 251 tristate "Haoyu Microelectronics HYM8563" 262 252 depends on OF ··· 723 733 This driver can also be built as a module. If so, the module 724 734 will be called rtc-max6902. 725 735 726 - config RTC_DRV_DS3234 727 - tristate "Maxim/Dallas DS3234" 728 - help 729 - If you say yes here you get support for the 730 - Maxim/Dallas DS3234 SPI RTC chip. 731 - 732 - This driver can also be built as a module. If so, the module 733 - will be called rtc-ds3234. 734 - 735 736 config RTC_DRV_PCF2123 736 737 tristate "NXP PCF2123" 737 738 help ··· 741 760 will be called rtc-mcp795. 742 761 743 762 endif # SPI_MASTER 763 + 764 + # 765 + # Helper to resolve issues with configs that have SPI enabled but I2C 766 + # modular. See SND_SOC_I2C_AND_SPI for more information 767 + # 768 + config RTC_I2C_AND_SPI 769 + tristate 770 + default m if I2C=m 771 + default y if I2C=y 772 + default y if SPI_MASTER=y 773 + select REGMAP_I2C if I2C 774 + select REGMAP_SPI if SPI_MASTER 775 + 776 + comment "SPI and I2C RTC drivers" 777 + 778 + config RTC_DRV_DS3232 779 + tristate "Dallas/Maxim DS3232/DS3234" 780 + depends on RTC_I2C_AND_SPI 781 + help 782 + If you say yes here you get support for Dallas Semiconductor 783 + DS3232 and DS3234 real-time clock chips. If an interrupt is associated 784 + with the device, the alarm functionality is supported. 785 + 786 + This driver can also be built as a module. If so, the module 787 + will be called rtc-ds3232. 744 788 745 789 comment "Platform RTC drivers" 746 790
-1
drivers/rtc/Makefile
··· 60 60 obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 61 61 obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o 62 62 obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o 63 - obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o 64 63 obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o 65 64 obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o 66 65 obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
+164 -3
drivers/rtc/rtc-ds3232.c
··· 1 1 /* 2 - * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C 2 + * RTC client/driver for the Maxim/Dallas DS3232/DS3234 Real-Time Clock 3 3 * 4 4 * Copyright (C) 2009-2011 Freescale Semiconductor. 5 5 * Author: Jack Lan <jack.lan@freescale.com> 6 + * Copyright (C) 2008 MIMOMax Wireless Ltd. 6 7 * 7 8 * This program is free software; you can redistribute it and/or modify it 8 9 * under the terms of the GNU General Public License as published by the ··· 17 16 #include <linux/module.h> 18 17 #include <linux/interrupt.h> 19 18 #include <linux/i2c.h> 19 + #include <linux/spi/spi.h> 20 20 #include <linux/rtc.h> 21 21 #include <linux/bcd.h> 22 22 #include <linux/workqueue.h> ··· 483 481 SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume) 484 482 }; 485 483 484 + #if IS_ENABLED(CONFIG_I2C) 485 + 486 486 static int ds3232_i2c_probe(struct i2c_client *client, 487 487 const struct i2c_device_id *id) 488 488 { ··· 524 520 .remove = ds3232_i2c_remove, 525 521 .id_table = ds3232_id, 526 522 }; 527 - module_i2c_driver(ds3232_driver); 523 + 524 + static int ds3232_register_driver(void) 525 + { 526 + return i2c_add_driver(&ds3232_driver); 527 + } 528 + 529 + static void ds3232_unregister_driver(void) 530 + { 531 + i2c_del_driver(&ds3232_driver); 532 + } 533 + 534 + #else 535 + 536 + static int ds3232_register_driver(void) 537 + { 538 + return 0; 539 + } 540 + 541 + static void ds3232_unregister_driver(void) 542 + { 543 + } 544 + 545 + #endif 546 + 547 + #if IS_ENABLED(CONFIG_SPI_MASTER) 548 + 549 + static int ds3234_probe(struct spi_device *spi) 550 + { 551 + int res; 552 + unsigned int tmp; 553 + static const struct regmap_config config = { 554 + .reg_bits = 8, 555 + .val_bits = 8, 556 + .write_flag_mask = 0x80, 557 + }; 558 + struct regmap *regmap; 559 + 560 + regmap = devm_regmap_init_spi(spi, &config); 561 + if (IS_ERR(regmap)) { 562 + dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n", 563 + __func__, PTR_ERR(regmap)); 564 + return PTR_ERR(regmap); 565 + } 566 + 567 + spi->mode = SPI_MODE_3; 568 + spi->bits_per_word = 8; 569 + spi_setup(spi); 570 + 571 + res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp); 572 + if (res) 573 + return res; 574 + 575 + /* Control settings 576 + * 577 + * CONTROL_REG 578 + * BIT 7 6 5 4 3 2 1 0 579 + * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE 580 + * 581 + * 0 0 0 1 1 1 0 0 582 + * 583 + * CONTROL_STAT_REG 584 + * BIT 7 6 5 4 3 2 1 0 585 + * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F 586 + * 587 + * 1 0 0 0 1 0 0 0 588 + */ 589 + res = regmap_read(regmap, DS3232_REG_CR, &tmp); 590 + if (res) 591 + return res; 592 + res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c); 593 + if (res) 594 + return res; 595 + 596 + res = regmap_read(regmap, DS3232_REG_SR, &tmp); 597 + if (res) 598 + return res; 599 + res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88); 600 + if (res) 601 + return res; 602 + 603 + /* Print our settings */ 604 + res = regmap_read(regmap, DS3232_REG_CR, &tmp); 605 + if (res) 606 + return res; 607 + dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp); 608 + 609 + res = regmap_read(regmap, DS3232_REG_SR, &tmp); 610 + if (res) 611 + return res; 612 + dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); 613 + 614 + return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234"); 615 + } 616 + 617 + static int ds3234_remove(struct spi_device *spi) 618 + { 619 + return ds3232_remove(&spi->dev); 620 + } 621 + 622 + static struct spi_driver ds3234_driver = { 623 + .driver = { 624 + .name = "ds3234", 625 + }, 626 + .probe = ds3234_probe, 627 + .remove = ds3234_remove, 628 + }; 629 + 630 + static int ds3234_register_driver(void) 631 + { 632 + return spi_register_driver(&ds3234_driver); 633 + } 634 + 635 + static void ds3234_unregister_driver(void) 636 + { 637 + spi_unregister_driver(&ds3234_driver); 638 + } 639 + 640 + #else 641 + 642 + static int ds3234_register_driver(void) 643 + { 644 + return 0; 645 + } 646 + 647 + static void ds3234_unregister_driver(void) 648 + { 649 + } 650 + 651 + #endif 652 + 653 + static int __init ds323x_init(void) 654 + { 655 + int ret; 656 + 657 + ret = ds3232_register_driver(); 658 + if (ret) { 659 + pr_err("Failed to register ds3232 driver: %d\n", ret); 660 + return ret; 661 + } 662 + 663 + ret = ds3234_register_driver(); 664 + if (ret) { 665 + pr_err("Failed to register ds3234 driver: %d\n", ret); 666 + ds3232_unregister_driver(); 667 + } 668 + 669 + return ret; 670 + } 671 + module_init(ds323x_init) 672 + 673 + static void __exit ds323x_exit(void) 674 + { 675 + ds3234_unregister_driver(); 676 + ds3232_unregister_driver(); 677 + } 678 + module_exit(ds323x_exit) 528 679 529 680 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>"); 530 - MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver"); 681 + MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>"); 682 + MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver"); 531 683 MODULE_LICENSE("GPL"); 684 + MODULE_ALIAS("spi:ds3234");
-171
drivers/rtc/rtc-ds3234.c
··· 1 - /* rtc-ds3234.c 2 - * 3 - * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal 4 - * and SRAM. 5 - * 6 - * Copyright (C) 2008 MIMOMax Wireless Ltd. 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License version 2 as 10 - * published by the Free Software Foundation. 11 - * 12 - */ 13 - 14 - #include <linux/init.h> 15 - #include <linux/module.h> 16 - #include <linux/device.h> 17 - #include <linux/platform_device.h> 18 - #include <linux/rtc.h> 19 - #include <linux/spi/spi.h> 20 - #include <linux/bcd.h> 21 - 22 - #define DS3234_REG_SECONDS 0x00 23 - #define DS3234_REG_MINUTES 0x01 24 - #define DS3234_REG_HOURS 0x02 25 - #define DS3234_REG_DAY 0x03 26 - #define DS3234_REG_DATE 0x04 27 - #define DS3234_REG_MONTH 0x05 28 - #define DS3234_REG_YEAR 0x06 29 - #define DS3234_REG_CENTURY (1 << 7) /* Bit 7 of the Month register */ 30 - 31 - #define DS3234_REG_CONTROL 0x0E 32 - #define DS3234_REG_CONT_STAT 0x0F 33 - 34 - static int ds3234_set_reg(struct device *dev, unsigned char address, 35 - unsigned char data) 36 - { 37 - struct spi_device *spi = to_spi_device(dev); 38 - unsigned char buf[2]; 39 - 40 - /* MSB must be '1' to indicate write */ 41 - buf[0] = address | 0x80; 42 - buf[1] = data; 43 - 44 - return spi_write_then_read(spi, buf, 2, NULL, 0); 45 - } 46 - 47 - static int ds3234_get_reg(struct device *dev, unsigned char address, 48 - unsigned char *data) 49 - { 50 - struct spi_device *spi = to_spi_device(dev); 51 - 52 - *data = address & 0x7f; 53 - 54 - return spi_write_then_read(spi, data, 1, data, 1); 55 - } 56 - 57 - static int ds3234_read_time(struct device *dev, struct rtc_time *dt) 58 - { 59 - int err; 60 - unsigned char buf[8]; 61 - struct spi_device *spi = to_spi_device(dev); 62 - 63 - buf[0] = 0x00; /* Start address */ 64 - 65 - err = spi_write_then_read(spi, buf, 1, buf, 8); 66 - if (err != 0) 67 - return err; 68 - 69 - /* Seconds, Minutes, Hours, Day, Date, Month, Year */ 70 - dt->tm_sec = bcd2bin(buf[0]); 71 - dt->tm_min = bcd2bin(buf[1]); 72 - dt->tm_hour = bcd2bin(buf[2] & 0x3f); 73 - dt->tm_wday = bcd2bin(buf[3]) - 1; /* 0 = Sun */ 74 - dt->tm_mday = bcd2bin(buf[4]); 75 - dt->tm_mon = bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */ 76 - dt->tm_year = bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */ 77 - 78 - return rtc_valid_tm(dt); 79 - } 80 - 81 - static int ds3234_set_time(struct device *dev, struct rtc_time *dt) 82 - { 83 - ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); 84 - ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); 85 - ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); 86 - 87 - /* 0 = Sun */ 88 - ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1)); 89 - ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday)); 90 - 91 - /* 0 = Jan */ 92 - ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1)); 93 - 94 - /* Assume 20YY although we just want to make sure not to go negative. */ 95 - if (dt->tm_year > 100) 96 - dt->tm_year -= 100; 97 - 98 - ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year)); 99 - 100 - return 0; 101 - } 102 - 103 - static const struct rtc_class_ops ds3234_rtc_ops = { 104 - .read_time = ds3234_read_time, 105 - .set_time = ds3234_set_time, 106 - }; 107 - 108 - static int ds3234_probe(struct spi_device *spi) 109 - { 110 - struct rtc_device *rtc; 111 - unsigned char tmp; 112 - int res; 113 - 114 - spi->mode = SPI_MODE_3; 115 - spi->bits_per_word = 8; 116 - spi_setup(spi); 117 - 118 - res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); 119 - if (res != 0) 120 - return res; 121 - 122 - /* Control settings 123 - * 124 - * CONTROL_REG 125 - * BIT 7 6 5 4 3 2 1 0 126 - * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE 127 - * 128 - * 0 0 0 1 1 1 0 0 129 - * 130 - * CONTROL_STAT_REG 131 - * BIT 7 6 5 4 3 2 1 0 132 - * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F 133 - * 134 - * 1 0 0 0 1 0 0 0 135 - */ 136 - ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp); 137 - ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c); 138 - 139 - ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); 140 - ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88); 141 - 142 - /* Print our settings */ 143 - ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp); 144 - dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp); 145 - 146 - ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); 147 - dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); 148 - 149 - rtc = devm_rtc_device_register(&spi->dev, "ds3234", 150 - &ds3234_rtc_ops, THIS_MODULE); 151 - if (IS_ERR(rtc)) 152 - return PTR_ERR(rtc); 153 - 154 - spi_set_drvdata(spi, rtc); 155 - 156 - return 0; 157 - } 158 - 159 - static struct spi_driver ds3234_driver = { 160 - .driver = { 161 - .name = "ds3234", 162 - }, 163 - .probe = ds3234_probe, 164 - }; 165 - 166 - module_spi_driver(ds3234_driver); 167 - 168 - MODULE_DESCRIPTION("DS3234 SPI RTC driver"); 169 - MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>"); 170 - MODULE_LICENSE("GPL"); 171 - MODULE_ALIAS("spi:ds3234");