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