static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) { void __iomem *base = s3c_rtc_base; int year = tm->tm_year - 100; pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME cancel_delayed_work(&rtc_sync_work); rtc_sync_start_save_delta (); #endif /* CONFIG_RTC_S3C_SYNC_SYSTEM_TIME */ /* we get around y2k by simply not supporting it */ if (year < 0 || year >= 100) { dev_err(dev, "rtc only supports 100 years\n"); return -EINVAL; } #ifdef CONFIG_RTC_DRV_MAX8998 max8998_rtc_set_time(tm); #endif writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); #if defined(CONFIG_CPU_S5PC110) year = (0x00000fff & year); writel(bin2bcd(year), base + S3C2410_RTCYEAR); #else writeb(bin2bcd(year), base + S3C2410_RTCYEAR); #endif return 0; }
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) { void __iomem *base = s3c_rtc_base; int year = tm->tm_year - 100; pr_debug("set time %02d.%02d.%02d %02d:%02d:%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); #ifdef CONFIG_RTC_SYNC cancel_delayed_work(&rtc_sync_work); rtc_sync_start_save_delta (); #endif /* CONFIG_RTC_SYNC */ #ifdef I8000_RTC if ( !already_set ) { already_set=1; tm->tm_hour=tm->tm_hour; // the difference in tz + 1! printk("I8000 TZ diff: %d hours\n",zone_diff); return 0; } if (tm->tm_hour<0) { tm->tm_hour+=24; tm->tm_mday--;} if (tm->tm_hour>=24) { tm->tm_hour-=24; tm->tm_mday++;} #endif /* we get around y2k by simply not supporting it */ if (year < 0 || year >= 100) { dev_err(dev, "rtc only supports 100 years\n"); return -EINVAL; } writeb(bin2bcd(tm->tm_sec), base + S3C_RTCSEC); writeb(bin2bcd(tm->tm_min), base + S3C_RTCMIN); writeb(bin2bcd(tm->tm_hour), base + S3C_RTCHOUR); writeb(bin2bcd(tm->tm_mday), base + S3C_RTCDATE); writeb(bin2bcd(tm->tm_mon + 1), base + S3C_RTCMON); writeb(bin2bcd(year + I8000_YEAR_CORRECT), base + S3C_RTCYEAR); //bss return 0; }
static int __devinit s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; unsigned char bcd_tmp,bcd_loop; int ret; #ifdef CONFIG_RTC_DRV_MAX8998 struct rtc_time tm; #endif pr_debug("%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, res->end - res->start + 1); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C2410_RTCCON)); s3c_rtc_setfreq(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1); #ifdef CONFIG_RTC_DRV_MAX8998 max8998_rtc_read_time(&tm); #endif /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } rtc->max_user_freq = S3C_MAX_CNT; #ifdef CONFIG_RTC_DRV_MAX8998 s3c_rtc_settime(rtc, &tm); //update from pmic #endif #ifdef SET_RTC_DEFAULT_RESET_TIME { struct rtc_time tm; s3c_rtc_gettime (pdev, &tm); if (rtc_valid_tm (&tm) != 0) { struct rtc_time reset_tm = { .tm_sec = DEFAULT_RESET_TIME_SEC, .tm_min = DEFAULT_RESET_TIME_MIN, .tm_hour = DEFAULT_RESET_TIME_HOUR, .tm_mday = DEFAULT_RESET_TIME_DATE, .tm_mon = DEFAULT_RESET_TIME_MON - 1, .tm_year = DEFAULT_RESET_TIME_YEAR - 1900, }; s3c_rtc_settime (pdev, &reset_tm); #ifdef CONFIG_RTC_DRV_MAX8998 max8998_rtc_set_time(&reset_tm); // also update pmic rtc as default #endif } } #else /* check rtc time */ for (bcd_loop = S3C2410_RTCSEC ; bcd_loop <= S3C2410_RTCYEAR ; bcd_loop +=0x4) { bcd_tmp = readb(s3c_rtc_base + bcd_loop); if(((bcd_tmp & 0xf) > 0x9) || ((bcd_tmp & 0xf0) > 0x90)) writeb(0, s3c_rtc_base + bcd_loop); } #endif /* SET_RTC_DEFAULT_RESET_TIME */ platform_set_drvdata(pdev, rtc); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME rtc_sync_start_save_delta(); #endif /* CONFIG_RTC_S3C_SYNC_SYSTEM_TIME */ return 0; err_nortc: s3c_rtc_enable(pdev, 0); iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; } #ifdef CONFIG_PM /* RTC Power management control */ static struct timespec s3c_rtc_delta; static int ticnt_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { struct rtc_time tm; struct timespec time; time.tv_nsec = 0; /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); s3c_rtc_gettime(&pdev->dev, &tm); rtc_tm_to_time(&tm, &time.tv_sec); save_time_delta(&s3c_rtc_delta, &time); if (gpio_get_value(GPIO_WLAN_BT_EN) == 0) /* BCM4329 isnt working */ s3c_rtc_enable(pdev, 0); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME cancel_delayed_work(&rtc_sync_work); #endif /* CONFIG_RTC_S3C_SYNC_SYSTEM_TIME */ return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { struct rtc_time tm; struct timespec time; time.tv_nsec = 0; if (gpio_get_value(GPIO_WLAN_BT_EN) == 0) /* BCM4329 isnt working */ s3c_rtc_enable(pdev, 1); s3c_rtc_gettime(&pdev->dev, &tm); rtc_tm_to_time(&tm, &time.tv_sec); restore_time_delta(&s3c_rtc_delta, &time); writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); #ifdef CONFIG_RTC_S3C_SYNC_SYSTEM_TIME rtc_sync_start (); #endif return 0; } #else #define s3c_rtc_suspend NULL #define s3c_rtc_resume NULL #endif static struct platform_driver s3c2410_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, .driver = { .name = "s3c2410-rtc", .owner = THIS_MODULE, }, }; static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n"; static int __init s3c_rtc_init(void) { printk(banner); return platform_driver_register(&s3c2410_rtc_driver); }
static int s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; int ret; //unsigned char bcd_tmp,bcd_loop; pr_debug("%s: probe=%p\n", __func__, pdev); /* find the IRQs */ s3c_rtc_tickno = platform_get_irq(pdev, 1); if (s3c_rtc_tickno < 0) { dev_err(&pdev->dev, "no irq for rtc tick\n"); return -ENOENT; } s3c_rtc_alarmno = platform_get_irq(pdev, 0); if (s3c_rtc_alarmno < 0) { dev_err(&pdev->dev, "no irq for alarm\n"); return -ENOENT; } printk("s3c_rtc: tick irq %d, alarm irq %d\n", s3c_rtc_tickno, s3c_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get memory region resource\n"); return -ENOENT; } s3c_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); ret = -ENOENT; goto err_nores; } s3c_rtc_base = ioremap(res->start, res->end - res->start + 1); if (s3c_rtc_base == NULL) { dev_err(&pdev->dev, "failed ioremap()\n"); ret = -EINVAL; goto err_nomap; } /* check to see if everything is setup correctly */ s3c_rtc_enable(pdev, 1); pr_debug("s3c_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C_RTCCON)); s3c_rtc_setfreq(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "cannot attach rtc\n"); ret = PTR_ERR(rtc); goto err_nortc; } rtc->max_user_freq = S3C_MAX_CNT; #ifdef SET_RTC_DEFAULT_RESET_TIME { struct rtc_time tm; s3c_rtc_gettime (pdev, &tm); if (rtc_valid_tm (&tm) != 0) { struct rtc_time reset_tm = { .tm_sec = DEFAULT_RESET_TIME_SEC, .tm_min = DEFAULT_RESET_TIME_MIN, .tm_hour = DEFAULT_RESET_TIME_HOUR, .tm_mday = DEFAULT_RESET_TIME_DATE, .tm_mon = DEFAULT_RESET_TIME_MON - 1, .tm_year = DEFAULT_RESET_TIME_YEAR - 1900, }; s3c_rtc_settime (pdev, &reset_tm); } } #else /* check rtc time */ for (bcd_loop = S3C_RTCSEC ; bcd_loop <= S3C_RTCYEAR ; bcd_loop +=0x4) { bcd_tmp = readb(s3c_rtc_base + bcd_loop); if(((bcd_tmp & 0xf) > 0x9) || ((bcd_tmp & 0xf0) > 0x90)) writeb(0, s3c_rtc_base + bcd_loop); } #endif platform_set_drvdata(pdev, rtc); #ifdef CONFIG_RTC_SYNC rtc_sync_start_save_delta(); #endif /* CONFIG_RTC_SYNC */ return 0; err_nortc: s3c_rtc_enable(pdev, 0); iounmap(s3c_rtc_base); err_nomap: release_resource(s3c_rtc_mem); err_nores: return ret; } #ifdef CONFIG_PM /* RTC Power management control */ static int ticnt_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C_TICNT); s3c_rtc_enable(pdev, 0); #ifdef CONFIG_RTC_SYNC cancel_delayed_work(&rtc_sync_work); #endif /* CONFIG_RTC_SYNC */ return 0; }