/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (C) 4Front Technologies 1996-2008.
 *
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_AUDIO_AUDIO_COMMON_H
#define	_SYS_AUDIO_AUDIO_COMMON_H

#include <sys/mkdev.h>
#include <sys/types.h>

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef	_KERNEL

/* Shared data structures */
typedef struct audio_parms audio_parms_t;
typedef struct audio_buffer audio_buffer_t;
typedef struct audio_stream audio_stream_t;
typedef struct audio_engine audio_engine_t;
typedef struct audio_client audio_client_t;
typedef struct audio_dev audio_dev_t;
typedef struct audio_mixer_ops audio_mixer_ops_t;
typedef struct audio_engine_ops audio_engine_ops_t;
typedef struct audio_ctrl audio_ctrl_t;
typedef struct audio_ctrl_desc audio_ctrl_desc_t;

struct audio_ctrl_desc {
	uint32_t		acd_version;
	uint32_t		acd_ctrl;		/* Control number */
	uint32_t		acd_type;		/* Entry type */
	uint64_t		acd_flags;		/* Characteristics */
	/*
	 * Minimum and Maximum values for this control.  The value
	 * must be between these values inclusive.  For
	 * AUDIO_CTRL_TYPE_CTRLS, the maxvalue is a bitmask of
	 * supported controls.
	 */
	uint64_t		acd_maxvalue;		/* max value control */
	uint64_t		acd_minvalue;		/* min value control */
	const char		*acd_name;		/* Controls Mnemonic */
	/*
	 * Array of pointers to names for each enum position. This
	 * should be null for all but AUDIO_CTRL_TYPE_ENUM.
	 */
	const char		*acd_enum[64];
};

/*
 * Audio data formats.  Note that these are represented int a bit
 * field, to allow for multiple values to be represented in the same
 * integer (in certain portions of the API.)
 */
#define	AUDIO_FORMAT_NONE		0x00000000U
#define	AUDIO_FORMAT_ULAW		0x00000001U
#define	AUDIO_FORMAT_ALAW		0x00000002U
#define	AUDIO_FORMAT_S8			0x00000004U
#define	AUDIO_FORMAT_U8			0x00000008U
#define	AUDIO_FORMAT_S16_LE		0x00000010U
#define	AUDIO_FORMAT_S16_BE		0x00000020U
#define	AUDIO_FORMAT_U16_LE		0x00000040U
#define	AUDIO_FORMAT_U16_BE		0x00000080U
#define	AUDIO_FORMAT_S24_LE		0x00000100U
#define	AUDIO_FORMAT_S24_BE		0x00000200U
#define	AUDIO_FORMAT_S32_LE		0x00000400U
#define	AUDIO_FORMAT_S32_BE		0x00000800U
#define	AUDIO_FORMAT_S24_PACKED		0x00001000U
#define	AUDIO_FORMAT_AC3		0x00010000U
#define	AUDIO_FORMAT_OPAQUE_MASK	0xffff0000U
#define	AUDIO_FORMAT_CONVERTIBLE	0x0000ffffU
/*
 * We only support signed 16, 24, and 32 bit format conversions in the
 * engines, for simplicity.  (We haven't run into any engines that
 * require other formats.)
 */
#define	AUDIO_FORMAT_PCM		0x00000f30

/*
 * Some big endian/little endian handling macros (native endian and opposite
 * endian formats). The usage of these macros is described in the OSS
 * Programmer's Manual.
 */

#if defined(_BIG_ENDIAN)

#define	AUDIO_FORMAT_S16_NE	AUDIO_FORMAT_S16_BE
#define	AUDIO_FORMAT_U16_NE	AUDIO_FORMAT_U16_BE
#define	AUDIO_FORMAT_S32_NE	AUDIO_FORMAT_S32_BE
#define	AUDIO_FORMAT_S24_NE	AUDIO_FORMAT_S24_BE
#define	AUDIO_FORMAT_S16_OE	AUDIO_FORMAT_S16_LE
#define	AUDIO_FORMAT_U16_OE	AUDIO_FORMAT_U16_LE
#define	AUDIO_FORMAT_S32_OE	AUDIO_FORMAT_S32_LE
#define	AUDIO_FORMAT_S24_OE	AUDIO_FORMAT_S24_LE

#elif defined(_LITTLE_ENDIAN)
#define	AUDIO_FORMAT_S16_NE	AUDIO_FORMAT_S16_LE
#define	AUDIO_FORMAT_U16_NE	AUDIO_FORMAT_U16_LE
#define	AUDIO_FORMAT_S32_NE	AUDIO_FORMAT_S32_LE
#define	AUDIO_FORMAT_S24_NE	AUDIO_FORMAT_S24_LE
#define	AUDIO_FORMAT_S16_OE	AUDIO_FORMAT_S16_BE
#define	AUDIO_FORMAT_U16_OE	AUDIO_FORMAT_U16_BE
#define	AUDIO_FORMAT_S32_OE	AUDIO_FORMAT_S32_BE
#define	AUDIO_FORMAT_S24_OE	AUDIO_FORMAT_S24_BE

