Discussion:
Via VT2020: issues with kernel 2.6.38.{2, 3} (alsa 1.0.23) - working with 2.6.33.2 (alsa 1.0.21)
alex dot baldacchino dot alsasub at gmail dot com
2011-05-07 17:30:12 UTC
Permalink
Hello,
First of all let me apologize if I'm not fulfilling any requirements for
this list, and for any errors in my English.
I've sent a mail with same subject and content to this list as a non-subscriber
on April, 26, but perhaps that's gone lost, or perhaps is still under moderation
or didn't pass it, so I'm resending this from a different address as a
subscriber.
So, please, ignore my previous mail if it came out from moderation.

As per subject, I'm experiencing problems with my motherboard built-in audio
device (an Asrock with ATI SB8xx), embedding a Via VT2020 codec (I haven't
tested the ATI HDMI part in same conditions).

The card is recognized 'about' correctly (later in this mail something about
dmesg and other issues), and stuff in /proc/asound seems correct, also I
have no apparent problem with /dev special files, but I get no sound after
having installed kernel 2.6.38.2 and updated to version 2.6.38.3 (both
compiled from source); no mixer seems to work (later specific errors), but
everything still works with older kernel 2.6.33.2 I've kept in my system
(built with the same build environment). Since I'm using the very same
userspace environment in both cases, I deem it to be a driver(s) related
issue more likely; though, I've updated my alsa-lib and -utils to latest
versions (were such when I downloaded sources - alsa-lib 1.0.24.1 &
alsa-utils 1.0.24.2) and still get the very same results.

But let me go into more details. Here is an excerpt from dmesg called with
kernel 2.6.33.2 (sound works, but I'm just using headphone jack, so I can't tell
about anything related with later issue with smart5.1 and hda I've seen in list
archives):

[...]
HDA Intel 0000:00:14.2: PCI INT A -> GSI 16 (level, low) -> IRQ 16
HDA Intel 0000:01:05.1: PCI INT B -> GSI 19 (level, low) -> IRQ 19
HDA Intel 0000:01:05.1: irq 28 for MSI/MSI-X
HDA Intel 0000:01:05.1: setting latency timer to 64
[...]
ohci1394 0000:04:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
ohci1394 0000:04:00.0: setting latency timer to 64
[...]
ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[16] MMIO=[fe9ff800-fe9fffff]
Max Packet=[2048] IR/IT contexts=[4/8]
ieee1394: Host added: ID:BUS[0-00:1023] GUID[008f130043910900]
[...]
hda-intel: azx_get_response timeout, switching to polling mode: last
cmd=0x000f0001
[...]

