ucb1200.c revision 1.3 1 /* $NetBSD: ucb1200.c,v 1.3 2000/02/27 16:37:50 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
80 #ifdef UCB1200DEBUG
81 void ucb1200_dump __P((struct ucb1200_softc*));
82 #endif
83
84 struct cfattach ucb_ca = {
85 sizeof(struct ucb1200_softc), ucb1200_match, ucb1200_attach
86 };
87
88 int
89 ucb1200_match(parent, cf, aux)
90 struct device *parent;
91 struct cfdata *cf;
92 void *aux;
93 {
94 struct txsib_attach_args *sa = aux;
95 u_int16_t reg;
96
97 if (sa->sa_slot != 0) /* UCB1200 must be subframe 0 */
98 return 0;
99 reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
100
101 if (reg == UCB1200_ID || reg == TC35413F_ID)
102 return 1;
103 else
104 return 0;
105 }
106
107 void
108 ucb1200_attach(parent, self, aux)
109 struct device *parent;
110 struct device *self;
111 void *aux;
112 {
113 struct txsib_attach_args *sa = aux;
114 struct ucb1200_softc *sc = (void*)self;
115
116 sc->sc_tc = sa->sa_tc;
117 sc->sc_parent = parent;
118 sc->sc_snd_rate = sa->sa_snd_rate;
119 sc->sc_tel_rate = sa->sa_tel_rate;
120
121 tx39sib_enable1(sc->sc_parent);
122 tx39sib_enable2(sc->sc_parent);
123
124 #ifdef UCB1200DEBUG
125 if (ucb1200debug)
126 ucb1200_dump(sc);
127 #endif
128 printf("\n");
129
130 config_search(ucb1200_search, self, ucb1200_print);
131 }
132
133 int
134 ucb1200_search(parent, cf, aux)
135 struct device *parent;
136 struct cfdata *cf;
137 void *aux;
138 {
139 struct ucb1200_softc *sc = (void*)parent;
140 struct ucb1200_attach_args ucba;
141
142 ucba.ucba_tc = sc->sc_tc;
143 ucba.ucba_snd_rate = sc->sc_snd_rate;
144 ucba.ucba_tel_rate = sc->sc_tel_rate;
145 ucba.ucba_sib = sc->sc_parent;
146 ucba.ucba_ucb = parent;
147
148 if ((*cf->cf_attach->ca_match)(parent, cf, &ucba))
149 config_attach(parent, cf, &ucba, ucb1200_print);
150
151 return 0;
152 }
153
154 int
155 ucb1200_print(aux, pnp)
156 void *aux;
157 const char *pnp;
158 {
159 return pnp ? QUIET : UNCONF;
160 }
161
162 void
163 ucb1200_state_install(dev, sfun, sarg, sid)
164 struct device *dev;
165 int (*sfun) __P((void*));
166 void *sarg;
167 int sid;
168 {
169 struct ucb1200_softc *sc = (void*)dev;
170
171 sc->sc_child[sid].cs_busy = sfun;
172 sc->sc_child[sid].cs_arg = sarg;
173 }
174
175 int
176 ucb1200_state_idle(dev)
177 struct device *dev;
178 {
179 struct ucb1200_softc *sc = (void*)dev;
180 struct ucbchild_state *cs;
181 int i;
182
183 cs = sc->sc_child;
184 for (i = 0; i < UCB1200_MODULE_MAX; i++, cs++)
185 if (cs->cs_busy)
186 if ((*cs->cs_busy)(cs->cs_arg))
187 return 0;
188
189 return 1; /* idle state */
190 }
191
192 #ifdef UCB1200DEBUG
193 void
194 ucb1200_dump(sc)
195 struct ucb1200_softc *sc;
196 {
197 const char *regname[] = {
198 "IO_DATA ",
199 "IO_DIR ",
200 "POSINTEN ",
201 "NEGINTEN ",
202 "INTSTAT ",
203 "TELECOMCTRLA ",
204 "TELECOMCTRLB ",
205 "AUDIOCTRLA ",
206 "AUDIOCTRLB ",
207 "TOUCHSCREENCTRL",
208 "ADCCTRL ",
209 "ADCDATA ",
210 "ID ",
211 "MODE ",
212 "RESERVED ",
213 "NULL "
214 };
215 tx_chipset_tag_t tc = sc->sc_tc;
216 u_int16_t reg;
217 int i;
218
219 printf("\n\t[UCB1200 register]\n");
220 for (i = 0; i < 16; i++) {
221 reg = txsibsf0_reg_read(tc, i);
222 printf("%s(%02d) 0x%04x ", regname[i], i, reg);
223 bitdisp(reg);
224 }
225 }
226 #endif /* UCB1200DEBUG */
227