#else
#error "Machine endianness undefined"
#endif

/*
 * These are parameterized around the maximum minor number available
 * for use in the filesystem.  Unfortunately, we have to use 32-bit limits,
 * because we could have 32-bit userland apps (we usually will, in fact).
 */
#define	AUDIO_MN_CLONE_NBITS	(NBITSMINOR32 - 1)
#define	AUDIO_MN_CLONE_MASK	(1U << (AUDIO_MN_CLONE_NBITS - 1))
#define	AUDIO_MN_TYPE_NBITS	(4)
#define	AUDIO_MN_TYPE_SHIFT	(0)
#define	AUDIO_MN_TYPE_MASK	((1U << AUDIO_MN_TYPE_NBITS) - 1)
#define	AUDIO_MN_INST_NBITS	((NBITSMINOR32 - 1) - AUDIO_MN_TYPE_NBITS)
#define	AUDIO_MN_INST_MASK	((1U << AUDIO_MN_INST_NBITS) - 1)
#define	AUDIO_MN_INST_SHIFT	(AUDIO_MN_TYPE_NBITS)
#define	AUDIO_MKMN(inst, typ)	\
	(((inst) << AUDIO_MN_INST_SHIFT) | ((typ) << AUDIO_MN_TYPE_SHIFT))

#define	AUDIO_MINOR_MIXER	(0)
#define	AUDIO_MINOR_PLAYBACK	(1)
#define	AUDIO_MINOR_RECORD	(2)
#define	AUDIO_MINOR_DEVAUDIO	(3)
#define	AUDIO_MINOR_DEVAUDIOCTL	(4)


#define	AUDIO_CTRL_VERSION		1	/* Control API version */

/*
 * This is a list of well-known controls. These are common to most hardware.
 * When a driver registers a well-known control it should use these defines
 * for ctrl number.
 *
 * Not that some client modules may look for these legacy ones for special
 * user IOCTL's so use caution with these.
 *
 */
/* Output volume controls */
#define	AUDIO_CONTROL_LINEOUT		0	/* "Front Volume" */
#define	AUDIO_CONTROL_REAR		1	/* "REAR Out" */
#define	AUDIO_CONTROL_HEADPHONE		2	/* "HeadPhones" */
#define	AUDIO_CONTROL_CENTER		3	/* "Center Out" */
#define	AUDIO_CONTROL_LFE		4	/* "LFE Out" */
#define	AUDIO_CONTROL_SURROUND		5	/* "Surround Out" */
#define	AUDIO_CONTROL_MONOOUT		6	/* "Mono Master Volume" */
#define	AUDIO_CONTROL_SPEAKER		7	/* "Speaker" */
#define	AUDIO_CONTROL_AUX1OUT		8	/* "AUX 1 Out" */
#define	AUDIO_CONTROL_AUX2OUT		9	/* "AUX 2 Out" */
/* Effect output controls */
#define	AUDIO_CONTROL_BASS		10	/* "Bass" */
#define	AUDIO_CONTROL_TREBLE		11	/* "Treble" */
#define	AUDIO_CONTROL_3DDEPTH		12	/* "3D Depth" */
#define	AUDIO_CONTROL_3DCENT		13	/* "3D Center" */
/* Input volume controls */
#define	AUDIO_CONTROL_PHONE		14	/* "Phone Monitor" */
#define	AUDIO_CONTROL_MIC		15	/* "MIC In" */
#define	AUDIO_CONTROL_LINEIN		16	/* "Line In" */
#define	AUDIO_CONTROL_CD		17	/* "CD In" */
#define	AUDIO_CONTROL_VIDEO		18	/* "Video In" */
#define	AUDIO_CONTROL_AUX1IN		19	/* "AUX In" */
#define	AUDIO_CONTROL_PCMIN		20	/* *PCM" PCM remix */
#define	AUDIO_CONTROL_IGAIN		21	/* "Rec GAIN" Input gain */
#define	AUDIO_CONTROL_AUX2IN		22	/* "AUX 2 In" */
/* Selector Controls */
#define	AUDIO_CONTROL_MICBOOST		23	/* 20DB MIC boost on/off */
#define	AUDIO_CONTROL_3DONOFF		24	/* "3D" */
#define	AUDIO_CONTROL_LOOPBACK		25	/* "Loop Back" */
#define	AUDIO_CONTROL_LOUDNESS		26	/* "Loudness Boost" */
#define	AUDIO_CONTROL_OUTPUTS		27	/* "PORTS" */
#define	AUDIO_CONTROL_INPUTS		28	/* "Record SOURCE" */
#define	AUDIO_CONTROL_DIAG		29	/* "DIAG LoopBack" */
/* Digital controls */
#define	AUDIO_CONTROL_SPDIFOUT		30	/* "SPDIF Out" */
#define	AUDIO_CONTROL_SPDIFIN		31	/* "SPDIF In" */
/* pseudo controls */
#define	AUDIO_CONTROL_MASTER		32	/* "Master Volume" */
#define	AUDIO_CONTROL_MUTE		33	/* Master Mute */
#define	AUDIO_CONTROL_MONITOR		34	/* Master MONITOR volume */
#define	AUDIO_CONTROL_FORCEMON		35	/* Force MONITOR's on */