Notice last line is an harmless warning (sound works) and is there because
msi seems to be enabled by default; by adding "options snd-hda-intel
enable_msi=0" to
/etc/modprobe.d/alsa-base.conf both the warning and any reference to
MSI/MSI-X disappear; same effect with pci=nomsi on command line (this time
affecting other drivers, such as r8169). VT2020 is part of device
0000:00:14.2 sharing IRQ 16 with ohci1394; device 0000:01:05.1 is ATI HDMI,
while device 0000:05.0 should be embedded radeon vga (bridged together
according with lspci -t with 0000:00:01.0 on top); for each bridge I can
find with lspci -t corresponding msi_bus file in sys filesystem (in
/sys/bus/pci/devices/*) is always 1, regardless of any boot command (this
with kernel 2.6.33.2).

Now an excerpt from dmesg in kernel 2.6.38.3:

[...]
HDA Intel 0000:00:14.2: PCI INT A -> GSI 16 (level, low) -> IRQ 16
hda-codec: no NID for mapping control Independent HP:0:0
HDA Intel 0000:01:05.1: PCI INT B -> GSI 19 (level, low) -> IRQ 19
HDA Intel 0000:01:05.1: setting latency timer to 64
[...]
r8169 0000:03:00.0: irq 43 for MSI/MSI-X
[...]
firewire_ohci 0000:04:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
firewire_ohci 0000:04:00.0: setting latency timer to 64
[...]
firewire_ohci: Added fw-ohci device 0000:04:00.0, OHCI v1.10, 4 IR + 8 IT
contexts, quirks 0x11
firewire_core: created device fw0: GUID 008f130043910900, S400
[...]

Now firewire_ohci replaces ohci1394, again sharing IRQ 16 with hda-intel for
vt2020. Line about r8169 is just for reference, since it gets a different
irq for msi now. Similar behaviour for MSI: enabled/disabled with pci=nomsi
(seems to be enabled by
default without pci=msi) and msi_bus == 1 for bridges regardless of boot
options, *but for bridge on top of ati hdmi device*: now msi seems to be
disabled regardless of both 'enable_msi' option and pci=* boot command and
corresponding bridge
(device at bus 0000:00:01.0) holds a value of 0 for msi_bus...

Notice there are no more warnings about response timeouts, as it
happened in older
kernel after disabling msi (both globally and for alsa through alsa
config options).

Notice also line "hda-codec: no NID for mapping control Independent HP:0:0".
That's because function

'snd_hda_get_connections' (patch_via.c)

called by

'via_hp_build'

returns 3 ( test for 'nums <= 1' fails and the function doesn't return),
but function

'side_mute_channel',

called to init knew->subdevice when 'registering' via_hp_mixer[1], returns 0
(default value) and so condition 'if(nid > 0)', in function

'snd_hda_add_nid' (hda_codec.c),

is not met and the error is triggered (by the way, param nid is of type
hda_nid_t which in turn is an unsigned integer (u16), so, should that be
'if(nid != 0)' instead? just to avoid the risk of giving the impression that
negative values are possible but mistaken (hda_nid_t is defined elsewhere).
Also: param @nid, in function
comment/documentation is defined as optional, but it doesn't seem to be).
Incidentally, in /proc/asound/card0/codec#0 node 0x35 looks much like node
0x34 (with both older and newer kernel; posting excerpt for kernel
2.6.38.3):

Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b 0x0c*
Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b* 0x0c

(notice connections and wcaps similarity, if relevant at all)

Since I'm quite crazy, I've tried to modify 'side_mute_channel' to have it
returning '0x35' for codec type 'VT1718S', but to no avail; I also tried to
bypass 'snd_hda_add_nid', both avoiding 'via_hp_build' to clone
via_hp_mixer[<something>] and/or modifying 'via_build_controls' and
'snd_hda_add_new_ctls' (hda_control.c) so
that "Independent HP" ctls were handled by the latter (achieving this was just
a matter of a pair of strcmp's to choose skipping the rest of an
iteration or not),
as I deem it was done in alsa 1.0.21 (embedded in kernel 2.6.33.2),
but it didn't
work (the only result I got this ways was to avoid that error message about nids
in system logs).

Additional infos from userspace applications:

mplayer works fine with kernel 2.6.33.2 (again, only using one exit, I
haven't tested
all jacks combinations); called from cmdline (under X - but
that's the same shutting X down) with default options ('mplayer
<path/to/file>') it gives the following output (relevant excerpt, as I
deem it, after codec choice, can provide more if needed):

socket(): Address family not supported by protocol
AO: [pulse] Init failed: Connection refused
Failed to initialize audio driver 'pulse'
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...

(notice I'm not using alsa-tools, such as pulse-audio; with the above
invocation sound/video works)

running mplayer with option '-ao sdl' (using sdl audio, same file) I get the
following output:

[AO SDL] Samplerate: 44100Hz Channels: Stereo Format s16le
AO: [sdl] 44100Hz 2ch s16le (2 bytes per sample)
Starting playback...

Again, sound works. In both cases, I can notice a change in
/proc/asound/card0/codec#0 as follows:

In nodes 0x08, 0x09, 0x0a, 0x0e (all [Audio Output] nodes, first 3 with
'wcaps 0x41d: Stereo Amp-Out', last with
'wcaps 0x611: Stereo Digital'), the following line:

Converter: stream=0, channel=0

changes into:

Converter: stream=5, channel=0

With kernel 2.6.38.x I get the following:

running mplayer with no option, I get no sound and following output:

socket(): Address family not supported by protocol
AO: [pulse] Init failed: Connection refused
Failed to initialize audio driver 'pulse'
[AO_ALSA] alsa-lib: confmisc.c:768:(parse_card) cannot find card '0'
[AO_ALSA] alsa-lib: conf.c:4184:(_snd_config_evaluate) function
snd_func_card_driver returned error: No such device
[AO_ALSA] alsa-lib: confmisc.c:392:(snd_func_concat) error evaluating
strings
[AO_ALSA] alsa-lib: conf.c:4184:(_snd_config_evaluate) function
snd_func_concat returned error: No such device
[AO_ALSA] alsa-lib: confmisc.c:1251:(snd_func_refer) error evaluating name
[AO_ALSA] alsa-lib: conf.c:4184:(_snd_config_evaluate) function
snd_func_refer returned error: No such device
[AO_ALSA] alsa-lib: conf.c:4663:(snd_config_expand) Evaluate error: No such
device
[AO_ALSA] alsa-lib: pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM default
[AO_ALSA] Playback open error: No such device
Failed to initialize audio driver 'alsa'
[AO SDL] Samplerate: 44100Hz Channels: Stereo Format s16le
[AO SDL] using aalib audio driver.
[AO SDL] Unable to open audio: No available audio device
Failed to initialize audio driver 'sdl:aalib'
Could not open/initialize audio device -> no sound.
Audio: no sound

and nothing changes in codec#0 file; with option -ao sdl, instead:

[AO SDL] Samplerate: 44100Hz Channels: Stereo Format s16le
ALSA lib confmisc.c:768:(parse_card) cannot find card '0'
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_card_driver
returned error: No such device
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_concat
returned error: No such device
ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_refer returned
error: No such device
ALSA lib conf.c:4663:(snd_config_expand) Evaluate error: No such device
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM default
AO: [sdl] 44100Hz 2ch s16le (2 bytes per sample)

And sound works! Same changes as per (working) playback with kernel 33.2
(alsa 1.0.21) are noticeable in /proc/asound/card0/codec#0 in this case
(that is, when getting sound with kernel 2.6.38.x); in addition, node 0x0c,
now changes as well (again, '[Audio Output] wcaps 0x41d: Stereo Amp-Out.'
and 'Converter: stream=5, channel=0')

Moreover: with kernel 38.2, 38.3 alsamixer fails telling about problems
finding device:

cannot open mixer: No such device

And amixer says:

amixer: Mixer attach default error: No such device

But there's no problem with /dev stuff (and same devices works pretty fine
with kernel 2.6.33.2) - aplay -l doesn't work
as well:

aplay: device_list:240: no soundcards found...

With kernel 2.6.33.2, aplay -l says:

**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: VT2020 Analog [VT2020 Analog]
Subdevices: 2/2
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
card 0: SB [HDA ATI SB], device 1: VT2020 Digital [VT2020 Digital]
Subdevices: 2/2
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
card 1: HDMI [HDA ATI HDMI], device 3: ATI HDMI [ATI HDMI]
Subdevices: 1/1
Subdevice #0: subdevice #0

A 'third party' mixer embedded in my distribution aborts by hitting a failed
assertion in function

'snd_hctl_load' (hcontrol.c)

failing assertion being 'assert(hctl->count == 0)' - I've added a few simple
lines above the assertion to print out some info on stderr, and got the
following results:

In kernel 2.6.33.2:

hctl->count: 0
hctl->ctl: 134748144 (0x80817F0)
hctl->ctl->name: hw:0

which seems reasonable - according to /proc/iomem address 0x80817F0 is in
range 00100000-cf83ffff (system ram) and higher than kernel stuff subranges
( 01000000-012c3be7: Kernel code - 012c3be8-0141dadf : Kernel data -
01481000-014b1e03 : Kernel bss);

In kernel 2.6.38.2 & .38.3:

hctl->count: 1156
hctl->ctl: 5398 (0x1516)
Segmentation fault

suggesting memory corruption (that's always the same address) - according to
/proc/iomem address 0x1516 is in first range (0x0000-0xffff) which is
reserved.

I thought (and hoped) that could have been somehow related to
cached/noncached pages issue solved by commit
c27b92295ab4c6b90b1cee94c4c9c1b4732e1c2e, but applying diff patch for kernel
2.6.38.3 didn't change anything. After that, I've read changelog for
kermel 2.6.38.4
but such didn't seem to me to present related material, so I didn't updgrade.

I hope this post can help solving this issue and improving alsa
infrastracture (I cannot easily go further).
Best regards.
Raymond Yau
2011-05-08 06:40:36 UTC
Permalink
2011/5/8 alex dot baldacchino dot alsasub at gmail dot com <
Post by alex dot baldacchino dot alsasub at gmail dot com
Notice also line "hda-codec: no NID for mapping control Independent HP:0:0".
That's because function
'snd_hda_get_connections' (patch_via.c)
called by
'via_hp_build'
returns 3 ( test for 'nums <= 1' fails and the function doesn't return),
but function
'side_mute_channel',
called to init knew->subdevice when 'registering' via_hp_mixer[1], returns 0
(default value) and so condition 'if(nid > 0)', in function
'snd_hda_add_nid' (hda_codec.c),
is not met and the error is triggered (by the way, param nid is of type
hda_nid_t which in turn is an unsigned integer (u16), so, should that be
'if(nid != 0)' instead? just to avoid the risk of giving the impression that
negative values are possible but mistaken (hda_nid_t is defined elsewhere).
comment/documentation is defined as optional, but it doesn't seem to be).
Incidentally, in /proc/asound/card0/codec#0 node 0x35 looks much like node
0x34 (with both older and newer kernel; posting excerpt for kernel
Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b 0x0c*
Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b* 0x0c
(notice connections and wcaps similarity, if relevant at all)
Since I'm quite crazy, I've tried to modify 'side_mute_channel' to have it
returning '0x35' for codec type 'VT1718S', but to no avail; I also tried to
bypass 'snd_hda_add_nid', both avoiding 'via_hp_build' to clone
via_hp_mixer[<something>] and/or modifying 'via_build_controls' and
'snd_hda_add_new_ctls' (hda_control.c) so
that "Independent HP" ctls were handled by the latter (achieving this was just
a matter of a pair of strcmp's to choose skipping the rest of an
iteration or not),
as I deem it was done in alsa 1.0.21 (embedded in kernel 2.6.33.2),
but it didn't
work (the only result I got this ways was to avoid that error message about nids
in system logs).
Try the snapshot tarballs or git at

http://www.kernel.org/pub/linux/kernel/people/tiwai/docs/HD-Audio.html

Post the output of alsa-info.sh

What is the model of your computer (desktop/notebook) ?

How many audio jacks ?

https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/729659

It seem that vt2020 is 10 channels HDA with 5 [Audio Output] 0x8, 0x9, 0xa,
0xb and 0xc
alex dot baldacchino dot alsasub at gmail dot com
2011-05-08 23:16:01 UTC
Permalink
Hello,

Thanks for your answer.
Post by Raymond Yau
2011/5/8 alex dot baldacchino dot alsasub at gmail dot com <
[...]
Try the snapshot tarballs or git at
http://www.kernel.org/pub/linux/kernel/people/tiwai/docs/HD-Audio.html
Sorry, I've never build modules out of 'regular' kernel build process
before, so I'd have a few questions. I'm using a tarball kernel source
for kernel 2.6.38.2 taken from kernel.org, patched with some stuff
required by my distro (therein aufs) and incremented to version
2.6.38.3 with the incremental patch taken, again, from kernel.org; I
have no git version of the kernel to pull the alsa git snapshot over,
and am not using a 'real' broadband connection at the moment, so I'd
prefer not to download a full git source. For accomplishing your
request, I've downloaded tarball alsa-driver-20110508.tar.bz2 from the
ftp pointed to within the document linked above

Now my questions. In file 'SUPPORTED_KERNELS' I can read the following:

"The alsa-drivers in this package are designed for the following kernels:

- Vanilla 2.6.29 or earlier
- Vanilla 2.4.31 or earlier
- Vanilla 2.2.26 or earlier

It's not guaranteed that they work with any newer version than above
or modified kernels by distributors."

Is it a harmless warning, or should I upgrade my kernel to version
2.6.38.4 or 38.5 and test the embedded alsa version (more recent than
current one I'm using) instead?

I've modified, through menuconfig ( CONFIG_LOCALVERSION ), my kernel
version string, so I can modify configuration at whim and keep
different flavors of the same kernel version (though I'm using just
one flavor for k 2.6.38.3); moreover, kernel source path doesn't match
the exact 'name' of the kernel (as named in /lib/modules/<version>)
and is located out of /usr/src, though actual source path is symlinked
from within kernel install dir as standard 'source' subdir (pointing
to <path/to/linux-2.6.33.2>). Hence, for what I've understood from
file 'INSTALL' in ALSA snapshot tarball, kernel version and source
tree should be easily identified by configure script, however, in case
there is a risk that ALSA snapshot gets misconfigured I prefer to ask
if I'd better to explicitly pass in --with-kernel and --with-build
options.

But my main concern is about overall configuration. For better
comparison, I'd wish to use the very same sound configuration I've
used in kernel build process, but that's unclear to me if configure
script for ALSA snapshot will retrieve and use it, or if the script
can just use configuration options passed in/default values (as a
'regular' configure script).

Lastly, do I need to enable debug? (that is, is it required for better
alsa-info output?)

For now, below I'm posting alsa-info.sh output for current
configuration and for kernel 2.6.33.2 (with working sound), hoping
this can help for comparison.
Post by Raymond Yau
Post the output of alsa-info.sh
What is the model of your computer (desktop/notebook) ?
Sorry I didn't make it more clear in my previous post. Mine is a
home-build desktop with an Asrock motherboard (I don't know of any
notebook with asrock MoBo), model '890GX Extreme3', with integrated
graphics (Radeon HD4290) and audio (via vt2020 codec and ati hdmi), NB
AMD 890GX, SB850; CPU is a Phenom II X4 (kernel 2.6.38.3 is configured
with amd specific optimizations while retaining x86 compatibility
code; kernel 2.6.33.2 has no cpu-related optimization enabled; both
are 32 bit); 4 GB ddr3 memory; no expansion cards.

If more details are needed, I'll write full specs.
Post by Raymond Yau
How many audio jacks ?
Rear panel: 5 jacks for 7.1 channels audio + 1 Optical SPDIF OUT port
On board: front panel audio header for ac97/hd audio (connectors for
mic, left, right - I'm not sure if that's for supporting 2 independent
mono jacks, one stereo (headset) jack or both cases, I don't know
neither ac97, nor hd audio specifications) + header for 1 hdmi_spdif
out (to be connected to a discrete vga with hdmi capabilities)
Post by Raymond Yau
https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/729659
It seem that vt2020 is 10 channels HDA with 5 [Audio Output] 0x8, 0x9, 0xa,
0xb and 0xc
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
__________________________________________________
OUTPUT FOR ALSA-INFO.SH -- K 2.6.38.3 - ALSA 1.0.23:

http://www.pastebin.ca/2055424

__________________________________________________
OUTPUT FOR ALSA-INFO.SH -- K2.6.33.2 - ALSA 1.0.21:

http://pastebin.ca/2055501
Raymond Yau
2011-05-10 02:03:03 UTC
Permalink
2011/5/9 alex dot baldacchino dot alsasub at gmail dot com <
***@gmail.com>

you have to ask the distribution maintainer how to test the latest
alsa-driver without upgrading the kernel.

it look like the driver is not installed correctly

!!Aplay/Arecord output
!!------------

APLAY

aplay: device_list:240: no soundcards found...

ARECORD

arecord: device_list:240: no soundcards found...


!!Amixer output
!!-------------

!!-------Mixer controls for card 0 [SB]

Invalid card number.
Usage: amixer <options> [command]




Most likely you will need this patch

cb34c207af4944e9c93e2b462e351430f15daad6

so that the driver do not create "smart5.1" control since blue jack may need
to retask as side according to the user manual

ALSA: hda - VIA: Fix Smart5.1 isn't useful for 6 audio jacks motherboard.
Post by alex dot baldacchino dot alsasub at gmail dot com
Lastly, do I need to enable debug? (that is, is it required for better
alsa-info output?)
The driver print debug messages in system log , you are able to know which
[Audio Output] is used when switch "Independent HP" on/off or retask blue
jack as output
Post by alex dot baldacchino dot alsasub at gmail dot com
For now, below I'm posting alsa-info.sh output for current
configuration and for kernel 2.6.33.2 (with working sound), hoping
this can help for comparison.
Post by Raymond Yau
Post the output of alsa-info.sh
What is the model of your computer (desktop/notebook) ?
Mine is a home-build desktop with an Asrock motherboard (I don't know of
any
notebook with asrock MoBo), model '890GX Extreme3', with integrated
graphics (Radeon HD4290) and audio (via vt2020 codec and ati hdmi), NB
AMD 890GX, SB850;
Post by Raymond Yau
How many audio jacks ?
Rear panel: 5 jacks for 7.1 channels audio + 1 Optical SPDIF OUT port
On board: front panel audio header for ac97/hd audio (connectors for
mic, left, right -
Refer to page 12 of 890GX Extreme3 's user manual

TABLE for Audio Output Connection

Blue jack is re-tasked for "Side" channel to support 8 channels
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
"hda-codec: no NID for mapping control Independent HP:0:0".
Node 0x28 HP is connected to 0x34 through 0x1b

[Audio Output] 0x0c has the "Headphone Volume" control

As "Line in" can only be connected to 0x0c

so the fix mainly depend on whether 0x0b can be used or not

if vt2020 is as same as vt1718s, you need to find a correct nid in the
function side_mute_channel() for update_side_mute_status() which mute/unmute
side channel when independent HP Is "ON"/"OFF"


Node 0x2a [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x00002334: IN OUT Detect
Vref caps: HIZ 50 100
Pin Default 0x0181303e: [Jack] Line In at Ext Rear
Conn = 1/8, Color = Blue
DefAssociation = 0x3, Sequence = 0xe
Pin-ctls: 0x20: IN VREF_HIZ
Unsolicited: tag=04, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 2
0x09* 0x0c


send: NID=0x21, VERB=0x370(set_amp_gain_mute,I:LR#0), PARM=0x80
send: NID=0x21, VERB=0x371(set_amp_gain_mute,I:LR#1), PARM=0x80
send: NID=0x21, VERB=0x372(set_amp_gain_mute,I:LR#2), PARM=0x80
send: NID=0x21, VERB=0x373(set_amp_gain_mute,I:LR#3), PARM=0x80
send: NID=0x21, VERB=0x375(set_amp_gain_mute,I:LR#5), PARM=0x0
invalid amp index 5 (conns=5)

Node 0x21 only has 5 connections instead of 6

Seem no "Stereo Mix" , 0x28 is HP and only 0x2c, 0x2b and 0x29 are input
sources and the other must be muted

node 0x2a "Line Playback Switch" have to be muted and write-protect whenever
blue jack is retask

need to modify vt1718S_auto_create_analog_input_ctls()


Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Front Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Front Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Rear Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Rear Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x97 0x97]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28
Post by alex dot baldacchino dot alsasub at gmail dot com
I'm not sure if that's for supporting 2 independent
mono jacks, one stereo (headset) jack or both cases,
http://www.intel.com/support/motherboards/desktop/sb/cs-020642.htm#multistream

Multistreaming allows you to listen to two different audio sources on two
different speaker sets. For example, you can listen to one audio source
through the back panel speakers and a second audio source through front
panel headphones or speakers.

In page 13,

To enable Multi-Streaming function, you need to connect a front panel audio
cable to the front panel audio header,
Post by alex dot baldacchino dot alsasub at gmail dot com
I don't know neither ac97, nor hd audio specifications) + header for 1
hdmi_spdif
out (to be connected to a discrete vga with hdmi capabilities)
http://www.intel.com/support/motherboards/desktop/sb/cs-020642.htm#standards
*

How to Identify your Front Panel Audio Solution Codec

*You can also physically check the audio cable of the front panel audio
solution. If there is a cable connected to Pin 4, you have an HD Audio
module; if there is no cable to Pin 4, you have an AC97 module.

page 60 (BIOS setup)

Front Panel
Select [Auto] or [Disabled] for the onboard HD Audio Front Panel.
alex dot baldacchino dot alsasub at gmail dot com
2011-05-16 16:03:21 UTC
Permalink
Hello,
It took me a while before I could post again here, sorry.

I've installed the snapshot tarball I had downloaded, with debug
support enabled, result at following link; results are close to
previous ones.

http://pastebin.ca/2056960
Post by Raymond Yau
2011/5/9 alex dot baldacchino dot alsasub at gmail dot com <
you have to ask the distribution maintainer how to test the latest
alsa-driver without upgrading the kernel.
It seems configure script for the snapshot has found correct source
and installation paths, overwriting existing sound drivers, as
expectable; I've left userspace configuration untouched (installed new
modules with 'make install-modules' to leave alsa script in
/etc/init.d as it was).

In my previous messages I forgot to mention my chassis has a front
panel with mic and hp jacks; it is said to support both hd and ac'97
audio - it's got a multi-pin single connector labeled 'hd audio' with
all available pins wired (fully fitting the MoBo header, and is
actually inserted); from that one, another connector is derived,
labeled 'ac97 audio', with a pair of pins missing and some other
'duplicated' (I'm not using it). I've made a few tests, one with front
panel disabled in bios, one with front panel enabled in bios (bios
option set to auto - please, note there can be an error in my MoBo
manual, since only available options for the front panel are 'Auto'
and 'Disabled', there's no 'Enabled' ) but physically unconnected.
Results are at following addresses:

Front panel disabled in bios:

http://pastebin.ca/2060444

Front panel disconnected but enabled in bios:

http://pastebin.ca/2060448


Please, notice the following excerpts (perhaps it sounds normal at
you, but I'm trying to understand how to interpret things at this
stage):

With panel disabled in bios:

Node 0x0c [Audio Output] wcaps 0x41d: Stereo Amp-Out
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0


( missing lines:
Control: name="Headphone Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0 )


Node 0x28 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x422140f0: [N/A] HP Out at Ext Front
Conn = 1/8, Color = Green
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x00: VREF_HIZ
Unsolicited: tag=21, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1b


( missing lines:
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
different 'Pin Default', different 'DefAssociation' )


Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b 0x0c*


( missing line:
Control: name="Independent HP", index=0, device=0 )


/sys/class/sound/hwC0D0/init_pin_configs:
0x24 0x01014010
0x25 0x01011012
0x26 0x01016011
0x27 0x410120f0
0x28 0x422140f0
0x29 0x42a190f7
0x2a 0x0181303e
0x2b 0x01a19036
0x2c 0x593701f8
0x2d 0x074510f0
0x2e 0x474401f0
0x2f 0x47c411f0


( different pin configurations with respect to the normal case - the
first link in this message - and the following case )


ALSA hda_intel.c:1457: Enable sync_write for AMD chipset
ALSA hda_codec.c:4707: autoconfig: line_outs=3
(0x24/0x25/0x26/0x0/0x0) type:line
ALSA hda_codec.c:4711: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4715: hp_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4716: mono: mono_out=0x0
ALSA hda_codec.c:4719: dig-out=0x2d/0x0
ALSA hda_codec.c:4720: inputs:
ALSA hda_codec.c:4726:


( it seems there's no hp output, 0x28 is _not_ listed )


With front panel disconnected but enabled in bios:


Node 0x0c [Audio Output] wcaps 0x41d: Stereo Amp-Out
Control: name="Headphone Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0


( as if panel were connected )


Node 0x28 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x0221411f: [Jack] HP Out at Ext Front
Conn = 1/8, Color = Green
DefAssociation = 0x1, Sequence = 0xf
Misc = NO_PRESENCE
Pin-ctls: 0xc0: OUT HP VREF_HIZ
Unsolicited: tag=21, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 1
0x1b


Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3


( again, as when panel is connected, but for line:
Misc = NO_PRESENCE )


/sys/class/sound/hwC0D0/init_pin_configs:
0x24 0x01014010
0x25 0x01011012
0x26 0x01016011
0x27 0x410120f0
0x28 0x0221411f
0x29 0x02a19137
0x2a 0x0181303e
0x2b 0x01a19036
0x2c 0x593701f8
0x2d 0x074510f0
0x2e 0x474401f0
0x2f 0x47c411f0


ALSA hda_codec.c:4707: autoconfig: line_outs=3
(0x24/0x25/0x26/0x0/0x0) type:line
ALSA hda_codec.c:4711: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4715: hp_outs=1 (0x28/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4716: mono: mono_out=0x0
ALSA hda_codec.c:4719: dig-out=0x2d/0x0
ALSA hda_codec.c:4720: inputs:
ALSA hda_codec.c:4726:


It seems that node 0x28 represents the front panel line-out and
connection 0x0c is not used by anyone else (possible? rigth to work
this way? am I misunderstanding the log?). On the other hand, it is
labeled as "[Jack] HP Out at Ext Front", so it was expectable to work
this way (right?).

Now, I'm courious about node 0x24, which represents the rear green
line-out (and is the only rear line-out involved in all output
configurations, from 2 to 8 channels); in all cases it is presented
the following way:


Node 0x24 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0001001c: OUT HP EAPD Detect
EAPD 0x2: EAPD
Pin Default 0x01014010: [Jack] Line Out at Ext Rear
Conn = 1/8, Color = Green
DefAssociation = 0x1, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 1
0x18


Node 0x18 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x00 0x00] [0x00 0x00]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 2
0x08 0x21


Node 0x08 [Audio Output] wcaps 0x41d: Stereo Amp-Out
Control: name="Front Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Device: name="VT2020 Analog", type="Audio", device=0
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0


0x08 is also listed as possible connection for node 0x034 and 0x035

Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b 0x0c*
Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b* 0x0c


Therefore, could 0x18 be a suitable return value for
side_mute_channel() function? (though I'd suppose an 'Audio Selector'
should be looked for instead of an 'Audio Mixer') How could I check
that?

In other words, I need also to understand what are exactly the
"Independent HP"s looked for and how they're enumerated, whether by
counting all possible output configurations that could be involved in
a Multi-Stream scenario (hence including rear channels) or just those
ones which exist beside the 'main group' (the rear group of line-outs
making up multichannel configurations).

In the latter case, are they always coupled? I'm asking because it
seems to me that via_hp_build() assumes there are either exactly 2
Independent HP controls (when snd_hda_get_connections() returns a
value greater than 1) or none (otherwise). Could there be just one
such control instead?
Post by Raymond Yau
it look like the driver is not installed correctly
[...cut...]
All is possible... but I wonder how... All I've done is downloading
the new kernel, patching it according to older kernels for my distro
(nothing related to sound, just lowering DEFAULT_CONSOLE_LOGLEVEL from
7 to 3, adding a few printk's to usb-storage, additional vortex device
ids, aufs), configuring it through 'make menuconfig' (using older
kernel configuration as a hint), issuing 'make bzImage', issuing 'make
modules', issuing 'make INSTALL_MOD_PATH=/some/path modules_install",
copying modules in their final destination ( /lib/modules/<version> ),
updating my initrd (which doesn't handle sound) and rebooting.... I've
left sound configuration (userspace-side) untouched.

That worked with the older kernel I'm using (from my distro - it was
yet configured and patched, but I've updated patches - such as aufs -
tuned it a few times to create different flavours, build and installed
it as above). Unless there's something only working for alsa 1.0.21
and causing problems with alsa 1.0.23 - alsa 1.0.24 in
/etc/init.d/alsa, /etc/modprobe.d/* files (I have no .asoundrc),
drivers installation shouldn't be the problem, AFAICT...
Post by Raymond Yau
Most likely you will need this patch
cb34c207af4944e9c93e2b462e351430f15daad6
so that the driver do not create "smart5.1" control since blue jack may need
to retask as side according to the user manual
ALSA: hda - VIA: Fix Smart5.1 isn't useful for 6 audio jacks motherboard.
I guess that should be embedded in the snapshot I've installed... In
file 'patch_via.c', function 'via_smart51_build' checks for line_outs
number before cloning smart5.1 controls; anyway, there's nothing
connected to my blue jack at the moment.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Lastly, do I need to enable debug? (that is, is it required for better
alsa-info output?)
The driver print debug messages in system log , you are able to know which
[Audio Output] is used when switch "Independent HP" on/off or retask blue
jack as output
Well, alsa-info.sh collects those messages related to sound, I was
asking if people here wish to read them for a better understanding of
the problem (I've enabled debug in the snapshot, so those lines are in
my new alsa-info posts). Sorry I wasn't clear about my doubt.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
For now, below I'm posting alsa-info.sh output for current
configuration and for kernel 2.6.33.2 (with working sound), hoping
this can help for comparison.
Post by Raymond Yau
Post the output of alsa-info.sh
What is the model of your computer (desktop/notebook) ?
Mine is a home-build desktop with an Asrock motherboard (I don't know of
any
notebook with asrock MoBo), model '890GX Extreme3', with integrated
graphics (Radeon HD4290) and audio (via vt2020 codec and ati hdmi), NB
AMD 890GX, SB850;
Post by Raymond Yau
How many audio jacks ?
Rear panel: 5 jacks for 7.1 channels audio + 1 Optical SPDIF OUT port
On board: front panel audio header for ac97/hd audio (connectors for
mic, left, right -
Refer to page 12 of 890GX Extreme3 's user manual
TABLE for Audio Output Connection
Blue jack is re-tasked for "Side" channel to support 8 channels
I was trying to count the max number of jacks my MoBo can support,
regardless they're in the rear or front panel, present or not. I guess
you were asking for rear ones only, sorry for my misunderstanding.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
"hda-codec: no NID for mapping control Independent HP:0:0".
Node 0x28 HP  is connected to 0x34 through 0x1b
[Audio Output] 0x0c has the "Headphone Volume" control
As "Line in" can only be connected to 0x0c
so the fix mainly depend on whether 0x0b can be used or not
How can I check that? (that is, 0x0b usability for the purpose?)

Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b 0x0c*

What does the asterisk mean? Is it to indicate the active/used connection?

It seems to me that

Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x02a19037: [Jack] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x7
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1c

is connected through

Node 0x1c [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x00 0x00] [0x80 0x80]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 2
0x35 0x21

to

Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08 0x0b* 0x0c

which uses

Node 0x0b [Audio Output] wcaps 0x41d: Stereo Amp-Out
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3

Am I wrong?
Should it work differently?
Post by Raymond Yau
if vt2020 is as same as vt1718s,  you need to find a correct nid in the
function side_mute_channel() for update_side_mute_status() which mute/unmute
side channel when independent HP Is "ON"/"OFF"
Given actual implementation, those should be at least compatible to
some extent; in case there were differences between nids in different
'flavours' of vt1718s ( for the sake of side_mute_channel(struct
via_spec *spec) ), it should be possible to check
spec->codec->vendor_id within the switch statement when
spec->codec_type is VT1718S - the problem is finding the right nid
Post by Raymond Yau
Node 0x2a [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
 Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-Out vals:  [0x80 0x80]
 Pincap 0x00002334: IN OUT Detect
   Vref caps: HIZ 50 100
 Pin Default 0x0181303e: [Jack] Line In at Ext Rear
   Conn = 1/8, Color = Blue
   DefAssociation = 0x3, Sequence = 0xe
 Pin-ctls: 0x20: IN VREF_HIZ
 Unsolicited: tag=04, enabled=1
 Power states:  D0 D1 D2 D3
 Power: setting=D3, actual=D3
 Connection: 2
    0x09* 0x0c
send: NID=0x21, VERB=0x370(set_amp_gain_mute,I:LR#0), PARM=0x80
send: NID=0x21, VERB=0x371(set_amp_gain_mute,I:LR#1), PARM=0x80
send: NID=0x21, VERB=0x372(set_amp_gain_mute,I:LR#2), PARM=0x80
send: NID=0x21, VERB=0x373(set_amp_gain_mute,I:LR#3), PARM=0x80
send: NID=0x21, VERB=0x375(set_amp_gain_mute,I:LR#5), PARM=0x0
invalid amp index 5 (conns=5)
How did you get these values?
Post by Raymond Yau
Seem no "Stereo Mix" , 0x28 is HP and only 0x2c, 0x2b and 0x29 are input
sources and the other must be muted
node 0x2a "Line Playback Switch" have to be muted and write-protect whenever
blue jack is retask
need to modify vt1718S_auto_create_analog_input_ctls()
I have no idea how to do that, my understanding of the code is to
limited for now. Perhaps it should be also considered if one needs to
modify only vt1718S_auto_create_analog_input_ctls(), both this one and
vt_auto_create_analog_input_ctls() or just the latter (but perhaps you
just mean the former function should pass a different array to the
latter one, and I'm misunderstanding they should also take care
somehow of node 0x2a retasking, at least on creation)

Node 0x2c [Pin Complex] wcaps 0x400401: Stereo
Pincap 0x00000020: IN
Pin Default 0x593701f8: [N/A] CD at Int ATAPI
Conn = Analog, Color = Unknown
DefAssociation = 0xf, Sequence = 0x8
Misc = NO_PRESENCE
Pin-ctls: 0x00:
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0

What should this be? It doesn't seem to me there's any CD Audio
connector in my motherboard. Is it supported by the codec anyway?

Regards
Raymond Yau
2011-05-18 03:36:33 UTC
Permalink
2011/5/17 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Hello,
It took me a while before I could post again here, sorry.
I've installed the snapshot tarball I had downloaded, with debug
support enabled, result at following link; results are close to
previous ones.
http://pastebin.ca/2056960
Post by Raymond Yau
2011/5/9 alex dot baldacchino dot alsasub at gmail dot com <
you have to ask the distribution maintainer how to test the latest
alsa-driver without upgrading the kernel.
It seems configure script for the snapshot has found correct source
and installation paths, overwriting existing sound drivers, as
expectable; I've left userspace configuration untouched (installed new
modules with 'make install-modules' to leave alsa script in
/etc/init.d as it was).
!!Aplay/Arecord output
!!------------

APLAY

aplay: device_list:240: no soundcards found...

ARECORD

arecord: device_list:240: no soundcards found...

!!Amixer output
!!-------------

!!-------Mixer controls for card 0 [SB]

Invalid card number.
Usage: amixer <options> [command]



You may need the expert to tell you what 's wrong since you need
amixer to change the controls and aplay/arecord to perform test
Post by alex dot baldacchino dot alsasub at gmail dot com
In my previous messages I forgot to mention my chassis has a front
panel with mic and hp jacks; it is said to support both hd and ac'97
audio - it's got a multi-pin single connector labeled 'hd audio' with
all available pins wired (fully fitting the MoBo header, and is
actually inserted); from that one, another connector is derived,
labeled 'ac97 audio', with a pair of pins missing and some other
'duplicated' (I'm not using it). I've made a few tests, one with front
panel disabled in bios, one with front panel enabled in bios (bios
option set to auto - please, note there can be an error in my MoBo
manual, since only available options for the front panel are 'Auto'
and 'Disabled', there's no 'Enabled' ) but physically unconnected.
http://pastebin.ca/2060444
Node 0x28 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x422140f0: [N/A] HP Out at Ext Front
Conn = 1/8, Color = Green
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x00: VREF_HIZ
Unsolicited: tag=21, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1b
ALSA hda_intel.c:1457: Enable sync_write for AMD chipset
ALSA hda_codec.c:4707: autoconfig: line_outs=3
(0x24/0x25/0x26/0x0/0x0) type:line
ALSA hda_codec.c:4711:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4715:    hp_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4716:    mono: mono_out=0x0
ALSA hda_codec.c:4719:    dig-out=0x2d/0x0
( it seems there's no hp output, 0x28 is _not_ listed )
Some part of the code in the driver seem expect HP jack always present
but this is not true any more
As someone mention in the bug report that his small desktop (used as
media center) does not even has the front audio panel,

using hda-emu and your codec info

send: NID=0x0, VERB=0xf00(get_parameters), PARM=0xc(pin_cap)
receive: 0x0
send: NID=0x0, VERB=0xf09(get_pin_sense), PARM=0x0
Invalid pin node
receive: 0x0


The driver should not create "Independent HP" switch when there is no hp jack

There shold be only one subdevice when there is no "Independent HP" switch

    info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
        spec->multiout.dac_nids[0];
+    info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams =
+       ( snd_hda_find_mixer_ctl(codec, "Independent HP") ? 2 : 1);

    info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
Post by alex dot baldacchino dot alsasub at gmail dot com
http://pastebin.ca/2060448
Node 0x28 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
 Control: name="Headphone Playback Switch", index=0, device=0
   ControlAmp: chs=3, dir=Out, idx=0, ofs=0
 Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-Out vals:  [0x00 0x00]
 Pincap 0x0000233c: IN OUT HP Detect
   Vref caps: HIZ 50 100
 Pin Default 0x0221411f: [Jack] HP Out at Ext Front
   Conn = 1/8, Color = Green
   DefAssociation = 0x1, Sequence = 0xf
   Misc = NO_PRESENCE
 Pin-ctls: 0xc0: OUT HP VREF_HIZ
 Unsolicited: tag=21, enabled=1
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 1
    0x1b
Misc=NO_PRESENCE mean the external circuitry is not capable of
supporting the functionality

Misc[3:0] is a bit field used to indicate other information about the jack.
Currently, only bit 0 is defined. If bit 0 is set, it indicates that
the jack has no presence detect capability, so even if a Pin Complex
indicates that the codec hardware supports the presence detect
functionality on the jack, the external circuitry is not capable of
supporting the functionality.
Post by alex dot baldacchino dot alsasub at gmail dot com
   Misc = NO_PRESENCE )
ALSA hda_codec.c:4707: autoconfig: line_outs=3
(0x24/0x25/0x26/0x0/0x0) type:line
ALSA hda_codec.c:4711:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4715:    hp_outs=1 (0x28/0x0/0x0/0x0/0x0)
ALSA hda_codec.c:4716:    mono: mono_out=0x0
ALSA hda_codec.c:4719:    dig-out=0x2d/0x0
It seems that node 0x28 represents the front panel line-out and
connection 0x0c is not used by anyone else (possible? rigth to work
this way? am I misunderstanding the log?). On the other hand, it is
labeled as "[Jack] HP Out at Ext Front", so it was expectable to work
this way (right?).
Do you mean the BIOS is able to differentiate HD front panel and AC97
Front panel without user to setup ?

I think those first generation HDA codecs are AC97 compatible
Post by alex dot baldacchino dot alsasub at gmail dot com
Now, I'm courious about node 0x24, which represents the rear green
line-out (and is the only rear line-out involved in all output
configurations, from 2 to 8 channels); in all cases it is presented
Node 0x24 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
 Control: name="Front Playback Switch", index=0, device=0
   ControlAmp: chs=3, dir=Out, idx=0, ofs=0
 Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-Out vals:  [0x00 0x00]
 Pincap 0x0001001c: OUT HP EAPD Detect
 EAPD 0x2: EAPD
 Pin Default 0x01014010: [Jack] Line Out at Ext Rear
   Conn = 1/8, Color = Green
   DefAssociation = 0x1, Sequence = 0x0
 Pin-ctls: 0x40: OUT
 Unsolicited: tag=20, enabled=1
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 1
    0x18
Node 0x18 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
 Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-In vals:  [0x00 0x00] [0x00 0x00]
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 2
    0x08 0x21
Node 0x08 [Audio Output] wcaps 0x41d: Stereo Amp-Out
 Control: name="Front Playback Volume", index=0, device=0
   ControlAmp: chs=3, dir=Out, idx=0, ofs=0
 Device: name="VT2020 Analog", type="Audio", device=0
 Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
 Amp-Out vals:  [0x2a 0x2a]
 Converter: stream=0, channel=0
   rates [0x5e0]: 44100 48000 88200 96000 192000
   bits [0xe]: 16 20 24
   formats [0x1]: PCM
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
0x08 is also listed as possible connection for node 0x034 and 0x035
Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
 Control: name="Independent HP", index=0, device=0
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 3
    0x08 0x0b 0x0c*
Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 3
    0x08 0x0b* 0x0c
Therefore, could 0x18 be a suitable return value for
side_mute_channel() function? (though I'd suppose an 'Audio Selector'
should be looked for instead of an 'Audio Mixer') How could I check
that?
In other words, I need also to understand what are exactly the
"Independent HP"s looked for and how they're enumerated, whether by
counting all possible output configurations that could be involved in
a Multi-Stream scenario (hence including rear channels) or just those
ones which exist beside the 'main group' (the rear group of line-outs
making up multichannel configurations).
The usage of those [Audio Output] are defined in
vt1718S_auto_create_multi_out_ctls()
Post by alex dot baldacchino dot alsasub at gmail dot com
In the latter case, are they always coupled? I'm asking because it
seems to me that via_hp_build() assumes there are either exactly 2
Independent HP controls (when snd_hda_get_connections() returns a
value greater than 1) or none (otherwise). Could there be just one
such control instead?
Post by Raymond Yau
it look like the driver is not installed correctly
[...cut...]
All is possible... but I wonder how... All I've done is downloading
the new kernel, patching it according to older kernels for my distro
(nothing related to sound, just lowering DEFAULT_CONSOLE_LOGLEVEL from
7 to 3, adding a few printk's to usb-storage, additional vortex device
ids, aufs), configuring it through 'make menuconfig' (using older
kernel configuration as a hint), issuing 'make bzImage', issuing 'make
modules', issuing 'make INSTALL_MOD_PATH=/some/path modules_install",
copying modules in their final destination ( /lib/modules/<version> ),
updating my initrd (which doesn't handle sound) and rebooting.... I've
left sound configuration (userspace-side) untouched.
That worked with the older kernel I'm using (from my distro - it was
yet configured and patched, but I've updated patches - such as aufs -
tuned it a few times to create different flavours, build and installed
it as above). Unless there's something only working for alsa 1.0.21
and causing problems with alsa 1.0.23 - alsa 1.0.24 in
/etc/init.d/alsa, /etc/modprobe.d/* files (I have no .asoundrc),
drivers installation shouldn't be the problem, AFAICT...
Post by Raymond Yau
Most likely you will need this patch
cb34c207af4944e9c93e2b462e351430f15daad6
so that the driver do not create "smart5.1" control since blue jack may need
to retask as side according to the user manual
ALSA: hda - VIA: Fix Smart5.1 isn't useful for 6 audio jacks motherboard.
I guess that should be embedded in the snapshot I've installed... In
file 'patch_via.c', function 'via_smart51_build' checks for line_outs
number before cloning smart5.1 controls; anyway, there's nothing
connected to my blue jack at the moment.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Lastly, do I need to enable debug? (that is, is it required for better
alsa-info output?)
The driver print debug messages in system log , you are able to know which
[Audio Output] is used when switch "Independent HP" on/off or retask blue
jack as output
Well, alsa-info.sh collects those messages related to sound, I was
asking if people here wish to read them for a better understanding of
the problem (I've enabled debug in the snapshot, so those lines are in
my new alsa-info posts). Sorry I wasn't clear about my doubt.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
For now, below I'm posting alsa-info.sh output for current
configuration and for kernel 2.6.33.2 (with working sound), hoping
this can help for comparison.
Post by Raymond Yau
Post the output of alsa-info.sh
What is the model of your computer (desktop/notebook) ?
Mine is a home-build desktop with an Asrock motherboard (I don't know of
any
notebook with asrock MoBo), model '890GX Extreme3', with integrated
graphics (Radeon HD4290) and audio (via vt2020 codec and ati hdmi), NB
AMD 890GX, SB850;
Post by Raymond Yau
How many audio jacks ?
Rear panel: 5 jacks for 7.1 channels audio + 1 Optical SPDIF OUT port
On board: front panel audio header for ac97/hd audio (connectors for
mic, left, right -
Refer to page 12 of 890GX Extreme3 's user manual
TABLE for Audio Output Connection
Blue jack is re-tasked for "Side" channel to support 8 channels
I was trying to count the max number of jacks my MoBo can support,
regardless they're in the rear or front panel, present or not. I guess
you were asking for rear ones only, sorry for my misunderstanding.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
"hda-codec: no NID for mapping control Independent HP:0:0".
Node 0x28 HP  is connected to 0x34 through 0x1b
[Audio Output] 0x0c has the "Headphone Volume" control
As "Line in" can only be connected to 0x0c
so the fix mainly depend on whether 0x0b can be used or not
How can I check that? (that is, 0x0b usability for the purpose?)
static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
const struct auto_pin_cfg *cfg)
{
char name[32];
static const char * const chname[4] = {
"Front", "Surround", "C/LFE", "Side"
};
hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};


the current driver only support 6 channels since it cannot find the
grey jack at node 0x27

spec->multiout.max_channels = spec->multiout.num_dacs * 2;

The current driver seem work with 6 jacks motherboard and need fix to
work with 5 jacks motherboard
Post by alex dot baldacchino dot alsasub at gmail dot com
Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
 Control: name="Independent HP", index=0, device=0
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 3
    0x08 0x0b 0x0c*
What does the asterisk mean? Is it to indicate the active/used connection?
It seems to me that
Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
 Control: name="Front Mic Boost Capture Volume", index=0, device=0
   ControlAmp: chs=3, dir=In, idx=0, ofs=0
 Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-Out vals:  [0x80 0x80]
 Pincap 0x0000233c: IN OUT HP Detect
   Vref caps: HIZ 50 100
 Pin Default 0x02a19037: [Jack] Mic at Ext Front
   Conn = 1/8, Color = Pink
   DefAssociation = 0x3, Sequence = 0x7
 Pin-ctls: 0x21: IN VREF_50
 Unsolicited: tag=20, enabled=1
 Power states:  D0 D1 D2 D3
 Power: setting=D3, actual=D3
 Connection: 1
    0x1c
is connected through
Node 0x1c [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
 Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
 Amp-In vals:  [0x00 0x00] [0x80 0x80]
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 2
    0x35 0x21
to
Node 0x35 [Audio Selector] wcaps 0x300501: Stereo
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
 Connection: 3
    0x08 0x0b* 0x0c
which uses
Node 0x0b [Audio Output] wcaps 0x41d: Stereo Amp-Out
 Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
 Amp-Out vals:  [0x2a 0x2a]
 Converter: stream=0, channel=0
   rates [0x5e0]: 44100 48000 88200 96000 192000
   bits [0xe]: 16 20 24
   formats [0x1]: PCM
 Power states:  D0 D1 D2 D3
 Power: setting=D3, actual=D3
Am I wrong?
Should it work differently?
Take a look at via_independent_get() and via_independent_put()

pinsel determine the connection of [Audio Selector] to [Audio Output]
0x08 , 0x0b and 0x0c

so it depend on using 0x0b or 0x0c as [Audio Output] for headphone
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
if vt2020 is as same as vt1718s,  you need to find a correct nid in the
function side_mute_channel() for update_side_mute_status() which mute/unmute
side channel when independent HP Is "ON"/"OFF"
it seem that vt1718s does not need to update_side_mute_status if there
is a grey jack

http://git.alsa-project.org/?p=alsa-kernel.git;a=commit;h=4d02d1b638af580ae3d69367248539a8b3893064


static const struct snd_kcontrol_new via_hp_mixer[2] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Independent HP",
.info = via_independent_hp_info,
.get = via_independent_hp_get,
.put = via_independent_hp_put,
},
{
.iface = NID_MAPPING,
.name = "Independent HP",
},
};
Post by alex dot baldacchino dot alsasub at gmail dot com
Given actual implementation, those should be at least compatible to
some extent; in case there were differences between nids in different
'flavours' of vt1718s ( for the sake of side_mute_channel(struct
via_spec *spec) ), it should be possible to check
spec->codec->vendor_id within the switch statement when
spec->codec_type is VT1718S - the problem is finding the right nid
https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/772638

There is codec info of vt1718s on ASRock H55M Pro

comparing the nodes and topology with those of vt1718s

vt2020 has

Node 0x13 [Audio Input] wcaps 0x100711: Stereo Digital
Node 0x22 [Beep Generator Widget] wcaps 0x70040c: Mono Amp-Out
Node 0x2f [Pin Complex] wcaps 0x400601: Stereo Digital

1) grey jack at 0x27 is connected to 0x0b through 0x1a and  HP is
connected to 0x0c through 0x1b


what the driver need is a "channel mode" switch from 6 to 8 which
configure 0x2a as output/input , and change max_channels between 6 and
8


2) without grey jack ,
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
note there can be an error in my MoBo manual,
There are two choice
a) 0x2a is really can be retask as output and connected to 0x0c so HP
may need to connect to 0x0b

b) HP is retasked as Side



http://www.viaarena.com/forums/showthread.php?t=41015

Refer to administrator 's answer

The Headphone Configuration Panel is shown in Figure 18. There are two
headphone configurations that can be chosen: “Independent Headphone”
or “Redirected Headphone”.
The “Independent Headphone” feature enables the user to play separate
music on the headphone and speaker. For example, the user can use a
multi-channel device (such as 5.1 surround sound) to watch a movie
while simultaneously using the independent headphone feature to make
phone calls through a VoIP Internet phone.

The “Redirected Headphone” feature enables the user to hear the same
audio that is being channeled to the front speakers. In this mode,
once the headphone has been inserted the audio will be redirected from
the speakers to the headphone.
Please note that the “Independent Headphone” function requires two
channels. Therefore, only six
channels will be available if “Independent Headphone” is being used.


In alsa,

when independent HP is on,

The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1

you can use aplay -Dhw:0,0,1 stereo.wav

When Independent HP is off, (it is similar to Redirected Headphone)
when automute is not enabled
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
send: NID=0x21, VERB=0x370(set_amp_gain_mute,I:LR#0), PARM=0x80
send: NID=0x21, VERB=0x371(set_amp_gain_mute,I:LR#1), PARM=0x80
send: NID=0x21, VERB=0x372(set_amp_gain_mute,I:LR#2), PARM=0x80
send: NID=0x21, VERB=0x373(set_amp_gain_mute,I:LR#3), PARM=0x80
send: NID=0x21, VERB=0x375(set_amp_gain_mute,I:LR#5), PARM=0x0
invalid amp index 5 (conns=5)
How did you get these values?
hda-emu show this error since 0x21 only has 5 connections

ode 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
  Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
  Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x97 0x97]
  Power states:  D0 D1 D2 D3
  Power: setting=D0, actual=D0
  Connection: 5
     0x2c 0x2b 0x2a 0x29 0x28

Fix seem to be

static const struct hda_verb vt1718S_volume_init_verbs[] = {

/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Seem no "Stereo Mix" ,  0x28 is HP and only 0x2c, 0x2b and 0x29 are input
sources and the other must be muted
node 0x2a "Line Playback Switch" have to be muted and write-protect whenever
blue jack is retask
need to modify vt1718S_auto_create_analog_input_ctls()
I have no idea how to do that, my understanding of the code is to
limited for now. Perhaps it should be also considered if one needs to
modify only vt1718S_auto_create_analog_input_ctls(), both this one and
vt_auto_create_analog_input_ctls() or just the latter (but perhaps you
just mean the former function should pass a different array to the
latter one, and I'm misunderstanding they should also take care
somehow of node 0x2a retasking, at least on creation)
Can you record from blue jack ?

you should able to hear the input signal of blue jack at green jack
when you unmute "Line Playback Volume"
Post by alex dot baldacchino dot alsasub at gmail dot com
Node 0x2c [Pin Complex] wcaps 0x400401: Stereo
 Pincap 0x00000020: IN
 Pin Default 0x593701f8: [N/A] CD at Int ATAPI
   Conn = Analog, Color = Unknown
   DefAssociation = 0xf, Sequence = 0x8
   Misc = NO_PRESENCE
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
What should this be? It doesn't seem to me there's any CD Audio
connector in my motherboard. Is it supported by the codec anyway?
This mean that No physical connection for CD connector at the motherboard

Pin Default 0x593701f8

Bit 31:30 Port connectiviy

00b The Port Complex is connected to a jack (1/8", ATAPI, etc.).
01b No physical connection for Port.
10b A fixed function device (integrated speaker, integrated mic, etc.)
is attached.
11b Both a jack and an internal device are attached. The Information
provided in all other fields refers to the integrated device. The PD
pin will reflect the status of the jack; the user will need to be
queried to figure out what it is.
alex dot baldacchino dot alsasub at gmail dot com
2011-05-27 14:49:05 UTC
Permalink
Post by Raymond Yau
2011/5/17 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Hello,
It took me a while before I could post again here, sorry.
I've installed the snapshot tarball I had downloaded, with debug
support enabled, result at following link; results are close to
previous ones.
[...]
It seems configure script for the snapshot has found correct source
and installation paths, overwriting existing sound drivers, as
expectable; I've left userspace configuration untouched (installed new
modules with 'make install-modules' to leave alsa script in
/etc/init.d as it was).
!!Aplay/Arecord output
!!------------
APLAY
aplay: device_list:240: no soundcards found...
ARECORD
arecord: device_list:240: no soundcards found...
!!Amixer output
!!-------------
!!-------Mixer controls for card 0 [SB]
Invalid card number.
Usage: amixer <options> [command]
You may need the expert to tell you what 's wrong since you need
amixer to change the controls and aplay/arecord to perform test
As I wrote in my first mail, there's a mixer in my system failing an
assertion in alsa-lib; starting from there I've investigated what was
going on there in (by adding some fprintf to stderr to a few library
functions) and have found a sort of inconsistency across /dev/snd/*
files minors, udev and the driver. Alsa-lib was using files in
/dev/snd, which are statically created with minors that work in kernel
2.6.33.2 + alsa driver 1.0.21, but seems to be unusable for driver
version 1.0.23 - 1.0.24. At the same time, udev created sound related
stuff in /dev (which weren't used), with the very same major/minor as
those ones in /dev/snd in k .33 + alsa 1.0.21, but different minors
with a newer alsa driver (e.g. I get /dev/controlC0 with minor 6 (by
udev) vs /dev/snd/controlC0 (statically existing) with minor 0,
/dev/controlC1 with minor 9 vs /dev/snd/controlC1 with minor 32 and so
on). Changing some macros in alsa lib, such as SND_FILE_CONTROL in
cards.c, so that files in /dev where used seemed to solve, so I've
rebuild alsa lib with option "--with-alsa-devdir=/dev" and now things
seem to work... (please, note that's the same regardless of compiling
the driver with or without support for dynamic minors, actually it
works without dynamic minors using udev created files) alsa-info
output at following link:

http://pastebin.ca/2069512


As an aside, I've noted there are different macros defined in
different files (in alsa-lib source) to access the same resource. For
instance, in file cards.c

#define SND_FILE_CONTROL ALSA_DEVICE_DIRECTORY "controlC%i"

and in file control_hw.c

#define SNDRV_FILE_CONTROL ALSA_DEVICE_DIRECTORY "controlC%i"

those are/can be used in the same 'context', I mean, at some point
function _snd_ctl_hw_open() (in file control_hw.c) can call function
snd_card_get_index() (in file cards.c) which uses function
snd_card_load1() which uses SND_FILE_CONTROL; then (at
last)_snd_ctl_hw_open() calls snd_ctl_hw_open() (same file) which uses
SNDRV_FILE_CONTROL, but then snd_ctl_hw_open() can call snd_card_load
(cards.c) and again snd_card_load1(). It might look a bit complicated
(and somehow duplicated, but both _snd_ctl_hw_open() and
snd_ctl_hw_open() are interface functions and could be eventually
called independently), but I understand one may need to open a device
ro and call an ioctl to get info about it before (re-)opening it rw
(though I think functions in cards.c could avoid calling both
snd_ctl_hw_open() and snd_ctl_card_info() with a simple change to
snd_card_load2(), but that's another story). Anyway, the overall
mechanism requires consistency between macros used to identify a
control's path, so, perhaps, using just one and moving it into a
(local, non-interface) header could improve maintainability a bit,
eventually (just a little consideration).

Moreover, it looks like there's a bug in snd_ctl_hw_open() (but it
could have been fixed and I could have missed it - just using the
stable source I got a while ago for lib 1.0.24.1). In the end it
executes the following block - I've added a comment where I think
something else should be done:

err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name);
if (err < 0) {
close(fd);
free(hw);
/* COMMENT ADDED BY ME */
/* should return -ENOMEM (that is err) ?*/
}
ctl->ops = &snd_ctl_hw_ops;
ctl->private_data = hw;
ctl->poll_fd = fd;
*handle = ctl;
return 0;

