[alsa-devel] Via Codecs: functions mute_aa_path() and is_aa_path_mute() (file patch_via.c) seem to support different codecs.

alex dot baldacchino dot alsasub at gmail dot com alex.baldacchino.alsasub at gmail.com
Thu Jun 30 18:43:19 CEST 2011


These functions seem to support different codecs through different
switch statements:

mute_aa_path:

...
	/* get nid of MW0 and start & end index */
	switch (spec->codec_type) {
	case VT1708:
		nid_mixer = 0x17;
		start_idx = 2;
		end_idx = 4;
		break;
	case VT1709_10CH:
	case VT1709_6CH:
		nid_mixer = 0x18;
		start_idx = 2;
		end_idx = 4;
		break;
	case VT1708B_8CH:
	case VT1708B_4CH:
	case VT1708S:
	case VT1716S:
		nid_mixer = 0x16;
		start_idx = 2;
		end_idx = 4;
		break;
	case VT1718S:
		nid_mixer = 0x21;
		start_idx = 1;
		end_idx = 3;
		break;
	default:
		return;
	}



is_aa_path_mute:

...
	/* get nid of MW0 and start & end index */
	switch (spec->codec_type) {
	case VT1708B_8CH:
	case VT1708B_4CH:
	case VT1708S:
	case VT1716S:
		nid_mixer = 0x16;
		start_idx = 2;
		end_idx = 4;
		break;
	case VT1702:
		nid_mixer = 0x1a;
		start_idx = 1;
		end_idx = 3;
		break;
	case VT1718S:
		nid_mixer = 0x21;
		start_idx = 1;
		end_idx = 3;
		break;
	case VT2002P:
	case VT1812:
	case VT1802:
		nid_mixer = 0x21;
		start_idx = 0;
		end_idx = 2;
		break;
	default:
		return 0;
	}



It would seem that AA-path can be muted but not inquired for mute
state for codecs VT1708, VT1709_10CH and VT1709_6CH, vice-versa for
codecs VT1702, VT2002P, VT1812, VT1802. If this is the real way such
codecs work, I wonder if analog_input_switch_put() works as expected
for codec VT1708, in which case, perhaps, it should be modified:


static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);

	set_widgets_power_state(codec);
	analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
	if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
		if (is_aa_path_mute(codec))
			vt1708_start_hp_work(codec->spec);
		else
			vt1708_stop_hp_work(codec->spec);
	}
	return change;
}


Since is_aa_path_mute() always returns 0 for codec VT1708 (default
case), and both vt1708_start_hp_work() and vt1708_stop_hp_work() only
execute for such a codec (due to an if statement checking for codec
type and returning from the function if that's not VT1708),
vt1708_stop_hp_work() is the only one that can be executed, so perhaps
the code could be clearer without the if statement checking
is_aa_path_mute() result. Moreover:


static void vt1708_stop_hp_work(struct via_spec *spec)
{
	if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
		return;
	if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
	    && !is_aa_path_mute(spec->codec))
		return;
	snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
			    !spec->vt1708_jack_detectect);
	cancel_delayed_work_sync(&spec->vt1708_hp_work);
}


Since !is_aa_path_mute(spec->codec) is always true for VT1708, there
is no real dependence on it in the if statement above, thus it should
be removed. But this also means that, if
snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1,
then analog_input_switch_put() will call vt1708_stop_hp_work(), which
in turn will return without performing any operation, so that it would
seem useless, unless any reconfiguration might happen just in time
between the first call to snd_hda_get_bool_hint in
analog_input_switch_put() and the second call within
vt1708_stop_hp_work().


Otherwise, if those switch statements should match against each other,
they could be replaced with a call to a new inline function, so that a
single switch could be moved within it and become easier to maintain.
For instance:


static inline int get_supported_aa_mute_info( const struct via_spec *
const spec,
				hda_nid_t *mixer, int *first_idx, int *last_idx )
{
	/* get correct nid of mixer and start & end index */
	switch (spec->codec_type) {
		case VT1708:
				*mixer = 0x17;
				*first_idx = 2;
				*last_idx = 4;
				return 0;
		case VT1709_10CH:
		case VT1709_6CH:
				*mixer = 0x18;
				*first_idx = 2;
				*last_idx = 4;
				return 0;
		case VT1708B_8CH:
		case VT1708B_4CH:
		case VT1708S:
		case VT1716S:
				*mixer = 0x16;
				*first_idx = 2;
				*last_idx = 4;
				return 0;
		case VT1702:
				*mixer = 0x1a;
				*first_idx = 1;
				*last_idx = 3;
				return 0;
		case VT1718S:
				*mixer = 0x21;
				*first_idx = 1;
				*last_idx = 3;
				return 0;
		case VT2002P:
		case VT1812:
		case VT1802:
				*mixer = 0x21;
				*first_idx = 0;
				*last_idx = 2;
				return 0;
		default:
				return -EINVAL;
	}
}



In mute_aa_path:

...
	if( get_supported_aa_mute_info( spec, &nid_mixer, &start_idx, &end_idx ) < 0 )
		return;


In is_aa_path_mute:


...
	if( get_supported_aa_mute_info( spec, &nid_mixer, &start_idx, &end_idx ) < 0 )
		return 0;


It happens that the list of codec types tested by is_aa_path_mute() is
the same tested by function analog_low_current_mode(); however, there
should be no dependence on that, because whatever is_aa_path_mute()
returned for any other codec would be filtered out by the switch
statement within analog_low_current_mode().

Regards.


More information about the Alsa-devel mailing list