Exemple #1
0
static int fwspk_volume_put(struct snd_kcontrol *control,
			  struct snd_ctl_elem_value *value)
{
	struct fwspk *fwspk = control->private_data;
	unsigned int i, changed_channels;
	bool equal_values = true;
	s16 volume;
	int err;

	for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
		if (value->value.integer.value[i] < fwspk->volume_min ||
		    value->value.integer.value[i] > fwspk->volume_max)
			return -EINVAL;
		if (value->value.integer.value[i] !=
		    value->value.integer.value[0])
			equal_values = false;
	}

	changed_channels = 0;
	for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
		if (value->value.integer.value[channel_map[i]] !=
							fwspk->volume[i])
			changed_channels |= 1 << (i + 1);

	if (equal_values && changed_channels != 0)
		changed_channels = 1 << 0;

	for (i = 0; i <= fwspk->device_info->mixer_channels; ++i) {
		volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
		if (changed_channels & (1 << i)) {
			err = fwspk_volume_command(fwspk, &volume, i,
						   CTL_CURRENT, CTL_WRITE);
			if (err < 0)
				return err;
		}
		if (i > 0)
			fwspk->volume[i - 1] = volume;
	}

	return changed_channels != 0;
}
			.info = snd_ctl_boolean_mono_info,
			.get = fwspk_mute_get,
			.put = fwspk_mute_put,
		},
		{
			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
			.name = "PCM Playback Volume",
			.info = fwspk_volume_info,
			.get = fwspk_volume_get,
			.put = fwspk_volume_put,
		},
	};
	unsigned int i, first_ch;
	int err;

	err = fwspk_volume_command(fwspk, &fwspk->volume_min,
				   0, CTL_MIN, CTL_READ);
	if (err < 0)
		return err;
	err = fwspk_volume_command(fwspk, &fwspk->volume_max,
				   0, CTL_MAX, CTL_READ);
	if (err < 0)
		return err;

	err = fwspk_mute_command(fwspk, &fwspk->mute, CTL_READ);
	if (err < 0)
		return err;

	first_ch = fwspk->device_info->mixer_channels == 1 ? 0 : 1;
	for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
		err = fwspk_volume_command(fwspk, &fwspk->volume[i],
					   first_ch + i, CTL_CURRENT, CTL_READ);