arduino-audio-driver
Loading...
Searching...
No Matches
TLV320AIC3104.h
Go to the documentation of this file.
1
13#pragma once
14#include <cstddef>
16
17namespace audio_driver {
18
27
28// Make it easier to represent bits from the datasheet.
29// Bits D[l] - D[r] = 0b[v] l & r are between 7 and 0 inclusive.
30// For example: "D7-D5 set to 010" is `makeBits(7, 5, 0b010)` or
31// `makeBits(7, 5, 2)`.
32// Plain functions (not macros) are used here, unlike ESP-IDF's own
33// single-arg BIT(x) macro (from esp_bit_defs.h), so this header never has
34// to undef/restore anyone else's macro. They live at namespace scope
35// (rather than as class members) so they are fully defined before any
36// static constexpr class member that uses them in its initializer.
37static constexpr uint8_t makeBits(uint8_t l, uint8_t r, uint8_t v) {
38 return (uint8_t)(((v) << (r)) & ((1 << ((l) + 1)) - 1));
39}
40static constexpr uint8_t makeBit(uint8_t l, uint8_t v) {
41 return (uint8_t)(((v) & 0x01) << (l));
42}
43
56 public:
58 struct RegAddr {
59 uint8_t page;
60 uint8_t reg;
61 };
62
63 static constexpr uint8_t I2C_ADDR = 0x18;
64
65 // ---- Page 0 registers ----
66 static constexpr RegAddr SOFT_RESET_ADDR{0, 1};
67 static constexpr RegAddr SAMPLE_RATE_SEL_ADDR{0, 2};
68 static constexpr RegAddr PLL_PROGA_ADDR{0, 3};
69 static constexpr RegAddr PLL_PROGB_ADDR{0, 4};
70 static constexpr RegAddr PLL_PROGC_ADDR{0, 5};
71 static constexpr RegAddr PLL_PROGD_ADDR{0, 6};
72 static constexpr RegAddr CODEC_DATAPATH_ADDR{0, 7};
73 static constexpr RegAddr ASD_INTF_CTRLA_ADDR{0, 8};
74 static constexpr RegAddr ASD_INTF_CTRLB_ADDR{0, 9};
75 static constexpr RegAddr ASD_INTF_CTRLC_ADDR{0, 10};
76 static constexpr RegAddr OVRF_STATUS_PLLR_ADDR{0, 11};
77 static constexpr RegAddr DIGI_FILT_CTRL_ADDR{0, 12};
78 static constexpr RegAddr HEADSET_BTN_PRESS_DETECTA_ADDR{0, 13};
79 static constexpr RegAddr HEADSET_BTN_PRESS_DETECTB_ADDR{0, 14};
80 static constexpr RegAddr LADC_VOL_ADDR{0, 15};
81 static constexpr RegAddr RADC_VOL_ADDR{0, 16};
82 static constexpr RegAddr MIC2_LADC_CTRL_ADDR{0, 17};
83 static constexpr RegAddr MIC2_RADC_CTRL_ADDR{0, 18};
84 static constexpr RegAddr LINE1L_LADC_CTRL_ADDR{0, 19};
85 // 20 is reserved
86 static constexpr RegAddr LINE1R_LADC_CTRL_ADDR{0, 21};
87 static constexpr RegAddr LINE1R_RADC_CTRL_ADDR{0, 22};
88 // 23 is reserved
89 static constexpr RegAddr LINE1L_RADC_CTRL_ADDR{0, 24};
90 static constexpr RegAddr MICBIAS_CTRL_ADDR{0, 25};
91 static constexpr RegAddr LAGC_CTRLA_ADDR{0, 26};
92 static constexpr RegAddr LAGC_CTRLB_ADDR{0, 27};
93 static constexpr RegAddr LAGC_CTRLC_ADDR{0, 28};
94 static constexpr RegAddr RAGC_CTRLA_ADDR{0, 29};
95 static constexpr RegAddr RAGC_CTRLB_ADDR{0, 30};
96 static constexpr RegAddr RAGC_CTRLC_ADDR{0, 31};
97 static constexpr RegAddr LAGC_GAIN_ADDR{0, 32};
98 static constexpr RegAddr RAGC_GAIN_ADDR{0, 33};
99 static constexpr RegAddr LAGC_NGATE_DEBOUNCE_ADDR{0, 34};
100 static constexpr RegAddr RAGC_NGATE_DEBOUNCE_ADDR{0, 35};
101 static constexpr RegAddr ADC_FLAG_ADDR{0, 36};
102 static constexpr RegAddr DAC_PWR_ADDR{0, 37};
103 static constexpr RegAddr HPRCOM_CFG_ADDR{0, 38};
104 // 39 is reserved
105 static constexpr RegAddr HPCOM_CMVOLT_ADDR{0, 40};
106 static constexpr RegAddr DAC_SW_CTRL_ADDR{0, 41};
107 static constexpr RegAddr POP_REDUCTION_ADDR{0, 42};
108 static constexpr RegAddr LDAC_VOL_ADDR{0, 43};
109 static constexpr RegAddr RDAC_VOL_ADDR{0, 44};
110 // 45 is reserved
111 static constexpr RegAddr PGAL_HPLOUT_VOL_ADDR{0, 46};
112 static constexpr RegAddr DACL1_HPLOUT_VOL_ADDR{0, 47};
113 // 48 is reserved
114 static constexpr RegAddr PGAR_HPLOUT_VOL_ADDR{0, 49};
115 static constexpr RegAddr DACR1_HPLOUT_VOL_ADDR{0, 50};
116 static constexpr RegAddr HPLOUT_CTRL_ADDR{0, 51};
117 // 52 is reserved
118 static constexpr RegAddr PGAL_HPLCOM_VOL_ADDR{0, 53};
119 static constexpr RegAddr DACL1_HPLCOM_VOL_ADDR{0, 54};
120 // 55 is reserved
121 static constexpr RegAddr PGAR_HPLCOM_VOL_ADDR{0, 56};
122 static constexpr RegAddr DACR1_HPLCOM_VOL_ADDR{0, 57};
123 static constexpr RegAddr HPLCOM_CTRL_ADDR{0, 58};
124 // 59 is reserved
125 static constexpr RegAddr PGAL_HPROUT_VOL_ADDR{0, 60};
126 static constexpr RegAddr DACL1_HPROUT_VOL_ADDR{0, 61};
127 // 62 is reserved
128 static constexpr RegAddr PGAR_HPROUT_VOL_ADDR{0, 63};
129 static constexpr RegAddr DACR1_HPROUT_VOL_ADDR{0, 64};
130 static constexpr RegAddr HPROUT_CTRL_ADDR{0, 65};
131 // 66 is reserved
132 static constexpr RegAddr PGAL_HPRCOM_VOL_ADDR{0, 67};
133 static constexpr RegAddr DACL1_HPRCOM_VOL_ADDR{0, 68};
134 // 69 is reserved
135 static constexpr RegAddr PGAR_HPRCOM_VOL_ADDR{0, 70};
136 static constexpr RegAddr DACR1_HPRCOM_VOL_ADDR{0, 71};
137 static constexpr RegAddr HPRCOM_CTRL_ADDR{0, 72};
138 // 73-80 are reserved
139 static constexpr RegAddr PGAL_LLOPM_VOL_ADDR{0, 81};
140 static constexpr RegAddr DACL1_LLOPM_VOL_ADDR{0, 82};
141 // 83 is reserved
142 static constexpr RegAddr PGAR_LLOPM_VOL_ADDR{0, 84};
143 static constexpr RegAddr DACR1_LLOPM_VOL_ADDR{0, 85};
144 static constexpr RegAddr LLOPM_CTRL_ADDR{0, 86};
145 // 87 is reserved
146 static constexpr RegAddr PGAL_RLOPM_VOL_ADDR{0, 88};
147 static constexpr RegAddr DACL1_RLOPM_VOL_ADDR{0, 89};
148 // 90 is reserved
149 static constexpr RegAddr PGAR_RLOPM_VOL_ADDR{0, 91};
150 static constexpr RegAddr DACR1_RLOPM_VOL_ADDR{0, 92};
151 static constexpr RegAddr RLOPM_CTRL_ADDR{0, 93};
152 static constexpr RegAddr POWER_STATUS_ADDR{0, 94};
153 static constexpr RegAddr SHORT_DETECT_ADDR{0, 95};
154 static constexpr RegAddr STICKY_IRQ_FLAGS_ADDR{0, 96};
155 static constexpr RegAddr RT_IRQ_FLAGS_ADDR{0, 97};
156 // 98-100 are reserved
157 static constexpr RegAddr CLK_ADDR{0, 101};
158 static constexpr RegAddr CLK_GEN_ADDR{0, 102};
159 static constexpr RegAddr LAGC_PROG_ATTACK_ADDR{0, 103};
160 static constexpr RegAddr LAGC_PROG_DECAY_ADDR{0, 104};
161 static constexpr RegAddr RAGC_PROG_ATTACK_ADDR{0, 105};
162 static constexpr RegAddr RAGC_PROG_DECAY_ADDR{0, 106};
163 static constexpr RegAddr ADC_DIG_FILT_CTRL_ADDR{0, 107};
164 static constexpr RegAddr I2C_BUS_STATUS_ADDR{0, 107}; // Yes, same address as above.
165 static constexpr RegAddr ANALOG_BYPASS_CTRL_ADDR{0, 108};
166 static constexpr RegAddr DAC_QUIESCENT_CURRENT_ADDR{0, 109};
167 // 110-127 are reserved
168
169 // ---- Page 1 registers ----
170 //static constexpr RegAddr PAGE_SELECT_ADDR{1, 0};
171 static constexpr RegAddr LCH_FX_N0_MSB_ADDR{1, 1};
172 static constexpr RegAddr LCH_FX_N0_LSB_ADDR{1, 2};
173 static constexpr RegAddr LCH_FX_N1_MSB_ADDR{1, 3};
174 static constexpr RegAddr LCH_FX_N1_LSB_ADDR{1, 4};
175 static constexpr RegAddr LCH_FX_N2_MSB_ADDR{1, 5};
176 static constexpr RegAddr LCH_FX_N2_LSB_ADDR{1, 6};
177 static constexpr RegAddr LCH_FX_N3_MSB_ADDR{1, 7};
178 static constexpr RegAddr LCH_FX_N3_LSB_ADDR{1, 8};
179 static constexpr RegAddr LCH_FX_N4_MSB_ADDR{1, 9};
180 static constexpr RegAddr LCH_FX_N4_LSB_ADDR{1, 10};
181 static constexpr RegAddr LCH_FX_N5_MSB_ADDR{1, 11};
182 static constexpr RegAddr LCH_FX_N5_LSB_ADDR{1, 12};
183 static constexpr RegAddr LCH_FX_D1_MSB_ADDR{1, 13};
184 static constexpr RegAddr LCH_FX_D1_LSB_ADDR{1, 14};
185 static constexpr RegAddr LCH_FX_D2_MSB_ADDR{1, 15};
186 static constexpr RegAddr LCH_FX_D2_LSB_ADDR{1, 16};
187 static constexpr RegAddr LCH_FX_D4_MSB_ADDR{1, 17};
188 static constexpr RegAddr LCH_FX_D4_LSB_ADDR{1, 18};
189 static constexpr RegAddr LCH_FX_D5_MSB_ADDR{1, 19};
190 static constexpr RegAddr LCH_FX_D5_LSB_ADDR{1, 20};
191 static constexpr RegAddr LCH_DEEMP_N0_MSB_ADDR{1, 21};
192 static constexpr RegAddr LCH_DEEMP_N0_LSB_ADDR{1, 22};
193 static constexpr RegAddr LCH_DEEMP_N1_MSB_ADDR{1, 23};
194 static constexpr RegAddr LCH_DEEMP_N1_LSB_ADDR{1, 24};
195 static constexpr RegAddr LCH_DEEMP_D0_MSB_ADDR{1, 25};
196 static constexpr RegAddr LCH_DEEMP_D0_LSB_ADDR{1, 26};
197 static constexpr RegAddr RCH_FX_N0_MSB_ADDR{1, 27};
198 static constexpr RegAddr RCH_FX_N0_LSB_ADDR{1, 28};
199 static constexpr RegAddr RCH_FX_N1_MSB_ADDR{1, 29};
200 static constexpr RegAddr RCH_FX_N1_LSB_ADDR{1, 30};
201 static constexpr RegAddr RCH_FX_N2_MSB_ADDR{1, 31};
202 static constexpr RegAddr RCH_FX_N2_LSB_ADDR{1, 32};
203 static constexpr RegAddr RCH_FX_N3_MSB_ADDR{1, 33};
204 static constexpr RegAddr RCH_FX_N3_LSB_ADDR{1, 34};
205 static constexpr RegAddr RCH_FX_N4_MSB_ADDR{1, 35};
206 static constexpr RegAddr RCH_FX_N4_LSB_ADDR{1, 36};
207 static constexpr RegAddr RCH_FX_N5_MSB_ADDR{1, 37};
208 static constexpr RegAddr RCH_FX_N5_LSB_ADDR{1, 38};
209 static constexpr RegAddr RCH_FX_D1_MSB_ADDR{1, 39};
210 static constexpr RegAddr RCH_FX_D1_LSB_ADDR{1, 40};
211 static constexpr RegAddr RCH_FX_D2_MSB_ADDR{1, 41};
212 static constexpr RegAddr RCH_FX_D2_LSB_ADDR{1, 42};
213 static constexpr RegAddr RCH_FX_D4_MSB_ADDR{1, 43};
214 static constexpr RegAddr RCH_FX_D4_LSB_ADDR{1, 44};
215 static constexpr RegAddr RCH_FX_D5_MSB_ADDR{1, 45};
216 static constexpr RegAddr RCH_FX_D5_LSB_ADDR{1, 46};
217 static constexpr RegAddr RCH_DEEMP_N0_MSB_ADDR{1, 47};
218 static constexpr RegAddr RCH_DEEMP_N0_LSB_ADDR{1, 48};
219 static constexpr RegAddr RCH_DEEMP_N1_MSB_ADDR{1, 49};
220 static constexpr RegAddr RCH_DEEMP_N1_LSB_ADDR{1, 50};
221 static constexpr RegAddr RCH_DEEMP_D0_MSB_ADDR{1, 51};
222 static constexpr RegAddr RCH_DEEMP_D0_LSB_ADDR{1, 52};
223 static constexpr RegAddr D3D_ATTEN_MSB{1, 53};
224 static constexpr RegAddr D3D_ATTEN_LSB{1, 54};
225 // 55-64 are reserved
226 static constexpr RegAddr LCH_ADC_HPF_N0_MSB_ADDR{1, 65};
227 static constexpr RegAddr LCH_ADC_HPF_N0_LSB_ADDR{1, 66};
228 static constexpr RegAddr LCH_ADC_HPF_N1_MSB_ADDR{1, 67};
229 static constexpr RegAddr LCH_ADC_HPF_N1_LSB_ADDR{1, 68};
230 static constexpr RegAddr LCH_ADC_HPF_D1_MSB_ADDR{1, 69};
231 static constexpr RegAddr LCH_ADC_HPF_D1_LSB_ADDR{1, 70};
232 static constexpr RegAddr RCH_ADC_HPF_N0_MSB_ADDR{1, 71};
233 static constexpr RegAddr RCH_ADC_HPF_N0_LSB_ADDR{1, 72};
234 static constexpr RegAddr RCH_ADC_HPF_N1_MSB_ADDR{1, 73};
235 static constexpr RegAddr RCH_ADC_HPF_N1_LSB_ADDR{1, 74};
236 static constexpr RegAddr RCH_ADC_HPF_D1_MSB_ADDR{1, 75};
237 static constexpr RegAddr RCH_ADC_HPF_D1_LSB_ADDR{1, 76};
238 // 77-127 are reserved
239
240 // WHEW!
241
242 // ---- Bit definitions ----
243 // Codec sample rate select register (NCODEC = NADC = NDAC on this device)
244 static constexpr uint8_t NCODEC_1 = 0x0;
245 static constexpr uint8_t NCODEC_1_5 = 0x1;
246 static constexpr uint8_t NCODEC_2 = 0x2;
247 static constexpr uint8_t NCODEC_2_5 = 0x3;
248 static constexpr uint8_t NCODEC_3 = 0x4;
249 static constexpr uint8_t NCODEC_3_5 = 0x5;
250 static constexpr uint8_t NCODEC_4 = 0x6;
251 static constexpr uint8_t NCODEC_4_5 = 0x7;
252 static constexpr uint8_t NCODEC_5 = 0x8;
253 static constexpr uint8_t NCODEC_5_5 = 0x9;
254 static constexpr uint8_t NCODEC_6 = 0xA;
255
256 // PLL registers need some mapping.
258 static uint8_t PLL_Q_CODE(uint8_t q) {
259 if (q == 16) return 0;
260 if (q == 17) return 1;
261 return q & 0x0F;
262 }
264 static uint8_t PLL_P_CODE(uint8_t p) { return (p == 8) ? 0 : p & 0x07; }
265
267 static uint8_t PLL_R_CODE(uint8_t r) { return (r==16) ? 0 : r & 0x0F; }
268
269 // Codec datapath setup register (7)
270 static constexpr uint8_t FSREF_44100 = makeBit(7, 1);
271 static constexpr uint8_t FSREF_48000 = 0;
272 static constexpr uint8_t DUAL_RATE_MODE = (makeBit(6, 1)) | (makeBit(5, 1));
273 static constexpr uint8_t LDAC2LCH = makeBit(3, 1);
274 static constexpr uint8_t RDAC2RCH = makeBit(1, 1);
275
276 // Audio serial data interface control register B (9)
277 static constexpr uint8_t AIC3104_IFTYPE_I2S = makeBits(7, 6, 0b00);
278 static constexpr uint8_t AIC3104_IFTYPE_DSP = makeBits(7, 6, 0b01);
279 static constexpr uint8_t AIC3104_IFTYPE_RJF = makeBits(7, 6, 0b10);
280 static constexpr uint8_t AIC3104_IFTYPE_LJF = makeBits(7, 6, 0b11);
281
282 static constexpr uint8_t ASD_WLEN_16 = makeBits(5, 4, 0b00);
283 static constexpr uint8_t ASD_WLEN_20 = makeBits(5, 4, 0b01);
284 static constexpr uint8_t ASD_WLEN_24 = makeBits(5, 4, 0b10);
285 static constexpr uint8_t ASD_WLEN_32 = makeBits(5, 4, 0b11);
286
287 // Generic route/mute/power bits, reused across many of the mixer /
288 // output-driver registers on this device (matches the pattern used by
289 // the vendor Linux driver for this codec family)
290 static constexpr uint8_t ROUTE_ON = makeBit(7, 1);
291 static constexpr uint8_t DAC_UNMUTE = makeBit(7, 1);
292 static constexpr uint8_t HP_UNMUTE = makeBit(3, 1);
293 static constexpr uint8_t OUT_PWR_ON = makeBit(0, 1);
294 static constexpr uint8_t ADC_PWR_ON = makeBit(2, 1);
295
296 static constexpr uint8_t LDAC_PWR_ON = makeBit(7, 1);
297 static constexpr uint8_t RDAC_PWR_ON = makeBit(6, 1);
298
301 static uint8_t ROUTE_VOL(uint8_t atten) {
302 return (uint8_t)(ROUTE_ON | makeBits(6, 0, atten));
303 }
304
306 static constexpr int CODEC_OUTPUT_VOLUME_MAX = 0;
307 static constexpr int CODEC_OUTPUT_VOLUME_MIN = -127;
308
312 struct PllDivs {
313 uint32_t clk;
314 uint32_t fsref;
315 uint8_t p;
316 uint8_t r;
317 uint8_t j;
318 uint16_t d;
319 };
320
324 struct RateDivs {
325 uint32_t rate;
326 uint32_t fsref;
327 uint8_t ncodec_code;
329 };
330
332
334 bool begin(uint32_t sample_rate, uint8_t bits, codec_mode_t mode,
335 i2s_format_t fmt, bool is_master, uint8_t channels) override {
336 (void)mode;
337 (void)fmt;
338 return begin(sample_rate, bits, channels, is_master);
339 }
340
341 bool begin(uint32_t sample_rate = 44100, uint8_t word_size = 16, uint8_t channels = 2, bool is_master = false, uint32_t mclk = 0) {
342 AD_LOGI("TLV320AIC3104 begin()");
343 AD_LOGD("rate:%d size:%d channels:%d master:%s mclk:%d", sample_rate, word_size, channels, is_master?"true":"false", mclk);
344
345 bool rc = true;
346 rc &= softReset();
347 delayMs(10);
348 rc &= configureClocks(sample_rate, word_size, channels, mclk, is_master);
349 rc &= configureDai(word_size);
350 rc &= configureInput();
351 rc &= configureOutput();
352 return rc;
353 }
354
356 bool softReset() {
357 AD_LOGI("TLV320AIC3104 softReset()");
359 }
360
362 bool configureDai(uint8_t word_size) {
363 AD_LOGI("TLV320AIC3104 configureDai()");
364 bool rc = writePagedReg(ASD_INTF_CTRLA_ADDR, makeBit(5, 1)); // BCLK, WCLK are inputs, DOUT is Hi-Z
365
366 uint8_t b = AIC3104_IFTYPE_I2S; // The library doesn't support any other interface types yet.
367 switch (word_size) {
368 case 16: b |= ASD_WLEN_16; break;
369 case 20: b |= ASD_WLEN_20; break;
370 case 24: b |= ASD_WLEN_24; break;
371 case 32: b |= ASD_WLEN_32; break;
372 default: return false;
373 }
374 b |= makeBits(2, 0, 0b111); // Resync DAC, ADC, with soft-mute
376 rc &= writePagedReg(ASD_INTF_CTRLC_ADDR, 0x00); // No offset.
377 return rc;
378 }
379
380
386 bool configureClocks(uint32_t sample_rate, uint8_t word_size, uint8_t channels, uint32_t mclk, bool is_master) {
387 AD_LOGI("TLV320AIC3104 configureClocks() rate:%d mclk:%d is_master:%s", sample_rate, mclk, is_master?"true":"false");
388
389 // Are we using MCLK or BCLK to derive our local clock?
390 bool use_bclk = (mclk == 0);
391 uint32_t clock = use_bclk ? (sample_rate * word_size * channels) : mclk;
392 AD_LOGI("MCLK: %d Using %s at %dHz", mclk, use_bclk?"BCLK":"MCLK", clock);
393
394 // Find the appropriate PLL and other register parameters for our clockrate.
395 size_t rate_count = 0;
396 const RateDivs* rate_table = rateDivTable(rate_count);
397 const RateDivs* rate_entry = nullptr;
398 for (size_t i = 0; i < rate_count; i++) {
399 if (rate_table[i].rate == sample_rate) {
400 rate_entry = &rate_table[i];
401 break;
402 }
403 }
404 if (rate_entry == nullptr) {
405 AD_LOGE("TLV320AIC3104::configureClocks() No rate_entry found");
406 return false;
407 }
408 AD_LOGI("Rate Table entry found: fSref:%d NCODEC:%d", rate_entry->fsref, rate_entry->ncodec_code);
409
410 size_t pll_count = 0;
411 const PllDivs* pll_table = pllDivTable(pll_count);
412 const PllDivs* pll_entry = nullptr;
413 for (size_t i = 0; i < pll_count; i++) {
414 if (pll_table[i].clk == clock && pll_table[i].fsref == rate_entry->fsref) {
415 pll_entry = &pll_table[i];
416 break;
417 }
418 }
419 if (pll_entry == nullptr) {
420 AD_LOGE("TLV320AIC3104::configureClocks() No pll_entry found. clock:%d fSref:%d", clock, rate_entry->fsref);
421 return false;
422 }
423 AD_LOGI("PLL Div entry found: D:%d J:%d P:%d R:%d", pll_entry->d, pll_entry->j, pll_entry->p, pll_entry->r);
424
425 bool rc = true;
426
427 // D7 is PLL enable. D6-3 is Q. D2-0 is P
428 uint8_t r3 = makeBit(7, 0b1) | makeBits(6, 3, (PLL_Q_CODE(2))) | makeBits(2, 0, PLL_P_CODE(pll_entry->p));
429 uint8_t r8 = makeBits(7, 6, is_master?0b11:0b00); // BCLK and LRCLK set to input (slave) or output (master)
430 // D0 is CODEC_CLKIN: 0 is PLL, 1 is CLKDIV
431 uint8_t r101 = makeBit(0, 0b0); // PLLDIV_OUT
432 uint8_t r102 = makeBits(7, 6, (use_bclk)?0b10:0b00) // CLKDIV_IN src. 0=MCLK, 2=BCLK.
433 | makeBits(5, 4, (use_bclk)?0b10:0b00) // PLLCLK_IN src. 0=MCLK, 2=BCLK.
434 | makeBits(3, 0, 0b0010); // reserved bits, required to be this value.
435 rc &= writePagedReg(PLL_PROGB_ADDR, makeBits(7, 2, pll_entry->j));
436 rc &= writePagedReg(PLL_PROGC_ADDR, makeBits(7, 0, pll_entry->d >> 6));
437 rc &= writePagedReg(PLL_PROGD_ADDR, makeBits(7, 2, pll_entry->d));
438 rc &= writePagedReg(OVRF_STATUS_PLLR_ADDR, makeBits(3, 0, PLL_R_CODE(pll_entry->r)));
440 rc &= writePagedReg(CLK_ADDR, r101);
441 rc &= writePagedReg(CLK_GEN_ADDR, r102);
442 rc &= writePagedReg(PLL_PROGA_ADDR, r3);
443 rc &= writePagedReg(ASD_INTF_CTRLA_ADDR, makeBit(5, 1)); // Hi-z on idle
444
445 // fS(ref) selection + shared NCODEC divider + dual-rate mode
446 uint8_t datapath = (rate_entry->fsref == 44100) ? FSREF_44100 : FSREF_48000;
447 datapath |= LDAC2LCH | RDAC2RCH;
448 if (rate_entry->dual_rate) datapath |= DUAL_RATE_MODE;
449 rc &= writePagedReg(CODEC_DATAPATH_ADDR, datapath);
451 makeBits(7, 4, rate_entry->ncodec_code) | // ADC Sample Rate Select
452 makeBits(3, 0, rate_entry->ncodec_code) // DAC Sample Rate Select
453 );
454 return rc;
455
456 }
457
459 bool startOutput() {
461 (uint8_t)(LDAC_PWR_ON | RDAC_PWR_ON));
462 }
463
465 bool stopOutput() {
466 return updatePagedReg(DAC_PWR_ADDR, (uint8_t)(LDAC_PWR_ON | RDAC_PWR_ON), 0);
467 }
468
477 AD_LOGI("TLV320AIC3104 configureOutput()");
478 bool rc = true;
481
482 // DAC_QUIESCENT_CURRENT_ADDR
483 //rc &= writePagedReg(DAC_QUIESCENT_CURRENT_ADDR, 0x40); // 50% increase in DAC current.
484
485 // Setup DACs, and HP outputs
486 rc &= writePagedReg(HEADSET_BTN_PRESS_DETECTB_ADDR, makeBit(7, 1)); // Sets HP for AC coupled.
487 rc &= writePagedReg(DAC_PWR_ADDR, makeBit(7, 1) | makeBit(6, 1) | makeBits(5, 4, 0b10)); // Both DACs on, HPLCOM independent
488 rc &= writePagedReg(HPRCOM_CFG_ADDR, makeBits(5, 3, 0b010) | makeBits(2, 1, 0b10)); //HPRCOM independent, Short circuit protection enabled, current limit.
489 //rc &= writePagedReg(DAC_SW_CTRL_ADDR, 0x00); // Defaults to: LDAC to DAC_L1, RDAC to DAC_R1, independent volumes
490 rc &= writePagedReg(HPCOM_CMVOLT_ADDR, makeBits(7, 6, 0b11)); // 1.8v common mode, soft step
491 rc &= writePagedReg(POP_REDUCTION_ADDR, makeBits(7, 4, 0b1001) | makeBits(3, 2, 0b01) | makeBit(1, 1)); // 800ms power-on time, 1ms ramp-up step, use band-gap for common mode reference
492
493 // Mute while making other changes
495 rc &= setDACMute(false);
496
497 // route DAC_L1/DAC_R1 to the headhpones output mixer at 0dB
500
501 // route DAC_L1/DAC_R1 to the fully differential line output mixer at 0dB
504
505 // power up/down the output drivers to match the requested devices
510
511 // Unmute selected outputs
516
517 return rc;
518 }
519
533 AD_LOGI("TLV320AIC3104 configureInput()");
534 bool rc = true;
535
536 // Default to powered up, but muted
537 uint8_t left1_reg = makeBits(6, 3, 0b1111) | makeBit(2, 1); // 19
538 uint8_t right1_reg = makeBits(6, 3, 0b1111) | makeBit(2, 1); // 22
539 uint8_t left2_reg = 0xFF; // 17
540 uint8_t right2_reg = 0xFF; // 18
541 uint8_t pga_gain_reg = 0; // 15, and 16
542 switch (input_device) {
543 case ADC_INPUT_DIFFERENCE: // Balanced inputs on Line1/Mic1, with Mic gain and bias.
544 left1_reg =
545 makeBit(7, 1) | // Fully differential input
546 makeBits(6, 3, 0) | // Input pad: -0dB
547 makeBit(2, 1) | // ADC powered up
548 makeBits(1, 0, 0); // ADC PGA soft stepping, 1/sample
549 right1_reg = left1_reg;
550 pga_gain_reg =
551 makeBit(7, 0) | // Not muted
552 makeBits(6, 0, 0b0110000); // 24dB PGA Gain about right for a microphone
553 break;
554 case ADC_INPUT_LINE1: // Single ended inputs on Line1/Mic1, Line level.
555 left1_reg =
556 makeBit(7, 0) | // Single ended input
557 makeBits(6, 3, 0) | // Input pad: -0dB
558 makeBit(2, 1) | // ADC powered up
559 makeBits(1, 0, 0); // ADC PGA soft stepping, 1/sample
560 right1_reg = left1_reg;
561 pga_gain_reg =
562 makeBit(7, 0) | // Not muted
563 makeBits(6, 0, 0b0000000); // 0dB PGA Gain for line level input
564 break;
565 case ADC_INPUT_LINE2: // ADC_INPUT_LINE2: Single ended inputs on Line2/Mic2, Line level
566 left2_reg =
567 makeBits(7, 4, 0b0000) | // Mic2L/Line2L ---> Left ADC
568 makeBits(3, 0, 0b1111); // Mic2R/Line2R -X-> Left ADC
569 right2_reg =
570 makeBits(7, 4, 0b1111) | // Mic2L/Line2L -X-> Right ADC
571 makeBits(3, 0, 0b0000); // Mic2R/Line2R ---> Right ADC
572 pga_gain_reg =
573 makeBit(7, 0) | // Not muted
574 makeBits(6, 0, 0b0000000); // 0dB PGA Gain for line level input
575 break;
576 case ADC_INPUT_LINE3: // ADC_INPUT_LINE3: Single ended inputs on Line2/Mic2, Mic gain and bias.
577 left2_reg =
578 makeBits(7, 4, 0b0000) | // Mic2L/Line2L ---> Left ADC
579 makeBits(3, 0, 0b1111); // Mic2R/Line2R -X-> Left ADC
580 right2_reg =
581 makeBits(7, 4, 0b1111) | // Mic2L/Line2L -X-> Right ADC
582 makeBits(3, 0, 0b0000); // Mic2R/Line2R ---> Right ADC
583 pga_gain_reg =
584 makeBit(7, 0) | // Not muted
585 makeBits(6, 0, 0b0110000); // 24dB PGA Gain about right for a microphone
586 break;
587 case ADC_INPUT_ALL: // Singled ended line inputs on Line1, Single ended mono Mic input on Mic2, Line2 off.
588 default:
589 left1_reg =
590 makeBit(7, 0) | // Single ended input
591 makeBits(6, 3, 0b1000) | // Input pad: -12dB to equalize Line Input with Mic gain, a little anyway.
592 makeBit(2, 1) | // ADC powered up
593 makeBits(1, 0, 0); // ADC PGA soft stepping, 1/sample
594 right1_reg = left1_reg;
595 left2_reg =
596 makeBits(7, 4, 0b0000) | // Mic2L/Line2L ---> Left ADC
597 makeBits(3, 0, 0b0000); // Mic2R/Line2R ---> Left ADC
598 right2_reg =
599 makeBits(7, 4, 0b1111) | // Mic2L/Line2L -X-> Right ADC
600 makeBits(3, 0, 0b1111); // Mic2R/Line2R -X-> Right ADC
601 pga_gain_reg =
602 makeBit(7, 0) | // Not muted
603 makeBits(6, 0, 0b0110000); // 24dB PGA Gain about right for a microphone
604 break;
605 }
606 rc &= writePagedReg(LINE1L_LADC_CTRL_ADDR, left1_reg);
607 rc &= writePagedReg(LINE1R_RADC_CTRL_ADDR, right1_reg);
608 rc &= writePagedReg(MIC2_LADC_CTRL_ADDR, left2_reg);
609 rc &= writePagedReg(MIC2_RADC_CTRL_ADDR, right2_reg);
610
611 rc &= writePagedReg(MICBIAS_CTRL_ADDR, makeBits(7, 6, 0b10)); // Bias 2.5v
612
613 rc &= writePagedReg(LADC_VOL_ADDR, pga_gain_reg);
614 rc &= writePagedReg(RADC_VOL_ADDR, pga_gain_reg);
615 return rc;
616 }
617
626 if (vol > CODEC_OUTPUT_VOLUME_MAX || vol < CODEC_OUTPUT_VOLUME_MIN) return false;
627 uint8_t atten = (uint8_t)(-vol);
628
629 switch (channel) {
638 case AIC3104Channel::All: {
639 bool rc = true;
644 return rc;
645 }
646 default:
647 return false;
648 }
649 }
650
651 bool setDACMute(bool mute) {
652 // makeBit(7, 1) is muted, makeBit(7, 0) is unmuted
653 uint8_t dac_val = mute ? DAC_UNMUTE : 0;
654 bool rc = true;
655 rc &= updatePagedReg(LDAC_VOL_ADDR, DAC_UNMUTE, dac_val);
656 rc &= updatePagedReg(RDAC_VOL_ADDR, DAC_UNMUTE, dac_val);
657 return rc;
658 }
659
662 uint8_t hp_val = mute ? 0 : HP_UNMUTE;
663 bool rc = true;
664 switch (channel) {
667 return rc;
670 return rc;
673 return rc;
676 return rc;
677 case AIC3104Channel::All: {
682 return rc;
683 }
684 default:
685 return false;
686 }
687 }
688
691 bool setVolume(int volume) override {
692 volume_percent = volume < 0 ? 0 : (volume > 100 ? 100 : volume);
693 int vol = CODEC_OUTPUT_VOLUME_MIN +
696 }
697
699 bool setMute(bool mute) override { return setOutputMute(mute, AIC3104Channel::All); }
700
703 this->input_device = input_device;
704 this->output_device = output_device;
705 return true;
706 }
707
708 // The *PagedReg() methods are public to allow for more complex
709 // configuration of the chip. It's capable of a lot that is not implemented
710 // generally by this driver.
711
713 bool writePagedReg(RegAddr reg, uint8_t value) {
714 if (!selectPage(reg.page)) return false;
715 return writeReg(reg.reg, value);
716 }
717
719 bool readPagedReg(RegAddr reg, uint8_t& value) {
720 if (!selectPage(reg.page)) return false;
721 // https://github.com/palmerr23/tlv320AIC3104/blob/2d53fc2c95a07494dad87241c47c2086245e0c8b/src/tlv320aic3104_comms.h#L91
722 return readReg(reg.reg, value, false); // stopBit = false, or TLV will enter auto-increment mode and return value of reg+1
723 // Requires mods to:
724 // * ZephyrDriverCommon.h readReg()
725 // * API_I2C.h i2c_bus_read_bytes()
726 // Both need to take a bool for an optional stopBit, and pass it to p_wire->endTransmission(stopBit)
727 }
728
730 bool updatePagedReg(RegAddr reg, uint8_t mask, uint8_t value) {
731 uint8_t old = 0;
732 if (!readPagedReg(reg, old)) return false;
733 uint8_t updated = (old & ~mask) | (value & mask);
734 if (updated == old) return true;
735 return writePagedReg(reg, updated);
736 }
737
738protected:
739 uint8_t current_page = 0xFF;
740
742 // used by configureOutput() and configureInputs()
745
747 bool selectPage(uint8_t page) {
748 if (current_page == page) return true;
749 uint8_t reg = PAGE_CONTROL_ADDR;
750 if (!writeReg(reg, page)) return false;
751 // pg47, 10.5.2. Recommended to read the page register back after writing.
752 uint8_t new_page = 0xFF;
753 // Ignoring errors. I don't want to succeed in write, but not update current_page because
754 // of a read error. new_page will EITHER be the new page (the read) actually succeeded,
755 // or it'll still be 0xFF which will trigger an attempt to write again next time.
756 readReg(reg, new_page);
757 current_page = new_page;
758 return true;
759 }
760
761 static constexpr uint8_t PAGE_CONTROL_ADDR = 0;
762
765 static const PllDivs* pllDivTable(size_t& count) {
766 static const PllDivs table[] = {
767 /* clk fsref p r j d */
768 {352800, 44100, 1, 16, 16, 0}, // BCLK 11025x16x2, 256
769 {705600, 44100, 1, 16, 8, 0}, // BCLK 22050x16x2, 128
770 {1411200, 44100, 1, 16, 4, 0}, // BCLK 44100x16x2, 64
771 {2822400, 44100, 1, 1, 32, 0},
772 {5644800, 44100, 1, 1, 16, 0},
773 {11289600, 44100, 1, 1, 8, 0}, //44.1*256
774 {12000000, 44100, 1, 1, 7, 5264},
775 {13000000, 44100, 1, 1, 6, 9474},
776 {16000000, 44100, 1, 1, 5, 6448},
777 {19200000, 44100, 1, 1, 4, 7040},
778 {19680000, 44100, 1, 1, 4, 5893},
779 {48000000, 44100, 4, 1, 7, 5264},
780
781 {256000, 48000, 1, 16, 24, 0}, // BCLK 8000x16x2, 384
782 {512000, 48000, 1, 16, 12, 0}, // BCLK 16000x16x2, 192
783 {768000, 48000, 1, 16, 8, 0}, // BCLK 24000x16x2, 128
784 {1024000, 48000, 1, 16, 6, 0}, // BCLK 32000x16x2, 96
785 {1536000, 48000, 1, 16, 4, 0}, // BCLK 48000x16x2, 64
786 {2048000, 48000, 1, 1, 48, 0},
787 {3072000, 48000, 1, 1, 32, 0},
788 {4096000, 48000, 1, 1, 24, 0},
789 {6144000, 48000, 1, 1, 16, 0},
790 {8192000, 48000, 1, 1, 12, 0},
791 {12000000, 48000, 1, 1, 8, 1920},
792 {12288000, 48000, 1, 1, 6, 0}, //48*256
793 {13000000, 48000, 1, 1, 7, 5618},
794 {16000000, 48000, 1, 1, 6, 1440},
795 {19200000, 48000, 1, 1, 5, 1200},
796 {19680000, 48000, 1, 1, 4, 9951},
797 {48000000, 48000, 4, 1, 8, 1920},
798 };
799 count = sizeof(table) / sizeof(table[0]);
800 return table;
801 }
802
805 static const RateDivs* rateDivTable(size_t& count) {
806 static const RateDivs table[] = {
807 //rate fsref ncodec_code dual_rate
808 {8000, 48000, NCODEC_6, false},
809 {11025, 44100, NCODEC_4, false},
810 {16000, 48000, NCODEC_3, false},
811 {22050, 44100, NCODEC_2, false},
812 {24000, 48000, NCODEC_2, false},
813 {32000, 48000, NCODEC_1_5, false},
814 {44100, 44100, NCODEC_1, false},
815 {48000, 48000, NCODEC_1, false},
816 {88200, 44100, NCODEC_1, true},
817 {96000, 48000, NCODEC_1, true},
818 };
819 count = sizeof(table) / sizeof(table[0]);
820 return table;
821 }
822
823#ifdef TLV320AIC3104_DEBUG
824public:
825 // Debugging stuff
826
827 // Start and end are inclusive. Doesn't matter whether you count from
828 // the left or the right, it will do the right thing.
829 uint32_t extractBits(uint32_t val, uint8_t _start, uint8_t _end) {
830 uint8_t start = (_start > _end) ? _start : _end; // max()
831 uint8_t end = (_start < _end) ? _start : _end; // min()
832 return ((val) & ~(0xFFFFFFFF << start+1)) >> end;
833 }
834 uint32_t extractBit(uint32_t val, uint8_t _start) {
835 return extractBits(val, _start, _start);
836 }
837
838 void dumpRegisters() {
839 AD_LOGI("Dumping Registers...");
840 AD_LOGI("[");
841 uint8_t val = 0;
842 bool ret;
843 RegAddr regaddr;
844 regaddr.page = 0;
845 for (uint8_t reg = 2; reg <= 109; reg++) {
846 regaddr.reg = reg;
847 ret = readPagedReg(regaddr, val);
848 AD_LOGI(" { \"reg\": %d, \"val\": %d }%s", reg, val, reg==109?"":",");
849 }
850 AD_LOGI("]");
851 }
852
853 void printPLLConfig() {
854 uint8_t pll_a, pll_b, pll_c, pll_d, pll_r, datapath, rate, clk_sel;
855
863 readPagedReg(CLK_GEN_ADDR, clk_sel);
864
865 // test cases
866 /*
867 Serial.printf("%d == 3\r\n", extractBits(0xFF, 7, 6));
868 Serial.printf("%d == 3\r\n", extractBits(0xFF, 1, 0));
869 Serial.printf("%d == 255\r\n", extractBits(0xFF, 7, 0));
870 Serial.printf("%d == 0\r\n", extractBits(0xFC, 1, 0));
871 Serial.printf("%d == 0\r\n", extractBits(0xF3, 3, 2));
872 Serial.printf("%d == 1\r\n", extractBit(0x08, 3));
873 Serial.printf("%d == 0\r\n", extractBit(0x08, 2));
874 Serial.printf("%d == 0\r\n", extractBit(0x08, 4));
875 */
876
877 AD_LOGI("printPLLConfig():");
878 AD_LOGI("Raw registers:");
879 AD_LOGI("PLL A:%02X B:%02X C:%02X D:%02X R:%02X\r\n",
880 pll_a, pll_b, pll_c, pll_d, pll_r);
881 AD_LOGI("CODEC Datapath:%02X SampleRate:%02X Clock Select:%02X\r\n",
882 datapath, rate, clk_sel);
883
884 // Decode
885 uint8_t P = extractBits(pll_a, 2, 0);
886 if (P < 1) P+= 8;
887 uint8_t Q = extractBits(pll_a, 6, 3);
888 if (Q < 2) Q += 16;
889 uint8_t J = extractBits(pll_b, 7, 2);
890 uint16_t D = ((uint16_t)pll_c << 6) + extractBits(pll_d, 7, 2);
891 uint8_t R = extractBits(pll_r, 3, 0);
892 const char *pll_enabled = extractBit(pll_a, 7) ? "en" : "dis";
893 const char *fSref = extractBit(datapath, 7) ? "44.1kHz" : "48kHz";
894 const char *ADC_DR = extractBit(datapath, 6) ? "en" : "dis";
895 const char *DAC_DR = extractBit(datapath, 5) ? "en" : "dis";
896 uint8_t LDAC_DP = extractBits(datapath, 4, 3);
897 uint8_t RDAC_DP = extractBits(datapath, 2, 1);
898 uint8_t NADC = extractBits(rate, 7, 4);
899 uint8_t NDAC = extractBits(rate, 3, 0);
900
901 AD_LOGI("P:%d Q:%d J:%d D:%d R:%d\r\n", P, Q, J, D, R);
902 AD_LOGI("PLL:%sabled fS(ref):%s ADC_DR:%s DAC_DR:%s\r\n", pll_enabled, fSref, ADC_DR, DAC_DR);
903 AD_LOGI("LDAC_DP:%d RDAC_DP:%d NADC:%d NDAC:%d\r\n", LDAC_DP, RDAC_DP, NADC, NDAC);
904 }
905#endif // TLV320AIC3104_DEBUG
906};
907
908} // namespace audio_driver
#define AD_LOGD(...)
Definition Logger.h:12
#define AD_LOGI(...)
Definition Logger.h:13
#define AD_LOGE(...)
Definition Logger.h:15
Header only C++ driver for the TLV320AIC3104 audio codec.
Definition TLV320AIC3104.h:55
static constexpr RegAddr LINE1L_RADC_CTRL_ADDR
Definition TLV320AIC3104.h:89
static constexpr RegAddr RAGC_GAIN_ADDR
Definition TLV320AIC3104.h:98
static constexpr uint8_t DUAL_RATE_MODE
Definition TLV320AIC3104.h:272
static constexpr RegAddr PGAR_HPROUT_VOL_ADDR
Definition TLV320AIC3104.h:128
static constexpr RegAddr ASD_INTF_CTRLC_ADDR
Definition TLV320AIC3104.h:75
static constexpr uint8_t NCODEC_6
Definition TLV320AIC3104.h:254
bool setDevices(input_device_t input_device, output_device_t output_device) override
Stores the output device selection for use by configureOutput()
Definition TLV320AIC3104.h:702
static constexpr RegAddr RCH_ADC_HPF_N1_MSB_ADDR
Definition TLV320AIC3104.h:234
static constexpr RegAddr ADC_DIG_FILT_CTRL_ADDR
Definition TLV320AIC3104.h:163
static constexpr uint8_t NCODEC_5
Definition TLV320AIC3104.h:252
static constexpr uint8_t NCODEC_4_5
Definition TLV320AIC3104.h:251
static constexpr RegAddr LDAC_VOL_ADDR
Definition TLV320AIC3104.h:108
static constexpr RegAddr D3D_ATTEN_LSB
Definition TLV320AIC3104.h:224
static constexpr RegAddr POWER_STATUS_ADDR
Definition TLV320AIC3104.h:152
static constexpr RegAddr PLL_PROGA_ADDR
Definition TLV320AIC3104.h:68
static constexpr RegAddr RAGC_CTRLA_ADDR
Definition TLV320AIC3104.h:94
static constexpr RegAddr RT_IRQ_FLAGS_ADDR
Definition TLV320AIC3104.h:155
static constexpr RegAddr PGAL_HPROUT_VOL_ADDR
Definition TLV320AIC3104.h:125
static constexpr RegAddr RCH_DEEMP_N0_MSB_ADDR
Definition TLV320AIC3104.h:217
static constexpr uint8_t NCODEC_3
Definition TLV320AIC3104.h:248
static constexpr uint8_t ASD_WLEN_32
Definition TLV320AIC3104.h:285
static constexpr RegAddr RCH_FX_N5_LSB_ADDR
Definition TLV320AIC3104.h:208
static constexpr RegAddr PGAL_RLOPM_VOL_ADDR
Definition TLV320AIC3104.h:146
static constexpr RegAddr RCH_FX_N0_LSB_ADDR
Definition TLV320AIC3104.h:198
static constexpr RegAddr DACR1_LLOPM_VOL_ADDR
Definition TLV320AIC3104.h:143
static constexpr RegAddr RCH_DEEMP_N1_MSB_ADDR
Definition TLV320AIC3104.h:219
static constexpr RegAddr PGAL_HPRCOM_VOL_ADDR
Definition TLV320AIC3104.h:132
static constexpr uint8_t NCODEC_1
Definition TLV320AIC3104.h:244
static constexpr RegAddr RAGC_CTRLC_ADDR
Definition TLV320AIC3104.h:96
static constexpr RegAddr LCH_FX_D4_MSB_ADDR
Definition TLV320AIC3104.h:187
static constexpr RegAddr RCH_FX_D5_LSB_ADDR
Definition TLV320AIC3104.h:216
bool softReset()
Soft reset of the codec.
Definition TLV320AIC3104.h:356
static constexpr uint8_t RDAC_PWR_ON
Definition TLV320AIC3104.h:297
static constexpr RegAddr LCH_FX_D5_LSB_ADDR
Definition TLV320AIC3104.h:190
static constexpr RegAddr LCH_FX_N2_LSB_ADDR
Definition TLV320AIC3104.h:176
static constexpr RegAddr PGAL_HPLOUT_VOL_ADDR
Definition TLV320AIC3104.h:111
static constexpr RegAddr PGAR_HPRCOM_VOL_ADDR
Definition TLV320AIC3104.h:135
static constexpr RegAddr I2C_BUS_STATUS_ADDR
Definition TLV320AIC3104.h:164
static constexpr RegAddr PGAR_RLOPM_VOL_ADDR
Definition TLV320AIC3104.h:149
static constexpr RegAddr DACR1_HPLCOM_VOL_ADDR
Definition TLV320AIC3104.h:122
static constexpr RegAddr LAGC_GAIN_ADDR
Definition TLV320AIC3104.h:97
static constexpr RegAddr DACL1_HPROUT_VOL_ADDR
Definition TLV320AIC3104.h:126
static constexpr RegAddr RCH_FX_N4_MSB_ADDR
Definition TLV320AIC3104.h:205
static constexpr RegAddr LAGC_CTRLC_ADDR
Definition TLV320AIC3104.h:93
static constexpr RegAddr LINE1R_LADC_CTRL_ADDR
Definition TLV320AIC3104.h:86
static constexpr RegAddr LAGC_NGATE_DEBOUNCE_ADDR
Definition TLV320AIC3104.h:99
bool setDACMute(bool mute)
Definition TLV320AIC3104.h:651
static constexpr RegAddr LCH_FX_N1_LSB_ADDR
Definition TLV320AIC3104.h:174
static constexpr RegAddr RCH_DEEMP_D0_LSB_ADDR
Definition TLV320AIC3104.h:222
static constexpr RegAddr RCH_FX_D1_MSB_ADDR
Definition TLV320AIC3104.h:209
static constexpr RegAddr SOFT_RESET_ADDR
Definition TLV320AIC3104.h:66
bool configureInput()
Configure the microphone/line input path to the Left/Right ADC PGA at 0dB and power up the ADC channe...
Definition TLV320AIC3104.h:532
bool setMute(bool mute) override
Mutes/unmutes all outputs.
Definition TLV320AIC3104.h:699
static constexpr RegAddr LCH_ADC_HPF_N1_MSB_ADDR
Definition TLV320AIC3104.h:228
static constexpr RegAddr SHORT_DETECT_ADDR
Definition TLV320AIC3104.h:153
bool configureDai(uint8_t word_size)
Configure the digital audio interface (I2S) word size and clock direction.
Definition TLV320AIC3104.h:362
static constexpr RegAddr MIC2_LADC_CTRL_ADDR
Definition TLV320AIC3104.h:82
static constexpr RegAddr LCH_FX_N4_MSB_ADDR
Definition TLV320AIC3104.h:179
static constexpr uint8_t LDAC_PWR_ON
Definition TLV320AIC3104.h:296
static constexpr RegAddr PGAL_LLOPM_VOL_ADDR
Definition TLV320AIC3104.h:139
static constexpr RegAddr LCH_ADC_HPF_N0_MSB_ADDR
Definition TLV320AIC3104.h:226
static constexpr RegAddr RADC_VOL_ADDR
Definition TLV320AIC3104.h:81
static constexpr RegAddr STICKY_IRQ_FLAGS_ADDR
Definition TLV320AIC3104.h:154
static constexpr RegAddr LCH_FX_N2_MSB_ADDR
Definition TLV320AIC3104.h:175
static constexpr RegAddr HPLOUT_CTRL_ADDR
Definition TLV320AIC3104.h:116
static constexpr RegAddr LCH_FX_N0_MSB_ADDR
Definition TLV320AIC3104.h:171
static constexpr RegAddr DACR1_RLOPM_VOL_ADDR
Definition TLV320AIC3104.h:150
static constexpr RegAddr LCH_FX_N1_MSB_ADDR
Definition TLV320AIC3104.h:173
static constexpr RegAddr HPRCOM_CFG_ADDR
Definition TLV320AIC3104.h:103
output_device_t output_device
Output and input device selections set via setDevices(),.
Definition TLV320AIC3104.h:743
static constexpr RegAddr LCH_ADC_HPF_D1_LSB_ADDR
Definition TLV320AIC3104.h:231
static uint8_t PLL_P_CODE(uint8_t p)
PLL P register code: P=8 -> 000, P=1..7 -> value itself.
Definition TLV320AIC3104.h:264
static constexpr RegAddr PLL_PROGD_ADDR
Definition TLV320AIC3104.h:71
static constexpr RegAddr CLK_ADDR
Definition TLV320AIC3104.h:157
static constexpr RegAddr DACL1_RLOPM_VOL_ADDR
Definition TLV320AIC3104.h:147
static constexpr RegAddr LCH_FX_N3_LSB_ADDR
Definition TLV320AIC3104.h:178
static constexpr uint8_t DAC_UNMUTE
Definition TLV320AIC3104.h:291
static constexpr RegAddr RLOPM_CTRL_ADDR
Definition TLV320AIC3104.h:151
bool configureOutput()
Configure the headphone (HPLOUT/HPROUT) and/or fully differential line (LOP/M) output paths,...
Definition TLV320AIC3104.h:476
static constexpr RegAddr DACR1_HPLOUT_VOL_ADDR
Definition TLV320AIC3104.h:115
static constexpr RegAddr D3D_ATTEN_MSB
Definition TLV320AIC3104.h:223
static constexpr uint8_t NCODEC_4
Definition TLV320AIC3104.h:250
static constexpr RegAddr PLL_PROGC_ADDR
Definition TLV320AIC3104.h:70
static constexpr RegAddr LLOPM_CTRL_ADDR
Definition TLV320AIC3104.h:144
static constexpr RegAddr DACL1_HPLCOM_VOL_ADDR
Definition TLV320AIC3104.h:119
static uint8_t PLL_Q_CODE(uint8_t q)
PLL Q register code: Q=16 -> 0000, Q=17 -> 0001, Q=2..15 -> value itself.
Definition TLV320AIC3104.h:258
static constexpr RegAddr PGAR_HPLCOM_VOL_ADDR
Definition TLV320AIC3104.h:121
static constexpr int CODEC_OUTPUT_VOLUME_MIN
Definition TLV320AIC3104.h:307
uint8_t current_page
cached page, invalid initially
Definition TLV320AIC3104.h:739
static constexpr RegAddr RCH_DEEMP_N0_LSB_ADDR
Definition TLV320AIC3104.h:218
static constexpr uint8_t NCODEC_3_5
Definition TLV320AIC3104.h:249
static constexpr int CODEC_OUTPUT_VOLUME_MAX
Output volume range, in 0.5dB steps (-63.5dB .. 0dB)
Definition TLV320AIC3104.h:306
static constexpr RegAddr HPCOM_CMVOLT_ADDR
Definition TLV320AIC3104.h:105
static constexpr RegAddr DACR1_HPRCOM_VOL_ADDR
Definition TLV320AIC3104.h:136
static constexpr RegAddr RCH_FX_N4_LSB_ADDR
Definition TLV320AIC3104.h:206
bool startOutput()
Power up the DAC channels.
Definition TLV320AIC3104.h:459
static constexpr uint8_t ASD_WLEN_16
Definition TLV320AIC3104.h:282
static constexpr RegAddr CLK_GEN_ADDR
Definition TLV320AIC3104.h:158
bool configureClocks(uint32_t sample_rate, uint8_t word_size, uint8_t channels, uint32_t mclk, bool is_master)
Configure the PLL for the given MCLK/fS(ref) combination, then set the shared ADC/DAC NCODEC divider ...
Definition TLV320AIC3104.h:386
static constexpr RegAddr RCH_FX_D4_MSB_ADDR
Definition TLV320AIC3104.h:213
static constexpr uint8_t FSREF_48000
Definition TLV320AIC3104.h:271
static uint8_t ROUTE_VOL(uint8_t atten)
Definition TLV320AIC3104.h:301
static constexpr RegAddr RCH_FX_N0_MSB_ADDR
Definition TLV320AIC3104.h:197
static constexpr RegAddr PGAR_HPLOUT_VOL_ADDR
Definition TLV320AIC3104.h:114
static constexpr RegAddr ANALOG_BYPASS_CTRL_ADDR
Definition TLV320AIC3104.h:165
static constexpr RegAddr DACL1_LLOPM_VOL_ADDR
Definition TLV320AIC3104.h:140
static constexpr RegAddr RCH_FX_D5_MSB_ADDR
Definition TLV320AIC3104.h:215
static constexpr RegAddr LCH_DEEMP_N0_MSB_ADDR
Definition TLV320AIC3104.h:191
static constexpr RegAddr DIGI_FILT_CTRL_ADDR
Definition TLV320AIC3104.h:77
static constexpr RegAddr LCH_DEEMP_D0_MSB_ADDR
Definition TLV320AIC3104.h:195
bool updatePagedReg(RegAddr reg, uint8_t mask, uint8_t value)
Read-Modify-Write of a register on the given page.
Definition TLV320AIC3104.h:730
static constexpr RegAddr LCH_FX_N5_MSB_ADDR
Definition TLV320AIC3104.h:181
bool begin(uint32_t sample_rate=44100, uint8_t word_size=16, uint8_t channels=2, bool is_master=false, uint32_t mclk=0)
Definition TLV320AIC3104.h:341
static constexpr RegAddr PGAR_LLOPM_VOL_ADDR
Definition TLV320AIC3104.h:142
static constexpr RegAddr RCH_ADC_HPF_D1_LSB_ADDR
Definition TLV320AIC3104.h:237
static constexpr RegAddr RCH_DEEMP_D0_MSB_ADDR
Definition TLV320AIC3104.h:221
static constexpr RegAddr DAC_PWR_ADDR
Definition TLV320AIC3104.h:102
static constexpr uint8_t ASD_WLEN_20
Definition TLV320AIC3104.h:283
static constexpr RegAddr RCH_FX_N1_LSB_ADDR
Definition TLV320AIC3104.h:200
static constexpr RegAddr LADC_VOL_ADDR
Definition TLV320AIC3104.h:80
bool readPagedReg(RegAddr reg, uint8_t &value)
Reads a register on the given page.
Definition TLV320AIC3104.h:719
static constexpr RegAddr HPLCOM_CTRL_ADDR
Definition TLV320AIC3104.h:123
static constexpr uint8_t FSREF_44100
Definition TLV320AIC3104.h:270
static constexpr RegAddr HEADSET_BTN_PRESS_DETECTA_ADDR
Definition TLV320AIC3104.h:78
static constexpr uint8_t LDAC2LCH
Definition TLV320AIC3104.h:273
static constexpr uint8_t RDAC2RCH
Definition TLV320AIC3104.h:274
static constexpr RegAddr LINE1L_LADC_CTRL_ADDR
Definition TLV320AIC3104.h:84
bool setOutputVolume(int vol, AIC3104Channel channel=AIC3104Channel::All)
Set the output (headphone / line out) volume.
Definition TLV320AIC3104.h:625
static constexpr uint8_t ROUTE_ON
Definition TLV320AIC3104.h:290
static constexpr uint8_t AIC3104_IFTYPE_DSP
Definition TLV320AIC3104.h:278
static constexpr uint8_t AIC3104_IFTYPE_I2S
Definition TLV320AIC3104.h:277
static const RateDivs * rateDivTable(size_t &count)
Definition TLV320AIC3104.h:805
static constexpr RegAddr RAGC_PROG_DECAY_ADDR
Definition TLV320AIC3104.h:162
bool setOutputMute(bool mute, AIC3104Channel channel=AIC3104Channel::All)
Mute / unmute the headphone and/or line output driver(s)
Definition TLV320AIC3104.h:661
bool begin(uint32_t sample_rate, uint8_t bits, codec_mode_t mode, i2s_format_t fmt, bool is_master, uint8_t channels) override
Initializes the codec for I2S with the given sample rate and bits per sample.
Definition TLV320AIC3104.h:334
static constexpr RegAddr RCH_FX_D2_MSB_ADDR
Definition TLV320AIC3104.h:211
static constexpr RegAddr DAC_SW_CTRL_ADDR
Definition TLV320AIC3104.h:106
static constexpr RegAddr LCH_FX_D2_LSB_ADDR
Definition TLV320AIC3104.h:186
static constexpr RegAddr LCH_DEEMP_N1_LSB_ADDR
Definition TLV320AIC3104.h:194
static constexpr RegAddr HEADSET_BTN_PRESS_DETECTB_ADDR
Definition TLV320AIC3104.h:79
static constexpr RegAddr RAGC_PROG_ATTACK_ADDR
Definition TLV320AIC3104.h:161
static constexpr RegAddr RAGC_CTRLB_ADDR
Definition TLV320AIC3104.h:95
TLV320AIC3104()
Definition TLV320AIC3104.h:331
static constexpr RegAddr LCH_FX_N3_MSB_ADDR
Definition TLV320AIC3104.h:177
static constexpr RegAddr RDAC_VOL_ADDR
Definition TLV320AIC3104.h:109
bool selectPage(uint8_t page)
Selects the active register page (writes register 0 of page 0)
Definition TLV320AIC3104.h:747
static constexpr RegAddr RCH_ADC_HPF_N1_LSB_ADDR
Definition TLV320AIC3104.h:235
static constexpr RegAddr LCH_ADC_HPF_N1_LSB_ADDR
Definition TLV320AIC3104.h:229
static constexpr RegAddr RCH_ADC_HPF_D1_MSB_ADDR
Definition TLV320AIC3104.h:236
static constexpr RegAddr DACR1_HPROUT_VOL_ADDR
Definition TLV320AIC3104.h:129
static constexpr uint8_t NCODEC_5_5
Definition TLV320AIC3104.h:253
static constexpr RegAddr RCH_FX_D2_LSB_ADDR
Definition TLV320AIC3104.h:212
static constexpr RegAddr ASD_INTF_CTRLB_ADDR
Definition TLV320AIC3104.h:74
static constexpr RegAddr RCH_FX_N5_MSB_ADDR
Definition TLV320AIC3104.h:207
static constexpr uint8_t AIC3104_IFTYPE_LJF
Definition TLV320AIC3104.h:280
static uint8_t PLL_R_CODE(uint8_t r)
PLL R value lives in OVRF_STATUS_AND_PLLR_ADDR, D3-D0 (code = R - 1)
Definition TLV320AIC3104.h:267
static constexpr RegAddr LCH_FX_N0_LSB_ADDR
Definition TLV320AIC3104.h:172
static constexpr RegAddr HPRCOM_CTRL_ADDR
Definition TLV320AIC3104.h:137
static constexpr uint8_t NCODEC_2
Definition TLV320AIC3104.h:246
static constexpr RegAddr DAC_QUIESCENT_CURRENT_ADDR
Definition TLV320AIC3104.h:166
static constexpr RegAddr RCH_FX_D1_LSB_ADDR
Definition TLV320AIC3104.h:210
static constexpr RegAddr LCH_FX_N5_LSB_ADDR
Definition TLV320AIC3104.h:182
static constexpr RegAddr LCH_DEEMP_N1_MSB_ADDR
Definition TLV320AIC3104.h:193
static constexpr RegAddr RAGC_NGATE_DEBOUNCE_ADDR
Definition TLV320AIC3104.h:100
static constexpr RegAddr LCH_FX_D1_LSB_ADDR
Definition TLV320AIC3104.h:184
static constexpr RegAddr LCH_FX_N4_LSB_ADDR
Definition TLV320AIC3104.h:180
static constexpr RegAddr LAGC_PROG_ATTACK_ADDR
Definition TLV320AIC3104.h:159
bool stopOutput()
Power down the DAC channels.
Definition TLV320AIC3104.h:465
static constexpr RegAddr LAGC_CTRLB_ADDR
Definition TLV320AIC3104.h:92
static constexpr RegAddr RCH_DEEMP_N1_LSB_ADDR
Definition TLV320AIC3104.h:220
bool setVolume(int volume) override
Definition TLV320AIC3104.h:691
static constexpr uint8_t OUT_PWR_ON
Definition TLV320AIC3104.h:293
static constexpr RegAddr RCH_FX_N2_MSB_ADDR
Definition TLV320AIC3104.h:201
static constexpr uint8_t HP_UNMUTE
Definition TLV320AIC3104.h:292
static constexpr RegAddr DACL1_HPRCOM_VOL_ADDR
Definition TLV320AIC3104.h:133
static constexpr uint8_t NCODEC_1_5
Definition TLV320AIC3104.h:245
static constexpr RegAddr LCH_DEEMP_D0_LSB_ADDR
Definition TLV320AIC3104.h:196
static constexpr RegAddr RCH_ADC_HPF_N0_LSB_ADDR
Definition TLV320AIC3104.h:233
static constexpr RegAddr MIC2_RADC_CTRL_ADDR
Definition TLV320AIC3104.h:83
static constexpr RegAddr DACL1_HPLOUT_VOL_ADDR
Definition TLV320AIC3104.h:112
static constexpr RegAddr POP_REDUCTION_ADDR
Definition TLV320AIC3104.h:107
static constexpr uint8_t I2C_ADDR
Definition TLV320AIC3104.h:63
static constexpr RegAddr RCH_FX_N2_LSB_ADDR
Definition TLV320AIC3104.h:202
static constexpr uint8_t ASD_WLEN_24
Definition TLV320AIC3104.h:284
static constexpr RegAddr LCH_DEEMP_N0_LSB_ADDR
Definition TLV320AIC3104.h:192
static constexpr RegAddr LAGC_PROG_DECAY_ADDR
Definition TLV320AIC3104.h:160
static constexpr RegAddr LCH_FX_D1_MSB_ADDR
Definition TLV320AIC3104.h:183
static constexpr uint8_t PAGE_CONTROL_ADDR
Definition TLV320AIC3104.h:761
bool writePagedReg(RegAddr reg, uint8_t value)
Writes a register on the given page.
Definition TLV320AIC3104.h:713
static constexpr RegAddr LCH_FX_D4_LSB_ADDR
Definition TLV320AIC3104.h:188
static constexpr RegAddr RCH_FX_N1_MSB_ADDR
Definition TLV320AIC3104.h:199
static constexpr RegAddr ADC_FLAG_ADDR
Definition TLV320AIC3104.h:101
static constexpr uint8_t AIC3104_IFTYPE_RJF
Definition TLV320AIC3104.h:279
static constexpr RegAddr MICBIAS_CTRL_ADDR
Definition TLV320AIC3104.h:90
static constexpr RegAddr LCH_FX_D2_MSB_ADDR
Definition TLV320AIC3104.h:185
static constexpr RegAddr PGAL_HPLCOM_VOL_ADDR
Definition TLV320AIC3104.h:118
static constexpr RegAddr LINE1R_RADC_CTRL_ADDR
Definition TLV320AIC3104.h:87
static constexpr RegAddr PLL_PROGB_ADDR
Definition TLV320AIC3104.h:69
static constexpr RegAddr LCH_FX_D5_MSB_ADDR
Definition TLV320AIC3104.h:189
static constexpr RegAddr LCH_ADC_HPF_D1_MSB_ADDR
Definition TLV320AIC3104.h:230
input_device_t input_device
Definition TLV320AIC3104.h:744
static constexpr RegAddr ASD_INTF_CTRLA_ADDR
Definition TLV320AIC3104.h:73
static constexpr RegAddr RCH_FX_N3_MSB_ADDR
Definition TLV320AIC3104.h:203
static constexpr RegAddr LCH_ADC_HPF_N0_LSB_ADDR
Definition TLV320AIC3104.h:227
static constexpr RegAddr SAMPLE_RATE_SEL_ADDR
Definition TLV320AIC3104.h:67
static constexpr RegAddr RCH_FX_D4_LSB_ADDR
Definition TLV320AIC3104.h:214
static constexpr RegAddr CODEC_DATAPATH_ADDR
Definition TLV320AIC3104.h:72
static const PllDivs * pllDivTable(size_t &count)
Definition TLV320AIC3104.h:765
static constexpr RegAddr LAGC_CTRLA_ADDR
Definition TLV320AIC3104.h:91
static constexpr RegAddr RCH_FX_N3_LSB_ADDR
Definition TLV320AIC3104.h:204
static constexpr RegAddr HPROUT_CTRL_ADDR
Definition TLV320AIC3104.h:130
static constexpr uint8_t NCODEC_2_5
Definition TLV320AIC3104.h:247
static constexpr uint8_t ADC_PWR_ON
Definition TLV320AIC3104.h:294
static constexpr RegAddr RCH_ADC_HPF_N0_MSB_ADDR
Definition TLV320AIC3104.h:232
static constexpr RegAddr OVRF_STATUS_PLLR_ADDR
Definition TLV320AIC3104.h:76
Common parent class for codec drivers that have been ported from the Zephyr RTOS audio driver impleme...
Definition ZephyrDriverCommon.h:22
uint8_t i2c_addr
Definition ZephyrDriverCommon.h:87
int volume_percent
Last volume (in %) provided to setVolume()
Definition ZephyrDriverCommon.h:89
bool readReg(uint8_t reg, uint8_t &value, bool stopBit=true)
Reads a single byte from an 8 bit register address.
Definition ZephyrDriverCommon.h:100
bool writeReg(uint8_t reg, uint8_t value)
Writes a single byte to an 8 bit register address.
Definition ZephyrDriverCommon.h:94
uint16_t RegAddr
Definition TLV320AIC3110.h:57
Namespace for audio driver components.
Definition AudioBoard.h:5
AIC3104Channel
Logical audio channels.
Definition TLV320AIC3104.h:20
@ LineOutRight
RIGHT_LOP/M (fully differential line output)
@ LineOutLeft
LEFT_LOP/M (fully differential line output)
input_device_t
Definition DriverCommon.h:170
@ ADC_INPUT_ALL
Definition DriverCommon.h:175
@ ADC_INPUT_LINE1
Definition DriverCommon.h:172
@ ADC_INPUT_LINE3
Definition DriverCommon.h:174
@ ADC_INPUT_LINE2
Definition DriverCommon.h:173
@ ADC_INPUT_DIFFERENCE
Definition DriverCommon.h:176
void delayMs(unsigned long ms)
Definition API_Delay.h:19
static constexpr uint8_t makeBits(uint8_t l, uint8_t r, uint8_t v)
Definition TLV320AIC3104.h:37
codec_mode_t
Definition DriverCommon.h:290
output_device_t
Definition DriverCommon.h:186
@ DAC_OUTPUT_LINE1
Definition DriverCommon.h:188
@ DAC_OUTPUT_ALL
Definition DriverCommon.h:190
@ DAC_OUTPUT_LINE2
Definition DriverCommon.h:189
static constexpr uint8_t makeBit(uint8_t l, uint8_t v)
Definition TLV320AIC3104.h:40
i2s_format_t
Definition DriverCommon.h:250
Definition TLV320AIC3104.h:312
uint32_t clk
Definition TLV320AIC3104.h:313
uint8_t r
Definition TLV320AIC3104.h:316
uint32_t fsref
44100 or 48000
Definition TLV320AIC3104.h:314
uint8_t p
Definition TLV320AIC3104.h:315
uint8_t j
Definition TLV320AIC3104.h:317
uint16_t d
Definition TLV320AIC3104.h:318
Definition TLV320AIC3104.h:324
uint8_t ncodec_code
Definition TLV320AIC3104.h:327
bool dual_rate
Definition TLV320AIC3104.h:328
uint32_t fsref
Definition TLV320AIC3104.h:326
uint32_t rate
Definition TLV320AIC3104.h:325
Page + register address pair.
Definition TLV320AIC3104.h:58
uint8_t page
Definition TLV320AIC3104.h:59
uint8_t reg
Definition TLV320AIC3104.h:60