Changeset 119


Ignore:
Timestamp:
Apr 12, 2011, 3:15:05 PM (6 years ago)
Author:
phj
Message:

RTC year and localtime

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kern_2.6.32/drivers/rtc/rtc-s3c.c

    r118 r119  
    3333#define CONFIG_RTC_SYNC 
    3434 
     35#define I8000_RTC 
     36//I8000_RTC means: the problem caused by to store the localtime in the RTC 
     37// in Windows CE elimination: the very first set of the RTC time not executed 
     38// ( no value stored in the RTC, but from now the difference stored in a variable 
     39// and each corresponding set/get RTC time call will adjust the read/write values 
     40// with that ). In this way the RTC will contain always the local time untouched, but the 
     41// system "knows" it is in UTC. Because the first gettime anyhow results local time 
     42// instead of UTC, on the android part must issue a hwclock -l -s command to correct it! 
     43 
     44#ifdef I8000_RTC 
     45// The year value in the RTC (from WinMo) contains a +20 year difference in i8000 
     46#define I8000_YEAR_CORRECT 20 
     47#endif 
     48 
    3549#ifdef CONFIG_RTC_SYNC 
    3650#include <linux/cpufreq.h> 
     
    4256 
    4357#ifdef SET_RTC_DEFAULT_RESET_TIME 
    44 #define DEFAULT_RESET_TIME_YEAR         (2001) //factory sequence 
    45 #define DEFAULT_RESET_TIME_YEAR_MAX (2037) 
     58#define DEFAULT_RESET_TIME_YEAR         (2000) 
    4659#define DEFAULT_RESET_TIME_MON          (1) 
    4760#define DEFAULT_RESET_TIME_DATE         (1) 
     
    172185        int                     cpu_idle; 
    173186 
    174         if (rtc_sync_state == RS_SAVE_DELTA) 
     187        switch (rtc_sync_state) 
    175188        { 
     189        case RS_SAVE_DELTA: 
    176190                rtc_sync_save_delta(); 
    177191                rtc_sync_start(); 
    178192                return; 
    179         } 
    180  
    181         switch (rtc_sync_state) 
    182         { 
    183193        case RS_WAIT_ADJUST_TIME: 
    184194                /* start adjust service */ 
     
    291301 
    292302/* Time read/write */ 
     303#ifdef I8000_RTC 
     304static int zone_diff=0;         // the timezone difference, valid after the first set RTC time call 
     305static int already_set=0;       // marker for valid zone_diff 
     306#endif 
    293307 
    294308static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 
     
    296310        unsigned int have_retried = 0; 
    297311        void __iomem *base = s3c_rtc_base; 
     312        int year_bin; 
    298313 
    299314 retry_get_time: 
     
    305320        rtc_tm->tm_sec  = readb(base + S3C_RTCSEC); 
    306321 
     322        year_bin = bcd2bin(rtc_tm->tm_year) - I8000_YEAR_CORRECT; //bss 
     323//      rtc_tm->tm_year = bin2bcd(year_bin);    //bss 
     324 
    307325        /* the only way to work out wether the system was mid-update 
    308326         * when we read it is to check the second counter, and if it 
     
    315333        } 
    316334 
    317         pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n", 
     335        pr_debug("BCD time  %02x.%02x.%02x %02x:%02x:%02x\n", 
    318336                 rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, 
    319337                 rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); 
     
    324342        rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); 
    325343        rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); 
    326         rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); 
     344        rtc_tm->tm_year = year_bin; //bcd2bin(rtc_tm->tm_year); 
    327345 
    328346        rtc_tm->tm_year += 100; 
    329347        rtc_tm->tm_mon -= 1; 
    330  
    331         //factory sequence 
    332         if((rtc_tm->tm_year < (DEFAULT_RESET_TIME_YEAR - 1900)) || (rtc_tm->tm_year > (DEFAULT_RESET_TIME_YEAR_MAX - 1900))) 
    333         { 
    334                 rtc_tm->tm_sec = DEFAULT_RESET_TIME_SEC; 
    335                 rtc_tm->tm_min = DEFAULT_RESET_TIME_MIN; 
    336                 rtc_tm->tm_hour = DEFAULT_RESET_TIME_HOUR; 
    337                 rtc_tm->tm_mday = DEFAULT_RESET_TIME_DATE; 
    338                 rtc_tm->tm_mon = DEFAULT_RESET_TIME_MON - 1; 
    339                 rtc_tm->tm_year = DEFAULT_RESET_TIME_YEAR - 1900; 
    340         } 
    341  
    342         pr_debug("read time %02d/%02d/%02d %02d.%02d.%02d\n", 
    343                  rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, 
    344                  rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); 
     348#ifdef I8000_RTC 
     349///////// special i8000! RTC store the locale time not UTC, so we must cheat..... 
     350        if (!already_set) { 
     351                zone_diff = rtc_tm->tm_hour; 
     352        } else { 
     353                rtc_tm->tm_hour += zone_diff + 1; //1 is an unknown offset?? 
     354                if (rtc_tm->tm_hour<0) { rtc_tm->tm_hour+=24; rtc_tm->tm_mday--;} // todo: month,year 
     355                if (rtc_tm->tm_hour>=24) { rtc_tm->tm_hour-=24; rtc_tm->tm_mday++;} 
     356        } 
     357#endif 
     358        pr_debug("read time %02d.%02d.%02d %02d:%02d:%02d\n", 
     359         rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, 
     360         rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); 
    345361 
    346362        return 0; 
     
    352368        int year = tm->tm_year - 100; 
    353369 
    354         pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", 
     370        pr_debug("set time %02d.%02d.%02d %02d:%02d:%02d\n", 
    355371                 tm->tm_year, tm->tm_mon, tm->tm_mday, 
    356372                 tm->tm_hour, tm->tm_min, tm->tm_sec); 
     
    361377#endif  /* CONFIG_RTC_SYNC */ 
    362378 
     379#ifdef I8000_RTC 
     380        if ( !already_set ) { 
     381                already_set=1; 
     382                zone_diff=tm->tm_hour-zone_diff;        // the difference in tz + 1! 
     383                printk("I8000 TZ diff: %d hours\n",zone_diff); 
     384                return 0; 
     385        } 
     386        tm->tm_hour-=zone_diff; 
     387        if (tm->tm_hour<0) { tm->tm_hour+=24; tm->tm_mday--;} 
     388        if (tm->tm_hour>=24) { tm->tm_hour-=24; tm->tm_mday++;} 
     389#endif 
    363390        /* we get around y2k by simply not supporting it */ 
    364391 
     
    373400        writeb(bin2bcd(tm->tm_mday), base + S3C_RTCDATE); 
    374401        writeb(bin2bcd(tm->tm_mon + 1), base + S3C_RTCMON); 
    375         writeb(bin2bcd(year), base + S3C_RTCYEAR); 
     402        writeb(bin2bcd(year + I8000_YEAR_CORRECT), base + S3C_RTCYEAR); //bss 
    376403 
    377404        return 0; 
     
    430457        } 
    431458 
    432         if (alm_en & S3C_RTCALM_YEAREN) 
    433                 alm_tm->tm_year = bcd2bin(alm_tm->tm_year); 
    434         else 
     459        if (alm_en & S3C_RTCALM_YEAREN) { 
     460                alm_tm->tm_year = bcd2bin(alm_tm->tm_year)-I8000_YEAR_CORRECT; 
     461                alm_tm->tm_year += 100; 
     462        } else 
    435463                alm_tm->tm_year = 0xffff; 
    436464 
     
    446474        int year = tm->tm_year - 100; 
    447475 
    448         pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", 
     476        pr_debug("s3c_rtc_setalarm: %d, %02d/%02d/%02d %02d:%02d:%02d\n", 
    449477                 alrm->enabled, 
    450478                 tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff, 
     
    481509        if (year < 100 && year >= 0) { 
    482510                alrm_en |= S3C_RTCALM_YEAREN; 
    483                 writeb(bin2bcd(year), base + S3C_ALMYEAR); 
     511                writeb(bin2bcd(year+I8000_YEAR_CORRECT), base + S3C_ALMYEAR); 
    484512        } 
    485513 
     
    610638 
    611639        s3c_rtc_enable_set(pdev,base,en); 
    612                 } 
     640} 
    613641 
    614642static int s3c_rtc_remove(struct platform_device *dev) 
Note: See TracChangeset for help on using the changeset viewer.