rtc: tps65910: Added rtc time init support
Sumit Sharma [Tue, 16 Oct 2012 04:45:38 +0000 (09:45 +0530)]
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>

Rebase-Id: R4585be954218589eb815447d12c0ae77900e3d32

drivers/rtc/rtc-tps65910.c
include/linux/mfd/tps65910.h

index a9caf04..c9e2aee 100644 (file)
@@ -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.
  *
@@ -229,6 +248,7 @@ static int 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);
 
@@ -266,6 +286,20 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
+       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 | IRQF_EARLY_RESUME,
                dev_name(&pdev->dev), &pdev->dev);
@@ -276,6 +310,18 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
        tps_rtc->irq = irq;
        device_set_wakeup_capable(&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 = devm_rtc_device_register(&pdev->dev, pdev->name,
                &tps65910_rtc_ops, THIS_MODULE);
        if (IS_ERR(tps_rtc->rtc)) {
index 455dac3..591bacd 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/gpio.h>
 #include <linux/regmap.h>
+#include <linux/rtc.h>
 
 /* TPS chip id list */
 #define TPS65910                       0
@@ -883,6 +884,7 @@ struct tps65910_board {
        bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
        unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
        struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
+       struct rtc_time time;
 };
 
 /**