aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig17
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-at91sam9.c2
-rw-r--r--drivers/rtc/rtc-bq32k.c12
-rw-r--r--drivers/rtc/rtc-cmos.c2
-rw-r--r--drivers/rtc/rtc-coh901331.c2
-rw-r--r--drivers/rtc/rtc-da9052.c293
-rw-r--r--drivers/rtc/rtc-davinci.c2
-rw-r--r--drivers/rtc/rtc-ds1305.c12
-rw-r--r--drivers/rtc/rtc-ds1307.c182
-rw-r--r--drivers/rtc/rtc-ds1374.c13
-rw-r--r--drivers/rtc/rtc-ds1390.c12
-rw-r--r--drivers/rtc/rtc-ds1511.c2
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-ds1672.c13
-rw-r--r--drivers/rtc/rtc-ds3232.c13
-rw-r--r--drivers/rtc/rtc-ds3234.c12
-rw-r--r--drivers/rtc/rtc-em3027.c13
-rw-r--r--drivers/rtc/rtc-fm3130.c12
-rw-r--r--drivers/rtc/rtc-isl12022.c13
-rw-r--r--drivers/rtc/rtc-isl1208.c15
-rw-r--r--drivers/rtc/rtc-lpc32xx.c2
-rw-r--r--drivers/rtc/rtc-ls1x.c210
-rw-r--r--drivers/rtc/rtc-m41t80.c13
-rw-r--r--drivers/rtc/rtc-m41t93.c12
-rw-r--r--drivers/rtc/rtc-m41t94.c14
-rw-r--r--drivers/rtc/rtc-max6900.c13
-rw-r--r--drivers/rtc/rtc-max6902.c12
-rw-r--r--drivers/rtc/rtc-max8925.c21
-rw-r--r--drivers/rtc/rtc-mpc5121.c4
-rw-r--r--drivers/rtc/rtc-mrst.c2
-rw-r--r--drivers/rtc/rtc-mv.c2
-rw-r--r--drivers/rtc/rtc-nuc900.c2
-rw-r--r--drivers/rtc/rtc-omap.c4
-rw-r--r--drivers/rtc/rtc-pcf2123.c13
-rw-r--r--drivers/rtc/rtc-pcf8563.c13
-rw-r--r--drivers/rtc/rtc-pcf8583.c13
-rw-r--r--drivers/rtc/rtc-pl030.c2
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/rtc/rtc-pm8xxx.c2
-rw-r--r--drivers/rtc/rtc-pxa.c4
-rw-r--r--drivers/rtc/rtc-r9701.c12
-rw-r--r--drivers/rtc/rtc-rs5c348.c13
-rw-r--r--drivers/rtc/rtc-rs5c372.c13
-rw-r--r--drivers/rtc/rtc-rv3029c2.c13
-rw-r--r--drivers/rtc/rtc-rx8025.c13
-rw-r--r--drivers/rtc/rtc-rx8581.c13
-rw-r--r--drivers/rtc/rtc-s35390a.c13
-rw-r--r--drivers/rtc/rtc-s3c.c4
-rw-r--r--drivers/rtc/rtc-sa1100.c7
-rw-r--r--drivers/rtc/rtc-sh.c8
-rw-r--r--drivers/rtc/rtc-spear.c100
-rw-r--r--drivers/rtc/rtc-stk17ta8.c2
-rw-r--r--drivers/rtc/rtc-twl.c28
-rw-r--r--drivers/rtc/rtc-tx4939.c2
-rw-r--r--drivers/rtc/rtc-vr41xx.c4
-rw-r--r--drivers/rtc/rtc-x1205.c13
57 files changed, 762 insertions, 502 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 3a125b83554..4f9fb25f945 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -554,6 +554,13 @@ config RTC_DRV_DS1742
This driver can also be built as a module. If so, the module
will be called rtc-ds1742.
+config RTC_DRV_DA9052
+ tristate "Dialog DA9052/DA9053 RTC"
+ depends on PMIC_DA9052
+ help
+ Say y here to support the RTC driver for Dialog Semiconductor
+ DA9052-BC and DA9053-AA/Bx PMICs.
+
config RTC_DRV_EFI
tristate "EFI RTC"
depends on IA64
@@ -1070,4 +1077,14 @@ config RTC_DRV_PUV3
This drive can also be built as a module. If so, the module
will be called rtc-puv3.
+config RTC_DRV_LOONGSON1
+ tristate "loongson1 RTC support"
+ depends on MACH_LOONGSON1
+ help
+ This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year
+ counter) to be used as a RTC.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ls1x.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e6982335c1..727ae7786e6 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
+obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
@@ -53,6 +54,7 @@ obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o
+obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o
obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o
obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index ee3c122c059..274a0aafe42 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -335,7 +335,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
/* register irq handler after we know what name we'll use */
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
- IRQF_DISABLED | IRQF_SHARED,
+ IRQF_SHARED,
dev_name(&rtc->rtcdev->dev), rtc);
if (ret) {
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 408cc8f735b..f090159dce4 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -187,17 +187,7 @@ static struct i2c_driver bq32k_driver = {
.id_table = bq32k_id,
};
-static __init int bq32k_init(void)
-{
- return i2c_add_driver(&bq32k_driver);
-}
-module_init(bq32k_init);
-
-static __exit void bq32k_exit(void)
-{
- i2c_del_driver(&bq32k_driver);
-}
-module_exit(bq32k_exit);
+module_i2c_driver(bq32k_driver);
MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index d7782aa0994..7d5f56edb8e 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
rtc_cmos_int_handler = cmos_interrupt;
retval = request_irq(rtc_irq, rtc_cmos_int_handler,
- IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev),
+ 0, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 80f9c88214c..a5b8a0c4ea8 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -199,7 +199,7 @@ static int __init coh901331_probe(struct platform_device *pdev)
}
rtap->irq = platform_get_irq(pdev, 0);
- if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED,
+ if (request_irq(rtap->irq, coh901331_interrupt, 0,
"RTC COH 901 331 Alarm", rtap)) {
ret = -EIO;
goto out_no_irq;
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
new file mode 100644
index 00000000000..da6ab5291a4
--- /dev/null
+++ b/drivers/rtc/rtc-da9052.c
@@ -0,0 +1,293 @@
+/*
+ * Real time clock driver for DA9052
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define rtc_err(da9052, fmt, ...) \
+ dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
+
+struct da9052_rtc {
+ struct rtc_device *rtc;
+ struct da9052 *da9052;
+ int irq;
+};
+
+static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable)
+{
+ int ret;
+ if (enable) {
+ ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+ DA9052_ALARM_Y_ALARM_ON,
+ DA9052_ALARM_Y_ALARM_ON);
+ if (ret != 0)
+ rtc_err(da9052, "Failed to enable ALM: %d\n", ret);
+ } else {
+ ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+ DA9052_ALARM_Y_ALARM_ON, 0);
+ if (ret != 0)
+ rtc_err(da9052, "Write error: %d\n", ret);
+ }
+ return ret;
+}
+
+static irqreturn_t da9052_rtc_irq(int irq, void *data)
+{
+ struct da9052_rtc *rtc = data;
+ int ret;
+
+ ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG);
+ if (ret < 0) {
+ rtc_err(rtc->da9052, "Read error: %d\n", ret);
+ return IRQ_NONE;
+ }
+
+ if (ret & DA9052_ALARMMI_ALARMTYPE) {
+ da9052_rtc_enable_alarm(rtc->da9052, 0);
+ rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
+ } else
+ rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF);
+
+ return IRQ_HANDLED;
+}
+
+static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+ int ret;
+ uint8_t v[5];
+
+ ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v);
+ if (ret != 0) {
+ rtc_err(da9052, "Failed to group read ALM: %d\n", ret);
+ return ret;
+ }
+
+ rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100;
+ rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1;
+ rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY;
+ rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR;
+ rtc_tm->tm_min = v[0] & DA9052_RTC_MIN;
+
+ ret = rtc_valid_tm(rtc_tm);
+ if (ret != 0)
+ return ret;
+ return ret;
+}
+
+static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+ int ret;
+ uint8_t v[3];
+
+ rtc_tm->tm_year -= 100;
+ rtc_tm->tm_mon += 1;
+
+ ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
+ DA9052_RTC_MIN, rtc_tm->tm_min);
+ if (ret != 0) {
+ rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret);
+ return ret;
+ }
+
+ v[0] = rtc_tm->tm_hour;
+ v[1] = rtc_tm->tm_mday;
+ v[2] = rtc_tm->tm_mon;
+
+ ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+ DA9052_RTC_YEAR, rtc_tm->tm_year);
+ if (ret != 0)
+ rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret);
+
+ return ret;
+}
+
+static int da9052_rtc_get_alarm_status(struct da9052 *da9052)
+{
+ int ret;
+
+ ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG);
+ if (ret < 0) {
+ rtc_err(da9052, "Failed to read ALM: %d\n", ret);
+ return ret;
+ }
+ ret &= DA9052_ALARM_Y_ALARM_ON;
+ return (ret > 0) ? 1 : 0;
+}
+
+static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
+{
+ struct da9052_rtc *rtc = dev_get_drvdata(dev);
+ uint8_t v[6];
+ int ret;
+
+ ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+ if (ret < 0) {
+ rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret);
+ return ret;
+ }
+
+ rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100;
+ rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1;
+ rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY;
+ rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR;
+ rtc_tm->tm_min = v[1] & DA9052_RTC_MIN;
+ rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC;
+
+ ret = rtc_valid_tm(rtc_tm);
+ if (ret != 0) {
+ rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct da9052_rtc *rtc;
+ uint8_t v[6];
+
+ rtc = dev_get_drvdata(dev);
+
+ v[0] = tm->tm_sec;
+ v[1] = tm->tm_min;
+ v[2] = tm->tm_hour;
+ v[3] = tm->tm_mday;
+ v[4] = tm->tm_mon + 1;
+ v[5] = tm->tm_year - 100;
+
+ return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+}
+
+static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ int ret;
+ struct rtc_time *tm = &alrm->time;
+ struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+ ret = da9052_read_alarm(rtc->da9052, tm);
+
+ if (ret)
+ return ret;
+
+ alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052);
+
+ return 0;
+}
+
+static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ int ret;
+ struct rtc_time *tm = &alrm->time;
+ struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+ ret = da9052_rtc_enable_alarm(rtc->da9052, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_set_alarm(rtc->da9052, tm);
+ if (ret)
+ return ret;
+
+ ret = da9052_rtc_enable_alarm(rtc->da9052, 1);
+
+ return ret;
+}
+
+static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+ return da9052_rtc_enable_alarm(rtc->da9052, enabled);
+}
+
+static const struct rtc_class_ops da9052_rtc_ops = {
+ .read_time = da9052_rtc_read_time,
+ .set_time = da9052_rtc_set_time,
+ .read_alarm = da9052_rtc_read_alarm,
+ .set_alarm = da9052_rtc_set_alarm,
+ .alarm_irq_enable = da9052_rtc_alarm_irq_enable,
+};
+
+static int __devinit da9052_rtc_probe(struct platform_device *pdev)
+{
+ struct da9052_rtc *rtc;
+ int ret;
+
+ rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
+ platform_set_drvdata(pdev, rtc);
+ rtc->irq = platform_get_irq_byname(pdev, "ALM");
+ ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "ALM", rtc);
+ if (ret != 0) {
+ rtc_err(rtc->da9052, "irq registration failed: %d\n", ret);
+ goto err_mem;
+ }
+
+ rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &da9052_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc->rtc)) {
+ ret = PTR_ERR(rtc->rtc);
+ goto err_free_irq;
+ }
+
+ return 0;
+
+err_free_irq:
+ free_irq(rtc->irq, rtc);
+err_mem:
+ devm_kfree(&pdev->dev, rtc);
+ return ret;
+}
+
+static int __devexit da9052_rtc_remove(struct platform_device *pdev)
+{
+ struct da9052_rtc *rtc = pdev->dev.platform_data;
+
+ rtc_device_unregister(rtc->rtc);
+ free_irq(rtc->irq, rtc);
+ platform_set_drvdata(pdev, NULL);
+ devm_kfree(&pdev->dev, rtc);
+
+ return 0;
+}
+
+static struct platform_driver da9052_rtc_driver = {
+ .probe = da9052_rtc_probe,
+ .remove = __devexit_p(da9052_rtc_remove),
+ .driver = {
+ .name = "da9052-rtc",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(da9052_rtc_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-rtc");
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
index 755e1fe914a..14c2109dbaa 100644
--- a/drivers/rtc/rtc-davinci.c
+++ b/drivers/rtc/rtc-davinci.c
@@ -542,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
- IRQF_DISABLED, "davinci_rtc", davinci_rtc);
+ 0, "davinci_rtc", davinci_rtc);
if (ret < 0) {
dev_err(dev, "unable to register davinci RTC interrupt\n");
goto fail4;
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index 3a33b1fdbe0..686a865913e 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -814,17 +814,7 @@ static struct spi_driver ds1305_driver = {
/* REVISIT add suspend/resume */
};
-static int __init ds1305_init(void)
-{
- return spi_register_driver(&ds1305_driver);
-}
-module_init(ds1305_init);
-
-static void __exit ds1305_exit(void)
-{
- spi_unregister_driver(&ds1305_driver);
-}
-module_exit(ds1305_exit);
+module_spi_driver(ds1305_driver);
MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 62b0763b7b9..cd188ab72f7 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -20,7 +20,8 @@
-/* We can't determine type by probing, but if we expect pre-Linux code
+/*
+ * We can't determine type by probing, but if we expect pre-Linux code
* to have set the chip up as a clock (turning on the oscillator and
* setting the date and time), Linux can ignore the non-clock features.
* That's a natural job for a factory or repair bench.
@@ -36,7 +37,8 @@ enum ds_type {
m41t00,
mcp7941x,
rx_8025,
- // rs5c372 too? different address...
+ last_ds_type /* always last */
+ /* rs5c372 too? different address... */
};
@@ -58,7 +60,8 @@ enum ds_type {
# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
#define DS1307_REG_YEAR 0x06 /* 00-99 */
-/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
+/*
+ * Other registers (control, status, alarms, trickle charge, NVRAM, etc)
* start at 7, and they differ a LOT. Only control and status matter for
* basic RTC date and time functionality; be careful using them.
*/
@@ -102,6 +105,8 @@ enum ds_type {
struct ds1307 {
u8 offset; /* register's offset */
u8 regs[11];
+ u16 nvram_offset;
+ struct bin_attribute *nvram;
enum ds_type type;
unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
@@ -116,34 +121,35 @@ struct ds1307 {
};
struct chip_desc {
- unsigned nvram56:1;
unsigned alarm:1;
+ u16 nvram_offset;
+ u16 nvram_size;
};
-static const struct chip_desc chips[] = {
-[ds_1307] = {
- .nvram56 = 1,
-},
-[ds_1337] = {
- .alarm = 1,
-},
-[ds_1338] = {
- .nvram56 = 1,
-},
-[ds_1339] = {
- .alarm = 1,
-},
-[ds_1340] = {
-},
-[ds_3231] = {
- .alarm = 1,
-},
-[m41t00] = {
-},
-[mcp7941x] = {
-},
-[rx_8025] = {
-}, };
+static const struct chip_desc chips[last_ds_type] = {
+ [ds_1307] = {
+ .nvram_offset = 8,
+ .nvram_size = 56,
+ },
+ [ds_1337] = {
+ .alarm = 1,
+ },
+ [ds_1338] = {
+ .nvram_offset = 8,
+ .nvram_size = 56,
+ },
+ [ds_1339] = {
+ .alarm = 1,
+ },
+ [ds_3231] = {
+ .alarm = 1,
+ },
+ [mcp7941x] = {
+ /* this is battery backed SRAM */
+ .nvram_offset = 0x20,
+ .nvram_size = 0x40,
+ },
+};
static const struct i2c_device_id ds1307_id[] = {
{ "ds1307", ds_1307 },
@@ -372,6 +378,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
| DS1340_BIT_CENTURY;
break;
case mcp7941x:
+ /*
+ * these bits were cleared when preparing the date/time
+ * values and need to be set again before writing the
+ * buffer out to the device.
+ */
buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST;
buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN;
break;
@@ -417,7 +428,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
ds1307->regs[6], ds1307->regs[7],
ds1307->regs[8]);
- /* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
+ /*
+ * report alarm time (ALARM1); assume 24 hour and day-of-month modes,
* and that all four fields are checked matches
*/
t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
@@ -445,7 +457,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
unsigned char *buf = ds1307->regs;
u8 control, status;
@@ -541,8 +553,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
/*----------------------------------------------------------------------*/
-#define NVRAM_SIZE 56
-
static ssize_t
ds1307_nvram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
@@ -555,14 +565,15 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj,
client = kobj_to_i2c_client(kobj);
ds1307 = i2c_get_clientdata(client);
- if (unlikely(off >= NVRAM_SIZE))
+ if (unlikely(off >= ds1307->nvram->size))
return 0;
- if ((off + count) > NVRAM_SIZE)
- count = NVRAM_SIZE - off;
+ if ((off + count) > ds1307->nvram->size)
+ count = ds1307->nvram->size - off;
if (unlikely(!count))
return count;
- result = ds1307->read_block_data(client, 8 + off, count, buf);
+ result = ds1307->read_block_data(client, ds1307->nvram_offset + off,
+ count, buf);
if (result < 0)
dev_err(&client->dev, "%s error %d\n", "nvram read", result);
return result;
@@ -580,14 +591,15 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
client = kobj_to_i2c_client(kobj);
ds1307 = i2c_get_clientdata(client);
- if (unlikely(off >= NVRAM_SIZE))
+ if (unlikely(off >= ds1307->nvram->size))
return -EFBIG;
- if ((off + count) > NVRAM_SIZE)
- count = NVRAM_SIZE - off;
+ if ((off + count) > ds1307->nvram->size)
+ count = ds1307->nvram->size - off;
if (unlikely(!count))
return count;
- result = ds1307->write_block_data(client, 8 + off, count, buf);
+ result = ds1307->write_block_data(client, ds1307->nvram_offset + off,
+ count, buf);
if (result < 0) {
dev_err(&client->dev, "%s error %d\n", "nvram write", result);
return result;
@@ -595,21 +607,8 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
return count;
}
-static struct bin_attribute nvram = {
- .attr = {
- .name = "nvram",
- .mode = S_IRUGO | S_IWUSR,
- },
-
- .read = ds1307_nvram_read,
- .write = ds1307_nvram_write,
- .size = NVRAM_SIZE,
-};
-
/*----------------------------------------------------------------------*/
-static struct i2c_driver ds1307_driver;
-
static int __devinit ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -630,7 +629,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
- if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
+ ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL);
+ if (!ds1307)
return -ENOMEM;
i2c_set_clientdata(client, ds1307);
@@ -652,11 +652,6 @@ static int __devinit ds1307_probe(struct i2c_client *client,
case ds_1337:
case ds_1339:
case ds_3231:
- /* has IRQ? */
- if (ds1307->client->irq > 0 && chip->alarm) {
- INIT_WORK(&ds1307->work, ds1307_work);
- want_irq = true;
- }
/* get registers that the "rtc" read below won't read... */
tmp = ds1307->read_block_data(ds1307->client,
DS1337_REG_CONTROL, 2, buf);
@@ -670,14 +665,19 @@ static int __devinit ds1307_probe(struct i2c_client *client,
if (ds1307->regs[0] & DS1337_BIT_nEOSC)
ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
- /* Using IRQ? Disable the square wave and both alarms.
+ /*
+ * Using IRQ? Disable the square wave and both alarms.
* For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW)
*/
- if (want_irq) {
+ if (ds1307->client->irq > 0 && chip->alarm) {
+ INIT_WORK(&ds1307-