[alsa-devel] Terratec EWS88D (ice1712) optical stuck on ADAT (no IEC958 optical i/o)
I just scored a nice Terratec EWS88D for $20.00. :-) ( http://nielsmayer.com/envy24control/EWS88D_Board_L.jpg missing midi cable though (*)) It works nicely with Linux and http://mudita24.googlecode.com , although it's missing some important controls to turn off the ADAT parts of the card. Alas, it wouldn't help to support them in mudita24, as I cannot get them to change values through standard ALSA tools like amixer(1) and alsamixer(1).
Therefore, the question: is what is it about snd-ice1712 that prevents the mixer control values detailed below from changing, and is there anything I can do to fix it? (sometimes you want to use this card in it's dual IEC958 optical + spdif I/O config, other times, you want to use the optical for ADAT and the spdif for IEC958, which is the only configuration I can get currently.)
The results from amixer(1): http://nielsmayer.com/envy24control/terratec-ews88d-amixer.txt Results of "cat /proc/asound/EWS88D/ice1712": http://nielsmayer.com/envy24control/terratec-ews88d-ice1712.txt
My attempts at changing optical port from ADAT to IEC958. Nothing happens:
///// ///// ///// ///// ///// ///// ///// ///// coggie-7-~> foreach i ( 'IEC958 Input Optical' 'IEC958 Input Optical' 'ADAT External Master Clock' 'ADAT Output Optical' 'ADAT Through' 'Enable ADAT' ) foreach? amixer cget iface=MIXER,name="$i" foreach? end numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=97,iface=MIXER,name='ADAT External Master Clock' ; type=BOOLEAN,access=rw------,values=1 : values=on numid=96,iface=MIXER,name='ADAT Output Optical' ; type=BOOLEAN,access=rw------,values=1 : values=on numid=99,iface=MIXER,name='ADAT Through' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=98,iface=MIXER,name='Enable ADAT' ; type=BOOLEAN,access=rw------,values=1 : values=on coggie-10-~> amixer cset iface=MIXER,name='Enable ADAT' off numid=98,iface=MIXER,name='Enable ADAT' ; type=BOOLEAN,access=rw------,values=1 : values=on coggie-11-~> amixer cset iface=MIXER,name='Enable ADAT' false numid=98,iface=MIXER,name='Enable ADAT' ; type=BOOLEAN,access=rw------,values=1 : values=on coggie-12-~> amixer cset iface=MIXER,name='Enable ADAT' off numid=98,iface=MIXER,name='Enable ADAT' ; type=BOOLEAN,access=rw------,values=1 : values=on coggie-13-~> amixer cset iface=MIXER,name='Enable ADAT' 0 numid=98,iface=MIXER,name='Enable ADAT' ; type=BOOLEAN,access=rw------,values=1 : values=on coggie-14-~> amixer cset iface=MIXER,name='IEC958 Input Optical' on numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off coggie-15-~> amixer cset iface=MIXER,name='IEC958 Input Optical' true numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off coggie-16-~> amixer cset iface=MIXER,name='IEC958 Input Optical' 1 numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off ///// ///// ///// ///// ///// ///// ///// /////
FYI, for more info on this board: ftp://ftp.terratec.de/Audio/EWS/88D/Manual/EWS88D_Manual_GB.pdf ftp://ftp.terratec.de/Audio/EWS/88D/TechnicalData/EWS88D_GB.pdf
Relevant snd-ice1712 sources:
http://git.alsa-project.org/?p=alsa-kernel.git;a=blob_plain;f=sound/pci/ice1...
http://git.alsa-project.org/?p=alsa-kernel.git;a=blob_plain;f=sound/pci/ice1...
Also, I'm running on Fedora12 ( 2.6.32.21-166.fc12.x86_64 ) which seems to have a somewhat odd mix of ALSA drivers and runtime:
coggie-17-~> drumstick-sysinfo ALSA Sequencer System Info, version: 0.5.0 Compiled ALSA library: 1.0.23 Runtime ALSA library: 1.0.23 Runtime ALSA drivers: 1.0.21. Numeric ALSA compiled library: 10017 Numeric ALSA runtime library: 10017 Numeric ALSA runtime driver: 10015
Will Fedora13 or "runtime ALSA drivers: 1.0.23" remedy this situation? (Probably not EWS88D is a pretty old card and I don't see any changes related to it recently). The target machine for this card will actually be running Fedora13, however, that machine hasn't been decommissioned, wiped, or setup for that purpose yet....
Niels http://nielsmayer.com
PS: (*) Anybody know where to find/build a 9-pin MIDI cable for the EWS88D? Will the RME HDSP9652 cable fit/work? http://www.bananasmusic.com/productdetail.asp/pid_3970/productname_RME-BOHDS...
On Monday 13 September 2010 16:55, Niels Mayer wrote:
I just scored a nice Terratec EWS88D for $20.00. :-) ( http://nielsmayer.com/envy24control/EWS88D_Board_L.jpg missing midi cable though (*)) It works nicely with Linux and http://mudita24.googlecode.com , although it's missing some important controls to turn off the ADAT parts of the card. Alas, it wouldn't help to support them in mudita24, as I cannot get them to change values through standard ALSA tools like amixer(1) and alsamixer(1).
Therefore, the question: is what is it about snd-ice1712 that prevents the mixer control values detailed below from changing, and is there anything I can do to fix it? (sometimes you want to use this card in it's dual IEC958 optical + spdif I/O config, other times, you want to use the optical for ADAT and the spdif for IEC958, which is the only configuration I can get currently.)
The results from amixer(1): http://nielsmayer.com/envy24control/terratec-ews88d-amixer.txt Results of "cat /proc/asound/EWS88D/ice1712": http://nielsmayer.com/envy24control/terratec-ews88d-ice1712.txt
My attempts at changing optical port from ADAT to IEC958. Nothing happens:
<snip>
May be helpful to use alsamixer (command-line pseudo graphical) - that should present all the controls the driver provides. Certainly I found that to be the most useful way of understanding/operating the underlying controls. (Which envy24control etc operate on top of).
I am fairly sure that the ice1712 driver has no run-time mechanism for enabling/disabling the paired digital streams that are ADAT on EWS88D, and go to/from the AK4524 codecs on most other versions. With the DMX6fire, which normally has 3-pairs, I added a different register value used at start-up so that 2 channel are not active (and picking up 'static' noise), but the other ice1712's enable all 4 pairs always.
It is possible that the functions and controls have been coded from data-sheets and never debugged on real hardware, or at least not in every respect. Perhaps others may know?
Hope this helps,
Alan
On Mon, Sep 13, 2010 at 1:35 PM, Alan Horstmann gineera@aspect135.co.ukwrote:
May be helpful to use alsamixer (command-line pseudo graphical) - that should present all the controls the driver provides. Certainly I found that to be the most useful way of understanding/operating the underlying controls. (Which envy24control etc operate on top of).
It's hard to cut and paste from alsamixer(1) which is why I used amixer(1) and scripting to show what happens in alsamixer(1). The controls of interest, 'IEC958 Input Optical' 'IEC958 Input Optical' 'ADAT External Master Clock' 'ADAT Output Optical' 'ADAT Through' 'Enable ADAT' -- all appear in alsamixer(1) and they're all "stuck" at the current settings.
Using either 'm' or 'space' or any other means that would normally change a boolean value for other ALSA properties do nothing for the above values in alsamixer(1). Basically, it appears that the property toggles, and then flips right back to the previous state (because that's what ALSA says it's at).
Similarly, when set from the commandline, the ALSA result indicates the value stays the same:
amixer cset iface=MIXER,name='IEC958 Input Optical' true numid=95,iface=MIXER,name='IEC958 Input Optical' ; type=BOOLEAN,access=rw------,values=1 : values=off
I am fairly sure that the ice1712 driver has no run-time mechanism for enabling/disabling the paired digital streams that are ADAT on EWS88D, and go to/from the AK4524 codecs on most other versions.
Seems like there's something of it in the code, and certainly the Windows drivers and the hardware itself support this functionality. See also
http://git.alsa-project.org/?p=alsa-kernel.git;a=blob_plain;f=sound/pci/ice1...
static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0), };
It's almost like set/get aren't handling "boolean" correctly... And also, this "invert" thing looks suspect -- explanation???
static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ... int invert = (kcontrol->private_value >> 8) & 1; ... } static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ... int invert = (kcontrol->private_value >> 8) & 1; ... }
With the DMX6fire, which normally has 3-pairs, I added a different register value used at start-up so that 2 channel are not active (and picking up 'static' noise), but the other ice1712's enable all 4 pairs always.
It is possible that the functions and controls have been coded from data-sheets and never debugged on real hardware, or at least not in every respect. Perhaps others may know?
Hoping somebody knows. Or knows of some magic command or patch I can use to switch these inputs.
-- Niels http://nielsmayer.com
On Tuesday 14 September 2010 02:13, you wrote:
On Mon, Sep 13, 2010 at 1:35 PM, Alan Horstmann
gineera@aspect135.co.ukwrote:
May be helpful to use alsamixer (command-line pseudo graphical) - that
It's hard to cut and paste from alsamixer(1) which is why I used amixer(1) and scripting to show what happens in alsamixer(1). The controls of interest, 'IEC958 Input Optical' 'IEC958 Input Optical' 'ADAT External Master Clock' 'ADAT Output Optical' 'ADAT Through' 'Enable ADAT' -- all appear in alsamixer(1) and they're all "stuck" at the current settings.
Using either 'm' or 'space' or any other means that would normally change a boolean value for other ALSA properties do nothing for the above values in alsamixer(1). Basically, it appears that the property toggles, and then flips right back to the previous state (because that's what ALSA says it's at).
Similarly, when set from the commandline, the ALSA result indicates the value stays the same:
I am fairly sure that the ice1712 driver has no run-time mechanism for enabling/disabling the paired digital streams that are ADAT on EWS88D, and go to/from the AK4524 codecs on most other versions.
Seems like there's something of it in the code, and certainly the Windows drivers and the hardware itself support this functionality. See also
I am trying to explain that there are 2 parts to this. The envy24 chip has config registers that are set up at init, in ice1712.c. Look for the uses of 'dxr_enable', and you will see that the ICE_EEP1_CODEC register is set to 0x60 unless its a DMX6fire. Terratec clearly change these at run-time (on Windows), as does the StAudio driver for DSP2000, but the Alsa driver sets this up at init only. Thus I am saying there is no mechanism in the driver to disable the digital stream pairs.
The other part, however, is the controls to switch the SPDIF etc inputs, specific to the EWS88D (and similar functions for the other cards). These are available to change at run-time. As the control get/set funcs are unique to the EWS88D there may be previously undetected bugs in them. The '6fire and DSP2000 controls do work fine, if comparison is any use. It comes down to use of 'printk()' and careful tracing of the failures!
http://git.alsa-project.org/?p=alsa-kernel.git;a=blob_plain;f=sound/pci/ice 1712/ews.c;hb=HEAD
static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0), };
Alan
On Tue, Sep 14, 2010 at 2:17 AM, Alan Horstmann gineera@aspect135.co.uk wrote:
I am trying to explain that there are 2 parts to this. The envy24 chip has config registers that are set up at init, in ice1712.c. Look for the uses of 'dxr_enable', and you will see that the ICE_EEP1_CODEC register is set to 0x60 unless its a DMX6fire. Terratec clearly change these at run-time (on Windows), as does the StAudio driver for DSP2000, but the Alsa driver sets this up at init only. Thus I am saying there is no mechanism in the driver to disable the digital stream pairs.
The other part, however, is the controls to switch the SPDIF etc inputs, specific to the EWS88D (and similar functions for the other cards). These are available to change at run-time. As the control get/set funcs are unique to the EWS88D there may be previously undetected bugs in them. The '6fire and DSP2000 controls do work fine, if comparison is any use. It comes down to use of 'printk()' and careful tracing of the failures!
I was thinking it might be something like this, and that the values I see in alsamixer/amixer reflect the start-up values set http://git.alsa-project.org/?p=alsa-kernel.git;a=blob_plain;f=sound/pci/ice1...
static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0), };
Is there a better way of changing these defaults prior to start-up time other than recompiling?? Oh, and if I were to recompile and try to replace my existing snd-ice1712.so on my fedora12 setup (Runtime ALSA library: 1.0.23, Runtime ALSA drivers: 1.0.21) could I build against 1.0.23, or would I need to go back and build against a 1.0.21 to match all the other drivers and the rest of ALSA? ... I should probably wait till I've actually setup the fedora-13-based system for which this card is intended. That already runs 1.0.23 drivers anyways.
Also, the asymmetry between similar "put" code for the EWS88D and the DMX6Fire is striking. Isn't snd_ice1712_ews88d_control_put() doing something like setting the value to the same thing no matter whether true or false??
if (invert) { if (! ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } else { if (ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } change = (data[shift >> 3] != ndata[shift >> 3]);
Is there documentation or external comments on all these rather squirrely and obtuse data structures, perhaps remedying complaint at https://www.ohloh.net/p/alsa -- "Few source code comments" ?? ... Anybody explain what all those shifts and ands and or's actually do?
static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct ews_spec *spec = ice->spec; int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; unsigned char data[2], ndata[2]; int change;
snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7)); if (invert) { if (! ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } else { if (ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } change = (data[shift >> 3] != ndata[shift >> 3]); if (change && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); return change; }
static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; int data, ndata; if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) return data; ndata = data & ~(1 << shift); if (ucontrol->value.integer.value[0]) ndata |= (1 << shift); if (invert) ndata ^= (1 << shift); if (data != ndata) { snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata); return 1; } return 0; }
-- Niels http://nielsmayer.com
participants (2)
-
Alan Horstmann
-
Niels Mayer