• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/sound/pcmcia/vx/
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 */
34static 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
43static 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 = (struct snd_vxpocket *)_chip;
47	ucontrol->value.integer.value[0] = chip->mic_level;
48	return 0;
49}
50
51static 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 = (struct snd_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
70static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0);
71
72static 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
88static 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 = (struct snd_vxpocket *)_chip;
92	ucontrol->value.integer.value[0] = chip->mic_level;
93	return 0;
94}
95
96static 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 = (struct snd_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
112static 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
121int vxp_add_mic_controls(struct vx_core *_chip)
122{
123	struct snd_vxpocket *chip = (struct snd_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