At Fri, 17 Apr 2009 21:31:37 +0600, Ivan Mironov wrote:
В Птн, 17/04/2009 в 16:46 +0200, Takashi Iwai пишет:
At Fri, 17 Apr 2009 20:40:23 +0600, Ivan Mironov wrote:
Hello. I'm trying to get sound from my Creative Sound Blaster X-Fi Xtreme Audio Notebook (it's expresscard) with fresh ALSA drivers (I tried both alsa-driver-snapshot and alsa-driver-unstable-snapshot from 16.04.2009).
Avoid unstable version right now. alsa-driver-snapshot already contains CA0110 patch.
At this moment I have ALSA drivers compiled from alsa-driver-snapshot.
I can change mixer values in alsamixer, but no sound output. For example:
$ speaker-test -D plughw:1,0
speaker-test 1.0.19
Playback device is plughw:1,0 Stream parameters are 48000Hz, S16_LE, 1 channels Using 16 octaves of pink noise Playback open error: -22,Invalid argument Playback open error: -22,Invalid argument Playback open error: -22,Invalid argument ^C
at this time ALSA kernel driver gives an error in dmesg:
... ALSA /home/ivan/stuff/alsa-driver/acore/pcm_native.c:2040: snd_pcm_hw_constraints_complete failed ALSA /home/ivan/stuff/alsa-driver/acore/pcm_native.c:2040: snd_pcm_hw_constraints_complete failed ALSA /home/ivan/stuff/alsa-driver/acore/pcm_native.c:2040: snd_pcm_hw_constraints_complete failed ...
What should I do? Here is some information:
Could you run alsa-info.sh with --no-upload option, and attach the generated file?
Done.
The problem is likely that the codec doesn't respond properly as expected by the driver regarding the PCM parameter inquiry. We can debug using hda-verb, for example...
I don't know how ALSA driver and HDA codec works internally, so I will not be able to do it myself. Could you tell me what exactly should I do? I downloaded and compiled hda-verb-0.3.
OK, let's check first what the driver gets wrong. For example, try the patch below. It'll give some debug prints.
Takashi
--- diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index fc6f98e..46d577c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1910,61 +1910,83 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; } err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); - if (err < 0) + if (err < 0) { + snd_printd("ACCESS minmax error\n"); return err; + }
err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); - if (err < 0) + if (err < 0) { + snd_printd("FORMAT minmax error\n"); return err; + }
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); - if (err < 0) + if (err < 0) { + snd_printd("SUBFORMAT minmax error\n"); return err; + }
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, hw->channels_min, hw->channels_max); - if (err < 0) + if (err < 0) { + snd_printd("CHANNELS minmax error\n"); return err; + }
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, hw->rate_min, hw->rate_max); - if (err < 0) - return err; + if (err < 0) { + snd_printd("RATE minmax error\n"); + return err; + }
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, hw->period_bytes_min, hw->period_bytes_max); - if (err < 0) - return err; + if (err < 0) { + snd_printd("PERIOD_BYTES minmax error\n"); + return err; + }
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, hw->periods_min, hw->periods_max); - if (err < 0) + if (err < 0) { + snd_printd("PERIODS minmax error\n"); return err; + }
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, hw->period_bytes_min, hw->buffer_bytes_max); - if (err < 0) + if (err < 0) { + snd_printd("BUFFER_BYTES minmax error\n"); return err; + }
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, snd_pcm_hw_rule_buffer_bytes_max, substream, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1); - if (err < 0) + if (err < 0) { + snd_printd("BUFFER_BYTES #2 error\n"); return err; + }
/* FIXME: remove */ if (runtime->dma_bytes) { err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); - if (err < 0) + if (err < 0) { + snd_printd("BUFFER_BYTES #3 error\n"); return -EINVAL; + } }
if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_pcm_hw_rule_rate, hw, SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) + if (err < 0) { + snd_printd("RATE #2 error\n"); return err; + } }
/* FIXME: this belong to lowlevel */ diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 66a7d3d..6cced40 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2796,6 +2796,8 @@ static int set_pcm_default_values(struct hda_codec *codec, return -EINVAL; info->ops.cleanup = hda_pcm_default_cleanup; } + printk(KERN_DEBUG "XXX PCM NID=0x%x rates=0x%x, formats=0x%llx, bps=0x%x\n", + info->nid, info->rates, (unsigned long long)info->formats, info->maxbps); return 0; }