Commit 7e86c0e6850504ec9516b953f316a47277825e33

Authored by Clemens Ladisch
Committed by Takashi Iwai
1 parent 37a76bd4f1

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>

Showing 1 changed file with 13 additions and 4 deletions Side-by-side Diff

sound/pci/oxygen/virtuoso.c
... ... @@ -26,7 +26,7 @@
26 26 * SPI 0 -> 1st PCM1796 (front)
27 27 * SPI 1 -> 2nd PCM1796 (surround)
28 28 * SPI 2 -> 3rd PCM1796 (center/LFE)
29   - * SPI 4 -> 4th PCM1796 (back)
  29 + * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!)
30 30 *
31 31 * GPIO 2 -> M0 of CS5381
32 32 * GPIO 3 -> M1 of CS5381
... ... @@ -207,6 +207,12 @@
207 207 static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
208 208 u8 reg, u8 value)
209 209 {
  210 + /*
  211 + * We don't want to do writes on SPI 4 because the EEPROM, which shares
  212 + * the same pin, might get confused and broken. We'd better take care
  213 + * that the driver works with the default register values ...
  214 + */
  215 +#if 0
210 216 /* maps ALSA channel pair number to SPI output */
211 217 static const u8 codec_map[4] = {
212 218 0, 1, 2, 4
... ... @@ -217,6 +223,7 @@
217 223 (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
218 224 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
219 225 (reg << 8) | value);
  226 +#endif
220 227 }
221 228  
222 229 static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
... ... @@ -750,6 +757,9 @@
750 757  
751 758 static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
752 759 {
  760 + if (!strncmp(template->name, "Master Playback ", 16))
  761 + /* disable volume/mute because they would require SPI writes */
  762 + return 1;
753 763 if (!strncmp(template->name, "CD Capture ", 11))
754 764 /* CD in is actually connected to the video in pin */
755 765 template->private_value ^= AC97_CD ^ AC97_VIDEO;
... ... @@ -840,9 +850,8 @@
840 850 .dac_volume_min = 0x0f,
841 851 .dac_volume_max = 0xff,
842 852 .misc_flags = OXYGEN_MISC_MIDI,
843   - .function_flags = OXYGEN_FUNCTION_SPI |
844   - OXYGEN_FUNCTION_ENABLE_SPI_4_5,
845   - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
  853 + .function_flags = OXYGEN_FUNCTION_SPI,
  854 + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
846 855 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
847 856 };
848 857