FreeBSD kernel sound device code
vibes.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2001 Orion Hodson <O.Hodson@cs.ucl.ac.uk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/*
30 * This card has the annoying habit of "clicking" when attached and
31 * detached, haven't been able to remedy this with any combination of
32 * muting.
33 */
34
35#ifdef HAVE_KERNEL_OPTION_HEADERS
36#include "opt_snd.h"
37#endif
38
39#include <dev/sound/pcm/sound.h>
40#include <dev/sound/pci/vibes.h>
41
42#include <dev/pci/pcireg.h>
43#include <dev/pci/pcivar.h>
44
45#include "mixer_if.h"
46
47SND_DECLARE_FILE("$FreeBSD$");
48
49/* ------------------------------------------------------------------------- */
50/* Constants */
51
52#define SV_PCI_ID 0xca005333
53#define SV_DEFAULT_BUFSZ 16384
54#define SV_MIN_BLKSZ 128
55#define SV_INTR_PER_BUFFER 2
56
57#ifndef DEB
58#define DEB(x) /* (x) */
59#endif
60
61/* ------------------------------------------------------------------------- */
62/* Structures */
63
64struct sc_info;
65
66struct sc_chinfo {
67 struct sc_info *parent;
68 struct pcm_channel *channel;
69 struct snd_dbuf *buffer;
70 u_int32_t fmt, spd;
71 int dir;
73};
74
75struct sc_info {
76 device_t dev;
77
78 /* DMA buffer allocator */
79 bus_dma_tag_t parent_dmat;
80
81 /* Enhanced register resources */
82 struct resource *enh_reg;
83 bus_space_tag_t enh_st;
84 bus_space_handle_t enh_sh;
87
88 /* DMA configuration */
89 struct resource *dmaa_reg, *dmac_reg;
90 bus_space_tag_t dmaa_st, dmac_st;
91 bus_space_handle_t dmaa_sh, dmac_sh;
94
95 /* Interrupt resources */
96 struct resource *irq;
97 int irqid;
98 void *ih;
99
100 /* User configurable buffer size */
101 unsigned int bufsz;
102
104 u_int8_t rev;
105};
106
107static u_int32_t sc_fmt[] = {
108 SND_FORMAT(AFMT_U8, 1, 0),
109 SND_FORMAT(AFMT_U8, 2, 0),
110 SND_FORMAT(AFMT_S16_LE, 1, 0),
111 SND_FORMAT(AFMT_S16_LE, 2, 0),
112 0
113};
114
115static struct pcmchan_caps sc_caps = {8000, 48000, sc_fmt, 0};
116
117/* ------------------------------------------------------------------------- */
118/* Register Manipulations */
119
120#define sv_direct_set(x, y, z) _sv_direct_set(x, y, z, __LINE__)
121
122static u_int8_t
123sv_direct_get(struct sc_info *sc, u_int8_t reg)
124{
125 return bus_space_read_1(sc->enh_st, sc->enh_sh, reg);
126}
127
128static void
129_sv_direct_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
130{
131 u_int8_t n;
132 bus_space_write_1(sc->enh_st, sc->enh_sh, reg, val);
133
134 n = sv_direct_get(sc, reg);
135 if (n != val) {
136 device_printf(sc->dev, "sv_direct_set register 0x%02x %d != %d from line %d\n", reg, n, val, line);
137 }
138}
139
140static u_int8_t
141sv_indirect_get(struct sc_info *sc, u_int8_t reg)
142{
145
146 bus_space_write_1(sc->enh_st, sc->enh_sh, SV_CM_INDEX, reg);
147 return bus_space_read_1(sc->enh_st, sc->enh_sh, SV_CM_DATA);
148}
149
150#define sv_indirect_set(x, y, z) _sv_indirect_set(x, y, z, __LINE__)
151
152static void
153_sv_indirect_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
154{
157
158 bus_space_write_1(sc->enh_st, sc->enh_sh, SV_CM_INDEX, reg);
159 bus_space_write_1(sc->enh_st, sc->enh_sh, SV_CM_DATA, val);
160
161 reg &= ~SV_CM_INDEX_MCE;
162 if (reg != SV_REG_ADC_PLLM) {
163 u_int8_t n;
164 n = sv_indirect_get(sc, reg);
165 if (n != val) {
166 device_printf(sc->dev, "sv_indirect_set register 0x%02x %d != %d line %d\n", reg, n, val, line);
167 }
168 }
169}
170
171static void
172sv_dma_set_config(bus_space_tag_t st, bus_space_handle_t sh,
173 u_int32_t base, u_int32_t count, u_int8_t mode)
174{
175 bus_space_write_4(st, sh, SV_DMA_ADDR, base);
176 bus_space_write_4(st, sh, SV_DMA_COUNT, count & 0xffffff);
177 bus_space_write_1(st, sh, SV_DMA_MODE, mode);
178
179 DEB(printf("base 0x%08x count %5d mode 0x%02x\n",
180 base, count, mode));
181}
182
183static u_int32_t
184sv_dma_get_count(bus_space_tag_t st, bus_space_handle_t sh)
185{
186 return bus_space_read_4(st, sh, SV_DMA_COUNT) & 0xffffff;
187}
188
189/* ------------------------------------------------------------------------- */
190/* Play / Record Common Interface */
191
192static void *
193svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
194{
195 struct sc_info *sc = devinfo;
196 struct sc_chinfo *ch;
197 ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch;
198
199 ch->parent = sc;
200 ch->channel = c;
201 ch->dir = dir;
202
203 if (sndbuf_alloc(b, sc->parent_dmat, 0, sc->bufsz) != 0) {
204 DEB(printf("svchan_init failed\n"));
205 return NULL;
206 }
207 ch->buffer = b;
208 ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
210 ch->dma_active = ch->dma_was_active = 0;
211
212 return ch;
213}
214
215static struct pcmchan_caps *
216svchan_getcaps(kobj_t obj, void *data)
217{
218 return &sc_caps;
219}
220
221static u_int32_t
222svchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
223{
224 struct sc_chinfo *ch = data;
225 struct sc_info *sc = ch->parent;
226
227 /* user has requested interrupts every blocksize bytes */
230 DEB(printf("svchan_setblocksize: %d\n", blocksize));
231 return blocksize;
232}
233
234static int
235svchan_setformat(kobj_t obj, void *data, u_int32_t format)
236{
237 struct sc_chinfo *ch = data;
238 /* NB Just note format here as setting format register
239 * generates noise if dma channel is inactive. */
242 return 0;
243}
244
245static u_int32_t
246svchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
247{
248 struct sc_chinfo *ch = data;
249 RANGE(speed, 8000, 48000);
250 ch->spd = speed;
251 return speed;
252}
253
254/* ------------------------------------------------------------------------- */
255/* Recording interface */
256
257static int
258sv_set_recspeed(struct sc_info *sc, u_int32_t speed)
259{
260 u_int32_t f_out, f_actual;
261 u_int32_t rs, re, r, best_r = 0, r2, t, n, best_n = 0;
262 int32_t m, best_m = 0, ms, me, err, min_err;
263
264 /* This algorithm is a variant described in sonicvibes.pdf
265 * appendix A. This search is marginally more extensive and
266 * results in (nominally) better sample rate matching. */
267
268 f_out = SV_F_SCALE * speed;
269 min_err = 0x7fffffff;
270
271 /* Find bounds of r to examine, rs <= r <= re */
272 t = 80000000 / f_out;
273 for (rs = 1; (1 << rs) < t; rs++);
274
275 t = 150000000 / f_out;
276 for (re = 1; (2 << re) < t; re++);
277 if (re > 7) re = 7;
278
279 /* Search over r, n, m */
280 for (r = rs; r <= re; r++) {
281 r2 = (1 << r);
282 for (n = 3; n < 34; n++) {
283 m = f_out * n / (SV_F_REF / r2);
284 ms = (m > 3) ? (m - 1) : 3;
285 me = (m < 129) ? (m + 1) : 129;
286 for (m = ms; m <= me; m++) {
287 f_actual = m * SV_F_REF / (n * r2);
288 if (f_actual > f_out) {
289 err = f_actual - f_out;
290 } else {
291 err = f_out - f_actual;
292 }
293 if (err < min_err) {
294 best_r = r;
295 best_m = m - 2;
296 best_n = n - 2;
297 min_err = err;
298 if (err == 0) break;
299 }
300 }
301 }
302 }
303
304 sv_indirect_set(sc, SV_REG_ADC_PLLM, best_m);
306 SV_ADC_PLLN(best_n) | SV_ADC_PLLR(best_r));
307 DEB(printf("svrchan_setspeed: %d -> PLLM 0x%02x PLLNR 0x%08x\n",
308 speed,
311 return 0;
312}
313
314static int
315svrchan_trigger(kobj_t obj, void *data, int go)
316{
317 struct sc_chinfo *ch = data;
318 struct sc_info *sc = ch->parent;
319 u_int32_t count, enable;
320 u_int8_t v;
321
322 switch(go) {
323 case PCMTRIG_START:
324 /* Set speed */
325 sv_set_recspeed(sc, ch->spd);
326
327 /* Set format */
328 v = sv_indirect_get(sc, SV_REG_FORMAT) & ~SV_AFMT_DMAC_MSK;
329 v |= SV_AFMT_DMAC(ch->fmt);
331
332 /* Program DMA */
333 count = sndbuf_getsize(ch->buffer) / 2; /* DMAC uses words */
336 count - 1,
341
342 /* Enable DMA */
345 ch->dma_active = 1;
346 break;
347 case PCMTRIG_STOP:
348 case PCMTRIG_ABORT:
349 enable = sv_indirect_get(sc, SV_REG_ENABLE) & ~SV_RECORD_ENABLE;
351 ch->dma_active = 0;
352 break;
353 }
354
355 return 0;
356}
357
358static u_int32_t
359svrchan_getptr(kobj_t obj, void *data)
360{
361 struct sc_chinfo *ch = data;
362 struct sc_info *sc = ch->parent;
363 u_int32_t sz, remain;
364
365 sz = sndbuf_getsize(ch->buffer);
366 /* DMAC uses words */
367 remain = (sv_dma_get_count(sc->dmac_st, sc->dmac_sh) + 1) * 2;
368 return sz - remain;
369}
370
371static kobj_method_t svrchan_methods[] = {
372 KOBJMETHOD(channel_init, svchan_init),
373 KOBJMETHOD(channel_setformat, svchan_setformat),
374 KOBJMETHOD(channel_setspeed, svchan_setspeed),
375 KOBJMETHOD(channel_setblocksize, svchan_setblocksize),
376 KOBJMETHOD(channel_trigger, svrchan_trigger),
377 KOBJMETHOD(channel_getptr, svrchan_getptr),
378 KOBJMETHOD(channel_getcaps, svchan_getcaps),
380};
382
383/* ------------------------------------------------------------------------- */
384/* Playback interface */
385
386static int
387svpchan_trigger(kobj_t obj, void *data, int go)
388{
389 struct sc_chinfo *ch = data;
390 struct sc_info *sc = ch->parent;
391 u_int32_t count, enable, speed;
392 u_int8_t v;
393
394 switch(go) {
395 case PCMTRIG_START:
396 /* Set speed */
397 speed = (ch->spd * 65536) / 48000;
398 if (speed > 65535)
399 speed = 65535;
402
403 /* Set format */
404 v = sv_indirect_get(sc, SV_REG_FORMAT) & ~SV_AFMT_DMAA_MSK;
405 v |= SV_AFMT_DMAA(ch->fmt);
407
408 /* Program DMA */
412 count - 1,
417
418 /* Enable DMA */
422 ch->dma_active = 1;
423 break;
424 case PCMTRIG_STOP:
425 case PCMTRIG_ABORT:
426 enable = sv_indirect_get(sc, SV_REG_ENABLE) & ~SV_PLAY_ENABLE;
428 ch->dma_active = 0;
429 break;
430 }
431
432 return 0;
433}
434
435static u_int32_t
436svpchan_getptr(kobj_t obj, void *data)
437{
438 struct sc_chinfo *ch = data;
439 struct sc_info *sc = ch->parent;
440 u_int32_t sz, remain;
441
442 sz = sndbuf_getsize(ch->buffer);
443 /* DMAA uses bytes */
444 remain = sv_dma_get_count(sc->dmaa_st, sc->dmaa_sh) + 1;
445 return (sz - remain);
446}
447
448static kobj_method_t svpchan_methods[] = {
449 KOBJMETHOD(channel_init, svchan_init),
450 KOBJMETHOD(channel_setformat, svchan_setformat),
451 KOBJMETHOD(channel_setspeed, svchan_setspeed),
452 KOBJMETHOD(channel_setblocksize, svchan_setblocksize),
453 KOBJMETHOD(channel_trigger, svpchan_trigger),
454 KOBJMETHOD(channel_getptr, svpchan_getptr),
455 KOBJMETHOD(channel_getcaps, svchan_getcaps),
457};
459
460/* ------------------------------------------------------------------------- */
461/* Mixer support */
462
464 u_int8_t reg; /* Register */
465 u_int8_t stereo:1; /* Supports 2 channels */
466 u_int8_t mute:1; /* Supports muting */
467 u_int8_t neg:1; /* Negative gain */
468 u_int8_t max; /* Max gain */
469 u_int8_t iselect; /* Input selector */
470} static const mt [SOUND_MIXER_NRDEVICES] = {
471 [SOUND_MIXER_LINE1] = {SV_REG_AUX1, 1, 1, 1, SV_DEFAULT_MAX, SV_INPUT_AUX1},
472 [SOUND_MIXER_CD] = {SV_REG_CD, 1, 1, 1, SV_DEFAULT_MAX, SV_INPUT_CD},
473 [SOUND_MIXER_LINE] = {SV_REG_LINE, 1, 1, 1, SV_DEFAULT_MAX, SV_INPUT_LINE},
474 [SOUND_MIXER_MIC] = {SV_REG_MIC, 0, 1, 1, SV_MIC_MAX, SV_INPUT_MIC},
475 [SOUND_MIXER_SYNTH] = {SV_REG_SYNTH, 0, 1, 1, SV_DEFAULT_MAX, 0},
476 [SOUND_MIXER_LINE2] = {SV_REG_AUX2, 1, 1, 1, SV_DEFAULT_MAX, SV_INPUT_AUX2},
477 [SOUND_MIXER_VOLUME] = {SV_REG_MIX, 1, 1, 1, SV_DEFAULT_MAX, 0},
478 [SOUND_MIXER_PCM] = {SV_REG_PCM, 1, 1, 1, SV_PCM_MAX, 0},
479 [SOUND_MIXER_RECLEV] = {SV_REG_ADC_INPUT, 1, 0, 0, SV_ADC_MAX, 0},
481
482static void
483sv_channel_gain(struct sc_info *sc, u_int32_t dev, u_int32_t gain, u_int32_t channel)
484{
485 u_int8_t v;
486 int32_t g;
487
488 g = mt[dev].max * gain / 100;
489 if (mt[dev].neg)
490 g = mt[dev].max - g;
491 v = sv_indirect_get(sc, mt[dev].reg + channel) & ~mt[dev].max;
492 v |= g;
493
494 if (mt[dev].mute) {
495 if (gain == 0) {
496 v |= SV_MUTE;
497 } else {
498 v &= ~SV_MUTE;
499 }
500 }
501 sv_indirect_set(sc, mt[dev].reg + channel, v);
502}
503
504static int
505sv_gain(struct sc_info *sc, u_int32_t dev, u_int32_t left, u_int32_t right)
506{
507 sv_channel_gain(sc, dev, left, 0);
508 if (mt[dev].stereo)
509 sv_channel_gain(sc, dev, right, 1);
510 return 0;
511}
512
513static void
515{
516 int32_t i;
517 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
518 if (mt[i].reg) sv_gain(sc, i, 0, 0);
519 }
520}
521
522static int
524{
525 u_int32_t i, v;
526
527 for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
528 if (mt[i].max) v |= (1 << i);
529 }
530 mix_setdevs(m, v);
531
532 for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
533 if (mt[i].iselect) v |= (1 << i);
534 }
535 mix_setrecdevs(m, v);
536
537 return 0;
538}
539
540static int
541sv_mix_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right)
542{
543 struct sc_info *sc = mix_getdevinfo(m);
544 return sv_gain(sc, dev, left, right);
545}
546
547static u_int32_t
548sv_mix_setrecsrc(struct snd_mixer *m, u_int32_t mask)
549{
550 struct sc_info *sc = mix_getdevinfo(m);
551 u_int32_t i, v;
552
554 for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
555 if ((1 << i) & mask) {
556 v |= mt[i].iselect;
557 }
558 }
559 DEB(printf("sv_mix_setrecsrc: mask 0x%08x adc_input 0x%02x\n", mask, v));
561 return mask;
562}
563
564static kobj_method_t sv_mixer_methods[] = {
565 KOBJMETHOD(mixer_init, sv_mix_init),
566 KOBJMETHOD(mixer_set, sv_mix_set),
569};
571
572/* ------------------------------------------------------------------------- */
573/* Power management and reset */
574
575static void
576sv_power(struct sc_info *sc, int state)
577{
578 u_int8_t v;
579
580 switch (state) {
581 case 0:
582 /* power on */
583 v = sv_indirect_get(sc, SV_REG_ANALOG_PWR) &~ SV_ANALOG_OFF;
586 v = sv_indirect_get(sc, SV_REG_DIGITAL_PWR) &~ SV_DIGITAL_OFF;
589 break;
590 default:
591 /* power off */
596 break;
597 }
598 DEB(printf("Power state %d\n", state));
599}
600
601static int
602sv_init(struct sc_info *sc)
603{
604 u_int8_t v;
605
606 /* Effect reset */
607 v = sv_direct_get(sc, SV_CM_CONTROL) & ~SV_CM_CONTROL_ENHANCED;
610 DELAY(50);
611
612 v = sv_direct_get(sc, SV_CM_CONTROL) & ~SV_CM_CONTROL_RESET;
614 DELAY(50);
615
616 /* Set in enhanced mode */
620
621 /* Enable interrupts (UDM and MIDM are superfluous) */
622 v = sv_direct_get(sc, SV_CM_IMR);
624 sv_direct_set(sc, SV_CM_IMR, v);
625
626 /* Select ADC PLL for ADC clock */
627 v = sv_indirect_get(sc, SV_REG_CLOCK_SOURCE) & ~SV_CLOCK_ALTERNATE;
629
630 /* Disable loopback - binds ADC and DAC rates */
631 v = sv_indirect_get(sc, SV_REG_LOOPBACK) & ~SV_LOOPBACK_ENABLE;
633
634 /* Disable SRS */
637
638 /* Get revision */
640
641 return 0;
642}
643
644static int
646{
647 struct sc_info *sc = pcm_getdevinfo(dev);
648
650 svrchan_trigger(NULL, &sc->rch, PCMTRIG_ABORT);
651
653 svrchan_trigger(NULL, &sc->pch, PCMTRIG_ABORT);
654
655 sv_mix_mute_all(sc);
656 sv_power(sc, 3);
657
658 return 0;
659}
660
661static int
662sv_resume(device_t dev)
663{
664 struct sc_info *sc = pcm_getdevinfo(dev);
665
666 sv_mix_mute_all(sc);
667 sv_power(sc, 0);
668 if (sv_init(sc) == -1) {
669 device_printf(dev, "unable to reinitialize the card\n");
670 return ENXIO;
671 }
672
673 if (mixer_reinit(dev) == -1) {
674 device_printf(dev, "unable to reinitialize the mixer\n");
675 return ENXIO;
676 }
677
678 if (sc->rch.dma_was_active) {
680 }
681
682 if (sc->pch.dma_was_active) {
684 }
685
686 return 0;
687}
688
689/* ------------------------------------------------------------------------- */
690/* Resource related */
691
692static void
694{
695 struct sc_info *sc = data;
696 u_int8_t status;
697
700 chn_intr(sc->pch.channel);
701
703 chn_intr(sc->rch.channel);
704
706 DEB(if (status) printf("intr 0x%02x ?\n", status));
707
708 return;
709}
710
711static int
712sv_probe(device_t dev)
713{
714 switch(pci_get_devid(dev)) {
715 case SV_PCI_ID:
716 device_set_desc(dev, "S3 Sonicvibes");
717 return BUS_PROBE_DEFAULT;
718 default:
719 return ENXIO;
720 }
721}
722
723static int
724sv_attach(device_t dev) {
725 struct sc_info *sc;
726 rman_res_t count, midi_start, games_start;
727 u_int32_t data;
728 char status[SND_STATUSLEN];
729 u_long sdmaa, sdmac, ml, mu;
730
731 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
732 sc->dev = dev;
733
734 pci_enable_busmaster(dev);
735
736 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
737 device_printf(dev, "chip is in D%d power mode "
738 "-- setting to D0\n", pci_get_powerstate(dev));
739 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
740 }
742 sc->enh_type = SYS_RES_IOPORT;
743 sc->enh_reg = bus_alloc_resource_any(dev, sc->enh_type,
744 &sc->enh_rid, RF_ACTIVE);
745 if (sc->enh_reg == NULL) {
746 device_printf(dev, "sv_attach: cannot allocate enh\n");
747 return ENXIO;
748 }
749 sc->enh_st = rman_get_bustag(sc->enh_reg);
750 sc->enh_sh = rman_get_bushandle(sc->enh_reg);
751
752 data = pci_read_config(dev, SV_PCI_DMAA, 4);
753 DEB(printf("sv_attach: initial dmaa 0x%08x\n", data));
754 data = pci_read_config(dev, SV_PCI_DMAC, 4);
755 DEB(printf("sv_attach: initial dmac 0x%08x\n", data));
756
757 /* Initialize DMA_A and DMA_C */
758 pci_write_config(dev, SV_PCI_DMAA, SV_PCI_DMA_EXTENDED, 4);
759 pci_write_config(dev, SV_PCI_DMAC, 0, 4);
760
761 /* Register IRQ handler */
762 sc->irqid = 0;
763 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
764 RF_ACTIVE | RF_SHAREABLE);
765 if (!sc->irq ||
766 snd_setup_intr(dev, sc->irq, 0, sv_intr, sc, &sc->ih)) {
767 device_printf(dev, "sv_attach: Unable to map interrupt\n");
768 goto fail;
769 }
770
771 sc->bufsz = pcm_getbuffersize(dev, 4096, SV_DEFAULT_BUFSZ, 65536);
772 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
773 /*boundary*/0,
774 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
775 /*highaddr*/BUS_SPACE_MAXADDR,
776 /*filter*/NULL, /*filterarg*/NULL,
777 /*maxsize*/sc->bufsz, /*nsegments*/1,
778 /*maxsegz*/0x3ffff, /*flags*/0,
779 /*lockfunc*/NULL, /*lockarg*/NULL,
780 &sc->parent_dmat) != 0) {
781 device_printf(dev, "sv_attach: Unable to create dma tag\n");
782 goto fail;
783 }
784
785 /* Power up and initialize */
786 sv_mix_mute_all(sc);
787 sv_power(sc, 0);
788 sv_init(sc);
789
790 if (mixer_init(dev, &sv_mixer_class, sc) != 0) {
791 device_printf(dev, "sv_attach: Mixer failed to initialize\n");
792 goto fail;
793 }
794
795 /* XXX This is a hack, and it's ugly. Okay, the deal is this
796 * card has two more io regions that available for automatic
797 * configuration by the pci code. These need to be allocated
798 * to used as control registers for the DMA engines.
799 * Unfortunately FBSD has no bus_space_foo() functions so we
800 * have to grab port space in region of existing resources. Go
801 * for space between midi and game ports.
802 */
803 bus_get_resource(dev, SYS_RES_IOPORT, SV_PCI_MIDI, &midi_start, &count);
804 bus_get_resource(dev, SYS_RES_IOPORT, SV_PCI_GAMES, &games_start, &count);
805
806 if (games_start < midi_start) {
807 ml = games_start;
808 mu = midi_start;
809 } else {
810 ml = midi_start;
811 mu = games_start;
812 }
813 /* Check assumptions about space availability and
814 alignment. How driver loaded can determine whether
815 games_start > midi_start or vice versa */
816 if ((mu - ml >= 0x800) ||
817 ((mu - ml) % 0x200)) {
818 device_printf(dev, "sv_attach: resource assumptions not met "
819 "(midi 0x%08lx, games 0x%08lx)\n",
820 (u_long)midi_start, (u_long)games_start);
821 goto fail;
822 }
823
824 sdmaa = ml + 0x40;
825 sdmac = sdmaa + 0x40;
826
827 /* Add resources to list of pci resources for this device - from here on
828 * they look like normal pci resources. */
829 bus_set_resource(dev, SYS_RES_IOPORT, SV_PCI_DMAA, sdmaa, SV_PCI_DMAA_SIZE);
830 bus_set_resource(dev, SYS_RES_IOPORT, SV_PCI_DMAC, sdmac, SV_PCI_DMAC_SIZE);
831
832 /* Cache resource short-cuts for dma_a */
833 sc->dmaa_rid = SV_PCI_DMAA;
834 sc->dmaa_type = SYS_RES_IOPORT;
835 sc->dmaa_reg = bus_alloc_resource_any(dev, sc->dmaa_type,
836 &sc->dmaa_rid, RF_ACTIVE);
837 if (sc->dmaa_reg == NULL) {
838 device_printf(dev, "sv_attach: cannot allocate dmaa\n");
839 goto fail;
840 }
841 sc->dmaa_st = rman_get_bustag(sc->dmaa_reg);
842 sc->dmaa_sh = rman_get_bushandle(sc->dmaa_reg);
843
844 /* Poke port into dma_a configuration, nb bit flags to enable dma */
845 data = pci_read_config(dev, SV_PCI_DMAA, 4) | SV_PCI_DMA_ENABLE | SV_PCI_DMA_EXTENDED;
846 data = ((u_int32_t)sdmaa & 0xfffffff0) | (data & 0x0f);
847 pci_write_config(dev, SV_PCI_DMAA, data, 4);
848 DEB(printf("dmaa: 0x%x 0x%x\n", data, pci_read_config(dev, SV_PCI_DMAA, 4)));
849
850 /* Cache resource short-cuts for dma_c */
851 sc->dmac_rid = SV_PCI_DMAC;
852 sc->dmac_type = SYS_RES_IOPORT;
853 sc->dmac_reg = bus_alloc_resource_any(dev, sc->dmac_type,
854 &sc->dmac_rid, RF_ACTIVE);
855 if (sc->dmac_reg == NULL) {
856 device_printf(dev, "sv_attach: cannot allocate dmac\n");
857 goto fail;
858 }
859 sc->dmac_st = rman_get_bustag(sc->dmac_reg);
860 sc->dmac_sh = rman_get_bushandle(sc->dmac_reg);
861
862 /* Poke port into dma_c configuration, nb bit flags to enable dma */
863 data = pci_read_config(dev, SV_PCI_DMAC, 4) | SV_PCI_DMA_ENABLE | SV_PCI_DMA_EXTENDED;
864 data = ((u_int32_t)sdmac & 0xfffffff0) | (data & 0x0f);
865 pci_write_config(dev, SV_PCI_DMAC, data, 4);
866 DEB(printf("dmac: 0x%x 0x%x\n", data, pci_read_config(dev, SV_PCI_DMAC, 4)));
867
868 if (bootverbose)
869 printf("Sonicvibes: revision %d.\n", sc->rev);
870
871 if (pcm_register(dev, sc, 1, 1)) {
872 device_printf(dev, "sv_attach: pcm_register fail\n");
873 goto fail;
874 }
875
876 pcm_addchan(dev, PCMDIR_PLAY, &svpchan_class, sc);
877 pcm_addchan(dev, PCMDIR_REC, &svrchan_class, sc);
878
879 snprintf(status, SND_STATUSLEN, "at io 0x%jx irq %jd %s",
880 rman_get_start(sc->enh_reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_vibes));
882
883 DEB(printf("sv_attach: succeeded\n"));
884
885 return 0;
886
887 fail:
888 if (sc->parent_dmat)
889 bus_dma_tag_destroy(sc->parent_dmat);
890 if (sc->ih)
891 bus_teardown_intr(dev, sc->irq, sc->ih);
892 if (sc->irq)
893 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
894 if (sc->enh_reg)
895 bus_release_resource(dev, sc->enh_type, sc->enh_rid, sc->enh_reg);
896 if (sc->dmaa_reg)
897 bus_release_resource(dev, sc->dmaa_type, sc->dmaa_rid, sc->dmaa_reg);
898 if (sc->dmac_reg)
899 bus_release_resource(dev, sc->dmac_type, sc->dmac_rid, sc->dmac_reg);
900 return ENXIO;
901}
902
903static int
904sv_detach(device_t dev) {
905 struct sc_info *sc;
906 int r;
907
909 if (r) return r;
910
911 sc = pcm_getdevinfo(dev);
912 sv_mix_mute_all(sc);
913 sv_power(sc, 3);
914
915 bus_dma_tag_destroy(sc->parent_dmat);
916 bus_teardown_intr(dev, sc->irq, sc->ih);
917 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
918 bus_release_resource(dev, sc->enh_type, sc->enh_rid, sc->enh_reg);
919 bus_release_resource(dev, sc->dmaa_type, sc->dmaa_rid, sc->dmaa_reg);
920 bus_release_resource(dev, sc->dmac_type, sc->dmac_rid, sc->dmac_reg);
921
922 free(sc, M_DEVBUF);
923
924 return 0;
925}
926
927static device_method_t sc_methods[] = {
928 DEVMETHOD(device_probe, sv_probe),
929 DEVMETHOD(device_attach, sv_attach),
930 DEVMETHOD(device_detach, sv_detach),
931 DEVMETHOD(device_resume, sv_resume),
932 DEVMETHOD(device_suspend, sv_suspend),
933 { 0, 0 }
934};
935
936static driver_t sonicvibes_driver = {
937 "pcm",
940};
941
944MODULE_VERSION(snd_vibes, 1);
u_int32_t data
Definition: ac97_if.m:60
void * devinfo
Definition: ac97_if.m:47
uint32_t format
Definition: audio_dai_if.m:39
uint32_t speed
Definition: audio_dai_if.m:86
int go
Definition: audio_dai_if.m:64
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
Definition: buffer.c:93
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf)
Definition: buffer.c:66
unsigned int sndbuf_getsize(struct snd_dbuf *b)
Definition: buffer.c:435
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
Definition: buffer.c:164
void chn_intr(struct pcm_channel *c)
Definition: channel.c:660
#define PCMDIR_PLAY
Definition: channel.h:339
#define PCMTRIG_START
Definition: channel.h:344
#define PCMTRIG_STOP
Definition: channel.h:347
#define PCMDIR_REC
Definition: channel.h:341
#define PCMTRIG_ABORT
Definition: channel.h:348
struct pcm_channel * c
Definition: channel_if.m:106
METHOD int free
Definition: channel_if.m:110
INTERFACE channel
Definition: channel_if.m:35
u_int32_t blocksize
Definition: channel_if.m:140
struct pcmchan_matrix * m
Definition: channel_if.m:232
struct snd_dbuf * b
Definition: channel_if.m:105
int max
Definition: dsp.c:392
unsigned stereo
Definition: es137x.c:262
unsigned right
Definition: es137x.c:261
unsigned left
Definition: es137x.c:260
u_int32_t count
Definition: feeder_if.m:86
uint16_t base
Definition: hdaa.c:124
uint8_t enable
Definition: hdac.c:213
uint8_t mask
Definition: hdac.c:212
uint8_t reg
Definition: hdac.c:211
int dir
Definition: hdac_if.m:45
uint8_t r
uint8_t n
uint16_t fail
uint32_t r2
#define KOBJMETHOD_END
Definition: midi.c:76
static int mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
Definition: mixer.c:373
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
Definition: mixer.c:725
static int mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
Definition: mixer.c:247
void mix_setdevs(struct snd_mixer *m, u_int32_t v)
Definition: mixer.c:489
int mixer_reinit(device_t dev)
Definition: mixer.c:860
void * mix_getdevinfo(struct snd_mixer *m)
Definition: mixer.c:645
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v)
Record mask of available recording devices.
Definition: mixer.c:529
unsigned dev
Definition: mixer_if.m:59
bool * status
int state
u_int32_t val
#define RANGE(var, low, high)
Definition: sequencer.h:45
void * pcm_getdevinfo(device_t dev)
Definition: sound.c:832
int pcm_setstatus(device_t dev, char *str)
Definition: sound.c:766
devclass_t pcm_devclass
Definition: sound.c:49
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
Definition: sound.c:692
int pcm_unregister(device_t dev)
Definition: sound.c:1170
int pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
Definition: sound.c:1080
int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
Definition: sound.c:117
unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz)
Definition: sound.c:840
#define PCM_KLDSTRING(a)
Definition: sound.h:619
#define SND_FORMAT(f, c, e)
Definition: sound.h:238
#define SOUND_PREFVER
Definition: sound.h:103
#define SOUND_MAXVER
Definition: sound.h:104
#define DSP_DEFAULT_SPEED
Definition: sound.h:295
#define AFMT_CHANNEL(v)
Definition: sound.h:227
#define SOUND_MINVER
Definition: sound.h:102
#define PCM_SOFTC_SIZE
Definition: sound.h:96
#define SND_STATUSLEN
Definition: sound.h:98
#define AFMT_16BIT
Definition: sound.h:191
u_int32_t dma_was_active
Definition: als4000.c:71
u_int32_t fmt
Definition: cmi.c:107
u_int32_t spd
Definition: cmi.c:107
struct pcm_channel * channel
Definition: als4000.c:68
int dma_was_active
Definition: vibes.c:72
struct sc_info * parent
Definition: als4000.c:67
u_int32_t dma_active
Definition: als4000.c:71
int dir
Definition: als4000.c:73
struct snd_dbuf * buffer
Definition: als4000.c:69
bus_space_tag_t dmac_st
Definition: vibes.c:90
struct resource * dmaa_reg
Definition: vibes.c:89
bus_space_tag_t dmaa_st
Definition: vibes.c:90
unsigned int bufsz
Definition: als4000.c:86
bus_space_tag_t enh_st
Definition: vibes.c:83
struct resource * dmac_reg
Definition: vibes.c:89
int dmac_rid
Definition: vibes.c:93
struct resource * irq
Definition: als4000.c:81
device_t dev
Definition: als4000.c:77
bus_space_handle_t dmaa_sh
Definition: vibes.c:91
int irqid
Definition: als4000.c:82
int enh_rid
Definition: vibes.c:86
bus_space_handle_t dmac_sh
Definition: vibes.c:91
bus_space_handle_t enh_sh
Definition: vibes.c:84
struct sc_chinfo pch rch
Definition: als4000.c:87
void * ih
Definition: als4000.c:83
u_int8_t rev
Definition: vibes.c:104
bus_dma_tag_t parent_dmat
Definition: als4000.c:80
struct resource * enh_reg
Definition: vibes.c:82
int dmaa_rid
Definition: vibes.c:93
int enh_type
Definition: vibes.c:85
struct sc_chinfo pch
Definition: cs4281.c:99
struct sc_chinfo ch[3]
Definition: ich.c:192
u_int32_t rev
Definition: emu10k1.c:213
int dmaa_type
Definition: vibes.c:92
int dmac_type
Definition: vibes.c:92
u_int8_t max
Definition: vibes.c:468
u_int8_t mute
Definition: vibes.c:466
u_int8_t stereo
Definition: vibes.c:465
u_int8_t reg
Definition: vibes.c:464
u_int8_t neg
Definition: vibes.c:467
u_int8_t iselect
Definition: vibes.c:469
CHANNEL_DECLARE(svrchan)
static struct pcmchan_caps * svchan_getcaps(kobj_t obj, void *data)
Definition: vibes.c:216
static int sv_detach(device_t dev)
Definition: vibes.c:904
static u_int32_t sc_fmt[]
Definition: vibes.c:107
#define SV_MIN_BLKSZ
Definition: vibes.c:54
static int svpchan_trigger(kobj_t obj, void *data, int go)
Definition: vibes.c:387
static int sv_attach(device_t dev)
Definition: vibes.c:724
static int svrchan_trigger(kobj_t obj, void *data, int go)
Definition: vibes.c:315
static void sv_mix_mute_all(struct sc_info *sc)
Definition: vibes.c:514
static void sv_intr(void *data)
Definition: vibes.c:693
DRIVER_MODULE(snd_vibes, pci, sonicvibes_driver, pcm_devclass, 0, 0)
static int svchan_setformat(kobj_t obj, void *data, u_int32_t format)
Definition: vibes.c:235
static int sv_init(struct sc_info *sc)
Definition: vibes.c:602
static void _sv_indirect_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
Definition: vibes.c:153
static int sv_mix_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right)
Definition: vibes.c:541
static int sv_probe(device_t dev)
Definition: vibes.c:712
SND_DECLARE_FILE("$FreeBSD$")
static int sv_set_recspeed(struct sc_info *sc, u_int32_t speed)
Definition: vibes.c:258
static kobj_method_t svrchan_methods[]
Definition: vibes.c:371
static void _sv_direct_set(struct sc_info *sc, u_int8_t reg, u_int8_t val, int line)
Definition: vibes.c:129
static u_int32_t svpchan_getptr(kobj_t obj, void *data)
Definition: vibes.c:436
struct sv_mix_props mt[SOUND_MIXER_NRDEVICES]
static int sv_gain(struct sc_info *sc, u_int32_t dev, u_int32_t left, u_int32_t right)
Definition: vibes.c:505
#define SV_DEFAULT_BUFSZ
Definition: vibes.c:53
static int sv_resume(device_t dev)
Definition: vibes.c:662
#define SV_PCI_ID
Definition: vibes.c:52
#define sv_direct_set(x, y, z)
Definition: vibes.c:120
#define sv_indirect_set(x, y, z)
Definition: vibes.c:150
static u_int8_t sv_direct_get(struct sc_info *sc, u_int8_t reg)
Definition: vibes.c:123
static u_int32_t svchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
Definition: vibes.c:222
static driver_t sonicvibes_driver
Definition: vibes.c:936
MODULE_DEPEND(snd_vibes, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static int sv_mix_init(struct snd_mixer *m)
Definition: vibes.c:523
MODULE_VERSION(snd_vibes, 1)
static int sv_suspend(device_t dev)
Definition: vibes.c:645
#define SV_INTR_PER_BUFFER
Definition: vibes.c:55
static u_int32_t sv_dma_get_count(bus_space_tag_t st, bus_space_handle_t sh)
Definition: vibes.c:184
static device_method_t sc_methods[]
Definition: vibes.c:927
static struct pcmchan_caps sc_caps
Definition: vibes.c:115
MIXER_DECLARE(sv_mixer)
static void * svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
Definition: vibes.c:193
static void sv_dma_set_config(bus_space_tag_t st, bus_space_handle_t sh, u_int32_t base, u_int32_t count, u_int8_t mode)
Definition: vibes.c:172
static u_int32_t svrchan_getptr(kobj_t obj, void *data)
Definition: vibes.c:359
static u_int8_t sv_indirect_get(struct sc_info *sc, u_int8_t reg)
Definition: vibes.c:141
static void sv_power(struct sc_info *sc, int state)
Definition: vibes.c:576
static kobj_method_t sv_mixer_methods[]
Definition: vibes.c:564
static void sv_channel_gain(struct sc_info *sc, u_int32_t dev, u_int32_t gain, u_int32_t channel)
Definition: vibes.c:483
static u_int32_t svchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
Definition: vibes.c:246
static kobj_method_t svpchan_methods[]
Definition: vibes.c:448
#define DEB(x)
Definition: vibes.c:58
static u_int32_t sv_mix_setrecsrc(struct snd_mixer *m, u_int32_t mask)
Definition: vibes.c:548
#define SV_INPUT_LINE
Definition: vibes.h:104
#define SV_PCI_DMAC
Definition: vibes.h:40
#define SV_DMA_MODE
Definition: vibes.h:58
#define SV_DIGITAL_OFF_GP
Definition: vibes.h:197
#define SV_REG_MIC
Definition: vibes.h:112
#define SV_DMA_MODE_AUTO
Definition: vibes.h:59
#define SV_AFMT_U8
Definition: vibes.h:127
#define SV_REG_SYNTH
Definition: vibes.h:113
#define SV_PCI_DMAA_SIZE
Definition: vibes.h:42
#define SV_REG_ADC_PLLM
Definition: vibes.h:160
#define SV_RECORD_ENABLE
Definition: vibes.h:135
#define SV_INPUT_AUX2
Definition: vibes.h:103
#define SV_DMA_COUNT
Definition: vibes.h:56
#define SV_REG_SRS_SPACE
Definition: vibes.h:170
#define SV_ADC_PLLR(x)
Definition: vibes.h:163
#define SV_REG_PCM_SAMPLING_HI
Definition: vibes.h:151
#define SV_AFMT_DMAC(x)
Definition: vibes.h:130
#define SV_ANALOG_OFF_SPLL
Definition: vibes.h:190
#define SV_CM_STATUS_AINT
Definition: vibes.h:82
#define SV_REG_DIGITAL_PWR
Definition: vibes.h:194
#define SV_INPUT_AUX1
Definition: vibes.h:105
#define SV_INPUT_GAIN_MASK
Definition: vibes.h:99
#define SV_ANALOG_OFF_SRS
Definition: vibes.h:189
#define SV_ADC_MAX
Definition: vibes.h:118
#define SV_PCI_ENHANCED
Definition: vibes.h:35
#define SV_REG_CLOCK_SOURCE
Definition: vibes.h:156
#define SV_DIGITAL_OFF_SYN
Definition: vibes.h:195
#define SV_REG_DMAA_COUNT_LO
Definition: vibes.h:146
#define SV_PCI_DMA_ENABLE
Definition: vibes.h:49
#define SV_ANALOG_OFF
Definition: vibes.h:192
#define SV_PCI_GAMES
Definition: vibes.h:38
#define SV_CM_IMR_SMSK
Definition: vibes.h:77
#define SV_AFMT_STEREO
Definition: vibes.h:125
#define SV_INPUT_CD
Definition: vibes.h:101
#define SV_REG_ADC_INPUT
Definition: vibes.h:98
#define SV_REG_ENABLE
Definition: vibes.h:133
#define SV_DMA_MODE_WR
Definition: vibes.h:61
#define SV_CM_CONTROL_ENHANCED
Definition: vibes.h:67
#define SV_INPUT_MIC
Definition: vibes.h:106
#define SV_REG_FORMAT
Definition: vibes.h:123
#define SV_AFMT_S16
Definition: vibes.h:126
#define SV_PCI_MIDI
Definition: vibes.h:37
#define SV_PLAYBACK_PAUSE
Definition: vibes.h:136
#define SV_CM_STATUS_CINT
Definition: vibes.h:83
#define SV_REG_LOOPBACK
Definition: vibes.h:140
#define SV_REG_DMAA_COUNT_HI
Definition: vibes.h:145
#define SV_CM_IMR_CMSK
Definition: vibes.h:76
#define SV_CM_DATA
Definition: vibes.h:93
#define SV_AFMT_MONO
Definition: vibes.h:124
#define SV_CM_IMR
Definition: vibes.h:74
#define SV_DIGITAL_OFF
Definition: vibes.h:199
#define SV_PCM_MAX
Definition: vibes.h:120
#define SV_CM_CONTROL_RESET
Definition: vibes.h:72
#define SV_REG_AUX2
Definition: vibes.h:114
#define SV_REG_ANALOG_PWR
Definition: vibes.h:185
#define SV_CM_STATUS
Definition: vibes.h:81
#define SV_MIC_MAX
Definition: vibes.h:119
#define SV_DIGITAL_OFF_MU
Definition: vibes.h:196
#define SV_DMA_ADDR
Definition: vibes.h:55
#define SV_DMA_MODE_RD
Definition: vibes.h:60
#define SV_DEFAULT_MAX
Definition: vibes.h:117
#define SV_REG_PCM
Definition: vibes.h:116
#define SV_REG_CD
Definition: vibes.h:110
#define SV_REG_PCM_SAMPLING_LO
Definition: vibes.h:150
#define SV_PCI_DMA_EXTENDED
Definition: vibes.h:50
#define SV_CM_INDEX
Definition: vibes.h:88
#define SV_REG_DMAC_COUNT_LO
Definition: vibes.h:148
#define SV_REG_ADC_PLLN
Definition: vibes.h:161
#define SV_F_SCALE
Definition: vibes.h:204
#define SV_CM_IMR_AMSK
Definition: vibes.h:75
#define SV_REG_REVISION
Definition: vibes.h:138
#define SV_MUTE
Definition: vibes.h:121
#define SV_PLAY_ENABLE
Definition: vibes.h:134
#define SV_ADC_PLLN(x)
Definition: vibes.h:162
#define SV_PCI_DMAC_SIZE
Definition: vibes.h:44
#define SV_F_REF
Definition: vibes.h:205
#define SV_CM_CONTROL
Definition: vibes.h:66
#define SV_REG_MIX
Definition: vibes.h:115
#define SV_REG_LINE
Definition: vibes.h:111
#define SV_AFMT_DMAA(x)
Definition: vibes.h:128
#define SV_REG_DMAC_COUNT_HI
Definition: vibes.h:147
#define SV_REG_AUX1
Definition: vibes.h:109
#define SV_PCI_DMAA
Definition: vibes.h:39
#define SV_SRS_DISABLED
Definition: vibes.h:176
#define SV_CM_INDEX_MCE
Definition: vibes.h:90