If snd_ctl_new() failed, variable ctl would rest uninitialized and a
random memory area would be overwritten by successive assignments to
dereferenced offsets of ctl.

For the rest, I need some more learning of the driver and architecture
insights. For the moment, I can tell the following.

First of all, I was misinterpreting entries in a connection list as
outputs instead of inputs (as per hd audio specs), so I was a bit
confused on what widget was driving what widget.

I've not applied the lines you were suggesting, because I'm still
trying to understand how things work and how would work after any
change (and have been more focused on solving driver installation
issues).
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
http://pastebin.ca/2060448
[..]
Misc=NO_PRESENCE mean the external circuitry is not capable of
supporting the functionality
Misc[3:0] is a bit field used to indicate other information about the jack.
Currently, only bit 0 is defined. If bit 0 is set, it indicates that
the jack has no presence detect capability, so even if a Pin Complex
indicates that the codec hardware supports the presence detect
functionality on the jack, the external circuitry is not capable of
supporting the functionality.
That's meaningful. Since the panel wasn't connected to the
motherboard, just enabled in bios, the driver must have checked what
signals came from that path and got none. It seems it worked as it
should be supposed to.
Post by Raymond Yau
Do you mean the BIOS is able to differentiate HD front panel and AC97
Front panel without user to setup ?
I think those first generation HDA codecs are AC97 compatible
My BIOS has only two options for the front panel: [Auto] and
[Disabled], thus it should be capable of autodetection (though, the
manual would suggest there should be a third option [Enabled] to set
the front panel up as AC97, but there's no such option).
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
if vt2020 is as same as vt1718s,  you need to find a correct nid in the
function side_mute_channel() for update_side_mute_status() which mute/unmute
side channel when independent HP Is "ON"/"OFF"
it seem that vt1718s does not need to update_side_mute_status if there
is a grey jack
http://git.alsa-project.org/?p=alsa-kernel.git;a=commit;h=4d02d1b638af580ae3d69367248539a8b3893064
static const struct snd_kcontrol_new via_hp_mixer[2] = {
       {
               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
               .name = "Independent HP",
               .info = via_independent_hp_info,
               .get = via_independent_hp_get,
               .put = via_independent_hp_put,
       },
       {
               .iface = NID_MAPPING,
               .name = "Independent HP",
       },
};
Must these controls be always coupled? Is it a specification
constraint? What if via_hp_build() didn't execute

knew = via_clone_control(spec, &via_hp_mixer[1]);

when side_mute_status() returned '0' ?
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Given actual implementation, those should be at least compatible to
some extent; in case there were differences between nids in different
'flavours' of vt1718s ( for the sake of side_mute_channel(struct
via_spec *spec) ), it should be possible to check
spec->codec->vendor_id within the switch statement when
spec->codec_type is VT1718S - the problem is finding the right nid
https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/772638
There is codec info of vt1718s on ASRock H55M Pro
comparing the nodes and topology with those of vt1718s
vt2020 has
Node 0x13 [Audio Input] wcaps 0x100711: Stereo Digital
Node 0x22 [Beep Generator Widget] wcaps 0x70040c: Mono Amp-Out
Node 0x2f [Pin Complex] wcaps 0x400601: Stereo Digital
1) grey jack at 0x27 is connected to 0x0b through 0x1a and  HP is
connected to 0x0c through 0x1b
what the driver need is a "channel mode" switch from 6 to 8 which
configure 0x2a as output/input , and change max_channels between 6 and
8
2) without grey jack ,
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
note there can be an error in my MoBo manual,
There are two choice
a) 0x2a is really can be retask as output and connected to  0x0c so HP
may need to connect to 0x0b
b) HP is retasked as Side
I haven't got an 8-channel system to test it; according to the manual,
line in should be used to create an 8 channel setup. As I understand
it, line-in (blue jack) should be a replacement for the gray jack when
retasked.
Post by Raymond Yau
http://www.viaarena.com/forums/showthread.php?t=41015
Refer to administrator 's answer
The Headphone Configuration Panel is shown in Figure 18. There are two
headphone configurations that can be chosen: “Independent Headphone”
or “Redirected Headphone”.
The “Independent Headphone” feature enables the user to play separate
music on the headphone and speaker. For example, the user can use a
multi-channel device (such as 5.1 surround sound) to watch a movie
while simultaneously using the independent headphone feature to make
phone calls through a VoIP Internet phone.
The “Redirected Headphone” feature enables the user to hear the same
audio that is being channeled to the front speakers. In this mode,
once the headphone has been inserted the audio will be redirected from
the speakers to the headphone.
Please note that the “Independent Headphone” function requires two
channels. Therefore, only six
channels will be available if “Independent Headphone” is being used.
The last part is interesting. If vt2020 works the same way, the
8-channel setup should disallow the "Independent HP" function, that is
it should be automatically turned off and 0x28 should be either muted,
or used as a 'duplicate' for 0x0c (same sound of blue jack) or 0x08
(same sound as rear green jack, as in 'redirected audio' ). If I'm not
misunderstanding everything, of course.

