Commit cd508fe58b07499403e806b558c7f15c90442292
1 parent
306ff3e473
Exists in
master
and in
4 other branches
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>
Showing 3 changed files with 25 additions and 10 deletions Side-by-side Diff
Documentation/sound/alsa/HD-Audio.txt
... | ... | @@ -196,6 +196,11 @@ |
196 | 196 | parser is much better than the generic parser (as now). Thus this |
197 | 197 | option is more about the debugging purpose. |
198 | 198 | |
199 | +Another special meaning has 'model=hwio'. For this model, the driver | |
200 | +bypasses any codec initialization and the reset procedure for codecs | |
201 | +is also bypassed. This mode is usefull to enable direct access using | |
202 | +hwdep interface (using hdaverb or hda-analyzer tools) and retain | |
203 | +codec setup from BIOS. | |
199 | 204 | |
200 | 205 | Speaker and Headphone Output |
201 | 206 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
sound/pci/hda/hda_codec.c
... | ... | @@ -609,11 +609,15 @@ |
609 | 609 | } |
610 | 610 | EXPORT_SYMBOL_HDA(snd_hda_bus_new); |
611 | 611 | |
612 | +#define is_hwio_config(codec) \ | |
613 | + (codec->modelname && !strcmp(codec->modelname, "hwio")) | |
612 | 614 | #ifdef CONFIG_SND_HDA_GENERIC |
613 | 615 | #define is_generic_config(codec) \ |
614 | - (codec->modelname && !strcmp(codec->modelname, "generic")) | |
616 | + ((codec->modelname && !strcmp(codec->modelname, "generic")) || \ | |
617 | + is_hwio_config(codec)) | |
615 | 618 | #else |
616 | -#define is_generic_config(codec) 0 | |
619 | +#define is_generic_config(codec) \ | |
620 | + is_hwio_config(codec) | |
617 | 621 | #endif |
618 | 622 | |
619 | 623 | #ifdef MODULE |
... | ... | @@ -1113,6 +1117,8 @@ |
1113 | 1117 | } |
1114 | 1118 | |
1115 | 1119 | if (is_generic_config(codec)) { |
1120 | + if (is_hwio_config(codec)) | |
1121 | + goto patched; | |
1116 | 1122 | err = snd_hda_parse_generic_codec(codec); |
1117 | 1123 | goto patched; |
1118 | 1124 | } |
sound/pci/hda/hda_intel.c
... | ... | @@ -858,10 +858,13 @@ |
858 | 858 | #endif |
859 | 859 | |
860 | 860 | /* reset codec link */ |
861 | -static int azx_reset(struct azx *chip) | |
861 | +static int azx_reset(struct azx *chip, int full_reset) | |
862 | 862 | { |
863 | 863 | int count; |
864 | 864 | |
865 | + if (!full_reset) | |
866 | + goto __skip; | |
867 | + | |
865 | 868 | /* clear STATESTS */ |
866 | 869 | azx_writeb(chip, STATESTS, STATESTS_INT_MASK); |
867 | 870 | |
... | ... | @@ -887,6 +890,7 @@ |
887 | 890 | /* Brent Chartrand said to wait >= 540us for codecs to initialize */ |
888 | 891 | msleep(1); |
889 | 892 | |
893 | + __skip: | |
890 | 894 | /* check to see if controller is ready */ |
891 | 895 | if (!azx_readb(chip, GCTL)) { |
892 | 896 | snd_printd(SFX "azx_reset: controller not ready!\n"); |
893 | 897 | |
... | ... | @@ -998,13 +1002,13 @@ |
998 | 1002 | /* |
999 | 1003 | * reset and start the controller registers |
1000 | 1004 | */ |
1001 | -static void azx_init_chip(struct azx *chip) | |
1005 | +static void azx_init_chip(struct azx *chip, int full_reset) | |
1002 | 1006 | { |
1003 | 1007 | if (chip->initialized) |
1004 | 1008 | return; |
1005 | 1009 | |
1006 | 1010 | /* reset controller */ |
1007 | - azx_reset(chip); | |
1011 | + azx_reset(chip, full_reset); | |
1008 | 1012 | |
1009 | 1013 | /* initialize interrupts */ |
1010 | 1014 | azx_int_clear(chip); |
... | ... | @@ -1348,7 +1352,7 @@ |
1348 | 1352 | |
1349 | 1353 | bus->in_reset = 1; |
1350 | 1354 | azx_stop_chip(chip); |
1351 | - azx_init_chip(chip); | |
1355 | + azx_init_chip(chip, 1); | |
1352 | 1356 | #ifdef CONFIG_PM |
1353 | 1357 | if (chip->initialized) { |
1354 | 1358 | int i; |
... | ... | @@ -1422,7 +1426,7 @@ |
1422 | 1426 | * get back to the sanity state. |
1423 | 1427 | */ |
1424 | 1428 | azx_stop_chip(chip); |
1425 | - azx_init_chip(chip); | |
1429 | + azx_init_chip(chip, 1); | |
1426 | 1430 | } |
1427 | 1431 | } |
1428 | 1432 | } |
... | ... | @@ -2112,7 +2116,7 @@ |
2112 | 2116 | } |
2113 | 2117 | } |
2114 | 2118 | if (power_on) |
2115 | - azx_init_chip(chip); | |
2119 | + azx_init_chip(chip, 1); | |
2116 | 2120 | else if (chip->running && power_save_controller && |
2117 | 2121 | !bus->power_keep_link_on) |
2118 | 2122 | azx_stop_chip(chip); |
... | ... | @@ -2182,7 +2186,7 @@ |
2182 | 2186 | azx_init_pci(chip); |
2183 | 2187 | |
2184 | 2188 | if (snd_hda_codecs_inuse(chip->bus)) |
2185 | - azx_init_chip(chip); | |
2189 | + azx_init_chip(chip, 1); | |
2186 | 2190 | |
2187 | 2191 | snd_hda_resume(chip->bus); |
2188 | 2192 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
... | ... | @@ -2573,7 +2577,7 @@ |
2573 | 2577 | |
2574 | 2578 | /* initialize chip */ |
2575 | 2579 | azx_init_pci(chip); |
2576 | - azx_init_chip(chip); | |
2580 | + azx_init_chip(chip, model[dev] == NULL || strcmp(model[dev], "hwio")); | |
2577 | 2581 | |
2578 | 2582 | /* codec detection */ |
2579 | 2583 | if (!chip->codec_mask) { |