aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/Kconfig10
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/sis7019.c1461
-rw-r--r--sound/pci/sis7019.h342
4 files changed, 1815 insertions, 0 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 356bf21a1506..45f0f6c2f353 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -802,6 +802,16 @@ config SND_RME9652
802 To compile this driver as a module, choose M here: the module 802 To compile this driver as a module, choose M here: the module
803 will be called snd-rme9652. 803 will be called snd-rme9652.
804 804
805config SND_SIS7019
806 tristate "SiS 7019 Audio Accelerator"
807 depends on SND && X86 && !X86_64
808 select SND_AC97_CODEC
809 help
810 Say Y here to include support for the SiS 7019 Audio Accelerator.
811
812 To compile this driver as a module, choose M here: the module
813 will be called snd-sis7019.
814
805config SND_SONICVIBES 815config SND_SONICVIBES
806 tristate "S3 SonicVibes" 816 tristate "S3 SonicVibes"
807 depends on SND 817 depends on SND
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 09ddc82eeca2..56738da9c14a 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -23,6 +23,7 @@ snd-intel8x0m-objs := intel8x0m.o
23snd-maestro3-objs := maestro3.o 23snd-maestro3-objs := maestro3.o
24snd-rme32-objs := rme32.o 24snd-rme32-objs := rme32.o
25snd-rme96-objs := rme96.o 25snd-rme96-objs := rme96.o
26snd-sis7019-objs := sis7019.o
26snd-sonicvibes-objs := sonicvibes.o 27snd-sonicvibes-objs := sonicvibes.o
27snd-via82xx-objs := via82xx.o 28snd-via82xx-objs := via82xx.o
28snd-via82xx-modem-objs := via82xx_modem.o 29snd-via82xx-modem-objs := via82xx_modem.o
@@ -48,6 +49,7 @@ obj-$(CONFIG_SND_INTEL8X0M) += snd-intel8x0m.o
48obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o 49obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
49obj-$(CONFIG_SND_RME32) += snd-rme32.o 50obj-$(CONFIG_SND_RME32) += snd-rme32.o
50obj-$(CONFIG_SND_RME96) += snd-rme96.o 51obj-$(CONFIG_SND_RME96) += snd-rme96.o
52obj-$(CONFIG_SND_SIS7019) += snd-sis7019.o
51obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o 53obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
52obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o 54obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
53obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o 55obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
new file mode 100644
index 000000000000..2f178598186d
--- /dev/null
+++ b/sound/pci/sis7019.c
@@ -0,0 +1,1461 @@
1/*
2 * Driver for SiS7019 Audio Accelerator
3 *
4 * Copyright (C) 2004-2007, David Dillow
5 * Written by David Dillow <dave@thedillows.org>
6 * Inspired by the Trident 4D-WaveDX/NX driver.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, version 2.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/pci.h>
27#include <linux/time.h>
28#include <linux/moduleparam.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <sound/core.h>
32#include <sound/ac97_codec.h>
33#include <sound/initval.h>
34#include "sis7019.h"
35
36MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
37MODULE_DESCRIPTION("SiS7019");
38MODULE_LICENSE("GPL");
39MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
40
41static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
42static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
43static int enable = 1;
44
45module_param(index, int, 0444);
46MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
47module_param(id, charp, 0444);
48MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
49module_param(enable, bool, 0444);
50MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
51
52static struct pci_device_id snd_sis7019_ids[] = {
53 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
54 { 0, }
55};
56
57MODULE_DEVICE_TABLE(pci, snd_sis7019_ids);
58
59/* There are three timing modes for the voices.
60 *
61 * For both playback and capture, when the buffer is one or two periods long,
62 * we use the hardware's built-in Mid-Loop Interrupt and End-Loop Interrupt
63 * to let us know when the periods have ended.
64 *
65 * When performing playback with more than two periods per buffer, we set
66 * the "Stop Sample Offset" and tell the hardware to interrupt us when we
67 * reach it. We then update the offset and continue on until we are
68 * interrupted for the next period.
69 *
70 * Capture channels do not have a SSO, so we allocate a playback channel to
71 * use as a timer for the capture periods. We use the SSO on the playback
72 * channel to clock out virtual periods, and adjust the virtual period length
73 * to maintain synchronization. This algorithm came from the Trident driver.
74 *
75 * FIXME: It'd be nice to make use of some of the synth features in the
76 * hardware, but a woeful lack of documentation is a significant roadblock.
77 */
78struct voice {
79 u16 flags;
80#define VOICE_IN_USE 1
81#define VOICE_CAPTURE 2
82#define VOICE_SSO_TIMING 4
83#define VOICE_SYNC_TIMING 8
84 u16 sync_cso;
85 u16 period_size;
86 u16 buffer_size;
87 u16 sync_period_size;
88 u16 sync_buffer_size;
89 u32 sso;
90 u32 vperiod;
91 struct snd_pcm_substream *substream;
92 struct voice *timing;
93 void __iomem *ctrl_base;
94 void __iomem *wave_base;
95 void __iomem *sync_base;
96 int num;
97};
98
99/* We need four pages to store our wave parameters during a suspend. If
100 * we're not doing power management, we still need to allocate a page
101 * for the silence buffer.
102 */
103#ifdef CONFIG_PM
104#define SIS_SUSPEND_PAGES 4
105#else
106#define SIS_SUSPEND_PAGES 1
107#endif
108
109struct sis7019 {
110 unsigned long ioport;
111 void __iomem *ioaddr;
112 int irq;
113 int codecs_present;
114
115 struct pci_dev *pci;
116 struct snd_pcm *pcm;
117 struct snd_card *card;
118 struct snd_ac97 *ac97[3];
119
120 /* Protect against more than one thread hitting the AC97
121 * registers (in a more polite manner than pounding the hardware
122 * semaphore)
123 */
124 struct mutex ac97_mutex;
125
126 /* voice_lock protects allocation/freeing of the voice descriptions
127 */
128 spinlock_t voice_lock;
129
130 struct voice voices[64];
131 struct voice capture_voice;
132
133 /* Allocate pages to store the internal wave state during
134 * suspends. When we're operating, this can be used as a silence
135 * buffer for a timing channel.
136 */
137 void *suspend_state[SIS_SUSPEND_PAGES];
138
139 int silence_users;
140 dma_addr_t silence_dma_addr;
141};
142
143#define SIS_PRIMARY_CODEC_PRESENT 0x0001
144#define SIS_SECONDARY_CODEC_PRESENT 0x0002
145#define SIS_TERTIARY_CODEC_PRESENT 0x0004
146
147/* The HW offset parameters (Loop End, Stop Sample, End Sample) have a
148 * documented range of 8-0xfff8 samples. Given that they are 0-based,
149 * that places our period/buffer range at 9-0xfff9 samples. That makes the
150 * max buffer size 0xfff9 samples * 2 channels * 2 bytes per sample, and
151 * max samples / min samples gives us the max periods in a buffer.
152 *
153 * We'll add a constraint upon open that limits the period and buffer sample
154 * size to values that are legal for the hardware.
155 */
156static struct snd_pcm_hardware sis_playback_hw_info = {
157 .info = (SNDRV_PCM_INFO_MMAP |
158 SNDRV_PCM_INFO_MMAP_VALID |
159 SNDRV_PCM_INFO_INTERLEAVED |
160 SNDRV_PCM_INFO_BLOCK_TRANSFER |
161 SNDRV_PCM_INFO_SYNC_START |
162 SNDRV_PCM_INFO_RESUME),
163 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
164 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
165 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
166 .rate_min = 4000,
167 .rate_max = 48000,
168 .channels_min = 1,
169 .channels_max = 2,
170 .buffer_bytes_max = (0xfff9 * 4),
171 .period_bytes_min = 9,
172 .period_bytes_max = (0xfff9 * 4),
173 .periods_min = 1,
174 .periods_max = (0xfff9 / 9),
175};
176
177static struct snd_pcm_hardware sis_capture_hw_info = {
178 .info = (SNDRV_PCM_INFO_MMAP |
179 SNDRV_PCM_INFO_MMAP_VALID |
180 SNDRV_PCM_INFO_INTERLEAVED |
181 SNDRV_PCM_INFO_BLOCK_TRANSFER |
182 SNDRV_PCM_INFO_SYNC_START |
183 SNDRV_PCM_INFO_RESUME),
184 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
185 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
186 .rates = SNDRV_PCM_RATE_48000,
187 .rate_min = 4000,
188 .rate_max = 48000,
189 .channels_min = 1,
190 .channels_max = 2,
191 .buffer_bytes_max = (0xfff9 * 4),
192 .period_bytes_min = 9,
193 .period_bytes_max = (0xfff9 * 4),
194 .periods_min = 1,
195 .periods_max = (0xfff9 / 9),
196};
197
198static void sis_update_sso(struct voice *voice, u16 period)
199{
200 void __iomem *base = voice->ctrl_base;
201
202 voice->sso += period;
203 if (voice->sso >= voice->buffer_size)
204 voice->sso -= voice->buffer_size;
205
206 /* Enforce the documented hardware minimum offset */
207 if (voice->sso < 8)
208 voice->sso = 8;
209
210 /* The SSO is in the upper 16 bits of the register. */
211 writew(voice->sso & 0xffff, base + SIS_PLAY_DMA_SSO_ESO + 2);
212}
213
214static void sis_update_voice(struct voice *voice)
215{
216 if (voice->flags & VOICE_SSO_TIMING) {
217 sis_update_sso(voice, voice->period_size);
218 } else if (voice->flags & VOICE_SYNC_TIMING) {
219 int sync;
220
221 /* If we've not hit the end of the virtual period, update
222 * our records and keep going.
223 */
224 if (voice->vperiod > voice->period_size) {
225 voice->vperiod -= voice->period_size;
226 if (voice->vperiod < voice->period_size)
227 sis_update_sso(voice, voice->vperiod);
228 else
229 sis_update_sso(voice, voice->period_size);
230 return;
231 }
232
233 /* Calculate our relative offset between the target and
234 * the actual CSO value. Since we're operating in a loop,
235 * if the value is more than half way around, we can
236 * consider ourselves wrapped.
237 */
238 sync = voice->sync_cso;
239 sync -= readw(voice->sync_base + SIS_CAPTURE_DMA_FORMAT_CSO);
240 if (sync > (voice->sync_buffer_size / 2))
241 sync -= voice->sync_buffer_size;
242
243 /* If sync is positive, then we interrupted too early, and
244 * we'll need to come back in a few samples and try again.
245 * There's a minimum wait, as it takes some time for the DMA
246 * engine to startup, etc...
247 */
248 if (sync > 0) {
249 if (sync < 16)
250 sync = 16;
251 sis_update_sso(voice, sync);
252 return;
253 }
254
255 /* Ok, we interrupted right on time, or (hopefully) just
256 * a bit late. We'll adjst our next waiting period based
257 * on how close we got.
258 *
259 * We need to stay just behind the actual channel to ensure
260 * it really is past a period when we get our interrupt --
261 * otherwise we'll fall into the early code above and have
262 * a minimum wait time, which makes us quite late here,
263 * eating into the user's time to refresh the buffer, esp.
264 * if using small periods.
265 *
266 * If we're less than 9 samples behind, we're on target.
267 */
268 if (sync > -9)
269 voice->vperiod = voice->sync_period_size + 1;
270 else
271 voice->vperiod = voice->sync_period_size - 4;
272
273 if (voice->vperiod < voice->buffer_size) {
274 sis_update_sso(voice, voice->vperiod);
275 voice->vperiod = 0;
276 } else
277 sis_update_sso(voice, voice->period_size);
278
279 sync = voice->sync_cso + voice->sync_period_size;
280 if (sync >= voice->sync_buffer_size)
281 sync -= voice->sync_buffer_size;
282 voice->sync_cso = sync;
283 }
284
285 snd_pcm_period_elapsed(voice->substream);
286}
287
288static void sis_voice_irq(u32 status, struct voice *voice)
289{
290 int bit;
291
292 while (status) {
293 bit = __ffs(status);
294 status >>= bit + 1;
295 voice += bit;
296 sis_update_voice(voice);
297 voice++;
298 }
299}
300
301static irqreturn_t sis_interrupt(int irq, void *dev)
302{
303 struct sis7019 *sis = dev;
304 unsigned long io = sis->ioport;
305 struct voice *voice;
306 u32 intr, status;
307
308 /* We only use the DMA interrupts, and we don't enable any other
309 * source of interrupts. But, it is possible to see an interupt
310 * status that didn't actually interrupt us, so eliminate anything
311 * we're not expecting to avoid falsely claiming an IRQ, and an
312 * ensuing endless loop.
313 */
314 intr = inl(io + SIS_GISR);
315 intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
316 SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
317 if (!intr)
318 return IRQ_NONE;
319
320 do {
321 status = inl(io + SIS_PISR_A);
322 if (status) {
323 sis_voice_irq(status, sis->voices);
324 outl(status, io + SIS_PISR_A);
325 }
326
327 status = inl(io + SIS_PISR_B);
328 if (status) {
329 sis_voice_irq(status, &sis->voices[32]);
330 outl(status, io + SIS_PISR_B);
331 }
332
333 status = inl(io + SIS_RISR);
334 if (status) {
335 voice = &sis->capture_voice;
336 if (!voice->timing)
337 snd_pcm_period_elapsed(voice->substream);
338
339 outl(status, io + SIS_RISR);
340 }
341
342 outl(intr, io + SIS_GISR);
343 intr = inl(io + SIS_GISR);
344 intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
345 SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
346 } while (intr);
347
348 return IRQ_HANDLED;
349}
350
351static u32 sis_rate_to_delta(unsigned int rate)
352{
353 u32 delta;
354
355 /* This was copied from the trident driver, but it seems its gotten
356 * around a bit... nevertheless, it works well.
357 *
358 * We special case 44100 and 8000 since rounding with the equation
359 * does not give us an accurate enough value. For 11025 and 22050
360 * the equation gives us the best answer. All other frequencies will
361 * also use the equation. JDW
362 */
363 if (rate == 44100)
364 delta = 0xeb3;
365 else if (rate == 8000)
366 delta = 0x2ab;
367 else if (rate == 48000)
368 delta = 0x1000;
369 else
370 delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
371 return delta;
372}
373
374static void __sis_map_silence(struct sis7019 *sis)
375{
376 /* Helper function: must hold sis->voice_lock on entry */
377 if (!sis->silence_users)
378 sis->silence_dma_addr = pci_map_single(sis->pci,
379 sis->suspend_state[0],
380 4096, PCI_DMA_TODEVICE);
381 sis->silence_users++;
382}
383
384static void __sis_unmap_silence(struct sis7019 *sis)
385{
386 /* Helper function: must hold sis->voice_lock on entry */
387 sis->silence_users--;
388 if (!sis->silence_users)
389 pci_unmap_single(sis->pci, sis->silence_dma_addr, 4096,
390 PCI_DMA_TODEVICE);
391}
392
393static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
394{
395 unsigned long flags;
396
397 spin_lock_irqsave(&sis->voice_lock, flags);
398 if (voice->timing) {
399 __sis_unmap_silence(sis);
400 voice->timing->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING |
401 VOICE_SYNC_TIMING);
402 voice->timing = NULL;
403 }
404 voice->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING | VOICE_SYNC_TIMING);
405 spin_unlock_irqrestore(&sis->voice_lock, flags);
406}
407
408static struct voice *__sis_alloc_playback_voice(struct sis7019 *sis)
409{
410 /* Must hold the voice_lock on entry */
411 struct voice *voice;
412 int i;
413
414 for (i = 0; i < 64; i++) {
415 voice = &sis->voices[i];
416 if (voice->flags & VOICE_IN_USE)
417 continue;
418 voice->flags |= VOICE_IN_USE;
419 goto found_one;
420 }
421 voice = NULL;
422
423found_one:
424 return voice;
425}
426
427static struct voice *sis_alloc_playback_voice(struct sis7019 *sis)
428{
429 struct voice *voice;
430 unsigned long flags;
431
432 spin_lock_irqsave(&sis->voice_lock, flags);
433 voice = __sis_alloc_playback_voice(sis);
434 spin_unlock_irqrestore(&sis->voice_lock, flags);
435
436 return voice;
437}
438
439static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
440 struct snd_pcm_hw_params *hw_params)
441{
442 struct sis7019 *sis = snd_pcm_substream_chip(substream);
443 struct snd_pcm_runtime *runtime = substream->runtime;
444 struct voice *voice = runtime->private_data;
445 unsigned int period_size, buffer_size;
446 unsigned long flags;
447 int needed;
448
449 /* If there are one or two periods per buffer, we don't need a
450 * timing voice, as we can use the capture channel's interrupts
451 * to clock out the periods.
452 */
453 period_size = params_period_size(hw_params);
454 buffer_size = params_buffer_size(hw_params);
455 needed = (period_size != buffer_size &&
456 period_size != (buffer_size / 2));
457
458 if (needed && !voice->timing) {
459 spin_lock_irqsave(&sis->voice_lock, flags);
460 voice->timing = __sis_alloc_playback_voice(sis);
461 if (voice->timing)
462 __sis_map_silence(sis);
463 spin_unlock_irqrestore(&sis->voice_lock, flags);
464 if (!voice->timing)
465 return -ENOMEM;
466 voice->timing->substream = substream;
467 } else if (!needed && voice->timing) {
468 sis_free_voice(sis, voice);
469 voice->timing = NULL;
470 }
471
472 return 0;
473}
474
475static int sis_playback_open(struct snd_pcm_substream *substream)
476{
477 struct sis7019 *sis = snd_pcm_substream_chip(substream);
478 struct snd_pcm_runtime *runtime = substream->runtime;
479 struct voice *voice;
480
481 voice = sis_alloc_playback_voice(sis);
482 if (!voice)
483 return -EAGAIN;
484
485 voice->substream = substream;
486 runtime->private_data = voice;
487 runtime->hw = sis_playback_hw_info;
488 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
489 9, 0xfff9);
490 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
491 9, 0xfff9);
492 snd_pcm_set_sync(substream);
493 return 0;
494}
495
496static int sis_substream_close(struct snd_pcm_substream *substream)
497{
498 struct sis7019 *sis = snd_pcm_substream_chip(substream);
499 struct snd_pcm_runtime *runtime = substream->runtime;
500 struct voice *voice = runtime->private_data;
501
502 sis_free_voice(sis, voice);
503 return 0;
504}
505
506static int sis_playback_hw_params(struct snd_pcm_substream *substream,
507 struct snd_pcm_hw_params *hw_params)
508{
509 return snd_pcm_lib_malloc_pages(substream,
510 params_buffer_bytes(hw_params));
511}
512
513static int sis_hw_free(struct snd_pcm_substream *substream)
514{
515 return snd_pcm_lib_free_pages(substream);
516}
517
518static int sis_pcm_playback_prepare(struct snd_pcm_substream *substream)
519{
520 struct snd_pcm_runtime *runtime = substream->runtime;
521 struct voice *voice = runtime->private_data;
522 void __iomem *ctrl_base = voice->ctrl_base;
523 void __iomem *wave_base = voice->wave_base;
524 u32 format, dma_addr, control, sso_eso, delta, reg;
525 u16 leo;
526
527 /* We rely on the PCM core to ensure that the parameters for this
528 * substream do not change on us while we're programming the HW.
529 */
530 format = 0;
531 if (snd_pcm_format_width(runtime->format) == 8)
532 format |= SIS_PLAY_DMA_FORMAT_8BIT;
533 if (!snd_pcm_format_signed(runtime->format))
534 format |= SIS_PLAY_DMA_FORMAT_UNSIGNED;
535 if (runtime->channels == 1)
536 format |= SIS_PLAY_DMA_FORMAT_MONO;
537
538 /* The baseline setup is for a single period per buffer, and
539 * we add bells and whistles as needed from there.
540 */
541 dma_addr = runtime->dma_addr;
542 leo = runtime->buffer_size - 1;
543 control = leo | SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_LEO;
544 sso_eso = leo;
545
546 if (runtime->period_size == (runtime->buffer_size / 2)) {
547 control |= SIS_PLAY_DMA_INTR_AT_MLP;
548 } else if (runtime->period_size != runtime->buffer_size) {
549 voice->flags |= VOICE_SSO_TIMING;
550 voice->sso = runtime->period_size - 1;
551 voice->period_size = runtime->period_size;
552 voice->buffer_size = runtime->buffer_size;
553
554 control &= ~SIS_PLAY_DMA_INTR_AT_LEO;
555 control |= SIS_PLAY_DMA_INTR_AT_SSO;
556 sso_eso |= (runtime->period_size - 1) << 16;
557 }
558
559 delta = sis_rate_to_delta(runtime->rate);
560
561 /* Ok, we're ready to go, set up the channel.
562 */
563 writel(format, ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
564 writel(dma_addr, ctrl_base + SIS_PLAY_DMA_BASE);
565 writel(control, ctrl_base + SIS_PLAY_DMA_CONTROL);
566 writel(sso_eso, ctrl_base + SIS_PLAY_DMA_SSO_ESO);
567
568 for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
569 writel(0, wave_base + reg);
570
571 writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
572 writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
573 writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
574 SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
575 SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
576 wave_base + SIS_WAVE_CHANNEL_CONTROL);
577
578 /* Force PCI writes to post. */
579 readl(ctrl_base);
580
581 return 0;
582}
583
584static int sis_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
585{
586 struct sis7019 *sis = snd_pcm_substream_chip(substream);
587 unsigned long io = sis->ioport;
588 struct snd_pcm_substream *s;
589 struct voice *voice;
590 void *chip;
591 int starting;
592 u32 record = 0;
593 u32 play[2] = { 0, 0 };
594
595 /* No locks needed, as the PCM core will hold the locks on the
596 * substreams, and the HW will only start/stop the indicated voices
597 * without changing the state of the others.
598 */
599 switch (cmd) {
600 case SNDRV_PCM_TRIGGER_START:
601 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
602 case SNDRV_PCM_TRIGGER_RESUME:
603 starting = 1;
604 break;
605 case SNDRV_PCM_TRIGGER_STOP:
606 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
607 case SNDRV_PCM_TRIGGER_SUSPEND:
608 starting = 0;
609 break;
610 default:
611 return -EINVAL;
612 }
613
614 snd_pcm_group_for_each_entry(s, substream) {
615 /* Make sure it is for us... */
616 chip = snd_pcm_substream_chip(s);
617 if (chip != sis)
618 continue;
619
620 voice = s->runtime->private_data;
621 if (voice->flags & VOICE_CAPTURE) {
622 record |= 1 << voice->num;
623 voice = voice->timing;
624 }
625
626 /* voice could be NULL if this a recording stream, and it
627 * doesn't have an external timing channel.
628 */
629 if (voice)
630 play[voice->num / 32] |= 1 << (voice->num & 0x1f);
631
632 snd_pcm_trigger_done(s, substream);
633 }
634
635 if (starting) {
636 if (record)
637 outl(record, io + SIS_RECORD_START_REG);
638 if (play[0])
639 outl(play[0], io + SIS_PLAY_START_A_REG);
640 if (play[1])
641 outl(play[1], io + SIS_PLAY_START_B_REG);
642 } else {
643 if (record)
644 outl(record, io + SIS_RECORD_STOP_REG);
645 if (play[0])
646 outl(play[0], io + SIS_PLAY_STOP_A_REG);
647 if (play[1])
648 outl(play[1], io + SIS_PLAY_STOP_B_REG);
649 }
650 return 0;
651}
652
653static snd_pcm_uframes_t sis_pcm_pointer(struct snd_pcm_substream *substream)
654{
655 struct snd_pcm_runtime *runtime = substream->runtime;
656 struct voice *voice = runtime->private_data;
657 u32 cso;
658
659 cso = readl(voice->ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
660 cso &= 0xffff;
661 return cso;
662}
663
664static int sis_capture_open(struct snd_pcm_substream *substream)
665{
666 struct sis7019 *sis = snd_pcm_substream_chip(substream);
667 struct snd_pcm_runtime *runtime = substream->runtime;
668 struct voice *voice = &sis->capture_voice;
669 unsigned long flags;
670
671 /* FIXME: The driver only supports recording from one channel
672 * at the moment, but it could support more.
673 */
674 spin_lock_irqsave(&sis->voice_lock, flags);
675 if (voice->flags & VOICE_IN_USE)
676 voice = NULL;
677 else
678 voice->flags |= VOICE_IN_USE;
679 spin_unlock_irqrestore(&sis->voice_lock, flags);
680
681 if (!voice)
682 return -EAGAIN;
683
684 voice->substream = substream;
685 runtime->private_data = voice;
686 runtime->hw = sis_capture_hw_info;
687 runtime->hw.rates = sis->ac97[0]->rates[AC97_RATES_ADC];
688 snd_pcm_limit_hw_rates(runtime);
689 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
690 9, 0xfff9);
691 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
692 9, 0xfff9);
693 snd_pcm_set_sync(substream);
694 return 0;
695}
696
697static int sis_capture_hw_params(struct snd_pcm_substream *substream,
698 struct snd_pcm_hw_params *hw_params)
699{
700 struct sis7019 *sis = snd_pcm_substream_chip(substream);
701 int rc;
702
703 rc = snd_ac97_set_rate(sis->ac97[0], AC97_PCM_LR_ADC_RATE,
704 params_rate(hw_params));
705 if (rc)
706 goto out;
707
708 rc = snd_pcm_lib_malloc_pages(substream,
709 params_buffer_bytes(hw_params));
710 if (rc < 0)
711 goto out;
712
713 rc = sis_alloc_timing_voice(substream, hw_params);
714
715out:
716 return rc;
717}
718
719static void sis_prepare_timing_voice(struct voice *voice,
720 struct snd_pcm_substream *substream)
721{
722 struct sis7019 *sis = snd_pcm_substream_chip(substream);
723 struct snd_pcm_runtime *runtime = substream->runtime;
724 struct voice *timing = voice->timing;
725 void __iomem *play_base = timing->ctrl_base;
726 void __iomem *wave_base = timing->wave_base;
727 u16 buffer_size, period_size;
728 u32 format, control, sso_eso, delta;
729 u32 vperiod, sso, reg;
730
731 /* Set our initial buffer and period as large as we can given a
732 * single page of silence.
733 */
734 buffer_size = 4096 / runtime->channels;
735 buffer_size /= snd_pcm_format_size(runtime->format, 1);
736 period_size = buffer_size;
737
738 /* Initially, we want to interrupt just a bit behind the end of
739 * the period we're clocking out. 10 samples seems to give a good
740 * delay.
741 *
742 * We want to spread our interrupts throughout the virtual period,
743 * so that we don't end up with two interrupts back to back at the
744 * end -- this helps minimize the effects of any jitter. Adjust our
745 * clocking period size so that the last period is at least a fourth
746 * of a full period.
747 *
748 * This is all moot if we don't need to use virtual periods.
749 */
750 vperiod = runtime->period_size + 10;
751 if (vperiod > period_size) {
752 u16 tail = vperiod % period_size;
753 u16 quarter_period = period_size / 4;
754
755 if (tail && tail < quarter_period) {
756 u16 loops = vperiod / period_size;
757
758 tail = quarter_period - tail;
759 tail += loops - 1;
760 tail /= loops;
761 period_size -= tail;
762 }
763
764 sso = period_size - 1;
765 } else {
766 /* The initial period will fit inside the buffer, so we
767 * don't need to use virtual periods -- disable them.
768 */
769 period_size = runtime->period_size;
770 sso = vperiod - 1;
771 vperiod = 0;
772 }
773
774 /* The interrupt handler implements the timing syncronization, so
775 * setup its state.
776 */
777 timing->flags |= VOICE_SYNC_TIMING;
778 timing->sync_base = voice->ctrl_base;
779 timing->sync_cso = runtime->period_size - 1;
780 timing->sync_period_size = runtime->period_size;
781 timing->sync_buffer_size = runtime->buffer_size;
782 timing->period_size = period_size;
783 timing->buffer_size = buffer_size;
784 timing->sso = sso;
785 timing->vperiod = vperiod;
786
787 /* Using unsigned samples with the all-zero silence buffer
788 * forces the output to the lower rail, killing playback.
789 * So ignore unsigned vs signed -- it doesn't change the timing.
790 */
791 format = 0;
792 if (snd_pcm_format_width(runtime->format) == 8)
793 format = SIS_CAPTURE_DMA_FORMAT_8BIT;
794 if (runtime->channels == 1)
795 format |= SIS_CAPTURE_DMA_FORMAT_MONO;
796
797 control = timing->buffer_size - 1;
798 control |= SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_SSO;
799 sso_eso = timing->buffer_size - 1;
800 sso_eso |= timing->sso << 16;
801
802 delta = sis_rate_to_delta(runtime->rate);
803
804 /* We've done the math, now configure the channel.
805 */
806 writel(format, play_base + SIS_PLAY_DMA_FORMAT_CSO);
807 writel(sis->silence_dma_addr, play_base + SIS_PLAY_DMA_BASE);
808 writel(control, play_base + SIS_PLAY_DMA_CONTROL);
809 writel(sso_eso, play_base + SIS_PLAY_DMA_SSO_ESO);
810
811 for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
812 writel(0, wave_base + reg);
813
814 writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
815 writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
816 writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
817 SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
818 SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
819 wave_base + SIS_WAVE_CHANNEL_CONTROL);
820}
821
822static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream)
823{
824 struct snd_pcm_runtime *runtime = substream->runtime;
825 struct voice *voice = runtime->private_data;
826 void __iomem *rec_base = voice->ctrl_base;
827 u32 format, dma_addr, control;
828 u16 leo;
829
830 /* We rely on the PCM core to ensure that the parameters for this
831 * substream do not change on us while we're programming the HW.
832 */
833 format = 0;
834 if (snd_pcm_format_width(runtime->format) == 8)
835 format = SIS_CAPTURE_DMA_FORMAT_8BIT;
836 if (!snd_pcm_format_signed(runtime->format))
837 format |= SIS_CAPTURE_DMA_FORMAT_UNSIGNED;
838 if (runtime->channels == 1)
839 format |= SIS_CAPTURE_DMA_FORMAT_MONO;
840
841 dma_addr = runtime->dma_addr;
842 leo = runtime->buffer_size - 1;
843 control = leo | SIS_CAPTURE_DMA_LOOP;
844
845 /* If we've got more than two periods per buffer, then we have
846 * use a timing voice to clock out the periods. Otherwise, we can
847 * use the capture channel's interrupts.
848 */
849 if (voice->timing) {
850 sis_prepare_timing_voice(voice, substream);
851 } else {
852 control |= SIS_CAPTURE_DMA_INTR_AT_LEO;
853 if (runtime->period_size != runtime->buffer_size)
854 control |= SIS_CAPTURE_DMA_INTR_AT_MLP;
855 }
856
857 writel(format, rec_base + SIS_CAPTURE_DMA_FORMAT_CSO);
858 writel(dma_addr, rec_base + SIS_CAPTURE_DMA_BASE);
859 writel(control, rec_base + SIS_CAPTURE_DMA_CONTROL);
860
861 /* Force the writes to post. */
862 readl(rec_base);
863
864 return 0;
865}
866
867static struct snd_pcm_ops sis_playback_ops = {
868 .open = sis_playback_open,
869 .close = sis_substream_close,
870 .ioctl = snd_pcm_lib_ioctl,
871 .hw_params = sis_playback_hw_params,
872 .hw_free = sis_hw_free,
873 .prepare = sis_pcm_playback_prepare,
874 .trigger = sis_pcm_trigger,
875 .pointer = sis_pcm_pointer,
876};
877
878static struct snd_pcm_ops sis_capture_ops = {
879 .open = sis_capture_open,
880 .close = sis_substream_close,
881 .ioctl = snd_pcm_lib_ioctl,
882 .hw_params = sis_capture_hw_params,
883 .hw_free = sis_hw_free,
884 .prepare = sis_pcm_capture_prepare,
885 .trigger = sis_pcm_trigger,
886 .pointer = sis_pcm_pointer,
887};
888
889static int __devinit sis_pcm_create(struct sis7019 *sis)
890{
891 struct snd_pcm *pcm;
892 int rc;
893
894 /* We have 64 voices, and the driver currently records from
895 * only one channel, though that could change in the future.
896 */
897 rc = snd_pcm_new(sis->card, "SiS7019", 0, 64, 1, &pcm);
898 if (rc)
899 return rc;
900
901 pcm->private_data = sis;
902 strcpy(pcm->name, "SiS7019");
903 sis->pcm = pcm;
904
905 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &sis_playback_ops);
906 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &sis_capture_ops);
907
908 /* Try to preallocate some memory, but it's not the end of the
909 * world if this fails.
910 */
911 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
912 snd_dma_pci_data(sis->pci), 64*1024, 128*1024);
913
914 return 0;
915}
916
917static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
918{
919 unsigned long io = sis->ioport;
920 unsigned short val = 0xffff;
921 u16 status;
922 u16 rdy;
923 int count;
924 const static u16 codec_ready[3] = {
925 SIS_AC97_STATUS_CODEC_READY,
926 SIS_AC97_STATUS_CODEC2_READY,
927 SIS_AC97_STATUS_CODEC3_READY,
928 };
929
930 rdy = codec_ready[codec];
931
932
933 /* Get the AC97 semaphore -- software first, so we don't spin
934 * pounding out IO reads on the hardware semaphore...
935 */
936 mutex_lock(&sis->ac97_mutex);
937
938 count = 0xffff;
939 while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
940 udelay(1);
941
942 if (!count)
943 goto timeout;
944
945 /* ... and wait for any outstanding commands to complete ...
946 */
947 count = 0xffff;
948 do {
949 status = inw(io + SIS_AC97_STATUS);
950 if ((status & rdy) && !(status & SIS_AC97_STATUS_BUSY))
951 break;
952
953 udelay(1);
954 } while (--count);
955
956 if (!count)
957 goto timeout_sema;
958
959 /* ... before sending our command and waiting for it to finish ...
960 */
961 outl(cmd, io + SIS_AC97_CMD);
962 udelay(10);
963
964 count = 0xffff;
965 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
966 udelay(1);
967
968 /* ... and reading the results (if any).
969 */
970 val = inl(io + SIS_AC97_CMD) >> 16;
971
972timeout_sema:
973 outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
974timeout:
975 mutex_unlock(&sis->ac97_mutex);
976
977 if (!count) {
978 printk(KERN_ERR "sis7019: ac97 codec %d timeout cmd 0x%08x\n",
979 codec, cmd);
980 }
981
982 return val;
983}
984
985static void sis_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
986 unsigned short val)
987{
988 const static u32 cmd[3] = {
989 SIS_AC97_CMD_CODEC_WRITE,
990 SIS_AC97_CMD_CODEC2_WRITE,
991 SIS_AC97_CMD_CODEC3_WRITE,
992 };
993 sis_ac97_rw(ac97->private_data, ac97->num,
994 (val << 16) | (reg << 8) | cmd[ac97->num]);
995}
996
997static unsigned short sis_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
998{
999 const static u32 cmd[3] = {
1000 SIS_AC97_CMD_CODEC_READ,
1001 SIS_AC97_CMD_CODEC2_READ,
1002 SIS_AC97_CMD_CODEC3_READ,
1003 };
1004 return sis_ac97_rw(ac97->private_data, ac97->num,
1005 (reg << 8) | cmd[ac97->num]);
1006}
1007
1008static int __devinit sis_mixer_create(struct sis7019 *sis)
1009{
1010 struct snd_ac97_bus *bus;
1011 struct snd_ac97_template ac97;
1012 static struct snd_ac97_bus_ops ops = {
1013 .write = sis_ac97_write,
1014 .read = sis_ac97_read,
1015 };
1016 int rc;
1017
1018 memset(&ac97, 0, sizeof(ac97));
1019 ac97.private_data = sis;
1020
1021 rc = snd_ac97_bus(sis->card, 0, &ops, NULL, &bus);
1022 if (!rc && sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
1023 rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[0]);
1024 ac97.num = 1;
1025 if (!rc && (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT))
1026 rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[1]);
1027 ac97.num = 2;
1028 if (!rc && (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT))
1029 rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[2]);
1030
1031 /* If we return an error here, then snd_card_free() should
1032 * free up any ac97 codecs that got created, as well as the bus.
1033 */
1034 return rc;
1035}
1036
1037static void sis_free_suspend(struct sis7019 *sis)
1038{
1039 int i;
1040
1041 for (i = 0; i < SIS_SUSPEND_PAGES; i++)
1042 kfree(sis->suspend_state[i]);
1043}
1044
1045static int sis_chip_free(struct sis7019 *sis)
1046{
1047 /* Reset the chip, and disable all interrputs.
1048 */
1049 outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
1050 udelay(10);
1051 outl(0, sis->ioport + SIS_GCR);
1052 outl(0, sis->ioport + SIS_GIER);
1053
1054 /* Now, free everything we allocated.
1055 */
1056 if (sis->irq >= 0)
1057 free_irq(sis->irq, sis);
1058
1059 if (sis->ioaddr)
1060 iounmap(sis->ioaddr);
1061
1062 pci_release_regions(sis->pci);
1063 pci_disable_device(sis->pci);
1064
1065 sis_free_suspend(sis);
1066 return 0;
1067}
1068
1069static int sis_dev_free(struct snd_device *dev)
1070{
1071 struct sis7019 *sis = dev->device_data;
1072 return sis_chip_free(sis);
1073}
1074
1075static int sis_chip_init(struct sis7019 *sis)
1076{
1077 unsigned long io = sis->ioport;
1078 void __iomem *ioaddr = sis->ioaddr;
1079 u16 status;
1080 int count;
1081 int i;
1082
1083 /* Reset the audio controller
1084 */
1085 outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
1086 udelay(10);
1087 outl(0, io + SIS_GCR);
1088
1089 /* Get the AC-link semaphore, and reset the codecs
1090 */
1091 count = 0xffff;
1092 while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
1093 udelay(1);
1094
1095 if (!count)
1096 return -EIO;
1097
1098 outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
1099 udelay(10);
1100
1101 count = 0xffff;
1102 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
1103 udelay(1);
1104
1105 /* Now that we've finished the reset, find out what's attached.
1106 */
1107 status = inl(io + SIS_AC97_STATUS);
1108 if (status & SIS_AC97_STATUS_CODEC_READY)
1109 sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
1110 if (status & SIS_AC97_STATUS_CODEC2_READY)
1111 sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
1112 if (status & SIS_AC97_STATUS_CODEC3_READY)
1113 sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
1114
1115 /* All done, let go of the semaphore, and check for errors
1116 */
1117 outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
1118 if (!sis->codecs_present || !count)
1119 return -EIO;
1120
1121 /* Let the hardware know that the audio driver is alive,
1122 * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
1123 * record channels. We're going to want to use Variable Rate Audio
1124 * for recording, to avoid needlessly resampling from 48kHZ.
1125 */
1126 outl(SIS_AC97_CONF_AUDIO_ALIVE, io + SIS_AC97_CONF);
1127 outl(SIS_AC97_CONF_AUDIO_ALIVE | SIS_AC97_CONF_PCM_LR_ENABLE |
1128 SIS_AC97_CONF_PCM_CAP_MIC_ENABLE |
1129 SIS_AC97_CONF_PCM_CAP_LR_ENABLE |
1130 SIS_AC97_CONF_CODEC_VRA_ENABLE, io + SIS_AC97_CONF);
1131
1132 /* All AC97 PCM slots should be sourced from sub-mixer 0.
1133 */
1134 outl(0, io + SIS_AC97_PSR);
1135
1136 /* There is only one valid DMA setup for a PCI environment.
1137 */
1138 outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);
1139
1140 /* Reset the syncronization groups for all of the channels
1141 * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc.
1142 * we'll need to change how we handle these. Until then, we just
1143 * assign sub-mixer 0 to all playback channels, and avoid any
1144 * attenuation on the audio.
1145 */
1146 outl(0, io + SIS_PLAY_SYNC_GROUP_A);
1147 outl(0, io + SIS_PLAY_SYNC_GROUP_B);
1148 outl(0, io + SIS_PLAY_SYNC_GROUP_C);
1149 outl(0, io + SIS_PLAY_SYNC_GROUP_D);
1150 outl(0, io + SIS_MIXER_SYNC_GROUP);
1151
1152 for (i = 0; i < 64; i++) {
1153 writel(i, SIS_MIXER_START_ADDR(ioaddr, i));
1154 writel(SIS_MIXER_RIGHT_NO_ATTEN | SIS_MIXER_LEFT_NO_ATTEN |
1155 SIS_MIXER_DEST_0, SIS_MIXER_ADDR(ioaddr, i));
1156 }
1157
1158 /* Don't attenuate any audio set for the wave amplifier.
1159 *
1160 * FIXME: Maximum attenuation is set for the music amp, which will
1161 * need to change if we start using the synth engine.
1162 */
1163 outl(0xffff0000, io + SIS_WEVCR);
1164
1165 /* Ensure that the wave engine is in normal operating mode.
1166 */
1167 outl(0, io + SIS_WECCR);
1168
1169 /* Go ahead and enable the DMA interrupts. They won't go live
1170 * until we start a channel.
1171 */
1172 outl(SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE |
1173 SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE, io + SIS_GIER);
1174
1175 return 0;
1176}
1177
1178#ifdef CONFIG_PM
1179static int sis_suspend(struct pci_dev *pci, pm_message_t state)
1180{
1181 struct snd_card *card = pci_get_drvdata(pci);
1182 struct sis7019 *sis = card->private_data;
1183 void __iomem *ioaddr = sis->ioaddr;
1184 int i;
1185
1186 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1187 snd_pcm_suspend_all(sis->pcm);
1188 if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
1189 snd_ac97_suspend(sis->ac97[0]);
1190 if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
1191 snd_ac97_suspend(sis->ac97[1]);
1192 if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
1193 snd_ac97_suspend(sis->ac97[2]);
1194
1195 /* snd_pcm_suspend_all() stopped all channels, so we're quiescent.
1196 */
1197 if (sis->irq >= 0) {
1198 synchronize_irq(sis->irq);
1199 free_irq(sis->irq, sis);
1200 sis->irq = -1;
1201 }
1202
1203 /* Save the internal state away
1204 */
1205 for (i = 0; i < 4; i++) {
1206 memcpy_fromio(sis->suspend_state[i], ioaddr, 4096);
1207 ioaddr += 4096;
1208 }
1209
1210 pci_disable_device(pci);
1211 pci_save_state(pci);
1212 pci_set_power_state(pci, pci_choose_state(pci, state));
1213 return 0;
1214}
1215
1216static int sis_resume(struct pci_dev *pci)
1217{
1218 struct snd_card *card = pci_get_drvdata(pci);
1219 struct sis7019 *sis = card->private_data;
1220 void __iomem *ioaddr = sis->ioaddr;
1221 int i;
1222
1223 pci_set_power_state(pci, PCI_D0);
1224 pci_restore_state(pci);
1225
1226 if (pci_enable_device(pci) < 0) {
1227 printk(KERN_ERR "sis7019: unable to re-enable device\n");
1228 goto error;
1229 }
1230
1231 if (sis_chip_init(sis)) {
1232 printk(KERN_ERR "sis7019: unable to re-init controller\n");
1233 goto error;
1234 }
1235
1236 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
1237 card->shortname, sis)) {
1238 printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
1239 goto error;
1240 }
1241
1242 /* Restore saved state, then clear out the page we use for the
1243 * silence buffer.
1244 */
1245 for (i = 0; i < 4; i++) {
1246 memcpy_toio(ioaddr, sis->suspend_state[i], 4096);
1247 ioaddr += 4096;
1248 }
1249
1250 memset(sis->suspend_state[0], 0, 4096);
1251
1252 sis->irq = pci->irq;
1253 pci_set_master(pci);
1254
1255 if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
1256 snd_ac97_resume(sis->ac97[0]);
1257 if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
1258 snd_ac97_resume(sis->ac97[1]);
1259 if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
1260 snd_ac97_resume(sis->ac97[2]);
1261
1262 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1263 return 0;
1264
1265error:
1266 snd_card_disconnect(card);
1267 return -EIO;
1268}
1269#endif /* CONFIG_PM */
1270
1271static int sis_alloc_suspend(struct sis7019 *sis)
1272{
1273 int i;
1274
1275 /* We need 16K to store the internal wave engine state during a
1276 * suspend, but we don't need it to be contiguous, so play nice
1277 * with the memory system. We'll also use this area for a silence
1278 * buffer.
1279 */
1280 for (i = 0; i < SIS_SUSPEND_PAGES; i++) {
1281 sis->suspend_state[i] = kmalloc(4096, GFP_KERNEL);
1282 if (!sis->suspend_state[i])
1283 return -ENOMEM;
1284 }
1285 memset(sis->suspend_state[0], 0, 4096);
1286
1287 return 0;
1288}
1289
1290static int __devinit sis_chip_create(struct snd_card *card,
1291 struct pci_dev *pci)
1292{
1293 struct sis7019 *sis = card->private_data;
1294 struct voice *voice;
1295 static struct snd_device_ops ops = {
1296 .dev_free = sis_dev_free,
1297 };
1298 int rc;
1299 int i;
1300
1301 rc = pci_enable_device(pci);
1302 if (rc)
1303 goto error_out;
1304
1305 if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0) {
1306 printk(KERN_ERR "sis7019: architecture does not support "
1307 "30-bit PCI busmaster DMA");
1308 goto error_out_enabled;
1309 }
1310
1311 memset(sis, 0, sizeof(*sis));
1312 mutex_init(&sis->ac97_mutex);
1313 spin_lock_init(&sis->voice_lock);
1314 sis->card = card;
1315 sis->pci = pci;
1316 sis->irq = -1;
1317 sis->ioport = pci_resource_start(pci, 0);
1318
1319 rc = pci_request_regions(pci, "SiS7019");
1320 if (rc) {
1321 printk(KERN_ERR "sis7019: unable request regions\n");
1322 goto error_out_enabled;
1323 }
1324
1325 rc = -EIO;
1326 sis->ioaddr = ioremap_nocache(pci_resource_start(pci, 1), 0x4000);
1327 if (!sis->ioaddr) {
1328 printk(KERN_ERR "sis7019: unable to remap MMIO, aborting\n");
1329 goto error_out_cleanup;
1330 }
1331
1332 rc = sis_alloc_suspend(sis);
1333 if (rc < 0) {
1334 printk(KERN_ERR "sis7019: unable to allocate state storage\n");
1335 goto error_out_cleanup;
1336 }
1337
1338 rc = sis_chip_init(sis);
1339 if (rc)
1340 goto error_out_cleanup;
1341
1342 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
1343 card->shortname, sis)) {
1344 printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
1345 goto error_out_cleanup;
1346 }
1347
1348 sis->irq = pci->irq;
1349 pci_set_master(pci);
1350
1351 for (i = 0; i < 64; i++) {
1352 voice = &sis->voices[i];
1353 voice->num = i;
1354 voice->ctrl_base = SIS_PLAY_DMA_ADDR(sis->ioaddr, i);
1355 voice->wave_base = SIS_WAVE_ADDR(sis->ioaddr, i);
1356 }
1357
1358 voice = &sis->capture_voice;
1359 voice->flags = VOICE_CAPTURE;
1360 voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN;
1361 voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num);
1362
1363 rc = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sis, &ops);
1364 if (rc)
1365 goto error_out_cleanup;
1366
1367 snd_card_set_dev(card, &pci->dev);
1368
1369 return 0;
1370
1371error_out_cleanup:
1372 sis_chip_free(sis);
1373
1374error_out_enabled:
1375 pci_disable_device(pci);
1376
1377error_out:
1378 return rc;
1379}
1380
1381static int __devinit snd_sis7019_probe(struct pci_dev *pci,
1382 const struct pci_device_id *pci_id)
1383{
1384 struct snd_card *card;
1385 struct sis7019 *sis;
1386 int rc;
1387
1388 rc = -ENOENT;
1389 if (!enable)
1390 goto error_out;
1391
1392 rc = -ENOMEM;
1393 card = snd_card_new(index, id, THIS_MODULE, sizeof(*sis));
1394 if (!card)
1395 goto error_out;
1396
1397 strcpy(card->driver, "SiS7019");
1398 strcpy(card->shortname, "SiS7019");
1399 rc = sis_chip_create(card, pci);
1400 if (rc)
1401 goto card_error_out;
1402
1403 sis = card->private_data;
1404
1405 rc = sis_mixer_create(sis);
1406 if (rc)
1407 goto card_error_out;
1408
1409 rc = sis_pcm_create(sis);
1410 if (rc)
1411 goto card_error_out;
1412
1413 snprintf(card->longname, sizeof(card->longname),
1414 "%s Audio Accelerator with %s at 0x%lx, irq %d",
1415 card->shortname, snd_ac97_get_short_name(sis->ac97[0]),
1416 sis->ioport, sis->irq);
1417
1418 rc = snd_card_register(card);
1419 if (rc)
1420 goto card_error_out;
1421
1422 pci_set_drvdata(pci, card);
1423 return 0;
1424
1425card_error_out:
1426 snd_card_free(card);
1427
1428error_out:
1429 return rc;
1430}
1431
1432static void __devexit snd_sis7019_remove(struct pci_dev *pci)
1433{
1434 snd_card_free(pci_get_drvdata(pci));
1435 pci_set_drvdata(pci, NULL);
1436}
1437
1438static struct pci_driver sis7019_driver = {
1439 .name = "SiS7019",
1440 .id_table = snd_sis7019_ids,
1441 .probe = snd_sis7019_probe,
1442 .remove = __devexit_p(snd_sis7019_remove),
1443
1444#ifdef CONFIG_PM
1445 .suspend = sis_suspend,
1446 .resume = sis_resume,
1447#endif
1448};
1449
1450static int __init sis7019_init(void)
1451{
1452 return pci_register_driver(&sis7019_driver);
1453}
1454
1455static void __exit sis7019_exit(void)
1456{
1457 pci_unregister_driver(&sis7019_driver);
1458}
1459
1460module_init(sis7019_init);
1461module_exit(sis7019_exit);
diff --git a/sound/pci/sis7019.h b/sound/pci/sis7019.h
new file mode 100644
index 000000000000..013b6739a742
--- /dev/null
+++ b/sound/pci/sis7019.h
@@ -0,0 +1,342 @@
1#ifndef __sis7019_h__
2#define __sis7019_h__
3
4/*
5 * Definitions for SiS7019 Audio Accelerator
6 *
7 * Copyright (C) 2004-2007, David Dillow
8 * Written by David Dillow <dave@thedillows.org>
9 * Inspired by the Trident 4D-WaveDX/NX driver.
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27
28/* General Control Register */
29#define SIS_GCR 0x00
30#define SIS_GCR_MACRO_POWER_DOWN 0x80000000
31#define SIS_GCR_MODEM_ENABLE 0x00010000
32#define SIS_GCR_SOFTWARE_RESET 0x00000001
33
34/* General Interrupt Enable Register */
35#define SIS_GIER 0x04
36#define SIS_GIER_MODEM_TIMER_IRQ_ENABLE 0x00100000
37#define SIS_GIER_MODEM_RX_DMA_IRQ_ENABLE 0x00080000
38#define SIS_GIER_MODEM_TX_DMA_IRQ_ENABLE 0x00040000
39#define SIS_GIER_AC97_GPIO1_IRQ_ENABLE 0x00020000
40#define SIS_GIER_AC97_GPIO0_IRQ_ENABLE 0x00010000
41#define SIS_GIER_AC97_SAMPLE_TIMER_IRQ_ENABLE 0x00000010
42#define SIS_GIER_AUDIO_GLOBAL_TIMER_IRQ_ENABLE 0x00000008
43#define SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE 0x00000004
44#define SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE 0x00000002
45#define SIS_GIER_AUDIO_WAVE_ENGINE_IRQ_ENABLE 0x00000001
46
47/* General Interrupt Status Register */
48#define SIS_GISR 0x08
49#define SIS_GISR_MODEM_TIMER_IRQ_STATUS 0x00100000
50#define SIS_GISR_MODEM_RX_DMA_IRQ_STATUS 0x00080000
51#define SIS_GISR_MODEM_TX_DMA_IRQ_STATUS 0x00040000
52#define SIS_GISR_AC97_GPIO1_IRQ_STATUS 0x00020000
53#define SIS_GISR_AC97_GPIO0_IRQ_STATUS 0x00010000
54#define SIS_GISR_AC97_SAMPLE_TIMER_IRQ_STATUS 0x00000010
55#define SIS_GISR_AUDIO_GLOBAL_TIMER_IRQ_STATUS 0x00000008
56#define SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS 0x00000004
57#define SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS 0x00000002
58#define SIS_GISR_AUDIO_WAVE_ENGINE_IRQ_STATUS 0x00000001
59
60/* DMA Control Register */
61#define SIS_DMA_CSR 0x10
62#define SIS_DMA_CSR_PCI_SETTINGS 0x0000001d
63#define SIS_DMA_CSR_CONCURRENT_ENABLE 0x00000200
64#define SIS_DMA_CSR_PIPELINE_ENABLE 0x00000100
65#define SIS_DMA_CSR_RX_DRAIN_ENABLE 0x00000010
66#define SIS_DMA_CSR_RX_FILL_ENABLE 0x00000008
67#define SIS_DMA_CSR_TX_DRAIN_ENABLE 0x00000004
68#define SIS_DMA_CSR_TX_LOWPRI_FILL_ENABLE 0x00000002
69#define SIS_DMA_CSR_TX_HIPRI_FILL_ENABLE 0x00000001
70
71/* Playback Channel Start Registers */
72#define SIS_PLAY_START_A_REG 0x14
73#define SIS_PLAY_START_B_REG 0x18
74
75/* Playback Channel Stop Registers */
76#define SIS_PLAY_STOP_A_REG 0x1c
77#define SIS_PLAY_STOP_B_REG 0x20
78
79/* Recording Channel Start Register */
80#define SIS_RECORD_START_REG 0x24
81
82/* Recording Channel Stop Register */
83#define SIS_RECORD_STOP_REG 0x28
84
85/* Playback Interrupt Status Registers */
86#define SIS_PISR_A 0x2c
87#define SIS_PISR_B 0x30
88
89/* Recording Interrupt Status Register */
90#define SIS_RISR 0x34
91
92/* AC97 AC-link Playback Source Register */
93#define SIS_AC97_PSR 0x40
94#define SIS_AC97_PSR_MODEM_HEADSET_SRC_MIXER 0x0f000000
95#define SIS_AC97_PSR_MODEM_LINE2_SRC_MIXER 0x00f00000
96#define SIS_AC97_PSR_MODEM_LINE1_SRC_MIXER 0x000f0000
97#define SIS_AC97_PSR_PCM_LFR_SRC_MIXER 0x0000f000
98#define SIS_AC97_PSR_PCM_SURROUND_SRC_MIXER 0x00000f00
99#define SIS_AC97_PSR_PCM_CENTER_SRC_MIXER 0x000000f0
100#define SIS_AC97_PSR_PCM_LR_SRC_MIXER 0x0000000f
101
102/* AC97 AC-link Command Register */
103#define SIS_AC97_CMD 0x50
104#define SIS_AC97_CMD_DATA_MASK 0xffff0000
105#define SIS_AC97_CMD_REG_MASK 0x0000ff00
106#define SIS_AC97_CMD_CODEC3_READ 0x0000000d
107#define SIS_AC97_CMD_CODEC3_WRITE 0x0000000c
108#define SIS_AC97_CMD_CODEC2_READ 0x0000000b
109#define SIS_AC97_CMD_CODEC2_WRITE 0x0000000a
110#define SIS_AC97_CMD_CODEC_READ 0x00000009
111#define SIS_AC97_CMD_CODEC_WRITE 0x00000008
112#define SIS_AC97_CMD_CODEC_WARM_RESET 0x00000005
113#define SIS_AC97_CMD_CODEC_COLD_RESET 0x00000004
114#define SIS_AC97_CMD_DONE 0x00000000
115
116/* AC97 AC-link Semaphore Register */
117#define SIS_AC97_SEMA 0x54
118#define SIS_AC97_SEMA_BUSY 0x00000001
119#define SIS_AC97_SEMA_RELEASE 0x00000000
120
121/* AC97 AC-link Status Register */
122#define SIS_AC97_STATUS 0x58
123#define SIS_AC97_STATUS_AUDIO_D2_INACT_SECS 0x03f00000
124#define SIS_AC97_STATUS_MODEM_ALIVE 0x00002000
125#define SIS_AC97_STATUS_AUDIO_ALIVE 0x00001000
126#define SIS_AC97_STATUS_CODEC3_READY 0x00000400
127#define SIS_AC97_STATUS_CODEC2_READY 0x00000200
128#define SIS_AC97_STATUS_CODEC_READY 0x00000100
129#define SIS_AC97_STATUS_WARM_RESET 0x00000080
130#define SIS_AC97_STATUS_COLD_RESET 0x00000040
131#define SIS_AC97_STATUS_POWERED_DOWN 0x00000020
132#define SIS_AC97_STATUS_NORMAL 0x00000010
133#define SIS_AC97_STATUS_READ_EXPIRED 0x00000004
134#define SIS_AC97_STATUS_SEMAPHORE 0x00000002
135#define SIS_AC97_STATUS_BUSY 0x00000001
136
137/* AC97 AC-link Audio Configuration Register */
138#define SIS_AC97_CONF 0x5c
139#define SIS_AC97_CONF_AUDIO_ALIVE 0x80000000
140#define SIS_AC97_CONF_WARM_RESET_ENABLE 0x40000000
141#define SIS_AC97_CONF_PR6_ENABLE 0x20000000
142#define SIS_AC97_CONF_PR5_ENABLE 0x10000000
143#define SIS_AC97_CONF_PR4_ENABLE 0x08000000
144#define SIS_AC97_CONF_PR3_ENABLE 0x04000000
145#define SIS_AC97_CONF_PR2_PR7_ENABLE 0x02000000
146#define SIS_AC97_CONF_PR0_PR1_ENABLE 0x01000000
147#define SIS_AC97_CONF_AUTO_PM_ENABLE 0x00800000
148#define SIS_AC97_CONF_PCM_LFE_ENABLE 0x00080000
149#define SIS_AC97_CONF_PCM_SURROUND_ENABLE 0x00040000
150#define SIS_AC97_CONF_PCM_CENTER_ENABLE 0x00020000
151#define SIS_AC97_CONF_PCM_LR_ENABLE 0x00010000
152#define SIS_AC97_CONF_PCM_CAP_MIC_ENABLE 0x00002000
153#define SIS_AC97_CONF_PCM_CAP_LR_ENABLE 0x00001000
154#define SIS_AC97_CONF_PCM_CAP_MIC_FROM_CODEC3 0x00000200
155#define SIS_AC97_CONF_PCM_CAP_LR_FROM_CODEC3 0x00000100
156#define SIS_AC97_CONF_CODEC3_PM_VRM 0x00000080
157#define SIS_AC97_CONF_CODEC_PM_VRM 0x00000040
158#define SIS_AC97_CONF_CODEC3_VRA_ENABLE 0x00000020
159#define SIS_AC97_CONF_CODEC_VRA_ENABLE 0x00000010
160#define SIS_AC97_CONF_CODEC3_PM_EAC 0x00000008
161#define SIS_AC97_CONF_CODEC_PM_EAC 0x00000004
162#define SIS_AC97_CONF_CODEC3_EXISTS 0x00000002
163#define SIS_AC97_CONF_CODEC_EXISTS 0x00000001
164
165/* Playback Channel Sync Group registers */
166#define SIS_PLAY_SYNC_GROUP_A 0x80
167#define SIS_PLAY_SYNC_GROUP_B 0x84
168#define SIS_PLAY_SYNC_GROUP_C 0x88
169#define SIS_PLAY_SYNC_GROUP_D 0x8c
170#define SIS_MIXER_SYNC_GROUP 0x90
171
172/* Wave Engine Config and Control Register */
173#define SIS_WECCR 0xa0
174#define SIS_WECCR_TESTMODE_MASK 0x00300000
175#define SIS_WECCR_TESTMODE_NORMAL 0x00000000
176#define SIS_WECCR_TESTMODE_BYPASS_NSO_ALPHA 0x00100000
177#define SIS_WECCR_TESTMODE_BYPASS_FC 0x00200000
178#define SIS_WECCR_TESTMODE_BYPASS_WOL 0x00300000
179#define SIS_WECCR_RESONANCE_DELAY_MASK 0x00060000
180#define SIS_WECCR_RESONANCE_DELAY_NONE 0x00000000
181#define SIS_WECCR_RESONANCE_DELAY_FC_1F00 0x00020000
182#define SIS_WECCR_RESONANCE_DELAY_FC_1E00 0x00040000
183#define SIS_WECCR_RESONANCE_DELAY_FC_1C00 0x00060000
184#define SIS_WECCR_IGNORE_CHANNEL_PARMS 0x00010000
185#define SIS_WECCR_COMMAND_CHANNEL_ID_MASK 0x0003ff00
186#define SIS_WECCR_COMMAND_MASK 0x00000007
187#define SIS_WECCR_COMMAND_NONE 0x00000000
188#define SIS_WECCR_COMMAND_DONE 0x00000000
189#define SIS_WECCR_COMMAND_PAUSE 0x00000001
190#define SIS_WECCR_COMMAND_TOGGLE_VEG 0x00000002
191#define SIS_WECCR_COMMAND_TOGGLE_MEG 0x00000003
192#define SIS_WECCR_COMMAND_TOGGLE_VEG_MEG 0x00000004
193
194/* Wave Engine Volume Control Register */
195#define SIS_WEVCR 0xa4
196#define SIS_WEVCR_LEFT_MUSIC_ATTENUATION_MASK 0xff000000
197#define SIS_WEVCR_RIGHT_MUSIC_ATTENUATION_MASK 0x00ff0000
198#define SIS_WEVCR_LEFT_WAVE_ATTENUATION_MASK 0x0000ff00
199#define SIS_WEVCR_RIGHT_WAVE_ATTENUATION_MASK 0x000000ff
200
201/* Wave Engine Interrupt Status Registers */
202#define SIS_WEISR_A 0xa8
203#define SIS_WEISR_B 0xac
204
205
206/* Playback DMA parameters (paramter RAM) */
207#define SIS_PLAY_DMA_OFFSET 0x0000
208#define SIS_PLAY_DMA_SIZE 0x10
209#define SIS_PLAY_DMA_ADDR(addr, num) \
210 ((num * SIS_PLAY_DMA_SIZE) + (addr) + SIS_PLAY_DMA_OFFSET)
211
212#define SIS_PLAY_DMA_FORMAT_CSO 0x00
213#define SIS_PLAY_DMA_FORMAT_UNSIGNED 0x00080000
214#define SIS_PLAY_DMA_FORMAT_8BIT 0x00040000
215#define SIS_PLAY_DMA_FORMAT_MONO 0x00020000
216#define SIS_PLAY_DMA_CSO_MASK 0x0000ffff
217#define SIS_PLAY_DMA_BASE 0x04
218#define SIS_PLAY_DMA_CONTROL 0x08
219#define SIS_PLAY_DMA_STOP_AT_SSO 0x04000000
220#define SIS_PLAY_DMA_RELEASE 0x02000000
221#define SIS_PLAY_DMA_LOOP 0x01000000
222#define SIS_PLAY_DMA_INTR_AT_SSO 0x00080000
223#define SIS_PLAY_DMA_INTR_AT_ESO 0x00040000
224#define SIS_PLAY_DMA_INTR_AT_LEO 0x00020000
225#define SIS_PLAY_DMA_INTR_AT_MLP 0x00010000
226#define SIS_PLAY_DMA_LEO_MASK 0x0000ffff
227#define SIS_PLAY_DMA_SSO_ESO 0x0c
228#define SIS_PLAY_DMA_SSO_MASK 0xffff0000
229#define SIS_PLAY_DMA_ESO_MASK 0x0000ffff
230
231/* Capture DMA parameters (paramter RAM) */
232#define SIS_CAPTURE_DMA_OFFSET 0x0800
233#define SIS_CAPTURE_DMA_SIZE 0x10
234#define SIS_CAPTURE_DMA_ADDR(addr, num) \
235 ((num * SIS_CAPTURE_DMA_SIZE) + (addr) + SIS_CAPTURE_DMA_OFFSET)
236
237#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_0 0
238#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_1 1
239#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_2 2
240#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_3 3
241#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_4 4
242#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_5 5
243#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_6 6
244#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_7 7
245#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_8 8
246#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_9 9
247#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_10 10
248#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_11 11
249#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_12 12
250#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_13 13
251#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_14 14
252#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_15 15
253#define SIS_CAPTURE_CHAN_AC97_PCM_IN 16
254#define SIS_CAPTURE_CHAN_AC97_MIC_IN 17
255#define SIS_CAPTURE_CHAN_AC97_LINE1_IN 18
256#define SIS_CAPTURE_CHAN_AC97_LINE2_IN 19
257#define SIS_CAPTURE_CHAN_AC97_HANDSE_IN 20
258
259#define SIS_CAPTURE_DMA_FORMAT_CSO 0x00
260#define SIS_CAPTURE_DMA_MONO_MODE_MASK 0xc0000000
261#define SIS_CAPTURE_DMA_MONO_MODE_AVG 0x00000000
262#define SIS_CAPTURE_DMA_MONO_MODE_LEFT 0x40000000
263#define SIS_CAPTURE_DMA_MONO_MODE_RIGHT 0x80000000
264#define SIS_CAPTURE_DMA_FORMAT_UNSIGNED 0x00080000
265#define SIS_CAPTURE_DMA_FORMAT_8BIT 0x00040000
266#define SIS_CAPTURE_DMA_FORMAT_MONO 0x00020000
267#define SIS_CAPTURE_DMA_CSO_MASK 0x0000ffff
268#define SIS_CAPTURE_DMA_BASE 0x04
269#define SIS_CAPTURE_DMA_CONTROL 0x08
270#define SIS_CAPTURE_DMA_STOP_AT_SSO 0x04000000
271#define SIS_CAPTURE_DMA_RELEASE 0x02000000
272#define SIS_CAPTURE_DMA_LOOP 0x01000000
273#define SIS_CAPTURE_DMA_INTR_AT_LEO 0x00020000
274#define SIS_CAPTURE_DMA_INTR_AT_MLP 0x00010000
275#define SIS_CAPTURE_DMA_LEO_MASK 0x0000ffff
276#define SIS_CAPTURE_DMA_RESERVED 0x0c
277
278
279/* Mixer routing list start pointer (parameter RAM) */
280#define SIS_MIXER_START_OFFSET 0x1000
281#define SIS_MIXER_START_SIZE 0x04
282#define SIS_MIXER_START_ADDR(addr, num) \
283 ((num * SIS_MIXER_START_SIZE) + (addr) + SIS_MIXER_START_OFFSET)
284
285#define SIS_MIXER_START_MASK 0x0000007f
286
287/* Mixer routing table (parameter RAM) */
288#define SIS_MIXER_OFFSET 0x1400
289#define SIS_MIXER_SIZE 0x04
290#define SIS_MIXER_ADDR(addr, num) \
291 ((num * SIS_MIXER_SIZE) + (addr) + SIS_MIXER_OFFSET)
292
293#define SIS_MIXER_RIGHT_ATTENUTATION_MASK 0xff000000
294#define SIS_MIXER_RIGHT_NO_ATTEN 0xff000000
295#define SIS_MIXER_LEFT_ATTENUTATION_MASK 0x00ff0000
296#define SIS_MIXER_LEFT_NO_ATTEN 0x00ff0000
297#define SIS_MIXER_NEXT_ENTRY_MASK 0x00007f00
298#define SIS_MIXER_NEXT_ENTRY_NONE 0x00000000
299#define SIS_MIXER_DEST_MASK 0x0000007f
300#define SIS_MIXER_DEST_0 0x00000020
301#define SIS_MIXER_DEST_1 0x00000021
302#define SIS_MIXER_DEST_2 0x00000022
303#define SIS_MIXER_DEST_3 0x00000023
304#define SIS_MIXER_DEST_4 0x00000024
305#define SIS_MIXER_DEST_5 0x00000025
306#define SIS_MIXER_DEST_6 0x00000026
307#define SIS_MIXER_DEST_7 0x00000027
308#define SIS_MIXER_DEST_8 0x00000028
309#define SIS_MIXER_DEST_9 0x00000029
310#define SIS_MIXER_DEST_10 0x0000002a
311#define SIS_MIXER_DEST_11 0x0000002b
312#define SIS_MIXER_DEST_12 0x0000002c
313#define SIS_MIXER_DEST_13 0x0000002d
314#define SIS_MIXER_DEST_14 0x0000002e
315#define SIS_MIXER_DEST_15 0x0000002f
316
317/* Wave Engine Control Parameters (parameter RAM) */
318#define SIS_WAVE_OFFSET 0x2000
319#define SIS_WAVE_SIZE 0x40
320#define SIS_WAVE_ADDR(addr, num) \
321 ((num * SIS_WAVE_SIZE) + (addr) + SIS_WAVE_OFFSET)
322
323#define SIS_WAVE_GENERAL 0x00
324#define SIS_WAVE_GENERAL_WAVE_VOLUME 0x80000000
325#define SIS_WAVE_GENERAL_MUSIC_VOLUME 0x00000000
326#define SIS_WAVE_GENERAL_VOLUME_MASK 0x7f000000
327#define SIS_WAVE_GENERAL_ARTICULATION 0x04
328#define SIS_WAVE_GENERAL_ARTICULATION_DELTA_MASK 0x3fff0000
329#define SIS_WAVE_ARTICULATION 0x08
330#define SIS_WAVE_TIMER 0x0c
331#define SIS_WAVE_GENERATOR 0x10
332#define SIS_WAVE_CHANNEL_CONTROL 0x14
333#define SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE 0x80000000
334#define SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE 0x40000000
335#define SIS_WAVE_CHANNEL_CONTROL_FILTER_ENABLE 0x20000000
336#define SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE 0x10000000
337#define SIS_WAVE_LFO_EG_CONTROL 0x18
338#define SIS_WAVE_LFO_EG_CONTROL_2 0x1c
339#define SIS_WAVE_LFO_EG_CONTROL_3 0x20
340#define SIS_WAVE_LFO_EG_CONTROL_4 0x24
341
342#endif /* __sis7019_h__ */