Great. Then I'll commit the fixes after your test result.
I am attaching a tested patch for ak4114.c and ak4114.h
Fixes: ------- * correct register for "IEC958 Non-PCM Bitstream", "IEC958 DTS Bitstream": AK4114_REG_RCS0 * correct check for control name: if (strstr(kctl->id.name, "Playback")) * correct check: if (! chip->init) in snd_ak4114_external_rate
New features: ----------------- * added PCM control "IEC958 PPL Lock Status"
All capture functions work, as well as all PCM + IEC958 controls (their values correspond to datasheet specifications). Since AK4114 is initialized without a crystal connected, the "IEC958 External Rate" is read correctly from IEC958 header in professional mode. In consumer mode the chip is able to detect 44100 and 48000, all other rates are returned as 44100. All the rates are correctly set in "IEC958 External Rate". I did the tests using the actual SPDIF output of the same card, which is capable of 32 - 192kHz consumer/professional mode. Other test data were provided by digital output of my CD player.
To make testing easier I patched amixer.c to display 5 bytes of SND_CTL_ELEM_TYPE_IEC958 which was so far unsupported (question mark instead). I find it usefull, it is up to you to decide if it finds way into official sources.
diff -r 2a2bde6bf7c2 amixer/amixer.c --- a/amixer/amixer.c Mon Jan 15 14:47:35 2007 +0100 +++ b/amixer/amixer.c Wed Apr 04 22:29:06 2007 +0200 @@ -534,6 +534,7 @@ static int show_control(const char *spac snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; + snd_aes_iec958_t iec958; snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); @@ -604,6 +605,12 @@ static int show_control(const char *spac break; case SND_CTL_ELEM_TYPE_BYTES: printf("0x%02x", snd_ctl_elem_value_get_byte(control, idx)); + break; + case SND_CTL_ELEM_TYPE_IEC958: + snd_ctl_elem_value_get_iec958 (control, &iec958); + printf("4=0x%01x, 3=0x%01x, 2=0x%01x, 1=0x%01x, 0=0x%01x", + iec958.status[4], iec958.status[3], iec958.status[2], + iec958.status[1], iec958.status[0]); break; default: printf("?");