NetBSD/sys/dev/audio/audiovar.h
isaki c8e35e0151 Fix suspend/resume.
- Revert temporary usage of sc_[pr]busy during suspend.  These indicate
  whether the mixer needs to be restarted or not.
- Avoid timeout error when about to suspend.
2020-05-29 03:09:14 +00:00

340 lines
10 KiB
C

/* $NetBSD: audiovar.h,v 1.12 2020/05/29 03:09:14 isaki Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by TAMURA Kent
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1991-1993 Regents of the University of California.
* All rights reserved.
*
* 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 Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory 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.
*
* From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL)
*/
#ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_
#define _SYS_DEV_AUDIO_AUDIOVAR_H_
#include <sys/condvar.h>
#include <sys/proc.h>
#include <sys/pserialize.h>
#include <sys/psref.h>
#include <sys/queue.h>
#include <dev/audio/audio_if.h>
#include <dev/audio/audiofil.h>
/*
* Whether supports [US]LINEAR24/24 as userland format.
*/
/* #define AUDIO_SUPPORT_LINEAR24 */
/*
* Frequency range.
* For lower limit, there are some antique machines who supports under
* 4000Hz, so that we accept 1000Hz as lower limit, regardless of
* practicality(?).
* For upper limit, there are some devices who supports 384000Hz, but
* I don't have them. :-)
*/
#define AUDIO_MIN_FREQUENCY (1000)
#define AUDIO_MAX_FREQUENCY (192000)
typedef struct audio_file audio_file_t;
typedef struct audio_trackmixer audio_trackmixer_t;
/* ring buffer */
typedef struct {
audio_format2_t fmt; /* format */
int capacity; /* capacity by frame */
int head; /* head position in frame */
int used; /* used frame count */
void *mem; /* sample ptr */
} audio_ring_t;
#define AUDIO_N_PORTS 4
struct au_mixer_ports {
int index; /* index of port-selector mixerctl */
int master; /* index of master mixerctl */
int nports; /* number of selectable ports */
bool isenum; /* selector is enum type */
u_int allports; /* all aumasks or'd */
u_int aumask[AUDIO_N_PORTS]; /* exposed value of "ports" */
int misel [AUDIO_N_PORTS]; /* ord of port, for selector */
int miport[AUDIO_N_PORTS]; /* index of port's mixerctl */
bool isdual; /* has working mixerout */
int mixerout; /* ord of mixerout, for dual case */
int cur_port; /* the port that gain actually controls when
mixerout is selected, for dual case */
};
struct audio_softc {
/* Myself (e.g.; audio0, audio1, ...) */
device_t sc_dev;
/* Hardware device struct (e.g.; sb0, hdafg0, ...) */
device_t hw_dev;
/*
* Hardware interface and driver handle.
* hw_if == NULL means that the device is (attached but) disabled.
*/
const struct audio_hw_if *hw_if;
void *hw_hdl;
/*
* Properties obtained by get_props().
* No need any locks to read this variable.
*/
int sc_props;
/*
* List of opened descriptors.
* Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH).
* Must be protected by sc_lock && sc_intr_lock for insertion/removal.
*/
SLIST_HEAD(, audio_file) sc_files;
/*
* Blocksize in msec.
* Must be protected by sc_exlock.
*/
int sc_blk_ms;
/*
* Track mixer for playback and recording.
* If null, the mixer is disabled.
* Must be protected by sc_exlock.
*/
audio_trackmixer_t *sc_pmixer;
audio_trackmixer_t *sc_rmixer;
/*
* Opening track counter.
* Must be protected by sc_lock && sc_exlock for modifying.
* Must be protected by sc_lock || sc_exlock for reference.
*/
int sc_popens;
int sc_ropens;
/*
* true if the track mixer is running.
* Must be protected by sc_exlock && sc_intr_lock for modifying.
* Must be protected by sc_exlock || sc_intr_lock for reference.
*/
bool sc_pbusy;
bool sc_rbusy;
/*
* These four are the parameters sustained with /dev/sound.
* Must be protected by sc_exlock.
*/
audio_format2_t sc_sound_pparams;
audio_format2_t sc_sound_rparams;
bool sc_sound_ppause;
bool sc_sound_rpause;
/* recent info for /dev/sound */
/* XXX TODO */
struct audio_info sc_ai;
/*
* Playback(write)/Recording(read) selector.
* Must be protected by sc_lock.
*/
struct selinfo sc_wsel;
struct selinfo sc_rsel;
/*
* Processes who want mixer SIGIO.
* sc_am is an array of pids, or NULL if empty.
* sc_am_capacity is the number of allocated elements.
* sc_am_used is the number of elements actually used.
* Must be protected by sc_exlock.
*/
pid_t *sc_am;
int sc_am_capacity;
int sc_am_used;
/*
* Thread lock and interrupt lock obtained by get_locks().
*/
kmutex_t *sc_lock;
kmutex_t *sc_intr_lock;
/*
* Critical section.
* Must be protected by sc_lock.
*/
int sc_exlock;
kcondvar_t sc_exlockcv;
/*
* Passive reference to prevent a race between detach and fileops.
* pserialize_perform(sc_psz) must be protected by sc_lock.
*/
pserialize_t sc_psz;
struct psref_target sc_psref;
/*
* Must be protected by sc_lock (?)
*/
bool sc_dying;
/*
* Indicates that about to suspend.
* Must be protected by sc_lock.
*/
bool sc_suspending;
/*
* If multiuser is false, other users who have different euid
* than the first user cannot open this device.
* Must be protected by sc_exlock.
*/
bool sc_multiuser;
kauth_cred_t sc_cred;
struct sysctllog *sc_log;
mixer_ctrl_t *sc_mixer_state;
int sc_nmixer_states;
struct au_mixer_ports sc_inports;
struct au_mixer_ports sc_outports;
int sc_monitor_port;
u_int sc_lastgain;
};
#ifdef DIAGNOSTIC
#define DIAGNOSTIC_filter_arg(arg) audio_diagnostic_filter_arg(__func__, (arg))
#define DIAGNOSTIC_format2(fmt) audio_diagnostic_format2(__func__, (fmt))
extern void audio_diagnostic_filter_arg(const char *,
const audio_filter_arg_t *);
extern void audio_diagnostic_format2(const char *, const audio_format2_t *);
#else
#define DIAGNOSTIC_filter_arg(arg)
#define DIAGNOSTIC_format2(fmt)
#endif
/*
* Return true if 'fmt' is the internal format.
* It does not check for frequency and number of channels.
*/
static __inline bool
audio_format2_is_internal(const audio_format2_t *fmt)
{
if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE)
return false;
if (fmt->precision != AUDIO_INTERNAL_BITS)
return false;
if (fmt->stride != AUDIO_INTERNAL_BITS)
return false;
return true;
}
/*
* Return true if fmt's encoding is one of LINEAR.
*/
static __inline bool
audio_format2_is_linear(const audio_format2_t *fmt)
{
return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
|| (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE)
|| (fmt->encoding == AUDIO_ENCODING_ULINEAR_LE)
|| (fmt->encoding == AUDIO_ENCODING_ULINEAR_BE);
}
/*
* Return true if fmt's encoding is one of SLINEAR.
*/
static __inline bool
audio_format2_is_signed(const audio_format2_t *fmt)
{
return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
|| (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE);
}
/*
* Return fmt's endian as LITTLE_ENDIAN or BIG_ENDIAN.
*/
static __inline int
audio_format2_endian(const audio_format2_t *fmt)
{
if (fmt->stride == 8) {
/* HOST ENDIAN */
return BYTE_ORDER;
}
if (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE ||
fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) {
return LITTLE_ENDIAN;
}
if (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE ||
fmt->encoding == AUDIO_ENCODING_ULINEAR_BE) {
return BIG_ENDIAN;
}
return BYTE_ORDER;
}
/* Interfaces for audiobell. */
int audiobellopen(dev_t, audio_file_t **);
int audiobellsetrate(audio_file_t *, u_int);
int audiobellclose(audio_file_t *);
int audiobellwrite(audio_file_t *, struct uio *);
#endif /* !_SYS_DEV_AUDIO_AUDIOVAR_H_ */