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