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