BTW, 0x2a is connected to (gets input from) 0x09, which is labeled
'Surround Playback Volume' and is also an input for 0x25 ('Surround
Playback Switch', black jack, rear speaker according to manual)
throughout 0x19; 0x27 (missing gray jack) would be connected to 0x0b
throughout 0x1a...
Post by Raymond Yau
In alsa,
when independent HP is on,
The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1
you can use aplay -Dhw:0,0,1 stereo.wav
Tested: it works. I can get different streams out of rear (front
playback) and front (hp) line out jacks (used mplayer on the 'default'
rear channel(s) and aplay as above on the front panel)
Post by Raymond Yau
When Independent HP is off, (it is similar to Redirected Headphone)
when automute is not enabled
Turning off Independent HP I can notice the following change:

Node 0x34 [Audio Selector] wcaps 0x300501: Stereo
Control: name="Independent HP", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 3
0x08* 0x0b 0x0c

Node 0x08 is connected to rear green jack, and I get same sound on
both rear and front jacks
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Seem no "Stereo Mix" ,  0x28 is HP and only 0x2c, 0x2b and 0x29 are input
sources and the other must be muted
node 0x2a "Line Playback Switch" have to be muted and write-protect whenever
blue jack is retask
need to modify vt1718S_auto_create_analog_input_ctls()
I have no idea how to do that, my understanding of the code is to
limited for now. Perhaps it should be also considered if one needs to
modify only vt1718S_auto_create_analog_input_ctls(), both this one and
vt_auto_create_analog_input_ctls() or just the latter (but perhaps you
just mean the former function should pass a different array to the
latter one, and I'm misunderstanding they should also take care
somehow of node 0x2a retasking, at least on creation)
Can you record from blue jack ?
you should able to hear the input signal of blue jack at green jack
when you unmute "Line Playback Volume"
I cannot test it properly at the moment. I've tried to use my
headset's mic connected to blue jack, setting 'line' as first input
source and executing 'arecord -vv -d 5 test.wav'. Playing the
resulting file with "aplay -vv test.wav" showed a noisy and highly
distorted, yet understandable (mono) sound (with all controls set to
their max value); recording from rear mic jack, selecting both 'stereo
mix' and 'rear mic' as input source created a more natural but still
noisy sound (playing with the mixer solves the problem, but I needed
top volumes to get sound from line-in without an external amplifier).

By the way, when I select 'Line' as input source with a mixer
(selected both sources), I can notice the following changes:


Node 0x1e [Audio Selector] wcaps 0x300501: Stereo
Control: name="Input Source", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 6
0x2c 0x2b 0x2a* 0x29 0x28 0x21
Node 0x1f [Audio Selector] wcaps 0x300501: Stereo
Control: name="Input Source", index=1, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 6
0x2c 0x2b 0x2a* 0x29 0x28 0x21


Selecting 'stereo mixer' those are:


Node 0x1e [Audio Selector] wcaps 0x300501: Stereo
Control: name="Input Source", index=0, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 6
0x2c 0x2b 0x2a 0x29 0x28 0x21*
Node 0x1f [Audio Selector] wcaps 0x300501: Stereo
Control: name="Input Source", index=1, device=0
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 6
0x2c 0x2b 0x2a 0x29 0x28 0x21*
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Node 0x2c [Pin Complex] wcaps 0x400401: Stereo
 Pincap 0x00000020: IN
 Pin Default 0x593701f8: [N/A] CD at Int ATAPI
   Conn = Analog, Color = Unknown
   DefAssociation = 0xf, Sequence = 0x8
   Misc = NO_PRESENCE
 Power states:  D0 D1 D2 D3
 Power: setting=D0, actual=D0
What should this be? It doesn't seem to me there's any CD Audio
connector in my motherboard. Is it supported by the codec anyway?
This mean that No physical connection for CD connector at the motherboard
Pin Default 0x593701f8
Bit 31:30 Port connectiviy
00b The Port Complex is connected to a jack (1/8", ATAPI, etc.).
01b No physical connection for Port.
10b A fixed function device (integrated speaker, integrated mic, etc.)
is attached.
11b Both a jack and an internal device are attached. The Information
provided in all other fields refers to the integrated device. The PD
pin will reflect the status of the jack; the user will need to be
queried to figure out what it is.
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Thank you for your clarification.

Regards
Raymond Yau
2011-05-31 13:34:01 UTC
Permalink
2011/5/27 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Must these controls be always coupled? Is it a specification
constraint? What if via_hp_build() didn't execute
knew = via_clone_control(spec, &via_hp_mixer[1]);
when side_mute_status() returned '0' ?
If you disabled "Front Audio Panel" in BIOS,
vt1718s_auto_create_hp_ctls() won't build any controls related to HP
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Given actual implementation, those should be at least compatible to
some extent; in case there were differences between nids in different
'flavours' of vt1718s ( for the sake of side_mute_channel(struct
via_spec *spec) ), it should be possible to check
spec->codec->vendor_id within the switch statement when
spec->codec_type is VT1718S - the problem is finding the right nid
The last part is interesting. If vt2020 works the same way, the
8-channel setup should disallow the "Independent HP" function, that is
it should be automatically turned off and 0x28 should be either muted,
or used as a 'duplicate' for 0x0c (same sound of blue jack) or 0x08
(same sound as rear green jack, as in 'redirected audio' ). If I'm not
misunderstanding everything, of course.
static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 10,
.nid = 0x8, /* NID to query formats and rates */

This look like vt1718s support 10 channels and 10 channels allow
independent HP and surround71 at the same time
Post by alex dot baldacchino dot alsasub at gmail dot com
BTW, 0x2a is connected to (gets input from) 0x09, which is labeled
'Surround Playback Volume' and is also an input for 0x25 ('Surround
Playback Switch', black jack, rear speaker according to manual)
throughout 0x19; 0x27 (missing gray jack) would be connected to 0x0b
throughout 0x1a...
Post by Raymond Yau
In alsa,
when independent HP is on,
The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1
you can use aplay -Dhw:0,0,1 stereo.wav
Tested: it works. I can get different streams out of rear (front
playback) and front (hp) line out jacks (used mplayer on the 'default'
rear channel(s) and aplay as above on the front panel)
so you can check whether 0xb can be used instead of 0xc for headphone

static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
hda_nid_t nid = kcontrol->private_value;
unsigned int pinsel = ucontrol->value.enumerated.item[0];
/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0;
if (spec->codec_type == VT1718S)
snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+ AC_VERB_SET_CONNECT_SEL, pinsel ?
+ spec->hp_independent_mode_index : 0);


static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
{
int err;

if (!pin)
return 0;
+ if (spec->autocfg.line_outs == 4) {
spec->multiout.hp_nid = 0xc; /* AOW4 */
+ spec->hp_independent_mode_index = 2;
+ }
+ else {
+ spec->multiout.hp_nid = 0xb;
spec->hp_independent_mode_index = 1;
+}



static const struct hda_verb vt1718S_volume_init_verbs[] = {

- {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
+ {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
{0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
Post by alex dot baldacchino dot alsasub at gmail dot com
I haven't got an 8-channel system to test it; according to the manual,
line in should be used to create an 8 channel setup. As I understand
it, line-in (blue jack) should be a replacement for the gray jack when
retasked.
struct via_spec {

...
/* channel model */
const struct hda_channel_mode *channel_mode;
int num_channel_mode;
int const_channel_count;
int ext_channel_count;




/*
* channel mode setting
*/
static int via_ch_mode_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
spec->num_channel_mode);
}

static int via_ch_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
spec->num_channel_mode,
spec->ext_channel_count);
}

static int via_ch_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
spec->num_channel_mode,
&spec->ext_channel_count);
if (err >= 0 && !spec->const_channel_count) {
spec->multiout.max_channels = spec->ext_channel_count;
}
activate_ctl(spec->codec, "Side Playback Volume",
spec->multiout.max_channels == 8);
activate_ctl(spec->codec, "Side Playback Switch",
spec->multiout.max_channels == 8);
return err;
}

static const struct hda_verb vt1718S_6ch_init[] = {
{ 0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
{ } /* end */
};

static const struct hda_verb vt1718S_8ch_init[] = {
{ 0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{ 0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
{ 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01 },
{ } /* end */
};

static const struct hda_channel_mode vt1718S_modes[2] = {
{ 6, vt1718S_6ch_init },
{ 8, vt1718S_8ch_init },
};

static const struct snd_kcontrol_new vt1718S_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Channel Mode",
.info = via_ch_mode_info,
.get = via_ch_mode_get,
.put = via_ch_mode_put,
},
{ }
};





/* add playback controls from the parsed DAC table */
static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
const struct auto_pin_cfg *cfg)
{


...
if (spec->autocfg.line_outs == 3) { /* and 0x2a can be retask as output pin */
nid_vol = 0xc;
nid_mute = 0x2a;
err = via_add_control(
spec, VIA_CTL_WIDGET_VOL, "Side Playback Volume",
HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
err = via_add_control(
spec, VIA_CTL_WIDGET_MUTE, "Side Playback Switch",
HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;

spec->private_dac_nids[AUTO_SEQ_SIDE] = nid_vol;
spec->const_channel_count = 6;
spec->channel_mode = vt1718S_modes;
spec->num_channel_mode = ARRAY_SIZE(vt1718S_modes);
spec->mixers[spec->num_mixers] = vt1718S_chmode_mixer;
spec->num_mixers++;
}
}
alex dot baldacchino dot alsasub at gmail dot com
2011-06-01 16:16:04 UTC
Permalink
Post by Raymond Yau
2011/5/27 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Must these controls be always coupled? Is it a specification
constraint? What if via_hp_build() didn't execute
knew = via_clone_control(spec, &via_hp_mixer[1]);
when side_mute_status() returned '0' ?
If you disabled "Front Audio Panel" in BIOS,
vt1718s_auto_create_hp_ctls()  won't build any controls related to HP
Yes, that's something I had noticed in my tests: front panel disabled
in bios -> no hp controls; front panel enabled in bios BUT not
connected to the motherboard-> misc: no_presence for both 0x28 and
0x29.
Post by Raymond Yau
static const struct snd_kcontrol_new via_hp_mixer[2] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Independent HP",
.info = via_independent_hp_info,
.get = via_independent_hp_get,
.put = via_independent_hp_put,
},
{
.iface = NID_MAPPING,
.name = "Independent HP",
},
};
Must there be always two "Independent HP" controls in all via codecs,
or there could be just one? In the latter case via_hp_mixer[1] could
be ignored in some cases.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
The last part is interesting. If vt2020 works the same way, the
8-channel setup should disallow the "Independent HP" function, that is
it should be automatically turned off and 0x28 should be either muted,
or used as a 'duplicate' for 0x0c (same sound of blue jack) or 0x08
(same sound as rear green jack, as in 'redirected audio' ). If I'm not
misunderstanding everything, of course.
static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
       .substreams = 2,
       .channels_min = 2,
       .channels_max = 10,
       .nid = 0x8, /* NID to query formats and rates */
This look like vt1718s support 10 channels and 10 channels allow
independent HP and surround71 at the same time
If this part of the driver is correct, you're definitely right. That
also means admin's answer at

http://www.viaarena.com/forums/showthread.php?t=41015

is mistaken when he says

"Please note that the “Independent Headphone” function requires two
channels. Therefore, only six
channels will be available if “Independent Headphone” is being used."

On the other hand, the picture of via's configuration panel seems to
give him right: in "Independent HP" mode ("Auricular independiente" in
the picture) the two side speakers for surround effects are grayed out
as to mean they're disabled, whereas in 'Redirected Ouptut"
("Auricular redirigido" in the picture) those ones seem to be enabled.
Though, there could be a lack of support for all ten channels in the
motherboard implementation and/or a limitation in that particular
version of via's driver/mixer (if possible at all, I'm just
guessing...)
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
BTW, 0x2a is connected to (gets input from) 0x09, which is labeled
'Surround Playback Volume' and is also an input for 0x25 ('Surround
Playback Switch', black jack, rear speaker according to manual)
throughout 0x19; 0x27 (missing gray jack) would be connected to 0x0b
throughout 0x1a...
Post by Raymond Yau
In alsa,
when independent HP is on,
The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1
you can use aplay -Dhw:0,0,1 stereo.wav
Tested: it works. I can get different streams out of rear (front
playback) and front (hp) line out jacks (used mplayer on the 'default'
rear channel(s) and aplay as above on the front panel)
so you can check whether 0xb can be used instead of 0xc for headphone
static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       hda_nid_t nid = kcontrol->private_value;
       unsigned int pinsel = ucontrol->value.enumerated.item[0];
       /* Get Independent Mode index of headphone pin widget */
       spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
               ? 1 : 0;
       if (spec->codec_type == VT1718S)
               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+                                   AC_VERB_SET_CONNECT_SEL, pinsel ?
+                                   spec->hp_independent_mode_index : 0);
This is to select entry at index #1 (which should be 0x0b) in the
connection list of node 0x34 (the Audio Selector driving node 0x28)
when Independent HP is selected, right?
Post by Raymond Yau
[...cut...]
static const struct hda_verb vt1718S_volume_init_verbs[] = {
-       {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
+       {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
       {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
What's the param field's meaning here? Is it the index of a connection
list to be selected? In this case, entry #0 for 0x34 should be 0x08,
is it to start with Independent HP turned off?

For the rest of your code (6/8 channels mode selection and retasking
part), shall I apply that altogether with the 0x0b selection part, or
should I rather test if 0x0b is usable for headphone in place of 0x0c
first?
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
I haven't got an 8-channel system to test it; according to the manual,
line in should be used to create an 8 channel setup. As I understand
it, line-in (blue jack) should be a replacement for the gray jack when
retasked.
struct via_spec {
...
       /* channel model */
       const struct hda_channel_mode *channel_mode;
       int num_channel_mode;
       int const_channel_count;
       int ext_channel_count;
/*
 * channel mode setting
 */
static int via_ch_mode_info(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_info *uinfo)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
                                   spec->num_channel_mode);
}
static int via_ch_mode_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
                                  spec->num_channel_mode,
                                  spec->ext_channel_count);
}
static int via_ch_mode_put(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
                                     spec->num_channel_mode,
                                     &spec->ext_channel_count);
       if (err >= 0 && !spec->const_channel_count) {
               spec->multiout.max_channels = spec->ext_channel_count;
       }
       activate_ctl(spec->codec, "Side Playback Volume",
                       spec->multiout.max_channels == 8);
       activate_ctl(spec->codec, "Side Playback Switch",
                       spec->multiout.max_channels == 8);
       return err;
}
static const struct hda_verb vt1718S_6ch_init[] = {
       { 0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
       { } /* end */
};
static const struct hda_verb vt1718S_8ch_init[] = {
       { 0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
       { 0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
       { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01 },
       { } /* end */
};
static const struct hda_channel_mode vt1718S_modes[2] = {
       { 6, vt1718S_6ch_init },
       { 8, vt1718S_8ch_init },
};
static const struct snd_kcontrol_new vt1718S_chmode_mixer[] = {
       {
               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
               .name = "Channel Mode",
               .info = via_ch_mode_info,
               .get = via_ch_mode_get,
               .put = via_ch_mode_put,
       },
       { }
};
/* add playback controls from the parsed DAC table */
static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
                                            const struct auto_pin_cfg *cfg)
{
...
       if (spec->autocfg.line_outs == 3) {  /* and 0x2a can be retask as output pin */
               nid_vol = 0xc;
               nid_mute = 0x2a;
               err = via_add_control(
                       spec, VIA_CTL_WIDGET_VOL, "Side Playback Volume",
                       HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
               if (err < 0)
                       return err;
               err = via_add_control(
                       spec, VIA_CTL_WIDGET_MUTE, "Side Playback Switch",
                       HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
                                           HDA_OUTPUT));
               if (err < 0)
                       return err;
               spec->private_dac_nids[AUTO_SEQ_SIDE] = nid_vol;
               spec->const_channel_count = 6;
               spec->channel_mode = vt1718S_modes;
               spec->num_channel_mode = ARRAY_SIZE(vt1718S_modes);
               spec->mixers[spec->num_mixers] = vt1718S_chmode_mixer;
               spec->num_mixers++;
       }
}
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Raymond Yau
2011-06-07 08:32:20 UTC
Permalink
2011/6/2 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Must these controls be always coupled? Is it a specification
constraint? What if via_hp_build() didn't execute
knew = via_clone_control(spec, &via_hp_mixer[1]);
when side_mute_status() returned '0' ?
static const struct snd_kcontrol_new via_hp_mixer[2] = {
       {
               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
               .name = "Independent HP",
               .info = via_independent_hp_info,
               .get = via_independent_hp_get,
               .put = via_independent_hp_put,
       },
       {
               .iface = NID_MAPPING,
               .name = "Independent HP",
       },
};
Must there be always two "Independent HP" controls in all via codecs,
or there could be just one? In the latter case via_hp_mixer[1] could
be ignored in some cases.
Refer to commit 3d83e577a8206f0f3822a3840e12f76477142ba2

There are codec which does not support indepedent HP

http://thread.gmane.org/gmane.linux.alsa.devel/68414

NID_MAPPING seem used for debugging only

The error "hda-codec: no NID for mapping control Independent HP:0:0"
can be fixed by checking the value returned by side_mute_channel()


knew = via_clone_control(spec, &via_hp_mixer[0]);
if (knew == NULL)
return -ENOMEM;

knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
knew->private_value = nid;
+
+ if (side_mute_channel(spec) == 0)
+ return 0;

knew = via_clone_control(spec, &via_hp_mixer[1]);
if (knew == NULL)
return -ENOMEM;
knew->subdevice = side_mute_channel(spec);
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
The last part is interesting. If vt2020 works the same way, the
8-channel setup should disallow the "Independent HP" function, that is
it should be automatically turned off and 0x28 should be either muted,
or used as a 'duplicate' for 0x0c (same sound of blue jack) or 0x08
(same sound as rear green jack, as in 'redirected audio' ). If I'm not
misunderstanding everything, of course.
static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
       .substreams = 2,
       .channels_min = 2,
       .channels_max = 10,
       .nid = 0x8, /* NID to query formats and rates */
This look like vt1718s support 10 channels and 10 channels allow
independent HP and surround71 at the same time
If this part of the driver is correct, you're definitely right. That
also means admin's answer at
http://www.viaarena.com/forums/showthread.php?t=41015
is mistaken when he says
"Please note that the “Independent Headphone” function requires two
channels. Therefore, only six
channels will be available if “Independent Headphone” is being used."
On the other hand, the picture of via's configuration panel seems to
give him right: in "Independent HP" mode ("Auricular independiente" in
the picture) the two side speakers for surround effects are grayed out
as to mean they're disabled, whereas in 'Redirected Ouptut"
("Auricular redirigido" in the picture) those ones seem to be enabled.
Though, there could be a lack of support for all ten channels in the
motherboard implementation and/or a limitation in that particular
version of via's driver/mixer (if possible at all, I'm just
guessing...)
The codec vt1708s mentioned in the thread is a 8 channel codec


if you look at vt1718S_auto_fill_dac_nids() and
vt1718S_auto_create_hp_ctls() ,
grey jack use 0x0b and headphone use 0x0c

yes, it is still possible that vt1718s without a grey jack is just a 8
channel codec , but those variants of vt1718s which has a grey jack
are most likely a 10 channel codec

/* fill in the dac_nids table from the parsed pin configuration */
static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
const struct auto_pin_cfg *cfg)
{
int i;
hda_nid_t nid;

spec->multiout.num_dacs = cfg->line_outs;

spec->multiout.dac_nids = spec->private_dac_nids;

for (i = 0; i < 4; i++) {
nid = cfg->line_out_pins[i];
if (nid) {
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
spec->private_dac_nids[i] = 0x8;
break;
case AUTO_SEQ_CENLFE:
spec->private_dac_nids[i] = 0xa;
break;
case AUTO_SEQ_SURROUND:
spec->private_dac_nids[i] = 0x9;
break;
case AUTO_SEQ_SIDE:
spec->private_dac_nids[i] = 0xb;
break;
}
}
}

return 0;
}
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
BTW, 0x2a is connected to (gets input from) 0x09, which is labeled
'Surround Playback Volume' and is also an input for 0x25 ('Surround
Playback Switch', black jack, rear speaker according to manual)
throughout 0x19; 0x27 (missing gray jack) would be connected to 0x0b
throughout 0x1a...
Post by Raymond Yau
In alsa,
when independent HP is on,
The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1
you can use aplay -Dhw:0,0,1 stereo.wav
Tested: it works. I can get different streams out of rear (front
playback) and front (hp) line out jacks (used mplayer on the 'default'
rear channel(s) and aplay as above on the front panel)
so you can check whether 0xb can be used instead of 0xc for headphone
static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       hda_nid_t nid = kcontrol->private_value;
       unsigned int pinsel = ucontrol->value.enumerated.item[0];
       /* Get Independent Mode index of headphone pin widget */
       spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
               ? 1 : 0;
       if (spec->codec_type == VT1718S)
               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+                                   AC_VERB_SET_CONNECT_SEL, pinsel ?
+                                   spec->hp_independent_mode_index : 0);
This is to select entry at index #1 (which should be 0x0b) in the
connection list of node 0x34 (the Audio Selector driving node 0x28)
when Independent HP is selected, right?
Refer to commit cdc1784d49258198df600fbc1d37c07d7eee5ed6

