Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for Digigram VXpocket soundcards
0004  *
0005  * VX-pocket mixer
0006  *
0007  * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
0008  */
0009 
0010 #include <sound/core.h>
0011 #include <sound/control.h>
0012 #include <sound/tlv.h>
0013 #include "vxpocket.h"
0014 
0015 #define MIC_LEVEL_MIN   0
0016 #define MIC_LEVEL_MAX   8
0017 
0018 /*
0019  * mic level control (for VXPocket)
0020  */
0021 static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0022 {
0023     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0024     uinfo->count = 1;
0025     uinfo->value.integer.min = 0;
0026     uinfo->value.integer.max = MIC_LEVEL_MAX;
0027     return 0;
0028 }
0029 
0030 static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0031 {
0032     struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
0033     struct snd_vxpocket *chip = to_vxpocket(_chip);
0034     ucontrol->value.integer.value[0] = chip->mic_level;
0035     return 0;
0036 }
0037 
0038 static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0039 {
0040     struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
0041     struct snd_vxpocket *chip = to_vxpocket(_chip);
0042     unsigned int val = ucontrol->value.integer.value[0];
0043 
0044     if (val > MIC_LEVEL_MAX)
0045         return -EINVAL;
0046     mutex_lock(&_chip->mixer_mutex);
0047     if (chip->mic_level != ucontrol->value.integer.value[0]) {
0048         vx_set_mic_level(_chip, ucontrol->value.integer.value[0]);
0049         chip->mic_level = ucontrol->value.integer.value[0];
0050         mutex_unlock(&_chip->mixer_mutex);
0051         return 1;
0052     }
0053     mutex_unlock(&_chip->mixer_mutex);
0054     return 0;
0055 }
0056 
0057 static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0);
0058 
0059 static const struct snd_kcontrol_new vx_control_mic_level = {
0060     .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0061     .access =   (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0062              SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0063     .name =     "Mic Capture Volume",
0064     .info =     vx_mic_level_info,
0065     .get =      vx_mic_level_get,
0066     .put =      vx_mic_level_put,
0067     .tlv = { .p = db_scale_mic },
0068 };
0069 
0070 /*
0071  * mic boost level control (for VXP440)
0072  */
0073 #define vx_mic_boost_info       snd_ctl_boolean_mono_info
0074 
0075 static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0076 {
0077     struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
0078     struct snd_vxpocket *chip = to_vxpocket(_chip);
0079     ucontrol->value.integer.value[0] = chip->mic_level;
0080     return 0;
0081 }
0082 
0083 static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0084 {
0085     struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
0086     struct snd_vxpocket *chip = to_vxpocket(_chip);
0087     int val = !!ucontrol->value.integer.value[0];
0088     mutex_lock(&_chip->mixer_mutex);
0089     if (chip->mic_level != val) {
0090         vx_set_mic_boost(_chip, val);
0091         chip->mic_level = val;
0092         mutex_unlock(&_chip->mixer_mutex);
0093         return 1;
0094     }
0095     mutex_unlock(&_chip->mixer_mutex);
0096     return 0;
0097 }
0098 
0099 static const struct snd_kcontrol_new vx_control_mic_boost = {
0100     .iface =    SNDRV_CTL_ELEM_IFACE_MIXER,
0101     .name =     "Mic Boost",
0102     .info =     vx_mic_boost_info,
0103     .get =      vx_mic_boost_get,
0104     .put =      vx_mic_boost_put,
0105 };
0106 
0107 
0108 int vxp_add_mic_controls(struct vx_core *_chip)
0109 {
0110     struct snd_vxpocket *chip = to_vxpocket(_chip);
0111     int err;
0112 
0113     /* mute input levels */
0114     chip->mic_level = 0;
0115     switch (_chip->type) {
0116     case VX_TYPE_VXPOCKET:
0117         vx_set_mic_level(_chip, 0);
0118         break;
0119     case VX_TYPE_VXP440:
0120         vx_set_mic_boost(_chip, 0);
0121         break;
0122     }
0123 
0124     /* mic level */
0125     switch (_chip->type) {
0126     case VX_TYPE_VXPOCKET:
0127         err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip));
0128         if (err < 0)
0129             return err;
0130         break;
0131     case VX_TYPE_VXP440:
0132         err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip));
0133         if (err < 0)
0134             return err;
0135         break;
0136     }
0137 
0138     return 0;
0139 }
0140