diff options
author | Torsten Schenk <torsten.schenk@zoho.com> | 2012-02-22 09:21:30 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-02-22 09:51:26 -0500 |
commit | 06bb4e7435019ff9b6dbc9b1d02d8babb36d8177 (patch) | |
tree | 535666c0d9876fae32ed4e43e410cf36f0ad993e /sound/usb | |
parent | d97c735a1047fa06165e55da32154cf0e6b9419c (diff) |
ALSA: snd-usb-6fire: add analog input volume control
Add a stereo volume control for analog input channel pair 1/2.
Signed-off-by: Torsten Schenk <torsten.schenk@zoho.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/6fire/control.c | 71 | ||||
-rw-r--r-- | sound/usb/6fire/control.h | 2 |
2 files changed, 73 insertions, 0 deletions
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index a2bbf48c6413..07ed914d5e71 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c | |||
@@ -55,6 +55,7 @@ static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; | |||
55 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; | 55 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; |
56 | 56 | ||
57 | static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0); | 57 | static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0); |
58 | static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500); | ||
58 | 59 | ||
59 | enum { | 60 | enum { |
60 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 | 61 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 |
@@ -82,6 +83,20 @@ static void usb6fire_control_output_mute_update(struct control_runtime *rt) | |||
82 | comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute); | 83 | comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute); |
83 | } | 84 | } |
84 | 85 | ||
86 | static void usb6fire_control_input_vol_update(struct control_runtime *rt) | ||
87 | { | ||
88 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
89 | int i; | ||
90 | |||
91 | if (comm_rt) | ||
92 | for (i = 0; i < 2; i++) | ||
93 | if (!(rt->ivol_updated & (1 << i))) { | ||
94 | comm_rt->write8(comm_rt, 0x12, 0x1c + i, | ||
95 | rt->input_vol[i] & 0x3f); | ||
96 | rt->ivol_updated |= 1 << i; | ||
97 | } | ||
98 | } | ||
99 | |||
85 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) | 100 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) |
86 | { | 101 | { |
87 | struct comm_runtime *comm_rt = rt->chip->comm; | 102 | struct comm_runtime *comm_rt = rt->chip->comm; |
@@ -261,6 +276,50 @@ static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol, | |||
261 | return 0; | 276 | return 0; |
262 | } | 277 | } |
263 | 278 | ||
279 | static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol, | ||
280 | struct snd_ctl_elem_info *uinfo) | ||
281 | { | ||
282 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
283 | uinfo->count = 2; | ||
284 | uinfo->value.integer.min = 0; | ||
285 | uinfo->value.integer.max = 30; | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol, | ||
290 | struct snd_ctl_elem_value *ucontrol) | ||
291 | { | ||
292 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
293 | int changed = 0; | ||
294 | |||
295 | if (rt->input_vol[0] != ucontrol->value.integer.value[0]) { | ||
296 | rt->input_vol[0] = ucontrol->value.integer.value[0] - 15; | ||
297 | rt->ivol_updated &= ~(1 << 0); | ||
298 | changed = 1; | ||
299 | } | ||
300 | if (rt->input_vol[1] != ucontrol->value.integer.value[1]) { | ||
301 | rt->input_vol[1] = ucontrol->value.integer.value[1] - 15; | ||
302 | rt->ivol_updated &= ~(1 << 1); | ||
303 | changed = 1; | ||
304 | } | ||
305 | |||
306 | if (changed) | ||
307 | usb6fire_control_input_vol_update(rt); | ||
308 | |||
309 | return changed; | ||
310 | } | ||
311 | |||
312 | static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, | ||
313 | struct snd_ctl_elem_value *ucontrol) | ||
314 | { | ||
315 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
316 | |||
317 | ucontrol->value.integer.value[0] = rt->input_vol[0] + 15; | ||
318 | ucontrol->value.integer.value[1] = rt->input_vol[1] + 15; | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
264 | static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, | 323 | static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, |
265 | struct snd_ctl_elem_info *uinfo) | 324 | struct snd_ctl_elem_info *uinfo) |
266 | { | 325 | { |
@@ -454,6 +513,17 @@ static struct __devinitdata snd_kcontrol_new elements[] = { | |||
454 | .get = usb6fire_control_digital_thru_get, | 513 | .get = usb6fire_control_digital_thru_get, |
455 | .put = usb6fire_control_digital_thru_put | 514 | .put = usb6fire_control_digital_thru_put |
456 | }, | 515 | }, |
516 | { | ||
517 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
518 | .name = "Analog Capture Volume", | ||
519 | .index = 0, | ||
520 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
521 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
522 | .info = usb6fire_control_input_vol_info, | ||
523 | .get = usb6fire_control_input_vol_get, | ||
524 | .put = usb6fire_control_input_vol_put, | ||
525 | .tlv = { .p = tlv_input } | ||
526 | }, | ||
457 | {} | 527 | {} |
458 | }; | 528 | }; |
459 | 529 | ||
@@ -518,6 +588,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) | |||
518 | usb6fire_control_line_phono_update(rt); | 588 | usb6fire_control_line_phono_update(rt); |
519 | usb6fire_control_output_vol_update(rt); | 589 | usb6fire_control_output_vol_update(rt); |
520 | usb6fire_control_output_mute_update(rt); | 590 | usb6fire_control_output_mute_update(rt); |
591 | usb6fire_control_input_vol_update(rt); | ||
521 | usb6fire_control_streaming_update(rt); | 592 | usb6fire_control_streaming_update(rt); |
522 | 593 | ||
523 | ret = usb6fire_control_add_virtual(rt, chip->card, | 594 | ret = usb6fire_control_add_virtual(rt, chip->card, |
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h index 9f9eb647bc6b..9a596d95474a 100644 --- a/sound/usb/6fire/control.h +++ b/sound/usb/6fire/control.h | |||
@@ -46,6 +46,8 @@ struct control_runtime { | |||
46 | u8 output_vol[6]; | 46 | u8 output_vol[6]; |
47 | u8 ovol_updated; | 47 | u8 ovol_updated; |
48 | u8 output_mute; | 48 | u8 output_mute; |
49 | s8 input_vol[2]; | ||
50 | u8 ivol_updated; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | int __devinit usb6fire_control_init(struct sfire_chip *chip); | 53 | int __devinit usb6fire_control_init(struct sfire_chip *chip); |