tx39sib.c revision 1.1 1 /* $NetBSD: tx39sib.c,v 1.1 2000/01/08 21:07:02 uch Exp $ */
2
3 /*
4 * Copyright (c) 2000, by UCHIYAMA Yasushi
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. The name of the developer may NOT be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29 /*
30 * TX39 SIB (Serial Interface Bus) module.
31 */
32
33 #include "opt_tx39_debug.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38
39 #include <machine/bus.h>
40 #include <machine/intr.h>
41
42 #include <hpcmips/tx/tx39var.h>
43 #include <hpcmips/tx/tx39icureg.h>
44 #include <hpcmips/tx/tx39sibvar.h>
45 #include <hpcmips/tx/tx39sibreg.h>
46
47 #include "locators.h"
48
49 #ifdef TX39SIBDEBUG
50 int tx39sib_debug = 0;
51 #define DPRINTF(arg) if (vrpiu_debug) printf arg;
52 #else
53 #define DPRINTF(arg)
54 #endif
55
56 int tx39sib_match __P((struct device*, struct cfdata*, void*));
57 void tx39sib_attach __P((struct device*, struct device*, void*));
58 int tx39sib_print __P((void*, const char*));
59 int tx39sib_search __P((struct device*, struct cfdata*, void*));
60
61 struct tx39sib_softc {
62 struct device sc_dev;
63 tx_chipset_tag_t sc_tc;
64
65 int sc_attached;
66 };
67
68 __inline int __txsibsf0_ready __P((tx_chipset_tag_t));
69 void tx39sib_dump __P((struct tx39sib_softc*));
70
71 struct cfattach tx39sib_ca = {
72 sizeof(struct tx39sib_softc), tx39sib_match, tx39sib_attach
73 };
74
75 int
76 tx39sib_match(parent, cf, aux)
77 struct device *parent;
78 struct cfdata *cf;
79 void *aux;
80 {
81 return 1;
82 }
83
84 void
85 tx39sib_attach(parent, self, aux)
86 struct device *parent;
87 struct device *self;
88 void *aux;
89 {
90 struct txsim_attach_args *ta = aux;
91 struct tx39sib_softc *sc = (void*)self;
92 tx_chipset_tag_t tc;
93 txreg_t reg;
94
95 sc->sc_tc = tc = ta->ta_tc;
96
97 printf("\n");
98 #ifdef TX39SIBDEBUG
99 tx39sib_dump(sc);
100 #endif
101 /*
102 * Enable subframe0 (UCB1200)
103 */
104 reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
105 reg |= TX39_SIBCTRL_ENSF0;
106 tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
107
108 /*
109 * Disable subframe1 (external codec)
110 */
111 reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
112 reg &= ~TX39_SIBCTRL_ENSF1;
113 tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
114
115 /*
116 * Enable SIB module
117 */
118 reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
119 reg |= TX39_SIBCTRL_ENSIB;
120 tx_conf_write(tc, TX39_SIBCTRL_REG, reg);
121
122 config_search(tx39sib_search, self, tx39sib_print);
123 }
124
125
126 int
127 tx39sib_search(parent, cf, aux)
128 struct device *parent;
129 struct cfdata *cf;
130 void *aux;
131 {
132 struct tx39sib_softc *sc = (void*)parent;
133 struct txsib_attach_args sa;
134
135 sa.sa_tc = sc->sc_tc;
136 sa.sa_slot = cf->cf_loc[TXSIBIFCF_SLOT];
137
138 if (sa.sa_slot == TXSIBIFCF_SLOT_DEFAULT) {
139 printf("tx39sib_search: wildcarded slot, skipping\n");
140 return 0;
141 }
142
143 if (!(sc->sc_attached & (1 << sa.sa_slot)) &&/* not attached slot */
144 (*cf->cf_attach->ca_match)(parent, cf, &sa)) {
145 config_attach(parent, cf, &sa, tx39sib_print);
146 sc->sc_attached |= (1 << sa.sa_slot);
147 }
148
149 return 0;
150 }
151
152 int
153 tx39sib_print(aux, pnp)
154 void *aux;
155 const char *pnp;
156 {
157 struct txsib_attach_args *sa = aux;
158
159 printf(" slot %d", sa->sa_slot);
160
161 return QUIET;
162 }
163
164 /*
165 * sync access method. don't use runtime.
166 */
167
168 __inline int
169 __txsibsf0_ready(tc)
170 tx_chipset_tag_t tc;
171 {
172 int i;
173
174 tx_conf_write(tc, TX39_INTRSTATUS1_REG, TX39_INTRSTATUS1_SIBSF0INT);
175 for (i = 0; (!(tx_conf_read(tc, TX39_INTRSTATUS1_REG) &
176 TX39_INTRSTATUS1_SIBSF0INT)) && i < 100; i++)
177 ;
178 if (i == 100) {
179 printf("sf0 busy\n");
180 return 0;
181 } else if (i > 50) {
182 printf("sf0 busy loop:%d\n", i);
183 return 0;
184 }
185
186 return 1;
187 }
188
189 void
190 txsibsf0_reg_write(tc, addr, val)
191 tx_chipset_tag_t tc;
192 int addr;
193 u_int16_t val;
194 {
195 txreg_t reg;
196
197 reg = txsibsf0_read(tc, addr);
198 reg |= TX39_SIBSF0_WRITE;
199 TX39_SIBSF0_REGDATA_CLR(reg);
200 reg = TX39_SIBSF0_REGDATA_SET(reg, val);
201
202 __txsibsf0_ready(tc);
203 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
204 }
205
206 u_int16_t
207 txsibsf0_reg_read(tc, addr)
208 tx_chipset_tag_t tc;
209 int addr;
210 {
211 return TX39_SIBSF0_REGDATA(txsibsf0_read(tc, addr));
212 }
213
214 u_int32_t
215 txsibsf0_read(tc, addr)
216 tx_chipset_tag_t tc;
217 int addr;
218 {
219 txreg_t reg;
220 int retry = 3;
221
222 do {
223 reg = TX39_SIBSF0_REGADDR_SET(0, addr);
224 __txsibsf0_ready(tc);
225 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
226
227 __txsibsf0_ready(tc);
228 reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
229
230 } while ((TX39_SIBSF0_REGADDR(reg) != addr) && --retry > 0);
231
232 if (retry <= 0)
233 printf("txsibsf0_read: command failed\n");
234
235 return reg;
236 }
237
238 /*
239 * debug functions.
240 */
241
242 #define ISSETPRINT_CTRL(r, m) \
243 __is_set_print(r, TX39_SIBCTRL_##m, #m)
244 #define ISSETPRINT_DMACTRL(r, m) \
245 __is_set_print(r, TX39_SIBDMACTRL_##m, #m)
246
247 void
248 tx39sib_dump(sc)
249 struct tx39sib_softc *sc;
250 {
251 tx_chipset_tag_t tc = sc->sc_tc;
252 txreg_t reg;
253
254 reg = tx_conf_read(tc, TX39_SIBCTRL_REG);
255 ISSETPRINT_CTRL(reg, SIBIRQ);
256 ISSETPRINT_CTRL(reg, ENCNTTEST);
257 ISSETPRINT_CTRL(reg, ENDMATEST);
258 ISSETPRINT_CTRL(reg, SNDMONO);
259 ISSETPRINT_CTRL(reg, RMONOSNDIN);
260 ISSETPRINT_CTRL(reg, TEL16);
261 ISSETPRINT_CTRL(reg, SND16);
262 ISSETPRINT_CTRL(reg, SELTELSF1);
263 ISSETPRINT_CTRL(reg, SELSNDSF1);
264 ISSETPRINT_CTRL(reg, ENTEL);
265 ISSETPRINT_CTRL(reg, ENSND);
266 ISSETPRINT_CTRL(reg, SIBLOOP);
267 ISSETPRINT_CTRL(reg, ENSF1);
268 ISSETPRINT_CTRL(reg, ENSF0);
269 ISSETPRINT_CTRL(reg, ENSIB);
270 printf("\n");
271 printf("SCLKDIV %d\n", TX39_SIBCTRL_SCLKDIV(reg));
272 printf("TELFSDIV %d\n", TX39_SIBCTRL_TELFSDIV(reg));
273 printf("SNDFSDIV %d\n", TX39_SIBCTRL_SNDFSDIV(reg));
274
275 reg = tx_conf_read(tc, TX39_SIBDMACTRL_REG);
276 ISSETPRINT_DMACTRL(reg, SNDBUFF1TIME);
277 ISSETPRINT_DMACTRL(reg, SNDDMALOOP);
278 ISSETPRINT_DMACTRL(reg, ENDMARXSND);
279 ISSETPRINT_DMACTRL(reg, ENDMATXSND);
280 ISSETPRINT_DMACTRL(reg, TELBUFF1TIME);
281 ISSETPRINT_DMACTRL(reg, TELDMALOOP);
282 ISSETPRINT_DMACTRL(reg, ENDMARXTEL);
283 ISSETPRINT_DMACTRL(reg, ENDMATXTEL);
284 printf("\n");
285 printf("SNDDMAPTR %d\n", TX39_SIBDMACTRL_TELDMAPTR(reg));
286 printf("TELDMAPTR %d\n", TX39_SIBDMACTRL_SNDDMAPTR(reg));
287
288 }
289