From 99d59c1a67d80029f97b784ac8a92d4dcda20837 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 21 Mar 2003 02:27:39 -0800 Subject: [PATCH] [PATCH] no arch specific headers for upd4990a --- include/linux/upd4990a.h | 140 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 include/linux/upd4990a.h diff --git a/include/linux/upd4990a.h b/include/linux/upd4990a.h new file mode 100644 index 0000000000000..ad5063490808e --- /dev/null +++ b/include/linux/upd4990a.h @@ -0,0 +1,140 @@ +/* + * Constant and architecture independent procedures + * for NEC uPD4990A serial I/O real-time clock. + * + * Copyright 2001 TAKAI Kousuke + * Kyoto University Microcomputer Club (KMC). + * + * References: + * uPD4990A serial I/O real-time clock users' manual (Japanese) + * No. S12828JJ4V0UM00 (4th revision), NEC Corporation, 1999. + */ + +#ifndef _LINUX_uPD4990A_H +#define _LINUX_uPD4990A_H + +#include + +#include + +/* Serial commands (4 bits) */ +#define UPD4990A_REGISTER_HOLD (0x0) +#define UPD4990A_REGISTER_SHIFT (0x1) +#define UPD4990A_TIME_SET_AND_COUNTER_HOLD (0x2) +#define UPD4990A_TIME_READ (0x3) +#define UPD4990A_TP_64HZ (0x4) +#define UPD4990A_TP_256HZ (0x5) +#define UPD4990A_TP_2048HZ (0x6) +#define UPD4990A_TP_4096HZ (0x7) +#define UPD4990A_TP_1S (0x8) +#define UPD4990A_TP_10S (0x9) +#define UPD4990A_TP_30S (0xA) +#define UPD4990A_TP_60S (0xB) +#define UPD4990A_INTERRUPT_RESET (0xC) +#define UPD4990A_INTERRUPT_TIMER_START (0xD) +#define UPD4990A_INTERRUPT_TIMER_STOP (0xE) +#define UPD4990A_TEST_MODE_SET (0xF) + +/* Parallel commands (3 bits) + 0-6 are same with serial commands. */ +#define UPD4990A_PAR_SERIAL_MODE 7 + +#ifndef UPD4990A_DELAY +# include +# define UPD4990A_DELAY(usec) udelay((usec)) +#endif +#ifndef UPD4990A_OUTPUT_DATA +# define UPD4990A_OUTPUT_DATA(bit) \ + do { \ + UPD4990A_OUTPUT_DATA_CLK((bit), 0); \ + UPD4990A_DELAY(1); /* t-DSU */ \ + UPD4990A_OUTPUT_DATA_CLK((bit), 1); \ + UPD4990A_DELAY(1); /* t-DHLD */ \ + } while (0) +#endif + +static __inline__ void upd4990a_serial_command(int command) +{ + UPD4990A_OUTPUT_DATA(command >> 0); + UPD4990A_OUTPUT_DATA(command >> 1); + UPD4990A_OUTPUT_DATA(command >> 2); + UPD4990A_OUTPUT_DATA(command >> 3); + UPD4990A_DELAY(1); /* t-HLD */ + UPD4990A_OUTPUT_STROBE(1); + UPD4990A_DELAY(1); /* t-STB & t-d1 */ + UPD4990A_OUTPUT_STROBE(0); + /* 19 microseconds extra delay is needed + iff previous mode is TIME READ command */ +} + +struct upd4990a_raw_data { + u8 sec; /* BCD */ + u8 min; /* BCD */ + u8 hour; /* BCD */ + u8 mday; /* BCD */ +#if defined __LITTLE_ENDIAN_BITFIELD + unsigned wday :4; /* 0-6 */ + unsigned mon :4; /* 1-based */ +#elif defined __BIG_ENDIAN_BITFIELD + unsigned mon :4; /* 1-based */ + unsigned wday :4; /* 0-6 */ +#else +# error Unknown bitfield endian! +#endif + u8 year; /* BCD */ +}; + +static __inline__ void upd4990a_get_time(struct upd4990a_raw_data *buf, + int leave_register_hold) +{ + int byte; + + upd4990a_serial_command(UPD4990A_TIME_READ); + upd4990a_serial_command(UPD4990A_REGISTER_SHIFT); + UPD4990A_DELAY(19); /* t-d2 - t-d1 */ + + for (byte = 0; byte < 6; byte++) { + u8 tmp; + int bit; + + for (tmp = 0, bit = 0; bit < 8; bit++) { + tmp = (tmp | (UPD4990A_READ_DATA() << 8)) >> 1; + UPD4990A_OUTPUT_CLK(1); + UPD4990A_DELAY(1); + UPD4990A_OUTPUT_CLK(0); + UPD4990A_DELAY(1); + } + ((u8 *) buf)[byte] = tmp; + } + + /* The uPD4990A users' manual says that we should issue `Register + Hold' command after each data retrieval, or next `Time Read' + command may not work correctly. */ + if (!leave_register_hold) + upd4990a_serial_command(UPD4990A_REGISTER_HOLD); +} + +static __inline__ void upd4990a_set_time(const struct upd4990a_raw_data *data, + int time_set_only) +{ + int byte; + + if (!time_set_only) + upd4990a_serial_command(UPD4990A_REGISTER_SHIFT); + + for (byte = 0; byte < 6; byte++) { + int bit; + u8 tmp = ((const u8 *) data)[byte]; + + for (bit = 0; bit < 8; bit++, tmp >>= 1) + UPD4990A_OUTPUT_DATA(tmp); + } + + upd4990a_serial_command(UPD4990A_TIME_SET_AND_COUNTER_HOLD); + + /* Release counter hold and start the clock. */ + if (!time_set_only) + upd4990a_serial_command(UPD4990A_REGISTER_HOLD); +} + +#endif /* _LINUX_uPD4990A_H */ -- 2.53.0