Commit 0021b532 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 27e0c846 ee2dd703
......@@ -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
----------------
......
......@@ -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, &reg);
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
......
This diff is collapsed.
This diff is collapsed.
......@@ -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
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment