ucb1200.c revision 1.4 1 /* $NetBSD: ucb1200.c,v 1.4 2000/03/12 15:36:11 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 * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
31 */
32 #define UCB1200DEBUG
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/tx39sibvar.h>
44 #include <hpcmips/tx/tx39sibreg.h>
45
46 #include <hpcmips/dev/ucb1200var.h>
47 #include <hpcmips/dev/ucb1200reg.h>
48
49 #ifdef UCB1200DEBUG
50 int ucb1200debug = 0;
51 #define DPRINTF(arg) if (ucb1200debug) printf arg;
52 #define DPRINTFN(n, arg) if (ucb1200debug > (n)) printf arg;
53 #else
54 #define DPRINTF(arg)
55 #define DPRINTFN(n, arg)
56 #endif
57
58 struct ucbchild_state {
59 int (*cs_busy) __P((void*));
60 void *cs_arg;
61 };
62
63 struct ucb1200_softc {
64 struct device sc_dev;
65 struct device *sc_parent; /* parent (TX39 SIB module) */
66 tx_chipset_tag_t sc_tc;
67
68 int sc_snd_rate; /* passed down from SIB module */
69 int sc_tel_rate;
70
71 /* inquire child module state */
72 struct ucbchild_state sc_child[UCB1200_MODULE_MAX];
73 };
74
75 int ucb1200_match __P((struct device*, struct cfdata*, void*));
76 void ucb1200_attach __P((struct device*, struct device*, void*));
77 int ucb1200_print __P((void*, const char*));
78 int ucb1200_search __P((struct device*, struct cfdata*, void*));
79 int ucb1200_check_id __P((u_int16_t, int));
80
81 #ifdef UCB1200DEBUG
82 void ucb1200_dump __P((struct ucb1200_softc*));
83 #endif
84
85 struct cfattach ucb_ca = {
86 sizeof(struct ucb1200_softc), ucb1200_match, ucb1200_attach
87 };
88
89 const struct ucb_id {
90 u_int16_t id;
91 const char *product;
92 } ucb_id[] = {
93 { UCB1100_ID, "PHILIPS UCB1100" },
94 { UCB1200_ID, "PHILIPS UCB1200" },
95 { UCB1300_ID, "PHILIPS UCB1300" },
96 { TC35413F_ID, "TOSHIBA TC35413F" },
97 { 0, 0 }
98 };
99
100 int
101 ucb1200_match(parent, cf, aux)
102 struct device *parent;
103 struct cfdata *cf;
104 void *aux;
105 {
106 struct txsib_attach_args *sa = aux;
107 u_int16_t reg;
108
109 if (sa->sa_slot != 0) /* UCB1200 must be subframe 0 */
110 return 0;
111 reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
112
113 return (ucb1200_check_id(reg, 0));
114 }
115
116 void
117 ucb1200_attach(parent, self, aux)
118 struct device *parent;
119 struct device *self;
120 void *aux;
121 {
122 struct txsib_attach_args *sa = aux;
123 struct ucb1200_softc *sc = (void*)self;
124 u_int16_t reg;
125
126 printf(": ");
127 sc->sc_tc = sa->sa_tc;
128 sc->sc_parent = parent;
129 sc->sc_snd_rate = sa->sa_snd_rate;
130 sc->sc_tel_rate = sa->sa_tel_rate;
131
132 tx39sib_enable1(sc->sc_parent);
133 tx39sib_enable2(sc->sc_parent);
134
135 #ifdef UCB1200DEBUG
136 if (ucb1200debug)
137 ucb1200_dump(sc);
138 #endif
139 reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
140 (void)ucb1200_check_id(reg, 1);
141 printf("\n");
142
143 config_search(ucb1200_search, self, ucb1200_print);
144 }
145
146 int
147 ucb1200_search(parent, cf, aux)
148 struct device *parent;
149 struct cfdata *cf;
150 void *aux;
151 {
152 struct ucb1200_softc *sc = (void*)parent;
153 struct ucb1200_attach_args ucba;
154
155 ucba.ucba_tc = sc->sc_tc;
156 ucba.ucba_snd_rate = sc->sc_snd_rate;
157 ucba.ucba_tel_rate = sc->sc_tel_rate;
158 ucba.ucba_sib = sc->sc_parent;
159 ucba.ucba_ucb = parent;
160
161 if ((*cf->cf_attach->ca_match)(parent, cf, &ucba))
162 config_attach(parent, cf, &ucba, ucb1200_print);
163
164 return 0;
165 }
166
167 int
168 ucb1200_print(aux, pnp)
169 void *aux;
170 const char *pnp;
171 {
172 return pnp ? QUIET : UNCONF;
173 }
174
175 int
176 ucb1200_check_id(idreg, print)
177 u_int16_t idreg;
178 int print;
179 {
180 int i;
181
182 for (i = 0; ucb_id[i].product; i++) {
183 if (ucb_id[i].id == idreg) {
184 if (print) {
185 printf("%s", ucb_id[i].product);
186 }
187
188 return (1);
189 }
190 }
191
192 return 0;
193 }
194
195 void
196 ucb1200_state_install(dev, sfun, sarg, sid)
197 struct device *dev;
198 int (*sfun) __P((void*));
199 void *sarg;
200 int sid;
201 {
202 struct ucb1200_softc *sc = (void*)dev;
203
204 sc->sc_child[sid].cs_busy = sfun;
205 sc->sc_child[sid].cs_arg = sarg;
206 }
207
208 int
209 ucb1200_state_idle(dev)
210 struct device *dev;
211 {
212 struct ucb1200_softc *sc = (void*)dev;
213 struct ucbchild_state *cs;
214 int i;
215
216 cs = sc->sc_child;
217 for (i = 0; i < UCB1200_MODULE_MAX; i++, cs++)
218 if (cs->cs_busy)
219 if ((*cs->cs_busy)(cs->cs_arg))
220 return 0;
221
222 return 1; /* idle state */
223 }
224
225 #ifdef UCB1200DEBUG
226 void
227 ucb1200_dump(sc)
228 struct ucb1200_softc *sc;
229 {
230 const char *regname[] = {
231 "IO_DATA ",
232 "IO_DIR ",
233 "POSINTEN ",
234 "NEGINTEN ",
235 "INTSTAT ",
236 "TELECOMCTRLA ",
237 "TELECOMCTRLB ",
238 "AUDIOCTRLA ",
239 "AUDIOCTRLB ",
240 "TOUCHSCREENCTRL",
241 "ADCCTRL ",
242 "ADCDATA ",
243 "ID ",
244 "MODE ",
245 "RESERVED ",
246 "NULL "
247 };
248 tx_chipset_tag_t tc = sc->sc_tc;
249 u_int16_t reg;
250 int i;
251
252 printf("\n\t[UCB1200 register]\n");
253 for (i = 0; i < 16; i++) {
254 reg = txsibsf0_reg_read(tc, i);
255 printf("%s(%02d) 0x%04x ", regname[i], i, reg);
256 bitdisp(reg);
257 }
258 }
259 #endif /* UCB1200DEBUG */
260