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