37 #include <linux/errno.h>
38 #include <linux/types.h>
40 #include <linux/module.h>
41 #include <linux/time.h>
44 #include <linux/poll.h>
45 #include <linux/rtc.h>
53 #define RTC_VERSION "1.10d"
56 static unsigned long epoch = 2000;
67 size_t count, loff_t *ppos);
69 static long hp_sdc_rtc_unlocked_ioctl(
struct file *
file,
70 unsigned int cmd,
unsigned long arg);
75 static int hp_sdc_rtc_fasync (
int fd,
struct file *filp,
int on);
77 static int hp_sdc_rtc_read_proc(
char *
page,
char **
start,
off_t off,
80 static void hp_sdc_rtc_isr (
int irq,
void *
dev_id,
86 static int hp_sdc_rtc_do_read_bbrtc (
struct rtc_time *rtctm)
107 t.act.semaphore = &tsem;
115 if (!((tseq[83] | tseq[90] | tseq[69] | tseq[76] |
116 tseq[55] | tseq[62] | tseq[34] | tseq[41] |
117 tseq[20] | tseq[27] | tseq[6] | tseq[13]) & 0x0f))
121 rtctm->
tm_year = (tseq[83] & 0x0f) + (tseq[90] & 0x0f) * 10;
122 rtctm->
tm_mon = (tseq[69] & 0x0f) + (tseq[76] & 0x0f) * 10;
123 rtctm->
tm_mday = (tseq[55] & 0x0f) + (tseq[62] & 0x0f) * 10;
124 rtctm->
tm_wday = (tseq[48] & 0x0f);
125 rtctm->
tm_hour = (tseq[34] & 0x0f) + (tseq[41] & 0x0f) * 10;
126 rtctm->
tm_min = (tseq[20] & 0x0f) + (tseq[27] & 0x0f) * 10;
127 rtctm->
tm_sec = (tseq[6] & 0x0f) + (tseq[13] & 0x0f) * 10;
132 static int hp_sdc_rtc_read_bbrtc (
struct rtc_time *rtctm)
139 if (hp_sdc_rtc_do_read_bbrtc(&tm_last))
return -1;
140 if (hp_sdc_rtc_do_read_bbrtc(&
tm))
return -1;
143 if (i++ > 4)
return -1;
145 if (hp_sdc_rtc_do_read_bbrtc(&
tm))
return -1;
154 static int64_t hp_sdc_rtc_read_i8042timer (
uint8_t loadcmd,
int numreg)
193 static inline int hp_sdc_rtc_read_rt(
struct timeval *
res) {
199 if (raw < 0)
return -1;
202 days = (
unsigned int)(raw >> 24) & 0xffff;
212 static inline int hp_sdc_rtc_read_fhs(
struct timeval *res) {
217 if (raw < 0)
return -1;
219 tenms = (
unsigned int)raw & 0xffff;
229 static inline int hp_sdc_rtc_read_mt(
struct timeval *res) {
234 if (raw < 0)
return -1;
246 static inline int hp_sdc_rtc_read_dt(
struct timeval *res) {
251 if (raw < 0)
return -1;
263 static inline int hp_sdc_rtc_read_ct(
struct timeval *res) {
268 if (raw < 0)
return -1;
280 static int hp_sdc_rtc_set_rt (
struct timeval *setto)
294 if (0xffff < setto->
tv_sec / 86400)
return -1;
295 days = setto->
tv_sec / 86400;
296 if (0xffff < setto->
tv_usec / 1000000 / 86400)
return -1;
297 days += ((setto->
tv_sec % 86400) + setto->
tv_usec / 1000000) / 86400;
298 if (days > 0xffff)
return -1;
300 if (0xffffff < setto->
tv_sec)
return -1;
301 tenms = setto->
tv_sec * 100;
302 if (0xffffff < setto->
tv_usec / 10000)
return -1;
303 tenms += setto->
tv_usec / 10000;
304 if (tenms > 0xffffff)
return -1;
306 tseq[3] = (
uint8_t)(tenms & 0xff);
307 tseq[4] = (
uint8_t)((tenms >> 8) & 0xff);
308 tseq[5] = (
uint8_t)((tenms >> 16) & 0xff);
310 tseq[9] = (
uint8_t)(days & 0xff);
311 tseq[10] = (
uint8_t)((days >> 8) & 0xff);
320 static int hp_sdc_rtc_set_fhs (
struct timeval *setto)
331 if (0xffff < setto->tv_sec)
return -1;
332 tenms = setto->
tv_sec * 100;
333 if (0xffff < setto->
tv_usec / 10000)
return -1;
334 tenms += setto->
tv_usec / 10000;
335 if (tenms > 0xffff)
return -1;
337 tseq[3] = (
uint8_t)(tenms & 0xff);
338 tseq[4] = (
uint8_t)((tenms >> 8) & 0xff);
348 #define hp_sdc_rtc_set_mt (setto) \
349 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_MT)
352 #define hp_sdc_rtc_set_dt (setto) \
353 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_DT)
356 #define hp_sdc_rtc_set_ct (setto) \
357 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_CT)
360 static int hp_sdc_rtc_set_i8042timer (
struct timeval *setto,
uint8_t setcmd)
371 if (0xffffff < setto->tv_sec)
return -1;
372 tenms = setto->
tv_sec * 100;
373 if (0xffffff < setto->
tv_usec / 10000)
return -1;
374 tenms += setto->
tv_usec / 10000;
375 if (tenms > 0xffffff)
return -1;
378 tseq[3] = (
uint8_t)(tenms & 0xff);
379 tseq[4] = (
uint8_t)((tenms >> 8) & 0xff);
380 tseq[5] = (
uint8_t)((tenms >> 16) & 0xff);
391 size_t count, loff_t *ppos) {
394 if (count <
sizeof(
unsigned long))
397 retval =
put_user(68, (
unsigned long __user *)buf);
401 static unsigned int hp_sdc_rtc_poll(
struct file *file,
poll_table *
wait)
411 static int hp_sdc_rtc_open(
struct inode *
inode,
struct file *file)
416 static int hp_sdc_rtc_fasync (
int fd,
struct file *filp,
int on)
418 return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue);
421 static int hp_sdc_rtc_proc_output (
char *buf)
423 #define YN(bit) ("no")
424 #define NY(bit) ("yes")
433 if (hp_sdc_rtc_read_bbrtc(&
tm)) {
434 p +=
sprintf(p,
"BBRTC\t\t: READ FAILED!\n");
437 "rtc_time\t: %02d:%02d:%02d\n"
438 "rtc_date\t: %04d-%02d-%02d\n"
439 "rtc_epoch\t: %04lu\n",
445 if (hp_sdc_rtc_read_rt(&tv)) {
446 p +=
sprintf(p,
"i8042 rtc\t: READ FAILED!\n");
448 p +=
sprintf(p,
"i8042 rtc\t: %ld.%02d seconds\n",
449 tv.tv_sec, (
int)tv.tv_usec/1000);
452 if (hp_sdc_rtc_read_fhs(&tv)) {
453 p +=
sprintf(p,
"handshake\t: READ FAILED!\n");
455 p +=
sprintf(p,
"handshake\t: %ld.%02d seconds\n",
456 tv.tv_sec, (
int)tv.tv_usec/1000);
459 if (hp_sdc_rtc_read_mt(&tv)) {
460 p +=
sprintf(p,
"alarm\t\t: READ FAILED!\n");
462 p +=
sprintf(p,
"alarm\t\t: %ld.%02d seconds\n",
463 tv.tv_sec, (
int)tv.tv_usec/1000);
466 if (hp_sdc_rtc_read_dt(&tv)) {
467 p +=
sprintf(p,
"delay\t\t: READ FAILED!\n");
469 p +=
sprintf(p,
"delay\t\t: %ld.%02d seconds\n",
470 tv.tv_sec, (
int)tv.tv_usec/1000);
473 if (hp_sdc_rtc_read_ct(&tv)) {
474 p +=
sprintf(p,
"periodic\t: READ FAILED!\n");
476 p +=
sprintf(p,
"periodic\t: %ld.%02d seconds\n",
477 tv.tv_sec, (
int)tv.tv_usec/1000);
484 "square_wave\t: %s\n"
487 "periodic_IRQ\t: %s\n"
488 "periodic_freq\t: %ld\n"
489 "batt_status\t: %s\n",
498 1 ?
"okay" :
"dead");
505 static int hp_sdc_rtc_read_proc(
char *
page,
char **
start,
off_t off,
506 int count,
int *eof,
void *
data)
508 int len = hp_sdc_rtc_proc_output (page);
509 if (len <= off+count) *eof = 1;
512 if (len>count) len =
count;
517 static int hp_sdc_rtc_ioctl(
struct file *file,
518 unsigned int cmd,
unsigned long arg)
546 if (hp_sdc_rtc_read_mt(&ttime))
return -
EFAULT;
547 if (hp_sdc_rtc_read_bbrtc(&wtime))
return -
EFAULT;
549 wtime.tm_hour = ttime.tv_sec / 3600; ttime.tv_sec %= 3600;
550 wtime.tm_min = ttime.tv_sec / 60; ttime.tv_sec %= 60;
551 wtime.tm_sec = ttime.tv_sec;
557 return put_user(hp_sdc_rtc_freq, (
unsigned long *)arg);
565 if ((arg < 1) || (arg > 100))
return -
EINVAL;
567 ttime.tv_usec = 1000000 /
arg;
569 hp_sdc_rtc_freq =
arg;
582 struct hp_sdc_rtc_time alm_tm;
585 sizeof(
struct hp_sdc_rtc_time)))
588 if (alm_tm.tm_hour > 23)
return -
EINVAL;
589 if (alm_tm.tm_min > 59)
return -
EINVAL;
590 if (alm_tm.tm_sec > 59)
return -
EINVAL;
592 ttime.sec = alm_tm.tm_hour * 3600 +
593 alm_tm.tm_min * 60 + alm_tm.tm_sec;
600 if (hp_sdc_rtc_read_bbrtc(&wtime))
return -
EFAULT;
606 unsigned char mon,
day, hrs,
min,
sec, leap_yr;
615 yrs = hp_sdc_rtc_tm.tm_year + 1900;
616 mon = hp_sdc_rtc_tm.tm_mon + 1;
617 day = hp_sdc_rtc_tm.tm_mday;
618 hrs = hp_sdc_rtc_tm.tm_hour;
619 min = hp_sdc_rtc_tm.tm_min;
620 sec = hp_sdc_rtc_tm.tm_sec;
625 leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
627 if ((mon > 12) || (day == 0))
629 if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
631 if ((hrs >= 24) || (min >= 60) || (sec >= 60))
634 if ((yrs -= eH) > 255)
664 static long hp_sdc_rtc_unlocked_ioctl(
struct file *file,
665 unsigned int cmd,
unsigned long arg)
670 ret = hp_sdc_rtc_ioctl(file, cmd, arg);
680 .read = hp_sdc_rtc_read,
681 .poll = hp_sdc_rtc_poll,
682 .unlocked_ioctl = hp_sdc_rtc_unlocked_ioctl,
683 .open = hp_sdc_rtc_open,
684 .fasync = hp_sdc_rtc_fasync,
690 .fops = &hp_sdc_rtc_fops
693 static int __init hp_sdc_rtc_init(
void)
702 sema_init(&i8042tregs, 1);
709 create_proc_read_entry (
"driver/rtc", 0,
NULL,
710 hp_sdc_rtc_read_proc,
NULL);
718 static void __exit hp_sdc_rtc_exit(
void)