This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLV320AIC3111: Headset detection problems

Part Number: TLV320AIC3111
Other Parts Discussed in Thread: TLV320AIC33, TLV320AIC3101,

Hello,

I'm having problems with headset detection on TLC320AIC3111 platform.  I am not using the EVM; the device is integrated on a custom board running Linux, using the tlv320aic31xx driver.

The headphone interface is AC coupled as recommended in the device data sheet, Figure 5-1, and shown in the schematic of the custom board below.

For testing I am using a standard stereo headset with microphone and switch; it is the one distributed by Apple for use with their phones with 3.5mm audio jacks a number of years ago.

A short summary of the problem I am having is this:

(1)  The headset is detected as a headset if the headset is plugged into the jack prior to playing sound output.

(2)  The headset is detected as headphones (not headset) if the headset is plugged into the jack while sound output is playing.

I have tried a number of settings but so far have not been able to get the device to detect the headset as a headset type when the headset is plugged in while sound is playing.  It seems to be something having to do with the debounce settings, but I think I have tried all combinations.

The driver is configured for headset detection using INT1.  The INT1 interrupt consistently activates on headset plug events.  I have tried a number of configurations inside the interrupt to check status of the headset insertion/removal flag in registers 0:44 and 0:46 and headset type in 0:67.  I have also tried a number of MICBIAS settings (maybe not exhaustive).

I also tried disabling the interrupt operation, thinking that somehow the reading of the sticky flags in register 0:44 was interfering with the debounce filtering.  I ran the following two tests:

(1)  With headset already inserted into the jack, no audio output, I read register 0:67 manually.  Both bits 5 and 6 are zero.  Then I started audio output, and read the register manually again.  Both bits were now set to '1', indicating that a headset with microphone is attached.

(2)  With headset out of the jack, I read register 0:67 manually and saw that both bits 5 and 6 are zero.  Then I started audio output and read the register again.  Both bits still zero.  Then I inserted the headset and then read the register manually.  I found that bit 5 was set to '1' and bit 6 was '0', indicating headset without microphone.

In searching this forum I found this document: SLAA454 – June 2010 "Headset Detection for TLV320AIC33 and TLV320AIC3101/4/5/6 Family"; it doesn't seem to directly apply (register references do not match my device), but it seems to have some useful information that may partially apply (?).

Please advise on how I can resolve this problem.

Thank you.

