[alsa-devel] patch for Dell 1210 which using stac9221 codec
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla, I wrote a patch and the reporter helped me to test it on his machine. It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with jack-sensing.
diff -Nur a/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-17 08:00:08.000000000 +0800 +++ b/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-17 17:07:27.000000000 +0800 @@ -171,6 +171,10 @@ 0x02, };
+static hda_nid_t dell_m82_1210_dac_nids[3] = { + 0x02, 0x05, 0x03, +}; + static hda_nid_t stac925x_adc_nids[1] = { 0x03, }; @@ -874,10 +878,10 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = { - 0x0221121f, 0x408103ff, 0x02111212, 0x90100310, - 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2, + 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, + 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4, -}; +};
static unsigned int d945gtp3_pin_configs[10] = { 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, @@ -1512,6 +1516,15 @@ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); }
+static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, + unsigned int event) +{ + if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | event)); +} + #define stac92xx_io_switch_info snd_ctl_boolean_mono_info
static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1542,6 +1555,18 @@ pinctl |= stac92xx_get_vref(codec, nid); stac92xx_auto_set_pinctl(codec, nid, pinctl); } + + if (spec->board_config == STAC_922X_DELL_M82) { + if (val) { + /*If front mic serves as output,let it mute the internal speaker*/ + spec->autocfg.hp_outs = 3; + spec->autocfg.hp_pins[2] = 0x0c; + enable_pin_detect(codec, 0x0c, STAC_HP_EVENT); + } else { + spec->autocfg.hp_outs = 2; + } + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + } return 1; }
@@ -1811,9 +1836,15 @@
struct sigmatel_spec *spec = codec->spec; unsigned int wid_caps; + int max_controls;
+ if (spec->board_config == STAC_922X_DELL_M82) { + max_controls = spec->multiout.num_dacs; + } else { + max_controls = cfg->line_outs; + }
- for (i = 0; i < cfg->line_outs; i++) { + for (i = 0; i < max_controls; i++) { if (!spec->multiout.dac_nids[i]) continue;
@@ -2268,15 +2299,6 @@ AC_VERB_SET_GPIO_DATA, gpiostate); }
-static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, - unsigned int event) -{ - if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - (AC_USRSP_EN | event)); -} - static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -2677,6 +2699,11 @@
spec->multiout.dac_nids = spec->dac_nids; + if (spec->board_config == STAC_922X_DELL_M82) { + spec->multiout.num_dacs = 3; + spec->multiout.dac_nids = dell_m82_1210_dac_nids; + } + err = stac92xx_parse_auto_config(codec, 0x08, 0x09); if (!err) { if (spec->board_config < 0) { @@ -2687,6 +2714,14 @@ } err = -EINVAL; } + + if ((err >= 0) && (spec->board_config == STAC_922X_DELL_M82)) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Front Mic as Output Switch", (spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC] << 8) | 1); + /*In case that add_controls realloc the spec->kctl_alloc*/ + if ((err >= 0) && (spec->kctl_alloc != spec->mixers[spec->num_mixers - 1])) + spec->mixers[spec->num_mixers - 1] = spec->kctl_alloc; + } + if (err < 0) { stac92xx_free(codec); return err;
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
I wrote a patch and the reporter helped me to test it on his machine. It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level. I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :)
Takashi
diff -Nur a/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-17 08:00:08.000000000 +0800 +++ b/alsa-driver-hg20071017/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-17 17:07:27.000000000 +0800 @@ -171,6 +171,10 @@ 0x02, };
+static hda_nid_t dell_m82_1210_dac_nids[3] = {
0x02, 0x05, 0x03,
+};
static hda_nid_t stac925x_adc_nids[1] = { 0x03, }; @@ -874,10 +878,10 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
- 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
- 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
- 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
- 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
-}; +};
static unsigned int d945gtp3_pin_configs[10] = { 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, @@ -1512,6 +1516,15 @@ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); }
+static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
unsigned int event)
+{
- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
(AC_USRSP_EN | event));
+}
#define stac92xx_io_switch_info snd_ctl_boolean_mono_info
static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1542,6 +1555,18 @@ pinctl |= stac92xx_get_vref(codec, nid); stac92xx_auto_set_pinctl(codec, nid, pinctl); }
- if (spec->board_config == STAC_922X_DELL_M82) {
if (val) {
/*If front mic serves as output,let it mute the internal speaker*/
spec->autocfg.hp_outs = 3;
spec->autocfg.hp_pins[2] = 0x0c;
enable_pin_detect(codec, 0x0c, STAC_HP_EVENT);
} else {
spec->autocfg.hp_outs = 2;
}
codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
- } return 1;
}
@@ -1811,9 +1836,15 @@
struct sigmatel_spec *spec = codec->spec; unsigned int wid_caps;
int max_controls;
if (spec->board_config == STAC_922X_DELL_M82) {
max_controls = spec->multiout.num_dacs;
} else {
max_controls = cfg->line_outs;
}
- for (i = 0; i < cfg->line_outs; i++) {
- for (i = 0; i < max_controls; i++) { if (!spec->multiout.dac_nids[i]) continue;
@@ -2268,15 +2299,6 @@ AC_VERB_SET_GPIO_DATA, gpiostate); }
-static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
unsigned int event)
-{
- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
(AC_USRSP_EN | event));
-}
static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -2677,6 +2699,11 @@
spec->multiout.dac_nids = spec->dac_nids;
- if (spec->board_config == STAC_922X_DELL_M82) {
spec->multiout.num_dacs = 3;
spec->multiout.dac_nids = dell_m82_1210_dac_nids;
- }
- err = stac92xx_parse_auto_config(codec, 0x08, 0x09); if (!err) { if (spec->board_config < 0) {
@@ -2687,6 +2714,14 @@ } err = -EINVAL; }
- if ((err >= 0) && (spec->board_config == STAC_922X_DELL_M82)) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Front
Mic as Output Switch", (spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC] << 8) | 1);
/*In case that add_controls realloc the spec->kctl_alloc*/
if ((err >= 0) && (spec->kctl_alloc != spec->mixers[spec->num_mixers
- 1]))
spec->mixers[spec->num_mixers - 1] = spec->kctl_alloc;
- }
- if (err < 0) { stac92xx_free(codec); return err;
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
I wrote a patch and the reporter helped me to test it on his
machine.
It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with
jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
I would like to try to do it.
At Fri, 19 Oct 2007 14:02:43 +0800, zhejiang wrote:
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
OK, good to hear.
I wrote a patch and the reporter helped me to test it on his
machine.
It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with
jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
This sounds good.
Does Dell 1210 have both front and rear mic jacks? I don't know of this machine, so it'd be helpful to understand if you describe the available I/O (PINs and jacks) and expected behavior briefly here. Since sigmatel patch uses the single detection code for every device, we need to cover all possible scenarios with different I/O mappings.
Thanks,
Takashi
On Fri, 2007-10-19 at 07:38 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 14:02:43 +0800, zhejiang wrote:
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
OK, good to hear.
I wrote a patch and the reporter helped me to test it on his
machine.
It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with
jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
This sounds good.
Does Dell 1210 have both front and rear mic jacks? I don't know of this machine, so it'd be helpful to understand if you describe the available I/O (PINs and jacks) and expected behavior briefly here. Since sigmatel patch uses the single detection code for every device, we need to cover all possible scenarios with different I/O mappings.
Dell 1210 doesn't have rear mic jacks. There are three jacks in the front : "Headphone","Headphone","Microphone". According to the spec,the mic need to work as output to support 6 channels mode.
Here is the picture of the jacks: http://www.notebookreview.com/assets/12583.jpg
Thanks,
Takashi
At Fri, 19 Oct 2007 15:42:09 +0800, zhejiang wrote:
On Fri, 2007-10-19 at 07:38 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 14:02:43 +0800, zhejiang wrote:
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
OK, good to hear.
I wrote a patch and the reporter helped me to test it on his
machine.
It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with
jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
This sounds good.
Does Dell 1210 have both front and rear mic jacks? I don't know of this machine, so it'd be helpful to understand if you describe the available I/O (PINs and jacks) and expected behavior briefly here. Since sigmatel patch uses the single detection code for every device, we need to cover all possible scenarios with different I/O mappings.
Dell 1210 doesn't have rear mic jacks. There are three jacks in the front : "Headphone","Headphone","Microphone". According to the spec,the mic need to work as output to support 6 channels mode.
Here is the picture of the jacks: http://www.notebookreview.com/assets/12583.jpg
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
Looking through the sigmatel code, we have several known use cases:
1. desktop 1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
2. laptop 2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
So, above all, a bit more cleaner implementation would be preferred...
Takashi
On Fri, 2007-10-19 at 10:39 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 15:42:09 +0800, zhejiang wrote:
On Fri, 2007-10-19 at 07:38 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 14:02:43 +0800, zhejiang wrote:
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote:
Hi,
Dell 1210 have three jacks on the front. Two of them serve as output jack and one serve as microphone. The microphone can be switched to output model too.
There are some problems with current dell 1210 driver: 1.Unable to use the front microphone 2.Unable to switch the microphone 3.If plug the left hp,another hp will be muted,so it's impossible to work as 6-channel
According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
OK, good to hear.
I wrote a patch and the reporter helped me to test it on his
machine.
It can support the front microphone. When switch the microphone to output model, it can mute/unmute the internal speaker with
jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
This sounds good.
Does Dell 1210 have both front and rear mic jacks? I don't know of this machine, so it'd be helpful to understand if you describe the available I/O (PINs and jacks) and expected behavior briefly here. Since sigmatel patch uses the single detection code for every device, we need to cover all possible scenarios with different I/O mappings.
Dell 1210 doesn't have rear mic jacks. There are three jacks in the front : "Headphone","Headphone","Microphone". According to the spec,the mic need to work as output to support 6 channels mode.
Here is the picture of the jacks: http://www.notebookreview.com/assets/12583.jpg
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Looking through the sigmatel code, we have several known use cases:
- desktop
1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
- laptop
2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
The call graph of stac92xx_parse_auto_config() :
1.snd_hda_parse_pin_def_config()
2.stac92xx_add_dyn_out_pins() It check the cfg->line_outs and input_pins[] to add dynamic lineouts.
3.stac92xx_auto_fill_dac_nids() It only fills the dac_nids from the cfg->line_out_pins[],
4.stac92xx_auto_create_multi_out_ctls() It add controls according to the cfg->line_outs.
we can see that they heavily depend on the line_outs[] info.
How about this method?
In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then we switch the cfg->hp_pins[] with cfg->line_out_pins[]. The 2,3,4 may work without change. At the end of the stac92xx_parse_auto_config(),we restore the cfg->hp_pins[] and cfg->line_out_pins[].
Another things to change : 1.snd_hda_parse_pin_def_config() Should sort the hp_pins[] by sequence. 2.stac92xx_auto_fill_dac_nids() Support the "Front Mic" switch as well. 3.stac92xx_io_switch_put() If Mic work as output for laptop,enable pin detect too.
Does it make sense?
So, above all, a bit more cleaner implementation would be preferred...
Takashi
At Mon, 22 Oct 2007 14:08:19 +0800, zhejiang wrote:
On Fri, 2007-10-19 at 10:39 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 15:42:09 +0800, zhejiang wrote:
On Fri, 2007-10-19 at 07:38 +0200, Takashi Iwai wrote:
At Fri, 19 Oct 2007 14:02:43 +0800, zhejiang wrote:
On Thu, 2007-10-18 at 22:55 +0800, Takashi Iwai wrote:
At Thu, 18 Oct 2007 10:49:16 +0800, zhejiang wrote: > > Hi, > > Dell 1210 have three jacks on the front. > Two of them serve as output jack and one serve as microphone. > The microphone can be switched to output model too. > > There are some problems with current dell 1210 driver: > 1.Unable to use the front microphone > 2.Unable to switch the microphone > 3.If plug the left hp,another hp will be muted,so it's impossible to > work as 6-channel > > According to the issue 0003427 on alsa-bugzilla,
Oops is bad. Does it still happen with the latest HG tree? This should be fixed urgently at first.
The oops won't happen with the latest HG tree. The reason of the oops is that there is no input pin.
Now the snd_hda_input_mux_put() will check the input_mux.num_items, if it is equal to zero,snd_hda_input_mux_put() will return directly and avoid the oops.
OK, good to hear.
> I wrote a patch and the reporter helped me to test it on his machine. > It can support the front microphone. When switch the microphone to > output model, it can mute/unmute the internal speaker with jack-sensing.
Thanks for the patch. I have little time right now for checking in details, but the changes appear in fairly deep level.
Yes,It's hard to support such kind of machine with current stac92xx_parse_auto_config().So my patch changed so many generic functions. :-).
I think we should rather fix the current code to handle multiple headphones better than the ad-hoc fixes. Surely there will be other models that require similar fixes (if you see Dell has shipped how many different variants :) Takashi
Great! I think this model should support: 1.Each headphone can mute the internal speaker. 2.Even the Front mic can work output jack 3.When mic works as output jack,it can mute the internal speaker too.
Does this make sense? Thanks!
This sounds good.
Does Dell 1210 have both front and rear mic jacks? I don't know of this machine, so it'd be helpful to understand if you describe the available I/O (PINs and jacks) and expected behavior briefly here. Since sigmatel patch uses the single detection code for every device, we need to cover all possible scenarios with different I/O mappings.
Dell 1210 doesn't have rear mic jacks. There are three jacks in the front : "Headphone","Headphone","Microphone". According to the spec,the mic need to work as output to support 6 channels mode.
Here is the picture of the jacks: http://www.notebookreview.com/assets/12583.jpg
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Thanks.
Looking through the sigmatel code, we have several known use cases:
- desktop
1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
- laptop
2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
The call graph of stac92xx_parse_auto_config() :
1.snd_hda_parse_pin_def_config()
2.stac92xx_add_dyn_out_pins() It check the cfg->line_outs and input_pins[] to add dynamic lineouts.
3.stac92xx_auto_fill_dac_nids() It only fills the dac_nids from the cfg->line_out_pins[],
4.stac92xx_auto_create_multi_out_ctls() It add controls according to the cfg->line_outs.
we can see that they heavily depend on the line_outs[] info.
How about this method?
In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then we switch the cfg->hp_pins[] with cfg->line_out_pins[].
Maybe better to check cfg->line_out_type. I guess it's AUTO_PIN_SPEAKER_OUT in the case of this Dell laptop. The driver takes speaker in prior to headphone as the primary line-out.
The 2,3,4 may work without change. At the end of the stac92xx_parse_auto_config(),we restore the cfg->hp_pins[] and cfg->line_out_pins[].
Alternatively, instead of saving/restoring informatoin, we can fix snd_hda_parse_pin_def_config() itself to check cfg->hp_outs and cfg->speaker_outs to determine the primary output. If one of them is greater, take it as the primary output. It's less hackish but *might* cause some regression in rare cases.
Another things to change : 1.snd_hda_parse_pin_def_config() Should sort the hp_pins[] by sequence.
Yeah, just missing right now.
2.stac92xx_auto_fill_dac_nids() Support the "Front Mic" switch as well. 3.stac92xx_io_switch_put() If Mic work as output for laptop,enable pin detect too.
Well, I think the better fix is to fix the "Front Mic". If there is only a front mic, it should be basically labelled as "Mic" because it's the only one. So, again, snd_hda_parse_pin_def_config(), we can reassign input_pins[AUTO_PIN_FRONT_MIC] to input_pins[AUTO_PIN_MIC] if there is only one mic. Then the rest wouldn't need changes.
Of course, another question is what to do when we have both rear and front mic and if we still want to handle them as outputs. Well, we have no such hardware yet, though.
thanks,
Takashi
On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote:
At Mon, 22 Oct 2007 14:08:19 +0800, zhejiang wrote:
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Thanks.
According to the response from the reporter,here is the pin config of the original driver.
ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: hp_outs=1 (0xa/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0)
Looking through the sigmatel code, we have several known use cases:
- desktop
1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
- laptop
2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
The call graph of stac92xx_parse_auto_config() :
1.snd_hda_parse_pin_def_config()
2.stac92xx_add_dyn_out_pins() It check the cfg->line_outs and input_pins[] to add dynamic lineouts.
3.stac92xx_auto_fill_dac_nids() It only fills the dac_nids from the cfg->line_out_pins[],
4.stac92xx_auto_create_multi_out_ctls() It add controls according to the cfg->line_outs.
we can see that they heavily depend on the line_outs[] info.
How about this method?
In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then we switch the cfg->hp_pins[] with cfg->line_out_pins[].
Maybe better to check cfg->line_out_type. I guess it's AUTO_PIN_SPEAKER_OUT in the case of this Dell laptop. The driver takes speaker in prior to headphone as the primary line-out.
The 2,3,4 may work without change. At the end of the stac92xx_parse_auto_config(),we restore the cfg->hp_pins[] and cfg->line_out_pins[].
Alternatively, instead of saving/restoring informatoin, we can fix snd_hda_parse_pin_def_config() itself to check cfg->hp_outs and cfg->speaker_outs to determine the primary output. If one of them is greater, take it as the primary output. It's less hackish but *might* cause some regression in rare cases.
I think that we need to restore the cfg->hp_pins and cfg->line_out_pins for the rest code,because:
1. stac92xx_auto_init_hp_out() need to use the hp_pins to enable the AC_PINCTL_HP_EN 2. stac92xx_hp_detect() need to use the hp_outs to detect jack presense and will disable line_out_pins and speaker_pins. 3. stac92xx_init() use the hp_pins to enable unsolicited response.
If we copy cfg->hp_outs to the line_out_pins, all these codes won't work. ^-^
Another things to change : 1.snd_hda_parse_pin_def_config() Should sort the hp_pins[] by sequence.
Yeah, just missing right now.
2.stac92xx_auto_fill_dac_nids() Support the "Front Mic" switch as well. 3.stac92xx_io_switch_put() If Mic work as output for laptop,enable pin detect too.
Well, I think the better fix is to fix the "Front Mic". If there is only a front mic, it should be basically labelled as "Mic" because it's the only one. So, again, snd_hda_parse_pin_def_config(), we can reassign input_pins[AUTO_PIN_FRONT_MIC] to input_pins[AUTO_PIN_MIC] if there is only one mic. Then the rest wouldn't need changes.
Great.
Of course, another question is what to do when we have both rear and front mic and if we still want to handle them as outputs. Well, we have no such hardware yet, though.
thanks,
Takashi
At Thu, 25 Oct 2007 15:44:42 +0800, zhejiang wrote:
On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote:
At Mon, 22 Oct 2007 14:08:19 +0800, zhejiang wrote:
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Thanks.
According to the response from the reporter,here is the pin config of the original driver.
ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: hp_outs=1 (0xa/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0)
Interesting. Then the driver seems probing a fairly wrong pin mapping. So obviously the PCI SSID table entry for this laptop isn't correct.
Looking through the sigmatel code, we have several known use cases:
- desktop
1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
- laptop
2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
The call graph of stac92xx_parse_auto_config() :
1.snd_hda_parse_pin_def_config()
2.stac92xx_add_dyn_out_pins() It check the cfg->line_outs and input_pins[] to add dynamic lineouts.
3.stac92xx_auto_fill_dac_nids() It only fills the dac_nids from the cfg->line_out_pins[],
4.stac92xx_auto_create_multi_out_ctls() It add controls according to the cfg->line_outs.
we can see that they heavily depend on the line_outs[] info.
How about this method?
In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then we switch the cfg->hp_pins[] with cfg->line_out_pins[].
Maybe better to check cfg->line_out_type. I guess it's AUTO_PIN_SPEAKER_OUT in the case of this Dell laptop. The driver takes speaker in prior to headphone as the primary line-out.
The 2,3,4 may work without change. At the end of the stac92xx_parse_auto_config(),we restore the cfg->hp_pins[] and cfg->line_out_pins[].
Alternatively, instead of saving/restoring informatoin, we can fix snd_hda_parse_pin_def_config() itself to check cfg->hp_outs and cfg->speaker_outs to determine the primary output. If one of them is greater, take it as the primary output. It's less hackish but *might* cause some regression in rare cases.
I think that we need to restore the cfg->hp_pins and cfg->line_out_pins for the rest code,because:
- stac92xx_auto_init_hp_out() need to use the hp_pins to enable the
AC_PINCTL_HP_EN
stac92xx_auto_init_multi_out() should check line_out_type and sets HP_EN appropriatley, too.
- stac92xx_hp_detect() need to use the hp_outs to detect jack presense and will disable line_out_pins and speaker_pins.
- stac92xx_init() use the hp_pins to enable unsolicited response.
Hm, these are nasty, indeed.
OK, what about the patch below? It doesn't change the pincfg, so it wouldn't work as is, though.
Takashi
diff -r 09088524dd7f pci/hda/hda_codec.c --- a/pci/hda/hda_codec.c Thu Oct 25 11:46:24 2007 +0200 +++ b/pci/hda/hda_codec.c Thu Oct 25 12:42:00 2007 +0200 @@ -2600,11 +2600,13 @@ int snd_hda_parse_pin_def_config(struct short seq, assoc_line_out, assoc_speaker; short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; + short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
memset(cfg, 0, sizeof(*cfg));
memset(sequences_line_out, 0, sizeof(sequences_line_out)); memset(sequences_speaker, 0, sizeof(sequences_speaker)); + memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = assoc_speaker = 0;
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); @@ -2659,9 +2661,12 @@ int snd_hda_parse_pin_def_config(struct cfg->speaker_outs++; break; case AC_JACK_HP_OUT: + seq = get_defcfg_sequence(def_conf); + assoc = get_defcfg_association(def_conf); if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) continue; cfg->hp_pins[cfg->hp_outs] = nid; + sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; cfg->hp_outs++; break; case AC_JACK_MIC_IN: { @@ -2705,7 +2710,24 @@ int snd_hda_parse_pin_def_config(struct cfg->line_outs); sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, cfg->speaker_outs); + sort_pins_by_sequence(cfg->hp_pins, sequences_hp, + cfg->hp_outs); + /* if we have only one mic, make it AUTO_PIN_MIC */ + if (!cfg->input_pins[AUTO_PIN_MIC] && + cfg->input_pins[AUTO_PIN_FRONT_MIC]) { + cfg->input_pins[AUTO_PIN_MIC] = + cfg->input_pins[AUTO_PIN_FRONT_MIC]; + cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0; + } + /* ditto for line-in */ + if (!cfg->input_pins[AUTO_PIN_LINE] && + cfg->input_pins[AUTO_PIN_FRONT_LINE]) { + cfg->input_pins[AUTO_PIN_LINE] = + cfg->input_pins[AUTO_PIN_FRONT_LINE]; + cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0; + } + /* * FIX-UP: if no line-outs are detected, try to use speaker or HP pin * as a primary output diff -r 09088524dd7f pci/hda/patch_sigmatel.c --- a/pci/hda/patch_sigmatel.c Thu Oct 25 11:46:24 2007 +0200 +++ b/pci/hda/patch_sigmatel.c Thu Oct 25 12:42:00 2007 +0200 @@ -1649,12 +1649,14 @@ static int stac92xx_add_control(struct s }
/* flag inputs as additional dynamic lineouts */ -static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) +static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, + struct auto_pin_cfg *cfg, + int line_outs, hda_nid_t *line_out_pins) { struct sigmatel_spec *spec = codec->spec; unsigned int wcaps, wtype; int i, num_dacs = 0; - + /* use the wcaps cache to count all DACs available for line-outs */ for (i = 0; i < codec->num_nodes; i++) { wcaps = codec->wcaps[i]; @@ -1665,49 +1667,48 @@ static int stac92xx_add_dyn_out_pins(str
snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); - switch (cfg->line_outs) { + switch (line_outs) { case 3: /* add line-in as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { - cfg->line_out_pins[cfg->line_outs] = + line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; - cfg->line_outs++; + line_outs++; } break; case 2: /* add line-in as clfe and mic as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { - cfg->line_out_pins[cfg->line_outs] = + line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; - cfg->line_outs++; + line_outs++; } if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { - cfg->line_out_pins[cfg->line_outs] = + line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; - cfg->line_outs++; + line_outs++; } break; case 1: /* add line-in as surr and mic as clfe */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { - cfg->line_out_pins[cfg->line_outs] = + line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; - cfg->line_outs++; + line_outs++; } if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { - cfg->line_out_pins[cfg->line_outs] = + line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; - cfg->line_outs++; + line_outs++; } break; } - - return 0; + return line_outs; }
@@ -1731,15 +1732,16 @@ static int is_in_dac_nids(struct sigmate * and 9202/925x. For those, dac_nids[] must be hard-coded. */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, - struct auto_pin_cfg *cfg) + struct auto_pin_cfg *cfg, + int line_outs, hda_nid_t *line_out_pins) { struct sigmatel_spec *spec = codec->spec; int i, j, conn_len = 0; hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; unsigned int wcaps, wtype; - for (i = 0; i < cfg->line_outs; i++) { - nid = cfg->line_out_pins[i]; + for (i = 0; i < line_outs; i++) { + nid = line_out_pins[i]; conn_len = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); for (j = 0; j < conn_len; j++) { @@ -1760,7 +1762,7 @@ static int stac92xx_auto_fill_dac_nids(s /* we have already working output pins, * so let's drop the broken ones again */ - cfg->line_outs = spec->multiout.num_dacs; + line_outs = spec->multiout.num_dacs; break; } /* error out, no available DAC found */ @@ -1787,7 +1789,8 @@ static int stac92xx_auto_fill_dac_nids(s spec->multiout.dac_nids[2], spec->multiout.dac_nids[3], spec->multiout.dac_nids[4]); - return 0; + + return line_outs; }
/* create volume control/switch for the given prefx type */ @@ -2087,6 +2090,8 @@ static int stac92xx_parse_auto_config(st static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) { struct sigmatel_spec *spec = codec->spec; + int line_outs, *line_out_p; + hda_nid_t *line_out_pins; int err;
if ((err = snd_hda_parse_pin_def_config(codec, @@ -2096,11 +2101,32 @@ static int stac92xx_parse_auto_config(st if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
- if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) + /* if we have multiple headphones and no line-outs, + * let's set up headphones as primary outputs and allow + * surround outputs + */ + if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && + spec->autocfg.hp_outs > 1) { + line_out_p = &spec->autocfg.hp_outs; + line_out_pins = spec->autocfg.hp_pins; + } else { + line_out_p = &spec->autocfg.line_outs; + line_out_pins = spec->autocfg.line_out_pins; + } + line_outs = *line_out_p; + err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg, + line_outs, line_out_pins); + if (err < 0) return err; - if (spec->multiout.num_dacs == 0) - if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) + line_outs = err; + if (spec->multiout.num_dacs == 0) { + err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg, + line_outs, line_out_pins); + if (err < 0) return err; + line_outs = err; + } + *line_out_p = line_outs; /* store back to autocfg */
err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
On Thu, 2007-10-25 at 11:07 +0200, Takashi Iwai wrote:
At Thu, 25 Oct 2007 15:44:42 +0800, zhejiang wrote:
On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote:
At Mon, 22 Oct 2007 14:08:19 +0800, zhejiang wrote:
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Thanks.
According to the response from the reporter,here is the pin config of the original driver.
ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: hp_outs=1 (0xa/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0)
Interesting. Then the driver seems probing a fairly wrong pin mapping. So obviously the PCI SSID table entry for this laptop isn't correct.
OK, what about the patch below? It doesn't change the pincfg, so it wouldn't work as is, though.
Takashi
diff -r 09088524dd7f pci/hda/hda_codec.c --- a/pci/hda/hda_codec.c Thu Oct 25 11:46:24 2007 +0200 +++ b/pci/hda/hda_codec.c Thu Oct 25 12:42:00 2007 +0200 @@ -2600,11 +2600,13 @@ int snd_hda_parse_pin_def_config(struct short seq, assoc_line_out, assoc_speaker; short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
memset(cfg, 0, sizeof(*cfg));
memset(sequences_line_out, 0, sizeof(sequences_line_out)); memset(sequences_speaker, 0, sizeof(sequences_speaker));
memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = assoc_speaker = 0;
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
@@ -2659,9 +2661,12 @@ int snd_hda_parse_pin_def_config(struct cfg->speaker_outs++; break; case AC_JACK_HP_OUT:
seq = get_defcfg_sequence(def_conf);
assoc = get_defcfg_association(def_conf); if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) continue; cfg->hp_pins[cfg->hp_outs] = nid;
case AC_JACK_MIC_IN: {sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; cfg->hp_outs++; break;
@@ -2705,7 +2710,24 @@ int snd_hda_parse_pin_def_config(struct cfg->line_outs); sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, cfg->speaker_outs);
sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
cfg->hp_outs);
/* if we have only one mic, make it AUTO_PIN_MIC */
if (!cfg->input_pins[AUTO_PIN_MIC] &&
cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
cfg->input_pins[AUTO_PIN_MIC] =
cfg->input_pins[AUTO_PIN_FRONT_MIC];
cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0;
}
/* ditto for line-in */
if (!cfg->input_pins[AUTO_PIN_LINE] &&
cfg->input_pins[AUTO_PIN_FRONT_LINE]) {
cfg->input_pins[AUTO_PIN_LINE] =
cfg->input_pins[AUTO_PIN_FRONT_LINE];
cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0;
}
/*
- FIX-UP: if no line-outs are detected, try to use speaker or HP pin
- as a primary output
diff -r 09088524dd7f pci/hda/patch_sigmatel.c --- a/pci/hda/patch_sigmatel.c Thu Oct 25 11:46:24 2007 +0200 +++ b/pci/hda/patch_sigmatel.c Thu Oct 25 12:42:00 2007 +0200 @@ -1649,12 +1649,14 @@ static int stac92xx_add_control(struct s }
/* flag inputs as additional dynamic lineouts */ -static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) +static int stac92xx_add_dyn_out_pins(struct hda_codec *codec,
struct auto_pin_cfg *cfg,
int line_outs, hda_nid_t *line_out_pins)
{ struct sigmatel_spec *spec = codec->spec; unsigned int wcaps, wtype; int i, num_dacs = 0;
- /* use the wcaps cache to count all DACs available for line-outs */ for (i = 0; i < codec->num_nodes; i++) { wcaps = codec->wcaps[i];
@@ -1665,49 +1667,48 @@ static int stac92xx_add_dyn_out_pins(str
snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
- switch (cfg->line_outs) {
- switch (line_outs) { case 3: /* add line-in as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
cfg->line_out_pins[cfg->line_outs] =
line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1;
cfg->line_outs++;
} break; case 2: /* add line-in as clfe and mic as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {line_outs++;
cfg->line_out_pins[cfg->line_outs] =
line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1;
cfg->line_outs++;
} if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {line_outs++;
cfg->line_out_pins[cfg->line_outs] =
line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1;
cfg->line_outs++;
} break; case 1: /* add line-in as surr and mic as clfe */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {line_outs++;
cfg->line_out_pins[cfg->line_outs] =
line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1;
cfg->line_outs++;
} if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {line_outs++;
cfg->line_out_pins[cfg->line_outs] =
line_out_pins[line_outs] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1;
cfg->line_outs++;
} break; }line_outs++;
- return 0;
- return line_outs;
}
@@ -1731,15 +1732,16 @@ static int is_in_dac_nids(struct sigmate
- and 9202/925x. For those, dac_nids[] must be hard-coded.
*/ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
struct auto_pin_cfg *cfg)
struct auto_pin_cfg *cfg,
int line_outs, hda_nid_t *line_out_pins)
{ struct sigmatel_spec *spec = codec->spec; int i, j, conn_len = 0; hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; unsigned int wcaps, wtype;
- for (i = 0; i < cfg->line_outs; i++) {
nid = cfg->line_out_pins[i];
- for (i = 0; i < line_outs; i++) {
conn_len = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); for (j = 0; j < conn_len; j++) {nid = line_out_pins[i];
@@ -1760,7 +1762,7 @@ static int stac92xx_auto_fill_dac_nids(s /* we have already working output pins, * so let's drop the broken ones again */
cfg->line_outs = spec->multiout.num_dacs;
line_outs = spec->multiout.num_dacs; break; } /* error out, no available DAC found */
@@ -1787,7 +1789,8 @@ static int stac92xx_auto_fill_dac_nids(s spec->multiout.dac_nids[2], spec->multiout.dac_nids[3], spec->multiout.dac_nids[4]);
- return 0;
- return line_outs;
}
/* create volume control/switch for the given prefx type */ @@ -2087,6 +2090,8 @@ static int stac92xx_parse_auto_config(st static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) { struct sigmatel_spec *spec = codec->spec;
int line_outs, *line_out_p;
hda_nid_t *line_out_pins; int err;
if ((err = snd_hda_parse_pin_def_config(codec,
@@ -2096,11 +2101,32 @@ static int stac92xx_parse_auto_config(st if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
- if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
- /* if we have multiple headphones and no line-outs,
* let's set up headphones as primary outputs and allow
* surround outputs
*/
- if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
line_out_p = &spec->autocfg.hp_outs;
line_out_pins = spec->autocfg.hp_pins;
- } else {
line_out_p = &spec->autocfg.line_outs;
line_out_pins = spec->autocfg.line_out_pins;
- }
- line_outs = *line_out_p;
- err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg,
line_outs, line_out_pins);
- if (err < 0) return err;
- if (spec->multiout.num_dacs == 0)
if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
line_outs = err;
if (spec->multiout.num_dacs == 0) {
err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg,
line_outs, line_out_pins);
if (err < 0) return err;
line_outs = err;
}
*line_out_p = line_outs; /* store back to autocfg */
err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs.
Thanks!
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs.
Right, then it might be actually easier to swap line_outs and hp_outs before and after as you suggested...
Takashi
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs.
Right, then it might be actually easier to swap line_outs and hp_outs before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Thanks!
diff -Nur a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = { - 0x0221121f, 0x408103ff, 0x02111212, 0x90100310, - 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2, + 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, + 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4, };
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err; + int hp_speaker_swap = 0;
if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, @@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
+ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && + spec->autocfg.hp_outs > 1) { + /*Copy hp_outs to line_outs, backup line_outs in speaker_outs*/ + memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, + sizeof(spec->autocfg.line_out_pins)); + spec->autocfg.speaker_outs = spec->autocfg.line_outs; + memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, + sizeof(spec->autocfg.hp_pins)); + spec->autocfg.line_outs = spec->autocfg.hp_outs; + hp_speaker_swap = 1; + } + if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) return err; if (spec->multiout.num_dacs == 0) @@ -2107,6 +2120,18 @@ if (err < 0) return err;
+ if (hp_speaker_swap == 1) { + /*Restore the hp_outs and line_outs*/ + memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, + sizeof(spec->autocfg.line_out_pins)); + spec->autocfg.hp_outs = spec->autocfg.line_outs; + memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins, + sizeof(spec->autocfg.speaker_pins)); + spec->autocfg.line_outs = spec->autocfg.speaker_outs; + memset(spec->autocfg.speaker_pins, 0, sizeof(spec->autocfg.speaker_pins)); + spec->autocfg.speaker_outs = 0; + } + err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
if (err < 0)
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs.
Right, then it might be actually easier to swap line_outs and hp_outs before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Thanks,
Takashi
Thanks!
diff -Nur a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
- 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
- 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
- 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
- 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
};
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err;
int hp_speaker_swap = 0;
if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
- if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
/*Copy hp_outs to line_outs, backup line_outs in speaker_outs*/
memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.speaker_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
sizeof(spec->autocfg.hp_pins));
spec->autocfg.line_outs = spec->autocfg.hp_outs;
hp_speaker_swap = 1;
- }
- if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) return err; if (spec->multiout.num_dacs == 0)
@@ -2107,6 +2120,18 @@ if (err < 0) return err;
- if (hp_speaker_swap == 1) {
/*Restore the hp_outs and line_outs*/
memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.hp_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.line_outs = spec->autocfg.speaker_outs;
memset(spec->autocfg.speaker_pins, 0,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.speaker_outs = 0;
}
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
if (err < 0)
At Wed, 31 Oct 2007 09:39:46 +0100, I wrote:
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs.
Right, then it might be actually easier to swap line_outs and hp_outs before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
FYI, the patch to autocfg in hda_codec.c was already committed to HG tree.
thanks,
Takashi
On Wed, 2007-10-31 at 09:39 +0100, Takashi Iwai wrote:
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Okay. Thanks
One minor issue: The mic pin is always in the hp_outs and have the unsolicited response ability.
If someone just plug the mic jack,the speaker will be muted.
How about this patch? 1.We may only return true in get_pin_presence() when it works as HP. 2.Trigger a unsol_event in stac92xx_io_switch_put();
Thanks!
diff -Nur a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-11-01 09:59:12.000000000 +0800 @@ -1552,6 +1552,9 @@ pinctl |= stac92xx_get_vref(codec, nid); stac92xx_auto_set_pinctl(codec, nid, pinctl); } + + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + return 1; }
@@ -2409,8 +2412,14 @@ if (!nid) return 0; if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) - & (1 << 31)) - return 1; + & (1 << 31)) { + if (snd_hda_codec_read(codec, nid, + 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00) & AC_PINCTL_IN_EN) + return 0; + else + return 1; + } + return 0; }
Thanks,
Takashi
Hi,Takashi:
Is there any new states about this patch? Maybe I can ask the reporter to help to test it.
Thanks!
On Wed, 2007-10-31 at 16:39 +0800, Takashi Iwai wrote:
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls
according to
cfg->line_outs. This patch seems to leave the cfg->line_outs
unchanged.
It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right
line_outs.
Right, then it might be actually easier to swap line_outs and
hp_outs
before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Thanks,
Takashi
Thanks!
diff -Nur
a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c
b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
};
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err;
int hp_speaker_swap = 0; if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
/*Copy hp_outs to line_outs, backup line_outs in
speaker_outs*/
memcpy(spec->autocfg.speaker_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.speaker_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.hp_pins,
sizeof(spec->autocfg.hp_pins));
spec->autocfg.line_outs = spec->autocfg.hp_outs;
hp_speaker_swap = 1;
}
if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) <
return err; if (spec->multiout.num_dacs == 0)
@@ -2107,6 +2120,18 @@ if (err < 0) return err;
if (hp_speaker_swap == 1) {
/*Restore the hp_outs and line_outs*/
memcpy(spec->autocfg.hp_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.hp_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.speaker_pins,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.line_outs = spec->autocfg.speaker_outs;
memset(spec->autocfg.speaker_pins, 0,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.speaker_outs = 0;
}
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); if (err < 0)
At Thu, 08 Nov 2007 15:06:22 +0800, zhejiang wrote:
Hi,Takashi:
Is there any new states about this patch? Maybe I can ask the reporter to help to test it.
Your patch looks almost fine, but I need your sign-off to merge to the upstream (as it's no trivial fix). Give the following explicitly to agree the general patch management (see $LINUX_KERNEL/Documentation/SubmittingPatches for details).
So far, three patches are pending:
- fix for pincfg - hack to swap hp and line-outs at probe - fix for speaker-off via mic-jack plug (which I'd need a bit more review, though)
Of course, the test of the patch with the original reporter is important.
thanks,
Takashi
Thanks!
On Wed, 2007-10-31 at 16:39 +0800, Takashi Iwai wrote:
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls
according to
cfg->line_outs. This patch seems to leave the cfg->line_outs
unchanged.
It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right
line_outs.
Right, then it might be actually easier to swap line_outs and
hp_outs
before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Thanks,
Takashi
Thanks!
diff -Nur
a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c
b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
};
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err;
int hp_speaker_swap = 0; if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
/*Copy hp_outs to line_outs, backup line_outs in
speaker_outs*/
memcpy(spec->autocfg.speaker_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.speaker_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.hp_pins,
sizeof(spec->autocfg.hp_pins));
spec->autocfg.line_outs = spec->autocfg.hp_outs;
hp_speaker_swap = 1;
}
if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) <
return err; if (spec->multiout.num_dacs == 0)
@@ -2107,6 +2120,18 @@ if (err < 0) return err;
if (hp_speaker_swap == 1) {
/*Restore the hp_outs and line_outs*/
memcpy(spec->autocfg.hp_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.hp_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.speaker_pins,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.line_outs = spec->autocfg.speaker_outs;
memset(spec->autocfg.speaker_pins, 0,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.speaker_outs = 0;
}
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); if (err < 0)
On Thu, 2007-11-08 at 05:48 +0100, Takashi Iwai wrote:
At Thu, 08 Nov 2007 15:06:22 +0800, zhejiang wrote:
Hi,Takashi:
Is there any new states about this patch? Maybe I can ask the reporter to help to test it.
Your patch looks almost fine, but I need your sign-off to merge to the upstream (as it's no trivial fix). Give the following explicitly to agree the general patch management (see $LINUX_KERNEL/Documentation/SubmittingPatches for details).
Thanks! Here is my sign-off:
Signed-off-by: Jiang Zhe zhe.jiang@intel.com
So far, three patches are pending:
- fix for pincfg
- hack to swap hp and line-outs at probe
- fix for speaker-off via mic-jack plug (which I'd need a bit more review, though)
Of course, the test of the patch with the original reporter is important.
I will ask the reporter to help to test the patch.
thanks,
Takashi
Thanks!
On Wed, 2007-10-31 at 16:39 +0800, Takashi Iwai wrote:
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls
according to
cfg->line_outs. This patch seems to leave the cfg->line_outs
unchanged.
It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right
line_outs.
Right, then it might be actually easier to swap line_outs and
hp_outs
before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Thanks,
Takashi
Thanks!
diff -Nur
a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c
b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
};
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err;
int hp_speaker_swap = 0; if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
/*Copy hp_outs to line_outs, backup line_outs in
speaker_outs*/
memcpy(spec->autocfg.speaker_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.speaker_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.hp_pins,
sizeof(spec->autocfg.hp_pins));
spec->autocfg.line_outs = spec->autocfg.hp_outs;
hp_speaker_swap = 1;
}
if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) <
return err; if (spec->multiout.num_dacs == 0)
@@ -2107,6 +2120,18 @@ if (err < 0) return err;
if (hp_speaker_swap == 1) {
/*Restore the hp_outs and line_outs*/
memcpy(spec->autocfg.hp_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.hp_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.speaker_pins,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.line_outs = spec->autocfg.speaker_outs;
memset(spec->autocfg.speaker_pins, 0,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.speaker_outs = 0;
}
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); if (err < 0)
Hi,Takashi:
[FYI] The reporter of the 0003427 helped to test the patch. Here is the result: 1. 6-channel mode is okay 2. Mic is okay 3. If switch the mic to output jack, it can mute the internal speaker.
Thanks!
Jiang,zhe
-----Original Message----- From: Jiang, Zhe Sent: 2007年11月9日 12:54 To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: Re: [alsa-devel] patch for Dell 1210 which using stac9221 codec
On Thu, 2007-11-08 at 05:48 +0100, Takashi Iwai wrote:
At Thu, 08 Nov 2007 15:06:22 +0800, zhejiang wrote:
Hi,Takashi:
Is there any new states about this patch? Maybe I can ask the reporter to help to test it.
Your patch looks almost fine, but I need your sign-off to merge to the upstream (as it's no trivial fix). Give the following explicitly to agree the general patch management (see $LINUX_KERNEL/Documentation/SubmittingPatches for details).
Thanks! Here is my sign-off:
Signed-off-by: Jiang Zhe zhe.jiang@intel.com
So far, three patches are pending:
- fix for pincfg
- hack to swap hp and line-outs at probe
- fix for speaker-off via mic-jack plug (which I'd need a bit more review, though)
Of course, the test of the patch with the original reporter is important.
I will ask the reporter to help to test the patch.
thanks,
Takashi
Thanks!
On Wed, 2007-10-31 at 16:39 +0800, Takashi Iwai wrote:
At Wed, 31 Oct 2007 16:49:44 +0800, zhejiang wrote:
On Tue, 2007-10-30 at 14:53 +0100, Takashi Iwai wrote:
At Tue, 30 Oct 2007 17:05:55 +0800, zhejiang wrote:
The stac92xx_auto_create_multi_out_ctls() create controls
according to
cfg->line_outs. This patch seems to leave the cfg->line_outs
unchanged.
It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right
line_outs.
Right, then it might be actually easier to swap line_outs and
hp_outs
before and after as you suggested...
Takashi
So,we should patch the patch_sigmatel.c like that?
Yes, that's what I meant (almost same change I did in my local tree :) I'm going to split this to two pieces, the change of m82 pin config and the hack for multi-HP outs (also my last change to autocfg parser).
Anyway, could you give your sign-off? Then I'll apply the patches to the HG tree for better testing.
Thanks,
Takashi
Thanks!
diff -Nur
a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c
b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c --- a/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-23 08:00:10.000000000 +0800 +++ b/alsa-driver-hg20071031/alsa-kernel/pci/hda/patch_sigmatel.c 2007-10-31 16:15:38.000000000 +0800 @@ -884,8 +884,8 @@ 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4,
};
@@ -2088,6 +2088,7 @@ { struct sigmatel_spec *spec = codec->spec; int err;
int hp_speaker_swap = 0; if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -2096,6 +2097,18 @@ if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
spec->autocfg.hp_outs > 1) {
/*Copy hp_outs to line_outs, backup line_outs in
speaker_outs*/
memcpy(spec->autocfg.speaker_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.speaker_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.hp_pins,
sizeof(spec->autocfg.hp_pins));
spec->autocfg.line_outs = spec->autocfg.hp_outs;
hp_speaker_swap = 1;
}
if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) <
return err; if (spec->multiout.num_dacs == 0)
@@ -2107,6 +2120,18 @@ if (err < 0) return err;
if (hp_speaker_swap == 1) {
/*Restore the hp_outs and line_outs*/
memcpy(spec->autocfg.hp_pins,
spec->autocfg.line_out_pins,
sizeof(spec->autocfg.line_out_pins));
spec->autocfg.hp_outs = spec->autocfg.line_outs;
memcpy(spec->autocfg.line_out_pins,
spec->autocfg.speaker_pins,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.line_outs = spec->autocfg.speaker_outs;
memset(spec->autocfg.speaker_pins, 0,
sizeof(spec->autocfg.speaker_pins));
spec->autocfg.speaker_outs = 0;
}
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); if (err < 0)
At Tue, 13 Nov 2007 17:16:51 +0800, Jiang, Zhe wrote:
Hi,Takashi:
[FYI] The reporter of the 0003427 helped to test the patch. Here is the result:
- 6-channel mode is okay
- Mic is okay
- If switch the mic to output jack, it can mute the internal speaker.
Thanks!
Jiang,zhe
Great. The patches have been already merged to HG tree. It's included in the daily snapshot of 20071113.
Thanks,
Takashi
On Thu, 2007-10-25 at 15:44 +0800, zhejiang wrote:
On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote:
At Mon, 22 Oct 2007 14:08:19 +0800, zhejiang wrote:
Ah, then it's basically similar like 3-stack model but with two headphones instead of a pair of line-out and line-in.
Without your modification of pin config, how the driver detects? Do you have an output of kernel message with debug option about auto pin configs?
I don't have the hardware. I have asked the bug reporter to do the experiment, I will post it here if i get any response.
Thanks.
According to the response from the reporter,here is the pin config of the original driver.
ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: hp_outs=1 (0xa/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0)
Looking through the sigmatel code, we have several known use cases:
- desktop
1a. 3stack + front panel front HP, front mic, rear line-out, rear line-in, rear mic
1b. 6stack + front panel front HP, front mic, rear line-out, rear surr, rear CLFE rear side, rear line-in, rear mic and variants without front panel.
In the case 1a, rear line-in and rear mic can be used as surround outputs.
- laptop
2a. minimal HP, speaker, mic, built-in mic 2b. a la desktop HP, speaker, line-in, mic, built-in mic 2c. dell HP x 2, speaker(s), mic, built-in mic
Now, the case 2c requires a similar hack. But, before going more deeply, it's better to recheck patch_sigmatel.c again. Basically, it has already the code to add output sharing using line-in/mic-in. The problem is that it checks only limited use-cases (1a) and it adds cfg->line_outs and thus this influences on all other places.
The call graph of stac92xx_parse_auto_config() :
1.snd_hda_parse_pin_def_config()
2.stac92xx_add_dyn_out_pins() It check the cfg->line_outs and input_pins[] to add dynamic lineouts.
3.stac92xx_auto_fill_dac_nids() It only fills the dac_nids from the cfg->line_out_pins[],
4.stac92xx_auto_create_multi_out_ctls() It add controls according to the cfg->line_outs.
we can see that they heavily depend on the line_outs[] info.
How about this method?
In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then we switch the cfg->hp_pins[] with cfg->line_out_pins[].
Maybe better to check cfg->line_out_type. I guess it's AUTO_PIN_SPEAKER_OUT in the case of this Dell laptop. The driver takes speaker in prior to headphone as the primary line-out.
The 2,3,4 may work without change. At the end of the stac92xx_parse_auto_config(),we restore the cfg->hp_pins[] and cfg->line_out_pins[].
Alternatively, instead of saving/restoring informatoin, we can fix snd_hda_parse_pin_def_config() itself to check cfg->hp_outs and cfg->speaker_outs to determine the primary output. If one of them is greater, take it as the primary output. It's less hackish but *might* cause some regression in rare cases.
I think that we need to restore the cfg->hp_pins and cfg->line_out_pins for the rest code,because:
- stac92xx_auto_init_hp_out() need to use the hp_pins to enable the
AC_PINCTL_HP_EN 2. stac92xx_hp_detect() need to use the hp_outs to detect jack presense and will disable line_out_pins and speaker_pins. 3. stac92xx_init() use the hp_pins to enable unsolicited response.
If we copy cfg->hp_outs to the line_out_pins, all these codes won't work. ^-^
Another things to change : 1.snd_hda_parse_pin_def_config() Should sort the hp_pins[] by sequence.
Yeah, just missing right now.
2.stac92xx_auto_fill_dac_nids() Support the "Front Mic" switch as well. 3.stac92xx_io_switch_put() If Mic work as output for laptop,enable pin detect too.
Well, I think the better fix is to fix the "Front Mic". If there is only a front mic, it should be basically labelled as "Mic" because it's the only one. So, again, snd_hda_parse_pin_def_config(), we can reassign input_pins[AUTO_PIN_FRONT_MIC] to input_pins[AUTO_PIN_MIC] if there is only one mic. Then the rest wouldn't need changes.
Great.
Of course, another question is what to do when we have both rear and front mic and if we still want to handle them as outputs. Well, we have no such hardware yet, though.
thanks,
Takashi
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Could you try this patch? I found an updated pin config on Dell'sweb site. If this works, go ahead and check it in.
Summary: Update Dell XPS 1210 Pin Config.
Signed off by Tobin Davis tdavis@dsl-only.net
At Tue, 30 Oct 2007 08:48:06 -0700, Tobin Davis wrote:
On Thu, 2007-10-25 at 15:44 +0800, zhejiang wrote:
On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote: > At Mon, 22 Oct 2007 14:08:19 +0800, > zhejiang wrote: > > > Ah, then it's basically similar like 3-stack model but with two > > > headphones instead of a pair of line-out and line-in. > > > > > > Without your modification of pin config, how the driver detects? > > > Do you have an output of kernel message with debug option about auto > > > pin configs? > > > > > I don't have the hardware. > > I have asked the bug reporter to do the experiment, > > I will post it here if i get any response. > > Thanks. > According to the response from the reporter,here is the pin config of the original driver. ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: hp_outs=1 (0xa/0x0/0x0/0x0/0x0) ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0) > > > Looking through the sigmatel code, we have several known use cases: > > > > > > 1. desktop > > > 1a. 3stack + front panel > > > front HP, front mic, rear line-out, rear line-in, rear mic > > > > > > 1b. 6stack + front panel > > > front HP, front mic, rear line-out, rear surr, rear CLFE > > > rear side, rear line-in, rear mic > > > and variants without front panel. > > > > > > In the case 1a, rear line-in and rear mic can be used as surround > > > outputs. > > > > > > 2. laptop > > > 2a. minimal > > > HP, speaker, mic, built-in mic > > > 2b. a la desktop > > > HP, speaker, line-in, mic, built-in mic > > > 2c. dell > > > HP x 2, speaker(s), mic, built-in mic > > > > > > Now, the case 2c requires a similar hack. But, before going more > > > deeply, it's better to recheck patch_sigmatel.c again. Basically, it > > > has already the code to add output sharing using line-in/mic-in. The > > > problem is that it checks only limited use-cases (1a) and it adds > > > cfg->line_outs and thus this influences on all other places. > > > > > > > The call graph of stac92xx_parse_auto_config() : > > > > 1.snd_hda_parse_pin_def_config() > > > > 2.stac92xx_add_dyn_out_pins() > > It check the cfg->line_outs and input_pins[] to add dynamic lineouts. > > > > 3.stac92xx_auto_fill_dac_nids() > > It only fills the dac_nids from the cfg->line_out_pins[], > > > > 4.stac92xx_auto_create_multi_out_ctls() > > It add controls according to the cfg->line_outs. > > > > we can see that they heavily depend on the line_outs[] info. > > > > How about this method? > > > > In stac92xx_add_dyn_out_pins(),we check the cfg->hp_outs,IF IT IS 2,then > > we switch the cfg->hp_pins[] with cfg->line_out_pins[]. > > Maybe better to check cfg->line_out_type. I guess it's > AUTO_PIN_SPEAKER_OUT in the case of this Dell laptop. The driver > takes speaker in prior to headphone as the primary line-out. > > > The 2,3,4 may work without change. > > At the end of the stac92xx_parse_auto_config(),we restore the > > cfg->hp_pins[] and cfg->line_out_pins[]. > > Alternatively, instead of saving/restoring informatoin, we can fix > snd_hda_parse_pin_def_config() itself to check cfg->hp_outs and > cfg->speaker_outs to determine the primary output. If one of them is > greater, take it as the primary output. > It's less hackish but *might* cause some regression in rare cases. > I think that we need to restore the cfg->hp_pins and cfg->line_out_pins for the rest code,because: 1. stac92xx_auto_init_hp_out() need to use the hp_pins to enable the AC_PINCTL_HP_EN 2. stac92xx_hp_detect() need to use the hp_outs to detect jack presense and will disable line_out_pins and speaker_pins. 3. stac92xx_init() use the hp_pins to enable unsolicited response. If we copy cfg->hp_outs to the line_out_pins, all these codes won't work. ^-^ > > Another things to change : > > 1.snd_hda_parse_pin_def_config() > > Should sort the hp_pins[] by sequence. > > Yeah, just missing right now. > > > 2.stac92xx_auto_fill_dac_nids() > > Support the "Front Mic" switch as well. > > 3.stac92xx_io_switch_put() > > If Mic work as output for laptop,enable pin detect too. > > Well, I think the better fix is to fix the "Front Mic". If there is > only a front mic, it should be basically labelled as "Mic" because > it's the only one. So, again, snd_hda_parse_pin_def_config(), we can > reassign input_pins[AUTO_PIN_FRONT_MIC] to input_pins[AUTO_PIN_MIC] if > there is only one mic. Then the rest wouldn't need changes. > Great. > Of course, another question is what to do when we have both rear and > front mic and if we still want to handle them as outputs. Well, we > have no such hardware yet, though. > > > thanks, > > Takashi _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Could you try this patch? I found an updated pin config on Dell'sweb site. If this works, go ahead and check it in.
Summary: Update Dell XPS 1210 Pin Config.
Signed off by Tobin Davis tdavis@dsl-only.net
diff -r 60b9916a18b8 pci/hda/patch_sigmatel.c --- a/pci/hda/patch_sigmatel.c Tue Oct 30 15:28:14 2007 +0100 +++ b/pci/hda/patch_sigmatel.c Tue Oct 30 08:43:39 2007 -0700 @@ -884,9 +884,9 @@ static unsigned int dell_922x_m81_pin_co 102801D7 (Dell XPS M1210) */ static unsigned int dell_922x_m82_pin_configs[10] = {
- 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
- 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
- 0x508003f3, 0x405003f4,
- 0x0221121e, 0x408103ff, 0x0281123e, 0x90100310,
- 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2,
- 0x50a003f3, 0x405003f4,
};
static unsigned int d945gtp3_pin_configs[10] = {
Hm, this definition looks slightly different from zhejiang's one.
static unsigned int dell_922x_m82_pin_configs[10] = { - 0x0221121f, 0x408103ff, 0x02111212, 0x90100310, - 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2, + 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, + 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4, -}; +};
Line-in and mic-in are assigned to different pins. Which one to take?
Takashi
Could you try this patch? I found an updated pin config on Dell'sweb site. If this works, go ahead and check it in.
Summary: Update Dell XPS 1210 Pin Config.
Signed off by Tobin Davis tdavis@dsl-only.net
I don't have the hardware.The bug [0003427] reporter helped me to do experiment.
The only difference is the usage of the third pin. That patch uses it as Line-In,but I think it should be Mic-In..
Please see: http://www.notebookreview.com/assets/12583.jpg
Thanks!
participants (4)
-
Jiang, Zhe
-
Takashi Iwai
-
Tobin Davis
-
zhejiang