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.

Linux/TLV320AIC3106: tlv320aic3106

Part Number: TLV320AIC3106
Other Parts Discussed in Thread: TPA2005D1, , TLV320AIC3007

Tool/software: Linux

Hello Sir ,

I am using "tlv320aic3106" audio codec IC, "TPA2005D1" Class-D Audio Power Amplifier,(4 or 8  )ohm speakers on line out [LEFT_LO+]  . I am able to get output but a constant static noise is there . Without any Alsa settings the noise is much louder , If i am enabling any  line out mixer as "left line mixer PGAR bypass" ,"left line mixer PGAL bypass" ,"left line mixer line2L bypass", or "left line mixer line 2R bypass" and setting the value to "0" i.e mute  the noise is reducing a bit but still it is there . The other thing which i had observed is while using a 4 ohm speaker the noise value is louder as compared to a 8 ohm speaker .

Sir could you please check the register configuration and suggest me a way to resolve the issue. I could not able to figure out whether it is due to some hardware or software.

static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
    0x00, 0x00, 0x00, 0x10,    /* 0 */
    0x04, 0x00, 0x00, 0x00,    /* 4 */
    0x00, 0x00, 0x00, 0x01,    /* 8 */
    0x00, 0x00, 0x00, 0x80,    /* 12 */
    0x80, 0xff, 0xff, 0x78,    /* 16 */
    0x78, 0x78, 0x78, 0x78,    /* 20 */
    0x78, 0x00, 0x00, 0xfe,    /* 24 */
    0x00, 0x00, 0xfe, 0x00,    /* 28 */
    0x18, 0x18, 0x00, 0x00,    /* 32 */
    0x00, 0x00, 0x00, 0x00,    /* 36 */
    0x00, 0x00, 0x00, 0x80,    /* 40 */
    0x80, 0x00, 0x00, 0x00,    /* 44 */
    0x00, 0x00, 0x00, 0x04,    /* 48 */
    0x00, 0x00, 0x00, 0x00,    /* 52 */
    0x00, 0x00, 0x04, 0x00,    /* 56 */
    0x00, 0x00, 0x00, 0x00,    /* 60 */
    0x00, 0x04, 0x00, 0x00,    /* 64 */
    0x00, 0x00, 0x00, 0x00,    /* 68 */
    0x04, 0x00, 0x00, 0x00,    /* 72 */
    0x00, 0x00, 0x00, 0x00,    /* 76 */
    0x00, 0x00, 0x00, 0x00,    /* 80 */
    0x00, 0x00, 0x00, 0x00,    /* 84 */
    0x00, 0x00, 0x00, 0x00,    /* 88 */
    0x00, 0x00, 0x00, 0x00,    /* 92 */
    0x00, 0x00, 0x00, 0x00,    /* 96 */
    0x00, 0x00, 0x02,    /* 100 */
};

with regards