and ce0e5a9e81fbb153ee15ca60246c6722f07fc546

it look like spec->hp_independent_mode_index is used to select the
path for HP pin to [Audio Output]

(e..g. vt1702 is using spec->hp_independent_mode_index = 0


Node 0x10 [Audio Output] wcaps 0x41d: Stereo Amp-Out
Control: name="Front Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Device: name="VT1702 Analog", type="Audio", device=0
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0

Node 0x17 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Control: name="Independent HP", index=0, device=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0000001c: OUT HP Detect
Pin Default 0x0221401f: [Jack] HP Out at Ext Front
Conn = 1/8, Color = Green
DefAssociation = 0x1, Sequence = 0xf
Pin-ctls: 0xc0: OUT HP
Unsolicited: tag=05, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 2
0x1d 0x1a*

Node 0x1a [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Master Front Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Control: name="Master Front Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Control: name="Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Control: name="Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x09 0x09] [0x00 0x00] [0x00 0x00] [0x00 0x00]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 4
0x10 0x14 0x15 0x18

Node 0x1d [Audio Output] wcaps 0x41d: Stereo Amp-Out
Control: name="Headphone Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x2a, nsteps=0x2a, stepsize=0x05, mute=0
Amp-Out vals: [0x2a 0x2a]
Converter: stream=0, channel=0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
[...cut...]
static const struct hda_verb vt1718S_volume_init_verbs[] = {
-       {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
+       {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
       {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
What's the param field's meaning here? Is it the index of a connection
list to be selected? In this case, entry #0 for 0x34 should be 0x08,
is it to start with Independent HP turned off?
For the rest of your code (6/8 channels mode selection and retasking
part), shall I apply that altogether with the 0x0b selection part, or
should I rather test if 0x0b is usable for headphone in place of 0x0c
first?
The 6/8 channel mode switch is based on vt2020 is a 10 channel codec
so you have to check whether [Audio Output] 0x0b can be used
alex dot baldacchino dot alsasub at gmail dot com
2011-06-08 14:33:18 UTC
Permalink
Post by Raymond Yau
2011/6/2 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Must these controls be always coupled? Is it a specification
constraint? What if via_hp_build() didn't execute
knew = via_clone_control(spec, &via_hp_mixer[1]);
when side_mute_status() returned '0' ?
static const struct snd_kcontrol_new via_hp_mixer[2] = {
       {
               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
               .name = "Independent HP",
               .info = via_independent_hp_info,
               .get = via_independent_hp_get,
               .put = via_independent_hp_put,
       },
       {
               .iface = NID_MAPPING,
               .name = "Independent HP",
       },
};
Must there be always two "Independent HP" controls in all via codecs,
or there could be just one? In the latter case via_hp_mixer[1] could
be ignored in some cases.
Refer to commit 3d83e577a8206f0f3822a3840e12f76477142ba2
There are codec which does not support indepedent HP
http://thread.gmane.org/gmane.linux.alsa.devel/68414
NID_MAPPING seem used for debugging only
The error "hda-codec: no NID for mapping control Independent HP:0:0"
can be fixed by checking  the value returned by side_mute_channel()
       knew = via_clone_control(spec, &via_hp_mixer[0]);
       if (knew == NULL)
               return -ENOMEM;
       knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
       knew->private_value = nid;
+
+     if (side_mute_channel(spec) == 0)
+              return 0;
       knew = via_clone_control(spec, &via_hp_mixer[1]);
       if (knew == NULL)
               return -ENOMEM;
       knew->subdevice = side_mute_channel(spec);
That's something I was thinking about, but wasn't sure if it was
possible (and safe) to ignore via_hp_mixer[1]. Now I'll apply this.
(Perhaps, by adding a further hda_nid_t variable one could avoid
calling side_mute_channel twice:
at the beginning:

- hda_nid_t nid;
+ hda_nid_t nid, side_nid;

then:

+ if( ( side_nid = side_mute_channel(spec) ) == 0 )
+ return 0;

       knew = via_clone_control(spec, &via_hp_mixer[1]);
       if (knew == NULL)
               return -ENOMEM;
-      knew->subdevice = side_mute_channel(spec);
+     knew->subdevice = side_nid;

though not that much important).
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
The last part is interesting. If vt2020 works the same way, the
8-channel setup should disallow the "Independent HP" function, that is
it should be automatically turned off and 0x28 should be either muted,
or used as a 'duplicate' for 0x0c (same sound of blue jack) or 0x08
(same sound as rear green jack, as in 'redirected audio' ). If I'm not
misunderstanding everything, of course.
static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
       .substreams = 2,
       .channels_min = 2,
       .channels_max = 10,
       .nid = 0x8, /* NID to query formats and rates */
This look like vt1718s support 10 channels and 10 channels allow
independent HP and surround71 at the same time
If this part of the driver is correct, you're definitely right. That
also means admin's answer at
http://www.viaarena.com/forums/showthread.php?t=41015
is mistaken when he says
"Please note that the “Independent Headphone” function requires two
channels. Therefore, only six
channels will be available if “Independent Headphone” is being used."
On the other hand, the picture of via's configuration panel seems to
give him right: in "Independent HP" mode ("Auricular independiente" in
the picture) the two side speakers for surround effects are grayed out
as to mean they're disabled, whereas in 'Redirected Ouptut"
("Auricular redirigido" in the picture) those ones seem to be enabled.
Though, there could be a lack of support for all ten channels in the
motherboard implementation and/or a limitation in that particular
version of via's driver/mixer (if possible at all, I'm just
guessing...)
The codec vt1708s mentioned in the thread is a 8 channel codec
Sorry for my insistence, I had confused codec names... However, 0x0b
doesn't seem to send audio to front panel line-out (I had made a few
tests an was going to post results, more details below).
Post by Raymond Yau
if you look at vt1718S_auto_fill_dac_nids() and
vt1718S_auto_create_hp_ctls() ,
grey jack use 0x0b and headphone use 0x0c
I see, and indeed, in /proc/asound/card0/codec#0, node 0x27 (missing
gray jack) is (would be) connected to 0x0b via 0x1a. Though 0x2a seems
to be connectable only to 0x09 ("Surround Playback Volume" - currently
labeled with an asterisk in 0x2a's connection list) and 0x0c, so
adding support for retasking blue jack as side in codec vt2020/vt1718s
without a grey jack could require some more effort to handle
Independent HP correctly (given 0x0b looks like unusable to 'drive'
0x28)... unless there could be some sort of 'confusion' between 0x2a's
and 0x29's connection lists, given the latter is connected to 0x0b via
0x1c and 0x35 (that is, could respective connection lists be
'inverted' somehow? does it make sense? or is bios-derived autoconfig
the only one usable?).
Post by Raymond Yau
yes, it is still possible that vt1718s without a grey jack is just a 8
channel codec , but those variants of vt1718s which has a grey jack
are most likely a 10 channel codec
That's a chance, unless 0x2a could be connected to 0x0b so that 0x0c
remained available for HP (I guess). Otherwise, 0x0c should be used as
side and front panel hp should be either muted or get input from 0x08
(front, as in redirected output) or 0x0c ('new' side) - again, I'm
guessing.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
In alsa,
when independent HP is on,
The HP jack is supposed to connected to [Audio Output] which is not
used by the rear panel jacks (i.e. 0x25) and application has to use
sudevice 1
you can use aplay -Dhw:0,0,1 stereo.wav
Tested: it works. I can get different streams out of rear (front
playback) and front (hp) line out jacks (used mplayer on the 'default'
rear channel(s) and aplay as above on the front panel)
so you can check whether 0xb can be used instead of 0xc for headphone
static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
{
       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
       struct via_spec *spec = codec->spec;
       hda_nid_t nid = kcontrol->private_value;
       unsigned int pinsel = ucontrol->value.enumerated.item[0];
       /* Get Independent Mode index of headphone pin widget */
       spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
               ? 1 : 0;
       if (spec->codec_type == VT1718S)
               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+                                   AC_VERB_SET_CONNECT_SEL, pinsel ?
+                                   spec->hp_independent_mode_index : 0);
[...cut...]
static const struct hda_verb vt1718S_volume_init_verbs[] = {
-       {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
+       {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
       {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
I've tried this part, along with:

static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
{
int err;

if (!pin)
return 0;
+ if (spec->autocfg.line_outs == 4) {
spec->multiout.hp_nid = 0xc; /* AOW4 */
+ spec->hp_independent_mode_index = 2;
+ }
+ else {
+ spec->multiout.hp_nid = 0xb;
spec->hp_independent_mode_index = 1;
+}


(from your previous message, reposting for clarity and reference)

but got no audio with aplay -Dhw:0,0,1 stereo.wav

On my first attempt, I noticed node 0x0c still got control "Headphone
Playback Volume", thus I modified vt1718S_auto_create_hp_ctls() so
that:


err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
"Headphone Playback Volume",
- HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
+ HDA_COMPOSE_AMP_VAL(spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));


which labeled 0x0b as "Headphone Playback Volume", but still no output
came from there; I've also tried to change

{0x34, AC_VERB_SET_CONNECT_SEL, 0x0}

into

{0x34, AC_VERB_SET_CONNECT_SEL, 0x1}

and

{0x35, AC_VERB_SET_CONNECT_SEL, 0x1}

into

{0x35, AC_VERB_SET_CONNECT_SEL, 0x0} or {0x35, AC_VERB_SET_CONNECT_SEL, 0x2}

in case some weird conflict happened when both 0x34 and 0x35 where
initialized with/switched to the same connection, still to no avail.

I've also applied a piece of code you posted earlier and retried those
combinations, but nothing changed -- code being:


static const struct hda_verb vt1718S_volume_init_verbs[] = {

/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},


(apparently should be unrelated, though trying to access a connection
that doesn't exist for 0x21 shouldn't be very safe/correct, so I've
kept the above).

This other code (from your same message addressing 0x21 access to a
wrong connection):


info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
spec->multiout.dac_nids[0];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams =
+ ( snd_hda_find_mixer_ctl(codec, "Independent HP") ? 2 : 1);

info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);


didn't work at all:

executing 'aplay -Dhw:0,0,1 stereo.wav' failed with error:


aplay: main:660: audio open error: Device or resource busy


executing 'aplay -l' showed the second subdevice for card#0 analog
device hadn't been created:


**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: VT2020 Analog [VT2020 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: SB [HDA ATI SB], device 1: VT2020 Digital [VT2020 Digital]
Subdevices: 2/2
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
card 1: HDMI [HDA ATI HDMI], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0


(this happened with front audio panel _enabled_ in BIOS)

Adding a few printk()'s to file "patch_via.c" showed me function
via_hp_build() is called before via_build_pcms() (unless front panel
is disabled in BIOS, in which case via_hp_build() isn't invoked at
all), therefore, when a control "Independent HP" is created, it should
be 'visible' by via_build_pcms(); however,
snd_hda_find_mixer_ctl(codec, "Independent HP") fails to find it until
the following loop is executed inside via_build_controls:


for (i = 0; i < spec->num_mixers; i++) {
err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
if (err < 0)
return err;
}


and via_build_controls() is called after via_build_pcms(), but then
it's too late (or seemed to be such) to modify the number of playback
substreams. At last, I've tried the following, which worked:

static int via_build_pcms(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;
+ const struct snd_kcontrol_new *knew;
+ int index, found=0;

[ ... ]
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
spec->multiout.dac_nids[0];
+
+ /* is this a multistream-capable environment? let's assume no and
check if yes instead */
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams = 1;
+ for( index = 0; index < spec->num_mixers; index++ ){
+ knew = spec->mixers[ index ];
+ while( knew->name ){
+ if( !strcmp( knew->name, "Independent HP" ) ){
+ /* it looks like there's a front panel */
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams = 2;
+ found = 1;
+ break;
+ }
+ knew++;
+ }
+ if( found )
+ break;
+ }
+
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);


(I'm omitting debug printk() calls and the rest of the function)

But, perhaps, struct via_spec could have a flag initialized to zero
(somewhere, before via_hp_build() and via_build_pcms() are invoked,
perhaps in via_new_spec() ) and set to 1 when via_hp_build() succeeds
cloning via_hp_mixer[0], that is:

knew = via_clone_control(spec, &via_hp_mixer[0]);
if (knew == NULL)
return -ENOMEM;

knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
knew->private_value = nid;
+ spec->front_panel = HDA_HW_WITH_FRONT_PANEL;

( "#define HDA_HW_WITH_FRONT_PANEL 1" and "#define
HDA_HW_WITHOUT_FRONT_PANEL 0" put somewhere in the file)

so that via_build_pcms() could just do something like:


info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams = 1 + spec->front_panel;


but via_hp_build() is called if spec->hp_mux is not null, therefore
one might think (mistakenly, according to me) to do just the
following:


info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams =
( spec->hp_mux ? 2 : 1 );


however, that shouldn't work, because even if spec->hp_mux has been
created, via_hp_build() might not create an "Independent HP" control,
for instance because of a wrong number of connections to the relevant
nid:


if (spec->codec_type != VT1708) {
nums = snd_hda_get_connections(codec, nid,
conn, HDA_MAX_CONNECTIONS);
if (nums <= 1)
return 0;
}


Anyway, I'm posting output of asla-info.sh for the above code I've
tested with front audio panel disabled in BIOS (the loop inside
via_build_pcms, I mean, for now I've preferred not to touch struct
via_spec)


http://pastebin.ca/2076750


By the way, should something like the above be done for capture
streams as well? I've noticed (with front panel disabled) that
controls "Front Mic Playback Volume" and "Front Mic Playback Switch"
are correctly missing from audio-mixer widget 0x21, but node 0x29 is
still 'attached' to control "Front Mic Boost Capture Volume", which is
accessible through a mixer (though I didn't try to play with it; it is
listed also by amixer output in above linked document). Is this the
wanted/expected behaviour? (I understand there must be, anyway, two
captures and two input sources, because there's still one line-in plus
one (rear) mic, plus stereo-mix to deal with, and one "boost capture
volume" control for the rear mic does make sense, my doubt is about
its corresponding control for the now missing front mic).

If there are any other tests you wish me to do (such as sending raw
verbs to the hw and posting results), just let me know.
alex dot baldacchino dot alsasub at gmail dot com
2011-06-09 16:08:24 UTC
Permalink
2011/6/8 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
2011/6/2 alex dot baldacchino dot alsasub at gmail dot com
if you look at vt1718S_auto_fill_dac_nids() and
vt1718S_auto_create_hp_ctls() ,
grey jack use 0x0b and headphone use 0x0c
I see, and indeed, in /proc/asound/card0/codec#0, node 0x27 (missing
gray jack) is (would be) connected to 0x0b via 0x1a. Though 0x2a seems
to be connectable only to 0x09 ("Surround Playback Volume" - currently
labeled with an asterisk in 0x2a's connection list) and 0x0c, so
adding support for retasking blue jack as side in codec vt2020/vt1718s
without a grey jack could require some more effort to handle
Independent HP correctly (given 0x0b looks like unusable to 'drive'
0x28)... unless there could be some sort of 'confusion' between 0x2a's
and 0x29's connection lists, given the latter is connected to 0x0b via
0x1c and 0x35 (that is, could respective connection lists be
'inverted' somehow? does it make sense? or is bios-derived autoconfig
the only one usable?).
Post by Raymond Yau
yes, it is still possible that vt1718s without a grey jack is just a 8
channel codec , but those variants of vt1718s which has a grey jack
are most likely a 10 channel codec
That's a chance, unless 0x2a could be connected to 0x0b so that 0x0c
remained available for HP (I guess). Otherwise, 0x0c should be used as
side and front panel hp should be either muted or get input from 0x08
(front, as in redirected output) or 0x0c ('new' side) - again, I'm
guessing.
Another weird (or even weirder) idea: could there be some sort of
'internal switch' (hidden/non-accessible) allowing 0x0b to be used for
HP only when 0x0c is connected to 0x2a and 0x2a is retasked as output?
I'd wish to check it by the mean of the code you had proposed for
line-in/side retasking, with some changes to it (and the rest), but
I'd need some help to complete the code; if it didn't work, I think
that could be a base to turn off Independent HP in 7.1 mode.

The logic should be as follows:

- In function vt1718S_auto_create_hp_ctls(), let's attach a 'fake'
control "Headphone Playback Volume #2" to widget 0x0b:

......
+ if (spec->autocfg.line_outs == 3){
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Headphone Playback Volume #2",
+ HDA_COMPOSE_AMP_VAL(0xb, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }


- In function via_independent_hp_put() let's use pinsel,
spec->hp_independent_mode_index and spec->ext_channel_count (or
spec->multiout.max_channels ?) to choose whether to select 0x0c
(connection #2) and activate control "Headphone Playback Volume" or to
select 0x0b (conn #1) and activate control "Headphone Playback Volume
#2":


struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
hda_nid_t nid = kcontrol->private_value;
unsigned int pinsel = ucontrol->value.enumerated.item[0];
+ unsigned int ch6_mode = 1;
+ char * vol_ctl_name = "Headphone Playback Volume";
/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0;
- if (spec->codec_type == VT1718S)
+ if (spec->codec_type == VT1718S){
+ if( spec->ext_channel_count == 8 ){
+ /* or should it be if(spec->multiout.max_channels == 8) ? */
+ ch6_mode = 0;
+ vol_ctl_name = "Headphone Playback Volume #2"
+ }
snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+ AC_VERB_SET_CONNECT_SEL, pinsel ?
+ ( spec->hp_independent_mode_index + ch6_mode ) : 0);
+ }
else
.........
- activate_ctl(codec, "Headphone Playback Volume",
+ activate_ctl(codec, vol_ctl_name,
spec->hp_independent_mode);
activate_ctl(codec, "Headphone Playback Switch",
spec->hp_independent_mode);


- In new function via_ch_mode_put(), after calling
snd_hda_ch_mode_put(), let's do the following:

1. If going to retask 0x2a as side ( spec->ext_channel_count == 8 or
spec->multiout.max_channels == 8 ?)

1.1 If "Independent HP" is on (spec->hp_independent_mode == 1)
1.1.2 mute headphones (with activate_ctl() on corresponding volume
and switch controls, or with snd_hda_codec_write()? or both?)

1.2 Set spec->multiout.hp_nid to 0x0b

1.3 Activate Side Playback Volume and Switch controls

1.4 If "Independent HP" was on
1.4.1 re-enable it ( select connection 1 (0x0b) for nid 0x34, call
snd_hda_codec_setup_stream() if needed, call activate_ctl properly)

2. Else (if going from 8 to 6 channels)
2.1 behave as above, but using 0x0c for HP and disabling Sid controls

(1 and 2 can be 'collapsed' by the mean of a few variables to be set
after first check)

The above assumes that (somewhere) the driver 'synchronizes' accesses
to mixer widgets so that no more than one ".put method" can be called
at a time (to handle side effects on other widgets correctly),
otherwise, if via_independent_hp_put() and via_ch_mode_put() were
called at the same time, some race condition/undefined behaviour could
show up.

Anyway, does it make sense? (eventually changed so that Independent HP
is always turned off when 0x2a is retasked as Side).


BTW, there's something I don't understand in your code for via_ch_mode_put()


static int via_ch_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct via_spec *spec = codec->spec;
int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
spec->num_channel_mode,
&spec->ext_channel_count);

/****** WHY THE FOLLOWING? ******/
if (err >= 0 && !spec->const_channel_count) {
spec->multiout.max_channels = spec->ext_channel_count;
}/****** uppercase in comment just to catch attention ******/

activate_ctl(spec->codec, "Side Playback Volume",
spec->multiout.max_channels == 8);
activate_ctl(spec->codec, "Side Playback Switch",
spec->multiout.max_channels == 8);
return err;
}


AFAICT, spec->const_channel_count is initialized to 6 in
vt1718S_auto_create_multi_out_ctls() if spec->autocfg.line_outs == 3,
in which case

spec->mixers[spec->num_mixers] = vt1718S_chmode_mixer;

is executed and vt1718S_chmode_mixer will be 'registered' by
via_build_controls(); otherwise, spec->const_channel_count is 0 (as
via_new_spec() allocates a block of memory initialized to zero by
kzalloc()) but the mixer isn't registered and thus via_ch_mode_put()
should never be called; I can't find another place where
spec->const_channel_mode is modified. Perhaps, should that be:

if (err >= 0) {
spec->multiout.max_channels = spec->ext_channel_count;
} else {
return err; /* to avoid messing with the rest, specially
if touching HP */
}

or am I missing something?
alex dot baldacchino dot alsasub at gmail dot com
2011-06-11 20:24:32 UTC
Permalink
IMPORTANT UPDATE!!!!!

Node 0x0b can drive HP! The problem was function
set_widgets_power_state_vt1718S() not updating power state for the
correct nid, solved as follows:


static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
{
...
if (spec->hp_independent_mode) {
- /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
+ /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) of AOW3 (bh) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x28, &parm);
snd_hda_codec_write(codec, 0x1b, 0,
AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0x34, 0,
AC_VERB_SET_POWER_STATE, parm);
- snd_hda_codec_write(codec, 0xc, 0,
+ snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
AC_VERB_SET_POWER_STATE, parm);
}


Anyway, there's another problem with hp_independent_mode_index when
there are four line-outs:

as suggested in a previous mail (with additional comment where
problems arise), in vt1718S_auto_create_hp_ctls()


if (spec->autocfg.line_outs == 4) {
spec->multiout.hp_nid = 0xc; /* AOW4 */
spec->hp_independent_mode_index = 2; /* <- TROUBLES! */
}else{
spec->multiout.hp_nid = 0xb;
spec->hp_independent_mode_index = 1;
}


but in via_independent_hp_put():


unsigned int pinsel = ucontrol->value.enumerated.item[0];
/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0; /* <- TROUBLES! */


When turning on Independent HP mode for codec VT1718S, pinsel is 1,
when turning it off that's 0, thus, if spec->hp_independent_mode_index
is 2, spec->hp_independent_mode is always 0 (condition
spec->hp_independent_mode_index == pinsel alwyas fails) and
corresponding controls can't be activated:


/* update HP volume/swtich active state */
if (spec->codec_type == VT1708S
|| spec->codec_type == VT1702
|| spec->codec_type == VT1718S
|| spec->codec_type == VT1716S
|| VT2002P_COMPATIBLE(spec)) {
activate_ctl(codec, "Headphone Playback Volume",
spec->hp_independent_mode);
activate_ctl(codec, "Headphone Playback Switch",
spec->hp_independent_mode);
}


I can confirm this in my system (3 line_outs) - I've used a printk()
to log the value of pinsel - but I guess that's the same with 4
line_outs (that is, codec vt1718s with gray jack), because old code
always set hp_independent_mode_index to 1. I can see two solutions for
this:

1) Use different values for spec->hp_independent_mode_index, in
vt1718S_auto_create_hp_ctls(), basing on available jacks (as in above
code), and change via_independent_hp_put() as follows:


/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0;
- if (spec->codec_type == VT1718S)
+ if (spec->codec_type == VT1718S){
+ /* when turning on Independent HP for VT1718S pinsel is 1 but */
+ /* spec->hp_independent_mod_index can be 1 or 2 */
+ if( ( spec->hp_independent_mode_index == 2 ) && ( pinsel == 1 ) )
+ spec->hp_independent_mode = 1;
snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+ AC_VERB_SET_CONNECT_SEL, pinsel ?
+ spec->hp_independent_mode_index : 0);
+ }
else
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_CONNECT_SEL, pinsel);


(call to snd_hda_codec_write as modified in your previous suggestion)

This choice would be consistent with the idea that
spec->hp_independent_mode_index is the index of the audio selector
widget's connection list to select when turning Independent HP mode
on. If struct via_spec had another field to tell the index of the
front connection, let's call it hp_redirected_mode_index, the else
statement above could be avoided and the code could become:


/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0;
if (spec->codec_type == VT1718S)
/* when turning on Independent HP for VT1718S pinsel is 1 but */
/* spec->hp_independent_mod_index can be 1 or 2 */
if( ( spec->hp_independent_mode_index == 2 ) && ( pinsel == 1 ) )
spec->hp_independent_mode = 1;

snd_hda_codec_write( codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
( spec->hp_independent_mode ?
spec->hp_independent_mode_index :
spec->hp_redirected_mode_index ) );


(I'm not using a diff-alike format here to improve readability)

Of course, that would require each vtxxxx_auto_create_hp_ctls() to be
modified so that (new field) spec->hp_redirected_mode_index were
initialized the right way (e.g. with the index of the "Front Playback
Volume" control nid). Notice that, as a side effect, there would be no
more dependence on pinsel value in call to snd_hda_codec_write, that
could be a safe behavior in case pinsel value were wrong (if possible
at all, e.g. because of a bug in a mixer application), in which case
the worst possible effect would be to turn off Independent HP
unwillingly, but no bad value would be passed to snd_hda_codec_write
(again, this is meaningful only if pinsel, that is
ucontrol->value.enumerated.item[0], may come from a user space
mistaken call to driver's interface). If this is wise, I'd suggest to
consider it.


2) Leave spec->hp_independent_mode_index = 1 in vt1718S_auto_create_hp_ctls():

starting from your suggested code:

if (spec->autocfg.line_outs == 4) {
spec->multiout.hp_nid = 0xc; /* AOW4 */
- spec->hp_independent_mode_index = 2;
}else{
spec->multiout.hp_nid = 0xb;
- spec->hp_independent_mode_index = 1;
}
+ spec->hp_independent_mode_index = 1; /* this was yet here in older code */

(without the comment of course)

and changing via_independent_hp_put() the following way:


/* Get Independent Mode index of headphone pin widget */
spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
? 1 : 0;
if (spec->codec_type == VT1718S)
snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
+ AC_VERB_SET_CONNECT_SEL, pinsel ?
+ ( spec->hp_independent_mode_index +
+ ( spec->multiout.hp_nid == 0xc ) ) : 0);
else
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_CONNECT_SEL, pinsel);


In this case, spec->hp_independent_mode is evaluated only once,
uniformly and consistently for all codecs, though it seems to me
hp_independent_mode_index use is a bit less consistent with its
intended meaning. Anyway, I think both solutions are viable.
(personally, I'd prefer the variant to the former one - less dependent
on pinsel value, but that must make sense to be chosen).

------------------------------------

With respect to your proposed code for retasking blue jack as side, as
far as I understand it, I think it should work, but could require
other changes to set_widgets_power_state_vt1718S(), for instance:


/* PW1 (25h), AOW1 (9h) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x25, &parm);
if (spec->smart51_enabled)
set_pin_power_state(codec, 0x2a, &parm);
snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
+
+ /* PW6 (2ah), AOW4 (ch) */
+ /* avoiding to conflict with Independent HP when its AOW is 4 (ch)*/
+ if( spec->autocfg.line_outs == 3 ){
+ parm = AC_PWRST_D3;
+ /* if a 7.1 system is connected, let's change the */
+ /* state of 0x0c into D0 else change it into D3 */
+ if( spec->ext_channel_count == 8 ){
+ set_pin_power_state( codec, 0x2a, &parm );
+ snd_hda_codec_write( codec, 0xc, 0, AC_VERB_SET_POWER_STATE, parm);
+ }

if (spec->hp_independent_mode) {
....

(or perhaps should it be "if( spec->multiout.max_channels == 8 )" to
be checked?)

Maybe also:


/* outputs */
/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x27, &parm);
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
- snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
+ /* avoiding to interfere with Independent HP when PW3 misses*/
+ if( spec->autocfg.line_outs == 4 )
+ snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);


So that, when Independent HP mode is on and there are only 3 line-outs
(missing grey jack, HP connected to 0x0b), and the function is not
called because of a change in Independent HP state, sound is not
turned off and on in sequence (given 0x0b would pass from state D0 to
D3 because of 0x27 missing, then again to D0 because of Independent HP
mode being active) - though such a change could be enough fast not to
be noticeable (whether noticeable or not might vary based on
scenarios).

Perahps, also:


/* inputs */
/* PW 5/6/7 (29h/2ah/2bh) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x29, &parm);
- set_pin_power_state(codec, 0x2a, &parm);
+ /* ensuring PW6 (2ah) is still an input widget before treating it as such */
+ if( ( spec->autocfg.line_outs == 4 || spec->ext_channel_count != 8)
+ && !spec->smart51_enabled )
+ set_pin_power_state(codec, 0x2a, &parm);
- set_pin_power_state(codec, 0x2b, &parm);
+ /* ensuring PW7 (2bh) is still an input widget before treating it as such */
+ if( !spec->smart51_enabled )
+ set_pin_power_state(codec, 0x2b, &parm);
if (imux_is_smixer)
parm = AC_PWRST_D0;
/* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);


(or perhaps should it be " spec->multiout.max_channels != 8 " to be checked up?)

This is just to avoid repeating actions (e.g. calling
set_pin_power_state twice on 0x2a as input and as retasked output) and
treating jacks retasked as output as if they were still inputs, so
that some widgets can be turned on/off more appropriately (e.g. 0x2a
is the only one setting parm to D0 value but is retasked as output,
and imux_is_smixer is false). (this part could be improved further, I
guess, taking care of what is actually connected to 0x1e and 0x1f)

But perhaps smart51 checks should be removed from this codec's power
state settings (since it's got more than 2 line-outs anyway).

Moreover:


/* PW0 (24h), AOW0 (8h) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x24, &parm);
- if (!spec->hp_independent_mode) /* check for redirected HP */
+ if ( !spec->hp_independent_mode ){ /* check for redirected HP */
+ /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) of AOW3 (bh) */
+ /* turning on/off widgets connected to PW4 appropriately*/
+ unsigned int parm2 = AC_PWRST_D3;
set_pin_power_state(codec, 0x28, &parm2);
+ snd_hda_codec_write( codec, 0x1b, 0,
+ AC_VERB_SET_POWER_STATE, parm2);
+ snd_hda_codec_write( codec, 0x34, 0,
+ AC_VERB_SET_POWER_STATE, parm2);
+ /* turning off hp_nid since unused in redirected output */
+ snd_hda_codec_write( codec, spec->multiout.hp_nid, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+ /* if PW4 (28h) is in D0 then AOW0 (8h) must be set to D0 */
+ if( parm2 == AC_PWRST_D0 )
+ parm = parm2;
+ }
snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);


However, I have _not_ tested changes to power state settings (but for
enabling 0xb to send output to HP - first part of this mail), so I'm
asking if the above make sense at all. If it does, specially for what
concern blue jack retasking, perhaps also:

static int via_ch_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
...
+ /* update jack power state */
+ set_widgets_power_state(codec);
return err;
}


Same as done, before returning, in both via_independent_hp_put() and
via_smart51_put() - unless its done implicitly (e.g. when calling
snd_hda_ch_mode_put() - it doesn't seems to me that function can
change power states, but I may be misunderstanding its operations).

--------------------------------------------------

Lastly, I don't understand the following:


static const struct hda_verb vt1718S_volume_init_verbs[] = {
...
/* Setup default input of Front HP to MW9 */
{0x28, AC_VERB_SET_CONNECT_SEL, 0x1},


In my system, 0x28 has just one connection, thus there's no connection
at index 1 (and no more than 6 "Audio Mixer" widgets. Or... what am I
misunderstanding there?


Node 0x28 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x0221401f: [Jack] HP Out at Ext Front
Conn = 1/8, Color = Green
DefAssociation = 0x1, Sequence = 0xf
Pin-ctls: 0xc0: OUT HP VREF_HIZ
Unsolicited: tag=21, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 1
0x1b
Raymond Yau
2011-06-19 01:46:43 UTC
Permalink
2011/6/12 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
IMPORTANT UPDATE!!!!!
Node 0x0b can drive HP! The problem was function
set_widgets_power_state_vt1718S() not updating power state for the
static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
{
...
       if (spec->hp_independent_mode) {
-               /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
+               /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) of AOW3 (bh) */
               parm = AC_PWRST_D3;
               set_pin_power_state(codec, 0x28, &parm);
               snd_hda_codec_write(codec, 0x1b, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
               snd_hda_codec_write(codec, 0x34, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0xc, 0,
+               snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
       }
Can your hear the same signal from black and orange jack when you
playing stereo to hw:0,0,0 ?

if you look at snd_hda_multi_out_analog_prepare() in hda_codec.c,

if mout->no_share_stream=0 ,it seem that there is "upmix" feature when
mout->num_dacs is 4 for those 5 jacks/6 jacks motherboard

i.e. the black and orange jacks can have the same signal as the green jack

/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
0, format);
if (!mout->no_share_stream &&
mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
/* headphone out will just decode front left/right (stereo) */
snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
0, format);
/* extra outputs copied from front */
for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
if (!mout->no_share_stream && mout->extra_out_nid[i])
snd_hda_codec_setup_stream(codec,
mout->extra_out_nid[i],
stream_tag, 0, format);

/* surrounds */
for (i = 1; i < mout->num_dacs; i++) {
if (chs >= (i + 1) * 2) /* independent out */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
i * 2, format);
else if (!mout->no_share_stream) /* copy front */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
0, format);
}
return 0;
}
Post by alex dot baldacchino dot alsasub at gmail dot com
       unsigned int pinsel = ucontrol->value.enumerated.item[0];
       /* Get Independent Mode index of headphone pin widget */
       spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
               ? 1 : 0; /* <- TROUBLES! */
When turning on Independent HP mode for codec VT1718S, pinsel is 1,
when turning it off that's 0, thus, if spec->hp_independent_mode_index
is 2, spec->hp_independent_mode is always 0 (condition
spec->hp_independent_mode_index == pinsel alwyas fails) and
       /* update HP volume/swtich active state */
       if (spec->codec_type == VT1708S
           || spec->codec_type == VT1702
           || spec->codec_type == VT1718S
           || spec->codec_type == VT1716S
           || VT2002P_COMPATIBLE(spec)) {
               activate_ctl(codec, "Headphone Playback Volume",
                            spec->hp_independent_mode);
               activate_ctl(codec, "Headphone Playback Switch",
                            spec->hp_independent_mode);
       }
if the hp jack can also use "copy front" mode for "redirected headphone"

the driver don't need to disable "Headphone Playback Volume" for those
10 channels codecs or change the connection in
via_independent_hp_put()

For those 3 jacks motherobard, "channel mode" 6-8 or "Use HP as Side"
switch may just need tot switch the connection to use 0x0b or 0x0c if
0b has "Side Playback Volume" and 0x0c has "Headphone Playback
Volume"
alex dot baldacchino dot alsasub at gmail dot com
2011-06-20 01:19:49 UTC
Permalink
Post by Raymond Yau
2011/6/12 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
IMPORTANT UPDATE!!!!!
Node 0x0b can drive HP! The problem was function
set_widgets_power_state_vt1718S() not updating power state for the
static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
{
...
       if (spec->hp_independent_mode) {
-               /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
+               /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) of AOW3 (bh) */
               parm = AC_PWRST_D3;
               set_pin_power_state(codec, 0x28, &parm);
               snd_hda_codec_write(codec, 0x1b, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
               snd_hda_codec_write(codec, 0x34, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
-               snd_hda_codec_write(codec, 0xc, 0,
+               snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
                                   AC_VERB_SET_POWER_STATE, parm);
       }
Can your hear the same signal from black and orange jack when you
playing stereo to hw:0,0,0 ?
if you look at snd_hda_multi_out_analog_prepare() in hda_codec.c,
if mout->no_share_stream=0 ,it seem that there is "upmix" feature when
mout->num_dacs is 4 for those 5 jacks/6 jacks motherboard
i.e. the black and orange jacks can have the same signal as the green jack
       /* front */
       snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
                                  0, format);
       if (!mout->no_share_stream &&
           mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
               /* headphone out will just decode front left/right (stereo) */
               snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
                                          0, format);
       /* extra outputs copied from front */
       for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
               if (!mout->no_share_stream && mout->extra_out_nid[i])
                       snd_hda_codec_setup_stream(codec,
                                                  mout->extra_out_nid[i],
                                                  stream_tag, 0, format);
       /* surrounds */
       for (i = 1; i < mout->num_dacs; i++) {
               if (chs >= (i + 1) * 2) /* independent out */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  i * 2, format);
               else if (!mout->no_share_stream) /* copy front */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  0, format);
       }
       return 0;
}
I fear I cannot test it the best way (I've got a 5.1 system, but have
some 'logistic' problems using it). I've made an attempt by using two
headphones, connected as follows:

1) one to (rear) green jack, one to orange,
2) one to green, one to black,
3) one to orange, one to black,

