⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsd_audio.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1991, 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: *	This product includes software developed by the University of *	California, Lawrence Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)bsd_audio.c	8.1 (Berkeley) 6/11/93 * * from: $Header: bsd_audio.c,v 1.18 93/04/24 16:20:35 leres Exp $ (LBL) */#include "bsdaudio.h"#if NBSDAUDIO > 0#include <sys/param.h>#include <sys/systm.h>#if BSD < 199103#ifndef SUNOS#define SUNOS#endif#endif#include <sys/errno.h>#include <sys/file.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/vnode.h>#include <sys/ioctl.h>#include <sys/time.h>#ifndef SUNOS#include <sys/tty.h>#endif#include <sys/uio.h>#ifdef SUNOS#include <sundev/mbvar.h>#include <sun4c/intreg.h>#else#include <sys/device.h>#include <machine/autoconf.h>#endif#include <machine/cpu.h>/* * Avoid name clashes with SunOS so we can config either the bsd or sun * streams driver in a SunOS kernel. */#ifdef SUNOS#include <sbusdev/bsd_audioreg.h>#include <sbusdev/bsd_audiovar.h>#include <sbusdev/bsd_audioio.h>struct selinfo {	struct proc *si_proc;	int si_coll;};#else#include <sparc/dev/bsd_audioreg.h>#include <sparc/dev/bsd_audiovar.h>#include <machine/bsd_audioio.h>#endif#ifdef SUNOS#include "bsd_audiocompat.h"#endif/* * Initial/default block size is patchable. */int audio_blocksize = DEFBLKSIZE;int audio_backlog = 400;		/* 50ms in samples *//* * Software state, per AMD79C30 audio chip. */struct audio_softc {#ifndef SUNOS	struct	device sc_dev;		/* base device */	struct	intrhand sc_hwih;	/* hardware interrupt vector */	struct	intrhand sc_swih;	/* software interrupt vector */#endif	int	sc_interrupts;		/* number of interrupts taken */	int	sc_open;		/* single use device */	u_long	sc_wseek;		/* timestamp of last frame written */	u_long	sc_rseek;		/* timestamp of last frame read */	struct	mapreg sc_map;		/* current contents of map registers */	struct	selinfo sc_wsel;	/* write selector */	struct	selinfo sc_rsel;	/* read selector */	/*	 * keep track of levels so we don't have to convert back from	 * MAP gain constants	 */	int	sc_rlevel;		/* record level */	int	sc_plevel;		/* play level */	int	sc_mlevel;		/* monitor level */	/* sc_au is special in that the hardware interrupt handler uses it */	struct	auio sc_au;		/* recv and xmit buffers, etc */};/* interrupt interfaces */#ifndef AUDIO_C_HANDLERint	audiohwintr __P((void *));#endifint	audioswintr __P((void *));/* forward declarations */int	audio_sleep __P((struct aucb *, int));void	audio_setmap __P((volatile struct amd7930 *, struct mapreg *));static void init_amd();#if !defined(AUDIO_C_HANDLER) || defined(SUNOS)struct auio *audio_au;extern void audio_trap();#endif#ifdef SUNOSstruct audio_softc audio_softc;#define SOFTC(dev) &audio_softc#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)#define AUDIOOPEN(d, f, i, p)\	audioopen(d, f, i)\	dev_t d; int f, i;#define AUDIOCLOSE(d, f, i, p)\	audioclose(d, f, i)\	dev_t d; int f, i;#define AUDIOREAD(d, u, f) \	audioread(d, u) dev_t d; struct uio *u;#define AUDIOWRITE(d, u, f) \	audiowrite(d, u) dev_t d; struct uio *u;#define AUDIOIOCTL(d, c, a, f, o)\	audioioctl(d, c, a, f)\	dev_t d; int c; caddr_t a; int f;#define AUDIOSELECT(d, r, p)\	audio_select(d, r, p)\	dev_t d; int r; struct proc *p;#define AUDIO_SET_SWINTR set_intreg(IR_SOFT_INT4, 1)intaudioselect(dev, rw)	register dev_t dev;	int rw;{	return (audio_select(dev, rw, u.u_procp));}static voidselrecord(p, si)	struct proc *p;	struct selinfo *si;{	if (si->si_proc != 0)		si->si_coll = 1;	else		si->si_proc = p;}#define SELWAKEUP(si) \{\	 if ((si)->si_proc != 0) {\		selwakeup((si)->si_proc, (si)->si_coll); \		(si)->si_proc = 0;\		(si)->si_coll = 0;\	}\}static int audioattach();static int audioidentify();struct dev_ops bsdaudio_ops = {	0,	audioidentify,	audioattach,};static intaudioidentify(cp)	char *cp;{	return (strcmp(cp, "audio") == 0);}static intaudioattach(dev)	struct dev_info *dev;{	register struct audio_softc *sc;	register volatile struct amd7930 *amd;	struct dev_reg *reg;	sc = &audio_softc;	if (dev->devi_nreg != 1 || dev->devi_nintr != 1) {		printf("audio: bad config\n");                return (-1);        }	reg = dev->devi_reg;	amd = (struct amd7930 *)map_regs(reg->reg_addr, reg->reg_size,					 reg->reg_bustype);	sc->sc_au.au_amd = amd;	init_amd(amd);	audio_au = &sc->sc_au;#ifndef AUDIO_C_HANDLER	settrap(dev->devi_intr->int_pri, audio_trap);#else	/* XXX */	addintr(dev->devi_intr->int_pri, audiohwintr, dev->devi_name,		dev->devi_unit);#endif	addintr(4, audioswintr, dev->devi_name, dev->devi_unit);	report_dev(dev);	return (0);}#else#define AUDIOOPEN(d, f, i, p) audioopen(dev_t d, int f, int i, struct proc *p)#define AUDIOCLOSE(d, f, i, p) audioclose(dev_t d, int f, int i, \					  struct proc *p)#define AUDIOREAD(d, u, f) audioread(dev_t d, struct uio *u, int f)#define AUDIOWRITE(d, u, f) audiowrite(dev_t d, struct uio *u, int f)#define AUDIOIOCTL(d, c, a, f, o)\	audioioctl(dev_t dev, int c, caddr_t a, int f, struct proc *p)#define AUDIOSELECT(d, r, p) audioselect(dev_t dev, int rw, struct proc *p)#define SELWAKEUP selwakeup#define AUDIO_SET_SWINTR ienab_bis(IE_L6)/* autoconfiguration driver */void	audioattach(struct device *, struct device *, void *);struct	cfdriver audiocd =    { NULL, "audio", matchbyname, audioattach,      DV_DULL, sizeof(struct audio_softc) };#define SOFTC(dev) audiocd.cd_devs[minor(dev)]#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)/* * Audio chip found. */voidaudioattach(parent, self, args)	struct device *parent, *self;	void *args;{	register struct audio_softc *sc = (struct audio_softc *)self;	register struct romaux *ra = args;	register volatile struct amd7930 *amd;	register int pri;	if (ra->ra_nintr != 1) {		printf(": expected 1 interrupt, got %d\n", ra->ra_nintr);		return;	}	pri = ra->ra_intr[0].int_pri;	printf(" pri %d, softpri %d\n", pri, PIL_AUSOFT);	amd = (volatile struct amd7930 *)(ra->ra_vaddr ?	    ra->ra_vaddr : mapiodev(ra->ra_paddr, sizeof *amd));	sc->sc_au.au_amd = amd;	init_amd(amd);#ifndef AUDIO_C_HANDLER	audio_au = &sc->sc_au;	intr_fasttrap(pri, audio_trap);#else	sc->sc_hwih.ih_fun = audiohwintr;	sc->sc_hwih.ih_arg = &sc->sc_au;	intr_establish(pri, &sc->sc_hwih);#endif	sc->sc_swih.ih_fun = audioswintr;	sc->sc_swih.ih_arg = sc;	intr_establish(PIL_AUSOFT, &sc->sc_swih);}#endifstatic voidinit_amd(amd)	register volatile struct amd7930 *amd;{	/* disable interrupts */	amd->cr = AMDR_INIT;	amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;	/*	 * Initialize the mux unit.  We use MCR3 to route audio (MAP)	 * through channel Bb.  MCR1 and MCR2 are unused.	 * Setting the INT enable bit in MCR4 will generate an interrupt	 * on each converted audio sample.	 */	amd->cr = AMDR_MUX_1_4; 	amd->dr = 0;	amd->dr = 0;	amd->dr = (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA;	amd->dr = AMD_MCR4_INT_ENABLE;}static int audio_default_level = 150;static void ausetrgain __P((struct audio_softc *, int));static void ausetpgain __P((struct audio_softc *, int));static void ausetmgain __P((struct audio_softc *, int));static int audiosetinfo __P((struct audio_softc *, struct audio_info *));static int audiogetinfo __P((struct audio_softc *, struct audio_info *));struct sun_audio_info;static int sunaudiosetinfo __P((struct audio_softc *,				struct sun_audio_info *));static int sunaudiogetinfo __P((struct audio_softc *,				struct sun_audio_info *));static void audio_setmmr2 __P((volatile struct amd7930 *, int));/* ARGSUSED */intAUDIOOPEN(dev, flags, ifmt, p){	register struct audio_softc *sc;	register volatile struct amd7930 *amd;	int unit = minor(dev);#ifdef SUNOS	if (unit > 0)		return (ENXIO);	sc = &audio_softc;#else	if (unit >= audiocd.cd_ndevs || (sc = audiocd.cd_devs[unit]) == NULL)		return (ENXIO);#endif	if (sc->sc_open)		return (EBUSY);	sc->sc_open = 1;	sc->sc_au.au_lowat = audio_blocksize;	sc->sc_au.au_hiwat = AUCB_SIZE - sc->sc_au.au_lowat;	sc->sc_au.au_blksize = audio_blocksize;	sc->sc_au.au_backlog = audio_backlog;	/* set up read and write blocks and `dead sound' zero value. */	AUCB_INIT(&sc->sc_au.au_rb);	sc->sc_au.au_rb.cb_thresh = AUCB_SIZE;	AUCB_INIT(&sc->sc_au.au_wb);	sc->sc_au.au_wb.cb_thresh = -1;	/* nothing read or written yet */	sc->sc_rseek = 0;	sc->sc_wseek = 0;	bzero((char *)&sc->sc_map, sizeof sc->sc_map);	/* default to speaker */	sc->sc_map.mr_mmr2 = AMD_MMR2_AINB | AMD_MMR2_LS;		/* enable interrupts and set parameters established above */	amd = sc->sc_au.au_amd;	audio_setmmr2(amd, sc->sc_map.mr_mmr2);	ausetrgain(sc, audio_default_level);	ausetpgain(sc, audio_default_level);	ausetmgain(sc, 0);	amd->cr = AMDR_INIT;	amd->dr = AMD_INIT_PMS_ACTIVE;	return (0);}static intaudio_drain(sc)	register struct audio_softc *sc;{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -