summaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorSumit Sharma <sumsharma@nvidia.com>2012-10-16 10:15:38 +0530
committerSimone Willett <swillett@nvidia.com>2012-10-31 19:07:42 -0700
commit36971605863f4ed20e2a5b0ded23c58f4f3e5c54 (patch)
treebad598948f87ec412f2656fc59b3f1f05fe2bf73 /drivers/rtc
parent093772a30d7f8283fab1cf1c362a2bdf4d99abf7 (diff)
rtc: tps65910: Added rtc time init support
Added support for initializing rtc time Fixed IRQ numbers in header file Changed module name fro rtc-tps65910 to tps65910-rtc Bug 1055083 Change-Id: I067a52ef21e58eb03331d25417062f53e45b082d Signed-off-by: Sumit Sharma <sumsharma@nvidia.com> Reviewed-on: http://git-master/r/144765 GVS: Gerrit_Virtual_Submit Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-tps65910.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index 691ab967bfcb..1200930211b1 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -34,6 +34,10 @@ struct tps65910_rtc {
/* Total number of RTC registers needed to set time*/
#define NUM_TIME_REGS (TPS65910_YEARS - TPS65910_SECONDS + 1)
+#define OS_REF_YEAR 1900
+
+#define RTC_YEAR_OFFSET 100
+
static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
{
struct tps65910 *tps = dev_get_drvdata(dev->parent);
@@ -45,6 +49,21 @@ static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val);
}
+static int tps65910_rtc_valid_tm(struct rtc_time *tm)
+{
+ if (tm->tm_year >= (RTC_YEAR_OFFSET + 99)
+ || tm->tm_year < (RTC_YEAR_OFFSET)
+ || tm->tm_mon >= 12
+ || tm->tm_mday < 1
+ || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + OS_REF_YEAR)
+ || tm->tm_hour >= 24
+ || tm->tm_min >= 60
+ || tm->tm_sec >= 60)
+ return -EINVAL;
+ return 0;
+}
+
+
/*
* Gets current tps65910 RTC time and date parameters.
*
@@ -230,6 +249,7 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
int ret;
int irq;
u32 rtc_reg;
+ struct rtc_time tm;
tps65910 = dev_get_drvdata(pdev->dev.parent);
@@ -261,16 +281,43 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
return ret;
}
- irq += TPS65910_IRQ_RTC_ALARM;
+ irq += platform_get_irq(pdev, 0);
+
+ rtc_reg = INT_MSK_RTC_ALARM_IT_MSK_MASK;
+ ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n");
+ return ret;
+ }
+
+ rtc_reg = TPS65910_RTC_INTERRUPTS_IT_ALARM;
+ ret = regmap_write(tps65910->regmap, TPS65910_RTC_INTERRUPTS, rtc_reg);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n");
+ return ret;
+ }
+
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
- "rtc-tps65910", &pdev->dev);
+ "tps65910-rtc", &pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
return ret;
}
device_init_wakeup(&pdev->dev, 1);
+ tps65910_rtc_read_time(&pdev->dev, &tm);
+
+ if (tps65910_rtc_valid_tm(&tm) < 0) {
+ if (pmic_plat_data->time.tm_year < 2000 || pmic_plat_data->time.tm_year >= 2100) {
+ memset(&pmic_plat_data->time, 0, sizeof(pmic_plat_data->time));
+ pmic_plat_data->time.tm_year = 2000;
+ pmic_plat_data->time.tm_mday = 1;
+ }
+ pmic_plat_data->time.tm_year -= OS_REF_YEAR;
+ tps65910_rtc_set_time(&pdev->dev, &pmic_plat_data->time);
+ }
+
tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
&tps65910_rtc_ops, THIS_MODULE);
if (IS_ERR(tps_rtc->rtc)) {
@@ -341,8 +388,7 @@ static struct platform_driver tps65910_rtc_driver = {
.remove = __devexit_p(tps65910_rtc_remove),
.driver = {
.owner = THIS_MODULE,
- .name = "rtc-tps65910",
- .pm = DEV_PM_OPS,
+ .name = "tps65910-rtc",
},
};