Commit 7e86c0e6850504ec9516b953f316a47277825e33
Committed by
Takashi Iwai
1 parent
37a76bd4f1
Exists in
master
and in
39 other branches
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 |