2 * RTC routines for RICOH Rx5C348 SPI chip.
3 * Copyright (C) 2000-2001 Toshiba Corporation
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/rtc.h>
16 #include <linux/time.h>
17 #include <linux/bcd.h>
19 #include <asm/tx4938/spi.h>
24 #define Rx5C348_REG_SECOND 0
25 #define Rx5C348_REG_MINUTE 1
26 #define Rx5C348_REG_HOUR 2
27 #define Rx5C348_REG_WEEK 3
28 #define Rx5C348_REG_DAY 4
29 #define Rx5C348_REG_MONTH 5
30 #define Rx5C348_REG_YEAR 6
31 #define Rx5C348_REG_ADJUST 7
32 #define Rx5C348_REG_ALARM_W_MIN 8
33 #define Rx5C348_REG_ALARM_W_HOUR 9
34 #define Rx5C348_REG_ALARM_W_WEEK 10
35 #define Rx5C348_REG_ALARM_D_MIN 11
36 #define Rx5C348_REG_ALARM_D_HOUR 12
37 #define Rx5C348_REG_CTL1 14
38 #define Rx5C348_REG_CTL2 15
41 #define Rx5C348_BIT_PM 0x20 /* REG_HOUR */
42 #define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */
43 #define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */
44 #define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */
47 #define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
48 #define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
49 #define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
50 #define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
52 static struct spi_dev_desc srtc_dev_desc
= {
53 .baud
= 1000000, /* 1.0Mbps @ Vdd 2.0V */
57 /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
58 .byteorder
= 1, /* MSB-First */
59 .polarity
= 0, /* High-Active */
60 .phase
= 1, /* Shift-Then-Sample */
63 static int srtc_chipid
;
67 spi_rtc_io(unsigned char *inbuf
, unsigned char *outbuf
, unsigned int count
)
69 unsigned char *inbufs
[1], *outbufs
[1];
70 unsigned int incounts
[2], outcounts
[2];
77 return txx9_spi_io(srtc_chipid
, &srtc_dev_desc
,
78 inbufs
, incounts
, outbufs
, outcounts
, 0);
81 /* RTC-dependent code for time.c */
84 rtc_rx5c348_set_time(unsigned long t
)
86 unsigned char inbuf
[8];
88 u8 year
, month
, day
, hour
, minute
, second
, century
;
93 year
= tm
.tm_year
% 100;
94 month
= tm
.tm_mon
+1; /* tm_mon starts from 0 to 11 */
99 century
= tm
.tm_year
/ 100;
101 inbuf
[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND
);
111 /* hour 0 is AM12, noon is PM12 */
114 inbuf
[3] = Rx5C348_BIT_PM
;
115 hour
= (hour
+ 11) % 12 + 1;
119 inbuf
[4] = 0; /* ignore week */
125 inbuf
[6] |= Rx5C348_BIT_Y2K
;
128 /* write in one transfer to avoid data inconsistency */
129 return spi_rtc_io(inbuf
, NULL
, 8);
133 rtc_rx5c348_get_time(void)
135 unsigned char inbuf
[8], outbuf
[8];
136 unsigned int year
, month
, day
, hour
, minute
, second
;
138 inbuf
[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND
);
139 memset(inbuf
+ 1, 0, 7);
140 /* read in one transfer to avoid data inconsistency */
141 if (spi_rtc_io(inbuf
, outbuf
, 8))
151 hour
= outbuf
[3] & ~Rx5C348_BIT_PM
;
154 if (outbuf
[3] & Rx5C348_BIT_PM
)
159 month
= outbuf
[6] & ~Rx5C348_BIT_Y2K
;
165 return mktime(year
, month
, day
, hour
, minute
, second
);
169 rtc_rx5c348_init(int chipid
)
171 unsigned char inbuf
[2], outbuf
[2];
172 srtc_chipid
= chipid
;
173 /* turn on RTC if it is not on */
174 inbuf
[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2
);
176 spi_rtc_io(inbuf
, outbuf
, 2);
177 if (outbuf
[1] & Rx5C348_BIT_XSTP
) {
178 inbuf
[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2
);
180 spi_rtc_io(inbuf
, NULL
, 2);
183 inbuf
[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1
);
185 spi_rtc_io(inbuf
, outbuf
, 2);
186 if (outbuf
[1] & Rx5C348_BIT_24H
)
189 /* set the function pointers */
190 rtc_mips_get_time
= rtc_rx5c348_get_time
;
191 rtc_mips_set_time
= rtc_rx5c348_set_time
;