pranav

  • Hi, Pranav,

    Could you please provide details of the register setup used? it is unclear from the format you sent what value corresponds to which register/page.

    Regarding your issue, It is recommended to route the DAC output through the PGA mixer output to reduce the output noise as the PGA has filters integrated not present on the direct path from the DAC outputs. Please refer to section 2.5 of this app note for detailed information.

    The noise you are hearing may be related to the out-of-band noise from the DAC modulator that is coupled back to the audible spectrum by the Class-D amplifier.  this can be avoided by using a out-of-band noise filter like the described in this app note. Do you have a filter like this in your system?. Have you tried monitoring the output of the codec directly to isolate the noise issue to the codec?.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • Sir i am using the below register with their corresponding names ,now could you please tell me what all modifications do i need to resolve the issue.

    snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
        snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);

        /* DAC default volume and mute */
        snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
        snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);

        /* DAC to HP default volume and route to Output mixer */
        snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
        snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
        snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
        snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
        /* DAC to Line Out default volume and route to Output mixer */
        snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
        snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
        /* DAC to Mono Line Out default volume and route to Output mixer */
        snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
        snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);

        /* unmute all outputs */
        reg = snd_soc_read(codec, LLOPM_CTRL);
        snd_soc_write(codec, LLOPM_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, RLOPM_CTRL);
        snd_soc_write(codec, RLOPM_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, MONOLOPM_CTRL);
        snd_soc_write(codec, MONOLOPM_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, HPLOUT_CTRL);
        snd_soc_write(codec, HPLOUT_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, HPROUT_CTRL);
        snd_soc_write(codec, HPROUT_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, HPLCOM_CTRL);
        snd_soc_write(codec, HPLCOM_CTRL, reg | UNMUTE);
        reg = snd_soc_read(codec, HPRCOM_CTRL);
        snd_soc_write(codec, HPRCOM_CTRL, reg | UNMUTE);

        /* ADC default volume and unmute */
        snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
        snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
        /* By default route Line1 to ADC PGA mixer */
        snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
        snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);

        /* PGA to HP Bypass default volume, disconnect from Output Mixer */
        snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
        /* PGA to Line Out default volume, disconnect from Output Mixer */
        snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
        /* PGA to Mono Line Out default volume, disconnect from Output Mixer */
        snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);

        /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
        snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
        snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
        snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
        /* Line2 Line Out default volume, disconnect from Output Mixer */
        snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
        /* Line2 to Mono Out default volume, disconnect from Output Mixer */
        snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);

     =========================================================================================================================================================
    /* AIC3X register space */
    #define AIC3X_CACHEREGNUM        103

    /* Page select register */
    #define AIC3X_PAGE_SELECT        0
    /* Software reset register */
    #define AIC3X_RESET            1
    /* Codec Sample rate select register */
    #define AIC3X_SAMPLE_RATE_SEL_REG    2
    /* PLL progrramming register A */
    #define AIC3X_PLL_PROGA_REG        3
    /* PLL progrramming register B */
    #define AIC3X_PLL_PROGB_REG        4
    /* PLL progrramming register C */
    #define AIC3X_PLL_PROGC_REG        5
    /* PLL progrramming register D */
    #define AIC3X_PLL_PROGD_REG        6
    /* Codec datapath setup register */
    #define AIC3X_CODEC_DATAPATH_REG    7
    /* Audio serial data interface control register A */
    #define AIC3X_ASD_INTF_CTRLA        8
    /* Audio serial data interface control register B */
    #define AIC3X_ASD_INTF_CTRLB        9
    /* Audio serial data interface control register C */
    #define AIC3X_ASD_INTF_CTRLC        10
    /* Audio overflow status and PLL R value programming register */
    #define AIC3X_OVRF_STATUS_AND_PLLR_REG    11
    /* Audio codec digital filter control register */
    #define AIC3X_CODEC_DFILT_CTRL        12
    /* Headset/button press detection register */
    #define AIC3X_HEADSET_DETECT_CTRL_A    13
    #define AIC3X_HEADSET_DETECT_CTRL_B    14
    /* ADC PGA Gain control registers */
    #define LADC_VOL            15
    #define RADC_VOL            16
    /* MIC3 control registers */
    #define MIC3LR_2_LADC_CTRL        17
    #define MIC3LR_2_RADC_CTRL        18
    /* Line1 Input control registers */
    #define LINE1L_2_LADC_CTRL        19
    #define LINE1R_2_LADC_CTRL        21
    #define LINE1R_2_RADC_CTRL        22
    #define LINE1L_2_RADC_CTRL        24
    /* Line2 Input control registers */
    #define LINE2L_2_LADC_CTRL        20
    #define LINE2R_2_RADC_CTRL        23
    /* MICBIAS Control Register */
    #define MICBIAS_CTRL            25

    /* AGC Control Registers A, B, C */
    #define LAGC_CTRL_A            26
    #define LAGC_CTRL_B            27
    #define LAGC_CTRL_C            28
    #define RAGC_CTRL_A            29
    #define RAGC_CTRL_B            30
    #define RAGC_CTRL_C            31

    /* DAC Power and Left High Power Output control registers */
    #define DAC_PWR                37
    #define HPLCOM_CFG            37
    /* Right High Power Output control registers */
    #define HPRCOM_CFG            38
    /* DAC Output Switching control registers */
    #define DAC_LINE_MUX            41
    /* High Power Output Driver Pop Reduction registers */
    #define HPOUT_POP_REDUCTION        42
    /* DAC Digital control registers */
    #define LDAC_VOL            43
    #define RDAC_VOL            44
    /* Left High Power Output control registers */
    #define LINE2L_2_HPLOUT_VOL        45
    #define PGAL_2_HPLOUT_VOL        46
    #define DACL1_2_HPLOUT_VOL        47
    #define LINE2R_2_HPLOUT_VOL        48
    #define PGAR_2_HPLOUT_VOL        49
    #define DACR1_2_HPLOUT_VOL        50
    #define HPLOUT_CTRL            51
    /* Left High Power COM control registers */
    #define LINE2L_2_HPLCOM_VOL        52
    #define PGAL_2_HPLCOM_VOL        53
    #define DACL1_2_HPLCOM_VOL        54
    #define LINE2R_2_HPLCOM_VOL        55
    #define PGAR_2_HPLCOM_VOL        56
    #define DACR1_2_HPLCOM_VOL        57
    #define HPLCOM_CTRL            58
    /* Right High Power Output control registers */
    #define LINE2L_2_HPROUT_VOL        59
    #define PGAL_2_HPROUT_VOL        60
    #define DACL1_2_HPROUT_VOL        61
    #define LINE2R_2_HPROUT_VOL        62
    #define PGAR_2_HPROUT_VOL        63
    #define DACR1_2_HPROUT_VOL        64
    #define HPROUT_CTRL            65
    /* Right High Power COM control registers */
    #define LINE2L_2_HPRCOM_VOL        66
    #define PGAL_2_HPRCOM_VOL        67
    #define DACL1_2_HPRCOM_VOL        68
    #define LINE2R_2_HPRCOM_VOL        69
    #define PGAR_2_HPRCOM_VOL        70
    #define DACR1_2_HPRCOM_VOL        71
    #define HPRCOM_CTRL            72
    /* Mono Line Output Plus/Minus control registers */
    #define LINE2L_2_MONOLOPM_VOL        73
    #define PGAL_2_MONOLOPM_VOL        74
    #define DACL1_2_MONOLOPM_VOL        75
    #define LINE2R_2_MONOLOPM_VOL        76
    #define PGAR_2_MONOLOPM_VOL        77
    #define DACR1_2_MONOLOPM_VOL        78
    #define MONOLOPM_CTRL            79
    /* Class-D speaker driver on tlv320aic3007 */
    #define CLASSD_CTRL            73
    /* Left Line Output Plus/Minus control registers */
    #define LINE2L_2_LLOPM_VOL        80
    #define PGAL_2_LLOPM_VOL        81
    #define DACL1_2_LLOPM_VOL        82
    #define LINE2R_2_LLOPM_VOL        83
    #define PGAR_2_LLOPM_VOL        84
    #define DACR1_2_LLOPM_VOL        85
    #define LLOPM_CTRL            86
    /* Right Line Output Plus/Minus control registers */
    #define LINE2L_2_RLOPM_VOL        87
    #define PGAL_2_RLOPM_VOL        88
    #define DACL1_2_RLOPM_VOL        89
    #define LINE2R_2_RLOPM_VOL        90
    #define PGAR_2_RLOPM_VOL        91
    #define DACR1_2_RLOPM_VOL        92
    #define RLOPM_CTRL            93
    /* GPIO/IRQ registers */
    #define AIC3X_STICKY_IRQ_FLAGS_REG    96
    #define AIC3X_RT_IRQ_FLAGS_REG        97
    #define AIC3X_GPIO1_REG            98
    #define AIC3X_GPIO2_REG            99
    #define AIC3X_GPIOA_REG            100
    #define AIC3X_GPIOB_REG            101
    /* Clock generation control register */
    #define AIC3X_CLKGEN_CTRL_REG        102

    /* Page select register bits */
    #define PAGE0_SELECT        0
    #define PAGE1_SELECT        1

    /* Audio serial data interface control register A bits */
    #define BIT_CLK_MASTER          0x80
    #define WORD_CLK_MASTER         0x40

    /* Codec Datapath setup register 7 */
    #define FSREF_44100        (1 << 7)
    #define FSREF_48000        (0 << 7)
    #define DUAL_RATE_MODE        ((1 << 5) | (1 << 6))
    #define LDAC2LCH        (0x1 << 3)
    #define RDAC2RCH        (0x1 << 1)

    /* PLL registers bitfields */
    #define PLLP_SHIFT        0
    #define PLLP_MASK        7
    #define PLLQ_SHIFT        3
    #define PLLR_SHIFT        0
    #define PLLJ_SHIFT        2
    #define PLLD_MSB_SHIFT        0
    #define PLLD_LSB_SHIFT        2

    /* Clock generation register bits */
    #define CODEC_CLKIN_PLLDIV    0
    #define CODEC_CLKIN_CLKDIV    1
    #define PLL_CLKIN_SHIFT        4
    #define MCLK_SOURCE        0x0
    #define PLL_CLKDIV_SHIFT    0

    /* Software reset register bits */
    #define SOFT_RESET        0x80

    /* PLL progrramming register A bits */
    #define PLL_ENABLE        0x80

    /* Route bits */
    #define ROUTE_ON        0x80

    /* Mute bits */
    #define UNMUTE            0x08
    #define MUTE_ON            0x80

    /* Power bits */
    #define LADC_PWR_ON        0x04
    #define RADC_PWR_ON        0x04
    #define LDAC_PWR_ON        0x80
    #define RDAC_PWR_ON        0x40
    #define HPLOUT_PWR_ON        0x01
    #define HPROUT_PWR_ON        0x01
    #define HPLCOM_PWR_ON        0x01
    #define HPRCOM_PWR_ON        0x01
    #define MONOLOPM_PWR_ON        0x01
    #define LLOPM_PWR_ON        0x01
    #define RLOPM_PWR_ON    0x01

    #define INVERT_VOL(val)   (0x7f - val)

    /* Default output volume (inverted) */
    #define DEFAULT_VOL     INVERT_VOL(0x50)
    /* Default input volume */
    #define DEFAULT_GAIN    0x20

    void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
    int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);

    /* headset detection / button API */

    /* The AIC3x supports detection of stereo headsets (GND + left + right signal)
     * and cellular headsets (GND + speaker output + microphone input).
     * It is recommended to enable MIC bias for this function to work properly.
     * For more information, please refer to the datasheet. */
    enum {
        AIC3X_HEADSET_DETECT_OFF    = 0,
        AIC3X_HEADSET_DETECT_STEREO    = 1,
        AIC3X_HEADSET_DETECT_CELLULAR   = 2,
        AIC3X_HEADSET_DETECT_BOTH    = 3
    };

    enum {
        AIC3X_HEADSET_DEBOUNCE_16MS    = 0,
        AIC3X_HEADSET_DEBOUNCE_32MS    = 1,
        AIC3X_HEADSET_DEBOUNCE_64MS    = 2,
        AIC3X_HEADSET_DEBOUNCE_128MS    = 3,
        AIC3X_HEADSET_DEBOUNCE_256MS    = 4,
        AIC3X_HEADSET_DEBOUNCE_512MS    = 5
    };

    enum {
        AIC3X_BUTTON_DEBOUNCE_0MS    = 0,
        AIC3X_BUTTON_DEBOUNCE_8MS    = 1,
        AIC3X_BUTTON_DEBOUNCE_16MS    = 2,
        AIC3X_BUTTON_DEBOUNCE_32MS    = 3
    };

    #define AIC3X_HEADSET_DETECT_ENABLED    0x80
    #define AIC3X_HEADSET_DETECT_SHIFT    5
    #define AIC3X_HEADSET_DETECT_MASK    3
    #define AIC3X_HEADSET_DEBOUNCE_SHIFT    2
    #define AIC3X_HEADSET_DEBOUNCE_MASK    7
    #define AIC3X_BUTTON_DEBOUNCE_SHIFT     0
    #define AIC3X_BUTTON_DEBOUNCE_MASK    3

    /* see the enums above for valid parameters to this function */
    void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
                     int headset_debounce, int button_debounce);
    int aic3x_headset_detected(struct snd_soc_codec *codec);
    int aic3x_button_pressed(struct snd_soc_codec *codec);

    #endif /* _AIC3X_H */