and played a short two-channels file with aplay -Dhw:0,0,0 stereo.wav
a few times, in each case I was able to here (same) sound from both
headsets.

However, it would seem to me that snd_hda_multi_out_analog_prepare()
is not used by VIA Codecs, instead, some pcm operations are defined
within patch_via.c and used by each codec, e.g.


static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 10,
.nid = 0x8, /* NID to query formats and rates */
.ops = {
.open = via_playback_pcm_open,
.prepare = via_playback_multi_pcm_prepare,
.cleanup = via_playback_multi_pcm_cleanup,
.close = via_pcm_open_close,
},
};


(not all codec use via_pcm_open_close, actually)

None of them calls snd_hda_multi_out_analog_{prepare, cleanup}() for
analog stuff, instead, part of the code in those (general) functions
is reused and modified, and spec->multiout.no_share_stream isn't used,
nor initialized (AFAICT).

By the way, my modification to set_widgets_power_state_vt1718S you've
quoted is due to 0x0b being set to D3 because side is missing:


/* outputs */
/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x27, &parm);
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);


Since 0x27 is not present, parm is not changed in
set_pin_power_state() and 0x0b is 'turned off'. Therefore, if 0x0b
must/can be used for independent hp, power state cannot be changed for
a fixed nid, but current value for spec->multiout.hp_nid have to be
used.


