Home | History | Annotate | Line # | Download | only in dev
ucb1200.c revision 1.4
      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