Esempio n. 1
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_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;
}
Esempio n. 2
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;
}
Esempio n. 3
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);
}
Esempio n. 4
0
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;
}