Browse Source

ALSA: hda-intel - add special 'hwio' model to bypass initialization

Using the 'model=hwio' option, the driver bypasses any codec
initialization and the reset procedure for codecs is also
bypassed. This mode is usefull to enable direct access using
hwdep interface (using hdaverb or hda-analyzer tools) and
retain codec setup from BIOS.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Jaroslav Kysela 15 years ago
parent
commit
cd508fe58b
3 changed files with 25 additions and 10 deletions
  1. 5 0
      Documentation/sound/alsa/HD-Audio.txt
  2. 8 2
      sound/pci/hda/hda_codec.c
  3. 12 8
      sound/pci/hda/hda_intel.c

+ 5 - 0
Documentation/sound/alsa/HD-Audio.txt

@@ -196,6 +196,11 @@ generic parser regardless of the codec.  Usually the codec-specific
 parser is much better than the generic parser (as now).  Thus this
 parser is much better than the generic parser (as now).  Thus this
 option is more about the debugging purpose.
 option is more about the debugging purpose.
 
 
+Another special meaning has 'model=hwio'. For this model, the driver
+bypasses any codec initialization and the reset procedure for codecs
+is also bypassed. This mode is usefull to enable direct access using
+hwdep interface (using hdaverb or hda-analyzer tools) and retain
+codec setup from BIOS.
 
 
 Speaker and Headphone Output
 Speaker and Headphone Output
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 8 - 2
sound/pci/hda/hda_codec.c

@@ -609,11 +609,15 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
 }
 }
 EXPORT_SYMBOL_HDA(snd_hda_bus_new);
 EXPORT_SYMBOL_HDA(snd_hda_bus_new);
 
 
+#define is_hwio_config(codec) \
+	(codec->modelname && !strcmp(codec->modelname, "hwio"))
 #ifdef CONFIG_SND_HDA_GENERIC
 #ifdef CONFIG_SND_HDA_GENERIC
 #define is_generic_config(codec) \
 #define is_generic_config(codec) \
-	(codec->modelname && !strcmp(codec->modelname, "generic"))
+	((codec->modelname && !strcmp(codec->modelname, "generic")) || \
+	 is_hwio_config(codec))
 #else
 #else
-#define is_generic_config(codec)	0
+#define is_generic_config(codec) \
+	is_hwio_config(codec)
 #endif
 #endif
 
 
 #ifdef MODULE
 #ifdef MODULE
@@ -1113,6 +1117,8 @@ int snd_hda_codec_configure(struct hda_codec *codec)
 	}
 	}
 
 
 	if (is_generic_config(codec)) {
 	if (is_generic_config(codec)) {
+		if (is_hwio_config(codec))
+			goto patched;
 		err = snd_hda_parse_generic_codec(codec);
 		err = snd_hda_parse_generic_codec(codec);
 		goto patched;
 		goto patched;
 	}
 	}

+ 12 - 8
sound/pci/hda/hda_intel.c

@@ -858,10 +858,13 @@ static void azx_power_notify(struct hda_bus *bus);
 #endif
 #endif
 
 
 /* reset codec link */
 /* reset codec link */
-static int azx_reset(struct azx *chip)
+static int azx_reset(struct azx *chip, int full_reset)
 {
 {
 	int count;
 	int count;
 
 
+	if (!full_reset)
+		goto __skip;
+
 	/* clear STATESTS */
 	/* clear STATESTS */
 	azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
 	azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
 
 
@@ -887,6 +890,7 @@ static int azx_reset(struct azx *chip)
 	/* Brent Chartrand said to wait >= 540us for codecs to initialize */
 	/* Brent Chartrand said to wait >= 540us for codecs to initialize */
 	msleep(1);
 	msleep(1);
 
 
+      __skip:
 	/* check to see if controller is ready */
 	/* check to see if controller is ready */
 	if (!azx_readb(chip, GCTL)) {
 	if (!azx_readb(chip, GCTL)) {
 		snd_printd(SFX "azx_reset: controller not ready!\n");
 		snd_printd(SFX "azx_reset: controller not ready!\n");
@@ -998,13 +1002,13 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
 /*
 /*
  * reset and start the controller registers
  * reset and start the controller registers
  */
  */
-static void azx_init_chip(struct azx *chip)
+static void azx_init_chip(struct azx *chip, int full_reset)
 {
 {
 	if (chip->initialized)
 	if (chip->initialized)
 		return;
 		return;
 
 
 	/* reset controller */
 	/* reset controller */
-	azx_reset(chip);
+	azx_reset(chip, full_reset);
 
 
 	/* initialize interrupts */
 	/* initialize interrupts */
 	azx_int_clear(chip);
 	azx_int_clear(chip);
@@ -1348,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
 
 
 	bus->in_reset = 1;
 	bus->in_reset = 1;
 	azx_stop_chip(chip);
 	azx_stop_chip(chip);
-	azx_init_chip(chip);
+	azx_init_chip(chip, 1);
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	if (chip->initialized) {
 	if (chip->initialized) {
 		int i;
 		int i;
@@ -1422,7 +1426,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
 				 * get back to the sanity state.
 				 * get back to the sanity state.
 				 */
 				 */
 				azx_stop_chip(chip);
 				azx_stop_chip(chip);
-				azx_init_chip(chip);
+				azx_init_chip(chip, 1);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2112,7 +2116,7 @@ static void azx_power_notify(struct hda_bus *bus)
 		}
 		}
 	}
 	}
 	if (power_on)
 	if (power_on)
-		azx_init_chip(chip);
+		azx_init_chip(chip, 1);
 	else if (chip->running && power_save_controller &&
 	else if (chip->running && power_save_controller &&
 		 !bus->power_keep_link_on)
 		 !bus->power_keep_link_on)
 		azx_stop_chip(chip);
 		azx_stop_chip(chip);
@@ -2182,7 +2186,7 @@ static int azx_resume(struct pci_dev *pci)
 	azx_init_pci(chip);
 	azx_init_pci(chip);
 
 
 	if (snd_hda_codecs_inuse(chip->bus))
 	if (snd_hda_codecs_inuse(chip->bus))
-		azx_init_chip(chip);
+		azx_init_chip(chip, 1);
 
 
 	snd_hda_resume(chip->bus);
 	snd_hda_resume(chip->bus);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2573,7 +2577,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 
 
 	/* initialize chip */
 	/* initialize chip */
 	azx_init_pci(chip);
 	azx_init_pci(chip);
-	azx_init_chip(chip);
+	azx_init_chip(chip, model[dev] == NULL || strcmp(model[dev], "hwio"));
 
 
 	/* codec detection */
 	/* codec detection */
 	if (!chip->codec_mask) {
 	if (!chip->codec_mask) {