/** * \file pcm186x_if.c * * \brief APIs to configure the PCM186X ADC * * This file contains the implementation of the PCM186X ADC driver for * DSP BIOS operating system. * * (C) Copyright 2017, Texas Instruments, Inc */ /* * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* ========================================================================== */ /* INCLUDE FILES */ /* ========================================================================== */ #include #include "pcm186x_if.h" #include #include #include "cmb.h" /****************************************************************************** ** INTERNAL MACRO DEFINITIONS *******************************************************************************/ #define I2C_CODEC_U1_ADDR (0x4A) #define I2C_CODEC_U2_ADDR (0x4B) // micr gain in dB (0 dB to 32 dB) #define MIC_GAIN_DB 32 /* ** Register Address for PCM186X Codec */ #define PCM186X_P0_REG0 (0) /* Page Select */ #define PCM186X_P0_REG1 (1) /* Software Reset */ #define PCM186X_P0_REG2 (2) /* Codec Sample Rate Select */ #define PCM186X_P0_REG3 (3) /* PLL Programming A */ #define PCM186X_P0_REG4 (4) /* PLL Programming B */ #define PCM186X_P0_REG5 (5) /* PLL Programming C */ #define PCM186X_P0_REG6 (6) /* PLL Programming D */ #define PCM186X_P0_REG7 (7) /* Codec Datapath Setup */ #define PCM186X_P0_REG8 (8) /* Audio Serial Data I/f Control A */ #define PCM186X_P0_REG9 (9) /* Audio Serial Data I/f Control B */ #define PCM186X_P0_REG10 (10) /* Audio Serial Data I/f Control C */ #define PCM186X_P0_REG11 (11) /* Audio Codec Overflow Flag */ #define PCM186X_P0_REG12 (12) /* Audio Codec Digital Filter Ctrl */ #define PCM186X_P0_REG13 (13) /* Headset / Button Press Detect A */ #define PCM186X_P0_REG14 (14) /* Headset / Button Press Detect B */ #define PCM186X_P0_REG15 (15) /* Left ADC PGA Gain Control */ #define PCM186X_P0_REG16 (16) /* Right ADC PGA Gain Control */ #define PCM186X_P0_REG17 (17) /* MIC3L/R to Left ADC Control */ #define PCM186X_P0_REG18 (18) /* MIC3L/R to Right ADC Control */ #define PCM186X_P0_REG19 (19) /* LINE1L to Left ADC Control */ #define PCM186X_P0_REG20 (20) /* LINE2L to Left ADC Control */ #define PCM186X_P0_REG21 (21) /* LINE1R to Left ADC Control */ #define PCM186X_P0_REG22 (22) /* LINE1R to Right ADC Control */ #define PCM186X_P0_REG23 (23) /* LINE2R to Right ADC Control */ #define PCM186X_P0_REG24 (24) /* LINE1L to Right ADC Control */ #define PCM186X_P0_REG25 (25) /* MICBIAS Control */ #define PCM186X_P0_REG26 (26) /* Left AGC Control A */ #define PCM186X_P0_REG27 (27) /* Left AGC Control B */ #define PCM186X_P0_REG28 (28) /* Left AGC Control C */ #define PCM186X_P0_REG29 (29) /* Right AGC Control A */ #define PCM186X_P0_REG30 (30) /* Right AGC Control B */ #define PCM186X_P0_REG31 (31) /* Right AGC Control C */ #define PCM186X_P0_REG32 (32) /* Left AGC Gain */ #define PCM186X_P0_REG33 (33) /* Right AGC Gain */ #define PCM186X_P0_REG34 (34) /* Left AGC Noise Gate Debounce */ #define PCM186X_P0_REG35 (35) /* Right AGC Noise Gate Debounce */ #define PCM186X_P0_REG36 (36) /* ADC Flag */ #define PCM186X_P0_REG37 (37) /* DAC Power and Output Driver Control */ #define PCM186X_P0_REG38 (38) /* High Power Output Driver Control*/ #define PCM186X_P0_REG40 (40) /* High Power Output Stage Control*/ #define PCM186X_P0_REG41 (41) /* DAC Output Switching Control */ #define PCM186X_P0_REG42 (42) /* Output Driver Pop Reduction */ #define PCM186X_P0_REG43 (43) /* Left DAC Digital Volume Control */ #define PCM186X_P0_REG44 (44) /* Right DAC Digital Volume Control */ #define PCM186X_P0_REG45 (45) /* LINE2L to HPLOUT Volume Control */ #define PCM186X_P0_REG46 (46) /* PGA_L to HPLOUT Volume Control */ #define PCM186X_P0_REG47 (47) /* DAC_L1 to HPLOUT Volume Control */ #define PCM186X_P0_REG48 (48) /* LINE2R to HPLOUT Volume Control */ #define PCM186X_P0_REG49 (49) /* PGA_R to HPLOUT Volume Control */ #define PCM186X_P0_REG50 (50) /* DAC_R1 to HPLOUT Volume Control */ #define PCM186X_P0_REG51 (51) /* HPLOUT Output Level Control */ #define PCM186X_P0_REG52 (52) /* LINE2L to HPLCOM Volume Control */ #define PCM186X_P0_REG53 (53) /* PGA_L to HPLCOM Volume Control */ #define PCM186X_P0_REG54 (54) /* DAC_L1 to HPLCOM Volume Control */ #define PCM186X_P0_REG55 (55) /* LINE2R to HPLCOM Volume Control */ #define PCM186X_P0_REG56 (56) /* PGA_R to HPLCOM Volume Control */ #define PCM186X_P0_REG57 (57) /* DAC_R1 to HPLCOM Volume Control */ #define PCM186X_P0_REG58 (58) /* HPLCOM Output Level Control */ #define PCM186X_P0_REG59 (59) /* LINE2L to HPROUT Volume Control */ #define PCM186X_P0_REG60 (60) /* PGA_L to HPROUT Volume Control */ #define PCM186X_P0_REG61 (61) /* DAC_L1 to HPROUT Volume Control */ #define PCM186X_P0_REG62 (62) /* LINE2R to HPROUT Volume Control */ #define PCM186X_P0_REG63 (63) /* PGA_R to HPROUT Volume Control */ #define PCM186X_P0_REG64 (64) /* DAC_R1 to HPROUT Volume Control */ #define PCM186X_P0_REG65 (65) /* HPROUT Output Level Control */ #define PCM186X_P0_REG66 (66) /* LINE2L to HPRCOM Volume Control */ #define PCM186X_P0_REG67 (67) /* PGA_L to HPRCOM Volume Control */ #define PCM186X_P0_REG68 (68) /* DAC_L1 to HPRCOM Volume Control */ #define PCM186X_P0_REG69 (69) /* LINE2R to HPRCOM Volume Control */ #define PCM186X_P0_REG70 (70) /* PGA_R to HPRCOM Volume Control */ #define PCM186X_P0_REG71 (71) /* DAC_R1 to HPRCOM Volume Control */ #define PCM186X_P0_REG72 (72) /* HPRCOM Output Level Control */ #define PCM186X_P0_REG73 (73) /* LINE2L to MONO_LOP/M Volume Control*/ #define PCM186X_P0_REG74 (74) /* PGA_L to MONO_LOP/M Volume Control */ #define PCM186X_P0_REG75 (75) /* DAC_L1 to MONO_LOP/M Volume Control */ #define PCM186X_P0_REG76 (76) /* LINE2R to MONO_LOP/M Volume Control */ #define PCM186X_P0_REG77 (77) /* PGA_R to MONO_LOP/M Volume Control */ #define PCM186X_P0_REG78 (78) /* DAC_R1 to MONO_LOP/M Volume Control */ #define PCM186X_P0_REG79 (79) /* MONO_LOP/M Output Level Control */ #define PCM186X_P0_REG80 (80) /* LINE2L to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG81 (81) /* PGA_L to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG82 (82) /* DAC_L1 to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG83 (83) /* LINE2R to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG84 (84) /* PGA_R to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG85 (85) /* DAC_R1 to LEFT_LOP/M Volume Control */ #define PCM186X_P0_REG86 (86) /* LEFT_LOP/M Output Level Control */ #define PCM186X_P0_REG87 (87) /* LINE2L to RIGHT_LOP/M Volume Control */ #define PCM186X_P0_REG88 (88) /* PGA_L to RIGHT_LOP/M Volume Control */ #define PCM186X_P0_REG89 (89) /* DAC_L1 to RIGHT_LOP/M Volume Control */ #define PCM186X_P0_REG90 (90) /* LINE2R to RIGHT_LOP/M Volume Control */ #define PCM186X_P0_REG91 (91) /* PGA_R to RIGHT_LOP/M Volume Control */ #define PCM186X_P0_REG92 (92) /* DAC_R1 to RIGHT_LOP/M Volume Control*/ #define PCM186X_P0_REG93 (93) /* RIGHT_LOP/M Output Level Control */ #define PCM186X_P0_REG94 (94) /* Module Power Status */ #define PCM186X_P0_REG95 (95) /**< O/P Driver Short Circuit Detection Status*/ #define PCM186X_P0_REG96 (96) /* Sticky Interrupt Flags */ #define PCM186X_P0_REG97 (97) /* Real-time Interrupt Flags */ #define PCM186X_P0_REG98 (98) /* GPIO1 Control */ #define PCM186X_P0_REG99 (99) /* GPIO2 Control */ #define PCM186X_P0_REG100 (100) /* Additional GPIO Control A */ #define PCM186X_P0_REG101 (101) /* Additional GPIO Control B */ #define PCM186X_P0_REG102 (102) /* Clock Generation Control */ #define PCM186X_P0_REG109 (109) /* DAC Quiescent Current Adjustment */ #define PCM186X_RESET (0x80) #define PCM186X_SLOT_WIDTH_16 (0u << 4u) #define PCM186X_SLOT_WIDTH_20 (1u << 4u) #define PCM186X_SLOT_WIDTH_24 (2u << 4u) #define PCM186X_SLOT_WIDTH_32 (3u << 4u) extern unsigned int I2C_slaveAddr; /****************************************************************************** ** FUNCTION DEFINITIONS *******************************************************************************/ /** * \brief Resets the PCM186X Codec * * \param baseAddr Base Address of the interface connected to PCM186X * * \return None. * **/ void PCM186XReset(unsigned int baseAddr) { /* Select Page 0 */ CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0); /* Reset the codec */ CodecRegWrite(baseAddr, PCM186X_P0_REG1, PCM186X_RESET); } /** * \brief Initializes the ADC section of the PCM186X Codec * * \param baseAddr Base Address of the interface connected to PCM186X * * \return None. * **/ void PCM186XADCInit(void) { #if 0 unsigned int baseAddr = SOC_I2C_1_REGS; volatile int looper; // // U1 set up // // initialize U1 on CMB ///I2CCodecIfInit(baseAddr, 2, I2C_CODEC_U1_ADDR); I2C_slaveAddr = I2C_CODEC_U1_ADDR; #ifdef AUXCLK_MASTER_MODE // changae to page 0 CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0x00); // {0x01, 0x40}, /** PGA CH1_L to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG1, (MIC_GAIN_DB*2)&0x7F); // {0x02, 0x40}, /** PGA CH1_R to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG2, (MIC_GAIN_DB*2)&0x7F); // {0x03, 0x40}, /** PGA CH2_L to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG3, (MIC_GAIN_DB*2)&0x7F); // {0x04, 0x40}, /** PGA CH2_R to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG4, (MIC_GAIN_DB*2)&0x7F); // {0x06, 0x41}, /** Polarity : Normal, Channel : VINL1[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG6, 0x41); // {0x07, 0x41}, /** Polarity : Normal, Channel : VINR1[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG7, 0x41); // {0x08, 0x44}, /** Polarity : Normal, Channel : VINL3[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG8, 0x44); // {0x09, 0x44}, /** Polarity : Normal, Channel : VINR3[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG9, 0x44); // {0x0B, 0x0C}, /** TX_WLEN: 16, FMT: I2S */ ///CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x0C); // {0x0B, 0x0B}, /** RX WLEN : 24bit, TDM_LRCK_MODE : Duty cycle of LRCK is 50%, TX WLEN : 24 bit, FMT : I2S format */ CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x44); // {0x10, 0x00}, /** GPIO0_FUNC - GPIO0, GPIO0_POL - Normal // GPIO1_FUNC - GPIO1, GPIO1_POL - Normal */ CodecRegWrite(baseAddr, PCM186X_P0_REG16, 0x00); // {0x11, 0x50}, /** GPIO2_FUNC - GPIO2, GPIO2_POL - Normal // GPIO3_FUNC - DOUT2, GPIO3_POL - Normal */ CodecRegWrite(baseAddr, PCM186X_P0_REG17, 0x50); // {0x12, 0x00}, /** GPIO0_DIR - GPIO0 - Input // GPIO1_DIR - GPIO1 - Input */ CodecRegWrite(baseAddr, PCM186X_P0_REG18, 0x00); // {0x13, 0x40}, /** GPIO2_DIR - GPIO2 - Input // GPIO3_DIR - GPIO3 - Output */ CodecRegWrite(baseAddr, PCM186X_P0_REG19, 0x40); // {0x20, 0x01}, /** SCK_XI_SEL : SCK or XTAL, MST_SCK_SRC : SCK or XI, // MST_MODE : Slave, CMB_ADC_CLK_SRC : SCK,DSP2_CLK_SRC : SCK, // DSP1_CLK_SRC : SCK,CLKDET_EN : Enable */ CodecRegWrite(baseAddr, PCM186X_P0_REG32, 0x41); // wait for coec to be ready for (looper = 0; looper < 20000; looper++) { ; // Wait } // // U2 set up // // initialize U2 on CMB ///I2CCodecIfInit(baseAddr, 2, I2C_CODEC_U2_ADDR); I2C_slaveAddr = I2C_CODEC_U2_ADDR; // changae to page 0 CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0x00); // {0x01, 0x40}, /** PGA CH1_L to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG1, (MIC_GAIN_DB*2)&0x7F); // {0x02, 0x40}, /** PGA CH1_R to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG2, (MIC_GAIN_DB*2)&0x7F); // {0x03, 0x40}, /** PGA CH2_L to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG3, (MIC_GAIN_DB*2)&0x7F); // {0x04, 0x40}, /** PGA CH2_R to MIC_GAIN_DB */ CodecRegWrite(baseAddr, PCM186X_P0_REG4, (MIC_GAIN_DB*2)&0x7F); // {0x06, 0x41}, /** Polarity : Normal, Channel : VINL1[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG6, 0x41); // {0x07, 0x41}, /** Polarity : Normal, Channel : VINR1[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG7, 0x41); // {0x08, 0x44}, /** Polarity : Normal, Channel : VINL3[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG8, 0x44); // {0x09, 0x44}, /** Polarity : Normal, Channel : VINR3[SE] */ CodecRegWrite(baseAddr, PCM186X_P0_REG9, 0x44); // {0x0B, 0x0C}, /** TX_WLEN: 16, FMT: I2S */ ///CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x0C); // {0x0B, 0x0B}, /** RX WLEN : 24bit, TDM_LRCK_MODE : Duty cycle of LRCK is 50%, TX WLEN : 24 bit, FMT : I2S format */ CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x44); // {0x10, 0x00}, /** GPIO0_FUNC - GPIO0, GPIO0_POL - Normal // GPIO1_FUNC - GPIO1, GPIO1_POL - Normal */ CodecRegWrite(baseAddr, PCM186X_P0_REG16, 0x00); // {0x11, 0x50}, /** GPIO2_FUNC - GPIO2, GPIO2_POL - Normal // GPIO3_FUNC - DOUT2, GPIO3_POL - Normal */ CodecRegWrite(baseAddr, PCM186X_P0_REG17, 0x50); // {0x12, 0x00}, /** GPIO0_DIR - GPIO0 - Input // GPIO1_DIR - GPIO1 - Input */ CodecRegWrite(baseAddr, PCM186X_P0_REG18, 0x00); // {0x13, 0x40}, /** GPIO2_DIR - GPIO2 - Input // GPIO3_DIR - GPIO3 - Output */ CodecRegWrite(baseAddr, PCM186X_P0_REG19, 0x40); // {0x20, 0x01}, /** SCK_XI_SEL : SCK or XTAL, MST_SCK_SRC : SCK or XI, // MST_MODE : Slave, CMB_ADC_CLK_SRC : SCK,DSP2_CLK_SRC : SCK, // DSP1_CLK_SRC : SCK,CLKDET_EN : Enable */ CodecRegWrite(baseAddr, PCM186X_P0_REG32, 0x41); // wait for coec to be ready for (looper = 0; looper < 2000; looper++) { ; // Wait } #endif #else Cmb_STATUS status; volatile int looper; I2C_slaveAddr = I2C_CODEC_U1_ADDR; status = (Cmb_STATUS)cmb_AudioAdcInit(CMB_ADC_DEVICE_0); if(status != Cmb_EOK) { IFPRINT(cmb_write("audioAdcConfig : audioAdcConfig Failed\n")); return; } // wait for coec to be ready for (looper = 0; looper < 20000; looper++) { ; // Wait } I2C_slaveAddr = I2C_CODEC_U2_ADDR; status = (Cmb_STATUS)cmb_AudioAdcInit(CMB_ADC_DEVICE_1); if(status != Cmb_EOK) { IFPRINT(cmb_write("audioAdcConfig : audioAdcConfig Failed\n")); return; } // wait for coec to be ready for (looper = 0; looper < 20000; looper++) { ; // Wait } #endif } /***************************** End Of File ***********************************/