1 /* 2 * Driver for Digigram VXpocket soundcards 3 * 4 * VX-pocket mixer 5 * 6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 #include <sound/core.h> 24 #include <sound/control.h> 25 #include <sound/tlv.h> 26 #include "vxpocket.h" 27 28 #define MIC_LEVEL_MIN 0 29 #define MIC_LEVEL_MAX 8 30 31 /* 32 * mic level control (for VXPocket) 33 */ 34 static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 35 { 36 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 37 uinfo->count = 1; 38 uinfo->value.integer.min = 0; 39 uinfo->value.integer.max = MIC_LEVEL_MAX; 40 return 0; 41 } 42 43 static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 44 { 45 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 46 struct snd_vxpocket *chip = to_vxpocket(_chip); 47 ucontrol->value.integer.value[0] = chip->mic_level; 48 return 0; 49 } 50 51 static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 52 { 53 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 54 struct snd_vxpocket *chip = to_vxpocket(_chip); 55 unsigned int val = ucontrol->value.integer.value[0]; 56 57 if (val > MIC_LEVEL_MAX) 58 return -EINVAL; 59 mutex_lock(&_chip->mixer_mutex); 60 if (chip->mic_level != ucontrol->value.integer.value[0]) { 61 vx_set_mic_level(_chip, ucontrol->value.integer.value[0]); 62 chip->mic_level = ucontrol->value.integer.value[0]; 63 mutex_unlock(&_chip->mixer_mutex); 64 return 1; 65 } 66 mutex_unlock(&_chip->mixer_mutex); 67 return 0; 68 } 69 70 static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); 71 72 static const struct snd_kcontrol_new vx_control_mic_level = { 73 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 74 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 75 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 76 .name = "Mic Capture Volume", 77 .info = vx_mic_level_info, 78 .get = vx_mic_level_get, 79 .put = vx_mic_level_put, 80 .tlv = { .p = db_scale_mic }, 81 }; 82 83 /* 84 * mic boost level control (for VXP440) 85 */ 86 #define vx_mic_boost_info snd_ctl_boolean_mono_info 87 88 static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 89 { 90 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 91 struct snd_vxpocket *chip = to_vxpocket(_chip); 92 ucontrol->value.integer.value[0] = chip->mic_level; 93 return 0; 94 } 95 96 static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 97 { 98 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 99 struct snd_vxpocket *chip = to_vxpocket(_chip); 100 int val = !!ucontrol->value.integer.value[0]; 101 mutex_lock(&_chip->mixer_mutex); 102 if (chip->mic_level != val) { 103 vx_set_mic_boost(_chip, val); 104 chip->mic_level = val; 105 mutex_unlock(&_chip->mixer_mutex); 106 return 1; 107 } 108 mutex_unlock(&_chip->mixer_mutex); 109 return 0; 110 } 111 112 static const struct snd_kcontrol_new vx_control_mic_boost = { 113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 114 .name = "Mic Boost", 115 .info = vx_mic_boost_info, 116 .get = vx_mic_boost_get, 117 .put = vx_mic_boost_put, 118 }; 119 120 121 int vxp_add_mic_controls(struct vx_core *_chip) 122 { 123 struct snd_vxpocket *chip = to_vxpocket(_chip); 124 int err; 125 126 /* mute input levels */ 127 chip->mic_level = 0; 128 switch (_chip->type) { 129 case VX_TYPE_VXPOCKET: 130 vx_set_mic_level(_chip, 0); 131 break; 132 case VX_TYPE_VXP440: 133 vx_set_mic_boost(_chip, 0); 134 break; 135 } 136 137 /* mic level */ 138 switch (_chip->type) { 139 case VX_TYPE_VXPOCKET: 140 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0) 141 return err; 142 break; 143 case VX_TYPE_VXP440: 144 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip))) < 0) 145 return err; 146 break; 147 } 148 149 return 0; 150 } 151 152