#define	AUDIO_CONTROL_PCBEEP		36	/* PC beeper volume */

#define	AUDIO_CONTROL_NR		37	/* Number currently defined */

/*
 * Base for extended device-private controls. Extended control numbers can
 * not be less then this value.
 */
#define	AUDIO_CONTROL_EXTBASE		0x4000	/* Extnd device-private base */

/*
 * Record and port selection, PORTS.
 *
 * For AUDIO_CONTROL_INPUTS usually only one may be selected at a
 * time.  It can be thought of as a switch to select the source for
 * recording.
 *
 * For AUDIO_CONTROL_OUTPUTS any number of these may be selected
 * at once and the ones not selected will remain muted. This control
 * can be thought of as overall mute controls for all muteable output
 * channels.
 */
#define	AUDIO_PORT_MIC			0x00000001
#define	AUDIO_PORT_CD			0x00000002
#define	AUDIO_PORT_VIDEO		0x00000004
#define	AUDIO_PORT_AUX1OUT		0x00000008
#define	AUDIO_PORT_AUX2OUT		0x00000010
#define	AUDIO_PORT_LINEOUT		0x00000020
#define	AUDIO_PORT_STEREOMIX		0x00000040
#define	AUDIO_PORT_MONOOUT		0x00000080
#define	AUDIO_PORT_PHONE		0x00000100
#define	AUDIO_PORT_REAR			0x00000200
#define	AUDIO_PORT_CENTER		0x00000400
#define	AUDIO_PORT_SURROUND		0x00000800
#define	AUDIO_PORT_LFE			0x00001000
#define	AUDIO_PORT_SPEAKER		0x00002000
#define	AUDIO_PORT_LINEIN		0x00004000
#define	AUDIO_PORT_AUX1IN		0x00008000
#define	AUDIO_PORT_AUX2IN		0x00010000
#define	AUDIO_PORT_HEADPHONES		0x00020000
#define	AUDIO_PORT_SPDIFIN		0x00040000
#define	AUDIO_PORT_SPDIFOUT		0x00080000
#define	AUDIO_PORT_MONOMIX		0x00100000

/*
 * Posible return values for walk callback function
 */
#define	AUDIO_WALK_CONTINUE	1	/* continue walk */
#define	AUDIO_WALK_STOP		2	/* stop the walk */
#define	AUDIO_WALK_RESTART	3	/* restart the walk from beginning */

/*
 * Control types
 */
#define	AUDIO_CTRL_TYPE_BOOLEAN		1	/* ON/OFF control */
#define	AUDIO_CTRL_TYPE_ENUM		2	/* Enumerated list */
#define	AUDIO_CTRL_TYPE_STEREO		3	/* stereo level control */
#define	AUDIO_CTRL_TYPE_MONO		4	/* mono level control */
#define	AUDIO_CTRL_TYPE_METER		5	/* VU meter */
#define	AUDIO_CTRL_TYPE_PORTS		6	/* bitmask of controls */

/*
 * Control characteristics flags
 */
#define	AUDIO_CTRL_FLAG_READABLE	0x00000001	/* Control readable */
#define	AUDIO_CTRL_FLAG_WRITEABLE	0x00000002	/* Control writable */
#define	AUDIO_CTRL_FLAG_VUPEAK		0x00000004	/* peak meter */
#define	AUDIO_CTRL_FLAG_CENTIBEL	0x00000008	/* Centibel (0.1 dB) */
#define	AUDIO_CTRL_FLAG_DECIBEL		0x00000010	/* Step size of 1 dB */
#define	AUDIO_CTRL_FLAG_POLL		0x00000020	/* May change itself */
/*
 * Some types (AUDIO_CTRL_TYPE_ENUM, AUDIO_CTRL_TYPE_CTRLS) might
 * allow more than a single value to be selected.  (Value is a
 * bitmask.)
 */
#define	AUDIO_CTRL_FLAG_MULTI		0x00000040

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_AUDIO_AUDIO_COMMON_H */
