1 /**
2 * \file pcm186x_if.c
3 *
4 * \brief APIs to configure the PCM186X ADC
5 *
6 * This file contains the implementation of the PCM186X ADC driver for
7 * DSP BIOS operating system.
8 *
9 * (C) Copyright 2017, Texas Instruments, Inc
10 */
12 /*
13 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
45 /* ========================================================================== */
46 /* INCLUDE FILES */
47 /* ========================================================================== */
48 #include <codec_if.h>
49 #include "pcm186x_if.h"
50 #include <ICodec.h>
51 #include <mcasp_cfg.h>
52 #include "cmb.h"
54 /******************************************************************************
55 ** INTERNAL MACRO DEFINITIONS
56 *******************************************************************************/
57 #define I2C_CODEC_U1_ADDR (0x4A)
58 #define I2C_CODEC_U2_ADDR (0x4B)
59 // micr gain in dB (0 dB to 32 dB)
60 #define MIC_GAIN_DB 32
62 /*
63 ** Register Address for PCM186X Codec
64 */
65 #define PCM186X_P0_REG0 (0) /* Page Select */
66 #define PCM186X_P0_REG1 (1) /* Software Reset */
67 #define PCM186X_P0_REG2 (2) /* Codec Sample Rate Select */
68 #define PCM186X_P0_REG3 (3) /* PLL Programming A */
69 #define PCM186X_P0_REG4 (4) /* PLL Programming B */
70 #define PCM186X_P0_REG5 (5) /* PLL Programming C */
71 #define PCM186X_P0_REG6 (6) /* PLL Programming D */
72 #define PCM186X_P0_REG7 (7) /* Codec Datapath Setup */
73 #define PCM186X_P0_REG8 (8) /* Audio Serial Data I/f Control A */
74 #define PCM186X_P0_REG9 (9) /* Audio Serial Data I/f Control B */
75 #define PCM186X_P0_REG10 (10) /* Audio Serial Data I/f Control C */
76 #define PCM186X_P0_REG11 (11) /* Audio Codec Overflow Flag */
77 #define PCM186X_P0_REG12 (12) /* Audio Codec Digital Filter Ctrl */
78 #define PCM186X_P0_REG13 (13) /* Headset / Button Press Detect A */
79 #define PCM186X_P0_REG14 (14) /* Headset / Button Press Detect B */
80 #define PCM186X_P0_REG15 (15) /* Left ADC PGA Gain Control */
81 #define PCM186X_P0_REG16 (16) /* Right ADC PGA Gain Control */
82 #define PCM186X_P0_REG17 (17) /* MIC3L/R to Left ADC Control */
83 #define PCM186X_P0_REG18 (18) /* MIC3L/R to Right ADC Control */
84 #define PCM186X_P0_REG19 (19) /* LINE1L to Left ADC Control */
85 #define PCM186X_P0_REG20 (20) /* LINE2L to Left ADC Control */
86 #define PCM186X_P0_REG21 (21) /* LINE1R to Left ADC Control */
87 #define PCM186X_P0_REG22 (22) /* LINE1R to Right ADC Control */
88 #define PCM186X_P0_REG23 (23) /* LINE2R to Right ADC Control */
89 #define PCM186X_P0_REG24 (24) /* LINE1L to Right ADC Control */
90 #define PCM186X_P0_REG25 (25) /* MICBIAS Control */
91 #define PCM186X_P0_REG26 (26) /* Left AGC Control A */
92 #define PCM186X_P0_REG27 (27) /* Left AGC Control B */
93 #define PCM186X_P0_REG28 (28) /* Left AGC Control C */
94 #define PCM186X_P0_REG29 (29) /* Right AGC Control A */
95 #define PCM186X_P0_REG30 (30) /* Right AGC Control B */
96 #define PCM186X_P0_REG31 (31) /* Right AGC Control C */
97 #define PCM186X_P0_REG32 (32) /* Left AGC Gain */
98 #define PCM186X_P0_REG33 (33) /* Right AGC Gain */
99 #define PCM186X_P0_REG34 (34) /* Left AGC Noise Gate Debounce */
100 #define PCM186X_P0_REG35 (35) /* Right AGC Noise Gate Debounce */
101 #define PCM186X_P0_REG36 (36) /* ADC Flag */
102 #define PCM186X_P0_REG37 (37) /* DAC Power and Output Driver Control */
103 #define PCM186X_P0_REG38 (38) /* High Power Output Driver Control*/
104 #define PCM186X_P0_REG40 (40) /* High Power Output Stage Control*/
105 #define PCM186X_P0_REG41 (41) /* DAC Output Switching Control */
106 #define PCM186X_P0_REG42 (42) /* Output Driver Pop Reduction */
107 #define PCM186X_P0_REG43 (43) /* Left DAC Digital Volume Control */
108 #define PCM186X_P0_REG44 (44) /* Right DAC Digital Volume Control */
109 #define PCM186X_P0_REG45 (45) /* LINE2L to HPLOUT Volume Control */
110 #define PCM186X_P0_REG46 (46) /* PGA_L to HPLOUT Volume Control */
111 #define PCM186X_P0_REG47 (47) /* DAC_L1 to HPLOUT Volume Control */
112 #define PCM186X_P0_REG48 (48) /* LINE2R to HPLOUT Volume Control */
113 #define PCM186X_P0_REG49 (49) /* PGA_R to HPLOUT Volume Control */
114 #define PCM186X_P0_REG50 (50) /* DAC_R1 to HPLOUT Volume Control */
115 #define PCM186X_P0_REG51 (51) /* HPLOUT Output Level Control */
116 #define PCM186X_P0_REG52 (52) /* LINE2L to HPLCOM Volume Control */
117 #define PCM186X_P0_REG53 (53) /* PGA_L to HPLCOM Volume Control */
118 #define PCM186X_P0_REG54 (54) /* DAC_L1 to HPLCOM Volume Control */
119 #define PCM186X_P0_REG55 (55) /* LINE2R to HPLCOM Volume Control */
120 #define PCM186X_P0_REG56 (56) /* PGA_R to HPLCOM Volume Control */
121 #define PCM186X_P0_REG57 (57) /* DAC_R1 to HPLCOM Volume Control */
122 #define PCM186X_P0_REG58 (58) /* HPLCOM Output Level Control */
123 #define PCM186X_P0_REG59 (59) /* LINE2L to HPROUT Volume Control */
124 #define PCM186X_P0_REG60 (60) /* PGA_L to HPROUT Volume Control */
125 #define PCM186X_P0_REG61 (61) /* DAC_L1 to HPROUT Volume Control */
126 #define PCM186X_P0_REG62 (62) /* LINE2R to HPROUT Volume Control */
127 #define PCM186X_P0_REG63 (63) /* PGA_R to HPROUT Volume Control */
128 #define PCM186X_P0_REG64 (64) /* DAC_R1 to HPROUT Volume Control */
129 #define PCM186X_P0_REG65 (65) /* HPROUT Output Level Control */
130 #define PCM186X_P0_REG66 (66) /* LINE2L to HPRCOM Volume Control */
131 #define PCM186X_P0_REG67 (67) /* PGA_L to HPRCOM Volume Control */
132 #define PCM186X_P0_REG68 (68) /* DAC_L1 to HPRCOM Volume Control */
133 #define PCM186X_P0_REG69 (69) /* LINE2R to HPRCOM Volume Control */
134 #define PCM186X_P0_REG70 (70) /* PGA_R to HPRCOM Volume Control */
135 #define PCM186X_P0_REG71 (71) /* DAC_R1 to HPRCOM Volume Control */
136 #define PCM186X_P0_REG72 (72) /* HPRCOM Output Level Control */
137 #define PCM186X_P0_REG73 (73) /* LINE2L to MONO_LOP/M Volume Control*/
138 #define PCM186X_P0_REG74 (74) /* PGA_L to MONO_LOP/M Volume Control */
139 #define PCM186X_P0_REG75 (75) /* DAC_L1 to MONO_LOP/M Volume Control */
140 #define PCM186X_P0_REG76 (76) /* LINE2R to MONO_LOP/M Volume Control */
141 #define PCM186X_P0_REG77 (77) /* PGA_R to MONO_LOP/M Volume Control */
142 #define PCM186X_P0_REG78 (78) /* DAC_R1 to MONO_LOP/M Volume Control */
143 #define PCM186X_P0_REG79 (79) /* MONO_LOP/M Output Level Control */
144 #define PCM186X_P0_REG80 (80) /* LINE2L to LEFT_LOP/M Volume Control */
145 #define PCM186X_P0_REG81 (81) /* PGA_L to LEFT_LOP/M Volume Control */
146 #define PCM186X_P0_REG82 (82) /* DAC_L1 to LEFT_LOP/M Volume Control */
147 #define PCM186X_P0_REG83 (83) /* LINE2R to LEFT_LOP/M Volume Control */
148 #define PCM186X_P0_REG84 (84) /* PGA_R to LEFT_LOP/M Volume Control */
149 #define PCM186X_P0_REG85 (85) /* DAC_R1 to LEFT_LOP/M Volume Control */
150 #define PCM186X_P0_REG86 (86) /* LEFT_LOP/M Output Level Control */
151 #define PCM186X_P0_REG87 (87) /* LINE2L to RIGHT_LOP/M Volume Control */
152 #define PCM186X_P0_REG88 (88) /* PGA_L to RIGHT_LOP/M Volume Control */
153 #define PCM186X_P0_REG89 (89) /* DAC_L1 to RIGHT_LOP/M Volume Control */
154 #define PCM186X_P0_REG90 (90) /* LINE2R to RIGHT_LOP/M Volume Control */
155 #define PCM186X_P0_REG91 (91) /* PGA_R to RIGHT_LOP/M Volume Control */
156 #define PCM186X_P0_REG92 (92) /* DAC_R1 to RIGHT_LOP/M Volume Control*/
157 #define PCM186X_P0_REG93 (93) /* RIGHT_LOP/M Output Level Control */
158 #define PCM186X_P0_REG94 (94) /* Module Power Status */
159 #define PCM186X_P0_REG95 (95) /**< O/P Driver Short Circuit Detection Status*/
160 #define PCM186X_P0_REG96 (96) /* Sticky Interrupt Flags */
161 #define PCM186X_P0_REG97 (97) /* Real-time Interrupt Flags */
162 #define PCM186X_P0_REG98 (98) /* GPIO1 Control */
163 #define PCM186X_P0_REG99 (99) /* GPIO2 Control */
164 #define PCM186X_P0_REG100 (100) /* Additional GPIO Control A */
165 #define PCM186X_P0_REG101 (101) /* Additional GPIO Control B */
166 #define PCM186X_P0_REG102 (102) /* Clock Generation Control */
167 #define PCM186X_P0_REG109 (109) /* DAC Quiescent Current Adjustment */
169 #define PCM186X_RESET (0x80)
171 #define PCM186X_SLOT_WIDTH_16 (0u << 4u)
172 #define PCM186X_SLOT_WIDTH_20 (1u << 4u)
173 #define PCM186X_SLOT_WIDTH_24 (2u << 4u)
174 #define PCM186X_SLOT_WIDTH_32 (3u << 4u)
176 extern unsigned int I2C_slaveAddr;
178 /******************************************************************************
179 ** FUNCTION DEFINITIONS
180 *******************************************************************************/
181 /**
182 * \brief Resets the PCM186X Codec
183 *
184 * \param baseAddr Base Address of the interface connected to PCM186X
185 *
186 * \return None.
187 *
188 **/
189 void PCM186XReset(unsigned int baseAddr)
190 {
191 /* Select Page 0 */
192 CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0);
194 /* Reset the codec */
195 CodecRegWrite(baseAddr, PCM186X_P0_REG1, PCM186X_RESET);
196 }
198 /**
199 * \brief Initializes the ADC section of the PCM186X Codec
200 *
201 * \param baseAddr Base Address of the interface connected to PCM186X
202 *
203 * \return None.
204 *
205 **/
206 void PCM186XADCInit(void)
207 {
208 #if 0
209 unsigned int baseAddr = SOC_I2C_1_REGS;
210 volatile int looper;
212 //
213 // U1 set up
214 //
215 // initialize U1 on CMB
216 ///I2CCodecIfInit(baseAddr, 2, I2C_CODEC_U1_ADDR);
217 I2C_slaveAddr = I2C_CODEC_U1_ADDR;
219 #ifdef AUXCLK_MASTER_MODE
220 // changae to page 0
221 CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0x00);
223 // {0x01, 0x40}, /** PGA CH1_L to MIC_GAIN_DB */
224 CodecRegWrite(baseAddr, PCM186X_P0_REG1, (MIC_GAIN_DB*2)&0x7F);
226 // {0x02, 0x40}, /** PGA CH1_R to MIC_GAIN_DB */
227 CodecRegWrite(baseAddr, PCM186X_P0_REG2, (MIC_GAIN_DB*2)&0x7F);
229 // {0x03, 0x40}, /** PGA CH2_L to MIC_GAIN_DB */
230 CodecRegWrite(baseAddr, PCM186X_P0_REG3, (MIC_GAIN_DB*2)&0x7F);
232 // {0x04, 0x40}, /** PGA CH2_R to MIC_GAIN_DB */
233 CodecRegWrite(baseAddr, PCM186X_P0_REG4, (MIC_GAIN_DB*2)&0x7F);
235 // {0x06, 0x41}, /** Polarity : Normal, Channel : VINL1[SE] */
236 CodecRegWrite(baseAddr, PCM186X_P0_REG6, 0x41);
238 // {0x07, 0x41}, /** Polarity : Normal, Channel : VINR1[SE] */
239 CodecRegWrite(baseAddr, PCM186X_P0_REG7, 0x41);
241 // {0x08, 0x44}, /** Polarity : Normal, Channel : VINL3[SE] */
242 CodecRegWrite(baseAddr, PCM186X_P0_REG8, 0x44);
244 // {0x09, 0x44}, /** Polarity : Normal, Channel : VINR3[SE] */
245 CodecRegWrite(baseAddr, PCM186X_P0_REG9, 0x44);
247 // {0x0B, 0x0C}, /** TX_WLEN: 16, FMT: I2S */
248 ///CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x0C);
249 // {0x0B, 0x0B}, /** RX WLEN : 24bit, TDM_LRCK_MODE : Duty cycle of LRCK is 50%, TX WLEN : 24 bit, FMT : I2S format */
250 CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x44);
252 // {0x10, 0x00}, /** GPIO0_FUNC - GPIO0, GPIO0_POL - Normal
253 // GPIO1_FUNC - GPIO1, GPIO1_POL - Normal */
254 CodecRegWrite(baseAddr, PCM186X_P0_REG16, 0x00);
256 // {0x11, 0x50}, /** GPIO2_FUNC - GPIO2, GPIO2_POL - Normal
257 // GPIO3_FUNC - DOUT2, GPIO3_POL - Normal */
258 CodecRegWrite(baseAddr, PCM186X_P0_REG17, 0x50);
260 // {0x12, 0x00}, /** GPIO0_DIR - GPIO0 - Input
261 // GPIO1_DIR - GPIO1 - Input */
262 CodecRegWrite(baseAddr, PCM186X_P0_REG18, 0x00);
264 // {0x13, 0x40}, /** GPIO2_DIR - GPIO2 - Input
265 // GPIO3_DIR - GPIO3 - Output */
266 CodecRegWrite(baseAddr, PCM186X_P0_REG19, 0x40);
268 // {0x20, 0x01}, /** SCK_XI_SEL : SCK or XTAL, MST_SCK_SRC : SCK or XI,
269 // MST_MODE : Slave, CMB_ADC_CLK_SRC : SCK,DSP2_CLK_SRC : SCK,
270 // DSP1_CLK_SRC : SCK,CLKDET_EN : Enable */
271 CodecRegWrite(baseAddr, PCM186X_P0_REG32, 0x41);
273 // wait for coec to be ready
274 for (looper = 0; looper < 20000; looper++)
275 {
276 ; // Wait
277 }
279 //
280 // U2 set up
281 //
282 // initialize U2 on CMB
283 ///I2CCodecIfInit(baseAddr, 2, I2C_CODEC_U2_ADDR);
284 I2C_slaveAddr = I2C_CODEC_U2_ADDR;
285 // changae to page 0
286 CodecRegWrite(baseAddr, PCM186X_P0_REG0, 0x00);
288 // {0x01, 0x40}, /** PGA CH1_L to MIC_GAIN_DB */
289 CodecRegWrite(baseAddr, PCM186X_P0_REG1, (MIC_GAIN_DB*2)&0x7F);
291 // {0x02, 0x40}, /** PGA CH1_R to MIC_GAIN_DB */
292 CodecRegWrite(baseAddr, PCM186X_P0_REG2, (MIC_GAIN_DB*2)&0x7F);
294 // {0x03, 0x40}, /** PGA CH2_L to MIC_GAIN_DB */
295 CodecRegWrite(baseAddr, PCM186X_P0_REG3, (MIC_GAIN_DB*2)&0x7F);
297 // {0x04, 0x40}, /** PGA CH2_R to MIC_GAIN_DB */
298 CodecRegWrite(baseAddr, PCM186X_P0_REG4, (MIC_GAIN_DB*2)&0x7F);
300 // {0x06, 0x41}, /** Polarity : Normal, Channel : VINL1[SE] */
301 CodecRegWrite(baseAddr, PCM186X_P0_REG6, 0x41);
303 // {0x07, 0x41}, /** Polarity : Normal, Channel : VINR1[SE] */
304 CodecRegWrite(baseAddr, PCM186X_P0_REG7, 0x41);
306 // {0x08, 0x44}, /** Polarity : Normal, Channel : VINL3[SE] */
307 CodecRegWrite(baseAddr, PCM186X_P0_REG8, 0x44);
309 // {0x09, 0x44}, /** Polarity : Normal, Channel : VINR3[SE] */
310 CodecRegWrite(baseAddr, PCM186X_P0_REG9, 0x44);
312 // {0x0B, 0x0C}, /** TX_WLEN: 16, FMT: I2S */
313 ///CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x0C);
314 // {0x0B, 0x0B}, /** RX WLEN : 24bit, TDM_LRCK_MODE : Duty cycle of LRCK is 50%, TX WLEN : 24 bit, FMT : I2S format */
315 CodecRegWrite(baseAddr, PCM186X_P0_REG11, 0x44);
317 // {0x10, 0x00}, /** GPIO0_FUNC - GPIO0, GPIO0_POL - Normal
318 // GPIO1_FUNC - GPIO1, GPIO1_POL - Normal */
319 CodecRegWrite(baseAddr, PCM186X_P0_REG16, 0x00);
321 // {0x11, 0x50}, /** GPIO2_FUNC - GPIO2, GPIO2_POL - Normal
322 // GPIO3_FUNC - DOUT2, GPIO3_POL - Normal */
323 CodecRegWrite(baseAddr, PCM186X_P0_REG17, 0x50);
325 // {0x12, 0x00}, /** GPIO0_DIR - GPIO0 - Input
326 // GPIO1_DIR - GPIO1 - Input */
327 CodecRegWrite(baseAddr, PCM186X_P0_REG18, 0x00);
329 // {0x13, 0x40}, /** GPIO2_DIR - GPIO2 - Input
330 // GPIO3_DIR - GPIO3 - Output */
331 CodecRegWrite(baseAddr, PCM186X_P0_REG19, 0x40);
333 // {0x20, 0x01}, /** SCK_XI_SEL : SCK or XTAL, MST_SCK_SRC : SCK or XI,
334 // MST_MODE : Slave, CMB_ADC_CLK_SRC : SCK,DSP2_CLK_SRC : SCK,
335 // DSP1_CLK_SRC : SCK,CLKDET_EN : Enable */
336 CodecRegWrite(baseAddr, PCM186X_P0_REG32, 0x41);
338 // wait for coec to be ready
339 for (looper = 0; looper < 2000; looper++)
340 {
341 ; // Wait
342 }
343 #endif
344 #else
345 Cmb_STATUS status;
346 volatile int looper;
348 I2C_slaveAddr = I2C_CODEC_U1_ADDR;
349 status = (Cmb_STATUS)cmb_AudioAdcInit(CMB_ADC_DEVICE_0);
350 if(status != Cmb_EOK)
351 {
352 IFPRINT(cmb_write("audioAdcConfig : audioAdcConfig Failed\n"));
353 return;
354 }
356 // wait for coec to be ready
357 for (looper = 0; looper < 20000; looper++)
358 {
359 ; // Wait
360 }
362 I2C_slaveAddr = I2C_CODEC_U2_ADDR;
363 status = (Cmb_STATUS)cmb_AudioAdcInit(CMB_ADC_DEVICE_1);
364 if(status != Cmb_EOK)
365 {
366 IFPRINT(cmb_write("audioAdcConfig : audioAdcConfig Failed\n"));
367 return;
368 }
370 // wait for coec to be ready
371 for (looper = 0; looper < 20000; looper++)
372 {
373 ; // Wait
374 }
375 #endif
376 }
378 /***************************** End Of File ***********************************/