rs5c313_landisk.c revision 1.2 1 /* $NetBSD: rs5c313_landisk.c,v 1.2 2007/11/06 00:36:30 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.2 2007/11/06 00:36:30 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, struct cfdata *, void *);
52 static void rs5c313_landisk_attach(device_t, device_t, void *);
53
54 CFATTACH_DECL(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, struct cfdata *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_ops = &rs5c313_landisk_ops;
98 rs5c313_attach(sc);
99 }
100
101
102 static void
103 rtc_begin(struct rs5c313_softc *sc)
104 {
105
106 SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT
107 | SCSPTR_SPB0IO | SCSPTR_SPB0DT;
108 ndelay(100);
109 }
110
111
112 /*
113 * CE pin
114 */
115 static void
116 rtc_ce(struct rs5c313_softc *sc, int onoff)
117 {
118
119 if (onoff)
120 _reg_write_1(LANDISK_PWRMNG, PWRMNG_RTC_CE);
121 else
122 _reg_write_1(LANDISK_PWRMNG, 0);
123 ndelay(600);
124 }
125
126
127 /*
128 * SCLK pin is connnected to SPB0DT.
129 * SPB0DT is always in output mode, we set SPB0IO in rtc_begin.
130 */
131 static void
132 rtc_clk(struct rs5c313_softc *sc, int onoff)
133 {
134 uint8_t r = SHREG_SCSPTR;
135
136 if (onoff)
137 r |= SCSPTR_SPB0DT;
138 else
139 r &= ~SCSPTR_SPB0DT;
140 SHREG_SCSPTR = r;
141 }
142
143
144 /*
145 * SIO pin is connected to SPB1DT.
146 * SPB1DT is output when SPB1IO is set.
147 */
148 static void
149 rtc_dir(struct rs5c313_softc *sc, int output)
150 {
151 uint8_t r = SHREG_SCSPTR;
152
153 if (output)
154 r |= SCSPTR_SPB1IO;
155 else
156 r &= ~SCSPTR_SPB1IO;
157 SHREG_SCSPTR = r;
158 }
159
160
161 /*
162 * Read bit from SPB1DT pin.
163 */
164 static int
165 rtc_read(struct rs5c313_softc *sc)
166 {
167 int bit;
168
169 ndelay(300);
170
171 bit = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0;
172
173 rtc_clk(sc, 0);
174 ndelay(300);
175 rtc_clk(sc, 1);
176
177 return bit;
178 }
179
180
181 /*
182 * Write bit via SPB1DT pin.
183 */
184 static void
185 rtc_write(struct rs5c313_softc *sc, int bit)
186 {
187 uint8_t r = SHREG_SCSPTR;
188
189 if (bit)
190 r |= SCSPTR_SPB1DT;
191 else
192 r &= ~SCSPTR_SPB1DT;
193 SHREG_SCSPTR = r;
194
195 ndelay(300);
196
197 rtc_clk(sc, 0);
198 ndelay(300);
199 rtc_clk(sc, 1);
200 }
201