Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) #define __NO_VERSION__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Driver for Digigram pcxhr compatible soundcards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * mixer callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (c) 2004 by Digigram <alsa@digigram.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "pcxhr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include "pcxhr_hwdep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "pcxhr_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "pcxhr_mixer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "pcxhr_mix22.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #define PCXHR_LINE_CAPTURE_LEVEL_MIN   0	/* -112.0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define PCXHR_LINE_CAPTURE_LEVEL_MAX   255	/* +15.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define PCXHR_LINE_CAPTURE_ZERO_LEVEL  224	/* 0.0 dB ( 0 dBu -> 0 dBFS ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define PCXHR_LINE_PLAYBACK_LEVEL_MIN  0	/* -104.0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define PCXHR_LINE_PLAYBACK_LEVEL_MAX  128	/* +24.0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104	/* 0.0 dB ( 0 dBFS -> 0 dBu ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 					   int is_capture, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	int err, vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	if (is_capture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 		rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		rmh.cmd[2] = chip->analog_capture_volume[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 		rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 		if (chip->analog_playback_active[channel])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 			vol = chip->analog_playback_volume[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 			vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 		/* playback analog levels are inversed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	rmh.cmd[1]  = 1 << ((2 * chip->chip_idx) + channel);	/* audio mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	rmh.cmd_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 			"error update_analog_audio_level card(%d)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 			   " is_capture(%d) err(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 			   chip->chip_idx, is_capture, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  * analog level control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	if (kcontrol->private_value == 0) {	/* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	    if (chip->mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		uinfo->value.integer.min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 			HR222_LINE_PLAYBACK_LEVEL_MIN;	/* -25 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		uinfo->value.integer.max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 			HR222_LINE_PLAYBACK_LEVEL_MAX;	/* +24 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	    } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		uinfo->value.integer.min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 			PCXHR_LINE_PLAYBACK_LEVEL_MIN;	/*-104 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		uinfo->value.integer.max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 			PCXHR_LINE_PLAYBACK_LEVEL_MAX;	/* +24 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	} else {				/* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	    if (chip->mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		uinfo->value.integer.min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 			HR222_LINE_CAPTURE_LEVEL_MIN;	/*-112 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		uinfo->value.integer.max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 			HR222_LINE_CAPTURE_LEVEL_MAX;	/* +15.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	    } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		uinfo->value.integer.min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 			PCXHR_LINE_CAPTURE_LEVEL_MIN;	/*-112 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		uinfo->value.integer.max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 			PCXHR_LINE_CAPTURE_LEVEL_MAX;	/* +15.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	if (kcontrol->private_value == 0) {	/* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	  ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	  ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	} else {				/* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	  ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	  ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	int is_capture, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	is_capture = (kcontrol->private_value != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		int  new_volume = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 		int *stored_volume = is_capture ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 			&chip->analog_capture_volume[i] :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 			&chip->analog_playback_volume[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		if (is_capture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 			if (chip->mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 				if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 				    new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 				if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 				    new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 			if (chip->mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 				if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 				    new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 				if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 				    new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		if (*stored_volume != new_volume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			*stored_volume = new_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 				hr222_update_analog_audio_level(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 								is_capture, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 				pcxhr_update_analog_audio_level(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 								is_capture, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) static const struct snd_kcontrol_new pcxhr_control_analog_level = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 			 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	/* name will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	.info =		pcxhr_analog_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	.get =		pcxhr_analog_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	.put =		pcxhr_analog_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	/* tlv will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) /* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #define pcxhr_sw_info		snd_ctl_boolean_stereo_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	int i, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	for(i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		if (chip->analog_playback_active[i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		    ucontrol->value.integer.value[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			chip->analog_playback_active[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 				!!ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			/* update playback levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 				hr222_update_analog_audio_level(chip, 0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 				pcxhr_update_analog_audio_level(chip, 0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) static const struct snd_kcontrol_new pcxhr_control_output_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	.name =		"Master Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	.info =		pcxhr_sw_info,		/* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	.get =		pcxhr_audio_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	.put =		pcxhr_audio_sw_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) #define PCXHR_DIGITAL_LEVEL_MIN		0x000	/* -110 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) #define PCXHR_DIGITAL_LEVEL_MAX		0x1ff	/* +18 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) #define PCXHR_DIGITAL_ZERO_LEVEL	0x1b7	/*  0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) #define MORE_THAN_ONE_STREAM_LEVEL	0x000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) #define VALID_STREAM_PAN_LEVEL_MASK	0x800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) #define VALID_STREAM_LEVEL_MASK		0x400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) #define VALID_STREAM_LEVEL_1_MASK	0x200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) #define VALID_STREAM_LEVEL_2_MASK	0x100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	struct pcxhr_pipe *pipe = &chip->playback_pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	int left, right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	if (chip->digital_playback_active[idx][0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		left = chip->digital_playback_volume[idx][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		left = PCXHR_DIGITAL_LEVEL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	if (chip->digital_playback_active[idx][1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		right = chip->digital_playback_volume[idx][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		right = PCXHR_DIGITAL_LEVEL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	/* add pipe and stream mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	/* volume left->left / right->right panoramic level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	rmh.cmd[2]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	rmh.cmd[2] |= (left << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	rmh.cmd[3]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	rmh.cmd[3] |= right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	rmh.cmd_len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		dev_dbg(chip->card->dev, "error update_playback_stream_level "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			   "card(%d) err(%x)\n", chip->chip_idx, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) #define AUDIO_IO_HAS_MUTE_LEVEL		0x400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) #define AUDIO_IO_HAS_MUTE_MONITOR_1	0x200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) #define VALID_AUDIO_IO_DIGITAL_LEVEL	0x000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) #define VALID_AUDIO_IO_MONITOR_LEVEL	0x000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) #define VALID_AUDIO_IO_MUTE_LEVEL	0x000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) #define VALID_AUDIO_IO_MUTE_MONITOR_1	0x000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					 int capture, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct pcxhr_pipe *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		pipe = &chip->capture_pipe[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		pipe = &chip->playback_pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	/* add channel mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 				  1 << (channel + pipe->first_audio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	/* TODO : if mask (3 << pipe->first_audio) is used, left and right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 * channel will be programmed to the same params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if (capture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		/* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		 * (capture pipe level) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		rmh.cmd[2] = chip->digital_capture_volume[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		rmh.cmd[0] |=	VALID_AUDIO_IO_MONITOR_LEVEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 				VALID_AUDIO_IO_MUTE_MONITOR_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		/* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		 * not yet handled (playback pipe level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		if (chip->monitoring_active[channel] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	rmh.cmd_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 			"error update_audio_level(%d) err=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			   chip->chip_idx, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) /* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	uinfo->value.integer.min = PCXHR_DIGITAL_LEVEL_MIN;   /* -109.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	uinfo->value.integer.max = PCXHR_DIGITAL_LEVEL_MAX;   /*   18.0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	/* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	int *stored_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	int is_capture = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	if (is_capture)		/* digital capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		stored_volume = chip->digital_capture_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	else			/* digital playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		stored_volume = chip->digital_playback_volume[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	ucontrol->value.integer.value[0] = stored_volume[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	ucontrol->value.integer.value[1] = stored_volume[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	/* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	int is_capture = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	int *stored_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	if (is_capture)		/* digital capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		stored_volume = chip->digital_capture_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	else			/* digital playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		stored_volume = chip->digital_playback_volume[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		int vol = ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		if (vol < PCXHR_DIGITAL_LEVEL_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		    vol > PCXHR_DIGITAL_LEVEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		if (stored_volume[i] != vol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 			stored_volume[i] = vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			if (is_capture)	/* update capture volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				pcxhr_update_audio_pipe_level(chip, 1, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	if (!is_capture && changed)	/* update playback volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		pcxhr_update_playback_stream_level(chip, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) static const struct snd_kcontrol_new snd_pcxhr_pcm_vol =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	/* name will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	/* count will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	.info =		pcxhr_digital_vol_info,		/* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	.get =		pcxhr_pcm_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	.put =		pcxhr_pcm_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	.tlv = { .p = db_scale_digital },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	j = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		if (chip->digital_playback_active[j][i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		    ucontrol->value.integer.value[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			chip->digital_playback_active[j][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 				!!ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		pcxhr_update_playback_stream_level(chip, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static const struct snd_kcontrol_new pcxhr_control_pcm_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	.name =		"PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	.count =	PCXHR_PLAYBACK_STREAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	.info =		pcxhr_sw_info,		/* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	.get =		pcxhr_pcm_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	.put =		pcxhr_pcm_sw_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  * monitoring level control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		if (chip->monitoring_volume[i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		    ucontrol->value.integer.value[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			chip->monitoring_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			if (chip->monitoring_active[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 				/* update monitoring volume and mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 				/* do only when monitoring is unmuted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 				pcxhr_update_audio_pipe_level(chip, 0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) static const struct snd_kcontrol_new pcxhr_control_monitor_vol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	.name =         "Monitoring Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	.info =		pcxhr_digital_vol_info,		/* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	.get =		pcxhr_monitor_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	.put =		pcxhr_monitor_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	.tlv = { .p = db_scale_digital },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * monitoring switch control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	ucontrol->value.integer.value[0] = chip->monitoring_active[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	ucontrol->value.integer.value[1] = chip->monitoring_active[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		if (chip->monitoring_active[i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		    ucontrol->value.integer.value[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			chip->monitoring_active[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 				!!ucontrol->value.integer.value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 			changed |= (1<<i); /* mask 0x01 and 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	if (changed & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		/* update left monitoring volume and mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		pcxhr_update_audio_pipe_level(chip, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	if (changed & 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		/* update right monitoring volume and mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		pcxhr_update_audio_pipe_level(chip, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	return (changed != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) static const struct snd_kcontrol_new pcxhr_control_monitor_sw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	.name =         "Monitoring Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	.info =         pcxhr_sw_info,		/* shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	.get =          pcxhr_monitor_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	.put =          pcxhr_monitor_sw_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  * audio source select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) #define PCXHR_SOURCE_AUDIO01_UER	0x000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) #define PCXHR_SOURCE_AUDIO01_SYNC	0x000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) #define PCXHR_SOURCE_AUDIO23_UER	0x000400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) #define PCXHR_SOURCE_AUDIO45_UER	0x001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) #define PCXHR_SOURCE_AUDIO67_UER	0x040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	unsigned int mask, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	unsigned int codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	int err, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	switch (chip->chip_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (chip->audio_capture_source != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		reg = mask;	/* audio source from digital plug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		reg = 0;	/* audio source from analog plug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	/* set the input source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	/* resync them (otherwise channel inversion possible) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		rmh.cmd[0] |= (1 << chip->chip_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (chip->mgr->board_aes_in_192k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		unsigned int src_config = 0xC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		/* update all src configs with one call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			if (chip->mgr->chip[i]->audio_capture_source == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 				src_config |= (1 << (3 - i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		/* set codec SRC on off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		rmh.cmd_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		rmh.cmd[1] = src_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		int use_src = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		if (chip->audio_capture_source == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			use_src = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		/* set codec SRC on off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		rmh.cmd_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		rmh.cmd[1] = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 			      (use_src ? 0x41 : 0x54));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			      (use_src ? 0x41 : 0x49));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 				struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	static const char *texts[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		"Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	i = 2;			/* no SRC, no Mic available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (chip->mgr->board_has_aes1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		i = 3;		/* SRC available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		if (chip->mgr->board_has_mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			i = 5;	/* Mic and MicroMix available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	return snd_ctl_enum_info(uinfo, 1, i, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	int i = 2;		/* no SRC, no Mic available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	if (chip->mgr->board_has_aes1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		i = 3;		/* SRC available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		if (chip->mgr->board_has_mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 			i = 5;	/* Mic and MicroMix available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	if (ucontrol->value.enumerated.item[0] >= i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		chip->audio_capture_source = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			hr222_set_audio_source(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			pcxhr_set_audio_source(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) static const struct snd_kcontrol_new pcxhr_control_audio_src = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	.name =		"Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	.info =		pcxhr_audio_src_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	.get =		pcxhr_audio_src_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	.put =		pcxhr_audio_src_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)  * clock type selection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698)  * enum pcxhr_clock_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699)  *	PCXHR_CLOCK_TYPE_INTERNAL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)  *	PCXHR_CLOCK_TYPE_WORD_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)  *	PCXHR_CLOCK_TYPE_AES_SYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702)  *	PCXHR_CLOCK_TYPE_AES_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703)  *	PCXHR_CLOCK_TYPE_AES_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704)  *	PCXHR_CLOCK_TYPE_AES_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)  *	PCXHR_CLOCK_TYPE_AES_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)  *	PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)  *	HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  *	HR22_CLOCK_TYPE_AES_SYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  *	HR22_CLOCK_TYPE_AES_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)  *	HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)  * };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	static const char *textsPCXHR[7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		"Internal", "WordClock", "AES Sync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		"AES 1", "AES 2", "AES 3", "AES 4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	static const char *textsHR22[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		"Internal", "AES Sync", "AES 1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	const char **texts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	int clock_items = 2;	/* at least Internal and AES Sync clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	if (mgr->board_has_aes1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		clock_items += mgr->capture_chips;	/* add AES x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		if (!mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			clock_items += 1;		/* add word clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	if (mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		texts = textsHR22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		texts = textsPCXHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	return snd_ctl_enum_info(uinfo, 1, clock_items, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	int rate, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if (mgr->board_has_aes1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		clock_items += mgr->capture_chips;	/* add AES x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		if (!mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			clock_items += 1;		/* add word clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (ucontrol->value.enumerated.item[0] >= clock_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	mutex_lock(&mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		mutex_lock(&mgr->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		mgr->use_clock_type = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 			pcxhr_get_external_clock(mgr, mgr->use_clock_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 						 &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			rate = mgr->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		if (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			pcxhr_set_clock(mgr, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			if (mgr->sample_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				mgr->sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		mutex_unlock(&mgr->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		ret = 1; /* return 1 even if the set was not done. ok ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	mutex_unlock(&mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) static const struct snd_kcontrol_new pcxhr_control_clock_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	.name =		"Clock Mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	.info =		pcxhr_clock_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	.get =		pcxhr_clock_type_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	.put =		pcxhr_clock_type_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797)  * clock rate control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)  * specific control that scans the sample rates on the external plugs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	uinfo->count = 3 + mgr->capture_chips;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	uinfo->value.integer.min = 0;		/* clock not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	uinfo->value.integer.max = 192000;	/* max sample rate 192 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	int i, err, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	mutex_lock(&mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	for(i = 0; i < 3 + mgr->capture_chips; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		if (i == PCXHR_CLOCK_TYPE_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			rate = mgr->sample_rate_real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			err = pcxhr_get_external_clock(mgr, i, &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		ucontrol->value.integer.value[i] = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	mutex_unlock(&mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) static const struct snd_kcontrol_new pcxhr_control_clock_rate = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	.iface =	SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	.name =		"Clock Rates",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.info =		pcxhr_clock_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	.get =		pcxhr_clock_rate_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  * IEC958 status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			     struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				     int aes_idx, unsigned char *aes_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	unsigned char temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	switch (chip->chip_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	  /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	case 0:	rmh.cmd[1] = CS8420_01_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	case 1:	rmh.cmd[1] = CS8420_23_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	case 2:	rmh.cmd[1] = CS8420_45_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	case 3:	rmh.cmd[1] = CS8420_67_CS; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (chip->mgr->board_aes_in_192k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		switch (aes_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		case 0:	rmh.cmd[2] = CS8416_CSB0; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		case 1:	rmh.cmd[2] = CS8416_CSB1; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		case 2:	rmh.cmd[2] = CS8416_CSB2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		case 3:	rmh.cmd[2] = CS8416_CSB3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		case 4:	rmh.cmd[2] = CS8416_CSB4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		switch (aes_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		  /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		case 0:	rmh.cmd[2] = CS8420_CSB0; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		case 1:	rmh.cmd[2] = CS8420_CSB1; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		case 2:	rmh.cmd[2] = CS8420_CSB2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		case 3:	rmh.cmd[2] = CS8420_CSB3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		case 4:	rmh.cmd[2] = CS8420_CSB4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	/* size and code the chip id for the fpga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	rmh.cmd[1] &= 0x0fffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	/* chip signature + map for spi read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	rmh.cmd_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	if (chip->mgr->board_aes_in_192k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		temp = (unsigned char)rmh.stat[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		/* reversed bit order (not with CS8416_01_CS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			temp <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			if (rmh.stat[1] & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 				temp |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	dev_dbg(chip->card->dev, "read iec958 AES %d byte %d = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		    chip->chip_idx, aes_idx, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	*aes_bits = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	unsigned char aes_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	for(i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		if (kcontrol->private_value == 0)	/* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			aes_bits = chip->aes_bits[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		else {				/* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 				err = hr222_iec958_capture_byte(chip, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 								&aes_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 				err = pcxhr_iec958_capture_byte(chip, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 								&aes_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		ucontrol->value.iec958.status[i] = aes_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	for (i = 0; i < 5; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		ucontrol->value.iec958.status[i] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 				    int aes_idx, unsigned char aes_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	int i, err, cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	unsigned char new_bits = aes_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	unsigned char old_bits = chip->aes_bits[aes_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	struct pcxhr_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		if ((old_bits & 0x01) != (new_bits & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			cmd = chip->chip_idx & 0x03;      /* chip index 0..3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 			if (chip->chip_idx > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 				/* new bit used if chip_idx>3 (PCX1222HR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 				cmd |= 1 << 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 			cmd |= (new_bits & 0x01) << 23;   /* add bit value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 			pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			rmh.cmd[0] |= IO_NUM_REG_CUER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			rmh.cmd[1] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			rmh.cmd_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 				"write iec958 AES %d byte %d bit %d (cmd %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 				    chip->chip_idx, aes_idx, i, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			err = pcxhr_send_msg(chip->mgr, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		old_bits >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		new_bits >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	chip->aes_bits[aes_idx] = aes_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 			    struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	int i, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	/* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	mutex_lock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 				hr222_iec958_update_byte(chip, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 					ucontrol->value.iec958.status[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 				pcxhr_iec958_update_byte(chip, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 					ucontrol->value.iec958.status[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	mutex_unlock(&chip->mgr->mixer_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static const struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	.info =		pcxhr_iec958_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	.get =		pcxhr_iec958_mask_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static const struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	.info =         pcxhr_iec958_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	.get =          pcxhr_iec958_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	.put =          pcxhr_iec958_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	.private_value = 0 /* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static const struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	.info =		pcxhr_iec958_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	.get =		pcxhr_iec958_mask_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static const struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	.name =         SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	.info =         pcxhr_iec958_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	.get =          pcxhr_iec958_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	.private_value = 1 /* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		if (chip->nb_streams_play) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			/* at boot time the digital volumes are unmuted 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 				chip->digital_playback_active[j][i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 				chip->digital_playback_volume[j][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 					PCXHR_DIGITAL_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			/* after boot, only two bits are set on the uer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 			 * interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 					     IEC958_AES0_PRO_FS_48000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 			/* analog volumes for playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			 * (is LEVEL_MIN after boot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			chip->analog_playback_active[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 				chip->analog_playback_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 					HR222_LINE_PLAYBACK_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 				chip->analog_playback_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 					PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 				pcxhr_update_analog_audio_level(chip, 0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			/* stereo cards need to be initialised after boot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 				hr222_update_analog_audio_level(chip, 0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		if (chip->nb_streams_capt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			/* at boot time the digital volumes are unmuted 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			chip->digital_capture_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 				PCXHR_DIGITAL_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			chip->analog_capture_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			/* analog volumes for playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			 * (is LEVEL_MIN after boot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 				chip->analog_capture_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 					HR222_LINE_CAPTURE_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 				chip->analog_capture_volume[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 					PCXHR_LINE_CAPTURE_ZERO_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 				pcxhr_update_analog_audio_level(chip, 1, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			/* stereo cards need to be initialised after boot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			if (chip->mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				hr222_update_analog_audio_level(chip, 1, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	struct snd_pcxhr *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	mutex_init(&mgr->mixer_mutex); /* can be in another place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	for (i = 0; i < mgr->num_cards; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		struct snd_kcontrol_new temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		chip = mgr->chip[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		if (chip->nb_streams_play) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			/* analog output level control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 			temp = pcxhr_control_analog_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			temp.name = "Master Playback Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 			temp.private_value = 0; /* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 			if (mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				temp.tlv.p = db_scale_a_hr222_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 				temp.tlv.p = db_scale_analog_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 					  snd_ctl_new1(&temp, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			/* output mute controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 				snd_ctl_new1(&pcxhr_control_output_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 			temp = snd_pcxhr_pcm_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 			temp.name = "PCM Playback Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			temp.count = PCXHR_PLAYBACK_STREAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			temp.private_value = 0; /* playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 					  snd_ctl_new1(&temp, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 				snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 			/* IEC958 controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 				snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 				snd_ctl_new1(&pcxhr_control_playback_iec958,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		if (chip->nb_streams_capt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 			/* analog input level control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 			temp = pcxhr_control_analog_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			temp.name = "Line Capture Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			temp.private_value = 1; /* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			if (mgr->is_hr_stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 				temp.tlv.p = db_scale_a_hr222_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 				temp.tlv.p = db_scale_analog_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 					  snd_ctl_new1(&temp, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 			temp = snd_pcxhr_pcm_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			temp.name = "PCM Capture Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			temp.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 			temp.private_value = 1; /* capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 					  snd_ctl_new1(&temp, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			/* Audio source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 				snd_ctl_new1(&pcxhr_control_audio_src, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 			/* IEC958 controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 				snd_ctl_new1(&pcxhr_control_capture_iec958,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			if (mgr->is_hr_stereo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 				err = hr222_add_mic_controls(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 				if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 					return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		/* monitoring only if playback and capture device available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			/* monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 				snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 				snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			/* clock mode only one control per pcxhr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 				snd_ctl_new1(&pcxhr_control_clock_type, mgr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			/* non standard control used to scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			 * the external clock presence/frequencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			err = snd_ctl_add(chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 				snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		/* init values for the mixer data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		pcxhr_init_audio_levels(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }