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/spi/tsc2101.h>
47 #include <linux/types.h>
48 #include <sound/initval.h>
49 #include <sound/control.h>
52 #define M_DPRINTK(ARGS...) \
54 printk(KERN_INFO "<%s>: ", __func__); \
58 #define M_DPRINTK(ARGS...) /* nop */
61 #define CHECK_BIT(INDX, ARG) (((ARG) & TSC2101_BIT(INDX)) >> INDX)
62 #define IS_UNMUTED(INDX, ARG) (((CHECK_BIT(INDX, ARG)) == 0))
64 #define DGC_DALVL_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
65 #define DGC_DARVL_EXTRACT(ARG) ((ARG & 0x007f))
67 #define HGC_ADPGA_HED_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
68 #define HNGC_ADPGA_HND_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
69 #define BGC_ADPGA_BGC_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
71 static int current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
72 static int current_rec_src = REC_SRC_SINGLE_ENDED_MICIN_HED;
75 * Simplified write for the tsc2101 audio registers.
77 inline void omap_tsc2101_audio_write(u8 address, u16 data)
79 tsc2101_write_sync(mcbsp_dev.tsc2101_dev, PAGE2_AUDIO_CODEC_REGISTERS,
84 * Simplified read for the tsc2101 audio registers.
86 inline u16 omap_tsc2101_audio_read(u8 address)
88 return (tsc2101_read_sync(mcbsp_dev.tsc2101_dev,
89 PAGE2_AUDIO_CODEC_REGISTERS, address));
93 * For selecting tsc2101 recourd source.
95 static void set_record_source(int val)
100 * Mute Analog Sidetone
101 * Analog sidetone gain db?
102 * Input selected by MICSEL connected to ADC
104 data = MPC_ASTMU | MPC_ASTG(0x45);
105 data &= ~MPC_MICSEL(7); /* clear all MICSEL bits */
106 data |= MPC_MICSEL(val);
108 omap_tsc2101_audio_write(TSC2101_MIXER_PGA_CTRL, data);
110 current_rec_src = val;
114 * Converts the Alsa mixer volume (0 - 100) to real
115 * Digital Gain Control (DGC) value that can be written
116 * or read from the TSC2101 registry.
118 * Note that the number "OUTPUT_VOLUME_MAX" is smaller than OUTPUT_VOLUME_MIN
119 * because DGC works as a volume decreaser. (The more bigger value is put
120 * to DGC, the more the volume of controlled channel is decreased)
122 * In addition the TCS2101 chip would allow the maximum
123 * volume reduction be 63.5 DB
124 * but according to some tests user can not hear anything with this chip
125 * when the volume is set to be less than 25 db.
126 * Therefore this function will return a value
127 * that means 38.5 db (63.5 db - 25 db)
128 * reduction in the channel volume, when mixer is set to 0.
129 * For mixer value 100, this will return a value that means
130 * 0 db volume reduction.
131 * ([mute_left_bit]0000000[mute_right_bit]0000000)
133 int get_mixer_volume_as_dac_gain_control_volume(int vol)
137 /* Convert 0 -> 100 volume to 0x7F(min) -> y(max) volume range */
138 retVal = ((vol * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MAX;
139 /* invert the value for getting the proper range 0 min and 100 max */
140 retVal = OUTPUT_VOLUME_MIN - retVal;
146 * Converts the Alsa mixer volume (0 - 100) to TSC2101
147 * Digital Gain Control (DGC) volume. Alsa mixer volume 0
148 * is converted to value meaning the volume reduction of -38.5 db
149 * and Alsa mixer volume 100 is converted to value meaning the
152 int set_mixer_volume_as_dac_gain_control_volume(int mixerVolL, int mixerVolR)
159 if ((mixerVolL < 0) ||
163 printk(KERN_ERR "Trying a bad mixer volume as dac gain control"
164 " volume value, left (%d), right (%d)!\n", mixerVolL,
168 M_DPRINTK("mixer volume left = %d, right = %d\n", mixerVolL, mixerVolR);
169 volL = get_mixer_volume_as_dac_gain_control_volume(mixerVolL);
170 volR = get_mixer_volume_as_dac_gain_control_volume(mixerVolR);
172 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
173 /* keep the old mute bit settings */
174 val &= ~(DGC_DALVL(OUTPUT_VOLUME_MIN) |
175 DGC_DARVL(OUTPUT_VOLUME_MIN));
176 val |= DGC_DALVL(volL) | DGC_DARVL(volR);
179 omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
181 M_DPRINTK("to registry: left = %d, right = %d, total = %d\n",
182 DGC_DALVL_EXTRACT(val), DGC_DARVL_EXTRACT(val), val);
187 * If unmuteLeft/unmuteRight == 0 --> mute
188 * If unmuteLeft/unmuteRight == 1 --> unmute
190 int dac_gain_control_unmute(int unmuteLeft, int unmuteRight)
196 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
198 * in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off,
199 * 0 --> on so if values are same, it's time to change the registry
202 if (unmuteLeft != IS_UNMUTED(15, val)) {
203 if (unmuteLeft == 0) {
204 /* mute --> turn bit on */
205 val = val | DGC_DALMU;
207 /* unmute --> turn bit off */
208 val = val & ~DGC_DALMU;
212 if (unmuteRight != IS_UNMUTED(7, val)) {
213 if (unmuteRight == 0) {
214 /* mute --> turn bit on */
215 val = val | DGC_DARMU;
217 /* unmute --> turn bit off */
218 val = val & ~DGC_DARMU;
223 omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
224 M_DPRINTK("changed value, is_unmuted left = %d, right = %d\n",
232 * unmute: 0 --> mute, 1 --> unmute
233 * page2RegIndx: Registry index in tsc2101 page2.
234 * muteBitIndx: Index number for the bit in registry that indicates whether
237 int adc_pga_unmute_control(int unmute, int page2regIndx, int muteBitIndx)
243 val = omap_tsc2101_audio_read(page2regIndx);
245 * in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off,
246 * 0 --> on so if the values are same, it's time to change the
249 if (unmute != IS_UNMUTED(muteBitIndx, val)) {
251 /* mute --> turn bit on */
252 val = val | TSC2101_BIT(muteBitIndx);
254 /* unmute --> turn bit off */
255 val = val & ~TSC2101_BIT(muteBitIndx);
257 M_DPRINTK("changed value, is_unmuted = %d\n",
258 IS_UNMUTED(muteBitIndx, val));
262 omap_tsc2101_audio_write(page2regIndx, val);
268 * Converts the DGC registry value read from the TSC2101 registry to
269 * Alsa mixer volume format (0 - 100).
271 int get_dac_gain_control_volume_as_mixer_volume(u16 vol)
275 retVal = OUTPUT_VOLUME_MIN - vol;
276 retVal = ((retVal - OUTPUT_VOLUME_MAX) * 100) / OUTPUT_VOLUME_RANGE;
277 /* fix scaling error */
278 if ((retVal > 0) && (retVal < 100))
285 * Converts the headset gain control volume (0 - 63.5 db)
286 * to Alsa mixer volume (0 - 100)
288 int get_headset_gain_control_volume_as_mixer_volume(u16 registerVal)
292 retVal = ((registerVal * 100) / INPUT_VOLUME_RANGE);
297 * Converts the handset gain control volume (0 - 63.5 db)
298 * to Alsa mixer volume (0 - 100)
300 int get_handset_gain_control_volume_as_mixer_volume(u16 registerVal)
302 return get_headset_gain_control_volume_as_mixer_volume(registerVal);
306 * Converts the Alsa mixer volume (0 - 100) to
307 * headset gain control volume (0 - 63.5 db)
309 int get_mixer_volume_as_headset_gain_control_volume(u16 mixerVal)
313 retVal = ((mixerVal * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
318 * Writes Alsa mixer volume (0 - 100) to TSC2101 headset volume registry in
319 * a TSC2101 format. (0 - 63.5 db)
320 * In TSC2101 OSS driver this functionality was controlled with "SET_LINE"
323 int set_mixer_volume_as_headset_gain_control_volume(int mixerVol)
329 if (mixerVol < 0 || mixerVol > 100) {
330 M_DPRINTK("Trying a bad headset mixer volume value(%d)!\n",
334 M_DPRINTK("mixer volume = %d\n", mixerVol);
336 * Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range
337 * NOTE: 0 is minimum volume and not mute
339 volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
340 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
341 /* preserve the old mute settings */
342 val &= ~(HGC_ADPGA_HED(INPUT_VOLUME_MAX));
343 val |= HGC_ADPGA_HED(volume);
344 omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
347 M_DPRINTK("to registry = %d\n", val);
352 * Writes Alsa mixer volume (0 - 100) to TSC2101 handset volume registry in
353 * a TSC2101 format. (0 - 63.5 db)
354 * In TSC2101 OSS driver this functionality was controlled with
355 * "SET_MIC" parameter.
357 int set_mixer_volume_as_handset_gain_control_volume(int mixerVol)
363 if (mixerVol < 0 || mixerVol > 100) {
364 M_DPRINTK("Trying a bad mic mixer volume value(%d)!\n",
368 M_DPRINTK("mixer volume = %d\n", mixerVol);
370 * Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range
371 * NOTE: 0 is minimum volume and not mute
373 volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
374 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
375 /* preserve the old mute settigns */
376 val &= ~(HNGC_ADPGA_HND(INPUT_VOLUME_MAX));
377 val |= HNGC_ADPGA_HND(volume);
378 omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
381 M_DPRINTK("to registry = %d\n", val);
385 void set_loudspeaker_to_playback_target(void)
387 /* power down SPK1, SPK2 and loudspeaker */
388 omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
389 CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
391 * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
395 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
398 * DAC left and right routed to SPK1/SPK2
400 * Keyclicks routed to SPK1/SPK2 */
401 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
403 AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
404 AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2);
407 * routing selected to SPK1 goes also to OUT8P/OUT8N. (loudspeaker)
408 * analog sidetone routed to loudspeaker
409 * buzzer pga routed to loudspeaker
410 * keyclick routing to loudspeaker
411 * cellphone input routed to loudspeaker
412 * mic selection (control register 04h/page2) routed to cell phone
414 * routing selected for SPK1 goes also to cellphone output (CP_OUT)
415 * OUT8P/OUT8N (loudspeakers) unmuted (0 = unmuted)
416 * Cellphone output is not muted (0 = unmuted)
417 * Enable loudspeaker short protection control (0 = enable protection)
418 * VGND short protection control (0 = enable protection)
420 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
421 AC6_SPL2LSK | AC6_AST2LSK | AC6_BUZ2LSK | AC6_KCL2LSK |
422 AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO);
423 current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
426 void set_headphone_to_playback_target(void)
428 /* power down SPK1, SPK2 and loudspeaker */
429 omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
430 CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
432 * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
433 Â * 1dB AGC hysteresis
436 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
439 * DAC left and right routed to SPK1/SPK2
441 * Keyclicks routed to SPK1/SPK2
443 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
444 AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
445 AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
448 /* OUT8P/OUT8N muted, CPOUT muted */
449 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
450 AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
452 current_playback_target = PLAYBACK_TARGET_HEADPHONE;
455 void set_telephone_to_playback_target(void)
458 * 0110 1101 0101 1100
459 * power down MICBIAS_HED, Analog sidetone, SPK2, DAC,
460 * Driver virtual ground, loudspeaker. Values D2-d5 are flags.
462 omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
463 CPC_MBIAS_HED | CPC_ASTPWD | CPC_SP2PWDN | CPC_DAPWDN |
464 CPC_VGPWDN | CPC_LSPWDN);
467 * 0010 1010 0100 0000
468 * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
472 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4,
473 AC4_MB_HND | AC4_MB_HED(0) | AC4_AGCHYS(1) |
474 AC4_BISTPD | AC4_ASSTPD | AC4_DASTPD);
475 printk(KERN_INFO "set_telephone_to_playback_target(), "
476 "TSC2101_AUDIO_CTRL_4 = %d\n",
477 omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
480 * 1110 0010 0000 0010
481 * DAC left and right routed to SPK1/SPK2
483 * keyclicks routed to SPK1/SPK2
485 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
486 AC5_DIFFIN | AC5_DAC2SPK1(3) |
487 AC5_CPI2SPK1 | AC5_MUTSPK2);
489 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
490 AC6_MIC2CPO | AC6_MUTLSPK |
491 AC6_LDSCPTC | AC6_VGNDSCPTC | AC6_CAPINTF);
492 current_playback_target = PLAYBACK_TARGET_CELLPHONE;
496 * 1100 0101 1101 0000
498 * #define MPC_ASTMU TSC2101_BIT(15)
499 * #define MPC_ASTG(ARG) (((ARG) & 0x7F) << 8)
500 * #define MPC_MICSEL(ARG) (((ARG) & 0x07) << 5)
501 * #define MPC_MICADC TSC2101_BIT(4)
502 * #define MPC_CPADC TSC2101_BIT(3)
503 * #define MPC_ASTGF (0x01)
505 static void set_telephone_to_record_source(void)
511 * --> AGC is off for handset input.
512 * --> ADC PGA is controlled by the ADMUT_HDN + ADPGA_HND
515 * --> AGC time constant for handset input,
516 * attack time = 8 mc, decay time = 100 ms
518 * --> AGC Target gain for handset input = -5.5 db
519 * D14 - D8 = 011 1100
520 * --> ADC handset PGA settings = 60 = 30 db
522 * --> Handset input ON (unmuted)
524 val = 0x3c00; /* 0011 1100 0000 0000 = 60 = 30 */
525 omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
529 * --> AGC is off for headset/Aux input
530 * --> ADC headset/Aux PGA is contoller by
531 * ADMUT_HED + ADPGA_HED
534 * --> Agc constant for headset/Aux input,
535 * attack time = 8 mc, decay time = 100 ms
537 * --> AGC target gain for headset input = -5.5 db
538 * D14 - D8 = 000 0000
539 * --> Adc headset/AUX pga settings = 0 db
541 * --> Headset/AUX input muted
543 * Mute headset aux input
545 val = 0x8000; /* 1000 0000 0000 0000 */
546 omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
547 set_record_source(REC_SRC_MICIN_HND_AND_AUX1);
551 * D0 = flag, Headset/Aux or handset PGA flag
552 * --> & with 1 (= 1 -->gain applied == pga
554 * D1 = 0, DAC channel PGA soft stepping control
555 * --> 0.5 db change every WCLK
556 * D2 = flag, DAC right channel PGA flag
558 * D3 = flag, DAC left channel PGA flag
560 * D7 - D4 = 0001, keyclick length
561 * --> 4 periods key clicks
562 * D10 - D8 = 100, keyclick frequency
564 * D11 = 0, Headset/Aux or handset soft stepping control
565 * --> 0,5 db change every WCLK or ADWS
566 * D14 -D12 = 100, Keyclick applitude control
567 * --> Medium amplitude
568 * D15 = 0, keyclick disabled
570 val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_2);
572 val = val | 0x4410; /* D14, D10, D4 bits == 1 */
573 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_2, val);
576 * D0 = 0 (reserved, write always 0)
579 * D2 - D5 = 0000 (reserved, write always 0000)
581 * --> MICBIAS_HND = 2.0 v
583 * --> MICBIAS_HED = 3.3 v
585 * --> Mic AGC hysteric selection = 2 db
587 * --> Disable buzzer PGA soft stepping
589 * --> Enable CELL phone PGA soft stepping control
591 * --> Disable analog sidetone soft
594 * --> Enable DAC PGA soft stepping control
596 * --> Enable headset/Aux or Handset soft
599 val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4);
600 val = val & 0x2a42; /* 0010 1010 0100 0010 */
601 val = val | 0x2a40; /* bits D13, D11, D9, D6 == 1 */
602 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, val);
603 printk(KERN_INFO "set_telephone_to_record_source(), "
604 "TSC2101_AUDIO_CTRL_4 = %d\n",
605 omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
608 * --> reserved, write always = 0
609 * D1 = flag, read only
611 * D5 - D2 = 1111, Buzzer input PGA settings
614 * --> power down buzzer input pga
615 * D7 = flag, read only
617 * D14 - D8 = 101 1101
620 * --> power up cell phone input PGA
622 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
624 /* bits, D14, D12, D11, D10, D8, D6, D5,D4,D3,D2 */
626 omap_tsc2101_audio_write(TSC2101_BUZZER_GAIN_CTRL, val);
630 * --> -4.5 db for DAC right channel volume control
632 * --> DAC right channel muted
633 * D14 - D8 = 000 1001
634 * --> -4.5 db for DAC left channel volume control
636 * --> DAC left channel muted
638 /* val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); */
640 omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
643 * 0000 0000 0100 0000
646 * --> GPIO 1 pin output is three stated
648 * --> Disaple GPIO2 for CLKOUT mode
650 * --> Disable GPUI1 for interrupt detection
652 * --> Disable GPIO2 for headset detection interrupt
653 * D5 = reserved, always 0
655 * --> 8 ms clitch detection
656 * D8 = reserved, write only 0
658 * --> 16 ms de-bouncing
659 * for glitch detection during headset detection
660 * D11 = flag for button press
661 * D12 = flag for headset detection
663 * --> type of headset detected = 00 == no stereo
666 * --> Disable headset detection
669 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, val);
673 * Checks whether the headset is detected.
674 * If headset is detected, the type is returned. Type can be
675 * 0x01 = stereo headset detected
676 * 0x02 = cellurar headset detected
677 * 0x03 = stereo + cellurar headset detected
678 * If headset is not detected 0 is returned.
680 u16 get_headset_detected(void)
686 curType = 0; /* not detected */
687 curVal = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_7);
688 curDetected = curVal & AC7_HDDETFL;
690 printk(KERN_INFO "headset detected, checking type from %d \n",
692 curType = ((curVal & 0x6000) >> 13);
693 printk(KERN_INFO "headset type detected = %d \n", curType);
695 printk(KERN_INFO "headset not detected\n");
700 void init_playback_targets(void)
704 set_loudspeaker_to_playback_target();
706 * Left line input volume control
707 * = SET_LINE in the OSS driver
709 set_mixer_volume_as_headset_gain_control_volume(DEFAULT_INPUT_VOLUME);
712 * Set headset to be controllable by handset mixer
713 * AGC enable for handset input
714 * Handset input not muted
716 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
717 val = val | HNGC_AGCEN_HND;
718 val = val & ~HNGC_ADMUT_HND;
719 omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
722 * mic input volume control
723 * SET_MIC in the OSS driver
725 set_mixer_volume_as_handset_gain_control_volume(DEFAULT_INPUT_VOLUME);
728 * Left/Right headphone channel volume control
729 * Zero-cross detect on
731 set_mixer_volume_as_dac_gain_control_volume(DEFAULT_OUTPUT_VOLUME,
732 DEFAULT_OUTPUT_VOLUME);
734 dac_gain_control_unmute(1, 1);
738 * Initializes tsc2101 recourd source (to line) and playback target
741 void snd_omap_init_mixer(void)
745 /* Headset/Hook switch detect enabled */
746 omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, AC7_DETECT);
748 /* Select headset to record source (MIC_INHED)*/
749 set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
750 /* Init loudspeaker as a default playback target*/
751 init_playback_targets();
756 static int __pcm_playback_target_info(struct snd_kcontrol *kcontrol,
757 struct snd_ctl_elem_info *uinfo)
759 static char *texts[PLAYBACK_TARGET_COUNT] = {
760 "Loudspeaker", "Headphone", "Cellphone"
763 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
765 uinfo->value.enumerated.items = PLAYBACK_TARGET_COUNT;
766 if (uinfo->value.enumerated.item > PLAYBACK_TARGET_COUNT - 1)
767 uinfo->value.enumerated.item = PLAYBACK_TARGET_COUNT - 1;
769 strcpy(uinfo->value.enumerated.name,
770 texts[uinfo->value.enumerated.item]);
774 static int __pcm_playback_target_get(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *ucontrol)
777 ucontrol->value.integer.value[0] = current_playback_target;
781 static int __pcm_playback_target_put(struct snd_kcontrol *kcontrol,
782 struct snd_ctl_elem_value *ucontrol)
788 curVal = ucontrol->value.integer.value[0];
790 (curVal < PLAYBACK_TARGET_COUNT) &&
791 (curVal != current_playback_target)) {
792 if (curVal == PLAYBACK_TARGET_LOUDSPEAKER) {
793 set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
794 set_loudspeaker_to_playback_target();
795 } else if (curVal == PLAYBACK_TARGET_HEADPHONE) {
796 set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HND);
797 set_headphone_to_playback_target();
798 } else if (curVal == PLAYBACK_TARGET_CELLPHONE) {
799 set_telephone_to_record_source();
800 set_telephone_to_playback_target();
807 static int __pcm_playback_volume_info(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_info *uinfo)
810 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
812 uinfo->value.integer.min = 0;
813 uinfo->value.integer.max = 100;
818 * Alsa mixer interface function for getting the volume read from the DGC in a
819 * 0 -100 alsa mixer format.
821 static int __pcm_playback_volume_get(struct snd_kcontrol *kcontrol,
822 struct snd_ctl_elem_value *ucontrol)
828 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
829 M_DPRINTK("registry value = %d!\n", val);
830 volL = DGC_DALVL_EXTRACT(val);
831 volR = DGC_DARVL_EXTRACT(val);
832 /* make sure that other bits are not on */
833 volL = volL & ~DGC_DALMU;
834 volR = volR & ~DGC_DARMU;
836 volL = get_dac_gain_control_volume_as_mixer_volume(volL);
837 volR = get_dac_gain_control_volume_as_mixer_volume(volR);
839 ucontrol->value.integer.value[0] = volL; /* L */
840 ucontrol->value.integer.value[1] = volR; /* R */
842 M_DPRINTK("mixer volume left = %ld, right = %ld\n",
843 ucontrol->value.integer.value[0],
844 ucontrol->value.integer.value[1]);
848 static int __pcm_playback_volume_put(struct snd_kcontrol *kcontrol,
849 struct snd_ctl_elem_value *ucontrol)
851 return set_mixer_volume_as_dac_gain_control_volume(
852 ucontrol->value.integer.value[0],
853 ucontrol->value.integer.value[1]);
856 static int __pcm_playback_switch_info(struct snd_kcontrol *kcontrol,
857 struct snd_ctl_elem_info *uinfo)
859 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
861 uinfo->value.integer.min = 0;
862 uinfo->value.integer.max = 1;
867 * When DGC_DALMU (bit 15) is 1, the left channel is muted.
868 * When DGC_DALMU is 0, left channel is not muted.
869 * Same logic apply also for the right channel.
871 static int __pcm_playback_switch_get(struct snd_kcontrol *kcontrol,
872 struct snd_ctl_elem_value *ucontrol)
874 u16 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
876 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); /* left */
877 ucontrol->value.integer.value[1] = IS_UNMUTED(7, val); /* right */
881 static int __pcm_playback_switch_put(struct snd_kcontrol *kcontrol,
882 struct snd_ctl_elem_value *ucontrol)
884 return dac_gain_control_unmute(ucontrol->value.integer.value[0],
885 ucontrol->value.integer.value[1]);
888 static int __headset_playback_volume_info(struct snd_kcontrol *kcontrol,
889 struct snd_ctl_elem_info *uinfo)
891 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
893 uinfo->value.integer.min = 0;
894 uinfo->value.integer.max = 100;
898 static int __headset_playback_volume_get(struct snd_kcontrol *kcontrol,
899 struct snd_ctl_elem_value *ucontrol)
904 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
905 M_DPRINTK("registry value = %d\n", val);
906 vol = HGC_ADPGA_HED_EXTRACT(val);
907 vol = vol & ~HGC_ADMUT_HED;
909 vol = get_headset_gain_control_volume_as_mixer_volume(vol);
910 ucontrol->value.integer.value[0] = vol;
912 M_DPRINTK("mixer volume returned = %ld\n",
913 ucontrol->value.integer.value[0]);
917 static int __headset_playback_volume_put(struct snd_kcontrol *kcontrol,
918 struct snd_ctl_elem_value *ucontrol)
920 return set_mixer_volume_as_headset_gain_control_volume(
921 ucontrol->value.integer.value[0]);
924 static int __headset_playback_switch_info(struct snd_kcontrol *kcontrol,
925 struct snd_ctl_elem_info *uinfo)
927 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
929 uinfo->value.integer.min = 0;
930 uinfo->value.integer.max = 1;
935 * When HGC_ADMUT_HED (bit 15) is 1, the headset is muted.
936 * When HGC_ADMUT_HED is 0, headset is not muted.
938 static int __headset_playback_switch_get(struct snd_kcontrol *kcontrol,
939 struct snd_ctl_elem_value *ucontrol)
941 u16 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
942 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
946 static int __headset_playback_switch_put(struct snd_kcontrol *kcontrol,
947 struct snd_ctl_elem_value *ucontrol)
949 /* mute/unmute headset */
950 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
951 TSC2101_HEADSET_GAIN_CTRL,
955 static int __handset_playback_volume_info(struct snd_kcontrol *kcontrol,
956 struct snd_ctl_elem_info *uinfo)
958 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
960 uinfo->value.integer.min = 0;
961 uinfo->value.integer.max = 100;
965 static int __handset_playback_volume_get(struct snd_kcontrol *kcontrol,
966 struct snd_ctl_elem_value *ucontrol)
971 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
972 M_DPRINTK("registry value = %d\n", val);
973 vol = HNGC_ADPGA_HND_EXTRACT(val);
974 vol = vol & ~HNGC_ADMUT_HND;
975 vol = get_handset_gain_control_volume_as_mixer_volume(vol);
976 ucontrol->value.integer.value[0] = vol;
978 M_DPRINTK("mixer volume returned = %ld\n",
979 ucontrol->value.integer.value[0]);
983 static int __handset_playback_volume_put(struct snd_kcontrol *kcontrol,
984 struct snd_ctl_elem_value *ucontrol)
986 return set_mixer_volume_as_handset_gain_control_volume(
987 ucontrol->value.integer.value[0]);
990 static int __handset_playback_switch_info(struct snd_kcontrol *kcontrol,
991 struct snd_ctl_elem_info *uinfo)
993 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
995 uinfo->value.integer.min = 0;
996 uinfo->value.integer.max = 1;
1001 * When HNGC_ADMUT_HND (bit 15) is 1, the handset is muted.
1002 * When HNGC_ADMUT_HND is 0, handset is not muted.
1004 static int __handset_playback_switch_get(struct snd_kcontrol *kcontrol,
1005 struct snd_ctl_elem_value *ucontrol)
1007 u16 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
1008 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
1012 static int __handset_playback_switch_put(struct snd_kcontrol *kcontrol,
1013 struct snd_ctl_elem_value *ucontrol)
1015 /* handset mute/unmute */
1016 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
1017 TSC2101_HANDSET_GAIN_CTRL,
1021 static int __cellphone_input_switch_info(struct snd_kcontrol *kcontrol,
1022 struct snd_ctl_elem_info *uinfo)
1024 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1026 uinfo->value.integer.min = 0;
1027 uinfo->value.integer.max = 1;
1032 * When BGC_MUT_CP (bit 15) = 1, power down cellphone input pga.
1033 * When BGC_MUT_CP = 0, power up cellphone input pga.
1035 static int __cellphone_input_switch_get(struct snd_kcontrol *kcontrol,
1036 struct snd_ctl_elem_value *ucontrol)
1038 u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
1039 ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
1043 static int __cellphone_input_switch_put(struct snd_kcontrol *kcontrol,
1044 struct snd_ctl_elem_value *ucontrol)
1046 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
1047 TSC2101_BUZZER_GAIN_CTRL,
1051 static int __buzzer_input_switch_info(struct snd_kcontrol *kcontrol,
1052 struct snd_ctl_elem_info *uinfo)
1054 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1056 uinfo->value.integer.min = 0;
1057 uinfo->value.integer.max = 1;
1062 * When BGC_MUT_BU (bit 6) = 1, power down cellphone input pga.
1063 * When BGC_MUT_BU = 0, power up cellphone input pga.
1065 static int __buzzer_input_switch_get(struct snd_kcontrol *kcontrol,
1066 struct snd_ctl_elem_value *ucontrol)
1068 u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
1069 ucontrol->value.integer.value[0] = IS_UNMUTED(6, val);
1073 static int __buzzer_input_switch_put(struct snd_kcontrol *kcontrol,
1074 struct snd_ctl_elem_value *ucontrol)
1076 return adc_pga_unmute_control(ucontrol->value.integer.value[0],
1077 TSC2101_BUZZER_GAIN_CTRL,
1081 static struct snd_kcontrol_new tsc2101_control[] __devinitdata = {
1083 .name = "Target Playback Route",
1084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1086 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1087 .info = __pcm_playback_target_info,
1088 .get = __pcm_playback_target_get,
1089 .put = __pcm_playback_target_put,
1091 .name = "Master Playback Volume",
1092 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1094 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1095 .info = __pcm_playback_volume_info,
1096 .get = __pcm_playback_volume_get,
1097 .put = __pcm_playback_volume_put,
1099 .name = "Master Playback Switch",
1100 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1102 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1103 .info = __pcm_playback_switch_info,
1104 .get = __pcm_playback_switch_get,
1105 .put = __pcm_playback_switch_put,
1107 .name = "Headset Playback Volume",
1108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1110 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1111 .info = __headset_playback_volume_info,
1112 .get = __headset_playback_volume_get,
1113 .put = __headset_playback_volume_put,
1115 .name = "Headset Playback Switch",
1116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1118 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1119 .info = __headset_playback_switch_info,
1120 .get = __headset_playback_switch_get,
1121 .put = __headset_playback_switch_put,
1123 .name = "Handset Playback Volume",
1124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1127 .info = __handset_playback_volume_info,
1128 .get = __handset_playback_volume_get,
1129 .put = __handset_playback_volume_put,
1131 .name = "Handset Playback Switch",
1132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1134 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1135 .info = __handset_playback_switch_info,
1136 .get = __handset_playback_switch_get,
1137 .put = __handset_playback_switch_put,
1139 .name = "Cellphone Input Switch",
1140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1142 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1143 .info = __cellphone_input_switch_info,
1144 .get = __cellphone_input_switch_get,
1145 .put = __cellphone_input_switch_put,
1147 .name = "Buzzer Input Switch",
1148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1150 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1151 .info = __buzzer_input_switch_info,
1152 .get = __buzzer_input_switch_get,
1153 .put = __buzzer_input_switch_put,
1159 void snd_omap_suspend_mixer(void)
1163 void snd_omap_resume_mixer(void)
1165 snd_omap_init_mixer();
1169 int snd_omap_mixer(struct snd_card_omap_codec *tsc2101)
1177 for (i = 0; i < ARRAY_SIZE(tsc2101_control); i++) {
1178 err = snd_ctl_add(tsc2101->card,
1179 snd_ctl_new1(&tsc2101_control[i],