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