2005-01-06 01:43:34 +00:00
|
|
|
/*-
|
2001-02-04 19:13:40 +00:00
|
|
|
* Copyright (c) 2000 Orion Hodson <O.Hodson@cs.ucl.ac.uk>
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
2009-05-27 18:13:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2001-02-04 19:13:40 +00:00
|
|
|
* This driver exists largely as a result of other people's efforts.
|
|
|
|
* Much of register handling is based on NetBSD CMI8x38 audio driver
|
|
|
|
* by Takuya Shiozaki <AoiMoe@imou.to>. Chen-Li Tien
|
|
|
|
* <cltien@cmedia.com.tw> clarified points regarding the DMA related
|
2003-01-01 18:49:04 +00:00
|
|
|
* registers and the 8738 mixer devices. His Linux driver was also a
|
2001-02-04 19:13:40 +00:00
|
|
|
* useful reference point.
|
2001-03-05 17:51:28 +00:00
|
|
|
*
|
2001-06-16 21:25:10 +00:00
|
|
|
* TODO: MIDI
|
2001-02-04 19:13:40 +00:00
|
|
|
*
|
|
|
|
* SPDIF contributed by Gerhard Gonter <gonter@whisky.wu-wien.ac.at>.
|
|
|
|
*
|
2001-03-29 15:36:31 +00:00
|
|
|
* This card/code does not always manage to sample at 44100 - actual
|
|
|
|
* rate drifts slightly between recordings (usually 0-3%). No
|
|
|
|
* differences visible in register dumps between times that work and
|
|
|
|
* those that don't.
|
2001-02-04 19:13:40 +00:00
|
|
|
*/
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
|
|
|
#include "opt_snd.h"
|
|
|
|
#endif
|
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
#include <dev/sound/pcm/sound.h>
|
|
|
|
#include <dev/sound/pci/cmireg.h>
|
|
|
|
#include <dev/sound/isa/sb.h>
|
|
|
|
|
2003-08-22 07:08:17 +00:00
|
|
|
#include <dev/pci/pcireg.h>
|
|
|
|
#include <dev/pci/pcivar.h>
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
#include <sys/sysctl.h>
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
#include <dev/sound/midi/mpu401.h>
|
2001-03-29 15:36:31 +00:00
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
#include "mixer_if.h"
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
#include "mpufoi_if.h"
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-08-23 11:30:52 +00:00
|
|
|
SND_DECLARE_FILE("$FreeBSD$");
|
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
/* Supported chip ID's */
|
|
|
|
#define CMI8338A_PCI_ID 0x010013f6
|
|
|
|
#define CMI8338B_PCI_ID 0x010113f6
|
|
|
|
#define CMI8738_PCI_ID 0x011113f6
|
|
|
|
#define CMI8738B_PCI_ID 0x011213f6
|
2009-01-18 04:29:42 +00:00
|
|
|
#define CMI120_USB_ID 0x01030d8c
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
/* Buffer size max is 64k for permitted DMA boundaries */
|
2001-10-10 17:56:35 +00:00
|
|
|
#define CMI_DEFAULT_BUFSZ 16384
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
/* Interrupts per length of buffer */
|
|
|
|
#define CMI_INTR_PER_BUFFER 2
|
|
|
|
|
|
|
|
/* Clarify meaning of named defines in cmireg.h */
|
|
|
|
#define CMPCI_REG_DMA0_MAX_SAMPLES CMPCI_REG_DMA0_BYTES
|
|
|
|
#define CMPCI_REG_DMA0_INTR_SAMPLES CMPCI_REG_DMA0_SAMPLES
|
|
|
|
#define CMPCI_REG_DMA1_MAX_SAMPLES CMPCI_REG_DMA1_BYTES
|
|
|
|
#define CMPCI_REG_DMA1_INTR_SAMPLES CMPCI_REG_DMA1_SAMPLES
|
|
|
|
|
|
|
|
/* Our indication of custom mixer control */
|
|
|
|
#define CMPCI_NON_SB16_CONTROL 0xff
|
|
|
|
|
|
|
|
/* Debugging macro's */
|
2001-03-29 15:36:31 +00:00
|
|
|
#undef DEB
|
2001-02-04 19:13:40 +00:00
|
|
|
#ifndef DEB
|
|
|
|
#define DEB(x) /* x */
|
|
|
|
#endif /* DEB */
|
|
|
|
|
|
|
|
#ifndef DEBMIX
|
|
|
|
#define DEBMIX(x) /* x */
|
|
|
|
#endif /* DEBMIX */
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Structures */
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo {
|
|
|
|
struct sc_info *parent;
|
|
|
|
struct pcm_channel *channel;
|
|
|
|
struct snd_dbuf *buffer;
|
|
|
|
u_int32_t fmt, spd, phys_buf, bps;
|
|
|
|
u_int32_t dma_active:1, dma_was_active:1;
|
|
|
|
int dir;
|
2001-02-04 19:13:40 +00:00
|
|
|
};
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info {
|
|
|
|
device_t dev;
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_space_tag_t st;
|
|
|
|
bus_space_handle_t sh;
|
|
|
|
bus_dma_tag_t parent_dmat;
|
2001-04-04 13:48:33 +00:00
|
|
|
struct resource *reg, *irq;
|
2001-03-29 15:36:31 +00:00
|
|
|
int regid, irqid;
|
|
|
|
void *ih;
|
2002-11-26 18:16:27 +00:00
|
|
|
struct mtx *lock;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-12-17 01:39:36 +00:00
|
|
|
int spdif_enabled;
|
2001-10-10 17:56:35 +00:00
|
|
|
unsigned int bufsz;
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo pch, rch;
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
struct mpu401 *mpu;
|
|
|
|
mpu401_intr_t *mpu_intr;
|
|
|
|
struct resource *mpu_reg;
|
|
|
|
int mpu_regid;
|
|
|
|
bus_space_tag_t mpu_bt;
|
|
|
|
bus_space_handle_t mpu_bh;
|
2001-02-04 19:13:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Channel caps */
|
|
|
|
|
|
|
|
static u_int32_t cmi_fmt[] = {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
SND_FORMAT(AFMT_U8, 1, 0),
|
|
|
|
SND_FORMAT(AFMT_U8, 2, 0),
|
|
|
|
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
|
|
|
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
2001-02-04 19:13:40 +00:00
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0};
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Register Utilities */
|
|
|
|
|
|
|
|
static u_int32_t
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_rd(struct sc_info *sc, int regno, int size)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
switch (size) {
|
|
|
|
case 1:
|
2001-03-29 15:36:31 +00:00
|
|
|
return bus_space_read_1(sc->st, sc->sh, regno);
|
2001-02-04 19:13:40 +00:00
|
|
|
case 2:
|
2001-03-29 15:36:31 +00:00
|
|
|
return bus_space_read_2(sc->st, sc->sh, regno);
|
2001-02-04 19:13:40 +00:00
|
|
|
case 4:
|
2001-03-29 15:36:31 +00:00
|
|
|
return bus_space_read_4(sc->st, sc->sh, regno);
|
2001-02-04 19:13:40 +00:00
|
|
|
default:
|
|
|
|
DEB(printf("cmi_rd: failed 0x%04x %d\n", regno, size));
|
|
|
|
return 0xFFFFFFFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
switch (size) {
|
|
|
|
case 1:
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_space_write_1(sc->st, sc->sh, regno, data);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_space_write_2(sc->st, sc->sh, regno, data);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_space_write_4(sc->st, sc->sh, regno, data);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_partial_wr4(struct sc_info *sc,
|
2001-02-04 19:13:40 +00:00
|
|
|
int reg, int shift, u_int32_t mask, u_int32_t val)
|
|
|
|
{
|
|
|
|
u_int32_t r;
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
r = cmi_rd(sc, reg, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
r &= ~(mask << shift);
|
|
|
|
r |= val << shift;
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, reg, r, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_clr4(struct sc_info *sc, int reg, u_int32_t mask)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
u_int32_t r;
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
r = cmi_rd(sc, reg, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
r &= ~mask;
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, reg, r, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_set4(struct sc_info *sc, int reg, u_int32_t mask)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
u_int32_t r;
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
r = cmi_rd(sc, reg, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
r |= mask;
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, reg, r, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Rate Mapping */
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static int cmi_rates[] = {5512, 8000, 11025, 16000,
|
2001-02-04 19:13:40 +00:00
|
|
|
22050, 32000, 44100, 48000};
|
|
|
|
#define NUM_CMI_RATES (sizeof(cmi_rates)/sizeof(cmi_rates[0]))
|
|
|
|
|
|
|
|
/* cmpci_rate_to_regvalue returns sampling freq selector for FCR1
|
|
|
|
* register - reg order is 5k,11k,22k,44k,8k,16k,32k,48k */
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static u_int32_t
|
2001-02-04 19:13:40 +00:00
|
|
|
cmpci_rate_to_regvalue(int rate)
|
|
|
|
{
|
|
|
|
int i, r;
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
for(i = 0; i < NUM_CMI_RATES - 1; i++) {
|
|
|
|
if (rate < ((cmi_rates[i] + cmi_rates[i + 1]) / 2)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEB(printf("cmpci_rate_to_regvalue: %d -> %d\n", rate, cmi_rates[i]));
|
|
|
|
|
|
|
|
r = ((i >> 1) | (i << 2)) & 0x07;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static int
|
|
|
|
cmpci_regvalue_to_rate(u_int32_t r)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = ((r << 1) | (r >> 2)) & 0x07;
|
|
|
|
DEB(printf("cmpci_regvalue_to_rate: %d -> %d\n", r, i));
|
|
|
|
return cmi_rates[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
2001-03-29 15:36:31 +00:00
|
|
|
/* ADC/DAC control - there are 2 dma channels on 8738, either can be
|
|
|
|
* playback or capture. We use ch0 for playback and ch1 for capture. */
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
static void
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_dma_prog(struct sc_info *sc, struct sc_chinfo *ch, u_int32_t base)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2002-08-23 20:54:32 +00:00
|
|
|
u_int32_t s, i, sz;
|
2001-03-29 15:36:31 +00:00
|
|
|
|
2003-02-20 17:31:12 +00:00
|
|
|
ch->phys_buf = sndbuf_getbufaddr(ch->buffer);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
2002-08-23 20:54:32 +00:00
|
|
|
cmi_wr(sc, base, ch->phys_buf, 4);
|
2001-03-29 15:36:31 +00:00
|
|
|
sz = (u_int32_t)sndbuf_getsize(ch->buffer);
|
|
|
|
|
|
|
|
s = sz / ch->bps - 1;
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_wr(sc, base + 4, s, 2);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
i = sz / (ch->bps * CMI_INTR_PER_BUFFER) - 1;
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_wr(sc, base + 6, i, 2);
|
2001-06-16 21:25:10 +00:00
|
|
|
}
|
2001-04-04 13:48:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
cmi_ch0_start(struct sc_info *sc, struct sc_chinfo *ch)
|
|
|
|
{
|
|
|
|
cmi_dma_prog(sc, ch, CMPCI_REG_DMA0_BASE);
|
|
|
|
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
|
|
|
|
cmi_set4(sc, CMPCI_REG_INTR_CTRL,
|
2001-04-04 13:48:33 +00:00
|
|
|
CMPCI_REG_CH0_INTR_ENABLE);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
ch->dma_active = 1;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
static u_int32_t
|
|
|
|
cmi_ch0_stop(struct sc_info *sc, struct sc_chinfo *ch)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
u_int32_t r = ch->dma_active;
|
|
|
|
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
|
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
|
2001-04-07 14:12:53 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
|
2001-03-29 15:36:31 +00:00
|
|
|
ch->dma_active = 0;
|
|
|
|
return r;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_ch1_start(struct sc_info *sc, struct sc_chinfo *ch)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_dma_prog(sc, ch, CMPCI_REG_DMA1_BASE);
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
|
2001-04-04 13:48:33 +00:00
|
|
|
/* Enable Interrupts */
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_set4(sc, CMPCI_REG_INTR_CTRL,
|
2001-04-04 13:48:33 +00:00
|
|
|
CMPCI_REG_CH1_INTR_ENABLE);
|
2001-03-29 15:36:31 +00:00
|
|
|
DEB(printf("cmi_ch1_start: dma prog\n"));
|
|
|
|
ch->dma_active = 1;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
static u_int32_t
|
|
|
|
cmi_ch1_stop(struct sc_info *sc, struct sc_chinfo *ch)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
u_int32_t r = ch->dma_active;
|
|
|
|
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
|
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
|
2001-04-07 14:12:53 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
|
2001-03-29 15:36:31 +00:00
|
|
|
ch->dma_active = 0;
|
|
|
|
return r;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_spdif_speed(struct sc_info *sc, int speed) {
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t fcr1, lcr, mcr;
|
|
|
|
|
|
|
|
if (speed >= 44100) {
|
|
|
|
fcr1 = CMPCI_REG_SPDIF0_ENABLE;
|
|
|
|
lcr = CMPCI_REG_XSPDIF_ENABLE;
|
2001-03-05 17:51:28 +00:00
|
|
|
mcr = (speed == 48000) ?
|
2001-02-04 19:13:40 +00:00
|
|
|
CMPCI_REG_W_SPDIF_48L | CMPCI_REG_SPDIF_48K : 0;
|
|
|
|
} else {
|
|
|
|
fcr1 = mcr = lcr = 0;
|
|
|
|
}
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_partial_wr4(sc, CMPCI_REG_MISC, 0,
|
2001-02-04 19:13:40 +00:00
|
|
|
CMPCI_REG_W_SPDIF_48L | CMPCI_REG_SPDIF_48K, mcr);
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_partial_wr4(sc, CMPCI_REG_FUNC_1, 0,
|
2001-03-21 12:51:37 +00:00
|
|
|
CMPCI_REG_SPDIF0_ENABLE, fcr1);
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_partial_wr4(sc, CMPCI_REG_LEGACY_CTRL, 0,
|
|
|
|
CMPCI_REG_XSPDIF_ENABLE, lcr);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Channel Interface implementation */
|
|
|
|
|
|
|
|
static void *
|
2001-06-16 21:25:10 +00:00
|
|
|
cmichan_init(kobj_t obj, void *devinfo,
|
2001-03-29 15:36:31 +00:00
|
|
|
struct snd_dbuf *b, struct pcm_channel *c, int dir)
|
|
|
|
{
|
|
|
|
struct sc_info *sc = devinfo;
|
|
|
|
struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch;
|
|
|
|
|
|
|
|
ch->parent = sc;
|
|
|
|
ch->channel = c;
|
|
|
|
ch->bps = 1;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
|
2001-03-29 15:36:31 +00:00
|
|
|
ch->spd = DSP_DEFAULT_SPEED;
|
|
|
|
ch->buffer = b;
|
|
|
|
ch->dma_active = 0;
|
2007-04-18 18:26:41 +00:00
|
|
|
if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) {
|
2001-02-04 19:13:40 +00:00
|
|
|
DEB(printf("cmichan_init failed\n"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ch->dir = dir;
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-04-04 13:48:33 +00:00
|
|
|
if (ch->dir == PCMDIR_PLAY) {
|
|
|
|
cmi_dma_prog(sc, ch, CMPCI_REG_DMA0_BASE);
|
2001-02-04 19:13:40 +00:00
|
|
|
} else {
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_dma_prog(sc, ch, CMPCI_REG_DMA1_BASE);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static int
|
|
|
|
cmichan_setformat(kobj_t obj, void *data, u_int32_t format)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo *ch = data;
|
2001-09-08 05:20:52 +00:00
|
|
|
struct sc_info *sc = ch->parent;
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t f;
|
|
|
|
|
|
|
|
if (format & AFMT_S16_LE) {
|
|
|
|
f = CMPCI_REG_FORMAT_16BIT;
|
|
|
|
ch->bps = 2;
|
|
|
|
} else {
|
|
|
|
f = CMPCI_REG_FORMAT_8BIT;
|
|
|
|
ch->bps = 1;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
if (AFMT_CHANNEL(format) > 1) {
|
2001-02-04 19:13:40 +00:00
|
|
|
f |= CMPCI_REG_FORMAT_STEREO;
|
|
|
|
ch->bps *= 2;
|
|
|
|
} else {
|
|
|
|
f |= CMPCI_REG_FORMAT_MONO;
|
|
|
|
}
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
if (ch->dir == PCMDIR_PLAY) {
|
|
|
|
cmi_partial_wr4(ch->parent,
|
|
|
|
CMPCI_REG_CHANNEL_FORMAT,
|
|
|
|
CMPCI_REG_CH0_FORMAT_SHIFT,
|
|
|
|
CMPCI_REG_CH0_FORMAT_MASK,
|
|
|
|
f);
|
|
|
|
} else {
|
|
|
|
cmi_partial_wr4(ch->parent,
|
|
|
|
CMPCI_REG_CHANNEL_FORMAT,
|
|
|
|
CMPCI_REG_CH1_FORMAT_SHIFT,
|
|
|
|
CMPCI_REG_CH1_FORMAT_MASK,
|
|
|
|
f);
|
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-03-05 17:51:28 +00:00
|
|
|
ch->fmt = format;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2001-02-04 19:13:40 +00:00
|
|
|
cmichan_setspeed(kobj_t obj, void *data, u_int32_t speed)
|
2001-03-05 17:51:28 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo *ch = data;
|
2001-09-08 05:20:52 +00:00
|
|
|
struct sc_info *sc = ch->parent;
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t r, rsp;
|
|
|
|
|
|
|
|
r = cmpci_rate_to_regvalue(speed);
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
if (ch->dir == PCMDIR_PLAY) {
|
2001-12-17 01:39:36 +00:00
|
|
|
if (speed < 44100) {
|
|
|
|
/* disable if req before rate change */
|
2001-02-04 19:13:40 +00:00
|
|
|
cmi_spdif_speed(ch->parent, speed);
|
2001-12-17 01:39:36 +00:00
|
|
|
}
|
2001-02-04 19:13:40 +00:00
|
|
|
cmi_partial_wr4(ch->parent,
|
|
|
|
CMPCI_REG_FUNC_1,
|
|
|
|
CMPCI_REG_DAC_FS_SHIFT,
|
|
|
|
CMPCI_REG_DAC_FS_MASK,
|
|
|
|
r);
|
2001-12-17 01:39:36 +00:00
|
|
|
if (speed >= 44100 && ch->parent->spdif_enabled) {
|
|
|
|
/* enable if req after rate change */
|
2001-02-04 19:13:40 +00:00
|
|
|
cmi_spdif_speed(ch->parent, speed);
|
2001-12-17 01:39:36 +00:00
|
|
|
}
|
2001-02-04 19:13:40 +00:00
|
|
|
rsp = cmi_rd(ch->parent, CMPCI_REG_FUNC_1, 4);
|
|
|
|
rsp >>= CMPCI_REG_DAC_FS_SHIFT;
|
|
|
|
rsp &= CMPCI_REG_DAC_FS_MASK;
|
|
|
|
} else {
|
|
|
|
cmi_partial_wr4(ch->parent,
|
|
|
|
CMPCI_REG_FUNC_1,
|
|
|
|
CMPCI_REG_ADC_FS_SHIFT,
|
|
|
|
CMPCI_REG_ADC_FS_MASK,
|
|
|
|
r);
|
|
|
|
rsp = cmi_rd(ch->parent, CMPCI_REG_FUNC_1, 4);
|
|
|
|
rsp >>= CMPCI_REG_ADC_FS_SHIFT;
|
|
|
|
rsp &= CMPCI_REG_ADC_FS_MASK;
|
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
ch->spd = cmpci_regvalue_to_rate(r);
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
DEB(printf("cmichan_setspeed (%s) %d -> %d (%d)\n",
|
2001-02-04 19:13:40 +00:00
|
|
|
(ch->dir == PCMDIR_PLAY) ? "play" : "rec",
|
|
|
|
speed, ch->spd, cmpci_regvalue_to_rate(rsp)));
|
|
|
|
|
|
|
|
return ch->spd;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2001-02-04 19:13:40 +00:00
|
|
|
cmichan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
|
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo *ch = data;
|
2001-10-10 17:56:35 +00:00
|
|
|
struct sc_info *sc = ch->parent;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
/* user has requested interrupts every blocksize bytes */
|
2001-10-10 17:56:35 +00:00
|
|
|
if (blocksize > sc->bufsz / CMI_INTR_PER_BUFFER) {
|
|
|
|
blocksize = sc->bufsz / CMI_INTR_PER_BUFFER;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
sndbuf_resize(ch->buffer, CMI_INTR_PER_BUFFER, blocksize);
|
|
|
|
|
2001-09-03 00:45:00 +00:00
|
|
|
return blocksize;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmichan_trigger(kobj_t obj, void *data, int go)
|
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2007-06-11 00:49:46 +00:00
|
|
|
if (!PCMTRIG_COMMON(go))
|
|
|
|
return 0;
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
if (ch->dir == PCMDIR_PLAY) {
|
|
|
|
switch(go) {
|
|
|
|
case PCMTRIG_START:
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_ch0_start(sc, ch);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
2007-06-11 00:49:46 +00:00
|
|
|
case PCMTRIG_STOP:
|
2001-02-04 19:13:40 +00:00
|
|
|
case PCMTRIG_ABORT:
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_ch0_stop(sc, ch);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2001-03-05 17:51:28 +00:00
|
|
|
} else {
|
2001-02-04 19:13:40 +00:00
|
|
|
switch(go) {
|
|
|
|
case PCMTRIG_START:
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_ch1_start(sc, ch);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
2007-06-11 00:49:46 +00:00
|
|
|
case PCMTRIG_STOP:
|
2001-02-04 19:13:40 +00:00
|
|
|
case PCMTRIG_ABORT:
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_ch1_stop(sc, ch);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2001-02-04 19:13:40 +00:00
|
|
|
cmichan_getptr(kobj_t obj, void *data)
|
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_chinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t physptr, bufptr, sz;
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
if (ch->dir == PCMDIR_PLAY) {
|
2001-03-29 15:36:31 +00:00
|
|
|
physptr = cmi_rd(sc, CMPCI_REG_DMA0_BASE, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
} else {
|
2001-03-29 15:36:31 +00:00
|
|
|
physptr = cmi_rd(sc, CMPCI_REG_DMA1_BASE, 4);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
sz = sndbuf_getsize(ch->buffer);
|
2001-03-29 15:36:31 +00:00
|
|
|
bufptr = (physptr - ch->phys_buf + sz - ch->bps) % sz;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return bufptr;
|
|
|
|
}
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static void
|
|
|
|
cmi_intr(void *data)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc = data;
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t intrstat;
|
2003-11-11 05:38:28 +00:00
|
|
|
u_int32_t toclear;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
intrstat = cmi_rd(sc, CMPCI_REG_INTR_STATUS, 4);
|
2003-11-11 05:38:28 +00:00
|
|
|
if ((intrstat & CMPCI_REG_ANY_INTR) != 0) {
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
toclear = 0;
|
|
|
|
if (intrstat & CMPCI_REG_CH0_INTR) {
|
|
|
|
toclear |= CMPCI_REG_CH0_INTR_ENABLE;
|
|
|
|
//cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
|
|
|
|
}
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
if (intrstat & CMPCI_REG_CH1_INTR) {
|
|
|
|
toclear |= CMPCI_REG_CH1_INTR_ENABLE;
|
|
|
|
//cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
|
|
|
|
}
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
if (toclear) {
|
|
|
|
cmi_clr4(sc, CMPCI_REG_INTR_CTRL, toclear);
|
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
/* Signal interrupts to channel */
|
|
|
|
if (intrstat & CMPCI_REG_CH0_INTR) {
|
|
|
|
chn_intr(sc->pch.channel);
|
|
|
|
}
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
if (intrstat & CMPCI_REG_CH1_INTR) {
|
|
|
|
chn_intr(sc->rch.channel);
|
|
|
|
}
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
cmi_set4(sc, CMPCI_REG_INTR_CTRL, toclear);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2003-11-11 05:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
if(sc->mpu_intr) {
|
|
|
|
(sc->mpu_intr)(sc->mpu);
|
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps *
|
2001-02-04 19:13:40 +00:00
|
|
|
cmichan_getcaps(kobj_t obj, void *data)
|
|
|
|
{
|
|
|
|
return &cmi_caps;
|
|
|
|
}
|
|
|
|
|
|
|
|
static kobj_method_t cmichan_methods[] = {
|
|
|
|
KOBJMETHOD(channel_init, cmichan_init),
|
|
|
|
KOBJMETHOD(channel_setformat, cmichan_setformat),
|
|
|
|
KOBJMETHOD(channel_setspeed, cmichan_setspeed),
|
|
|
|
KOBJMETHOD(channel_setblocksize, cmichan_setblocksize),
|
|
|
|
KOBJMETHOD(channel_trigger, cmichan_trigger),
|
|
|
|
KOBJMETHOD(channel_getptr, cmichan_getptr),
|
|
|
|
KOBJMETHOD(channel_getcaps, cmichan_getcaps),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
2001-02-04 19:13:40 +00:00
|
|
|
};
|
|
|
|
CHANNEL_DECLARE(cmichan);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Mixer - sb16 with kinks */
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(struct sc_info *sc, u_int8_t port, u_int8_t val)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, CMPCI_REG_SBADDR, port, 1);
|
|
|
|
cmi_wr(sc, CMPCI_REG_SBDATA, val, 1);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static u_int8_t
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_rd(struct sc_info *sc, u_int8_t port)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, CMPCI_REG_SBADDR, port, 1);
|
|
|
|
return (u_int8_t)cmi_rd(sc, CMPCI_REG_SBDATA, 1);
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct sb16props {
|
|
|
|
u_int8_t rreg; /* right reg chan register */
|
|
|
|
u_int8_t stereo:1; /* (no explanation needed, honest) */
|
|
|
|
u_int8_t rec:1; /* recording source */
|
|
|
|
u_int8_t bits:3; /* num bits to represent maximum gain rep */
|
|
|
|
u_int8_t oselect; /* output select mask */
|
|
|
|
u_int8_t iselect; /* right input select mask */
|
|
|
|
} static const cmt[SOUND_MIXER_NRDEVICES] = {
|
2001-03-05 17:51:28 +00:00
|
|
|
[SOUND_MIXER_SYNTH] = {CMPCI_SB16_MIXER_FM_R, 1, 1, 5,
|
2001-02-04 19:13:40 +00:00
|
|
|
CMPCI_SB16_SW_FM, CMPCI_SB16_MIXER_FM_SRC_R},
|
|
|
|
[SOUND_MIXER_CD] = {CMPCI_SB16_MIXER_CDDA_R, 1, 1, 5,
|
|
|
|
CMPCI_SB16_SW_CD, CMPCI_SB16_MIXER_CD_SRC_R},
|
|
|
|
[SOUND_MIXER_LINE] = {CMPCI_SB16_MIXER_LINE_R, 1, 1, 5,
|
|
|
|
CMPCI_SB16_SW_LINE, CMPCI_SB16_MIXER_LINE_SRC_R},
|
2001-03-05 17:51:28 +00:00
|
|
|
[SOUND_MIXER_MIC] = {CMPCI_SB16_MIXER_MIC, 0, 1, 5,
|
2001-02-04 19:13:40 +00:00
|
|
|
CMPCI_SB16_SW_MIC, CMPCI_SB16_MIXER_MIC_SRC},
|
|
|
|
[SOUND_MIXER_SPEAKER] = {CMPCI_SB16_MIXER_SPEAKER, 0, 0, 2, 0, 0},
|
|
|
|
[SOUND_MIXER_PCM] = {CMPCI_SB16_MIXER_VOICE_R, 1, 0, 5, 0, 0},
|
|
|
|
[SOUND_MIXER_VOLUME] = {CMPCI_SB16_MIXER_MASTER_R, 1, 0, 5, 0, 0},
|
|
|
|
/* These controls are not implemented in CMI8738, but maybe at a
|
|
|
|
future date. They are not documented in C-Media documentation,
|
|
|
|
though appear in other drivers for future h/w (ALSA, Linux, NetBSD).
|
|
|
|
*/
|
2001-03-05 17:51:28 +00:00
|
|
|
[SOUND_MIXER_IGAIN] = {CMPCI_SB16_MIXER_INGAIN_R, 1, 0, 2, 0, 0},
|
|
|
|
[SOUND_MIXER_OGAIN] = {CMPCI_SB16_MIXER_OUTGAIN_R, 1, 0, 2, 0, 0},
|
|
|
|
[SOUND_MIXER_BASS] = {CMPCI_SB16_MIXER_BASS_R, 1, 0, 4, 0, 0},
|
|
|
|
[SOUND_MIXER_TREBLE] = {CMPCI_SB16_MIXER_TREBLE_R, 1, 0, 4, 0, 0},
|
2001-03-29 15:36:31 +00:00
|
|
|
/* The mic pre-amp is implemented with non-SB16 compatible
|
|
|
|
registers. */
|
2001-02-04 19:13:40 +00:00
|
|
|
[SOUND_MIXER_MONITOR] = {CMPCI_NON_SB16_CONTROL, 0, 1, 4, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MIXER_GAIN_REG_RTOL(r) (r - 1)
|
|
|
|
|
|
|
|
static int
|
2001-03-24 23:10:29 +00:00
|
|
|
cmimix_init(struct snd_mixer *m)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc = mix_getdevinfo(m);
|
|
|
|
u_int32_t i,v;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
|
2001-02-04 19:13:40 +00:00
|
|
|
if (cmt[i].bits) v |= 1 << i;
|
|
|
|
}
|
|
|
|
mix_setdevs(m, v);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
for(i = v = 0; i < SOUND_MIXER_NRDEVICES; i++) {
|
|
|
|
if (cmt[i].rec) v |= 1 << i;
|
2001-02-04 19:13:40 +00:00
|
|
|
}
|
|
|
|
mix_setrecdevs(m, v);
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_RESET, 0);
|
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0);
|
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0);
|
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_OUTMIX,
|
2001-02-04 19:13:40 +00:00
|
|
|
CMPCI_SB16_SW_CD | CMPCI_SB16_SW_MIC | CMPCI_SB16_SW_LINE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-03-24 23:10:29 +00:00
|
|
|
cmimix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc = mix_getdevinfo(m);
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t r, l, max;
|
|
|
|
u_int8_t v;
|
|
|
|
|
|
|
|
max = (1 << cmt[dev].bits) - 1;
|
|
|
|
|
|
|
|
if (cmt[dev].rreg == CMPCI_NON_SB16_CONTROL) {
|
2001-03-29 15:36:31 +00:00
|
|
|
/* For time being this can only be one thing (mic in
|
|
|
|
* mic/aux reg) */
|
|
|
|
v = cmi_rd(sc, CMPCI_REG_AUX_MIC, 1) & 0xf0;
|
2001-02-04 19:13:40 +00:00
|
|
|
l = left * max / 100;
|
2001-03-29 15:36:31 +00:00
|
|
|
/* 3 bit gain with LSB MICGAIN off(1),on(1) -> 4 bit value */
|
2001-03-05 17:51:28 +00:00
|
|
|
v |= ((l << 1) | (~l >> 3)) & 0x0f;
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_wr(sc, CMPCI_REG_AUX_MIC, v, 1);
|
2001-02-04 19:13:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
l = (left * max / 100) << (8 - cmt[dev].bits);
|
|
|
|
if (cmt[dev].stereo) {
|
|
|
|
r = (right * max / 100) << (8 - cmt[dev].bits);
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, MIXER_GAIN_REG_RTOL(cmt[dev].rreg), l);
|
|
|
|
cmimix_wr(sc, cmt[dev].rreg, r);
|
2001-02-04 19:13:40 +00:00
|
|
|
DEBMIX(printf("Mixer stereo write dev %d reg 0x%02x "\
|
|
|
|
"value 0x%02x:0x%02x\n",
|
|
|
|
dev, MIXER_GAIN_REG_RTOL(cmt[dev].rreg), l, r));
|
|
|
|
} else {
|
|
|
|
r = l;
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, cmt[dev].rreg, l);
|
2001-02-04 19:13:40 +00:00
|
|
|
DEBMIX(printf("Mixer mono write dev %d reg 0x%02x " \
|
|
|
|
"value 0x%02x:0x%02x\n",
|
|
|
|
dev, cmt[dev].rreg, l, l));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero gain does not mute channel from output, but this does... */
|
2001-03-29 15:36:31 +00:00
|
|
|
v = cmimix_rd(sc, CMPCI_SB16_MIXER_OUTMIX);
|
2001-02-04 19:13:40 +00:00
|
|
|
if (l == 0 && r == 0) {
|
|
|
|
v &= ~cmt[dev].oselect;
|
|
|
|
} else {
|
|
|
|
v |= cmt[dev].oselect;
|
|
|
|
}
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_OUTMIX, v);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2001-03-24 23:10:29 +00:00
|
|
|
cmimix_setrecsrc(struct snd_mixer *m, u_int32_t src)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc = mix_getdevinfo(m);
|
2001-02-04 19:13:40 +00:00
|
|
|
u_int32_t i, ml, sl;
|
|
|
|
|
|
|
|
ml = sl = 0;
|
|
|
|
for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
|
|
|
|
if ((1<<i) & src) {
|
|
|
|
if (cmt[i].stereo) {
|
|
|
|
sl |= cmt[i].iselect;
|
|
|
|
} else {
|
|
|
|
ml |= cmt[i].iselect;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_R, sl|ml);
|
2001-02-04 19:13:40 +00:00
|
|
|
DEBMIX(printf("cmimix_setrecsrc: reg 0x%02x val 0x%02x\n",
|
2001-03-05 17:51:28 +00:00
|
|
|
CMPCI_SB16_MIXER_ADCMIX_R, sl|ml));
|
2001-02-04 19:13:40 +00:00
|
|
|
ml = CMPCI_SB16_MIXER_SRC_R_TO_L(ml);
|
2001-03-29 15:36:31 +00:00
|
|
|
cmimix_wr(sc, CMPCI_SB16_MIXER_ADCMIX_L, sl|ml);
|
2001-03-05 17:51:28 +00:00
|
|
|
DEBMIX(printf("cmimix_setrecsrc: reg 0x%02x val 0x%02x\n",
|
|
|
|
CMPCI_SB16_MIXER_ADCMIX_L, sl|ml));
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
2001-12-17 01:39:36 +00:00
|
|
|
/* Optional SPDIF support. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmi_initsys(struct sc_info* sc)
|
|
|
|
{
|
2006-06-18 14:14:41 +00:00
|
|
|
/* XXX: an user should be able to set this with a control tool,
|
|
|
|
if not done before 7.0-RELEASE, this needs to be converted
|
|
|
|
to a device specific sysctl "dev.pcm.X.yyy" via
|
|
|
|
device_get_sysctl_*() as discussed on multimedia@ in msg-id
|
|
|
|
<861wujij2q.fsf@xps.des.no> */
|
Welcome to Once-a-year Sound Mega-Commit. Enjoy numerous updates and fixes
in every sense.
General
-------
- Multichannel safe, endian safe, format safe
* Large part of critical pcm filters such as vchan.c, feeder_rate.c,
feeder_volume.c, feeder_fmt.c and feeder.c has been rewritten so that
using them does not cause the pcm data to be converted to 16bit little
endian.
* Macrosses for accessing pcm data safely are defined within sound.h in
the form of PCM_READ_* / PCM_WRITE_*
* Currently, most of them are probably limited for mono/stereo handling,
but the future addition of true multichannel will be much easier.
- Low latency operation
* Well, this require lot more works to do not just within sound driver,
but we're heading towards right direction. Buffer/block sizing within
channel.c is rewritten to calculate precise allocation for various
combination of sample/data/rate size. As a result, applying correct
SNDCTL_DSP_POLICY value will achive expected latency behaviour simmilar
to what commercial 4front driver do.
* Signal handling fix. ctrl+c of "cat /dev/zero > /dev/dsp" does not
result long delay.
* Eliminate sound truncation if the sound data is too small.
DIY:
1) Download / extract
http://people.freebsd.org/~ariff/lowlatency/shortfiles.tar.gz
2) Do a comparison between "cat state*.au > /dev/dsp" and
"for x in state*.au ; do cat $x > /dev/dsp ; done"
- there should be no "perceivable" differences.
Double close for PR kern/31445.
CAVEAT: Low latency come with (unbearable) price especially for poorly
written applications. Applications that trying to act smarter
by requesting (wrong) blocksize/blockcount will suffer the most.
Fixup samples/patches can be found at:
http://people.freebsd.org/~ariff/ports/
- Switch minimum/maximum sampling rate limit to "1" and "2016000" (48k * 42)
due to closer compatibility with 4front driver.
Discussed with: marcus@ (long time ago?)
- All driver specific sysctls in the form of "hw.snd.pcm%d.*" have been
moved to their own dev sysctl nodes, notably:
hw.snd.pcm%d.vchans -> dev.pcm.%d.vchans
Bump __FreeBSD_version.
Driver specific
---------------
- Ditto for sysctls.
- snd_atiixp, snd_es137x, snd_via8233, snd_hda
* Numerous cleanups and fixes.
* _EXPERIMENTAL_ polling mode support using simple callout_* mechanisme.
This was intended for pure debugging and latency measurement, but proven
good enough in few unexpected and rare cases (such as problematic shared
IRQ with GIANT devices - USB). Polling can be enabled/disabled through
dev.pcm.0.polling. Disabled by default.
- snd_ich
* Fix possible overflow during speed calibration. Delay final
initialization (pcm_setstatus) after calibration finished.
PR: kern/100169
Tested by: Kevin Overman <oberman@es.net>
* Inverted EAPD for few Nec VersaPro.
PR: kern/104715
Submitted by: KAWATA Masahiko <kawata@mta.biglobe.ne.jp>
Thanks to various people, notably Joel Dahl, Yuriy Tsibizov, Kevin Oberman,
those at #freebsd-azalia @ freenode and others for testing.
Joel Dahl will do the manpage update.
2006-11-26 12:24:06 +00:00
|
|
|
SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
|
|
|
|
OID_AUTO, "spdif_enabled", CTLFLAG_RW,
|
2001-12-17 01:39:36 +00:00
|
|
|
&sc->spdif_enabled, 0,
|
|
|
|
"enable SPDIF output at 44.1 kHz and above");
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
|
2001-12-17 01:39:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
2001-02-04 19:13:40 +00:00
|
|
|
static kobj_method_t cmi_mixer_methods[] = {
|
|
|
|
KOBJMETHOD(mixer_init, cmimix_init),
|
|
|
|
KOBJMETHOD(mixer_set, cmimix_set),
|
|
|
|
KOBJMETHOD(mixer_setrecsrc, cmimix_setrecsrc),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
2001-02-04 19:13:40 +00:00
|
|
|
};
|
|
|
|
MIXER_DECLARE(cmi_mixer);
|
|
|
|
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
/*
|
|
|
|
* mpu401 functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
static unsigned char
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
cmi_mread(struct mpu401 *arg, void *sc, int reg)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
|
|
|
unsigned int d;
|
|
|
|
|
|
|
|
d = bus_space_read_1(0,0, 0x330 + reg);
|
|
|
|
/* printf("cmi_mread: reg %x %x\n",reg, d);
|
|
|
|
*/
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
cmi_mwrite(struct mpu401 *arg, void *sc, int reg, unsigned char b)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
bus_space_write_1(0,0,0x330 + reg , b);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
cmi_muninit(struct mpu401 *arg, void *cookie)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
struct sc_info *sc = cookie;
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
sc->mpu_intr = 0;
|
|
|
|
sc->mpu = 0;
|
|
|
|
snd_mtxunlock(sc->lock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static kobj_method_t cmi_mpu_methods[] = {
|
|
|
|
KOBJMETHOD(mpufoi_read, cmi_mread),
|
|
|
|
KOBJMETHOD(mpufoi_write, cmi_mwrite),
|
|
|
|
KOBJMETHOD(mpufoi_uninit, cmi_muninit),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
};
|
|
|
|
|
2006-07-15 20:08:32 +00:00
|
|
|
static DEFINE_CLASS(cmi_mpu, cmi_mpu_methods, 0);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
cmi_midiattach(struct sc_info *sc) {
|
|
|
|
/*
|
|
|
|
const struct {
|
|
|
|
int port,bits;
|
|
|
|
} *p, ports[] = {
|
|
|
|
{0x330,0},
|
|
|
|
{0x320,1},
|
|
|
|
{0x310,2},
|
|
|
|
{0x300,3},
|
|
|
|
{0,0} } ;
|
|
|
|
Notes, CMPCI_REG_VMPUSEL sets the io port for the mpu. Does
|
|
|
|
anyone know how to bus_space tag?
|
|
|
|
*/
|
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_UART_ENABLE);
|
|
|
|
cmi_clr4(sc, CMPCI_REG_LEGACY_CTRL,
|
|
|
|
CMPCI_REG_VMPUSEL_MASK << CMPCI_REG_VMPUSEL_SHIFT);
|
|
|
|
cmi_set4(sc, CMPCI_REG_LEGACY_CTRL,
|
|
|
|
0 << CMPCI_REG_VMPUSEL_SHIFT );
|
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_UART_ENABLE);
|
|
|
|
sc->mpu = mpu401_init(&cmi_mpu_class, sc, cmi_intr, &sc->mpu_intr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Power and reset */
|
|
|
|
|
|
|
|
static void
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_power(struct sc_info *sc, int state)
|
2001-02-04 19:13:40 +00:00
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case 0: /* full power */
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_MISC, CMPCI_REG_POWER_DOWN);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* power off */
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_POWER_DOWN);
|
2001-02-04 19:13:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
static int
|
|
|
|
cmi_init(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
/* Effect reset */
|
|
|
|
cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_BUS_AND_DSP_RESET);
|
|
|
|
DELAY(100);
|
|
|
|
cmi_clr4(sc, CMPCI_REG_MISC, CMPCI_REG_BUS_AND_DSP_RESET);
|
|
|
|
|
|
|
|
/* Disable interrupts and channels */
|
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0,
|
|
|
|
CMPCI_REG_CH0_ENABLE | CMPCI_REG_CH1_ENABLE);
|
2001-04-04 13:48:33 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_INTR_CTRL,
|
|
|
|
CMPCI_REG_CH0_INTR_ENABLE | CMPCI_REG_CH1_INTR_ENABLE);
|
|
|
|
|
|
|
|
/* Configure DMA channels, ch0 = play, ch1 = capture */
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_DIR);
|
|
|
|
cmi_set4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
/* Attempt to enable 4 Channel output */
|
2001-06-16 21:25:10 +00:00
|
|
|
cmi_set4(sc, CMPCI_REG_MISC, CMPCI_REG_N4SPK3D);
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
/* Disable SPDIF1 - not compatible with config */
|
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF1_ENABLE);
|
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
|
|
|
|
|
|
|
|
return 0;
|
2001-06-16 21:25:10 +00:00
|
|
|
}
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
cmi_uninit(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
/* Disable interrupts and channels */
|
|
|
|
cmi_clr4(sc, CMPCI_REG_INTR_CTRL,
|
|
|
|
CMPCI_REG_CH0_INTR_ENABLE |
|
|
|
|
CMPCI_REG_CH1_INTR_ENABLE |
|
|
|
|
CMPCI_REG_TDMA_INTR_ENABLE);
|
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_0,
|
|
|
|
CMPCI_REG_CH0_ENABLE | CMPCI_REG_CH1_ENABLE);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
cmi_clr4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_UART_ENABLE);
|
|
|
|
|
|
|
|
if( sc->mpu )
|
|
|
|
sc->mpu_intr = 0;
|
2001-03-29 15:36:31 +00:00
|
|
|
}
|
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Bus and device registration */
|
|
|
|
static int
|
|
|
|
cmi_probe(device_t dev)
|
|
|
|
{
|
|
|
|
switch(pci_get_devid(dev)) {
|
|
|
|
case CMI8338A_PCI_ID:
|
|
|
|
device_set_desc(dev, "CMedia CMI8338A");
|
2005-03-01 08:58:06 +00:00
|
|
|
return BUS_PROBE_DEFAULT;
|
2001-02-04 19:13:40 +00:00
|
|
|
case CMI8338B_PCI_ID:
|
|
|
|
device_set_desc(dev, "CMedia CMI8338B");
|
2005-03-01 08:58:06 +00:00
|
|
|
return BUS_PROBE_DEFAULT;
|
2001-02-04 19:13:40 +00:00
|
|
|
case CMI8738_PCI_ID:
|
|
|
|
device_set_desc(dev, "CMedia CMI8738");
|
2005-03-01 08:58:06 +00:00
|
|
|
return BUS_PROBE_DEFAULT;
|
2001-02-04 19:13:40 +00:00
|
|
|
case CMI8738B_PCI_ID:
|
|
|
|
device_set_desc(dev, "CMedia CMI8738B");
|
2005-03-01 08:58:06 +00:00
|
|
|
return BUS_PROBE_DEFAULT;
|
2009-01-18 04:29:42 +00:00
|
|
|
case CMI120_USB_ID:
|
|
|
|
device_set_desc(dev, "CMedia CMI120");
|
|
|
|
return BUS_PROBE_DEFAULT;
|
2001-02-04 19:13:40 +00:00
|
|
|
default:
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-05 17:51:28 +00:00
|
|
|
static int
|
2001-02-04 19:13:40 +00:00
|
|
|
cmi_attach(device_t dev)
|
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc;
|
|
|
|
char status[SND_STATUSLEN];
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2007-06-17 06:10:43 +00:00
|
|
|
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
|
Fix severe out-of-bound mtx "type" pointer, causing WITNESS refcount
confusions and panic provided that the following conditions are met:
1) WITNESS is enabled (watch/trace).
2) Using modules, instead of statically linked (Not a strict
requirement, but easier to reproduce this way).
3) 2 or more modules share the same mtx type ("sound softc").
- They might share the same name (strcmp() == 0), but it always
point to different address.
4) Repetitive kldunload/load on any module that shares the same mtx
type (Not a strict requirement, but easier to reproduce this way).
Consider module A and module B:
- From enroll() - subr_witness.c:
* Load module A. Everything seems fine right now.
wA-w_refcount == 1 ; wA-w_name = "sound softc"
* Load module B.
* w->w_name == description will always fail.
("sound softc" from A and B point to different address).
* wA->w_refcount > 0 && strcmp(description, wA->w_name) == 0
* enroll() will return wA instead of returning (possibly unique)
wB.
wA->w_refcount++ , == 2.
* Unload module A, mtx_destroy(), wA->w_name become invalid,
but wA->w_refcount-- become 1 instead of 0. wA will not be
removed from witness list.
* Some other places call mtx_init(), iterating witness list,
found wA, failed on wA->w_name == description
* wA->w_refcount > 0 && strcmp(description, wA->w_name)
* Panic on strcmp() since wA->w_name no longer point to valid
address.
Note that this could happened in other places as well, not just sound
(eg. consider lots of drivers that share simmilar MTX_NETWORK_LOCK).
Solutions (for sound case):
1) Provide unique mtx type string for each mutex creation (chosen)
or
2) Put "sound softc" global variable somewhere and use it.
2007-03-15 16:41:27 +00:00
|
|
|
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_cmi softc");
|
2013-08-12 23:30:01 +00:00
|
|
|
pci_enable_busmaster(dev);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-12-17 01:39:36 +00:00
|
|
|
sc->dev = dev;
|
2003-09-02 17:30:40 +00:00
|
|
|
sc->regid = PCIR_BAR(0);
|
2005-02-01 07:43:34 +00:00
|
|
|
sc->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->regid,
|
|
|
|
RF_ACTIVE);
|
2001-03-29 15:36:31 +00:00
|
|
|
if (!sc->reg) {
|
2001-02-04 19:13:40 +00:00
|
|
|
device_printf(dev, "cmi_attach: Cannot allocate bus resource\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
2001-03-29 15:36:31 +00:00
|
|
|
sc->st = rman_get_bustag(sc->reg);
|
|
|
|
sc->sh = rman_get_bushandle(sc->reg);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2007-04-08 07:52:27 +00:00
|
|
|
if (0)
|
|
|
|
cmi_midiattach(sc);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
sc->irqid = 0;
|
2004-03-17 17:50:55 +00:00
|
|
|
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
|
|
|
|
RF_ACTIVE | RF_SHAREABLE);
|
2001-03-29 15:36:31 +00:00
|
|
|
if (!sc->irq ||
|
2004-04-21 04:23:51 +00:00
|
|
|
snd_setup_intr(dev, sc->irq, INTR_MPSAFE, cmi_intr, sc, &sc->ih)) {
|
2001-02-04 19:13:40 +00:00
|
|
|
device_printf(dev, "cmi_attach: Unable to map interrupt\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-10-10 17:56:35 +00:00
|
|
|
sc->bufsz = pcm_getbuffersize(dev, 4096, CMI_DEFAULT_BUFSZ, 65536);
|
|
|
|
|
2007-02-23 13:47:34 +00:00
|
|
|
if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
|
|
|
|
/*boundary*/0,
|
2001-02-04 19:13:40 +00:00
|
|
|
/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
|
|
|
|
/*highaddr*/BUS_SPACE_MAXADDR,
|
|
|
|
/*filter*/NULL, /*filterarg*/NULL,
|
2001-10-10 17:56:35 +00:00
|
|
|
/*maxsize*/sc->bufsz, /*nsegments*/1,
|
2001-03-05 17:51:28 +00:00
|
|
|
/*maxsegz*/0x3ffff, /*flags*/0,
|
2005-07-31 12:38:22 +00:00
|
|
|
/*lockfunc*/NULL,
|
|
|
|
/*lockfunc*/NULL,
|
2001-03-29 15:36:31 +00:00
|
|
|
&sc->parent_dmat) != 0) {
|
2001-02-04 19:13:40 +00:00
|
|
|
device_printf(dev, "cmi_attach: Unable to create dma tag\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_power(sc, 0);
|
2001-04-04 13:48:33 +00:00
|
|
|
if (cmi_init(sc))
|
|
|
|
goto bad;
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
if (mixer_init(dev, &cmi_mixer_class, sc))
|
2001-03-05 17:51:28 +00:00
|
|
|
goto bad;
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
if (pcm_register(dev, sc, 1, 1))
|
2001-02-04 19:13:40 +00:00
|
|
|
goto bad;
|
|
|
|
|
2001-12-17 01:39:36 +00:00
|
|
|
cmi_initsys(sc);
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
pcm_addchan(dev, PCMDIR_PLAY, &cmichan_class, sc);
|
|
|
|
pcm_addchan(dev, PCMDIR_REC, &cmichan_class, sc);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2004-03-06 15:52:42 +00:00
|
|
|
snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s",
|
|
|
|
rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_cmi));
|
2001-02-04 19:13:40 +00:00
|
|
|
pcm_setstatus(dev, status);
|
|
|
|
|
|
|
|
DEB(printf("cmi_attach: succeeded\n"));
|
|
|
|
return 0;
|
2001-03-05 17:51:28 +00:00
|
|
|
|
2001-02-04 19:13:40 +00:00
|
|
|
bad:
|
2001-06-16 21:25:10 +00:00
|
|
|
if (sc->parent_dmat)
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_dma_tag_destroy(sc->parent_dmat);
|
2001-06-16 21:25:10 +00:00
|
|
|
if (sc->ih)
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_teardown_intr(dev, sc->irq, sc->ih);
|
2001-06-16 21:25:10 +00:00
|
|
|
if (sc->irq)
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
|
2001-06-16 21:25:10 +00:00
|
|
|
if (sc->reg)
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, sc->regid, sc->reg);
|
2001-09-08 05:20:52 +00:00
|
|
|
if (sc->lock)
|
|
|
|
snd_mtxfree(sc->lock);
|
2001-06-16 21:25:10 +00:00
|
|
|
if (sc)
|
2001-03-29 15:36:31 +00:00
|
|
|
free(sc, M_DEVBUF);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmi_detach(device_t dev)
|
|
|
|
{
|
2001-03-29 15:36:31 +00:00
|
|
|
struct sc_info *sc;
|
2001-02-04 19:13:40 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
r = pcm_unregister(dev);
|
|
|
|
if (r) return r;
|
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
sc = pcm_getdevinfo(dev);
|
|
|
|
cmi_uninit(sc);
|
|
|
|
cmi_power(sc, 3);
|
2001-02-04 19:13:40 +00:00
|
|
|
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_dma_tag_destroy(sc->parent_dmat);
|
|
|
|
bus_teardown_intr(dev, sc->irq, sc->ih);
|
|
|
|
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
if(sc->mpu)
|
|
|
|
mpu401_uninit(sc->mpu);
|
2001-03-29 15:36:31 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, sc->regid, sc->reg);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
if (sc->mpu_reg)
|
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, sc->mpu_regid, sc->mpu_reg);
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxfree(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
free(sc, M_DEVBUF);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmi_suspend(device_t dev)
|
|
|
|
{
|
|
|
|
struct sc_info *sc = pcm_getdevinfo(dev);
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
sc->pch.dma_was_active = cmi_ch0_stop(sc, &sc->pch);
|
|
|
|
sc->rch.dma_was_active = cmi_ch1_stop(sc, &sc->rch);
|
|
|
|
cmi_power(sc, 3);
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmi_resume(device_t dev)
|
|
|
|
{
|
|
|
|
struct sc_info *sc = pcm_getdevinfo(dev);
|
|
|
|
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
cmi_power(sc, 0);
|
|
|
|
if (cmi_init(sc) != 0) {
|
|
|
|
device_printf(dev, "unable to reinitialize the card\n");
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mixer_reinit(dev) == -1) {
|
|
|
|
device_printf(dev, "unable to reinitialize the mixer\n");
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-03-29 15:36:31 +00:00
|
|
|
return ENXIO;
|
2001-06-16 21:25:10 +00:00
|
|
|
}
|
2001-03-29 15:36:31 +00:00
|
|
|
|
|
|
|
if (sc->pch.dma_was_active) {
|
|
|
|
cmichan_setspeed(NULL, &sc->pch, sc->pch.spd);
|
|
|
|
cmichan_setformat(NULL, &sc->pch, sc->pch.fmt);
|
|
|
|
cmi_ch0_start(sc, &sc->pch);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sc->rch.dma_was_active) {
|
|
|
|
cmichan_setspeed(NULL, &sc->rch, sc->rch.spd);
|
|
|
|
cmichan_setformat(NULL, &sc->rch, sc->rch.fmt);
|
|
|
|
cmi_ch1_start(sc, &sc->rch);
|
|
|
|
}
|
2001-09-08 05:20:52 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2001-02-04 19:13:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static device_method_t cmi_methods[] = {
|
|
|
|
DEVMETHOD(device_probe, cmi_probe),
|
|
|
|
DEVMETHOD(device_attach, cmi_attach),
|
|
|
|
DEVMETHOD(device_detach, cmi_detach),
|
2001-03-29 15:36:31 +00:00
|
|
|
DEVMETHOD(device_resume, cmi_resume),
|
|
|
|
DEVMETHOD(device_suspend, cmi_suspend),
|
2001-02-04 19:13:40 +00:00
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t cmi_driver = {
|
|
|
|
"pcm",
|
|
|
|
cmi_methods,
|
2001-08-23 11:30:52 +00:00
|
|
|
PCM_SOFTC_SIZE
|
2001-02-04 19:13:40 +00:00
|
|
|
};
|
|
|
|
|
2001-10-24 21:35:31 +00:00
|
|
|
DRIVER_MODULE(snd_cmi, pci, cmi_driver, pcm_devclass, 0, 0);
|
2004-07-16 04:00:08 +00:00
|
|
|
MODULE_DEPEND(snd_cmi, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
MODULE_DEPEND(snd_cmi, midi, 1,1,1);
|
2001-10-24 21:35:31 +00:00
|
|
|
MODULE_VERSION(snd_cmi, 1);
|