rs5c313_landisk.c revision 1.3 1 /* $NetBSD: rs5c313_landisk.c,v 1.3 2008/03/27 02:15:29 uwe Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the NetBSD
18 * Foundation, Inc. and its contributors.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: rs5c313_landisk.c,v 1.3 2008/03/27 02:15:29 uwe Exp $");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39 #include <sys/kernel.h>
40
41 #include <dev/clock_subr.h>
42 #include <dev/ic/rs5c313var.h>
43
44 #include <sh3/devreg.h>
45 #include <sh3/scireg.h>
46
47 #include <landisk/landisk/landiskreg.h>
48
49
50 /* autoconf glue */
51 static int rs5c313_landisk_match(device_t, cfdata_t, void *);
52 static void rs5c313_landisk_attach(device_t, device_t, void *);
53
54 CFATTACH_DECL_NEW(rs5c313_landisk, sizeof(struct rs5c313_softc),
55 rs5c313_landisk_match, rs5c313_landisk_attach, NULL, NULL);
56
57
58 /* chip access methods */
59 static void rtc_begin(struct rs5c313_softc *);
60 static void rtc_ce(struct rs5c313_softc *, int);
61 static void rtc_dir(struct rs5c313_softc *, int);
62 static void rtc_clk(struct rs5c313_softc *, int);
63 static int rtc_read(struct rs5c313_softc *);
64 static void rtc_write(struct rs5c313_softc *, int);
65
66 static struct rs5c313_ops rs5c313_landisk_ops = {
67 .rs5c313_op_begin = rtc_begin,
68 .rs5c313_op_ce = rtc_ce,
69 .rs5c313_op_clk = rtc_clk,
70 .rs5c313_op_dir = rtc_dir,
71 .rs5c313_op_read = rtc_read,
72 .rs5c313_op_write = rtc_write,
73 };
74
75 #define ndelay(x) delay(x)
76
77
78
79 static int
80 rs5c313_landisk_match(device_t parent, cfdata_t cf, void *aux)
81 {
82 static int matched = 0;
83
84 if (matched)
85 return 0;
86
87 matched = 1;
88 return 1;
89 }
90
91
92 static void
93 rs5c313_landisk_attach(device_t parent, device_t self, void *aux)
94 {
95 struct rs5c313_softc *sc = device_private(self);
96
97 sc->sc_dev = self;
98 sc->sc_ops = &rs5c313_landisk_ops;
99 rs5c313_attach(sc);
100 }
101
102
103 static void
104 rtc_begin(struct rs5c313_softc *sc)
105 {
106
107 SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT
108 | SCSPTR_SPB0IO | SCSPTR_SPB0DT;
109 ndelay(100);
110 }
111
112
113 /*
114 * CE pin
115 */
116 static void
117 rtc_ce(struct rs5c313_softc *sc, int onoff)
118 {
119
120 if (onoff)
121 _reg_write_1(LANDISK_PWRMNG, PWRMNG_RTC_CE);
122 else
123 _reg_write_1(LANDISK_PWRMNG, 0);
124 ndelay(600);
125 }
126
127
128 /*
129 * SCLK pin is connnected to SPB0DT.
130 * SPB0DT is always in output mode, we set SPB0IO in rtc_begin.
131 */
132 static void
133 rtc_clk(struct rs5c313_softc *sc, int onoff)
134 {
135 uint8_t r = SHREG_SCSPTR;
136
137 if (onoff)
138 r |= SCSPTR_SPB0DT;
139 else
140 r &= ~SCSPTR_SPB0DT;
141 SHREG_SCSPTR = r;
142 }
143
144
145 /*
146 * SIO pin is connected to SPB1DT.
147 * SPB1DT is output when SPB1IO is set.
148 */
149 static void
150 rtc_dir(struct rs5c313_softc *sc, int output)
151 {
152 uint8_t r = SHREG_SCSPTR;
153
154 if (output)
155 r |= SCSPTR_SPB1IO;
156 else
157 r &= ~SCSPTR_SPB1IO;
158 SHREG_SCSPTR = r;
159 }
160
161
162 /*
163 * Read bit from SPB1DT pin.
164 */
165 static int
166 rtc_read(struct rs5c313_softc *sc)
167 {
168 int bit;
169
170 ndelay(300);
171
172 bit = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0;
173
174 rtc_clk(sc, 0);
175 ndelay(300);
176 rtc_clk(sc, 1);
177
178 return bit;
179 }
180
181
182 /*
183 * Write bit via SPB1DT pin.
184 */
185 static void
186 rtc_write(struct rs5c313_softc *sc, int bit)
187 {
188 uint8_t r = SHREG_SCSPTR;
189
190 if (bit)
191 r |= SCSPTR_SPB1DT;
192 else
193 r &= ~SCSPTR_SPB1DT;
194 SHREG_SCSPTR = r;
195
196 ndelay(300);
197
198 rtc_clk(sc, 0);
199 ndelay(300);
200 rtc_clk(sc, 1);
201 }
202