/* * Juli does not use the standard ICE1724 clock scheme. Juli's ice1724 chip is * supplied by external clock provided by Xilinx array and MK73-1 PLL frequency * multiplier. Actual frequency is set by ice1724 GPIOs hooked to the Xilinx. * * The clock circuitry is supplied by the two ice1724 crystals. This * arrangement allows to generate independent clock signal for AK4114's input * rate detection circuit. As a result, Juli, unlike most other * ice1724+ak4114-based cards, detects spdif input rate correctly. * This fact is applied in the driver, allowing to modify PCM stream rate * parameter according to the actual input rate. * * Juli uses the remaining three stereo-channels of its DAC to optionally * monitor analog input, digital input, and digital output. The corresponding * I2S signals are routed by Xilinx, controlled by GPIOs. * * The master mute is implemented using output muting transistors (GPIO) in * combination with smuting the DAC. * * The card itself has no HW master volume control, implemented using the * vmaster control. * * TODO: * researching and fixing the input monitors
*/
staticconststruct snd_kcontrol_new juli_mute_controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
.info = juli_mute_info,
.get = juli_mute_get,
.put = juli_mute_put,
.private_value = GPIO_MUTE_CONTROL,
}, /* Although the following functionality respects the succint NDA'd * documentation from the card manufacturer, and the same way of * operation is coded in OSS Juli driver, only Digital Out monitor * seems to work. Surprisingly, Analog input monitor outputs Digital * output data. The two are independent, as enabling both doubles * volume of the monitor sound. * * Checking traces on the board suggests the functionality described * by the manufacturer is correct - I2S from ADC and AK4114 * go to ICE as well as to Xilinx, I2S inputs of DAC2,3,4 (the monitor * inputs) are fed from Xilinx. * * I even checked traces on board and coded a support in driver for * an alternative possibility - the unused I2S ICE output channels * switched to HW-IN/SPDIF-IN and providing the monitoring signal to * the DAC - to no avail. The I2S outputs seem to be unconnected. * * The windows driver supports the monitoring correctly.
*/
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Monitor Analog In Switch",
.info = juli_mute_info,
.get = juli_mute_get,
.put = juli_mute_put,
.private_value = GPIO_ANAIN_MONITOR,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Monitor Digital Out Switch",
.info = juli_mute_info,
.get = juli_mute_get,
.put = juli_mute_put,
.private_value = GPIO_DIGOUT_MONITOR,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Monitor Digital In Switch",
.info = juli_mute_info,
.get = juli_mute_get,
.put = juli_mute_put,
.private_value = GPIO_DIGIN_MONITOR,
},
};
staticunsignedint juli_get_rate(struct snd_ice1712 *ice)
{ int i; unsignedchar result;
result = ice->gpio.get_data(ice) & GPIO_RATE_MASK; for (i = 0; i < ARRAY_SIZE(gpio_vals); i++) if (gpio_vals[i] == result) return juli_rates[i]; return 0;
}
old = ice->gpio.get_data(ice); new = (old & ~GPIO_RATE_MASK) | get_gpio_val(rate); /* dev_dbg(ice->card->dev, "JULI - set_rate: old %x, new %x\n", old & GPIO_RATE_MASK,
new & GPIO_RATE_MASK); */
ice->gpio.set_data(ice, new); /* switching to external clock - supplied by external circuits */
val = inb(ICEMT1724(ice, RATE));
outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
}
staticinlineunsignedchar juli_set_mclk(struct snd_ice1712 *ice, unsignedint rate)
{ /* no change in master clock */ return 0;
}
err = snd_ak4114_create(ice->card,
juli_ak4114_read,
juli_ak4114_write,
ak4114_init_vals, ak4114_init_txcsb,
ice, &spec->ak4114); if (err < 0) return err; /* callback for codecs rate setting */
spec->ak4114->change_callback = juli_ak4114_change;
spec->ak4114->change_callback_private = ice; /* AK4114 in Juli can detect external rate correctly */
spec->ak4114->check_flags = 0;
#if 0 /* * it seems that the analog doughter board detection does not work reliably, so * force the analog flag; it should be very rare (if ever) to come at Juli@ * used without the analog daughter board
*/
spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1; #else
spec->analog = 1; #endif
if (spec->analog) {
dev_info(ice->card->dev, "juli@: analog I/O detected\n");
ice->num_total_dacs = 2;
ice->num_total_adcs = 2;
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
ak = ice->akm; if (!ak) return -ENOMEM;
ice->akm_codecs = 1;
err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice); if (err < 0) return err;
}
/* juli is clocked by Xilinx array */
ice->hw_rates = &juli_rates_info;
ice->is_spdif_master = juli_is_spdif_master;
ice->get_rate = juli_get_rate;
ice->set_rate = juli_set_rate;
ice->set_mclk = juli_set_mclk;
ice->set_spdif_clock = juli_set_spdif_clock;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.