[alsa-devel] Terratec EWS88D (ice1712) optical stuck on ADAT (no IEC958 optical i/o)
Niels Mayer
nielsmayer at gmail.com
Tue Sep 14 17:58:26 CEST 2010
On Tue, Sep 14, 2010 at 2:17 AM, Alan Horstmann <gineera at 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/ice1712/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),
};
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
More information about the Alsa-devel
mailing list