ALSA: hda-intel - add special 'hwio' model to bypass initialization
Jaroslav Kysela [Fri, 26 Mar 2010 09:28:46 +0000 (10:28 +0100)]
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>

Documentation/sound/alsa/HD-Audio.txt
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c

index f4dd3bf..ecacf53 100644 (file)
@@ -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
 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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 0e76ac2..cf6280b 100644 (file)
@@ -609,11 +609,15 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
 }
 EXPORT_SYMBOL_HDA(snd_hda_bus_new);
 
+#define is_hwio_config(codec) \
+       (codec->modelname && !strcmp(codec->modelname, "hwio"))
 #ifdef CONFIG_SND_HDA_GENERIC
 #define is_generic_config(codec) \
-       (codec->modelname && !strcmp(codec->modelname, "generic"))
+       ((codec->modelname && !strcmp(codec->modelname, "generic")) || \
+        is_hwio_config(codec))
 #else
-#define is_generic_config(codec)       0
+#define is_generic_config(codec) \
+       is_hwio_config(codec)
 #endif
 
 #ifdef MODULE
@@ -1113,6 +1117,8 @@ int snd_hda_codec_configure(struct hda_codec *codec)
        }
 
        if (is_generic_config(codec)) {
+               if (is_hwio_config(codec))
+                       goto patched;
                err = snd_hda_parse_generic_codec(codec);
                goto patched;
        }
index 8b29156..8d47761 100644 (file)
@@ -858,10 +858,13 @@ static void azx_power_notify(struct hda_bus *bus);
 #endif
 
 /* reset codec link */
-static int azx_reset(struct azx *chip)
+static int azx_reset(struct azx *chip, int full_reset)
 {
        int count;
 
+       if (!full_reset)
+               goto __skip;
+
        /* clear STATESTS */
        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 */
        msleep(1);
 
+      __skip:
        /* check to see if controller is ready */
        if (!azx_readb(chip, GCTL)) {
                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
  */
-static void azx_init_chip(struct azx *chip)
+static void azx_init_chip(struct azx *chip, int full_reset)
 {
        if (chip->initialized)
                return;
 
        /* reset controller */
-       azx_reset(chip);
+       azx_reset(chip, full_reset);
 
        /* initialize interrupts */
        azx_int_clear(chip);
@@ -1348,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
 
        bus->in_reset = 1;
        azx_stop_chip(chip);
-       azx_init_chip(chip);
+       azx_init_chip(chip, 1);
 #ifdef CONFIG_PM
        if (chip->initialized) {
                int i;
@@ -1422,7 +1426,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
                                 * get back to the sanity state.
                                 */
                                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)
-               azx_init_chip(chip);
+               azx_init_chip(chip, 1);
        else if (chip->running && power_save_controller &&
                 !bus->power_keep_link_on)
                azx_stop_chip(chip);
@@ -2182,7 +2186,7 @@ static int azx_resume(struct pci_dev *pci)
        azx_init_pci(chip);
 
        if (snd_hda_codecs_inuse(chip->bus))
-               azx_init_chip(chip);
+               azx_init_chip(chip, 1);
 
        snd_hda_resume(chip->bus);
        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 */
        azx_init_pci(chip);
-       azx_init_chip(chip);
+       azx_init_chip(chip, model[dev] == NULL || strcmp(model[dev], "hwio"));
 
        /* codec detection */
        if (!chip->codec_mask) {