📄 pxa270-rtc.c
字号:
return -EINVAL; pr_debug("pxa270_rtc: setting frequency %ld\n", arg); pxa270_rtc_setfreq(arg); return 0; case RTC_UIE_ON: case RTC_UIE_OFF: return -EINVAL; }#endif return -EINVAL;}static int pxa270_rtc_proc(char *buf){#if 0 unsigned int rtcalm = readb(PXA270_RTCALM); unsigned int ticnt = readb (PXA270_TICNT); char *p = buf; p += sprintf(p, "alarm_IRQ\t: %s\n", (rtcalm & PXA270_RTCALM_ALMEN) ? "yes" : "no" ); p += sprintf(p, "periodic_IRQ\t: %s\n", (ticnt & PXA270_TICNT_ENABLE) ? "yes" : "no" ); p += sprintf(p, "periodic_freq\t: %d\n", pxa270_rtc_freq); return p - buf;#endif}static int pxa270_rtc_open(void){ int ret= 0;#if 0 ret = request_irq(pxa270_rtc_alarmno, pxa270_rtc_alarmirq, SA_INTERRUPT, "pxa270-rtc alarm", NULL); if (ret) printk(KERN_ERR "IRQ%d already in use\n", pxa270_rtc_alarmno); ret = request_irq(pxa270_rtc_tickno, pxa270_rtc_tickirq, SA_INTERRUPT, "pxa270-rtc tick", NULL); if (ret) { printk(KERN_ERR "IRQ%d already in use\n", pxa270_rtc_tickno); goto tick_err; } return ret; tick_err: free_irq(pxa270_rtc_alarmno, NULL);#endif return ret;}static void pxa270_rtc_release(void){ /* do not clear AIE here, it may be needed for wake */#if 0 pxa270_rtc_setpie(0); free_irq(pxa270_rtc_alarmno, NULL); free_irq(pxa270_rtc_tickno, NULL);#endif return 0;}static struct rtc_ops pxa270_rtcops = { .owner = THIS_MODULE, .open = pxa270_rtc_open, .release = pxa270_rtc_release, .ioctl = pxa270_rtc_ioctl, .read_time = pxa270_rtc_gettime, .set_time = pxa270_rtc_settime, .read_alarm = pxa270_rtc_getalarm, .set_alarm = pxa270_rtc_setalarm, .proc = pxa270_rtc_proc,};static void pxa270_rtc_enable(struct device *dev, int en){ unsigned int tmp;#if 1// if (pxa270_rtc_base == NULL)// return; if (!en) { tmp = RTSR; RTSR=tmp & ~RTSR_HZE & ~RTSR_ALE; //tmp = readb(PXA270_TICNT); //writeb(tmp & ~PXA270_TICNT_ENABLE, PXA270_TICNT); } else { /* re-enable the device, and check it is ok */ if ((RTSR & RTSR_ALE) == 0){ dev_info(dev, "rtc alarm interrupt disabled, re-enabling\n"); tmp = RTSR; RTSR=tmp | RTSR_ALE; } if ((RTSR & RTSR_HZE) == 0){ dev_info(dev, "rtc HZ interrupt disabled, re-enabling\n"); tmp = RTSR; RTSR=tmp | RTSR_HZE; }/* if ((readb(PXA270_RTCCON) & PXA270_RTCCON_CNTSEL)){ dev_info(dev, "removing PXA270_RTCCON_CNTSEL\n"); tmp = readb(PXA270_RTCCON); writeb(tmp& ~PXA270_RTCCON_CNTSEL , PXA270_RTCCON); } if ((readb(PXA270_RTCCON) & PXA270_RTCCON_CLKRST)){ dev_info(dev, "removing PXA270_RTCCON_CLKRST\n"); tmp = readb(PXA270_RTCCON); writeb(tmp & ~PXA270_RTCCON_CLKRST, PXA270_RTCCON); }*/ }#endif}static int pxa270_rtc_remove(struct device *dev){#if 0 unregister_rtc(&pxa270_rtcops); pxa270_rtc_setpie(0); pxa270_rtc_setaie(0); if (pxa270_rtc_mem != NULL) { pr_debug("pxa270_rtc: releasing pxa270_rtc_mem\n"); iounmap(pxa270_rtc_base); release_resource(pxa270_rtc_mem); kfree(pxa270_rtc_mem); }#endif return 0;}static int pxa270_rtc_probe(struct device *dev){ struct platform_device *pdev = to_platform_device(dev); struct resource *res; int ret,delayi; printk("/***** ENTER pxa270_rtc_probe *****/\n"); #if 0 pr_debug("%s: probe=%p, device=%p\n", __FUNCTION__, pdev, dev); /* find the IRQs *//* pxa270_rtc_tickno = platform_get_irq(pdev, 1); if (pxa270_rtc_tickno <= 0) { dev_err(dev, "no irq for rtc tick\n"); return -ENOENT; }*/ pxa270_rtc_alarmno = platform_get_irq(pdev, 0); if (pxa270_rtc_alarmno <= 0) { dev_err(dev, "no irq for alarm\n"); return -ENOENT; } pr_debug("pxa270_rtc: tick irq %d, alarm irq %d\n", pxa270_rtc_tickno, pxa270_rtc_alarmno); /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(dev, "failed to get memory region resource\n"); return -ENOENT; } pxa270_rtc_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name); if (pxa270_rtc_mem == NULL) { dev_err(dev, "failed to reserve memory region\n"); ret = -ENOENT; goto exit_err; } pxa270_rtc_base = ioremap(res->start, res->end - res->start + 1); if (pxa270_rtc_base == NULL) { dev_err(dev, "failed ioremap()\n"); ret = -EINVAL; goto exit_err; } pxa270_rtc_mem = res; pr_debug("pxa270_rtc_base=%p\n", pxa270_rtc_base); printk("pxa270_rtc_base=%p\n",pxa270_rtc_base);#endif// pr_debug("pxa270_rtc: RTCCON=%02x\n", readb(PXA270_RTCCON)); /* check to see if everything is setup correctly */// pxa270_rtc_enable(dev, 1);// pr_debug("pxa270_rtc: RTCCON=%02x\n", readb(PXA270_RTCCON));/* printk("DEBUG Begin-----------\n"); printk("pxa270_rtc:RTSR=%8x\n",RTSR); printk("Timer section:\n"); printk("pxa270_rtc:RCNR=%8x\n",RCNR); printk("pxa270_rtc:RTAR=%8x\n",RTAR); printk("Wristwatch section:\n"); printk("pxa270_rtc:RDCR=%8x\n",RDCR); printk("pxa270_rtc:RDAR1=%8x\n",RDAR1); printk("pxa270_rtc:RDAR2=%8x\n",RDAR2); printk("pxa270_rtc:RYCR=%8x\n",RYCR); printk("pxa270_rtc:RYAR1=%8x\n",RYAR1); printk("pxa270_rtc:RYAR2=%8x\n",RYAR2); printk("Periodic Interrupt:\n"); printk("pxa270_rtc:PICR=%8x\n",RTCPICR);// printk("pxa270_rtc:PIAR=%8x\n",PIAR); printk("Trim section:\n"); printk("pxa270_rtc:RTTR=%8x\n",RTTR); printk("wait 3 seconds........\n"); for (delayi=0;delayi<3000;delayi++) udelay(1000); printk("after waiting\n"); printk("pxa270_rtc:RCNR=%8x\n",RCNR); printk("pxa270_rtc:RDCR=%8x\n",RDCR); printk("Perpare to alter RCNR's value....\n"); RCNR=0x0; for (delayi=0;delayi<128;delayi++); printk("pxa270_rtc:RCNR=%8x\n",RCNR); printk("pxa270_rtc:RDCR=%8x\n",RDCR); printk("wait 3 seconds........\n"); for (delayi=0;delayi<3000;delayi++) udelay(1000); printk("after waiting\n"); printk("pxa270_rtc:RCNR=%8x\n",RCNR); printk("pxa270_rtc:RDCR=%8x\n",RDCR); printk("Perpare to alter RDCR's value....\n"); RDCR=0x0; for (delayi=0;delayi<128;delayi++); printk("pxa270_rtc:RCNR=%8x\n",RCNR); printk("pxa270_rtc:RDCR=%8x\n",RDCR);// pxa270_rtc_setfreq(pxa270_rtc_freq);*/ /* register RTC and exit */ register_rtc(&pxa270_rtcops); return 0; exit_err: dev_err(dev, "error %d during initialisation\n", ret); return ret; }#ifdef CONFIG_PM/* PXA270 RTC Power management control */static struct timespec pxa270_rtc_delta;static int ticnt_save;static int pxa270_rtc_suspend(struct device *dev, u32 state, u32 level){ struct rtc_time tm; struct timespec time;#if 0 time.tv_nsec = 0; if (level == SUSPEND_POWER_DOWN) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(PXA270_TICNT); /* calculate time delta for suspend */ pxa270_rtc_gettime(&tm); rtc_tm_to_time(&tm, &time.tv_sec); save_time_delta(&pxa270_rtc_delta, &time); pxa270_rtc_enable(dev, 0); }#endif return 0;}static int pxa270_rtc_resume(struct device *dev, u32 level){ struct rtc_time tm; struct timespec time;#if 0 time.tv_nsec = 0; pxa270_rtc_enable(dev, 1); pxa270_rtc_gettime(&tm); rtc_tm_to_time(&tm, &time.tv_sec); restore_time_delta(&pxa270_rtc_delta, &time); writeb(ticnt_save, PXA270_TICNT);#endif return 0;}#else#define pxa270_rtc_suspend NULL#define pxa270_rtc_resume NULL#endifstatic struct device_driver pxa270_rtcdrv = { .name = "pxa270-rtc", .bus = &platform_bus_type, .probe = pxa270_rtc_probe, .remove = pxa270_rtc_remove, .suspend = pxa270_rtc_suspend, .resume = pxa270_rtc_resume,};static char __initdata banner[] = "PXA270 RTC, (c) 2004 Simtec Electronics\n";static int __init pxa270_rtc_init(void){ printk(banner); // printk("<1>pxa270_rtc:RCNR=%8x\n",RCNR); return driver_register(&pxa270_rtcdrv);}static void __exit pxa270_rtc_exit(void){ driver_unregister(&pxa270_rtcdrv);}module_init(pxa270_rtc_init);module_exit(pxa270_rtc_exit);MODULE_DESCRIPTION("PXA27X RTC Driver");MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -