initial import
[dosrtxon] / libs / mikmod / drivers / dos / doswss.h
1 /*      MikMod sound library
2         (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
3         complete list.
4
5         This library is free software; you can redistribute it and/or modify
6         it under the terms of the GNU Library General Public License as
7         published by the Free Software Foundation; either version 2 of
8         the License, or (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13         GNU Library General Public License for more details.
14
15         You should have received a copy of the GNU Library General Public
16         License along with this library; if not, write to the Free Software
17         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18         02111-1307, USA.
19 */
20
21 /*==============================================================================
22
23   $Id$
24
25   Windows Sound System and compatible soundcards definitions
26
27 ==============================================================================*/
28
29 #ifndef __DOSWSS_H__
30 #define __DOSWSS_H__
31
32 #include "dosdma.h"
33 #include "dosirq.h"
34
35 #define WSS_ADDR                        (wss.port + 0x04)
36 #define WSS_DATA                        (wss.port + 0x05)
37 #define WSS_STATUS                      (wss.port + 0x06)
38 #define WSS_PIO                         (wss.port + 0x07)
39
40 /* WSS_ADDR: Bits 0-4 select an internal register to read/write */
41 #define WSSR_INPUT_L                    0x00    /* Left input control register */
42 #define WSSR_INPUT_R                    0x01    /* RIght input control register */
43 #define WSSR_AUX1_L                     0x02    /* Left Aux #1 input control */
44 #define WSSR_AUX1_R                     0x03    /* Right Aux #1 input control */
45 #define WSSR_CD_L                       0x04    /* Left Aux #2 input control */
46 #define WSSR_CD_R                       0x05    /* Right Aux #2 input control */
47 #define WSSR_MASTER_L                   0x06    /* Left output control */
48 #define WSSR_MASTER_R                   0x07    /* Right output control */
49 #define WSSR_PLAY_FORMAT                0x08    /* Clock and data format */
50 #define WSSR_IFACE_CTRL                 0x09    /* Interface control */
51 #define WSSR_PIN_CTRL                   0x0a    /* Pin control */
52 #define WSSR_TEST_INIT                  0x0b    /* Test and initialization */
53 #define WSSR_MISC_INFO                  0x0c    /* Miscellaneaous information */
54 #define WSSR_LOOPBACK                   0x0d    /* Digital Mix */
55 #define WSSR_COUNT_HIGH                 0x0e    /* Playback Upper Base Count */
56 #define WSSR_COUNT_LOW                  0x0f    /* Playback Lower Base Count */
57 #define WSSR_ALT_FEATURE_1              0x10    /* alternate #1 feature enable */
58 #define WSSR_ALT_FEATURE_2              0x11    /* alternate #2 feature enable */
59 #define WSSR_LINE_IN_L                  0x12    /* left line input control */
60 #define WSSR_LINE_IN_R                  0x13    /* right line input control */
61 #define WSSR_TIMER_LOW                  0x14    /* timer low byte */
62 #define WSSR_TIMER_HIGH                 0x15    /* timer high byte */
63 #define WSSR_IRQ_STATUS                 0x18    /* irq status register */
64 #define WSSR_MONO_IO_CTRL               0x1a    /* mono input/output control */
65 #define WSSR_REC_FORMAT                 0x1c    /* record format */
66 #define WSSR_REC_COUNT_HIGH             0x1e    /* record upper count */
67 #define WSSR_REC_COUNT_LOW              0x1f    /* record lower count */
68
69 /* WSS_ADDR bits 7-5 definition */
70 #define WSSM_INIT                       0x80    /* Codec is initializing */
71 #define WSSM_MCE                        0x40    /* Mode change enable */
72 #define WSSM_TRD                        0x20    /* Transfer Request Disable */
73 /* bits 4-0 are indirect register address (0-15) */
74
75 /* WSS_STATUS bit masks */
76 #define WSSM_CUL                        0x80    /* Capture data upper/lower byte */
77 #define WSSM_CLR                        0x40    /* Capture left/right sample */
78 #define WSSM_CRDY                       0x20    /* Capture data read */
79 #define WSSM_SOUR                       0x10    /* Playback over/under run error */
80 #define WSSM_PUL                        0x08    /* Playback upper/lower byte */
81 #define WSSM_PLR                        0x04    /* Playback left/right sample */
82 #define WSSM_PRDY                       0x02    /* Playback data register read */
83 #define WSSM_INT                        0x01    /* interrupt status */
84
85 /* Definitions for output level registers */
86 #define WSSM_MUTE                       0x80    /* Mute this output source */
87 /* bits 5-0 are left output attenuation select (0-63) */
88 /* bits 5-0 are right output attenuation select (0-63) */
89
90 /* Definitions for clock and data format register (WSSR_PLAY_FORMAT) */
91 #define WSSM_STEREO                     0x10    /* stero mode */
92 #define WSSM_ULAW_8                     0x20    /* 8-bit U-law companded */
93 #define WSSM_16BITS                     0x40    /* 16 bit twos complement data - little endian */
94 #define WSSM_ALAW_8                     0x60    /* 8-bit A-law companded */
95 #define WSSM_16BITS_BE                  0xc0    /* 16-bit twos complement data - big endian */
96 #define WSSM_ADPCM_16                   0xa0    /* 16-bit ADPCM */
97 /* Bits 3-1 define frequency divisor */
98 #define WSSM_XTAL1                      0x00    /* 24.576 crystal */
99 #define WSSM_XTAL2                      0x01    /* 16.9344 crystal */
100
101 /* Definitions for interface control register (WSSR_IFACE_CTRL) */
102 #define WSSM_CAPTURE_PIO                0x80    /* Capture PIO enable */
103 #define WSSM_PLAYBACK_PIO               0x40    /* Playback PIO enable */
104 #define WSSM_AUTOCALIB                  0x08    /* auto calibrate */
105 #define WSSM_SINGLE_DMA                 0x04    /* Use single DMA channel */
106 #define WSSM_PLAYBACK_ENABLE            0x01    /* playback enable */
107
108 /* Definitions for Pin control register (WSSR_PIN_CTRL) */
109 #define WSSM_IRQ_ENABLE                 0x02    /* interrupt enable */
110 #define WSSM_XCTL1                      0x40    /* external control #1 */
111 #define WSSM_XCTL0                      0x80    /* external control #0 */
112
113 /* Definitions for WSSR_TEST_INIT register */
114 #define WSSM_CALIB_IN_PROGRESS 0x20     /* auto calibrate in progress */
115
116 /* Definitions for misc control register (WSR_MISC_INFO) */
117 #define WSSM_MODE2                      0x40    /* MODE 2 */
118 #define WSSM_MODE3                      0x6c    /* MODE 3 - enhanced mode */
119
120 /* Definitions for codec irq status (WSSR_IRQ_STATUS) */
121 #define WSSM_PLAYBACK_IRQ               0x10
122 #define WSSM_RECORD_IRQ                 0x20
123 #define WSSM_TIMER_IRQ                  0x40
124
125 typedef unsigned char boolean;
126
127 #ifndef FALSE
128 #define FALSE                           0
129 #define TRUE                            1
130 #endif
131
132 /* Play mode bits */
133 #define WSSMODE_16BITS                  0x0001
134 #define WSSMODE_STEREO                  0x0002
135 #define WSSMODE_SIGNED                  0x0004
136
137 /* You can fill some members of this struct (i.e. port,irq,dma) before
138  * calling wss_detect() or wss_open()... this will ignore environment settings.
139  */
140 typedef struct __wss_state_s {
141         boolean ok;                     /* Set if this structure is properly filled */
142         int port;                       /* Base codec port */
143         int irq;                        /* codec IRQ */
144         int dma;                        /* codec DMA */
145         struct irq_handle *irq_handle;  /* The interrupt handler */
146         dma_buffer *dma_buff;           /* Pre-allocated DMA buffer */
147         unsigned char mode;             /* Current WSS mode (WSSMODE_XXX) */
148         boolean open;                   /* Whenever the card has been opened */
149         int samples;                    /* Number of samples in DMA buffer */
150         unsigned char level;            /* Output level (63..0): doesn't change when mute */
151         unsigned char curlevel;         /* Current output level (63(min)..0(max)) */
152         volatile int irqcount;          /* Incremented on each IRQ... for diagnostics */
153         void (*timer_callback) ();      /* Called TWICE per buffer play */
154 } __wss_state;
155
156 extern __wss_state wss;
157
158 /* Wait until codec finishes initialization */
159 static inline boolean __wss_wait()
160 {
161         int count;
162         for (count = 10000; count >= 0; count--)
163                 if (!(inportb(WSS_ADDR) & WSSM_INIT))
164                         return TRUE;
165         return FALSE;
166 }
167
168 static inline void __wss_outreg(unsigned char reg, unsigned char val)
169 {
170         outportb(WSS_ADDR, reg);
171         outportb(WSS_DATA, val);
172 }
173
174 static inline unsigned char __wss_inreg(unsigned char reg)
175 {
176         outportb(WSS_ADDR, reg);
177         return inportb(WSS_DATA);
178 }
179
180 /* Set some bits in a specific register */
181 static inline void __wss_regbit_set(unsigned char reg, unsigned char mask)
182 {
183         outportb(WSS_ADDR, reg);
184         outportb(WSS_DATA, inportb(WSS_DATA) | mask);
185 }
186
187 /* Reset some bits in a specific register */
188 static inline void __wss_regbit_reset(unsigned char reg, unsigned char mask)
189 {
190         outportb(WSS_ADDR, reg);
191         outportb(WSS_DATA, inportb(WSS_DATA) & ~mask);
192 }
193
194 /* Detect whenever WSS is present and fill "wss" structure */
195 extern boolean wss_detect();
196 /* Reset WSS */
197 extern void wss_reset();
198 /* Open WSS for usage */
199 extern boolean wss_open();
200 /* Finish working with WSS */
201 extern boolean wss_close();
202 /* Enable/disable speaker output */
203 extern void wss_output(boolean enable);
204 /* Adjust frequency rate to nearest WSS available */
205 extern unsigned int wss_adjust_freq(unsigned int freq);
206 /* Start playing from DMA buffer in either 8/16 bit mono/stereo */
207 extern boolean wss_start_dma(unsigned char mode, unsigned int freq);
208 /* Stop playing from DMA buffer */
209 extern void wss_stop_dma();
210 /* Query current position/total size of the DMA buffer */
211 extern void wss_query_dma(unsigned int *dma_size, unsigned int *dma_pos);
212 /* Set output level (0(min)-63(max)) */
213 extern void wss_level(int level);
214
215 #endif /* __DOSWSS_H__ */
216
217 /* ex:set ts=4: */