2 * sound/arm/omap/omap-alsa-tsc2101-mixer.c
4 * Alsa Driver for TSC2101 codec for OMAP platform boards.
6 * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi> and
7 * Everett Coleman II <gcc80x86@fuzzyneural.net>
9 * Board initialization code is based on the code in TSC2101 OSS driver.
10 * Copyright (C) 2004 Texas Instruments, Inc.
11 * Written by Nishanth Menon and Sriram Kannan
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 * 2006-03-01 Mika Laitio - Mixer for the tsc2101 driver used in omap boards.
36 * Can switch between headset and loudspeaker playback,
37 * mute and unmute dgc, set dgc volume. Record source switch,
38 * keyclick, buzzer and headset volume and handset volume control
43 #include "omap-alsa-tsc2101.h"
44 #include "omap-alsa-tsc2101-mixer.h"
46 #include <linux/types.h>
47 #include <sound/initval.h>
48 #include <sound/control.h>
50 //#define M_DPRINTK(ARGS...) printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
51 #define M_DPRINTK(ARGS...) /* nop */
53 #define CHECK_BIT(INDX, ARG) (((ARG) & TSC2101_BIT(INDX)) >> INDX)
54 #define IS_UNMUTED(INDX, ARG) (((CHECK_BIT(INDX, ARG)) == 0))
56 #define DGC_DALVL_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
57 #define DGC_DARVL_EXTRACT(ARG) ((ARG & 0x007f))
59 #define HGC_ADPGA_HED_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
60 #define HNGC_ADPGA_HND_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
61 #define BGC_ADPGA_BGC_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
63 static int current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
64 static int current_rec_src = REC_SRC_SINGLE_ENDED_MICIN_HED;
67 * Simplified write for the tsc2101 audio registers.
69 inline void omap_tsc2101_audio_write(u8 address, u16 data)
71 omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data);
75 * Simplified read for the tsc2101 audio registers.
77 inline u16 omap_tsc2101_audio_read(u8 address)
79 return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address));
83 * For selecting tsc2101 recourd source.
85 static void set_record_source(int val)
89 /* Mute Analog Sidetone
90 * Analog sidetone gain db?
91 * Cell Phone In not connected to ADC
92 * Input selected by MICSEL connected to ADC
94 data = MPC_ASTMU | MPC_ASTG(0x45);
95 data &= ~MPC_MICSEL(7); /* clear all MICSEL bits */
96 data |= MPC_MICSEL(val);
98 omap_tsc2101_audio_write(TSC2101_MIXER_PGA_CTRL, data);
100 current_rec_src = val;
104 * Converts the Alsa mixer volume (0 - 100) to real
105 * Digital Gain Control (DGC) value that can be written
106 * or read from the TSC2101 registry.
108 * Note that the number "OUTPUT_VOLUME_MAX" is smaller than OUTPUT_VOLUME_MIN
109 * because DGC works as a volume decreaser. (The more bigger value is put
110 * to DGC, the more the volume of controlled channel is decreased)
112 * In addition the TCS2101 chip would allow the maximum volume reduction be 63.5 DB
113 * but according to some tests user can not hear anything with this chip
114 * when the volume is set to be less than 25 db.
115 * Therefore this function will return a value that means 38.5 db (63.5 db - 25 db)
116 * reduction in the channel volume, when mixer is set to 0.
117 * For mixer value 100, this will return a value that means 0 db volume reduction.
118 * ([mute_left_bit]0000000[mute_right_bit]0000000)
120 int get_mixer_volume_as_dac_gain_control_volume(int vol)
124 /* Convert 0 -> 100 volume to 0x7F(min) -> y(max) volume range */
125 retVal = ((vol * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MAX;
126 /* invert the value for getting the proper range 0 min and 100 max */
127 retVal = OUTPUT_VOLUME_MIN - retVal;
133 * Converts the Alsa mixer volume (0 - 100) to TSC2101
134 * Digital Gain Control (DGC) volume. Alsa mixer volume 0
135 * is converted to value meaning the volume reduction of -38.5 db
136 * and Alsa mixer volume 100 is converted to value meaning the
139 int set_mixer_volume_as_dac_gain_control_volume(int mixerVolL, int mixerVolR)
146 if ((mixerVolL < 0) ||
150 printk(KERN_ERR "Trying a bad mixer volume as dac gain control volume value, left (%d), right (%d)!\n", mixerVolL, mixerVolR);
153 M_DPRINTK("mixer volume left = %d, right = %d\n", mixerVolL, mixerVolR);
154 volL = get_mixer_volume_as_dac_gain_control_volume(mixerVolL);
155 volR = get_mixer_volume_as_dac_gain_control_volume(mixerVolR);
157 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
158 /* keep the old mute bit settings */
159 val &= ~(DGC_DALVL(OUTPUT_VOLUME_MIN) | DGC_DARVL(OUTPUT_VOLUME_MIN));
160 val |= DGC_DALVL(volL) | DGC_DARVL(volR);
163 omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
165 M_DPRINTK("to registry: left = %d, right = %d, total = %d\n", DGC_DALVL_EXTRACT(val), DGC_DARVL_EXTRACT(val), val);
170 * If unmuteLeft/unmuteRight == 0 --> mute
171 * If unmuteLeft/unmuteRight == 1 --> unmute
173 int dac_gain_control_unmute(int unmuteLeft, int unmuteRight)
179 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
180 /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
181 * so if values are same, it's time to change the registry value.
183 if (unmuteLeft != IS_UNMUTED(15, val)) {
184 if (unmuteLeft == 0) {
185 /* mute --> turn bit on */
186 val = val | DGC_DALMU;
189 /* unmute --> turn bit off */
190 val = val & ~DGC_DALMU;
194 if (unmuteRight != IS_UNMUTED(7, val)) {
195 if (unmuteRight == 0) {
196 /* mute --> turn bit on */
197 val = val | DGC_DARMU;
200 /* unmute --> turn bit off */
201 val = val & ~DGC_DARMU;
206 omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
207 M_DPRINTK("changed value, is_unmuted left = %d, right = %d\n",
215 * unmute: 0 --> mute, 1 --> unmute
216 * page2RegIndx: Registry index in tsc2101 page2.
217 * muteBitIndx: Index number for the bit in registry that indicates whether muted or unmuted.
219 int adc_pga_unmute_control(int unmute, int page2regIndx, int muteBitIndx)
225 val = omap_tsc2101_audio_read(page2regIndx);
226 /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
227 * so if the values are same, it's time to change the registry value...
229 if (unmute != IS_UNMUTED(muteBitIndx, val)) {
231 /* mute --> turn bit on */
232 val = val | TSC2101_BIT(muteBitIndx);
235 /* unmute --> turn bit off */
236 val = val & ~TSC2101_BIT(muteBitIndx);
238 M_DPRINTK("changed value, is_unmuted = %d\n", IS_UNMUTED(muteBitIndx, val));
242 omap_tsc2101_audio_write(page2regIndx, val);
248 * Converts the DGC registry value read from the TSC2101 registry to
249 * Alsa mixer volume format (0 - 100).
251 int get_dac_gain_control_volume_as_mixer_volume(u16 vol)
255 retVal = OUTPUT_VOLUME_MIN - vol;
256 retVal = ((retVal - OUTPUT_VOLUME_MAX) * 100) / OUTPUT_VOLUME_RANGE;
257 /* fix scaling error */
258 if ((retVal > 0) && (retVal < 100)) {
265 * Converts the headset gain control volume (0 - 63.5 db)
266 * to Alsa mixer volume (0 - 100)
268 int get_headset_gain_control_volume_as_mixer_volume(u16 registerVal)
272 retVal = ((registerVal * 100) / INPUT_VOLUME_RANGE);
277 * Converts the handset gain control volume (0 - 63.5 db)
278 * to Alsa mixer volume (0 - 100)
280 int get_handset_gain_control_volume_as_mixer_volume(u16 registerVal)
282 return get_headset_gain_control_volume_as_mixer_volume(registerVal);
286 * Converts the Alsa mixer volume (0 - 100) to
287 * headset gain control volume (0 - 63.5 db)
289 int get_mixer_volume_as_headset_gain_control_volume(u16 mixerVal)
293 retVal = ((mixerVal * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
298 * Writes Alsa mixer volume (0 - 100) to TSC2101 headset volume registry in
299 * a TSC2101 format. (0 - 63.5 db)
300 * In TSC2101 OSS driver this functionality was controlled with "SET_LINE" parameter.
302 int set_mixer_volume_as_headset_gain_control_volume(int mixerVol)
308 if (mixerVol < 0 || mixerVol > 100) {
309 M_DPRINTK("Trying a bad headset mixer volume value(%d)!\n", mixerVol);
312 M_DPRINTK("mixer volume = %d\n", mixerVol);
313 /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */
314 /* NOTE: 0 is minimum volume and not mute */
315 volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
316 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
317 /* preserve the old mute settings */
318 val &= ~(HGC_ADPGA_HED(INPUT_VOLUME_MAX));
319 val |= HGC_ADPGA_HED(volume);
320 omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
323 M_DPRINTK("to registry = %d\n", val);
328 * Writes Alsa mixer volume (0 - 100) to TSC2101 handset volume registry in
329 * a TSC2101 format. (0 - 63.5 db)
330 * In TSC2101 OSS driver this functionality was controlled with "SET_MIC" parameter.
332 int set_mixer_volume_as_handset_gain_control_volume(int mixerVol)
338 if (mixerVol < 0 || mixerVol > 100) {
339 M_DPRINTK("Trying a bad mic mixer volume value(%d)!\n", mixerVol);
342 M_DPRINTK("mixer volume = %d\n", mixerVol);
343 /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range
344 * NOTE: 0 is minimum volume and not mute
346 volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
347 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
348 /* preserve the old mute settigns */
349 val &= ~(HNGC_ADPGA_HND(INPUT_VOLUME_MAX));
350 val |= HNGC_ADPGA_HND(volume);
351 omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
354 M_DPRINTK("to registry = %d\n", val);
358 void set_loudspeaker_to_playback_target(void)
360 /* power down SPK1, SPK2 and loudspeaker */
361 omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
362 CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
363 /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
367 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
369 /* DAC left and right routed to SPK1/SPK2
371 * Keyclicks routed to SPK1/SPK2 */
372 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
374 AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
375 AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2);
377 /* routing selected to SPK1 goes also to OUT8P/OUT8N. (loudspeaker)
378 * analog sidetone routed to loudspeaker
379 * buzzer pga routed to loudspeaker
380 * keyclick routing to loudspeaker
381 * cellphone input routed to loudspeaker
382 * mic selection (control register 04h/page2) routed to cell phone output (CP_OUT)
383 * routing selected for SPK1 goes also to cellphone output (CP_OUT)
384 * OUT8P/OUT8N (loudspeakers) unmuted (0 = unmuted)
385 * Cellphone output is not muted (0 = unmuted)
386 * Enable loudspeaker short protection control (0 = enable protection)
387 * VGND short protection control (0 = enable protection)
389 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
390 AC6_SPL2LSK | AC6_AST2LSK | AC6_BUZ2LSK | AC6_KCL2LSK |
391 AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO);
392 current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
395 void set_headphone_to_playback_target(void)
397 /* power down SPK1, SPK2 and loudspeaker */
398 omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
399 CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
400 /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */
401 /* 1dB AGC hysteresis */
403 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
405 /* DAC left and right routed to SPK1/SPK2
407 * Keyclicks routed to SPK1/SPK2 */
408 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
409 AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
410 AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
413 /* OUT8P/OUT8N muted, CPOUT muted */
414 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
415 AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
417 current_playback_target = PLAYBACK_TARGET_HEADPHONE;
421 * Checks whether the headset is detected.
422 * If headset is detected, the type is returned. Type can be
423 * 0x01 = stereo headset detected
424 * 0x02 = cellurar headset detected
425 * 0x03 = stereo + cellurar headset detected
426 * If headset is not detected 0 is returned.
428 u16 get_headset_detected(void)
434 curType = 0; /* not detected */
435 curVal = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_7);
436 curDetected = curVal & AC7_HDDETFL;
438 printk("headset detected, checking type from %d \n", curVal);
439 curType = ((curVal & 0x6000) >> 13);
440 printk("headset type detected = %d \n", curType);
443 printk("headset not detected\n");
448 void init_playback_targets(void)
452 set_loudspeaker_to_playback_target();
453 /* Left line input volume control
454 * = SET_LINE in the OSS driver
456 set_mixer_volume_as_headset_gain_control_volume(DEFAULT_INPUT_VOLUME);
458 /* Set headset to be controllable by handset mixer
459 * AGC enable for handset input
460 * Handset input not muted
462 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
463 val = val | HNGC_AGCEN_HND;
464 val = val & ~HNGC_ADMUT_HND;
465 omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
467 /* mic input volume control
468 * SET_MIC in the OSS driver
470 set_mixer_volume_as_handset_gain_control_volume(DEFAULT_INPUT_VOLUME);
472 /* Left/Right headphone channel volume control
473 * Zero-cross detect on
475 set_mixer_volume_as_dac_gain_control_volume(DEFAULT_OUTPUT_VOLUME, DEFAULT_OUTPUT_VOLUME);
477 dac_gain_control_unmute(1, 1);
481 * Initializes tsc2101 recourd source (to line) and playback target (to loudspeaker)
483 void snd_omap_init_mixer(void)
487 /* Headset/Hook switch detect enabled */
488 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, AC7_DETECT);
490 /* Select headset to record source (MIC_INHED)*/
491 set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
492 /* Init loudspeaker as a default playback target*/
493 init_playback_targets();
498 static int __pcm_playback_target_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
500 static char *texts[PLAYBACK_TARGET_COUNT] = {
501 "Loudspeaker", "Headphone"
504 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
506 uinfo->value.enumerated.items = PLAYBACK_TARGET_COUNT;
507 if (uinfo->value.enumerated.item > PLAYBACK_TARGET_COUNT - 1) {
508 uinfo->value.enumerated.item = PLAYBACK_TARGET_COUNT - 1;
510 strcpy(uinfo->value.enumerated.name,
511 texts[uinfo->value.enumerated.item]);
515 static int __pcm_playback_target_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
517 ucontrol->value.integer.value[0] = current_playback_target;
521 static int __pcm_playback_target_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
527 curVal = ucontrol->value.integer.value[0];
529 (curVal < PLAYBACK_TARGET_COUNT) &&
530 (curVal != current_playback_target)) {
532 set_loudspeaker_to_playback_target();
535 set_headphone_to_playback_target();
542 static int __pcm_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
544 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
546 uinfo->value.integer.min = 0;
547 uinfo->value.integer.max = 100;
552 * Alsa mixer interface function for getting the volume read from the DGC in a
553 * 0 -100 alsa mixer format.
555 static int __pcm_playback_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
561 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
562 M_DPRINTK("registry value = %d!\n", val);
563 volL = DGC_DALVL_EXTRACT(val);
564 volR = DGC_DARVL_EXTRACT(val);
565 /* make sure that other bits are not on */
566 volL = volL & ~DGC_DALMU;
567 volR = volR & ~DGC_DARMU;
569 volL = get_dac_gain_control_volume_as_mixer_volume(volL);
570 volR = get_dac_gain_control_volume_as_mixer_volume(volR);
572 ucontrol->value.integer.value[0] = volL; /* L */
573 ucontrol->value.integer.value[1] = volR; /* R */
575 M_DPRINTK("mixer volume left = %ld, right = %ld\n", ucontrol->value.integer.value[0], ucontrol->value.integer.value[1]);
579 static int __pcm_playback_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
581 return set_mixer_volume_as_dac_gain_control_volume(ucontrol->value.integer.value[0],
582 ucontrol->value.integer.value[1]);
585 static int __pcm_playback_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
587 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
589 uinfo->value.integer.min = 0;
590 uinfo->value.integer.max = 1;
595 * When DGC_DALMU (bit 15) is 1, the left channel is muted.
596 * When DGC_DALMU is 0, left channel is not muted.
597 * Same logic apply also for the right channel.
599 static int __pcm_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
601 u16 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
603 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); // left
604 ucontrol->value.integer.value[1] = IS_UNMUTED(7, val); // right
608 static int __pcm_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
610 return dac_gain_control_unmute(ucontrol->value.integer.value[0],
611 ucontrol->value.integer.value[1]);
614 static int __headset_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
616 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
618 uinfo->value.integer.min = 0;
619 uinfo->value.integer.max = 100;
623 static int __headset_playback_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
628 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
629 M_DPRINTK("registry value = %d\n", val);
630 vol = HGC_ADPGA_HED_EXTRACT(val);
631 vol = vol & ~HGC_ADMUT_HED;
633 vol = get_headset_gain_control_volume_as_mixer_volume(vol);
634 ucontrol->value.integer.value[0] = vol;
636 M_DPRINTK("mixer volume returned = %ld\n", ucontrol->value.integer.value[0]);
640 static int __headset_playback_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
642 return set_mixer_volume_as_headset_gain_control_volume(ucontrol->value.integer.value[0]);
645 static int __headset_playback_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
647 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
649 uinfo->value.integer.min = 0;
650 uinfo->value.integer.max = 1;
654 /* When HGC_ADMUT_HED (bit 15) is 1, the headset is muted.
655 * When HGC_ADMUT_HED is 0, headset is not muted.
657 static int __headset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
659 u16 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
660 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
664 static int __headset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
666 // mute/unmute headset
667 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
668 TSC2101_HEADSET_GAIN_CTRL,
672 static int __handset_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
674 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
676 uinfo->value.integer.min = 0;
677 uinfo->value.integer.max = 100;
681 static int __handset_playback_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
686 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
687 M_DPRINTK("registry value = %d\n", val);
688 vol = HNGC_ADPGA_HND_EXTRACT(val);
689 vol = vol & ~HNGC_ADMUT_HND;
690 vol = get_handset_gain_control_volume_as_mixer_volume(vol);
691 ucontrol->value.integer.value[0] = vol;
693 M_DPRINTK("mixer volume returned = %ld\n", ucontrol->value.integer.value[0]);
697 static int __handset_playback_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
699 return set_mixer_volume_as_handset_gain_control_volume(ucontrol->value.integer.value[0]);
702 static int __handset_playback_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
704 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
706 uinfo->value.integer.min = 0;
707 uinfo->value.integer.max = 1;
711 /* When HNGC_ADMUT_HND (bit 15) is 1, the handset is muted.
712 * When HNGC_ADMUT_HND is 0, handset is not muted.
714 static int __handset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
716 u16 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
717 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
721 static int __handset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
723 // handset mute/unmute
724 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
725 TSC2101_HANDSET_GAIN_CTRL,
729 static snd_kcontrol_new_t tsc2101_control[] __devinitdata = {
731 .name = "Target Playback Route",
732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
734 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
735 .info = __pcm_playback_target_info,
736 .get = __pcm_playback_target_get,
737 .put = __pcm_playback_target_put,
739 .name = "Master Playback Volume",
740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
742 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
743 .info = __pcm_playback_volume_info,
744 .get = __pcm_playback_volume_get,
745 .put = __pcm_playback_volume_put,
747 .name = "Master Playback Switch",
748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
750 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
751 .info = __pcm_playback_switch_info,
752 .get = __pcm_playback_switch_get,
753 .put = __pcm_playback_switch_put,
755 .name = "Headset Playback Volume",
756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
758 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
759 .info = __headset_playback_volume_info,
760 .get = __headset_playback_volume_get,
761 .put = __headset_playback_volume_put,
763 .name = "Headset Playback Switch",
764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
766 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
767 .info = __headset_playback_switch_info,
768 .get = __headset_playback_switch_get,
769 .put = __headset_playback_switch_put,
771 .name = "Handset Playback Volume",
772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
774 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
775 .info = __handset_playback_volume_info,
776 .get = __handset_playback_volume_get,
777 .put = __handset_playback_volume_put,
779 .name = "Handset Playback Switch",
780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
782 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
783 .info = __handset_playback_switch_info,
784 .get = __handset_playback_switch_get,
785 .put = __handset_playback_switch_put,
791 void snd_omap_suspend_mixer(void)
795 void snd_omap_resume_mixer(void)
797 snd_omap_init_mixer();
801 int snd_omap_mixer(struct snd_card_omap_codec *tsc2101)
809 for (i=0; i < ARRAY_SIZE(tsc2101_control); i++) {
810 if ((err = snd_ctl_add(tsc2101->card,
811 snd_ctl_new1(&tsc2101_control[i],
812 tsc2101->card))) < 0) {