sound: virtuoso: do not overwrite EEPROM on Xonar D2/D2X
On the Asus Xonar D2 and D2X models, the SPI chip select signal for the fourth DAC shares its pin with the serial clock for the EEPROM that contains the PCI subdevice ID values. It appears that when DAC registers are written and some other unknown conditions occur (probably noise on the EEPROM's chip select line), the EEPROM gets overwritten with garbage, which makes it impossible to properly detect the card later. Therefore, we better avoid DAC register writes and make sure that the driver works with the DAC's registers' default values. Consequently, the sample format is now I2S instead of left-justified (no user-visible change), and the DAC's volume/mute registers cannot be used anymore (volume changes are now done by the software volume plugin). Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
37a76bd4f1
commit
7e86c0e685
1 changed files with 13 additions and 4 deletions
|
@ -26,7 +26,7 @@
|
|||
* SPI 0 -> 1st PCM1796 (front)
|
||||
* SPI 1 -> 2nd PCM1796 (surround)
|
||||
* SPI 2 -> 3rd PCM1796 (center/LFE)
|
||||
* SPI 4 -> 4th PCM1796 (back)
|
||||
* SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!)
|
||||
*
|
||||
* GPIO 2 -> M0 of CS5381
|
||||
* GPIO 3 -> M1 of CS5381
|
||||
|
@ -207,6 +207,12 @@ static void xonar_gpio_changed(struct oxygen *chip);
|
|||
static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
|
||||
u8 reg, u8 value)
|
||||
{
|
||||
/*
|
||||
* We don't want to do writes on SPI 4 because the EEPROM, which shares
|
||||
* the same pin, might get confused and broken. We'd better take care
|
||||
* that the driver works with the default register values ...
|
||||
*/
|
||||
#if 0
|
||||
/* maps ALSA channel pair number to SPI output */
|
||||
static const u8 codec_map[4] = {
|
||||
0, 1, 2, 4
|
||||
|
@ -217,6 +223,7 @@ static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
|
|||
(codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
|
||||
OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
|
||||
(reg << 8) | value);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
|
||||
|
@ -750,6 +757,9 @@ static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0);
|
|||
|
||||
static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
|
||||
{
|
||||
if (!strncmp(template->name, "Master Playback ", 16))
|
||||
/* disable volume/mute because they would require SPI writes */
|
||||
return 1;
|
||||
if (!strncmp(template->name, "CD Capture ", 11))
|
||||
/* CD in is actually connected to the video in pin */
|
||||
template->private_value ^= AC97_CD ^ AC97_VIDEO;
|
||||
|
@ -840,9 +850,8 @@ static const struct oxygen_model model_xonar_d2 = {
|
|||
.dac_volume_min = 0x0f,
|
||||
.dac_volume_max = 0xff,
|
||||
.misc_flags = OXYGEN_MISC_MIDI,
|
||||
.function_flags = OXYGEN_FUNCTION_SPI |
|
||||
OXYGEN_FUNCTION_ENABLE_SPI_4_5,
|
||||
.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
|
||||
.function_flags = OXYGEN_FUNCTION_SPI,
|
||||
.dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
|
||||
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue