ucb1200.c revision 1.5.2.2 1 1.5.2.2 bouyer /* $NetBSD: ucb1200.c,v 1.5.2.2 2000/11/20 20:46:19 bouyer Exp $ */
2 1.5.2.2 bouyer
3 1.5.2.2 bouyer /*
4 1.5.2.2 bouyer * Copyright (c) 2000, by UCHIYAMA Yasushi
5 1.5.2.2 bouyer * All rights reserved.
6 1.5.2.2 bouyer *
7 1.5.2.2 bouyer * Redistribution and use in source and binary forms, with or without
8 1.5.2.2 bouyer * modification, are permitted provided that the following conditions
9 1.5.2.2 bouyer * are met:
10 1.5.2.2 bouyer * 1. Redistributions of source code must retain the above copyright
11 1.5.2.2 bouyer * notice, this list of conditions and the following disclaimer.
12 1.5.2.2 bouyer * 2. The name of the developer may NOT be used to endorse or promote products
13 1.5.2.2 bouyer * derived from this software without specific prior written permission.
14 1.5.2.2 bouyer *
15 1.5.2.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.5.2.2 bouyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.5.2.2 bouyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.5.2.2 bouyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.5.2.2 bouyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.5.2.2 bouyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.5.2.2 bouyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.5.2.2 bouyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.5.2.2 bouyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.5.2.2 bouyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.5.2.2 bouyer * SUCH DAMAGE.
26 1.5.2.2 bouyer *
27 1.5.2.2 bouyer */
28 1.5.2.2 bouyer
29 1.5.2.2 bouyer /*
30 1.5.2.2 bouyer * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
31 1.5.2.2 bouyer */
32 1.5.2.2 bouyer #define UCB1200DEBUG
33 1.5.2.2 bouyer #include "opt_tx39_debug.h"
34 1.5.2.2 bouyer
35 1.5.2.2 bouyer #include <sys/param.h>
36 1.5.2.2 bouyer #include <sys/systm.h>
37 1.5.2.2 bouyer #include <sys/device.h>
38 1.5.2.2 bouyer
39 1.5.2.2 bouyer #include <machine/bus.h>
40 1.5.2.2 bouyer #include <machine/intr.h>
41 1.5.2.2 bouyer
42 1.5.2.2 bouyer #include <hpcmips/tx/tx39var.h>
43 1.5.2.2 bouyer #include <hpcmips/tx/tx39sibvar.h>
44 1.5.2.2 bouyer #include <hpcmips/tx/tx39sibreg.h>
45 1.5.2.2 bouyer
46 1.5.2.2 bouyer #include <hpcmips/dev/ucb1200var.h>
47 1.5.2.2 bouyer #include <hpcmips/dev/ucb1200reg.h>
48 1.5.2.2 bouyer
49 1.5.2.2 bouyer #ifdef UCB1200DEBUG
50 1.5.2.2 bouyer int ucb1200debug = 1;
51 1.5.2.2 bouyer #define DPRINTF(arg) if (ucb1200debug) printf arg;
52 1.5.2.2 bouyer #define DPRINTFN(n, arg) if (ucb1200debug > (n)) printf arg;
53 1.5.2.2 bouyer #else
54 1.5.2.2 bouyer #define DPRINTF(arg)
55 1.5.2.2 bouyer #define DPRINTFN(n, arg)
56 1.5.2.2 bouyer #endif
57 1.5.2.2 bouyer
58 1.5.2.2 bouyer struct ucbchild_state {
59 1.5.2.2 bouyer int (*cs_busy)(void *);
60 1.5.2.2 bouyer void *cs_arg;
61 1.5.2.2 bouyer };
62 1.5.2.2 bouyer
63 1.5.2.2 bouyer struct ucb1200_softc {
64 1.5.2.2 bouyer struct device sc_dev;
65 1.5.2.2 bouyer struct device *sc_parent; /* parent (TX39 SIB module) */
66 1.5.2.2 bouyer tx_chipset_tag_t sc_tc;
67 1.5.2.2 bouyer
68 1.5.2.2 bouyer int sc_snd_rate; /* passed down from SIB module */
69 1.5.2.2 bouyer int sc_tel_rate;
70 1.5.2.2 bouyer
71 1.5.2.2 bouyer /* inquire child module state */
72 1.5.2.2 bouyer struct ucbchild_state sc_child[UCB1200_MODULE_MAX];
73 1.5.2.2 bouyer };
74 1.5.2.2 bouyer
75 1.5.2.2 bouyer int ucb1200_match(struct device *, struct cfdata *, void *);
76 1.5.2.2 bouyer void ucb1200_attach(struct device *, struct device *, void *);
77 1.5.2.2 bouyer int ucb1200_print(void *, const char *);
78 1.5.2.2 bouyer int ucb1200_search(struct device *, struct cfdata *, void *);
79 1.5.2.2 bouyer int ucb1200_check_id(u_int16_t, int);
80 1.5.2.2 bouyer
81 1.5.2.2 bouyer #ifdef UCB1200DEBUG
82 1.5.2.2 bouyer void ucb1200_dump(struct ucb1200_softc *);
83 1.5.2.2 bouyer #endif
84 1.5.2.2 bouyer
85 1.5.2.2 bouyer struct cfattach ucb_ca = {
86 1.5.2.2 bouyer sizeof(struct ucb1200_softc), ucb1200_match, ucb1200_attach
87 1.5.2.2 bouyer };
88 1.5.2.2 bouyer
89 1.5.2.2 bouyer const struct ucb_id {
90 1.5.2.2 bouyer u_int16_t id;
91 1.5.2.2 bouyer const char *product;
92 1.5.2.2 bouyer } ucb_id[] = {
93 1.5.2.2 bouyer { UCB1100_ID, "PHILIPS UCB1100" },
94 1.5.2.2 bouyer { UCB1200_ID, "PHILIPS UCB1200" },
95 1.5.2.2 bouyer { UCB1300_ID, "PHILIPS UCB1300" },
96 1.5.2.2 bouyer { TC35413F_ID, "TOSHIBA TC35413F" },
97 1.5.2.2 bouyer { 0, 0 }
98 1.5.2.2 bouyer };
99 1.5.2.2 bouyer
100 1.5.2.2 bouyer int
101 1.5.2.2 bouyer ucb1200_match(struct device *parent, struct cfdata *cf, void *aux)
102 1.5.2.2 bouyer {
103 1.5.2.2 bouyer struct txsib_attach_args *sa = aux;
104 1.5.2.2 bouyer u_int16_t reg;
105 1.5.2.2 bouyer
106 1.5.2.2 bouyer if (sa->sa_slot != 0) /* UCB1200 must be subframe 0 */
107 1.5.2.2 bouyer return 0;
108 1.5.2.2 bouyer reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
109 1.5.2.2 bouyer
110 1.5.2.2 bouyer return (ucb1200_check_id(reg, 0));
111 1.5.2.2 bouyer }
112 1.5.2.2 bouyer
113 1.5.2.2 bouyer void
114 1.5.2.2 bouyer ucb1200_attach(struct device *parent, struct device *self, void *aux)
115 1.5.2.2 bouyer {
116 1.5.2.2 bouyer struct txsib_attach_args *sa = aux;
117 1.5.2.2 bouyer struct ucb1200_softc *sc = (void*)self;
118 1.5.2.2 bouyer u_int16_t reg;
119 1.5.2.2 bouyer
120 1.5.2.2 bouyer printf(": ");
121 1.5.2.2 bouyer sc->sc_tc = sa->sa_tc;
122 1.5.2.2 bouyer sc->sc_parent = parent;
123 1.5.2.2 bouyer sc->sc_snd_rate = sa->sa_snd_rate;
124 1.5.2.2 bouyer sc->sc_tel_rate = sa->sa_tel_rate;
125 1.5.2.2 bouyer
126 1.5.2.2 bouyer tx39sib_enable1(sc->sc_parent);
127 1.5.2.2 bouyer tx39sib_enable2(sc->sc_parent);
128 1.5.2.2 bouyer
129 1.5.2.2 bouyer #ifdef UCB1200DEBUG
130 1.5.2.2 bouyer if (ucb1200debug)
131 1.5.2.2 bouyer ucb1200_dump(sc);
132 1.5.2.2 bouyer #endif
133 1.5.2.2 bouyer reg = txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG);
134 1.5.2.2 bouyer (void)ucb1200_check_id(reg, 1);
135 1.5.2.2 bouyer printf("\n");
136 1.5.2.2 bouyer
137 1.5.2.2 bouyer config_search(ucb1200_search, self, ucb1200_print);
138 1.5.2.2 bouyer }
139 1.5.2.2 bouyer
140 1.5.2.2 bouyer int
141 1.5.2.2 bouyer ucb1200_search(struct device *parent, struct cfdata *cf, void *aux)
142 1.5.2.2 bouyer {
143 1.5.2.2 bouyer struct ucb1200_softc *sc = (void*)parent;
144 1.5.2.2 bouyer struct ucb1200_attach_args ucba;
145 1.5.2.2 bouyer
146 1.5.2.2 bouyer ucba.ucba_tc = sc->sc_tc;
147 1.5.2.2 bouyer ucba.ucba_snd_rate = sc->sc_snd_rate;
148 1.5.2.2 bouyer ucba.ucba_tel_rate = sc->sc_tel_rate;
149 1.5.2.2 bouyer ucba.ucba_sib = sc->sc_parent;
150 1.5.2.2 bouyer ucba.ucba_ucb = parent;
151 1.5.2.2 bouyer
152 1.5.2.2 bouyer if ((*cf->cf_attach->ca_match)(parent, cf, &ucba))
153 1.5.2.2 bouyer config_attach(parent, cf, &ucba, ucb1200_print);
154 1.5.2.2 bouyer
155 1.5.2.2 bouyer return 0;
156 1.5.2.2 bouyer }
157 1.5.2.2 bouyer
158 1.5.2.2 bouyer int
159 1.5.2.2 bouyer ucb1200_print(void *aux, const char *pnp)
160 1.5.2.2 bouyer {
161 1.5.2.2 bouyer return pnp ? QUIET : UNCONF;
162 1.5.2.2 bouyer }
163 1.5.2.2 bouyer
164 1.5.2.2 bouyer int
165 1.5.2.2 bouyer ucb1200_check_id(u_int16_t idreg, int print)
166 1.5.2.2 bouyer {
167 1.5.2.2 bouyer int i;
168 1.5.2.2 bouyer
169 1.5.2.2 bouyer for (i = 0; ucb_id[i].product; i++) {
170 1.5.2.2 bouyer if (ucb_id[i].id == idreg) {
171 1.5.2.2 bouyer if (print) {
172 1.5.2.2 bouyer printf("%s", ucb_id[i].product);
173 1.5.2.2 bouyer }
174 1.5.2.2 bouyer
175 1.5.2.2 bouyer return (1);
176 1.5.2.2 bouyer }
177 1.5.2.2 bouyer }
178 1.5.2.2 bouyer
179 1.5.2.2 bouyer return 0;
180 1.5.2.2 bouyer }
181 1.5.2.2 bouyer
182 1.5.2.2 bouyer void
183 1.5.2.2 bouyer ucb1200_state_install(struct device *dev, int (*sfun)(void *), void *sarg,
184 1.5.2.2 bouyer int sid)
185 1.5.2.2 bouyer {
186 1.5.2.2 bouyer struct ucb1200_softc *sc = (void*)dev;
187 1.5.2.2 bouyer
188 1.5.2.2 bouyer sc->sc_child[sid].cs_busy = sfun;
189 1.5.2.2 bouyer sc->sc_child[sid].cs_arg = sarg;
190 1.5.2.2 bouyer }
191 1.5.2.2 bouyer
192 1.5.2.2 bouyer int
193 1.5.2.2 bouyer ucb1200_state_idle(dev)
194 1.5.2.2 bouyer struct device *dev;
195 1.5.2.2 bouyer {
196 1.5.2.2 bouyer struct ucb1200_softc *sc = (void*)dev;
197 1.5.2.2 bouyer struct ucbchild_state *cs;
198 1.5.2.2 bouyer int i;
199 1.5.2.2 bouyer
200 1.5.2.2 bouyer cs = sc->sc_child;
201 1.5.2.2 bouyer for (i = 0; i < UCB1200_MODULE_MAX; i++, cs++)
202 1.5.2.2 bouyer if (cs->cs_busy)
203 1.5.2.2 bouyer if ((*cs->cs_busy)(cs->cs_arg))
204 1.5.2.2 bouyer return 0;
205 1.5.2.2 bouyer
206 1.5.2.2 bouyer return 1; /* idle state */
207 1.5.2.2 bouyer }
208 1.5.2.2 bouyer
209 1.5.2.2 bouyer #ifdef UCB1200DEBUG
210 1.5.2.2 bouyer void
211 1.5.2.2 bouyer ucb1200_dump(struct ucb1200_softc *sc)
212 1.5.2.2 bouyer {
213 1.5.2.2 bouyer const char *regname[] = {
214 1.5.2.2 bouyer "IO_DATA ",
215 1.5.2.2 bouyer "IO_DIR ",
216 1.5.2.2 bouyer "POSINTEN ",
217 1.5.2.2 bouyer "NEGINTEN ",
218 1.5.2.2 bouyer "INTSTAT ",
219 1.5.2.2 bouyer "TELECOMCTRLA ",
220 1.5.2.2 bouyer "TELECOMCTRLB ",
221 1.5.2.2 bouyer "AUDIOCTRLA ",
222 1.5.2.2 bouyer "AUDIOCTRLB ",
223 1.5.2.2 bouyer "TOUCHSCREENCTRL",
224 1.5.2.2 bouyer "ADCCTRL ",
225 1.5.2.2 bouyer "ADCDATA ",
226 1.5.2.2 bouyer "ID ",
227 1.5.2.2 bouyer "MODE ",
228 1.5.2.2 bouyer "RESERVED ",
229 1.5.2.2 bouyer "NULL "
230 1.5.2.2 bouyer };
231 1.5.2.2 bouyer tx_chipset_tag_t tc;
232 1.5.2.2 bouyer u_int16_t reg;
233 1.5.2.2 bouyer int i;
234 1.5.2.2 bouyer
235 1.5.2.2 bouyer tc = sc->sc_tc;
236 1.5.2.2 bouyer
237 1.5.2.2 bouyer printf("\n\t[UCB1200 register]\n");
238 1.5.2.2 bouyer for (i = 0; i < 16; i++) {
239 1.5.2.2 bouyer reg = txsibsf0_reg_read(tc, i);
240 1.5.2.2 bouyer printf("%s(%02d) 0x%04x ", regname[i], i, reg);
241 1.5.2.2 bouyer bitdisp(reg);
242 1.5.2.2 bouyer }
243 1.5.2.2 bouyer }
244 1.5.2.2 bouyer #endif /* UCB1200DEBUG */
245