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