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/driver.h> 24 #include <sound/core.h> 25 #include <sound/control.h> 26 #include <sound/tlv.h> 27 #include "vxpocket.h" 28 29 #define MIC_LEVEL_MIN 0 30 #define MIC_LEVEL_MAX 8 31 32 /* 33 * mic level control (for VXPocket) 34 */ 35 static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 36 { 37 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 38 uinfo->count = 1; 39 uinfo->value.integer.min = 0; 40 uinfo->value.integer.max = MIC_LEVEL_MAX; 41 return 0; 42 } 43 44 static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 45 { 46 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 47 struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; 48 ucontrol->value.integer.value[0] = chip->mic_level; 49 return 0; 50 } 51 52 static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 53 { 54 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 55 struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; 56 mutex_lock(&_chip->mixer_mutex); 57 if (chip->mic_level != ucontrol->value.integer.value[0]) { 58 vx_set_mic_level(_chip, ucontrol->value.integer.value[0]); 59 chip->mic_level = ucontrol->value.integer.value[0]; 60 mutex_unlock(&_chip->mixer_mutex); 61 return 1; 62 } 63 mutex_unlock(&_chip->mixer_mutex); 64 return 0; 65 } 66 67 static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); 68 69 static struct snd_kcontrol_new vx_control_mic_level = { 70 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 71 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 72 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 73 .name = "Mic Capture Volume", 74 .info = vx_mic_level_info, 75 .get = vx_mic_level_get, 76 .put = vx_mic_level_put, 77 .tlv = { .p = db_scale_mic }, 78 }; 79 80 /* 81 * mic boost level control (for VXP440) 82 */ 83 static int vx_mic_boost_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 84 { 85 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 86 uinfo->count = 1; 87 uinfo->value.integer.min = 0; 88 uinfo->value.integer.max = 1; 89 return 0; 90 } 91 92 static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 93 { 94 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 95 struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; 96 ucontrol->value.integer.value[0] = chip->mic_level; 97 return 0; 98 } 99 100 static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 101 { 102 struct vx_core *_chip = snd_kcontrol_chip(kcontrol); 103 struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; 104 mutex_lock(&_chip->mixer_mutex); 105 if (chip->mic_level != ucontrol->value.integer.value[0]) { 106 vx_set_mic_boost(_chip, ucontrol->value.integer.value[0]); 107 chip->mic_level = ucontrol->value.integer.value[0]; 108 mutex_unlock(&_chip->mixer_mutex); 109 return 1; 110 } 111 mutex_unlock(&_chip->mixer_mutex); 112 return 0; 113 } 114 115 static struct snd_kcontrol_new vx_control_mic_boost = { 116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 117 .name = "Mic Boost", 118 .info = vx_mic_boost_info, 119 .get = vx_mic_boost_get, 120 .put = vx_mic_boost_put, 121 }; 122 123 124 int vxp_add_mic_controls(struct vx_core *_chip) 125 { 126 struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; 127 int err; 128 129 /* mute input levels */ 130 chip->mic_level = 0; 131 switch (_chip->type) { 132 case VX_TYPE_VXPOCKET: 133 vx_set_mic_level(_chip, 0); 134 break; 135 case VX_TYPE_VXP440: 136 vx_set_mic_boost(_chip, 0); 137 break; 138 } 139 140 /* mic level */ 141 switch (_chip->type) { 142 case VX_TYPE_VXPOCKET: 143 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0) 144 return err; 145 break; 146 case VX_TYPE_VXP440: 147 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip))) < 0) 148 return err; 149 break; 150 } 151 152 return 0; 153 } 154 155