audiovar.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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) 1991-1992, 1997-2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _SYS_AUDIOVAR_H
#define _SYS_AUDIOVAR_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* The audio driver is divided into generic (device-independent) and
* device-specific modules. The generic routines handle most STREAMS
* protocol issues, communicating with the device-specific code via
* function callouts and a chained control block structure.
*
* Separate control block lists are maintained for reading (record) and
* writing (play). These control blocks simulate a chained-DMA
* structure, in that each block controls the transfer of data between
* the device and a single contiguous memory segment.
*
* The command block contains buffer start and stop addresses, a link
* address to the next block in the chain, a 'done' flag, a 'skip' flag
* (indicating that this command block contains no data), and a pointer
* to the STREAMS data block structure which is private to the generic
* driver.
*
* The device-specific audio driver code is expected to honor the 'skip'
* flag and set the 'done' flag when it has completed processing the
* command block (i.e., the data transfer, if any, is complete). For
* record command blocks, it is also expected to add to the 'data'
* pointer the number of bytes successfully read from the device.
*
* The device-specific driver module must initialize the static STREAMS
* control structures and must provide an identify routine (sbus-only),
* an attach routine, and an open routine. The open routine verifies the
* device unit number and calls the generic open routine with the address
* of the audio_state structure for that unit.
*
* The generic audio driver makes calls to the device-specific code
* through an ops-vector table. The following routines must be provided:
*
* The 'close' routine is called after either the play or record stream
* is closed. It may perform device-specific cleanup and initialization.
*
* void dev_close(as)
* aud_stream_t *as; // Pointer to audio device state
*
*
* The 'ioctl' routine is called from the STREAMS write put procedure
* when a non-generic ioctl is encountered (AUDIO_SETINFO, AUDIO_GETINFO,
* and AUDIO_DRAIN are the generic ioctls). Any required data mblk_t is
* ioctl, the user-supplied buffer at mp->b_cont is reused). If data is
* successfully returned, the iocp->ioc_count field should be set with
* the number of bytes returned. If an error occurs, the 'ioctl' routine
* should set iocp->ioc_error to the appropriate error code. Otherwise,
* the returned value should be AUDRETURN_CHANGE if a device state change
* occurred (in which case a signal is sent to the control device, if
* any) and AUDRETURN_NOCHANGE if no signal should be sent. If the ioctl
* can not complete right away, it should return AUDRETURN_DELAYED
* indicating that it will ack the ioctl at a later time.
*
* aud_return_t dev_ioctl(as, mp, iocp)
* aud_stream_t *as; // Pointer to audio device state
* mblk_t *mp; // ioctl STREAMS message block
* struct iocblk *iocp; // M_IOCTL message data
*
*
* The 'start' routine is called to start i/o. Ordinarily, it is called
* from the device-specific 'queuecmd' routine, but it is also called
* when paused output is resumed.
*
* void dev_start(as)
* aud_stream_t *as; // Pointer to audio device state
*
*
* The 'stop' routine is called to stop i/o. It is called when i/o is
* paused, flushed, or the device is closed. Note that currently queued
* command blocks should not be flushed by this routine, since i/o may be
* resumed from the current point.
*
* void dev_stop(as)
* aud_stream_t *as; // Pointer to audio device state
*
*
* The 'setflag' routine is called to get a single device-specific flag.
* The flag argument is either AUD_ACTIVE (return the active flag) or
* AUD_ERRORRESET (zero the error flag, returning its previous value).
* (The val argument is currently ignored.)
*
* void dev_setflag(as, flag, val)
* aud_stream_t *as; // Pointer to audio device state
* enum aud_opflag flag; // AUD_ACTIVE || AUD_ERRORESET
*
*
* The 'setinfo' routine is called to get or set device-specific fields
* in the audio state structure. If mp is NULL, the sample counters and
* active flags should be set in v. If mp is not NULL, then
* mp->b_cont->data points to the audio_info_t structure supplied in an
* AUDIO_SETINFO ioctl (ip). All device-specific fields (gains, ports,
* sample counts) in both v and the device itself should be updated, as
* long as the corresponding field in ip is not set to AUD_INIT_VALUE.
* When the sample counters are set, the value returned in v should be
* the previous value. If the setinfo can not complete right away, it
* should return AUDRETURN_DELAYED indicating that it will ack the ioctl
* at a later time. If an error occurs on setinfo, the iocp->ioc_error
* should be set as in dev_ioctl
*
* aud_return_t dev_setinfo(as, mp, iocp)
* aud_stream_t *as; // Pointer to audio device state
* mblk_t *mp; // user info structure or NULL
* struct iocblk *iocp; // M_IOCTL message data
*
*
* The 'queuecmd' routine is called whenever a new command block is
* linked into the chained command list. The device-specific code must
* ensure that the command is enqueued to the device and that i/o, if not
* currently active, is started.
*
* void dev_queuecmd(as, cmdp)
* aud_stream_t *as; // Pointer to audio device state
* struct aud_cmd *cmdp; // new command block to queue
*
*
* The 'flushcmd' routine is called whenever the chained command list is
* flushed. It is only called after i/o has been stopped (via the 'stop'
* routine) and after the command list in the audio state structure has
* been cleared. The device-specific code should flush the device's
* queued command list.
*
* void dev_flushcmd(as)
* aud_stream_t *as; // Pointer to audio device state
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Various generic audio driver constants
*/
#define AUD_INITVALUE (~0)
/*
* Define the virtual chained-DMA control structure
*/
struct aud_cmd {
/*
* Data pointers
*/
/*
* Linked list management
*/
/*
* Flags
*/
uint_t :0; /* Force word alignment */
/*
* Device-independent private, opaque storage
*/
void *dihandle;
};
/*
* Define the list-head for queued control structures
*/
typedef struct aud_cmdlist aud_cmdlist_t;
struct aud_cmdlist {
};
/*
* Define possible return values from the setinfo and ioctl calls
*/
typedef enum {
} aud_return_t;
/*
* Define legal values for the 'flag' argument to the 'setflag' callout
*/
enum aud_opflag {
AUD_ACTIVE, /* active flag */
AUD_ERRORRESET /* error flag (reset after read) */
};
/*
* The audio stream type determines the legal operations for a stream in the
* generic portion of an audio driver.
*/
typedef enum {
AUDTYPE_NONE = 00, /* Not a legal device */
typedef enum {
AUDMODE_NONE = 00, /* Not a legal mode */
/*
* This structure describes the state of the audio device and queues
*/
typedef struct aud_state aud_state_t;
struct aud_state {
/*
* Back-pointer to the device-dependent audio state
*/
void *ddstate;
/*
* Device-independent audio state
*/
/*
* Audio ops vector
*/
};
/*
* STREAMS routines pass the address of a 'struct audstream' when calling
* put and service procedures. This structure points to the STREAMS
* queues and back to the containing 'struct aud_state'.
*/
typedef struct aud_stream aud_stream_t;
struct aud_stream {
/*
* Sideways pointers to related aud_stream_t structures
*/
/*
* Software state
*/
int openflag; /* open flag & (FREAD|FWRITE) */
int maxfrag_size; /* max aud_cmd_t fragment size */
struct {
int action; /* IOCTL action */
int reason; /* HW implementation dep. reason */
} dioctl; /* Delayed ioctls */
/*
* STREAMS information
*/
/*
* OS-Dependent information
*
* NB - For now we lock on a per-unit basis, so this points to
* the mutex of the unit it belongs to. Other arrangements can
* be made later
*
* The condition variable in a output stream is used to wait for
* output to drain.
*
* The condition variable in a control stream is used to wait on
* open if the device is in use.
*/
};
#define AUDIOCACTION_INIT (0) /* no ioctl in progress */
/*
* Argument for audio_sensig
*/
typedef enum {
AUDIO_SENDSIG_NONE = 0, /* Default */
AUDIO_SENDSIG_EXPLICIT, /* Send signal up this aud_stream only */
AUDIO_SENDSIG_ALL /* Send signal up all related aud_streams */
/*
* Define the ops-vector table for device-specific callouts
*
* close close routine
* ioctl ioctl routine
* start routine to start I/O on a stream
* stop routine to stop I/O on a stream
* setflag routine to get or set a flag value
* setinfo routine to get or set the audio state structure
* queuecmd routine to queue a command on the HW command list
* flushcmd routine to flush the HW's command list
*/
struct aud_ops {
#ifdef __STDC__
void (*close)(aud_stream_t *);
void (*start)(aud_stream_t *);
void (*stop)(aud_stream_t *);
void (*flushcmd)(aud_stream_t *);
#else /* __STDC__ */
void (*close)();
aud_return_t (*ioctl)();
aud_return_t (*mproto)();
void (*start)();
void (*stop)();
aud_return_t (*setinfo)();
void (*queuecmd)();
void (*flushcmd)();
#endif /* __STDC__ */
};
/*
* Define pseudo-routine names for the device-specific callouts
*/
/*
* Device Independent Audio driver function prototypes
*/
#ifdef __STDC__
extern int audio_wsrv(queue_t *);
extern int audio_rsrv(queue_t *);
extern void audio_gc_output(aud_stream_t *);
extern void audio_process_output(aud_stream_t *);
extern void audio_process_input(aud_stream_t *);
extern void audio_flush_cmdlist(aud_stream_t *);
extern void audio_pause_play(aud_stream_t *);
extern void audio_pause_record(aud_stream_t *);
extern void audio_resume_play(aud_stream_t *);
extern void audio_resume_record(aud_stream_t *);
#else /* __STDC__ */
extern int audio_open();
extern int audio_close();
extern int audio_wput();
extern int audio_wsrv();
extern int audio_rput();
extern int audio_rsrv();
extern void audio_gc_output();
extern void audio_process_output();
extern void audio_process_input();
extern void audio_sendsig();
extern void audio_flush_cmdlist();
extern void audio_ack();
extern void audio_copyout();
extern void audio_pause_play();
extern void audio_pause_record();
extern void audio_resume_play();
extern void audio_resume_record();
extern void audio_trace()
extern void audio_trace_hdr();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_AUDIOVAR_H */