sound: virtuoso: do not overwrite EEPROM on Xonar D2/D2X
authorClemens Ladisch <clemens@ladisch.de>
Thu, 15 Jan 2009 09:21:23 +0000 (10:21 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 2 Feb 2009 16:28:15 +0000 (08:28 -0800)
commit 7e86c0e6850504ec9516b953f316a47277825e33 upstream.

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>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
sound/pci/oxygen/virtuoso.c

index 01d7b75..82a7814 100644 (file)
@@ -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
@@ -142,6 +142,12 @@ struct xonar_data {
 static void pcm1796_write(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
@@ -152,6 +158,7 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec,
                         (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
                         OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
                         (reg << 8) | value);
+#endif
 }
 
 static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
@@ -539,6 +546,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;
@@ -588,9 +598,8 @@ static const struct oxygen_model xonar_models[] = {
                .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,
        },
        [MODEL_D2X] = {
@@ -619,9 +628,8 @@ static const struct oxygen_model xonar_models[] = {
                .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,
        },
        [MODEL_D1] = {