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