[alsa-devel] [PATCH 1/2] snd-oxygen: Changes for oxygen driver to fix the Xonar DG card

Roman Volkov v1ron at mail.ru
Tue Nov 19 15:26:17 CET 2013


This patch does some preparation of existing Oxygen driver. Some constants added to the header files. To perform the SPI reading, there is a new function to wait when the SPI finishes a transaction. Channel routing must be updated when the user selects the audio output, and there are some extra symbols exported from the snd-oxygen-lib module.

Signed-off-by: Roman I Volkov <v1ron at mail.ru>
---
Should not affect other models of Oxygen driver, but who knows.
diff -uprN linux-3.12/sound/pci/oxygen/cs4245.h linux-3.12-my/sound/pci/oxygen/cs4245.h
--- linux-3.12/sound/pci/oxygen/cs4245.h	2013-11-04 03:41:51.000000000 +0400
+++ linux-3.12-my/sound/pci/oxygen/cs4245.h	2013-11-15 15:46:40.000000000 +0400
@@ -103,5 +103,6 @@
 #define CS4245_ADC_UNDRFL	0x01
 
 
-#define CS4245_SPI_ADDRESS	(0x9e << 16)
-#define CS4245_SPI_WRITE	(0 << 16)
+#define CS4245_SPI_ADDRESS	0x9e
+#define CS4245_SPI_WRITE	0
+#define CS4245_SPI_READ		1
diff -uprN linux-3.12/sound/pci/oxygen/oxygen.h linux-3.12-my/sound/pci/oxygen/oxygen.h
--- linux-3.12/sound/pci/oxygen/oxygen.h	2013-11-04 03:41:51.000000000 +0400
+++ linux-3.12-my/sound/pci/oxygen/oxygen.h	2013-11-15 15:47:38.000000000 +0400
@@ -198,7 +198,8 @@ void oxygen_write_ac97(struct oxygen *ch
 void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
 			      unsigned int index, u16 data, u16 mask);
 
-void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
+int oxygen_wait_spi(struct oxygen *chip);
+int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
 void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
 
 void oxygen_reset_uart(struct oxygen *chip);
diff -uprN linux-3.12/sound/pci/oxygen/oxygen_io.c linux-3.12-my/sound/pci/oxygen/oxygen_io.c
--- linux-3.12/sound/pci/oxygen/oxygen_io.c	2013-11-04 03:41:51.000000000 +0400
+++ linux-3.12-my/sound/pci/oxygen/oxygen_io.c	2013-11-19 00:56:12.000000000 +0400
@@ -105,8 +105,8 @@ static int oxygen_ac97_wait(struct oxyge
 	 * Reading the status register also clears the bits, so we have to save
 	 * the read bits in status.
 	 */
-	wait_event_timeout(chip->ac97_waitqueue,
-			   ({ status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS);
+	wait_event_timeout(chip->ac97_waitqueue, ({ status |= oxygen_read8(chip,
+					OXYGEN_AC97_INTERRUPT_STATUS);
 			      status & mask; }),
 			   msecs_to_jiffies(1) + 1);
 	/*
@@ -194,23 +194,35 @@ void oxygen_write_ac97_masked(struct oxy
 }
 EXPORT_SYMBOL(oxygen_write_ac97_masked);
 
-void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
+int oxygen_wait_spi(struct oxygen *chip)
 {
-	unsigned int count;
+	/* Higher interval to be sure - 100 microseconds */
+	unsigned int count = 100;
 
-	/* should not need more than 30.72 us (24 * 1.28 us) */
-	count = 10;
-	while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY)
-	       && count > 0) {
-		udelay(4);
-		--count;
+	for (;;) {
+		if ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) &
+						OXYGEN_SPI_BUSY) == 0)
+			break;
+		if (count == 0) {
+			snd_printk(KERN_ERR "oxygen: spi wait timeout\n");
+			return -EIO;
+		}
+		udelay(1);
+		count--;
 	}
+	return 0;
+}
+EXPORT_SYMBOL(oxygen_wait_spi);
 
+int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
+{
 	oxygen_write8(chip, OXYGEN_SPI_DATA1, data);
 	oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8);
 	if (control & OXYGEN_SPI_DATA_LENGTH_3)
 		oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16);
 	oxygen_write8(chip, OXYGEN_SPI_CONTROL, control);
+
+	return oxygen_wait_spi(chip);
 }
 EXPORT_SYMBOL(oxygen_write_spi);
 
diff -uprN linux-3.12/sound/pci/oxygen/oxygen_mixer.c linux-3.12-my/sound/pci/oxygen/oxygen_mixer.c
--- linux-3.12/sound/pci/oxygen/oxygen_mixer.c	2013-11-04 03:41:51.000000000 +0400
+++ linux-3.12-my/sound/pci/oxygen/oxygen_mixer.c	2013-11-18 14:03:54.000000000 +0400
@@ -190,6 +190,7 @@ void oxygen_update_dac_routing(struct ox
 	if (chip->model.update_center_lfe_mix)
 		chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
 }
+EXPORT_SYMBOL(oxygen_update_dac_routing);
 
 static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
 {
diff -uprN linux-3.12/sound/pci/oxygen/oxygen_regs.h linux-3.12-my/sound/pci/oxygen/oxygen_regs.h
--- linux-3.12/sound/pci/oxygen/oxygen_regs.h	2013-11-04 03:41:51.000000000 +0400
+++ linux-3.12-my/sound/pci/oxygen/oxygen_regs.h	2013-11-18 13:58:11.000000000 +0400
@@ -318,6 +318,7 @@
 #define  OXYGEN_PLAY_MUTE23		0x0002
 #define  OXYGEN_PLAY_MUTE45		0x0004
 #define  OXYGEN_PLAY_MUTE67		0x0008
+#define  OXYGEN_PLAY_MUTE_MASK		0x000f
 #define  OXYGEN_PLAY_MULTICH_MASK	0x0010
 #define  OXYGEN_PLAY_MULTICH_I2S_DAC	0x0000
 #define  OXYGEN_PLAY_MULTICH_AC97	0x0010


More information about the Alsa-devel mailing list