From cd508fe58b07499403e806b558c7f15c90442292 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 26 Mar 2010 10:28:46 +0100 Subject: [PATCH] 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 --- Documentation/sound/alsa/HD-Audio.txt | 5 +++++ sound/pci/hda/hda_codec.c | 10 ++++++++-- sound/pci/hda/hda_intel.c | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt index f4dd3bf99d12..ecacf53a8655 100644 --- a/Documentation/sound/alsa/HD-Audio.txt +++ b/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 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0e76ac2b2ace..cf6280bdaa19 100644 --- a/sound/pci/hda/hda_codec.c +++ b/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); +#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; } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8b2915631cc3..8d477613bccf 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -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) { -- 2.20.1