diff options
author | Sumit Sharma <sumsharma@nvidia.com> | 2012-10-16 10:15:38 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-10-31 19:07:42 -0700 |
commit | 36971605863f4ed20e2a5b0ded23c58f4f3e5c54 (patch) | |
tree | bad598948f87ec412f2656fc59b3f1f05fe2bf73 /drivers/rtc | |
parent | 093772a30d7f8283fab1cf1c362a2bdf4d99abf7 (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.c | 54 |
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", }, }; |