mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
sound fixes for 6.4-rc1
Here are collections of small fixes for rc1. The only (LOC-wise) dominant change was ASoC Qualcomm fix, but most of it was merely a code shuffling. Another significant change here is for ALSA PCM core; it received a revert and a series of fixes for PCM auto-silencing where it caused a regression in the previous PR for rc1. Others are all small: ASoC Intel fixes, various quirks for ASoC AMD, HD-audio and USB-audio, the continued legacy emu10k1 code cleanup, and some documentation updates. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmRWACMOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8vPA//Vh+gO0e1wcmCqeoIIJUwr5G0hQYY2Fp5Ke6A 3MuQAW3JyZ7hj5Xkor1PRalelinHUuvGMFDeazLnr92MV9zplnTisbKxp7EmDhJE 3iEdvj9evKTyMk7RpIhX1rhrHy0QLaCHDgDZDrv7IapyDpLUOl0lFtJQrlYV8DbS b0uSBJ/kpMi5AH+W7RWpdnPIFd2j8tDiyKGBDpAo3l8TIjkwdsdKo9jBz7uNpf0R tL8J6U4dA/Yo86XPAwg0g5tkug0vWOhZY8tdqNvJJFNgo9dW8ofqkCC4lg7JSmqM ugTm/l0CZnEC09t2GSw7k7bsUGxZkWus7r8PTEw9CryGsR2pQYAvcjMMFpXqTu6K Rc0PPkvFdmX2PIGtbkebwr/5y5Dbr2SmzqJjdkOSH91PZdle9RwN6k19dlXi1OFr ucS9g5gAxGWMNwOnLFud3x+qIN1XwZuuHI1CZd7jhlQ3krV+dEl6m9sttFs4saPs MNCMOXdVcKZ6NCBPRaCCwAEgP6Ttitdj25edTy1tKMr3td7ECInXQZiAPlAXLLwm 8aRscx07jj9cpfuk9fBTBvZdiAoK9KqYCLFSle4DzOJkyLuA9OiVFp3iixeoVIsb fRQdaYdwq166SWtJSBbsRnfxI5zxKhxz/vx0SLNf32Flh2SyIU0kQ6Wk88V716L7 D4tPskk= =jd8l -----END PGP SIGNATURE----- Merge tag 'sound-fix-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of small fixes for rc1. The only (LOC-wise) dominant change was ASoC Qualcomm fix, but most of it was merely a code shuffling. Another significant change here is for ALSA PCM core; it received a revert and a series of fixes for PCM auto-silencing where it caused a regression in the previous PR for rc1. Others are all small: ASoC Intel fixes, various quirks for ASoC AMD, HD-audio and USB-audio, the continued legacy emu10k1 code cleanup, and some documentation updates" * tag 'sound-fix-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (23 commits) ALSA: pcm: use exit controlled loop in snd_pcm_playback_silence() ALSA: pcm: simplify top-up mode init in snd_pcm_playback_silence() ALSA: pcm: playback silence - move silence variable updates to separate function ALSA: pcm: playback silence - remove extra code ALSA: pcm: fix playback silence - correct incremental silencing ALSA: pcm: fix playback silence - use the actual new_hw_ptr for the threshold mode ALSA: pcm: Revert "ALSA: pcm: rewrite snd_pcm_playback_silence()" ALSA: hda/realtek: Fix mute and micmute LEDs for an HP laptop ALSA: caiaq: input: Add error handling for unsupported input methods in `snd_usb_caiaq_input_init` ALSA: usb-audio: Add quirk for Pioneer DDJ-800 ALSA: hda/realtek: support HP Pavilion Aero 13-be0xxx Mute LED ASoC: Intel: soc-acpi-cht: Add quirk for Nextbook Ares 8A tablet ASoC: amd: yc: Add Asus VivoBook Pro 14 OLED M6400RC to the quirks list for acp6x ASoC: codecs: wcd938x: fix accessing regmap on unattached devices ALSA: docs: Fix code block indentation in ALSA driver example ALSA: docs: Extend module parameters description ALSA: hda/realtek: Add quirk for ASUS UM3402YAR using CS35L41 ALSA: emu10k1: use more existing defines instead of open-coded numbers ASoC: amd: yc: Add ASUS M3402RA into DMI table ALSA: hda/realtek: Add quirk for ThinkPad P1 Gen 6 ...
This commit is contained in:
commit
0021b532b2
@ -133,6 +133,19 @@ enable
|
||||
enable card;
|
||||
Default: enabled, for PCI and ISA PnP cards
|
||||
|
||||
These options are used for either specifying the order of instances or
|
||||
controlling enabling and disabling of each one of the devices if there
|
||||
are multiple devices bound with the same driver. For example, there are
|
||||
many machines which have two HD-audio controllers (one for HDMI/DP
|
||||
audio and another for onboard analog). In most cases, the second one is
|
||||
in primary usage, and people would like to assign it as the first
|
||||
appearing card. They can do it by specifying "index=1,0" module
|
||||
parameter, which will swap the assignment slots.
|
||||
|
||||
Today, with the sound backend like PulseAudio and PipeWire which
|
||||
supports dynamic configuration, it's of little use, but that was a
|
||||
help for static configuration in the past.
|
||||
|
||||
Module snd-adlib
|
||||
----------------
|
||||
|
||||
|
@ -3994,21 +3994,21 @@ Driver with A Single Source File
|
||||
|
||||
Suppose you have a file xyz.c. Add the following two lines::
|
||||
|
||||
snd-xyz-objs := xyz.o
|
||||
obj-$(CONFIG_SND_XYZ) += snd-xyz.o
|
||||
snd-xyz-objs := xyz.o
|
||||
obj-$(CONFIG_SND_XYZ) += snd-xyz.o
|
||||
|
||||
2. Create the Kconfig entry
|
||||
|
||||
Add the new entry of Kconfig for your xyz driver::
|
||||
|
||||
config SND_XYZ
|
||||
tristate "Foobar XYZ"
|
||||
depends on SND
|
||||
select SND_PCM
|
||||
help
|
||||
Say Y here to include support for Foobar XYZ soundcard.
|
||||
To compile this driver as a module, choose M here:
|
||||
the module will be called snd-xyz.
|
||||
config SND_XYZ
|
||||
tristate "Foobar XYZ"
|
||||
depends on SND
|
||||
select SND_PCM
|
||||
help
|
||||
Say Y here to include support for Foobar XYZ soundcard.
|
||||
To compile this driver as a module, choose M here:
|
||||
the module will be called snd-xyz.
|
||||
|
||||
The line ``select SND_PCM`` specifies that the driver xyz supports PCM.
|
||||
In addition to SND_PCM, the following components are supported for
|
||||
@ -4032,7 +4032,7 @@ located in the new subdirectory, sound/pci/xyz.
|
||||
1. Add a new directory (``sound/pci/xyz``) in ``sound/pci/Makefile``
|
||||
as below::
|
||||
|
||||
obj-$(CONFIG_SND) += sound/pci/xyz/
|
||||
obj-$(CONFIG_SND) += sound/pci/xyz/
|
||||
|
||||
|
||||
2. Under the directory ``sound/pci/xyz``, create a Makefile::
|
||||
|
@ -33,6 +33,25 @@
|
||||
static int fill_silence_frames(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t off, snd_pcm_uframes_t frames);
|
||||
|
||||
|
||||
static inline void update_silence_vars(struct snd_pcm_runtime *runtime,
|
||||
snd_pcm_uframes_t ptr,
|
||||
snd_pcm_uframes_t new_ptr)
|
||||
{
|
||||
snd_pcm_sframes_t delta;
|
||||
|
||||
delta = new_ptr - ptr;
|
||||
if (delta == 0)
|
||||
return;
|
||||
if (delta < 0)
|
||||
delta += runtime->boundary;
|
||||
if ((snd_pcm_uframes_t)delta < runtime->silence_filled)
|
||||
runtime->silence_filled -= delta;
|
||||
else
|
||||
runtime->silence_filled = 0;
|
||||
runtime->silence_start = new_ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* fill ring buffer with silence
|
||||
* runtime->silence_start: starting pointer to silence area
|
||||
@ -42,47 +61,67 @@ static int fill_silence_frames(struct snd_pcm_substream *substream,
|
||||
*
|
||||
* when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
|
||||
*/
|
||||
void snd_pcm_playback_silence(struct snd_pcm_substream *substream)
|
||||
void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_uframes_t appl_ptr = READ_ONCE(runtime->control->appl_ptr);
|
||||
snd_pcm_sframes_t added, hw_avail, frames;
|
||||
snd_pcm_uframes_t noise_dist, ofs, transfer;
|
||||
snd_pcm_uframes_t frames, ofs, transfer;
|
||||
int err;
|
||||
|
||||
added = appl_ptr - runtime->silence_start;
|
||||
if (added) {
|
||||
if (added < 0)
|
||||
added += runtime->boundary;
|
||||
if (added < runtime->silence_filled)
|
||||
runtime->silence_filled -= added;
|
||||
else
|
||||
runtime->silence_filled = 0;
|
||||
runtime->silence_start = appl_ptr;
|
||||
}
|
||||
|
||||
// This will "legitimately" turn negative on underrun, and will be mangled
|
||||
// into a huge number by the boundary crossing handling. The initial state
|
||||
// might also be not quite sane. The code below MUST account for these cases.
|
||||
hw_avail = appl_ptr - runtime->status->hw_ptr;
|
||||
if (hw_avail < 0)
|
||||
hw_avail += runtime->boundary;
|
||||
|
||||
noise_dist = hw_avail + runtime->silence_filled;
|
||||
if (runtime->silence_size < runtime->boundary) {
|
||||
frames = runtime->silence_threshold - noise_dist;
|
||||
if (frames <= 0)
|
||||
snd_pcm_sframes_t noise_dist;
|
||||
snd_pcm_uframes_t appl_ptr = READ_ONCE(runtime->control->appl_ptr);
|
||||
update_silence_vars(runtime, runtime->silence_start, appl_ptr);
|
||||
/* initialization outside pointer updates */
|
||||
if (new_hw_ptr == ULONG_MAX)
|
||||
new_hw_ptr = runtime->status->hw_ptr;
|
||||
/* get hw_avail with the boundary crossing */
|
||||
noise_dist = appl_ptr - new_hw_ptr;
|
||||
if (noise_dist < 0)
|
||||
noise_dist += runtime->boundary;
|
||||
/* total noise distance */
|
||||
noise_dist += runtime->silence_filled;
|
||||
if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
|
||||
return;
|
||||
frames = runtime->silence_threshold - noise_dist;
|
||||
if (frames > runtime->silence_size)
|
||||
frames = runtime->silence_size;
|
||||
} else {
|
||||
frames = runtime->buffer_size - noise_dist;
|
||||
if (frames <= 0)
|
||||
return;
|
||||
/*
|
||||
* This filling mode aims at free-running mode (used for example by dmix),
|
||||
* which doesn't update the application pointer.
|
||||
*/
|
||||
snd_pcm_uframes_t hw_ptr = runtime->status->hw_ptr;
|
||||
if (new_hw_ptr == ULONG_MAX) {
|
||||
/*
|
||||
* Initialization, fill the whole unused buffer with silence.
|
||||
*
|
||||
* Usually, this is entered while stopped, before data is queued,
|
||||
* so both pointers are expected to be zero.
|
||||
*/
|
||||
snd_pcm_sframes_t avail = runtime->control->appl_ptr - hw_ptr;
|
||||
if (avail < 0)
|
||||
avail += runtime->boundary;
|
||||
/*
|
||||
* In free-running mode, appl_ptr will be zero even while running,
|
||||
* so we end up with a huge number. There is no useful way to
|
||||
* handle this, so we just clear the whole buffer.
|
||||
*/
|
||||
runtime->silence_filled = avail > runtime->buffer_size ? 0 : avail;
|
||||
runtime->silence_start = hw_ptr;
|
||||
} else {
|
||||
/* Silence the just played area immediately */
|
||||
update_silence_vars(runtime, hw_ptr, new_hw_ptr);
|
||||
}
|
||||
/*
|
||||
* In this mode, silence_filled actually includes the valid
|
||||
* sample data from the user.
|
||||
*/
|
||||
frames = runtime->buffer_size - runtime->silence_filled;
|
||||
}
|
||||
|
||||
if (snd_BUG_ON(frames > runtime->buffer_size))
|
||||
return;
|
||||
if (frames == 0)
|
||||
return;
|
||||
ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
|
||||
do {
|
||||
transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
|
||||
@ -425,6 +464,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream, new_hw_ptr);
|
||||
|
||||
if (in_interrupt) {
|
||||
delta = new_hw_ptr - runtime->hw_ptr_interrupt;
|
||||
if (delta < 0)
|
||||
@ -442,10 +485,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
runtime->hw_ptr_wrap += runtime->boundary;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream);
|
||||
|
||||
update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
|
||||
|
||||
return snd_pcm_update_state(substream, runtime);
|
||||
|
@ -29,7 +29,8 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_runtime *runtime);
|
||||
int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
|
||||
|
||||
void snd_pcm_playback_silence(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_playback_silence(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t new_hw_ptr);
|
||||
|
||||
static inline snd_pcm_uframes_t
|
||||
snd_pcm_avail(struct snd_pcm_substream *substream)
|
||||
|
@ -958,7 +958,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
|
||||
if (snd_pcm_running(substream)) {
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream);
|
||||
snd_pcm_playback_silence(substream, ULONG_MAX);
|
||||
err = snd_pcm_update_state(substream, runtime);
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
@ -1455,7 +1455,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
|
||||
__snd_pcm_set_state(runtime, state);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream);
|
||||
snd_pcm_playback_silence(substream, ULONG_MAX);
|
||||
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
|
||||
}
|
||||
|
||||
@ -1916,7 +1916,7 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
|
||||
runtime->control->appl_ptr = runtime->status->hw_ptr;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream);
|
||||
snd_pcm_playback_silence(substream, ULONG_MAX);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
}
|
||||
|
||||
|
@ -120,9 +120,9 @@ release_voice(struct snd_emux_voice *vp)
|
||||
struct snd_emu10k1 *hw;
|
||||
|
||||
hw = vp->hw;
|
||||
dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
|
||||
dcysusv = (unsigned char)vp->reg.parm.modrelease | DCYSUSM_PHASE1_MASK;
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
|
||||
dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
|
||||
dcysusv = (unsigned char)vp->reg.parm.volrelease | DCYSUSV_PHASE1_MASK | DCYSUSV_CHANNELENABLE_MASK;
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
|
||||
}
|
||||
|
||||
@ -138,7 +138,8 @@ terminate_voice(struct snd_emux_voice *vp)
|
||||
if (snd_BUG_ON(!vp))
|
||||
return;
|
||||
hw = vp->hw;
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch,
|
||||
DCYSUSV_PHASE1_MASK | DCYSUSV_DECAYTIME_MASK | DCYSUSV_CHANNELENABLE_MASK);
|
||||
if (vp->block) {
|
||||
struct snd_emu10k1_memblk *emem;
|
||||
emem = (struct snd_emu10k1_memblk *)vp->block;
|
||||
@ -347,9 +348,9 @@ start_voice(struct snd_emux_voice *vp)
|
||||
}
|
||||
|
||||
/* channel to be silent and idle */
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
|
||||
snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
|
||||
snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
|
||||
snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0);
|
||||
snd_emu10k1_ptr_write(hw, VTFT, ch, VTFT_FILTERTARGET_MASK);
|
||||
snd_emu10k1_ptr_write(hw, CVCF, ch, CVCF_CURRENTFILTER_MASK);
|
||||
snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
|
||||
snd_emu10k1_ptr_write(hw, CPF, ch, 0);
|
||||
|
||||
@ -453,7 +454,7 @@ start_voice(struct snd_emux_voice *vp)
|
||||
/* reset volume */
|
||||
temp = (unsigned int)vp->vtarget << 16;
|
||||
snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
|
||||
snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
|
||||
snd_emu10k1_ptr_write(hw, CVCF, ch, temp | CVCF_CURRENTFILTER_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
|
||||
{
|
||||
snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, IP, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, ch, VTFT_FILTERTARGET_MASK);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, ch, CVCF_CURRENTFILTER_MASK);
|
||||
snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, CPF, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, CCR, ch, 0);
|
||||
@ -74,7 +74,7 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
|
||||
|
||||
snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, IFATN, ch, IFATN_FILTERCUTOFF_MASK | IFATN_ATTENUATION_MASK);
|
||||
snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
|
||||
@ -90,10 +90,10 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
|
||||
|
||||
/* Audigy extra stuffs */
|
||||
if (emu->audigy) {
|
||||
snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
|
||||
snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
|
||||
snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
|
||||
snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
|
||||
snd_emu10k1_ptr_write(emu, A_CSBA, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, A_CSDC, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, A_CSFE, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, A_CSHG, ch, 0);
|
||||
snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
|
||||
snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
|
||||
snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
|
||||
@ -259,7 +259,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir)
|
||||
|
||||
snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
|
||||
snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
|
||||
snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
|
||||
snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_256K); /* taken from original driver */
|
||||
|
||||
silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
|
||||
for (ch = 0; ch < NUM_G; ch++) {
|
||||
@ -818,7 +818,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
|
||||
/* FPGA netlist already present so clear it */
|
||||
/* Return to programming mode */
|
||||
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_HANA);
|
||||
}
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®);
|
||||
dev_dbg(emu->card->dev, "reg2 = 0x%x\n", reg);
|
||||
@ -858,36 +858,36 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
|
||||
/* Optical -> ADAT I/O */
|
||||
emu->emu1010.optical_in = 1; /* IN_ADAT */
|
||||
emu->emu1010.optical_out = 1; /* OUT_ADAT */
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
|
||||
/* Set no attenuation on Audio Dock pads. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
|
||||
emu->emu1010.adc_pads = 0x00;
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, emu->emu1010.adc_pads);
|
||||
/* Unmute Audio dock DACs, Headphone source DAC-4. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, EMU_HANA_DOCK_PHONES_192_DAC4);
|
||||
/* DAC PADs. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
|
||||
emu->emu1010.dac_pads = 0x0f;
|
||||
emu->emu1010.dac_pads = EMU_HANA_DOCK_DAC_PAD1 | EMU_HANA_DOCK_DAC_PAD2 |
|
||||
EMU_HANA_DOCK_DAC_PAD3 | EMU_HANA_DOCK_DAC_PAD4;
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, emu->emu1010.dac_pads);
|
||||
/* SPDIF Format. Set Consumer mode, 24bit, copy enable */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, EMU_HANA_SPDIF_MODE_RX_INVALID);
|
||||
/* MIDI routing */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
|
||||
/* Unknown. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, EMU_HANA_MIDI_INA_FROM_HAMOA | EMU_HANA_MIDI_INB_FROM_DOCK2);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, EMU_HANA_MIDI_OUT_DOCK2 | EMU_HANA_MIDI_OUT_SYNC2);
|
||||
/* IRQ Enable: All on */
|
||||
/* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
|
||||
/* snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x0f); */
|
||||
/* IRQ Enable: All off */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
|
||||
|
||||
emu->emu1010.internal_clock = 1; /* 48000 */
|
||||
/* Default WCLK set to 48kHz. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K);
|
||||
/* Word Clock source, Internal 48kHz x1 */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
|
||||
/* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
|
||||
/* Audio Dock LEDs. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_LOCK | EMU_HANA_DOCK_LEDS_2_48K);
|
||||
|
||||
#if 0
|
||||
/* For 96kHz */
|
||||
@ -1014,7 +1014,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
|
||||
EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
|
||||
|
||||
#if 0
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
|
@ -1355,7 +1355,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
||||
gpr += 2;
|
||||
|
||||
/* mic capture buffer */
|
||||
A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
|
||||
A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), A_C_40000000, A_EXTIN(A_EXTIN_AC97_R));
|
||||
|
||||
/* Audigy CD Playback Volume */
|
||||
A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
|
||||
@ -1438,7 +1438,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
||||
|
||||
/* Stereo Mix Center Playback */
|
||||
/* Center = sub = Left/2 + Right/2 */
|
||||
A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
|
||||
A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), A_C_40000000, A_GPR(stereo_mix+1));
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
|
||||
snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
|
||||
gpr++;
|
||||
@ -2478,7 +2478,7 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
|
||||
outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
|
||||
spin_unlock_irq(&emu->emu_lock);
|
||||
snd_emu10k1_ptr_write(emu, TCB, 0, 0);
|
||||
snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
|
||||
snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
|
||||
if (emu->fx8010.etram_pages.area != NULL) {
|
||||
snd_dma_free_pages(&emu->fx8010.etram_pages);
|
||||
emu->fx8010.etram_pages.area = NULL;
|
||||
|
@ -827,8 +827,8 @@ static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol,
|
||||
change = (emu->emu1010.optical_out != val);
|
||||
if (change) {
|
||||
emu->emu1010.optical_out = val;
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
|
||||
}
|
||||
return change;
|
||||
@ -878,8 +878,8 @@ static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol,
|
||||
change = (emu->emu1010.optical_in != val);
|
||||
if (change) {
|
||||
emu->emu1010.optical_in = val;
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
|
||||
tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
|
||||
(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
|
||||
}
|
||||
return change;
|
||||
|
@ -352,8 +352,8 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
||||
snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
|
||||
snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
|
||||
/* modulation envelope */
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
|
||||
snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f);
|
||||
snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000);
|
||||
@ -621,8 +621,8 @@ static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct s
|
||||
tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
|
||||
vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
|
||||
snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | VTFT_FILTERTARGET_MASK);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | CVCF_CURRENTFILTER_MASK);
|
||||
snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
|
||||
snd_emu10k1_voice_clear_loop_stop(emu, voice);
|
||||
}
|
||||
@ -663,8 +663,8 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
|
||||
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
|
||||
snd_emu10k1_ptr_write(emu, IP, voice, 0);
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,8 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
|
||||
regptr = (reg << 16) | chn;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(regptr, emu->port + 0x20 + PTR);
|
||||
val = inl(emu->port + 0x20 + DATA);
|
||||
outl(regptr, emu->port + PTR2);
|
||||
val = inl(emu->port + DATA2);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
return val;
|
||||
}
|
||||
@ -112,8 +112,8 @@ void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
|
||||
regptr = (reg << 16) | chn;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(regptr, emu->port + 0x20 + PTR);
|
||||
outl(data, emu->port + 0x20 + DATA);
|
||||
outl(regptr, emu->port + PTR2);
|
||||
outl(data, emu->port + DATA2);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
|
||||
/* This function is not re-entrant, so protect against it. */
|
||||
spin_lock(&emu->spi_lock);
|
||||
if (emu->card_capabilities->ca0108_chip)
|
||||
reg = 0x3c; /* PTR20, reg 0x3c */
|
||||
reg = P17V_SPI;
|
||||
else {
|
||||
/* For other chip types the SPI register
|
||||
* is currently unknown. */
|
||||
@ -280,10 +280,10 @@ void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 s
|
||||
return;
|
||||
if (snd_BUG_ON(src & ~0x71f))
|
||||
return;
|
||||
snd_emu1010_fpga_write(emu, 0x00, dst >> 8);
|
||||
snd_emu1010_fpga_write(emu, 0x01, dst & 0x1f);
|
||||
snd_emu1010_fpga_write(emu, 0x02, src >> 8);
|
||||
snd_emu1010_fpga_write(emu, 0x03, src & 0x1f);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f);
|
||||
}
|
||||
|
||||
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
|
||||
|
@ -254,19 +254,24 @@ static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
|
||||
emu->p16v_buffer->bytes);
|
||||
#endif /* debug */
|
||||
tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
|
||||
tmp &= ~(A_SPDIF_RATE_MASK | A_EHC_SRC48_MASK);
|
||||
switch (runtime->rate) {
|
||||
case 44100:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
|
||||
tmp | A_SPDIF_44100 | A_EHC_SRC48_44);
|
||||
break;
|
||||
case 96000:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
|
||||
tmp | A_SPDIF_96000 | A_EHC_SRC48_96);
|
||||
break;
|
||||
case 192000:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
|
||||
tmp | A_SPDIF_192000 | A_EHC_SRC48_192);
|
||||
break;
|
||||
case 48000:
|
||||
default:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel,
|
||||
tmp | A_SPDIF_48000 | A_EHC_SRC48_BYPASS);
|
||||
break;
|
||||
}
|
||||
/* FIXME: Check emu->buffer.size before actually writing to it. */
|
||||
@ -282,8 +287,8 @@ static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
|
||||
//snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
|
||||
snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
|
||||
snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
|
||||
snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
|
||||
snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
|
||||
snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_END_ADDRESS, channel, 0);
|
||||
snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_POINTER, channel, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -294,7 +299,6 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
|
||||
struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int channel = substream->pcm->device - emu->p16v_device_offset;
|
||||
u32 tmp;
|
||||
|
||||
/*
|
||||
dev_dbg(emu->card->dev, "prepare capture:channel_number=%d, rate=%d, "
|
||||
@ -304,24 +308,23 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
|
||||
runtime->buffer_size, runtime->period_size,
|
||||
frames_to_bytes(runtime, 1));
|
||||
*/
|
||||
tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
|
||||
switch (runtime->rate) {
|
||||
case 44100:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
|
||||
snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_44100);
|
||||
break;
|
||||
case 96000:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
|
||||
snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_96000);
|
||||
break;
|
||||
case 192000:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
|
||||
snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_192000);
|
||||
break;
|
||||
case 48000:
|
||||
default:
|
||||
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
|
||||
snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_48000);
|
||||
break;
|
||||
}
|
||||
/* FIXME: Check emu->buffer.size before actually writing to it. */
|
||||
snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
|
||||
snd_emu10k1_ptr20_write(emu, CAPTURE_FIFO_POINTER, channel, 0);
|
||||
snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
|
||||
snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
|
||||
snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
|
||||
|
@ -227,6 +227,7 @@ enum {
|
||||
AZX_DRIVER_ATI,
|
||||
AZX_DRIVER_ATIHDMI,
|
||||
AZX_DRIVER_ATIHDMI_NS,
|
||||
AZX_DRIVER_GFHDMI,
|
||||
AZX_DRIVER_VIA,
|
||||
AZX_DRIVER_SIS,
|
||||
AZX_DRIVER_ULI,
|
||||
@ -349,6 +350,7 @@ static const char * const driver_short_names[] = {
|
||||
[AZX_DRIVER_ATI] = "HDA ATI SB",
|
||||
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
|
||||
[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
|
||||
[AZX_DRIVER_GFHDMI] = "HDA GF HDMI",
|
||||
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
|
||||
[AZX_DRIVER_SIS] = "HDA SIS966",
|
||||
[AZX_DRIVER_ULI] = "HDA ULI M5461",
|
||||
@ -1743,6 +1745,12 @@ static int default_bdl_pos_adj(struct azx *chip)
|
||||
}
|
||||
|
||||
switch (chip->driver_type) {
|
||||
/*
|
||||
* increase the bdl size for Glenfly Gpus for hardware
|
||||
* limitation on hdac interrupt interval
|
||||
*/
|
||||
case AZX_DRIVER_GFHDMI:
|
||||
return 128;
|
||||
case AZX_DRIVER_ICH:
|
||||
case AZX_DRIVER_PCH:
|
||||
return 1;
|
||||
@ -1858,6 +1866,12 @@ static int azx_first_init(struct azx *chip)
|
||||
pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Fix response write request not synced to memory when handle
|
||||
* hdac interrupt on Glenfly Gpus
|
||||
*/
|
||||
if (chip->driver_type == AZX_DRIVER_GFHDMI)
|
||||
bus->polling_mode = 1;
|
||||
|
||||
err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
|
||||
if (err < 0)
|
||||
@ -1959,6 +1973,7 @@ static int azx_first_init(struct azx *chip)
|
||||
chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
|
||||
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
|
||||
break;
|
||||
case AZX_DRIVER_GFHDMI:
|
||||
case AZX_DRIVER_GENERIC:
|
||||
default:
|
||||
chip->playback_streams = ICH6_NUM_PLAYBACK;
|
||||
@ -2727,6 +2742,12 @@ static const struct pci_device_id azx_ids[] = {
|
||||
{ PCI_DEVICE(0x1002, 0xab38),
|
||||
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
||||
AZX_DCAPS_PM_RUNTIME },
|
||||
/* GLENFLY */
|
||||
{ PCI_DEVICE(0x6766, PCI_ANY_ID),
|
||||
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
||||
.class_mask = 0xffffff,
|
||||
.driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |
|
||||
AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },
|
||||
/* VIA VT8251/VT8237A */
|
||||
{ PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
|
||||
/* VIA GFX VT7122/VX900 */
|
||||
|
@ -4485,6 +4485,22 @@ static int patch_via_hdmi(struct hda_codec *codec)
|
||||
return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
|
||||
}
|
||||
|
||||
static int patch_gf_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = patch_generic_hdmi(codec);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Glenfly GPUs have two codecs, stream switches from one codec to
|
||||
* another, need to do actual clean-ups in codec_cleanup_stream
|
||||
*/
|
||||
codec->no_sticky_stream = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
*/
|
||||
@ -4575,6 +4591,12 @@ HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi),
|
||||
HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi),
|
||||
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
|
||||
HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
|
||||
HDA_CODEC_ENTRY(0x67663d82, "Arise 82 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x67663d83, "Arise 83 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x67663d84, "Arise 84 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x67663d85, "Arise 85 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x67663d86, "Arise 86 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x67663d87, "Arise 87 HDMI/DP", patch_gf_hdmi),
|
||||
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
|
||||
HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi),
|
||||
HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
|
||||
|
@ -9428,6 +9428,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
@ -9478,6 +9479,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
||||
@ -9500,6 +9502,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
|
||||
SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
|
||||
@ -9689,6 +9692,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2316, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2317, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
|
@ -227,6 +227,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M6400RC"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M3402RA"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
@ -1090,7 +1090,7 @@ config SND_SOC_MAX98088
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_MAX98090
|
||||
tristate
|
||||
tristate "Maxim MAX98090 CODEC"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_MAX98095
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -663,6 +663,7 @@ struct wcd938x_sdw_priv {
|
||||
bool is_tx;
|
||||
struct wcd938x_priv *wcd938x;
|
||||
struct irq_domain *slave_irq;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_WCD938X_SDW)
|
||||
|
@ -124,7 +124,7 @@ static const struct snd_soc_acpi_codecs rt5640_comp_ids = {
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_codecs wm5102_comp_ids = {
|
||||
.num_codecs = 2,
|
||||
.num_codecs = 3,
|
||||
.codecs = { "10WM5102", "WM510204", "WM510205"},
|
||||
};
|
||||
|
||||
|
@ -50,6 +50,31 @@ static struct snd_soc_acpi_mach *cht_quirk(void *arg)
|
||||
return mach;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some tablets with Android factory OS have buggy DSDTs with an ESSX8316 device
|
||||
* in the ACPI tables. While they are not using an ESS8316 codec. These DSDTs
|
||||
* also have an ACPI device for the correct codec, ignore the ESSX8316.
|
||||
*/
|
||||
static const struct dmi_system_id cht_ess8316_not_present_table[] = {
|
||||
{
|
||||
/* Nextbook Ares 8A */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "M882"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct snd_soc_acpi_mach *cht_ess8316_quirk(void *arg)
|
||||
{
|
||||
if (dmi_check_system(cht_ess8316_not_present_table))
|
||||
return NULL;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
static const struct snd_soc_acpi_codecs rt5640_comp_ids = {
|
||||
.num_codecs = 2,
|
||||
.codecs = { "10EC5640", "10EC3276" },
|
||||
@ -113,6 +138,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = {
|
||||
.drv_name = "bytcht_es8316",
|
||||
.fw_filename = "intel/fw_sst_22a8.bin",
|
||||
.board = "bytcht_es8316",
|
||||
.machine_quirk = cht_ess8316_quirk,
|
||||
.sof_tplg_filename = "sof-cht-es8316.tplg",
|
||||
},
|
||||
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
|
||||
|
@ -804,6 +804,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
|
||||
|
||||
default:
|
||||
/* no input methods supported on this device */
|
||||
ret = -EINVAL;
|
||||
goto exit_free_idev;
|
||||
}
|
||||
|
||||
|
@ -3884,6 +3884,64 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
/*
|
||||
* PIONEER DJ DDJ-800
|
||||
* PCM is 6 channels out, 6 channels in @ 44.1 fixed
|
||||
* The Feedback for the output is the input
|
||||
*/
|
||||
USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0029),
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_COMPOSITE,
|
||||
.data = (const struct snd_usb_audio_quirk[]) {
|
||||
{
|
||||
.ifnum = 0,
|
||||
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||
.data = &(const struct audioformat) {
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.channels = 6,
|
||||
.iface = 0,
|
||||
.altsetting = 1,
|
||||
.altset_idx = 1,
|
||||
.endpoint = 0x01,
|
||||
.ep_attr = USB_ENDPOINT_XFER_ISOC|
|
||||
USB_ENDPOINT_SYNC_ASYNC,
|
||||
.rates = SNDRV_PCM_RATE_44100,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.nr_rates = 1,
|
||||
.rate_table = (unsigned int[]) { 44100 }
|
||||
}
|
||||
},
|
||||
{
|
||||
.ifnum = 0,
|
||||
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||
.data = &(const struct audioformat) {
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.channels = 6,
|
||||
.iface = 0,
|
||||
.altsetting = 1,
|
||||
.altset_idx = 1,
|
||||
.endpoint = 0x82,
|
||||
.ep_idx = 1,
|
||||
.ep_attr = USB_ENDPOINT_XFER_ISOC|
|
||||
USB_ENDPOINT_SYNC_ASYNC|
|
||||
USB_ENDPOINT_USAGE_IMPLICIT_FB,
|
||||
.rates = SNDRV_PCM_RATE_44100,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.nr_rates = 1,
|
||||
.rate_table = (unsigned int[]) { 44100 }
|
||||
}
|
||||
},
|
||||
{
|
||||
.ifnum = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* MacroSilicon MS2100/MS2106 based AV capture cards
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user