By the way, since via_playback_pcm_open() calls
snd_hda_multi_out_analog_open(), which is the last one touching
runtime->hw.channels_max, the problem you pointed out in your previous
mail to report the right number of max channels for a substream,
perhaps, could be solved the following way:

in file hda_codec.c:


/**
-* snd_hda_multi_out_analog_open - open analog outputs
+* snd_hda_multiout_analog_open_set - open analog outputs
*
* Open analog outputs and set up the hw-constraints.
* If the digital outputs can be opened as slave, open the digital
* outputs, too.
*/
-int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+int snd_hda_multiout_analog_open_set(struct hda_codec *codec,
struct hda_multi_out *mout,
struct snd_pcm_substream *substream,
- struct hda_pcm_stream *hinfo)
+ struct hda_pcm_stream *hinfo, int max_channels)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->hw.channels_max = mout->max_channels;
+ if( max_channels > 0 && max_channels <= mout->max_channels)
+ runtime->hw.channels_max = max_channels;
+ else
+ runtime->hw.channels_max = mout->max_channels;
if (mout->dig_out_nid) {
....

-EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
+EXPORT_SYMBOL_HDA(snd_hda_multiout_analog_open_set);


+/**
+ * snd_hda_multi_out_analog_open - open analog outputs
+ *
+ * Open analog outputs and set up the hw-constraints.
+ * If the digital outputs can be opened as slave, open the digital
+ * outputs, too.
+ */
+int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+ struct hda_multi_out *mout,
+ struct snd_pcm_substream *substream,
+ struct hda_pcm_stream *hinfo)
+{
+ snd_hda_multiout_analog_open_set( codec, mout, substream, hinfo, 0 );
+}
+EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);


(to avoid breaking compatibility)

in file patch_via.c:


static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct via_spec *spec = codec->spec;
int idle = substream->pstr->substream_opened == 1
&& substream->ref_count == 0;
analog_low_current_mode(codec, idle);
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
+ return snd_hda_multiout_analog_open_set( codec, &spec->multiout, substream,
+ hinfo, ( substream->number == 1 ? 2
+ : spec->multiout.max_channels ) );
}


(substream->number is the same as subdevice, because their matching is
tested in snd_pcm_attach_substream())

However, since the question is more general, and could affect other
hda (and non-hda) codecs/drivers, a careful discussion on the general
design could be needed.
Post by Raymond Yau
Post by alex dot baldacchino dot alsasub at gmail dot com
       unsigned int pinsel = ucontrol->value.enumerated.item[0];
       /* Get Independent Mode index of headphone pin widget */
       spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
               ? 1 : 0; /* <- TROUBLES! */
When turning on Independent HP mode for codec VT1718S, pinsel is 1,
when turning it off that's 0, thus, if spec->hp_independent_mode_index
is 2, spec->hp_independent_mode is always 0 (condition
spec->hp_independent_mode_index == pinsel alwyas fails) and
       /* update HP volume/swtich active state */
       if (spec->codec_type == VT1708S
           || spec->codec_type == VT1702
           || spec->codec_type == VT1718S
           || spec->codec_type == VT1716S
           || VT2002P_COMPATIBLE(spec)) {
               activate_ctl(codec, "Headphone Playback Volume",
                            spec->hp_independent_mode);
               activate_ctl(codec, "Headphone Playback Switch",
                            spec->hp_independent_mode);
       }
if the hp jack can also use "copy front" mode for "redirected headphone"
the driver don't need to disable "Headphone Playback Volume" for those
10 channels codecs or change the connection in
via_independent_hp_put()
But if hp_independent_mode is always 0 because pinsel can never match
hp_independent_mode_index, those controls will _never_ be activated,
at least not by via_independent_hp_put, and, what's worse (as I
think), once via_independent_hp_put is called they'll become inactive,
even if setting the right connection for the "independent mode":


static void activate_ctl(struct hda_codec *codec, const char *name, int active)
{
struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
if (ctl) {
ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
ctl->vd[0].access |= active
? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(codec->bus->card,
SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
}
}


(active, as passed in by via_independent_hp_put is
spec->hp_independent_mode, which is always set to 0 if
spec->hp_independent_mode_index is 2, therefore the need to set
hp_independent_mode more properly)

Moreover, hp_independent_mode is used by other functions, such as
set_widgets_power_state_vtXXXX(), via_playback_multi_pcm_prepare(),
playback_multi_pcm_prep_0(), via_playback_multi_pcm_cleanup(),
therefore I think that's safer to set it properly, to avoid the risk
of breaking those algorithms counting on its value.
Post by Raymond Yau
For those 3 jacks motherobard, "channel mode" 6-8 or "Use HP as Side"
switch may just need tot switch the connection to use 0x0b or 0x0c if
0b has  "Side Playback Volume" and 0x0c has "Headphone Playback
Volume"
By the way, if there are 3 line-outs only, I'm selecting 0x0b as
multiout.hp_nid (as suggested by you), and also attaching control
"Headphone Playback Volume" to it:


static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
{
...
err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
"Headphone Playback Volume",
HDA_COMPOSE_AMP_VAL(spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
Post by Raymond Yau
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Raymond Yau
2011-06-20 07:13:02 UTC
Permalink
2011/6/20 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Post by Raymond Yau
Can your hear the same signal from black and orange jack when you
playing stereo to hw:0,0,0 ?
if you look at snd_hda_multi_out_analog_prepare() in hda_codec.c,
if mout->no_share_stream=0 ,it seem that there is "upmix" feature when
mout->num_dacs is 4 for those 5 jacks/6 jacks motherboard
i.e. the black and orange jacks can have the same signal as the green jack
       /* front */
       snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
                                  0, format);
       if (!mout->no_share_stream &&
           mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
               /* headphone out will just decode front left/right (stereo) */
               snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
                                          0, format);
       /* extra outputs copied from front */
       for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
               if (!mout->no_share_stream && mout->extra_out_nid[i])
                       snd_hda_codec_setup_stream(codec,
                                                  mout->extra_out_nid[i],
                                                  stream_tag, 0, format);
       /* surrounds */
       for (i = 1; i < mout->num_dacs; i++) {
               if (chs >= (i + 1) * 2) /* independent out */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  i * 2, format);
               else if (!mout->no_share_stream) /* copy front */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  0, format);
       }
       return 0;
}
I fear I cannot test it the best way (I've got a 5.1 system, but have
some 'logistic' problems using it). I've made an attempt by using two
1) one to (rear) green jack, one to orange,
2) one to green, one to black,
3) one to orange, one to black,
and played a short two-channels file with aplay -Dhw:0,0,0 stereo.wav
a few times, in each case I was able to here (same) sound from both
headsets.
However, it would seem to me that snd_hda_multi_out_analog_prepare()
is not used by VIA Codecs, instead, some pcm operations are defined
within patch_via.c and used by each codec, e.g.
Take a look at playback_multi_pcm_prep_0() in patch_via.c , it seem
this "copy front" mode is enabled by default in via codecs


/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
0, format);

if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
&& !spec->hp_independent_mode)
/* headphone out will just decode front left/right (stereo) */
snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
0, format);

/* extra outputs copied from front */
for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
if (mout->extra_out_nid[i])
snd_hda_codec_setup_stream(codec,
mout->extra_out_nid[i],
stream_tag, 0, format);

/* surrounds */
for (i = 1; i < mout->num_dacs; i++) {
if (chs >= (i + 1) * 2) /* independent out */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
i * 2, format);
else /* copy front */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
0, format);
}
alex dot baldacchino dot alsasub at gmail dot com
2011-06-20 13:48:24 UTC
Permalink
Post by Raymond Yau
2011/6/20 alex dot baldacchino dot alsasub at gmail dot com
Take a look at playback_multi_pcm_prep_0() in patch_via.c , it seem
this "copy front" mode is enabled by default in via codecs
       /* front */
       snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
                                  0, format);
       if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
           && !spec->hp_independent_mode)
               /* headphone out will just decode front left/right (stereo) */
               snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
                                          0, format);
       /* extra outputs copied from front */
       for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
               if (mout->extra_out_nid[i])
                       snd_hda_codec_setup_stream(codec,
                                                  mout->extra_out_nid[i],
                                                  stream_tag, 0, format);
       /* surrounds */
       for (i = 1; i < mout->num_dacs; i++) {
               if (chs >= (i + 1) * 2) /* independent out */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  i * 2, format);
               else /* copy front */
                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
                                                  0, format);
       }
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Yes, I had noticed it, but before seeing that line, I went out crazy
thinking mout->extra_out_nid was initialized somewhere in the code (in
the driver) and used in this function... Lastly, I found that place:
Nowhere Land, LOL!

I must be needing some new glasses, LOL.

Raymond Yau
2011-06-14 04:05:06 UTC
Permalink
2011/6/8 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
http://pastebin.ca/2076750
By the way, should something like the above be done for capture
streams as well? I've noticed (with front panel disabled) that
controls "Front Mic Playback Volume" and "Front Mic Playback Switch"
are correctly missing from audio-mixer widget 0x21, but node 0x29 is
still 'attached' to control "Front Mic Boost Capture Volume", which is
accessible through a mixer (though I didn't try to play with it; it is
listed also by amixer output in above linked document). Is this the
wanted/expected behaviour?
It seem that 0x2b and 0x29 does not have any mic boost capture volume,
that look like "Playback Switch" when they are retasked as output for
3 jacks motherboard

Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x02a19037: [Jack] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x7
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1c

Node 0x2b [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x00002334: IN OUT Detect
Vref caps: HIZ 50 100
Pin Default 0x01a19036: [Jack] Mic at Ext Rear
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x6
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 2
0x0a* 0x0c

/* capture mixer elements */
static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
- HDA_INPUT),



(I understand there must be, anyway, two
Post by alex dot baldacchino dot alsasub at gmail dot com
captures and two input sources, because there's still one line-in plus
one (rear) mic, plus stereo-mix to deal with, and one "boost capture
volume" control for the rear mic does make sense, my doubt is about
its corresponding control for the now missing front mic).
The problem is in hda_verb vt1718S_volume_init_verbs

/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},

node 0x21 of your vt2020 has only 5 connections

Refer to commit 4ab2d53a99b6dcee86837d2a9739bfb9f468db45

you will need to ask the author of this patch since the patch
explicitly change this non exisiting connection of node 0x21 on your
vt2020

- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},



Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Front Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Front Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Rear Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Rear Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x1f 0x1f] [0x1f 0x1f] [0x1f 0x1f] [0x97 0x97]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28
Raymond Yau
2011-06-18 08:29:20 UTC
Permalink
2011/6/8 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Adding a few printk()'s to file "patch_via.c" showed me function
via_hp_build() is called before via_build_pcms() (unless front panel
is disabled in BIOS, in which case via_hp_build() isn't invoked at
all), therefore, when a control "Independent HP" is created, it should
be 'visible' by via_build_pcms(); however,
snd_hda_find_mixer_ctl(codec, "Independent HP") fails to find it until
and via_build_controls() is called after via_build_pcms(), but then
it's too late (or seemed to be such) to modify the number of playback
The fix is to check spec->multiout.hp_nid since "Independent HP" need
the extra DAC for HP when there is no HP if front panel is disabled by
BIOS



static int via_build_pcms(struct hda_codec *codec)
{
...

info->name = spec->stream_name_analog;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
*(spec->stream_analog_playback);
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
spec->multiout.dac_nids[0];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams =
+ spec->multiout.hp_nid ? 2 : 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];

info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
spec->multiout.max_channels;


However there is a bug in using subdevice 1 for "Independent HP" and
subdevice 0 for multi-channels

