2 * Constant and architecture independent procedures
3 * for NEC uPD4990A serial I/O real-time clock.
5 * Copyright 2001 TAKAI Kousuke <tak@kmc.kyoto-u.ac.jp>
6 * Kyoto University Microcomputer Club (KMC).
9 * uPD4990A serial I/O real-time clock users' manual (Japanese)
10 * No. S12828JJ4V0UM00 (4th revision), NEC Corporation, 1999.
13 #ifndef _LINUX_uPD4990A_H
14 #define _LINUX_uPD4990A_H
16 #include <asm/byteorder.h>
18 #include <asm/upd4990a.h>
20 /* Serial commands (4 bits) */
21 #define UPD4990A_REGISTER_HOLD (0x0)
22 #define UPD4990A_REGISTER_SHIFT (0x1)
23 #define UPD4990A_TIME_SET_AND_COUNTER_HOLD (0x2)
24 #define UPD4990A_TIME_READ (0x3)
25 #define UPD4990A_TP_64HZ (0x4)
26 #define UPD4990A_TP_256HZ (0x5)
27 #define UPD4990A_TP_2048HZ (0x6)
28 #define UPD4990A_TP_4096HZ (0x7)
29 #define UPD4990A_TP_1S (0x8)
30 #define UPD4990A_TP_10S (0x9)
31 #define UPD4990A_TP_30S (0xA)
32 #define UPD4990A_TP_60S (0xB)
33 #define UPD4990A_INTERRUPT_RESET (0xC)
34 #define UPD4990A_INTERRUPT_TIMER_START (0xD)
35 #define UPD4990A_INTERRUPT_TIMER_STOP (0xE)
36 #define UPD4990A_TEST_MODE_SET (0xF)
38 /* Parallel commands (3 bits)
39 0-6 are same with serial commands. */
40 #define UPD4990A_PAR_SERIAL_MODE 7
42 #ifndef UPD4990A_DELAY
43 # include <linux/delay.h>
44 # define UPD4990A_DELAY(usec) udelay((usec))
46 #ifndef UPD4990A_OUTPUT_DATA
47 # define UPD4990A_OUTPUT_DATA(bit) \
49 UPD4990A_OUTPUT_DATA_CLK((bit), 0); \
50 UPD4990A_DELAY(1); /* t-DSU */ \
51 UPD4990A_OUTPUT_DATA_CLK((bit), 1); \
52 UPD4990A_DELAY(1); /* t-DHLD */ \
56 static __inline__ void upd4990a_serial_command(int command)
58 UPD4990A_OUTPUT_DATA(command >> 0);
59 UPD4990A_OUTPUT_DATA(command >> 1);
60 UPD4990A_OUTPUT_DATA(command >> 2);
61 UPD4990A_OUTPUT_DATA(command >> 3);
62 UPD4990A_DELAY(1); /* t-HLD */
63 UPD4990A_OUTPUT_STROBE(1);
64 UPD4990A_DELAY(1); /* t-STB & t-d1 */
65 UPD4990A_OUTPUT_STROBE(0);
66 /* 19 microseconds extra delay is needed
67 iff previous mode is TIME READ command */
70 struct upd4990a_raw_data {
75 #if defined __LITTLE_ENDIAN_BITFIELD
76 unsigned wday :4; /* 0-6 */
77 unsigned mon :4; /* 1-based */
78 #elif defined __BIG_ENDIAN_BITFIELD
79 unsigned mon :4; /* 1-based */
80 unsigned wday :4; /* 0-6 */
82 # error Unknown bitfield endian!
87 static __inline__ void upd4990a_get_time(struct upd4990a_raw_data *buf,
88 int leave_register_hold)
92 upd4990a_serial_command(UPD4990A_TIME_READ);
93 upd4990a_serial_command(UPD4990A_REGISTER_SHIFT);
94 UPD4990A_DELAY(19); /* t-d2 - t-d1 */
96 for (byte = 0; byte < 6; byte++) {
100 for (tmp = 0, bit = 0; bit < 8; bit++) {
101 tmp = (tmp | (UPD4990A_READ_DATA() << 8)) >> 1;
102 UPD4990A_OUTPUT_CLK(1);
104 UPD4990A_OUTPUT_CLK(0);
107 ((u8 *) buf)[byte] = tmp;
110 /* The uPD4990A users' manual says that we should issue `Register
111 Hold' command after each data retrieval, or next `Time Read'
112 command may not work correctly. */
113 if (!leave_register_hold)
114 upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
117 static __inline__ void upd4990a_set_time(const struct upd4990a_raw_data *data,
123 upd4990a_serial_command(UPD4990A_REGISTER_SHIFT);
125 for (byte = 0; byte < 6; byte++) {
127 u8 tmp = ((const u8 *) data)[byte];
129 for (bit = 0; bit < 8; bit++, tmp >>= 1)
130 UPD4990A_OUTPUT_DATA(tmp);
133 upd4990a_serial_command(UPD4990A_TIME_SET_AND_COUNTER_HOLD);
135 /* Release counter hold and start the clock. */
137 upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
140 #endif /* _LINUX_uPD4990A_H */