--ken

  • Hi,

    I tested the scenarios above on the EVM and I'm not seeing the issue. 

    On your 1st test above, why both bits are "00" in register 67 even with the jack inserted? Register 44 could change as the nature of sticky flag, but I would expect the type connection on register 67 should still be "11". On test 2, I would expect to see "11" and not "10" regardless audio is on or not.

    It seems some settings changed with your turning on/off the audio, maybe it's good to just check the detection mechanism first on your setup.

    I agree to check the register manually and also the MICBIAS maybe it's disabled when you turn on/off the audio.

    The SLAA454 is a good reference on how the headset detection works.

    AIC3111 Headset Detection.pdf

  • pdjuandi,

    The reason that both bits are "00" in register 67 with the plug inserted into the jack is that it seems that the jack detection only works when audio output is present.  This is actually not desirable (jack detection should work all the time), but I have not been able to see any change in bits, or any interrupt unless there is audio streaming to the output.  The "Headset Detection for TLV320AIC33 and TLV320AIC3101_4_5_6 Family" document seems to indicate (second bullet in Section 1.2.4) that headset detection is always active, not just when audio output is playing.

    I checked the driver, and it is true that the MICBIAS setting (register 1:46) was not getting configured properly when the audio output was enabled.  I fixed that and tried it with all three MICBIAS settings, and saw no difference in the results.  Does the MICBIAS setting factor into headset detection?

    In the document you attached, there is a note that states "Audio is not playing but path is still ON". I looked for that setting and I see that register 1:35 seems to have the setting this note is referring to: bits D7-D6 set to "10" for "DAC_L is routed directly to the HPL driver" and bits D3-D2 set to "10" for "DAC_R is routed directly to the HPR driver".  Is this what this note means?  I tried that also and it doesn't work either.

    Below is a log that I captured of my debug session.

    I can read and write registers of the TLV320AIC3111 device using this command syntax:

    Read register:

    echo <hexstring> > /sys/bus/i2c/devices/5-0018/reg

       followed by

    cat /sys/bus/i2c/devices/5-0018/reg

       ... where <hexstring> is a concatenation of 0x01 to command a register read, page byte, register address, and 0x00.

    For instance, to read register 1:46 the <hexstring> is "01012e00"

    Write register:

    echo <hexstring> > /sys/bus/i2c/devices/5-0018/reg

       ... where <hexstring is a concatenation of 0x00 to command a register write, page byte, register address, data byte.

    Please advise on what I may be doing wrong here.

    Thanks.

    --ken

    1667.log.txt
    Set up headphone path using amixer utility:
    -------------------------------------------
    root@imx8mp-var-dart:~# headphone_test
    Simple mixer control 'Speaker Driver',0
      Capabilities: pvolume pswitch
      Playback channels: Front Left - Front Right
      Limits: Playback 0 - 3
      Mono:
      Front Left: Playback 1 [33%] [12.00dB] [off]
      Front Right: Playback 1 [33%] [12.00dB] [off]
    Simple mixer control 'HP Analog',0
      Capabilities: pvolume
      Playback channels: Front Left - Front Right
      Limits: Playback 0 - 127
      Mono:
      Front Left: Playback 100 [79%] [-13.50dB]
      Front Right: Playback 100 [79%] [-13.50dB]
    Simple mixer control 'HP Driver',0
      Capabilities: pvolume pswitch
      Playback channels: Front Left - Front Right
      Limits: Playback 0 - 9
      Mono:
      Front Left: Playback 5 [56%] [5.00dB] [on]
      Front Right: Playback 5 [56%] [5.00dB] [on]
    Simple mixer control 'HP Driver',0
      Capabilities: pvolume pswitch
      Playback channels: Front Left - Front Right
      Limits: Playback 0 - 9
      Mono:
      Front Left: Playback 5 [56%] [5.00dB] [on]
      Front Right: Playback 5 [56%] [5.00dB] [on]
    Simple mixer control 'HP Left',0
      Capabilities: pswitch pswitch-joined
      Playback channels: Mono
      Mono: Playback [on]
    Simple mixer control 'HP Right',0
      Capabilities: pswitch pswitch-joined
      Playback channels: Mono
      Mono: Playback [on]
    Simple mixer control 'Output Left From Left DAC',0
      Capabilities: pswitch pswitch-joined
      Playback channels: Mono
      Mono: Playback [on]
    Simple mixer control 'Output Right From Right DAC',0
      Capabilities: pswitch pswitch-joined
      Playback channels: Mono
      Mono: Playback [on]
    Simple mixer control 'DAC',0
      Capabilities: pvolume
      Playback channels: Front Left - Front Right
      Limits: Playback 0 - 175
      Mono:
      Front Left: Playback 130 [74%] [1.50dB]
      Front Right: Playback 130 [74%] [1.50dB]
    
    Read register 67:
    -----------------
    root@imx8mp-var-dart:~# echo "01004300" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01004380 <-- register 67 value 0x80
    
    Read register 46:
    -----------------
    root@imx8mp-var-dart:~# echo "01002e00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01002e00 <-- register 46 value 0x00
    
    Read register 35:
    -----------------
    root@imx8mp-var-dart:~# readreg 1 35
    root@imx8mp-var-dart:~# echo "01012300" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01012344 <-- register 35 value 0x44
    
    Write 0x88 to register 35:
    --------------------------
    root@imx8mp-var-dart:~# writereg 1 35 88
    root@imx8mp-var-dart:~# echo "00012388" > /sys/bus/i2c/devices/5-0018/reg
    root@imx8mp-var-dart:~# echo "01012300" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01012388 <-- register 35 value 0x88
    
    Set PLL powered bit, register 5:
    --------------------------------
    root@imx8mp-var-dart:~# echo "01000500" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000511 <-- pre-write register 5 value 0x11
    root@imx8mp-var-dart:~# echo "00000591" > /sys/bus/i2c/devices/5-0018/reg
    root@imx8mp-var-dart:~# echo "01000500" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000591 <-- updated register 5 value 0x91
    
    Set NDAC divider power bit, register 11:
    ----------------------------------------
    root@imx8mp-var-dart:~# echo "01000b00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000b01 <-- pre-write register 11 value 0x01
    root@imx8mp-var-dart:~# echo "00000b81" > /sys/bus/i2c/devices/5-0018/reg
    root@imx8mp-var-dart:~# echo "01000b00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000b81 <-- updated register 11 value 0x81
    
    Set MDAC divider power bit, register 12:
    ----------------------------------------
    root@imx8mp-var-dart:~# echo "01000c00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000c01 <-- pre-write register 12 value 0x01
    root@imx8mp-var-dart:~# echo "00000c81" > /sys/bus/i2c/devices/5-0018/reg
    root@imx8mp-var-dart:~# echo "01000c00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01000c81 <-- updated register 12 value 0x81
    
    Set BCLK N-divider power bit, register 30:
    ----------------------------------------
    root@imx8mp-var-dart:~# echo "01001e00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01001e01 <-- pre-write register 30 value 0x01
    root@imx8mp-var-dart:~# echo "00001e81" > /sys/bus/i2c/devices/5-0018/reg
    root@imx8mp-var-dart:~# echo "01001e00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01001e81 <-- updated register 30 value 0x81
    
    Read DAC interrupt flags, registers 44, 46:
    -------------------------------------------
    root@imx8mp-var-dart:~# echo "01002c00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01002c00 <-- register 44 value 0x00
    root@imx8mp-var-dart:~# echo "01002e00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01002e00 <-- register 44 value 0x00
    
    Read headset detection register 67:
    -----------------------------------
    root@imx8mp-var-dart:~# readreg 67
    root@imx8mp-var-dart:~# echo "01004300" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01004380 <-- register 67 value 0x80
    
    *** Headset is plugged into jack here ***
    
    Read DAC interrupt flags, registers 44, 46:
    -------------------------------------------
    root@imx8mp-var-dart:~# echo "01002c00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01002c00 <-- register 44 value 0x00
    root@imx8mp-var-dart:~# echo "01002e00" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01002e00 <-- register 44 value 0x00
    
    Read headset detection register 67:
    -----------------------------------
    root@imx8mp-var-dart:~# echo "01004300" > /sys/bus/i2c/devices/5-0018/reg
    cat /sys/bus/i2c/devices/5-0018/reg
    01004380 <-- register 67 value 0x80
    
    

  • pdjuandi,

    In the current implementation, the MCLK is driven to the TLV320AIC3111 codec by the processor core and the BCLK and WCLK are derived from the MCLK and driven by the codec.  But the MCLK is only driven by the processor when audio is being played or recorded (i.e. it is not continuous).  Is the clock required by the codec in order to do the headphone/headset detection?  Maybe that is why it is only working when audio output is present?

    --ken

  • Hi,

    The detection should work all the time as shown in my slides as well.

    Path is ON means the audio path from DAC to HP is enabled (all registers are set) only the sound coming in is off.

    You can see the detection circuitry in the SLAA454 note and how MICBIAS is used and as long as it's ON with a fixed voltage the detection should work.

    Now this front end detection is just going through comparator, but the detected signal is going into the internal digital circuit which uses MCLK so without MCLK this might cause an issue. Can you force this MCLK to always on to confirm the issue you see?

  • pdjuandi,

    Changing the configuration to keep the MCLK continuously running fixed my problem.

    (It was not easy to configure continuous MCLK, but that did the trick.)

    Thanks.

    --ken