aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-03-26 10:28:46 +0100
committerJaroslav Kysela <perex@perex.cz>2010-03-26 10:37:39 +0100
commitcd508fe58b07499403e806b558c7f15c90442292 (patch)
tree5ec4c40b7c7b84595c65f5f9dda96e1a01eacc2b
parent306ff3e473a970f88680e8355c0900fcab0357e2 (diff)
downloadlinux-linaro-android-cd508fe58b07499403e806b558c7f15c90442292.tar.gz
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>
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt5
-rw-r--r--sound/pci/hda/hda_codec.c10
-rw-r--r--sound/pci/hda/hda_intel.c20
3 files changed, 25 insertions, 10 deletions
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index f4dd3bf99d1..ecacf53a865 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 0e76ac2b2ac..cf6280bdaa1 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 8b2915631cc..8d477613bcc 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) {