1vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual
2Workstations' onboard audio.
3
4Copyright 1999 Silicon Graphics, Inc.  All rights reserved.
5
6
7At the time of this writing, March 1999, there are two models of
8Visual Workstation, the 320 and the 540.  This document only describes
9those models.  Future Visual Workstation models may have different
10sound capabilities, and this driver will probably not work on those
11boxes.
12
13The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
14codec chip.  The AD1843 is accessed through the Cobalt I/O ASIC, also
15known as Lithium.  This driver programs both both chips.
16
17==============================================================================
18QUICK CONFIGURATION
19
20	# insmod soundcore
21	# insmod vwsnd
22
23==============================================================================
24I/O CONNECTIONS
25
26On the Visual Workstation, only three of the AD1843 inputs are hooked
27up.  The analog line in jacks are connected to the AD1843's AUX1
28input.  The CD audio lines are connected to the AD1843's AUX2 input.
29The microphone jack is connected to the AD1843's MIC input.  The mic
30jack is mono, but the signal is delivered to both the left and right
31MIC inputs.  You can record in stereo from the mic input, but you will
32get the same signal on both channels (within the limits of A/D
33accuracy).  Full scale on the Line input is +/- 2.0 V.  Full scale on
34the MIC input is 20 dB less, or +/- 0.2 V.
35
36The AD1843's LOUT1 outputs are connected to the Line Out jacks.  The
37AD1843's HPOUT outputs are connected to the speaker/headphone jack.
38LOUT2 is not connected.  Line out's maximum level is +/- 2.0 V peak to
39peak.  The speaker/headphone out's maximum is +/- 4.0 V peak to peak.
40
41The AD1843's PCM input channel and one of its output channels (DAC1)
42are connected to Lithium.  The other output channel (DAC2) is not
43connected.
44
45==============================================================================
46CAPABILITIES
47
48The AD1843 has PCM input and output (Pulse Code Modulation, also known
49as wavetable).  PCM input and output can be mono or stereo in any of
50four formats.  The formats are 16 bit signed and 8 bit unsigned,
51u-Law, and A-Law format.  Any sample rate from 4 KHz to 49 KHz is
52available, in 1 Hz increments.
53
54The AD1843 includes an analog mixer that can mix all three input
55signals (line, mic and CD) into the analog outputs.  The mixer has a
56separate gain control and mute switch for each input.
57
58There are two outputs, line out and speaker/headphone out.  They
59always produce the same signal, and the speaker always has 3 dB more
60gain than the line out.  The speaker/headphone output can be muted,
61but this driver does not export that function.
62
63The hardware can sync audio to the video clock, but this driver does
64not have a way to specify syncing to video.
65
66==============================================================================
67PROGRAMMING
68
69This section explains the API supported by the driver.  Also see the
70Open Sound Programming Guide at http://www.opensound.com/pguide/ .
71This section assumes familiarity with that document.
72
73The driver has two interfaces, an I/O interface and a mixer interface.
74There is no MIDI or sequencer capability.
75
76==============================================================================
77PROGRAMMING PCM I/O
78
79The I/O interface is usually accessed as /dev/audio or /dev/dsp.
80Using the standard Open Sound System (OSS) ioctl calls, the sample
81rate, number of channels, and sample format may be set within the
82limitations described above.  The driver supports triggering.  It also
83supports getting the input and output pointers with one-sample
84accuracy.
85
86The SNDCTL_DSP_GETCAP ioctl returns these capabilities.
87
88	DSP_CAP_DUPLEX - driver supports full duplex.
89
90	DSP_CAP_TRIGGER - driver supports triggering.
91
92	DSP_CAP_REALTIME - values returned by SNDCTL_DSP_GETIPTR
93	and SNDCTL_DSP_GETOPTR are accurate to a few samples.
94
95Memory mapping (mmap) is not implemented.
96
97The driver permits subdivided fragment sizes from 64 to 4096 bytes.
98The number of fragments can be anything from 3 fragments to however
99many fragments fit into 124 kilobytes.  It is up to the user to
100determine how few/small fragments can be used without introducing
101glitches with a given workload.  Linux is not realtime, so we can't
102promise anything.  (sigh...)
103
104When this driver is switched into or out of mu-Law or A-Law mode on
105output, it may produce an audible click.  This is unavoidable.  To
106prevent clicking, use signed 16-bit mode instead, and convert from
107mu-Law or A-Law format in software.
108
109==============================================================================
110PROGRAMMING THE MIXER INTERFACE
111
112The mixer interface is usually accessed as /dev/mixer.  It is accessed
113through ioctls.  The mixer allows the application to control gain or
114mute several audio signal paths, and also allows selection of the
115recording source.
116
117Each of the constants described here can be read using the
118MIXER_READ(SOUND_MIXER_xxx) ioctl.  Those that are not read-only can
119also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl.  In most
120cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and
121SOUND_MIXER_WRITE_xxx which work just as well.
122
123SOUND_MIXER_CAPS	Read-only
124
125This is a mask of optional driver capabilities that are implemented.
126This driver's only capability is SOUND_CAP_EXCL_INPUT, which means
127that only one recording source can be active at a time.
128
129SOUND_MIXER_DEVMASK	Read-only
130
131This is a mask of the sound channels.  This driver's channels are PCM,
132LINE, MIC, CD, and RECLEV.
133
134SOUND_MIXER_STEREODEVS	Read-only
135
136This is a mask of which sound channels are capable of stereo.  All
137channels are capable of stereo.  (But see caveat on MIC input in I/O
138CONNECTIONS section above).
139
140SOUND_MIXER_OUTMASK	Read-only
141
142This is a mask of channels that route inputs through to outputs.
143Those are LINE, MIC, and CD.
144
145SOUND_MIXER_RECMASK	Read-only
146
147This is a mask of channels that can be recording sources.  Those are
148PCM, LINE, MIC, CD.
149
150SOUND_MIXER_PCM		Default: 0x5757 (0 dB)
151
152This is the gain control for PCM output.  The left and right channel
153gain are controlled independently.  This gain control has 64 levels,
154which range from -82.5 dB to +12.0 dB in 1.5 dB steps.  Those 64
155levels are mapped onto 100 levels at the ioctl, see below.
156
157SOUND_MIXER_LINE	Default: 0x4a4a (0 dB)
158
159This is the gain control for mixing the Line In source into the
160outputs.  The left and right channel gain are controlled
161independently.  This gain control has 32 levels, which range from
162-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
163100 levels at the ioctl, see below.
164
165SOUND_MIXER_MIC		Default: 0x4a4a (0 dB)
166
167This is the gain control for mixing the MIC source into the outputs.
168The left and right channel gain are controlled independently.  This
169gain control has 32 levels, which range from -34.5 dB to +12.0 dB in
1701.5 dB steps.  Those 32 levels are mapped onto 100 levels at the
171ioctl, see below.
172
173SOUND_MIXER_CD		Default: 0x4a4a (0 dB)
174
175This is the gain control for mixing the CD audio source into the
176outputs.  The left and right channel gain are controlled
177independently.  This gain control has 32 levels, which range from
178-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
179100 levels at the ioctl, see below.
180
181SOUND_MIXER_RECLEV	 Default: 0 (0 dB)
182
183This is the gain control for PCM input (RECording LEVel).  The left
184and right channel gain are controlled independently.  This gain
185control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB
186steps.  Those 16 levels are mapped onto 100 levels at the ioctl, see
187below.
188
189SOUND_MIXER_RECSRC	 Default: SOUND_MASK_LINE
190
191This is a mask of currently selected PCM input sources (RECording
192SouRCes).  Because the AD1843 can only have a single recording source
193at a time, only one bit at a time can be set in this mask.  The
194allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC,
195or SOUND_MASK_CD.  Selecting SOUND_MASK_PCM sets up internal
196resampling which is useful for loopback testing and for hardware
197sample rate conversion.  But software sample rate conversion is
198probably faster, so I don't know how useful that is.
199
200SOUND_MIXER_OUTSRC	DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD
201
202This is a mask of sources that are currently passed through to the
203outputs.  Those sources whose bits are not set are muted.
204
205==============================================================================
206GAIN CONTROL
207
208There are five gain controls listed above.  Each has 16, 32, or 64
209steps.  Each control has 1.5 dB of gain per step.  Each control is
210stereo.
211
212The OSS defines the argument to a channel gain ioctl as having two
213components, left and right, each of which ranges from 0 to 100.  The
214two components are packed into the same word, with the left side gain
215in the least significant byte, and the right side gain in the second
216least significant byte.  In C, we would say this.
217
218	#include <assert.h>
219
220	...
221
222	 	assert(leftgain >= 0 && leftgain <= 100);
223		assert(rightgain >= 0 && rightgain <= 100);
224		arg = leftgain | rightgain << 8;
225
226So each OSS gain control has 101 steps.  But the hardware has 16, 32,
227or 64 steps.  The hardware steps are spread across the 101 OSS steps
228nearly evenly.  The conversion formulas are like this, given N equals
22916, 32, or 64.
230
231	int round = N/2 - 1;
232	OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1);
233	hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100;
234
235Here is a snippet of C code that will return the left and right gain
236of any channel in dB.  Pass it one of the predefined gain_desc_t
237structures to access any of the five channels' gains.
238
239	typedef struct gain_desc {
240		float min_gain;
241		float gain_step;
242		int nbits;
243		int chan;
244	} gain_desc_t;
245
246	const gain_desc_t gain_pcm    = { -82.5, 1.5, 6, SOUND_MIXER_PCM    };
247	const gain_desc_t gain_line   = { -34.5, 1.5, 5, SOUND_MIXER_LINE   };
248	const gain_desc_t gain_mic    = { -34.5, 1.5, 5, SOUND_MIXER_MIC    };
249	const gain_desc_t gain_cd     = { -34.5, 1.5, 5, SOUND_MIXER_CD     };
250	const gain_desc_t gain_reclev = {   0.0, 1.5, 4, SOUND_MIXER_RECLEV };
251
252	int get_gain_dB(int fd, const gain_desc_t *gp,
253			float *left, float *right)
254	{
255		int word;
256		int lg, rg;
257		int mask = (1 << gp->nbits) - 1;
258
259		if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0)
260			return -1;	/* fail */
261		lg = word & 0xFF;
262		rg = word >> 8 & 0xFF;
263		lg = (lg * mask + mask / 2) / 100;
264		rg = (rg * mask + mask / 2) / 100;
265		*left = gp->min_gain + gp->gain_step * lg;
266		*right = gp->min_gain + gp->gain_step * rg;
267		return 0;
268	}
269
270And here is the corresponding routine to set a channel's gain in dB.
271
272	int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right)
273	{
274		float max_gain =
275			gp->min_gain + (1 << gp->nbits) * gp->gain_step;
276		float round = gp->gain_step / 2;
277		int mask = (1 << gp->nbits) - 1;
278		int word;
279		int lg, rg;
280
281		if (left < gp->min_gain || right < gp->min_gain)
282			return EINVAL;
283		lg = (left - gp->min_gain + round) / gp->gain_step;
284		rg = (right - gp->min_gain + round) / gp->gain_step;
285		if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits))
286			return EINVAL;
287		lg = (100 * lg + mask / 2) / mask;
288		rg = (100 * rg + mask / 2) / mask;
289		word = lg | rg << 8;
290
291		return ioctl(fd, MIXER_WRITE(gp->chan), &word);
292	}
293
294