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>

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

index 691ab96..1200930 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.
  *
@@ -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",
        },
 };
 
index cbb5409..98a34f0 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
 #define TPS65910_IRQ_GPIO_F                            9
 #define TPS65910_NUM_IRQ                               10
 
-#define TPS65911_IRQ_VBAT_VMBDCH                       0
-#define TPS65911_IRQ_VBAT_VMBDCH2L                     1
-#define TPS65911_IRQ_VBAT_VMBDCH2H                     2
-#define TPS65911_IRQ_VBAT_VMHI                         3
-#define TPS65911_IRQ_PWRON                             4
-#define TPS65911_IRQ_PWRON_LP                          5
-#define TPS65911_IRQ_PWRHOLD_F                         6
-#define TPS65911_IRQ_PWRHOLD_R                         7
-#define TPS65911_IRQ_HOTDIE                            8
-#define TPS65911_IRQ_RTC_ALARM                         9
-#define TPS65911_IRQ_RTC_PERIOD                                10
-#define TPS65911_IRQ_GPIO0_R                           11
-#define TPS65911_IRQ_GPIO0_F                           12
-#define TPS65911_IRQ_GPIO1_R                           13
-#define TPS65911_IRQ_GPIO1_F                           14
-#define TPS65911_IRQ_GPIO2_R                           15
-#define TPS65911_IRQ_GPIO2_F                           16
-#define TPS65911_IRQ_GPIO3_R                           17
-#define TPS65911_IRQ_GPIO3_F                           18
-#define TPS65911_IRQ_GPIO4_R                           19
-#define TPS65911_IRQ_GPIO4_F                           20
-#define TPS65911_IRQ_GPIO5_R                           21
-#define TPS65911_IRQ_GPIO5_F                           22
-#define TPS65911_IRQ_WTCHDG                            23
-#define TPS65911_IRQ_PWRDN                             24
-
-#define TPS65911_NUM_IRQ                               25
+#define TPS65911_IRQ_PWRHOLD_F                         0
+#define TPS65911_IRQ_VBAT_VMHI                         1
+#define TPS65911_IRQ_PWRON                             2
+#define TPS65911_IRQ_PWRON_LP                          3
+#define TPS65911_IRQ_PWRHOLD_R                         4
+#define TPS65911_IRQ_HOTDIE                            5
+#define TPS65911_IRQ_RTC_ALARM                         6
+#define TPS65911_IRQ_RTC_PERIOD                                7
+#define TPS65911_IRQ_GPIO0_R                           8
+#define TPS65911_IRQ_GPIO0_F                           9
+#define TPS65911_IRQ_GPIO1_R                           10
+#define TPS65911_IRQ_GPIO1_F                           11
+#define TPS65911_IRQ_GPIO2_R                           12
+#define TPS65911_IRQ_GPIO2_F                           13
+#define TPS65911_IRQ_GPIO3_R                           14
+#define TPS65911_IRQ_GPIO3_F                           15
+#define TPS65911_IRQ_GPIO4_R                           16
+#define TPS65911_IRQ_GPIO4_F                           17
+#define TPS65911_IRQ_GPIO5_R                           18
+#define TPS65911_IRQ_GPIO5_F                           19
+#define TPS65911_IRQ_WTCHDG                            20
+#define TPS65911_IRQ_VMBCH2_H                          21
+#define TPS65911_IRQ_VMBCH2_L                          22
+#define TPS65911_IRQ_PWRDN                             23
+
+#define TPS65911_NUM_IRQ                               24
+
 
 
 /* GPIO Register Definitions */
@@ -822,6 +823,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;
 };
 
 /**