Home | History | Annotate | Line # | Download | only in ic
ad1848.c revision 1.8.2.1
      1  1.8.2.1   bouyer /*	$NetBSD: ad1848.c,v 1.8.2.1 2000/11/20 11:40:03 bouyer Exp $	*/
      2      1.1       pk 
      3      1.5  mycroft /*-
      4      1.5  mycroft  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5      1.5  mycroft  * All rights reserved.
      6      1.5  mycroft  *
      7      1.5  mycroft  * This code is derived from software contributed to The NetBSD Foundation
      8      1.5  mycroft  * by Ken Hornstein and John Kohl.
      9      1.5  mycroft  *
     10      1.5  mycroft  * Redistribution and use in source and binary forms, with or without
     11      1.5  mycroft  * modification, are permitted provided that the following conditions
     12      1.5  mycroft  * are met:
     13      1.5  mycroft  * 1. Redistributions of source code must retain the above copyright
     14      1.5  mycroft  *    notice, this list of conditions and the following disclaimer.
     15      1.5  mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.5  mycroft  *    notice, this list of conditions and the following disclaimer in the
     17      1.5  mycroft  *    documentation and/or other materials provided with the distribution.
     18      1.5  mycroft  * 3. All advertising materials mentioning features or use of this software
     19      1.5  mycroft  *    must display the following acknowledgement:
     20      1.7    itohy  *	This product includes software developed by the NetBSD
     21      1.7    itohy  *	Foundation, Inc. and its contributors.
     22      1.7    itohy  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23      1.7    itohy  *    contributors may be used to endorse or promote products derived
     24      1.5  mycroft  *    from this software without specific prior written permission.
     25      1.5  mycroft  *
     26      1.5  mycroft  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27      1.5  mycroft  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28      1.5  mycroft  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29      1.5  mycroft  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30      1.5  mycroft  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31      1.5  mycroft  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32      1.5  mycroft  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33      1.5  mycroft  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34      1.5  mycroft  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35      1.5  mycroft  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36      1.5  mycroft  * POSSIBILITY OF SUCH DAMAGE.
     37      1.5  mycroft  */
     38      1.1       pk /*
     39      1.1       pk  * Copyright (c) 1994 John Brezak
     40      1.1       pk  * Copyright (c) 1991-1993 Regents of the University of California.
     41      1.1       pk  * All rights reserved.
     42      1.1       pk  *
     43      1.1       pk  * Redistribution and use in source and binary forms, with or without
     44      1.1       pk  * modification, are permitted provided that the following conditions
     45      1.1       pk  * are met:
     46      1.1       pk  * 1. Redistributions of source code must retain the above copyright
     47      1.1       pk  *    notice, this list of conditions and the following disclaimer.
     48      1.1       pk  * 2. Redistributions in binary form must reproduce the above copyright
     49      1.1       pk  *    notice, this list of conditions and the following disclaimer in the
     50      1.1       pk  *    documentation and/or other materials provided with the distribution.
     51      1.1       pk  * 3. All advertising materials mentioning features or use of this software
     52      1.1       pk  *    must display the following acknowledgement:
     53      1.1       pk  *	This product includes software developed by the Computer Systems
     54      1.1       pk  *	Engineering Group at Lawrence Berkeley Laboratory.
     55      1.1       pk  * 4. Neither the name of the University nor of the Laboratory may be used
     56      1.1       pk  *    to endorse or promote products derived from this software without
     57      1.1       pk  *    specific prior written permission.
     58      1.1       pk  *
     59      1.1       pk  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     60      1.1       pk  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61      1.1       pk  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     62      1.1       pk  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     63      1.1       pk  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     64      1.1       pk  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     65      1.1       pk  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66      1.1       pk  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67      1.1       pk  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68      1.1       pk  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69      1.1       pk  * SUCH DAMAGE.
     70      1.1       pk  *
     71      1.1       pk  */
     72      1.1       pk 
     73      1.1       pk /*
     74      1.1       pk  * Copyright by Hannu Savolainen 1994
     75      1.1       pk  *
     76      1.1       pk  * Redistribution and use in source and binary forms, with or without
     77      1.1       pk  * modification, are permitted provided that the following conditions are
     78      1.1       pk  * met: 1. Redistributions of source code must retain the above copyright
     79      1.1       pk  * notice, this list of conditions and the following disclaimer. 2.
     80      1.1       pk  * Redistributions in binary form must reproduce the above copyright notice,
     81      1.1       pk  * this list of conditions and the following disclaimer in the documentation
     82      1.1       pk  * and/or other materials provided with the distribution.
     83      1.1       pk  *
     84      1.1       pk  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
     85      1.1       pk  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     86      1.1       pk  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     87      1.1       pk  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
     88      1.1       pk  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     89      1.1       pk  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     90      1.1       pk  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     91      1.1       pk  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     92      1.1       pk  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     93      1.1       pk  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     94      1.1       pk  * SUCH DAMAGE.
     95      1.1       pk  *
     96      1.1       pk  */
     97      1.1       pk /*
     98      1.1       pk  * Portions of this code are from the VOXware support for the ad1848
     99      1.1       pk  * by Hannu Savolainen <hannu (at) voxware.pp.fi>
    100      1.1       pk  *
    101      1.1       pk  * Portions also supplied from the SoundBlaster driver for NetBSD.
    102      1.1       pk  */
    103      1.1       pk 
    104      1.1       pk #include <sys/param.h>
    105      1.1       pk #include <sys/systm.h>
    106      1.1       pk #include <sys/errno.h>
    107      1.1       pk #include <sys/ioctl.h>
    108      1.1       pk #include <sys/device.h>
    109      1.7    itohy #include <sys/fcntl.h>
    110      1.1       pk /*#include <sys/syslog.h>*/
    111      1.1       pk /*#include <sys/proc.h>*/
    112      1.1       pk 
    113      1.1       pk #include <machine/cpu.h>
    114      1.1       pk #include <machine/bus.h>
    115      1.1       pk 
    116      1.1       pk #include <sys/audioio.h>
    117      1.1       pk 
    118      1.1       pk #include <dev/audio_if.h>
    119      1.1       pk #include <dev/auconv.h>
    120      1.1       pk 
    121      1.1       pk #include <dev/ic/ad1848reg.h>
    122      1.1       pk #include <dev/ic/cs4231reg.h>
    123      1.6       rh #include <dev/ic/cs4237reg.h>
    124      1.1       pk #include <dev/ic/ad1848var.h>
    125      1.1       pk #if 0
    126      1.1       pk #include <dev/isa/cs4231var.h>
    127      1.1       pk #endif
    128      1.1       pk 
    129      1.1       pk #ifdef AUDIO_DEBUG
    130      1.1       pk #define DPRINTF(x)	if (ad1848debug) printf x
    131      1.2       pk int	ad1848debug = 0;
    132      1.1       pk #else
    133      1.1       pk #define DPRINTF(x)
    134      1.1       pk #endif
    135      1.1       pk 
    136      1.1       pk /*
    137      1.1       pk  * Initial values for the indirect registers of CS4248/AD1848.
    138      1.1       pk  */
    139      1.1       pk static int ad1848_init_values[] = {
    140      1.1       pk     GAIN_12|INPUT_MIC_GAIN_ENABLE,	/* Left Input Control */
    141      1.1       pk     GAIN_12|INPUT_MIC_GAIN_ENABLE,	/* Right Input Control */
    142      1.1       pk     ATTEN_12,				/* Left Aux #1 Input Control */
    143      1.1       pk     ATTEN_12,				/* Right Aux #1 Input Control */
    144      1.1       pk     ATTEN_12,				/* Left Aux #2 Input Control */
    145      1.1       pk     ATTEN_12,				/* Right Aux #2 Input Control */
    146      1.1       pk     /* bits 5-0 are attenuation select */
    147      1.1       pk     ATTEN_12,				/* Left DAC output Control */
    148      1.1       pk     ATTEN_12,				/* Right DAC output Control */
    149      1.1       pk     CLOCK_XTAL1|FMT_PCM8,		/* Clock and Data Format */
    150      1.1       pk     SINGLE_DMA|AUTO_CAL_ENABLE,		/* Interface Config */
    151      1.1       pk     INTERRUPT_ENABLE,			/* Pin control */
    152      1.1       pk     0x00,				/* Test and Init */
    153      1.1       pk     MODE2,				/* Misc control */
    154      1.1       pk     ATTEN_0<<2,				/* Digital Mix Control */
    155      1.1       pk     0,					/* Upper base Count */
    156      1.1       pk     0,					/* Lower base Count */
    157      1.1       pk 
    158      1.1       pk     /* These are for CS4231 &c. only (additional registers): */
    159      1.1       pk     0,					/* Alt feature 1 */
    160      1.1       pk     0,					/* Alt feature 2 */
    161      1.1       pk     ATTEN_12,				/* Left line in */
    162      1.1       pk     ATTEN_12,				/* Right line in */
    163      1.1       pk     0,					/* Timer low */
    164      1.1       pk     0,					/* Timer high */
    165      1.1       pk     0,					/* unused */
    166      1.1       pk     0,					/* unused */
    167      1.1       pk     0,					/* IRQ status */
    168      1.1       pk     0,					/* unused */
    169      1.1       pk 			/* Mono input (a.k.a speaker) (mic) Control */
    170      1.1       pk     MONO_INPUT_MUTE|ATTEN_6,		/* mute speaker by default */
    171      1.1       pk     0,					/* unused */
    172      1.1       pk     0,					/* record format */
    173      1.1       pk     0,					/* Crystal Clock Select */
    174      1.1       pk     0,					/* upper record count */
    175      1.1       pk     0					/* lower record count */
    176      1.1       pk };
    177      1.1       pk 
    178      1.1       pk 
    179      1.1       pk __inline int ad_read __P((struct ad1848_softc *, int));
    180      1.1       pk __inline void ad_write __P((struct ad1848_softc *, int, int));
    181      1.1       pk static void ad_set_MCE __P((struct ad1848_softc *, int));
    182      1.1       pk static void wait_for_calibration __P((struct ad1848_softc *));
    183      1.1       pk 
    184      1.1       pk 
    185      1.1       pk int
    186      1.1       pk ad1848_to_vol(cp, vol)
    187      1.1       pk 	mixer_ctrl_t *cp;
    188      1.1       pk 	struct ad1848_volume *vol;
    189      1.1       pk {
    190      1.1       pk 	if (cp->un.value.num_channels == 1) {
    191      1.1       pk 		vol->left =
    192      1.1       pk 		vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    193      1.1       pk 		return(1);
    194      1.1       pk 	}
    195      1.1       pk 	else if (cp->un.value.num_channels == 2) {
    196      1.1       pk 		vol->left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    197      1.1       pk 		vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    198      1.1       pk 		return(1);
    199      1.1       pk 	}
    200      1.1       pk 	return(0);
    201      1.1       pk }
    202      1.1       pk 
    203      1.1       pk int
    204      1.1       pk ad1848_from_vol(cp, vol)
    205      1.1       pk 	mixer_ctrl_t *cp;
    206      1.1       pk 	struct ad1848_volume *vol;
    207      1.1       pk {
    208      1.1       pk 	if (cp->un.value.num_channels == 1) {
    209      1.1       pk 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
    210      1.1       pk 		return(1);
    211      1.1       pk 	}
    212      1.1       pk 	else if (cp->un.value.num_channels == 2) {
    213      1.1       pk 		cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
    214      1.1       pk 		cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
    215      1.1       pk 		return(1);
    216      1.1       pk 	}
    217      1.1       pk 	return(0);
    218      1.1       pk }
    219      1.1       pk 
    220      1.1       pk 
    221      1.1       pk __inline int
    222      1.1       pk ad_read(sc, reg)
    223      1.1       pk 	struct ad1848_softc *sc;
    224      1.1       pk 	int reg;
    225      1.1       pk {
    226      1.1       pk 	int x;
    227      1.1       pk 
    228      1.1       pk 	ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
    229      1.1       pk 	x = ADREAD(sc, AD1848_IDATA);
    230      1.1       pk 	/*  printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */
    231      1.1       pk 	return x;
    232      1.1       pk }
    233      1.1       pk 
    234      1.1       pk __inline void
    235      1.1       pk ad_write(sc, reg, data)
    236      1.1       pk 	struct ad1848_softc *sc;
    237      1.1       pk 	int reg;
    238      1.1       pk 	int data;
    239      1.1       pk {
    240      1.1       pk 	ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
    241      1.1       pk 	ADWRITE(sc, AD1848_IDATA, data & 0xff);
    242      1.1       pk 	/* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
    243      1.1       pk }
    244      1.1       pk 
    245      1.6       rh /*
    246      1.6       rh  * extended registers (mode 3) require an additional level of
    247      1.6       rh  * indirection through CS_XREG (I23).
    248      1.6       rh  */
    249      1.6       rh 
    250      1.6       rh __inline int
    251      1.6       rh ad_xread(sc, reg)
    252      1.6       rh 	struct ad1848_softc *sc;
    253      1.6       rh 	int reg;
    254      1.6       rh {
    255      1.6       rh 	int x;
    256      1.6       rh 
    257      1.6       rh 	ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
    258      1.6       rh 	ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
    259      1.6       rh 	x = ADREAD(sc, AD1848_IDATA);
    260      1.6       rh 
    261      1.6       rh 	return x;
    262      1.6       rh }
    263      1.6       rh 
    264      1.6       rh __inline void
    265      1.6       rh ad_xwrite(sc, reg, val)
    266      1.6       rh 	struct ad1848_softc *sc;
    267      1.6       rh 	int reg, val;
    268      1.6       rh {
    269      1.6       rh 	ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
    270      1.6       rh 	ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
    271      1.6       rh 	ADWRITE(sc, AD1848_IDATA, val & 0xff);
    272      1.6       rh }
    273      1.6       rh 
    274      1.1       pk static void
    275      1.1       pk ad_set_MCE(sc, state)
    276      1.1       pk 	struct ad1848_softc *sc;
    277      1.1       pk 	int state;
    278      1.1       pk {
    279      1.1       pk 	if (state)
    280      1.1       pk 		sc->MCE_bit = MODE_CHANGE_ENABLE;
    281      1.1       pk 	else
    282      1.1       pk 		sc->MCE_bit = 0;
    283      1.1       pk 	ADWRITE(sc, AD1848_IADDR, sc->MCE_bit);
    284      1.1       pk }
    285      1.1       pk 
    286      1.1       pk static void
    287      1.1       pk wait_for_calibration(sc)
    288      1.1       pk 	struct ad1848_softc *sc;
    289      1.1       pk {
    290      1.1       pk 	int timeout;
    291      1.1       pk 
    292      1.1       pk 	DPRINTF(("ad1848: Auto calibration started.\n"));
    293      1.1       pk 	/*
    294      1.1       pk 	 * Wait until the auto calibration process has finished.
    295      1.1       pk 	 *
    296      1.1       pk 	 * 1) Wait until the chip becomes ready (reads don't return 0x80).
    297      1.1       pk 	 * 2) Wait until the ACI bit of I11 gets on and then off.
    298      1.1       pk 	 *    Because newer chips are fast we may never see the ACI
    299      1.1       pk 	 *    bit go on.  Just delay a little instead.
    300      1.1       pk 	 */
    301      1.1       pk 	timeout = 10000;
    302      1.1       pk 	while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) {
    303      1.1       pk 		delay(10);
    304      1.1       pk 		timeout--;
    305      1.1       pk 	}
    306      1.1       pk 	if (timeout <= 0)
    307      1.1       pk 		DPRINTF(("ad1848: Auto calibration timed out(1).\n"));
    308      1.1       pk 
    309      1.1       pk 	/* Set register addr */
    310      1.1       pk 	ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
    311      1.1       pk 	/* Wait for address to appear when read back. */
    312      1.1       pk 	timeout = 100000;
    313      1.1       pk 	while (timeout > 0 &&
    314      1.1       pk 	       (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) {
    315      1.1       pk 		delay(10);
    316      1.1       pk 		timeout--;
    317      1.1       pk 	}
    318      1.1       pk 	if (timeout <= 0)
    319      1.1       pk 		DPRINTF(("ad1848: Auto calibration timed out(1.5).\n"));
    320      1.1       pk 
    321      1.1       pk 	if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
    322      1.1       pk 		if (sc->mode > 1) {
    323      1.1       pk 			/* A new chip, just delay a little. */
    324      1.1       pk 			delay(100);         /* XXX what should it be? */
    325      1.1       pk 		} else {
    326      1.1       pk 			timeout = 10000;
    327      1.1       pk 			while (timeout > 0 &&
    328      1.1       pk 			       !(ad_read(sc, SP_TEST_AND_INIT) &
    329      1.1       pk 				 AUTO_CAL_IN_PROG)) {
    330      1.1       pk 				delay(10);
    331      1.1       pk 				timeout--;
    332      1.1       pk 			}
    333      1.1       pk 			if (timeout <= 0)
    334      1.1       pk 				DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
    335      1.1       pk 		}
    336      1.1       pk 	}
    337      1.1       pk 
    338      1.1       pk 	timeout = 10000;
    339      1.1       pk 	while (timeout > 0 &&
    340      1.1       pk 	       ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) {
    341      1.1       pk 		delay(10);
    342      1.1       pk 		timeout--;
    343      1.1       pk 	}
    344      1.1       pk 	if (timeout <= 0)
    345      1.1       pk 		DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
    346      1.1       pk }
    347      1.1       pk 
    348      1.1       pk #ifdef AUDIO_DEBUG
    349      1.1       pk void
    350      1.1       pk ad1848_dump_regs(sc)
    351      1.1       pk 	struct ad1848_softc *sc;
    352      1.1       pk {
    353      1.1       pk 	int i;
    354      1.1       pk 	u_char r;
    355      1.1       pk 
    356      1.1       pk 	printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
    357      1.1       pk 	printf(" regs: ");
    358      1.1       pk 	for (i = 0; i < 16; i++) {
    359      1.1       pk 		r = ad_read(sc, i);
    360      1.1       pk 		printf("%02x ", r);
    361      1.1       pk 	}
    362      1.6       rh 	if (sc->mode >= 2) {
    363      1.1       pk 		for (i = 16; i < 32; i++) {
    364      1.1       pk 			r = ad_read(sc, i);
    365      1.1       pk 			printf("%02x ", r);
    366      1.1       pk 		}
    367      1.1       pk 	}
    368      1.1       pk 	printf("\n");
    369      1.1       pk }
    370      1.1       pk #endif
    371      1.1       pk 
    372      1.1       pk 
    373      1.1       pk /*
    374      1.1       pk  * Attach hardware to driver, attach hardware driver to audio
    375      1.1       pk  * pseudo-device driver .
    376      1.1       pk  */
    377      1.1       pk void
    378      1.1       pk ad1848_attach(sc)
    379      1.1       pk 	struct ad1848_softc *sc;
    380      1.1       pk {
    381      1.1       pk 	int i;
    382      1.1       pk 	static struct ad1848_volume vol_mid = {220, 220};
    383      1.1       pk 	static struct ad1848_volume vol_0   = {0, 0};
    384      1.1       pk 	struct audio_params pparams, rparams;
    385      1.1       pk 	int timeout;
    386      1.1       pk 
    387      1.1       pk 	/* Initialize the ad1848... */
    388      1.1       pk 	for (i = 0; i < 0x10; i++) {
    389      1.1       pk 		ad_write(sc, i, ad1848_init_values[i]);
    390      1.1       pk 		timeout = 100000;
    391      1.7    itohy 		while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
    392      1.1       pk 			timeout--;
    393      1.1       pk 	}
    394      1.1       pk 	/* ...and additional CS4231 stuff too */
    395      1.6       rh 	if (sc->mode >= 2) {
    396      1.1       pk 		ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
    397      1.1       pk 		for (i = 0x10; i < 0x20; i++)
    398      1.1       pk 			if (ad1848_init_values[i] != 0) {
    399      1.1       pk 				ad_write(sc, i, ad1848_init_values[i]);
    400      1.1       pk 				timeout = 100000;
    401      1.1       pk 				while (timeout > 0 &&
    402      1.7    itohy 				       ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
    403      1.1       pk 					timeout--;
    404      1.1       pk 			}
    405      1.1       pk 	}
    406      1.1       pk 	ad1848_reset(sc);
    407      1.1       pk 
    408      1.1       pk 	pparams = audio_default;
    409      1.1       pk 	rparams = audio_default;
    410      1.1       pk 	ad1848_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
    411      1.1       pk 
    412      1.1       pk 	/* Set default gains */
    413      1.1       pk 	ad1848_set_rec_gain(sc, &vol_mid);
    414      1.1       pk 	ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
    415      1.1       pk 	ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
    416      1.1       pk 	ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);	/* CD volume */
    417      1.7    itohy 	sc->mute[AD1848_MONITOR_CHANNEL] = MUTE_ALL;
    418      1.6       rh 	if (sc->mode >= 2) {
    419      1.1       pk 		ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
    420      1.1       pk 		ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
    421      1.1       pk 		ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
    422      1.1       pk 		sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
    423      1.1       pk 	} else
    424      1.1       pk 		ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
    425      1.1       pk 
    426      1.1       pk 	/* Set default port */
    427      1.1       pk 	ad1848_set_rec_port(sc, MIC_IN_PORT);
    428      1.1       pk 
    429      1.1       pk 	printf(": %s", sc->chip_name);
    430      1.1       pk }
    431      1.1       pk 
    432      1.1       pk /*
    433      1.1       pk  * Various routines to interface to higher level audio driver
    434      1.1       pk  */
    435      1.1       pk struct ad1848_mixerinfo {
    436      1.1       pk 	int  left_reg;
    437      1.1       pk 	int  right_reg;
    438      1.1       pk 	int  atten_bits;
    439      1.1       pk 	int  atten_mask;
    440      1.1       pk } mixer_channel_info[] =
    441      1.1       pk {
    442      1.1       pk   { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
    443      1.1       pk     AUX_INPUT_ATTEN_MASK },
    444      1.1       pk   { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
    445      1.1       pk     AUX_INPUT_ATTEN_MASK },
    446      1.1       pk   { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
    447      1.1       pk     OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
    448      1.1       pk   { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
    449      1.1       pk     LINE_INPUT_ATTEN_MASK },
    450      1.1       pk   { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
    451      1.1       pk   { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
    452      1.1       pk };
    453      1.1       pk 
    454      1.1       pk /*
    455      1.1       pk  *  This function doesn't set the mute flags but does use them.
    456      1.1       pk  *  The mute flags reflect the mutes that have been applied by the user.
    457      1.1       pk  *  However, the driver occasionally wants to mute devices (e.g. when chaing
    458      1.1       pk  *  sampling rate). These operations should not affect the mute flags.
    459      1.1       pk  */
    460      1.1       pk 
    461      1.1       pk void
    462      1.1       pk ad1848_mute_channel(sc, device, mute)
    463      1.1       pk 	struct ad1848_softc *sc;
    464      1.1       pk 	int device;
    465      1.1       pk 	int mute;
    466      1.1       pk {
    467      1.1       pk 	u_char reg;
    468      1.1       pk 
    469      1.1       pk 	reg = ad_read(sc, mixer_channel_info[device].left_reg);
    470      1.1       pk 
    471      1.1       pk 	if (mute & MUTE_LEFT) {
    472      1.7    itohy 		if (device == AD1848_MONITOR_CHANNEL) {
    473      1.7    itohy 			if (sc->open_mode & FREAD)
    474      1.7    itohy 				ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
    475      1.1       pk 			ad_write(sc, mixer_channel_info[device].left_reg,
    476      1.7    itohy 				 reg & ~DIGITAL_MIX1_ENABLE);
    477      1.7    itohy 		} else
    478      1.1       pk 			ad_write(sc, mixer_channel_info[device].left_reg,
    479      1.1       pk 				 reg | 0x80);
    480      1.1       pk 	} else if (!(sc->mute[device] & MUTE_LEFT)) {
    481      1.7    itohy 		if (device == AD1848_MONITOR_CHANNEL) {
    482      1.1       pk 			ad_write(sc, mixer_channel_info[device].left_reg,
    483      1.7    itohy 				 reg | DIGITAL_MIX1_ENABLE);
    484      1.7    itohy 			if (sc->open_mode & FREAD)
    485      1.7    itohy 				ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
    486      1.7    itohy 		} else
    487      1.1       pk 			ad_write(sc, mixer_channel_info[device].left_reg,
    488      1.1       pk 				 reg & ~0x80);
    489      1.1       pk 	}
    490      1.1       pk 
    491      1.1       pk 	if (!mixer_channel_info[device].right_reg)
    492      1.1       pk 		return;
    493      1.1       pk 
    494      1.1       pk 	reg = ad_read(sc, mixer_channel_info[device].right_reg);
    495      1.1       pk 
    496      1.1       pk 	if (mute & MUTE_RIGHT) {
    497      1.1       pk 		ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
    498      1.1       pk 	} else if (!(sc->mute[device] & MUTE_RIGHT)) {
    499      1.1       pk 		ad_write(sc, mixer_channel_info[device].right_reg, reg &~0x80);
    500      1.1       pk 	}
    501      1.1       pk }
    502      1.1       pk 
    503      1.1       pk 
    504      1.1       pk int
    505      1.1       pk ad1848_set_channel_gain(sc, device, gp)
    506      1.1       pk 	struct ad1848_softc *sc;
    507      1.1       pk 	int device;
    508      1.1       pk 	struct ad1848_volume *gp;
    509      1.1       pk {
    510      1.1       pk 	struct ad1848_mixerinfo *info = &mixer_channel_info[device];
    511      1.1       pk 	u_char reg;
    512      1.1       pk 	u_int atten;
    513      1.1       pk 
    514      1.1       pk 	sc->gains[device] = *gp;
    515      1.1       pk 
    516      1.7    itohy 	atten = (AUDIO_MAX_GAIN - gp->left) * (info->atten_bits + 1) /
    517      1.7    itohy 		(AUDIO_MAX_GAIN + 1);
    518      1.1       pk 
    519      1.1       pk 	reg = ad_read(sc, info->left_reg) & (info->atten_mask);
    520      1.1       pk 	if (device == AD1848_MONITOR_CHANNEL)
    521      1.1       pk 		reg |= ((atten & info->atten_bits) << 2);
    522      1.1       pk 	else
    523      1.1       pk 		reg |= ((atten & info->atten_bits));
    524      1.1       pk 
    525      1.1       pk 	ad_write(sc, info->left_reg, reg);
    526      1.1       pk 
    527      1.1       pk 	if (!info->right_reg)
    528      1.1       pk 		return (0);
    529      1.1       pk 
    530      1.7    itohy 	atten = (AUDIO_MAX_GAIN - gp->right) * (info->atten_bits + 1) /
    531      1.7    itohy 		(AUDIO_MAX_GAIN + 1);
    532      1.1       pk 	reg = ad_read(sc, info->right_reg);
    533      1.1       pk 	reg &= info->atten_mask;
    534      1.1       pk 	ad_write(sc, info->right_reg, (atten & info->atten_bits) | reg);
    535      1.1       pk 
    536      1.1       pk 	return(0);
    537      1.1       pk }
    538      1.1       pk 
    539      1.1       pk 
    540      1.1       pk int
    541      1.1       pk ad1848_get_device_gain(sc, device, gp)
    542      1.1       pk 	struct ad1848_softc *sc;
    543      1.1       pk 	int device;
    544      1.1       pk 	struct ad1848_volume *gp;
    545      1.1       pk {
    546      1.1       pk 	*gp = sc->gains[device];
    547      1.1       pk 	return(0);
    548      1.1       pk }
    549      1.1       pk 
    550      1.1       pk int
    551      1.1       pk ad1848_get_rec_gain(sc, gp)
    552      1.1       pk 	struct ad1848_softc *sc;
    553      1.1       pk 	struct ad1848_volume *gp;
    554      1.1       pk {
    555      1.1       pk 	*gp = sc->rec_gain;
    556      1.1       pk 	return(0);
    557      1.1       pk }
    558      1.1       pk 
    559      1.1       pk int
    560      1.1       pk ad1848_set_rec_gain(sc, gp)
    561      1.1       pk 	struct ad1848_softc *sc;
    562      1.1       pk 	struct ad1848_volume *gp;
    563      1.1       pk {
    564      1.1       pk 	u_char reg, gain;
    565      1.1       pk 
    566      1.1       pk 	DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
    567      1.1       pk 
    568      1.1       pk 	sc->rec_gain = *gp;
    569      1.1       pk 
    570      1.7    itohy 	gain = (gp->left * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
    571      1.1       pk 	reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
    572      1.1       pk 	reg &= INPUT_GAIN_MASK;
    573      1.1       pk 	ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg);
    574      1.1       pk 
    575      1.7    itohy 	gain = (gp->right * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
    576      1.1       pk 	reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
    577      1.1       pk 	reg &= INPUT_GAIN_MASK;
    578      1.1       pk 	ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg);
    579      1.1       pk 
    580      1.1       pk 	return(0);
    581      1.1       pk }
    582      1.1       pk 
    583      1.1       pk 
    584      1.1       pk void
    585      1.7    itohy ad1848_mute_wave_output(sc, mute, set)
    586      1.7    itohy 	struct ad1848_softc *sc;
    587      1.7    itohy 	int mute, set;
    588      1.1       pk {
    589      1.7    itohy 	int m;
    590      1.7    itohy 
    591      1.7    itohy 	DPRINTF(("ad1848_mute_wave_output: %d, %d\n", mute, set));
    592      1.1       pk 
    593      1.7    itohy 	if (mute == WAVE_MUTE2_INIT) {
    594      1.7    itohy 		sc->wave_mute_status = 0;
    595      1.7    itohy 		mute = WAVE_MUTE2;
    596      1.1       pk 	}
    597      1.7    itohy 	if (set)
    598      1.7    itohy 		m = sc->wave_mute_status |= mute;
    599      1.7    itohy 	else
    600      1.7    itohy 		m = sc->wave_mute_status &= ~mute;
    601      1.1       pk 
    602      1.7    itohy 	if (m & WAVE_MUTE0 || ((m & WAVE_UNMUTE1) == 0 && m & WAVE_MUTE2))
    603      1.7    itohy 		ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, MUTE_ALL);
    604      1.7    itohy 	else
    605      1.7    itohy 		ad1848_mute_channel(sc, AD1848_DAC_CHANNEL,
    606      1.7    itohy 					    sc->mute[AD1848_DAC_CHANNEL]);
    607      1.1       pk }
    608      1.1       pk 
    609      1.1       pk int
    610      1.1       pk ad1848_set_mic_gain(sc, gp)
    611      1.1       pk 	struct ad1848_softc *sc;
    612      1.1       pk 	struct ad1848_volume *gp;
    613      1.1       pk {
    614      1.1       pk 	u_char reg;
    615      1.1       pk 
    616      1.1       pk 	DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
    617      1.1       pk 
    618      1.1       pk 	if (gp->left > AUDIO_MAX_GAIN/2) {
    619      1.1       pk 		sc->mic_gain_on = 1;
    620      1.1       pk 		reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
    621      1.1       pk 		ad_write(sc, SP_LEFT_INPUT_CONTROL,
    622      1.1       pk 			 reg | INPUT_MIC_GAIN_ENABLE);
    623      1.1       pk 	} else {
    624      1.1       pk 		sc->mic_gain_on = 0;
    625      1.1       pk 		reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
    626      1.1       pk 		ad_write(sc, SP_LEFT_INPUT_CONTROL,
    627      1.1       pk 			 reg & ~INPUT_MIC_GAIN_ENABLE);
    628      1.1       pk 	}
    629      1.1       pk 
    630      1.1       pk 	return(0);
    631      1.1       pk }
    632      1.1       pk 
    633      1.1       pk int
    634      1.1       pk ad1848_get_mic_gain(sc, gp)
    635      1.1       pk 	struct ad1848_softc *sc;
    636      1.1       pk 	struct ad1848_volume *gp;
    637      1.1       pk {
    638      1.1       pk 	if (sc->mic_gain_on)
    639      1.1       pk 		gp->left = gp->right = AUDIO_MAX_GAIN;
    640      1.1       pk 	else
    641      1.1       pk 		gp->left = gp->right = AUDIO_MIN_GAIN;
    642      1.1       pk 	return(0);
    643      1.1       pk }
    644      1.1       pk 
    645      1.1       pk 
    646      1.1       pk static ad1848_devmap_t *
    647      1.1       pk 	ad1848_mixer_find_dev __P((ad1848_devmap_t *, int, mixer_ctrl_t *));
    648      1.1       pk 
    649      1.1       pk static ad1848_devmap_t *
    650      1.1       pk ad1848_mixer_find_dev(map, cnt, cp)
    651      1.1       pk 	ad1848_devmap_t *map;
    652      1.1       pk 	int cnt;
    653      1.1       pk 	mixer_ctrl_t *cp;
    654      1.1       pk {
    655      1.1       pk 	int i;
    656      1.1       pk 
    657      1.1       pk 	for (i = 0; i < cnt; i++) {
    658      1.1       pk 		if (map[i].id == cp->dev) {
    659      1.1       pk 			return (&map[i]);
    660      1.1       pk 		}
    661      1.1       pk 	}
    662      1.1       pk 	return (0);
    663      1.1       pk }
    664      1.1       pk 
    665      1.1       pk int
    666      1.1       pk ad1848_mixer_get_port(ac, map, cnt, cp)
    667      1.1       pk 	struct ad1848_softc *ac;
    668      1.1       pk 	struct ad1848_devmap *map;
    669      1.1       pk 	int cnt;
    670      1.1       pk 	mixer_ctrl_t *cp;
    671      1.1       pk {
    672      1.1       pk 	ad1848_devmap_t *entry;
    673      1.1       pk 	struct ad1848_volume vol;
    674      1.1       pk 	int error = EINVAL;
    675      1.1       pk 	int dev;
    676      1.1       pk 
    677      1.1       pk 	if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
    678      1.1       pk 		return (ENXIO);
    679      1.1       pk 
    680      1.1       pk 	dev = entry->dev;
    681      1.1       pk 
    682      1.1       pk 	switch (entry->kind) {
    683      1.1       pk 	case AD1848_KIND_LVL:
    684      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE)
    685      1.1       pk 			break;
    686      1.1       pk 
    687      1.1       pk 		if (dev < AD1848_AUX2_CHANNEL ||
    688      1.1       pk 		    dev > AD1848_MONITOR_CHANNEL)
    689      1.1       pk 			break;
    690      1.1       pk 
    691      1.1       pk 		if (cp->un.value.num_channels != 1 &&
    692      1.1       pk 		    mixer_channel_info[dev].right_reg == 0)
    693      1.1       pk 			break;
    694      1.1       pk 
    695      1.1       pk 		error = ad1848_get_device_gain(ac, dev, &vol);
    696      1.1       pk 		if (!error)
    697      1.1       pk 			ad1848_from_vol(cp, &vol);
    698      1.1       pk 
    699      1.1       pk 		break;
    700      1.1       pk 
    701      1.1       pk 	case AD1848_KIND_MUTE:
    702      1.1       pk 		if (cp->type != AUDIO_MIXER_ENUM) break;
    703      1.1       pk 
    704      1.1       pk 		cp->un.ord = ac->mute[dev] ? 1 : 0;
    705      1.1       pk 		error = 0;
    706      1.1       pk 		break;
    707      1.1       pk 
    708      1.1       pk 	case AD1848_KIND_RECORDGAIN:
    709      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE) break;
    710      1.1       pk 
    711      1.1       pk 		error = ad1848_get_rec_gain(ac, &vol);
    712      1.1       pk 		if (!error)
    713      1.1       pk 			ad1848_from_vol(cp, &vol);
    714      1.1       pk 
    715      1.1       pk 		break;
    716      1.1       pk 
    717      1.1       pk 	case AD1848_KIND_MICGAIN:
    718      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE) break;
    719      1.1       pk 
    720      1.1       pk 		error = ad1848_get_mic_gain(ac, &vol);
    721      1.1       pk 		if (!error)
    722      1.1       pk 			ad1848_from_vol(cp, &vol);
    723      1.1       pk 
    724      1.1       pk 		break;
    725      1.1       pk 
    726      1.1       pk 	case AD1848_KIND_RECORDSOURCE:
    727      1.1       pk 		if (cp->type != AUDIO_MIXER_ENUM) break;
    728      1.1       pk 		cp->un.ord = ad1848_get_rec_port(ac);
    729      1.1       pk 		error = 0;
    730      1.1       pk 		break;
    731      1.1       pk 
    732      1.1       pk 	default:
    733      1.1       pk 		printf ("Invalid kind\n");
    734      1.1       pk 		break;
    735      1.1       pk 	}
    736      1.1       pk 
    737      1.1       pk 	return (error);
    738      1.1       pk }
    739      1.1       pk 
    740      1.1       pk int
    741      1.1       pk ad1848_mixer_set_port(ac, map, cnt, cp)
    742      1.1       pk 	struct ad1848_softc *ac;
    743      1.1       pk 	struct ad1848_devmap *map;
    744      1.1       pk 	int cnt;
    745      1.1       pk 	mixer_ctrl_t *cp;
    746      1.1       pk {
    747      1.1       pk 	ad1848_devmap_t *entry;
    748      1.1       pk 	struct ad1848_volume vol;
    749      1.1       pk 	int error = EINVAL;
    750      1.1       pk 	int dev;
    751      1.1       pk 
    752      1.1       pk 	if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
    753      1.1       pk 		return (ENXIO);
    754      1.1       pk 
    755      1.1       pk 	dev = entry->dev;
    756      1.1       pk 
    757      1.1       pk 	switch (entry->kind) {
    758      1.1       pk 	case AD1848_KIND_LVL:
    759      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE)
    760      1.1       pk 			break;
    761      1.1       pk 
    762      1.1       pk 		if (dev < AD1848_AUX2_CHANNEL ||
    763      1.1       pk 		    dev > AD1848_MONITOR_CHANNEL)
    764      1.1       pk 			break;
    765      1.1       pk 
    766      1.1       pk 		if (cp->un.value.num_channels != 1 &&
    767      1.1       pk 		    mixer_channel_info[dev].right_reg == 0)
    768      1.1       pk 			break;
    769      1.1       pk 
    770      1.1       pk 		ad1848_to_vol(cp, &vol);
    771      1.1       pk 		error = ad1848_set_channel_gain(ac, dev, &vol);
    772      1.1       pk 		break;
    773      1.1       pk 
    774      1.1       pk 	case AD1848_KIND_MUTE:
    775      1.1       pk 		if (cp->type != AUDIO_MIXER_ENUM) break;
    776      1.1       pk 
    777      1.1       pk 		ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
    778      1.1       pk 		ad1848_mute_channel(ac, dev, ac->mute[dev]);
    779      1.1       pk 		error = 0;
    780      1.1       pk 		break;
    781      1.1       pk 
    782      1.1       pk 	case AD1848_KIND_RECORDGAIN:
    783      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE) break;
    784      1.1       pk 
    785      1.1       pk 		ad1848_to_vol(cp, &vol);
    786      1.1       pk 		error = ad1848_set_rec_gain(ac, &vol);
    787      1.1       pk 		break;
    788      1.1       pk 
    789      1.1       pk 	case AD1848_KIND_MICGAIN:
    790      1.1       pk 		if (cp->type != AUDIO_MIXER_VALUE) break;
    791      1.1       pk 
    792      1.1       pk 		ad1848_to_vol(cp, &vol);
    793      1.1       pk 		error = ad1848_set_mic_gain(ac, &vol);
    794      1.1       pk 		break;
    795      1.1       pk 
    796      1.1       pk 	case AD1848_KIND_RECORDSOURCE:
    797      1.1       pk 		if (cp->type != AUDIO_MIXER_ENUM) break;
    798      1.1       pk 
    799      1.1       pk 		error = ad1848_set_rec_port(ac,  cp->un.ord);
    800      1.1       pk 		break;
    801      1.1       pk 
    802      1.1       pk 	default:
    803      1.1       pk 		printf ("Invalid kind\n");
    804      1.1       pk 		break;
    805      1.1       pk 	}
    806      1.1       pk 
    807      1.1       pk 	return (error);
    808      1.1       pk }
    809      1.1       pk 
    810      1.1       pk 
    811      1.1       pk int
    812      1.1       pk ad1848_query_encoding(addr, fp)
    813      1.1       pk 	void *addr;
    814      1.1       pk 	struct audio_encoding *fp;
    815      1.1       pk {
    816      1.1       pk 	struct ad1848_softc *sc = addr;
    817      1.1       pk 
    818      1.1       pk 	switch (fp->index) {
    819      1.1       pk 	case 0:
    820      1.1       pk 		strcpy(fp->name, AudioEmulaw);
    821      1.1       pk 		fp->encoding = AUDIO_ENCODING_ULAW;
    822      1.1       pk 		fp->precision = 8;
    823      1.1       pk 		fp->flags = 0;
    824      1.1       pk 		break;
    825      1.1       pk 	case 1:
    826      1.1       pk 		strcpy(fp->name, AudioEalaw);
    827      1.1       pk 		fp->encoding = AUDIO_ENCODING_ALAW;
    828      1.1       pk 		fp->precision = 8;
    829      1.1       pk 		fp->flags = 0;
    830      1.1       pk 		break;
    831      1.1       pk 	case 2:
    832      1.1       pk 		strcpy(fp->name, AudioEslinear_le);
    833      1.1       pk 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    834      1.1       pk 		fp->precision = 16;
    835      1.1       pk 		fp->flags = 0;
    836      1.1       pk 		break;
    837      1.1       pk 	case 3:
    838      1.1       pk 		strcpy(fp->name, AudioEulinear);
    839      1.1       pk 		fp->encoding = AUDIO_ENCODING_ULINEAR;
    840      1.1       pk 		fp->precision = 8;
    841      1.1       pk 		fp->flags = 0;
    842      1.1       pk 		break;
    843      1.1       pk 
    844      1.1       pk 	case 4: /* only on CS4231 */
    845      1.1       pk 		strcpy(fp->name, AudioEslinear_be);
    846      1.1       pk 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    847      1.1       pk 		fp->precision = 16;
    848      1.1       pk 		fp->flags = sc->mode == 1 ? AUDIO_ENCODINGFLAG_EMULATED : 0;
    849      1.1       pk 		break;
    850      1.1       pk 
    851      1.1       pk 		/* emulate some modes */
    852      1.1       pk 	case 5:
    853      1.1       pk 		strcpy(fp->name, AudioEslinear);
    854      1.1       pk 		fp->encoding = AUDIO_ENCODING_SLINEAR;
    855      1.1       pk 		fp->precision = 8;
    856      1.1       pk 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    857      1.1       pk 		break;
    858      1.1       pk 	case 6:
    859      1.1       pk 		strcpy(fp->name, AudioEulinear_le);
    860      1.1       pk 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
    861      1.1       pk 		fp->precision = 16;
    862      1.1       pk 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    863      1.1       pk 		break;
    864      1.1       pk 	case 7:
    865      1.1       pk 		strcpy(fp->name, AudioEulinear_be);
    866      1.1       pk 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
    867      1.1       pk 		fp->precision = 16;
    868      1.1       pk 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    869      1.1       pk 		break;
    870      1.1       pk 
    871      1.1       pk 	case 8: /* only on CS4231 */
    872      1.1       pk 		if (sc->mode == 1)
    873      1.1       pk 			return EINVAL;
    874      1.1       pk 		strcpy(fp->name, AudioEadpcm);
    875      1.1       pk 		fp->encoding = AUDIO_ENCODING_ADPCM;
    876      1.1       pk 		fp->precision = 8;
    877      1.1       pk 		fp->flags = 0;
    878      1.1       pk 		break;
    879      1.1       pk 	default:
    880      1.1       pk 		return EINVAL;
    881      1.1       pk 		/*NOTREACHED*/
    882      1.1       pk 	}
    883      1.1       pk 	return (0);
    884      1.1       pk }
    885      1.1       pk 
    886      1.1       pk int
    887      1.1       pk ad1848_set_params(addr, setmode, usemode, p, r)
    888      1.1       pk 	void *addr;
    889      1.1       pk 	int setmode, usemode;
    890      1.1       pk 	struct audio_params *p, *r;
    891      1.1       pk {
    892      1.1       pk 	struct ad1848_softc *sc = addr;
    893      1.1       pk 	int error, bits, enc;
    894      1.1       pk 	void (*pswcode) __P((void *, u_char *buf, int cnt));
    895      1.1       pk 	void (*rswcode) __P((void *, u_char *buf, int cnt));
    896      1.1       pk 
    897      1.1       pk 	DPRINTF(("ad1848_set_params: %d %d %d %ld\n",
    898      1.1       pk 		 p->encoding, p->precision, p->channels, p->sample_rate));
    899      1.1       pk 
    900      1.1       pk 	enc = p->encoding;
    901      1.1       pk 	pswcode = rswcode = 0;
    902      1.1       pk 	switch (enc) {
    903      1.1       pk 	case AUDIO_ENCODING_SLINEAR_LE:
    904      1.1       pk 		if (p->precision == 8) {
    905      1.1       pk 			enc = AUDIO_ENCODING_ULINEAR_LE;
    906      1.1       pk 			pswcode = rswcode = change_sign8;
    907      1.1       pk 		}
    908      1.1       pk 		break;
    909      1.1       pk 	case AUDIO_ENCODING_SLINEAR_BE:
    910      1.1       pk 		if (p->precision == 16 && sc->mode == 1) {
    911      1.1       pk 			enc = AUDIO_ENCODING_SLINEAR_LE;
    912      1.1       pk 			pswcode = rswcode = swap_bytes;
    913      1.1       pk 		}
    914      1.1       pk 		break;
    915      1.1       pk 	case AUDIO_ENCODING_ULINEAR_LE:
    916      1.1       pk 		if (p->precision == 16) {
    917      1.1       pk 			enc = AUDIO_ENCODING_SLINEAR_LE;
    918  1.8.2.1   bouyer 			pswcode = rswcode = change_sign16_le;
    919      1.1       pk 		}
    920      1.1       pk 		break;
    921      1.1       pk 	case AUDIO_ENCODING_ULINEAR_BE:
    922      1.1       pk 		if (p->precision == 16) {
    923      1.1       pk 			if (sc->mode == 1) {
    924      1.1       pk 				enc = AUDIO_ENCODING_SLINEAR_LE;
    925  1.8.2.1   bouyer 				pswcode = swap_bytes_change_sign16_le;
    926  1.8.2.1   bouyer 				rswcode = change_sign16_swap_bytes_le;
    927      1.1       pk 			} else {
    928      1.1       pk 				enc = AUDIO_ENCODING_SLINEAR_BE;
    929  1.8.2.1   bouyer 				pswcode = rswcode = change_sign16_be;
    930      1.1       pk 			}
    931      1.1       pk 		}
    932      1.1       pk 		break;
    933      1.1       pk 	}
    934      1.1       pk 	switch (enc) {
    935      1.1       pk 	case AUDIO_ENCODING_ULAW:
    936      1.1       pk 		bits = FMT_ULAW >> 5;
    937      1.1       pk 		break;
    938      1.1       pk 	case AUDIO_ENCODING_ALAW:
    939      1.1       pk 		bits = FMT_ALAW >> 5;
    940      1.1       pk 		break;
    941      1.1       pk 	case AUDIO_ENCODING_ADPCM:
    942      1.1       pk 		bits = FMT_ADPCM >> 5;
    943      1.1       pk 		break;
    944      1.1       pk 	case AUDIO_ENCODING_SLINEAR_LE:
    945      1.1       pk 		if (p->precision == 16)
    946      1.1       pk 			bits = FMT_TWOS_COMP >> 5;
    947      1.1       pk 		else
    948      1.1       pk 			return EINVAL;
    949      1.1       pk 		break;
    950      1.1       pk 	case AUDIO_ENCODING_SLINEAR_BE:
    951      1.1       pk 		if (p->precision == 16)
    952      1.1       pk 			bits = FMT_TWOS_COMP_BE >> 5;
    953      1.1       pk 		else
    954      1.1       pk 			return EINVAL;
    955      1.1       pk 		break;
    956      1.1       pk 	case AUDIO_ENCODING_ULINEAR_LE:
    957      1.1       pk 		if (p->precision == 8)
    958      1.1       pk 			bits = FMT_PCM8 >> 5;
    959      1.1       pk 		else
    960      1.1       pk 			return EINVAL;
    961      1.1       pk 		break;
    962      1.1       pk 	default:
    963      1.1       pk 		return EINVAL;
    964      1.1       pk 	}
    965      1.1       pk 
    966      1.1       pk 	if (p->channels < 1 || p->channels > 2)
    967      1.1       pk 		return EINVAL;
    968      1.1       pk 
    969      1.1       pk 	error = ad1848_set_speed(sc, &p->sample_rate);
    970      1.1       pk 	if (error)
    971      1.1       pk 		return error;
    972      1.1       pk 
    973      1.1       pk 	p->sw_code = pswcode;
    974      1.1       pk 	r->sw_code = rswcode;
    975      1.1       pk 
    976      1.1       pk 	sc->format_bits = bits;
    977      1.1       pk 	sc->channels = p->channels;
    978      1.1       pk 	sc->precision = p->precision;
    979      1.1       pk 	sc->need_commit = 1;
    980      1.1       pk 
    981      1.1       pk 	DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
    982      1.1       pk 	return (0);
    983      1.1       pk }
    984      1.1       pk 
    985      1.1       pk int
    986      1.1       pk ad1848_set_rec_port(sc, port)
    987      1.1       pk 	struct ad1848_softc *sc;
    988      1.1       pk 	int port;
    989      1.1       pk {
    990      1.1       pk 	u_char inp, reg;
    991      1.7    itohy 
    992      1.1       pk 	DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
    993      1.1       pk 
    994      1.1       pk 	if (port == MIC_IN_PORT)
    995      1.1       pk 		inp = MIC_INPUT;
    996      1.1       pk 	else if (port == LINE_IN_PORT)
    997      1.1       pk 		inp = LINE_INPUT;
    998      1.1       pk 	else if (port == DAC_IN_PORT)
    999      1.1       pk 		inp = MIXED_DAC_INPUT;
   1000      1.6       rh 	else if (sc->mode >= 2 && port == AUX1_IN_PORT)
   1001      1.1       pk 		inp = AUX_INPUT;
   1002      1.1       pk 	else
   1003      1.1       pk 		return(EINVAL);
   1004      1.1       pk 
   1005      1.1       pk 	reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
   1006      1.1       pk 	reg &= INPUT_SOURCE_MASK;
   1007      1.1       pk 	ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg));
   1008      1.1       pk 
   1009      1.1       pk 	reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
   1010      1.1       pk 	reg &= INPUT_SOURCE_MASK;
   1011      1.1       pk 	ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg));
   1012      1.1       pk 
   1013      1.1       pk 	sc->rec_port = port;
   1014      1.1       pk 
   1015      1.1       pk 	return (0);
   1016      1.1       pk }
   1017      1.1       pk 
   1018      1.1       pk int
   1019      1.1       pk ad1848_get_rec_port(sc)
   1020      1.1       pk 	struct ad1848_softc *sc;
   1021      1.1       pk {
   1022      1.1       pk 	return (sc->rec_port);
   1023      1.1       pk }
   1024      1.1       pk 
   1025      1.1       pk int
   1026      1.1       pk ad1848_round_blocksize(addr, blk)
   1027      1.1       pk 	void *addr;
   1028      1.1       pk 	int blk;
   1029      1.1       pk {
   1030      1.1       pk 
   1031      1.1       pk 	/* Round to a multiple of the biggest sample size. */
   1032      1.1       pk 	return (blk &= -4);
   1033      1.1       pk }
   1034      1.1       pk 
   1035      1.1       pk int
   1036      1.1       pk ad1848_open(addr, flags)
   1037      1.1       pk 	void *addr;
   1038      1.1       pk 	int flags;
   1039      1.1       pk {
   1040      1.1       pk 	struct ad1848_softc *sc = addr;
   1041      1.5  mycroft 	u_char reg;
   1042      1.1       pk 
   1043      1.1       pk 	DPRINTF(("ad1848_open: sc=%p\n", sc));
   1044      1.1       pk 
   1045      1.7    itohy 	sc->open_mode = flags;
   1046      1.7    itohy 
   1047      1.1       pk 	/* Enable interrupts */
   1048      1.1       pk 	DPRINTF(("ad1848_open: enable intrs\n"));
   1049      1.5  mycroft 	reg = ad_read(sc, SP_PIN_CONTROL);
   1050      1.5  mycroft 	ad_write(sc, SP_PIN_CONTROL, reg | INTERRUPT_ENABLE);
   1051      1.1       pk 
   1052      1.7    itohy 	/* If recording && monitoring, the playback part is also used. */
   1053      1.7    itohy 	if (flags & FREAD && sc->mute[AD1848_MONITOR_CHANNEL] == 0)
   1054      1.7    itohy 		ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
   1055      1.7    itohy 
   1056      1.1       pk #ifdef AUDIO_DEBUG
   1057      1.1       pk 	if (ad1848debug)
   1058      1.1       pk 		ad1848_dump_regs(sc);
   1059      1.1       pk #endif
   1060      1.1       pk 
   1061      1.1       pk 	return 0;
   1062      1.1       pk }
   1063      1.1       pk 
   1064      1.1       pk /*
   1065      1.1       pk  * Close function is called at splaudio().
   1066      1.1       pk  */
   1067      1.1       pk void
   1068      1.1       pk ad1848_close(addr)
   1069      1.1       pk 	void *addr;
   1070      1.1       pk {
   1071      1.1       pk 	struct ad1848_softc *sc = addr;
   1072      1.5  mycroft 	u_char reg;
   1073      1.1       pk 
   1074      1.7    itohy 	sc->open_mode = 0;
   1075      1.7    itohy 
   1076      1.7    itohy 	ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
   1077      1.7    itohy 
   1078      1.1       pk 	/* Disable interrupts */
   1079      1.1       pk 	DPRINTF(("ad1848_close: disable intrs\n"));
   1080      1.5  mycroft 	reg = ad_read(sc, SP_PIN_CONTROL);
   1081      1.5  mycroft 	ad_write(sc, SP_PIN_CONTROL, reg & ~INTERRUPT_ENABLE);
   1082      1.1       pk 
   1083      1.1       pk #ifdef AUDIO_DEBUG
   1084      1.1       pk 	if (ad1848debug)
   1085      1.1       pk 		ad1848_dump_regs(sc);
   1086      1.1       pk #endif
   1087      1.1       pk }
   1088      1.1       pk 
   1089      1.1       pk /*
   1090      1.1       pk  * Lower-level routines
   1091      1.1       pk  */
   1092      1.1       pk int
   1093      1.1       pk ad1848_commit_settings(addr)
   1094      1.1       pk 	void *addr;
   1095      1.1       pk {
   1096      1.1       pk 	struct ad1848_softc *sc = addr;
   1097      1.1       pk 	int timeout;
   1098      1.1       pk 	u_char fs;
   1099      1.1       pk 	int s;
   1100      1.1       pk 
   1101      1.1       pk 	if (!sc->need_commit)
   1102      1.1       pk 		return 0;
   1103      1.1       pk 
   1104      1.1       pk 	s = splaudio();
   1105      1.1       pk 
   1106      1.7    itohy 	ad1848_mute_wave_output(sc, WAVE_MUTE0, 1);
   1107      1.1       pk 
   1108      1.1       pk 	ad_set_MCE(sc, 1);	/* Enables changes to the format select reg */
   1109      1.1       pk 
   1110      1.1       pk 	fs = sc->speed_bits | (sc->format_bits << 5);
   1111      1.1       pk 
   1112      1.1       pk 	if (sc->channels == 2)
   1113      1.1       pk 		fs |= FMT_STEREO;
   1114      1.1       pk 
   1115      1.1       pk 	ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
   1116      1.1       pk 
   1117      1.1       pk 	/*
   1118      1.6       rh 	 * If mode >= 2 (CS4231), set I28 also.
   1119      1.1       pk 	 * It's the capture format register.
   1120      1.1       pk 	 */
   1121      1.6       rh 	if (sc->mode >= 2) {
   1122      1.1       pk 		/*
   1123      1.1       pk 		 * Gravis Ultrasound MAX SDK sources says something about
   1124      1.1       pk 		 * errata sheets, with the implication that these inb()s
   1125      1.1       pk 		 * are necessary.
   1126      1.1       pk 		 */
   1127      1.1       pk 		(void)ADREAD(sc, AD1848_IDATA);
   1128      1.1       pk 		(void)ADREAD(sc, AD1848_IDATA);
   1129      1.1       pk 		/* Write to I8 starts resyncronization. Wait for completion. */
   1130      1.1       pk 		timeout = 100000;
   1131      1.1       pk 		while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
   1132      1.1       pk 			timeout--;
   1133      1.1       pk 
   1134      1.1       pk 		ad_write(sc, CS_REC_FORMAT, fs);
   1135      1.1       pk 		(void)ADREAD(sc, AD1848_IDATA);
   1136      1.1       pk 		(void)ADREAD(sc, AD1848_IDATA);
   1137      1.1       pk 		/* Now wait for resync for capture side of the house */
   1138      1.1       pk 	}
   1139      1.1       pk 	/*
   1140      1.1       pk 	 * Write to I8 starts resyncronization. Wait until it completes.
   1141      1.1       pk 	 */
   1142      1.1       pk 	timeout = 100000;
   1143      1.8  thorpej 	while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) {
   1144      1.8  thorpej 		delay(10);
   1145      1.1       pk 		timeout--;
   1146      1.8  thorpej 	}
   1147      1.1       pk 
   1148      1.1       pk 	if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
   1149      1.1       pk 		printf("ad1848_commit: Auto calibration timed out\n");
   1150      1.1       pk 
   1151      1.1       pk 	/*
   1152      1.1       pk 	 * Starts the calibration process and
   1153      1.1       pk 	 * enters playback mode after it.
   1154      1.1       pk 	 */
   1155      1.1       pk 	ad_set_MCE(sc, 0);
   1156      1.1       pk 	wait_for_calibration(sc);
   1157      1.1       pk 
   1158      1.7    itohy 	ad1848_mute_wave_output(sc, WAVE_MUTE0, 0);
   1159      1.1       pk 
   1160      1.1       pk 	splx(s);
   1161      1.1       pk 
   1162      1.1       pk 	sc->need_commit = 0;
   1163      1.1       pk 	return 0;
   1164      1.1       pk }
   1165      1.1       pk 
   1166      1.1       pk void
   1167      1.1       pk ad1848_reset(sc)
   1168      1.1       pk 	struct ad1848_softc *sc;
   1169      1.1       pk {
   1170      1.1       pk 	u_char r;
   1171      1.1       pk 
   1172      1.1       pk 	DPRINTF(("ad1848_reset\n"));
   1173      1.1       pk 
   1174      1.1       pk 	/* Clear the PEN and CEN bits */
   1175      1.1       pk 	r = ad_read(sc, SP_INTERFACE_CONFIG);
   1176      1.1       pk 	r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
   1177      1.1       pk 	ad_write(sc, SP_INTERFACE_CONFIG, r);
   1178      1.1       pk 
   1179      1.6       rh 	if (sc->mode >= 2) {
   1180      1.1       pk 		ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
   1181      1.1       pk 		ADWRITE(sc, AD1848_IDATA, 0);
   1182      1.1       pk 	}
   1183      1.1       pk 	/* Clear interrupt status */
   1184      1.1       pk 	ADWRITE(sc, AD1848_STATUS, 0);
   1185      1.1       pk #ifdef AUDIO_DEBUG
   1186      1.1       pk 	if (ad1848debug)
   1187      1.1       pk 		ad1848_dump_regs(sc);
   1188      1.1       pk #endif
   1189      1.1       pk }
   1190      1.1       pk 
   1191      1.1       pk int
   1192      1.1       pk ad1848_set_speed(sc, argp)
   1193      1.1       pk 	struct ad1848_softc *sc;
   1194      1.1       pk 	u_long *argp;
   1195      1.1       pk {
   1196      1.1       pk 	/*
   1197      1.1       pk 	 * The sampling speed is encoded in the least significant nible of I8.
   1198      1.1       pk 	 * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 Mhz) and
   1199      1.1       pk 	 * other three bits select the divisor (indirectly):
   1200      1.1       pk 	 *
   1201      1.1       pk 	 * The available speeds are in the following table. Keep the speeds in
   1202      1.1       pk 	 * the increasing order.
   1203      1.1       pk 	 */
   1204      1.1       pk 	typedef struct {
   1205      1.1       pk 		int	speed;
   1206      1.1       pk 		u_char	bits;
   1207      1.1       pk 	} speed_struct;
   1208      1.1       pk 	u_long arg = *argp;
   1209      1.1       pk 
   1210      1.1       pk 	static speed_struct speed_table[] =  {
   1211      1.1       pk 		{5510, (0 << 1) | 1},
   1212      1.1       pk 		{5510, (0 << 1) | 1},
   1213      1.1       pk 		{6620, (7 << 1) | 1},
   1214      1.1       pk 		{8000, (0 << 1) | 0},
   1215      1.1       pk 		{9600, (7 << 1) | 0},
   1216      1.1       pk 		{11025, (1 << 1) | 1},
   1217      1.1       pk 		{16000, (1 << 1) | 0},
   1218      1.1       pk 		{18900, (2 << 1) | 1},
   1219      1.1       pk 		{22050, (3 << 1) | 1},
   1220      1.1       pk 		{27420, (2 << 1) | 0},
   1221      1.1       pk 		{32000, (3 << 1) | 0},
   1222      1.1       pk 		{33075, (6 << 1) | 1},
   1223      1.1       pk 		{37800, (4 << 1) | 1},
   1224      1.1       pk 		{44100, (5 << 1) | 1},
   1225      1.1       pk 		{48000, (6 << 1) | 0}
   1226      1.1       pk 	};
   1227      1.1       pk 
   1228      1.1       pk 	int i, n, selected = -1;
   1229      1.1       pk 
   1230      1.1       pk 	n = sizeof(speed_table) / sizeof(speed_struct);
   1231      1.1       pk 
   1232      1.1       pk 	if (arg < speed_table[0].speed)
   1233      1.1       pk 		selected = 0;
   1234      1.1       pk 	if (arg > speed_table[n - 1].speed)
   1235      1.1       pk 		selected = n - 1;
   1236      1.1       pk 
   1237      1.1       pk 	for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
   1238      1.1       pk 		if (speed_table[i].speed == arg)
   1239      1.1       pk 			selected = i;
   1240      1.1       pk 		else if (speed_table[i].speed > arg) {
   1241      1.1       pk 			int diff1, diff2;
   1242      1.1       pk 
   1243      1.1       pk 			diff1 = arg - speed_table[i - 1].speed;
   1244      1.1       pk 			diff2 = speed_table[i].speed - arg;
   1245      1.1       pk 
   1246      1.1       pk 			if (diff1 < diff2)
   1247      1.1       pk 				selected = i - 1;
   1248      1.1       pk 			else
   1249      1.1       pk 				selected = i;
   1250      1.1       pk 		}
   1251      1.1       pk 
   1252      1.1       pk 	if (selected == -1) {
   1253      1.1       pk 		printf("ad1848: Can't find speed???\n");
   1254      1.1       pk 		selected = 3;
   1255      1.1       pk 	}
   1256      1.1       pk 
   1257      1.1       pk 	sc->speed_bits = speed_table[selected].bits;
   1258      1.1       pk 	sc->need_commit = 1;
   1259      1.1       pk 	*argp = speed_table[selected].speed;
   1260      1.1       pk 
   1261      1.1       pk 	return (0);
   1262      1.1       pk }
   1263      1.1       pk 
   1264      1.1       pk /*
   1265      1.1       pk  * Halt I/O
   1266      1.1       pk  */
   1267      1.1       pk int
   1268      1.5  mycroft ad1848_halt_output(addr)
   1269      1.1       pk 	void *addr;
   1270      1.1       pk {
   1271      1.1       pk 	struct ad1848_softc *sc = addr;
   1272      1.1       pk 	u_char reg;
   1273      1.1       pk 
   1274      1.5  mycroft 	DPRINTF(("ad1848: ad1848_halt_output\n"));
   1275      1.1       pk 
   1276      1.1       pk 	reg = ad_read(sc, SP_INTERFACE_CONFIG);
   1277      1.5  mycroft 	ad_write(sc, SP_INTERFACE_CONFIG, reg & ~PLAYBACK_ENABLE);
   1278      1.1       pk 
   1279      1.1       pk 	return(0);
   1280      1.1       pk }
   1281      1.1       pk 
   1282      1.1       pk int
   1283      1.5  mycroft ad1848_halt_input(addr)
   1284      1.1       pk 	void *addr;
   1285      1.1       pk {
   1286      1.1       pk 	struct ad1848_softc *sc = addr;
   1287      1.1       pk 	u_char reg;
   1288      1.1       pk 
   1289      1.5  mycroft 	DPRINTF(("ad1848: ad1848_halt_input\n"));
   1290      1.1       pk 
   1291      1.1       pk 	reg = ad_read(sc, SP_INTERFACE_CONFIG);
   1292      1.5  mycroft 	ad_write(sc, SP_INTERFACE_CONFIG, reg & ~CAPTURE_ENABLE);
   1293      1.1       pk 
   1294      1.1       pk 	return(0);
   1295      1.1       pk }
   1296