The channel count reported by snd_pcm_hw_params_get_channels_max() or
snd_pcm_hw_params_test_channel() for subdevice 1 is also equal to
spec->multiout.max_channels but this subdevice 1 only support stereo
alex dot baldacchino dot alsasub at gmail dot com
2011-06-19 12:44:16 UTC
Permalink
Post by alex dot baldacchino dot alsasub at gmail dot com
2011/6/8 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
Adding a few printk()'s to file "patch_via.c" showed me function
via_hp_build() is called before via_build_pcms() (unless front panel
is disabled in BIOS, in which case via_hp_build() isn't invoked at
all), therefore, when a control "Independent HP" is created, it should
be 'visible' by via_build_pcms(); however,
snd_hda_find_mixer_ctl(codec, "Independent HP") fails to find it until
and via_build_controls() is called after via_build_pcms(), but then
it's too late (or seemed to be such) to modify the number of playback
The fix is to check spec->multiout.hp_nid  since "Independent HP" need
the extra DAC for HP when there is no HP if front panel is disabled by
BIOS
static int via_build_pcms(struct hda_codec *codec)
{
...
       info->name = spec->stream_name_analog;
       info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
               *(spec->stream_analog_playback);
       info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
               spec->multiout.dac_nids[0];
+     info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams =
+             spec->multiout.hp_nid ? 2 : 1;
       info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
       info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
       info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
               spec->multiout.max_channels;
It might work, but might also fail, I guess. Even if everything else
went ok during initialization, and multiout.hp_nid were set in
vtxxxx_auto_create_hp_ctls(), via_hp_build() could fail to create an
Independent HP control, because of either a failure allocating memory
for it, when calling via_clone_control():


knew = via_clone_control(spec, &via_hp_mixer[0]);
if (knew == NULL)
return -ENOMEM;

or because the nid corresponding to the Independent HP control hasn't
got enough connections:


if (spec->codec_type != VT1708) {
nums = snd_hda_get_connections(codec, nid,
conn, HDA_MAX_CONNECTIONS);
if (nums <= 1)
return 0;
}


As I understand it, without a control "Independent HP" with its proper
.get and .put methods, that's not possible to switch between single-
and multi-streaming, thus the problem is here, I think.

But perhaps, if there are not enough connections to switch from/to, it
might happen that autocfg.hp_pins[0] is 0, so that:


static int vtXXXX_parse_auto_config(struct hda_codec *codec)
{
...

err = vtXXX_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
...


triggered:


static int vtXXX_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
{
...

if (!pin)
return 0;
...


before spec->multiout.hp_nid is set, but it may also not happen,
because, regardless of support for multi-streaming, there can be
support for a front panel line-out in redirected output (refer to
commit 3d83e577a8206f0f3822a3840e12f76477142ba2 and
ee3c35c0827de02de414d08b2ddcbb910c2263ab, if there is need to solve
that problem in via_hp_build(), it should mean that
spec->multiout.hp_nid is not null in such scenarios).

However, that wouldn't solve the memory failure risk, or the risk
via_hp_build is not called at all because spec->hp_mux wasn't created
(though, this latter risk is fixable by moving assignment to
spec->multiout.hp_nid at the end of vtXXX_auto_create_hp_ctls, and
using local variables before), and anyway, in doubt, I think a safe
choice is to add a proper field, I've called
independent_front_panel_out, to struct via_spec, initialize it to 0
and set it to 1 in via_hp_build() after via_clone_control(spec,
&via_hp_mixer[0]) succeeds, so that in via_build_pcms():


info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams = 1 +
spec->independent_front_panel_out;


I was using it also in patch_vtXXXX() (for a few codecs, not all) to
create a "Front Mic Boost Volume" control dynamically only when the
front panel exist (but that's wrong, I've modified it to check for
spec->autocfg.hp_pins[0], which seems to be 0 when there's no front
panel seen by the BIOS).

More code is in my last mail for this thread, before this one, I've
changed since then:

front_panel_out renamed independent_front_panel_out, and
vt_add_front_mic_boost() now is:


static int vt_add_front_mic_boost( struct via_spec *spec, const struct
snd_kcontrol_new *fmb_ctl ){
struct snd_kcontrol_new *knew;

if( spec->autocfg.hp_pins[0] ){ /* if there is a front audio panel */
knew = via_clone_control( spec, fmb_ctl );
if( knew == NULL )
return -ENOMEM;
return 1;
}

return 0;
}


(here, it would be the same to check for spec->multiout.hp_nid being
set, but only if the position of the assignment to
spec->multiout.hp_nid is not moved around in
vtxxx_auto_create_hp_ctls)
Post by alex dot baldacchino dot alsasub at gmail dot com
However there is a bug in using subdevice 1 for "Independent HP" and
subdevice 0 for multi-channels
The channel count reported by snd_pcm_hw_params_get_channels_max() or
snd_pcm_hw_params_test_channel() for subdevice 1 is also equal to
spec->multiout.max_channels but this subdevice 1 only support stereo
I haven't understood all of the pcm layer, but I guess that issue
could be hard to fix without touching it at some level, or creating a
separate pcm (struct snd_pcm) to handle multi-outs and hp separately,
with a careful inspection of the code needed to handle them in tandem
(via_playback_pcm_open() and so on).

struct hda_pcm can hold only 2 struct hda_pcm_stream elements (one
actually used for playback, the other for capture):

/* for PCM creation */
struct hda_pcm {
char *name;
struct hda_pcm_stream stream[2];
...

and at least snd_hda_attach_pcm() (hda_codec.c) counts on it:

static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
{
struct hda_bus *bus = codec->bus;
struct hda_pcm_stream *info;
int stream, err;

if (snd_BUG_ON(!pcm->name))
return -EINVAL;
for (stream = 0; stream < 2; stream++) {
info = &pcm->stream[stream];
if (info->substreams) {
err = set_pcm_default_values(codec, info);
if (err < 0)
return err;
}
}
return bus->ops.attach_pcm(bus, codec, pcm);
}


Moreover, only one pcm is created for a VIA codec, to handle analog
outputs, plus one if there are digital connections:

(file patch_via.c)

static int via_build_pcms(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;

codec->num_pcms = 1;
codec->pcm_info = info;
....

if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
codec->num_pcms++;
info++;
...


(file hda_codec.c)

int snd_hda_codec_build_pcms(struct hda_codec *codec)
{
unsigned int pcm;
int err;
...

for (pcm = 0; pcm < codec->num_pcms; pcm++) {
struct hda_pcm *cpcm = &codec->pcm_info[pcm];
int dev;
...

if (!cpcm->pcm) {
dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
if (dev < 0)
continue; /* no fatal error */
cpcm->device = dev;
err = snd_hda_attach_pcm(codec, cpcm);
...


snd_hda_attach_pcm() calls bus->ops.attach_pcm(), that is (in file
hda_intel.c) azx_attach_pcm_stream():


static int
azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
struct hda_pcm *cpcm)
{
struct azx *chip = bus->private_data;
struct snd_pcm *pcm;
struct azx_pcm *apcm;
int pcm_dev = cpcm->device;
int s, err;
...

err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
&pcm);
...

apcm->chip = chip;
apcm->codec = codec;
pcm->private_data = apcm;
...

cpcm->pcm = pcm;
for (s = 0; s < 2; s++) {
apcm->hinfo[s] = &cpcm->stream[s];
if (cpcm->stream[s].substreams)
snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
}
...


again counting on two streams only:

(hda_intel.c):

struct azx_pcm {
struct azx *chip;
struct hda_codec *codec;
struct hda_pcm_stream *hinfo[2];
};


(pcm.h):

struct snd_pcm {
...
struct snd_pcm_str streams[2];
...
void *private_data;
...


struct snd_pcm_str {
int stream; /* stream (direction) */
struct snd_pcm *pcm;
/* -- substreams -- */
unsigned int substream_count;
unsigned int substream_opened;
struct snd_pcm_substream *substream;
...


struct snd_pcm_substream {
struct snd_pcm *pcm;
struct snd_pcm_str *pstr;
void *private_data; /* copied from pcm->private_data */
...

/* -- hardware operations -- */
struct snd_pcm_ops *ops;
/* -- runtime information -- */
struct snd_pcm_runtime *runtime;

(notice above comment about field private_data, from file)


struct snd_pcm_runtime {
...
/* -- hardware description -- */
struct snd_pcm_hardware hw;
struct snd_pcm_hw_constraints hw_constraints;
...


struct snd_pcm_hardware {
...
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
...

(pcm.c):

int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm ** rpcm)
{
struct snd_pcm *pcm;
int err;
...

if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
playback_count)) < 0) {
...
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE,
capture_count)) < 0) {
...


int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
{
int idx, err;
struct snd_pcm_str *pstr = &pcm->streams[stream];
struct snd_pcm_substream *substream, *prev;
...

pstr->stream = stream;
pstr->pcm = pcm;
pstr->substream_count = substream_count;
...
for (idx = 0, prev = NULL; idx < substream_count; idx++) {
substream = kzalloc(sizeof(*substream), GFP_KERNEL);
...

substream->pcm = pcm;
substream->pstr = pstr;
substream->number = idx;
substream->stream = stream;
....


int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
struct file *file,
struct snd_pcm_substream **rsubstream)
{
struct snd_pcm_str * pstr;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
...

runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
...

substream->runtime = runtime;
substream->private_data = pcm->private_data;
...
*rsubstream = substream;
return 0;
}



This one called by: (pcm_native.c):


int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
struct file *file,
struct snd_pcm_substream **rsubstream)
{
struct snd_pcm_substream *substream;
int err;

err = snd_pcm_attach_substream(pcm, stream, file, &substream);
...

if ((err = substream->ops->open(substream)) < 0)
goto error;

substream->hw_opened = 1;
...

*rsubstream = substream;
...


called by snd_pcm_open_file(), in turn called by snd_pcm_open(), in
turn called by snd_pcm_{playback, capture}_open(), which are
'exported' as file_operations; substream->ops->open(), as set by
azx_attach_pcm_stream(), is:

(hda_intel.c):

static int azx_pcm_open(struct snd_pcm_substream *substream)
{
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
struct azx *chip = apcm->chip;
struct azx_dev *azx_dev;
struct snd_pcm_runtime *runtime = substream->runtime;
...

runtime->hw.channels_min = hinfo->channels_min;
runtime->hw.channels_max = hinfo->channels_max;
...


In file pcm.h:

#define snd_pcm_substream_chip(substream) ((substream)->private_data)

since substream->private_data is shared by all substreams of the same
snd_pcm, in case of playback (substream->stream ==
SNDRV_PCM_STREAM_PLAYBACK), hinfo is spec->stream_analog_playback, and
.channel_{min, max} fields hold same values for both multi-out and
Independent HP subdevices (if I'm not mistaken, of course).

If my interpretation above is correct, something should change in that
chain in order to have different values retrieved for different
substreams of the same stream of the same pcm.

On the other hand, using separate pcms could require less invasive,
yet careful, changes (affecting only patch_via.c, or one patch at a
time, to test it better), but could affect any application eventually
counting on analog outputs being handled by the same pcm.
Post by alex dot baldacchino dot alsasub at gmail dot com
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
alex dot baldacchino dot alsasub at gmail dot com
2011-06-16 18:50:40 UTC
Permalink
(Sorry for previous message being too long)

2011/6/14 Raymond Yau <***@gmail.com>:
- Nascondi testo citato -
Post by alex dot baldacchino dot alsasub at gmail dot com
2011/6/8 alex dot baldacchino dot alsasub at gmail dot com
Post by alex dot baldacchino dot alsasub at gmail dot com
http://pastebin.ca/2076750
By the way, should something like the above be done for capture
streams as well? I've noticed (with front panel disabled) that
controls "Front Mic Playback Volume" and "Front Mic Playback Switch"
are correctly missing from audio-mixer widget 0x21, but node 0x29 is
still 'attached' to control "Front Mic Boost Capture Volume", which is
accessible through a mixer (though I didn't try to play with it; it is
listed also by amixer output in above linked document). Is this the
wanted/expected behaviour?
It seem that 0x2b and 0x29 does not have any mic boost capture volume,
that look like "Playback Switch" when they are retasked as output for
3 jacks motherboard
Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x02a19037: [Jack] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x7
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1c
Node 0x2b [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x00002334: IN OUT Detect
Vref caps: HIZ 50 100
Pin Default 0x01a19036: [Jack] Mic at Ext Rear
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x6
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 2
0x0a* 0x0c
That pastebin was alsa-info.sh output with front panel disabled in
bios, to show via_build_pcms() can be fixed to avoid creating a
sencond playback pcm substream (thus, a second subdevice) when there's
no front audio panel in the system (or is disabled), even if
snd_hda_find_mixer_ctl() cannot find control "Independent HP" if
called from within via_build_pcms:

APLAY

**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: VT2020 Analog [VT2020 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0


But I might have pasted a wrong file (sorry for that), correct output
for that (sort of) patch would be:


Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x42a190f7: [N/A] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0xf, Sequence = 0x7
Pin-ctls: 0x00: VREF_HIZ
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1c


Front audio panel not connected (not seen by the BIOS) -> front mic
not available -> power setting D3 (because of set_pin_power_state()
checking for presence, I guess)


Node 0x2b [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x00002334: IN OUT Detect
Vref caps: HIZ 50 100
Pin Default 0x01a19036: [Jack] Mic at Ext Rear
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x6
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 2
0x0a* 0x0c


Rear jack present (on the motherboard), but nothing connected to it ->
power state D3
Post by alex dot baldacchino dot alsasub at gmail dot com
/* capture mixer elements */
static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
- HDA_INPUT),
This would eliminate both boost volume controls at once, but in normal
conditions (e.g. front audio panel enabled in bios, headset connected
to it) Front Mic Boost works (e.g. I can record sound louder and
noisier). I just wondered if creating "Front Mic Boost Capture Volume"
could have been done dynamically, instead, to match the driver
capability (as is) to avoid creating Volume and Switch controls (on
mixer 0x21) for Front Mic:

with front audio panel missing (disabled in bios):

Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x80 0x80] [0x1f 0x1f] [0x80 0x80] [0x80 0x80]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28


otherwise:


Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Front Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Front Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Rear Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Rear Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x1f 0x1f] [0x1f 0x1f] [0x1f 0x1f] [0x80 0x80]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28


A possible solution:


/* capture mixer elements */
static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
- HDA_INPUT),

...

+ static const struct snd_kcontrol_new vt1718S_front_mic_boost =
+ HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
+ HDA_INPUT);


+ static int vt1718S_add_front_mic_boost( struct via_spec *spec ){
+ snd_kcontrol_new *knew;
+
+ if( spec->front_panel_out == HDA_HW_WITH_FRONT_PANEL){
+ knew = via_clone_control( spec, &vt1718S_front_mic_boost );
+ if( knew == NULL )
+ return -ENOMEM;
+ return 1;
+ }
+
+ return 0;
+ }


in struct via_spec:

...

struct hda_pcm pcm_rec[ VIA_NUM_REC];
+ #define HDA_HW_WITHOUT_FRONT_PANEL 0 /* initial value*/
+ #define HDA_HW_WITH_FRONT_PANEL 1
+ unsigned int front_panel_out; /* used to determine the correct
number of playback pcm substreams */


in via_new_spec():

...

codec->spec = spec;
spec->codec = codec;
spec->codec_type = get_codec_type(codec);
+ spec->front_panel_out = HDA_HW_WITHOUT_FRONT_PANEL;


in via_hp_build():

...

knew = via_clone_control(spec, &via_hp_mixer[0]);
if (knew == NULL){
return -ENOMEM;
}
knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
knew->private_value = nid;
+ spec->front_panel_out = HDA_HW_WITH_FRONT_PANEL; /* now we
know there's a valid secondary playback pcm substream */


in via_build_pcms():

...

info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
spec->multiout.dac_nids[0];
+ /* is this a multistream-capable environment? let's compute
real number of playback pcm substreams */
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams = 1 +
spec->front_panel_out;


in patch_vt1718S():

...
if (!spec->adc_nids && spec->input_mux) {
spec->adc_nids = vt1718S_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
get_mux_nids(codec);
override_mic_boost(codec, 0x2b, 0, 3, 40);
override_mic_boost(codec, 0x29, 0, 3, 40);
spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
spec->num_mixers++;
+ vt1718S_add_front_mic_boost( spec );
}


It worked for me, AFAICT:

With front audio panel _enabled_ in bios:

Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Front Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Front Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=3, ofs=0
Control: name="Rear Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Rear Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x1f 0x1f] [0x1f 0x1f] [0x1f 0x1f] [0x80 0x80]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28


Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Front Mic Boost Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x02a19037: [Jack] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x7
Pin-ctls: 0x21: IN VREF_50
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 1
0x1c


aplay -l output

**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: VT2020 Analog [VT2020 Analog]
Subdevices: 2/2
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
[...]


and front mic boost control listed in amixer:

Simple mixer control 'Front Mic Boost',0
Capabilities: cvolume penum
Capture channels: Front Left - Front Right
Limits: Capture 0 - 3
Front Left: Capture 0 [0%] [0.00dB]
Front Right: Capture 0 [0%] [0.00dB]


With front audio panel _disabled_ in bios:


Node 0x21 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
Control: name="Mic Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Mic Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Line Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Control: name="Line Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=2, ofs=0
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x80 0x80] [0x80 0x80] [0x1f 0x1f] [0x80 0x80] [0x80 0x80]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
Connection: 5
0x2c 0x2b 0x2a 0x29 0x28


Node 0x29 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000233c: IN OUT HP Detect
Vref caps: HIZ 50 100
Pin Default 0x42a190f7: [N/A] Mic at Ext Front
Conn = 1/8, Color = Pink
DefAssociation = 0xf, Sequence = 0x7
Pin-ctls: 0x00: VREF_HIZ
Unsolicited: tag=20, enabled=1
Power states: D0 D1 D2 D3
Power: setting=D3, actual=D3
Connection: 1
0x1c


aplay -l output:

**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: VT2020 Analog [VT2020 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
[...]

and control "Front Mic Boost" missing in amixer output. Attaching
alsa-info.sh outputs.

Perhaps other codecs could benefit of that, like VT1708S, VT1716S,
VT2002P, VT1812, all creating a "Front Mic Boost Capture Volume"
control statically (each one needing its own modification to
vtxxxxx_capture_mixer, patch_vtxxxxx(), and
vt1718S_add_front_mic_boost() function renamed, moved upward in the
file before patch_vt1708S() and modified with a further
snd_kcontrol_new argument to be used by all others, e.g. called as
vt_add_front_mic_boost( spec, &vt1718S_front_mic_boost ):

+ static int vt_add_front_mic_boost( struct via_spec *spec, const
struct snd_kcontrol_new *fmb_ctl ){
+ snd_kcontrol_new *knew;
+
+ if( spec->front_panel_out == HDA_HW_WITH_FRONT_PANEL){
+ knew = via_clone_control( spec, fmb_ctl );
+ if( knew == NULL )
+ return -ENOMEM;
+ return 1;
+ }
+
+ return 0;
+ }


).
Post by alex dot baldacchino dot alsasub at gmail dot com
The problem is in hda_verb vt1718S_volume_init_verbs
/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
node 0x21 of your vt2020 has only 5 connections
Refer to commit 4ab2d53a99b6dcee86837d2a9739bfb9f468db45
you will need to ask the author of this patch since the patch
explicitly change this non exisiting connection of node 0x21 on your
vt2020
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
Will do. Perhaps there could be the need to create a separate
vt2020_volume_init_verbs, unless that operation is due to internal
implementation of the codec (reacting properly to the non-existing
connection write query). Thank you for everything.
- Nascondi testo citato -
Post by alex dot baldacchino dot alsasub at gmail dot com
_______________________________________________
Alsa-devel mailing list
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Loading...