[audio][sherlock] Add L+R HW mixing for woofer
Note that this does not imply frequency filtering.
Test: audio uapp and manually crafted input checked on a scope.
Change-Id: I772b28cb21b0ae01d7a4bb3ffcebca06651de83b
diff --git a/system/dev/audio/astro-tdm-output/audio-stream-out.cpp b/system/dev/audio/astro-tdm-output/audio-stream-out.cpp
index e71852c..3620891 100644
--- a/system/dev/audio/astro-tdm-output/audio-stream-out.cpp
+++ b/system/dev/audio/astro-tdm-output/audio-stream-out.cpp
@@ -77,8 +77,8 @@
// Setup TDM.
- // 3 bitoffset, 4 slots, 32 bits/slot, 16 bits/sample.
- aml_audio_->ConfigTdmOutSlot(3, 3, 31, 15);
+ // 3 bitoffset, 4 slots, 32 bits/slot, 16 bits/sample, no mixing.
+ aml_audio_->ConfigTdmOutSlot(3, 3, 31, 15, 0);
// Lane0 right channel.
aml_audio_->ConfigTdmOutSwaps(0x00000010);
diff --git a/system/dev/audio/sherlock-tdm-output/audio-stream-out.cpp b/system/dev/audio/sherlock-tdm-output/audio-stream-out.cpp
index 1927e85..586700a 100644
--- a/system/dev/audio/sherlock-tdm-output/audio-stream-out.cpp
+++ b/system/dev/audio/sherlock-tdm-output/audio-stream-out.cpp
@@ -13,8 +13,9 @@
namespace audio {
namespace sherlock {
-// Expects L tweeter + R tweeter + Woofer.
-constexpr size_t kNumberOfChannels = 3;
+// Expects L+R for tweeters + L+R for the 1 Woofer (mixed in HW).
+// The user must perform crossover filtering on these channels.
+constexpr size_t kNumberOfChannels = 4;
// Calculate ring buffer size for 1 second of 16-bit, 48kHz.
constexpr size_t kRingBufferSize = fbl::round_up<size_t, size_t>(48000 * 2 * kNumberOfChannels,
PAGE_SIZE);
@@ -98,19 +99,20 @@
// data lines (ConfigTdmOutSlot bitoffset=4 below accomplishes this).
// -3072MHz/64 = 48KHz.
- // 4 bitoffset, 2 slots, 32 bits/slot, 16 bits/sample.
- aml_audio_->ConfigTdmOutSlot(4, 1, 31, 15);
+ // 4 bitoffset, 2 slots, 32 bits/slot, 16 bits/sample, enable mix L+R on lane 1.
+ aml_audio_->ConfigTdmOutSlot(4, 1, 31, 15, (1 << 1));
- // Lane 0 left channel set to FRDDR slot 0.
- // Lane 0 right channel set to FRDDR slot 1.
- // Lane 1 left channel set to FRDDR slot 2.
- aml_audio_->ConfigTdmOutSwaps(0x00000210);
+ // Lane 0 L channel set to FRDDR slot 0.
+ // Lane 0 R channel set to FRDDR slot 1.
+ // Lane 1 L channel set to FRDDR slot 2. Mixed with R, see ConfigTdmOutSlot above.
+ // Lane 1 R channel set to FRDDR slot 3. Mixed with L, see ConfigTdmOutSlot above.
+ aml_audio_->ConfigTdmOutSwaps(0x00003210);
// Tweeters: Lane 0, unmask TDM slots 0 & 1 (L+R FRDDR slots 0 & 1).
aml_audio_->ConfigTdmOutLane(0, 0x00000003);
- // Woofer: Lane 1, unmask TDM slot 0 (Woofer FRDDR slot 2).
- aml_audio_->ConfigTdmOutLane(1, 0x00000001);
+ // Woofer: Lane 1, unmask TDM slot 0 & 1 (Woofer FRDDR slots 2 & 3).
+ aml_audio_->ConfigTdmOutLane(1, 0x00000003);
// mclk = T931_HIFI_PLL_RATE/125 = 1536MHz/125 = 12.288MHz.
aml_audio_->SetMclkDiv(124);
diff --git a/system/dev/lib/amlogic/aml-tdm-audio.cpp b/system/dev/lib/amlogic/aml-tdm-audio.cpp
index fe67ec5..56cdd95 100644
--- a/system/dev/lib/amlogic/aml-tdm-audio.cpp
+++ b/system/dev/lib/amlogic/aml-tdm-audio.cpp
@@ -71,6 +71,11 @@
//Value to be inserted in a slot if it is masked
mmio_.Write32(0x00000000, GetTdmOffset(TDMOUT_MASK_VAL_OFFS));
+ mmio_.Write32(0x00000000, GetTdmOffset(TDMOUT_MUTE0_OFFS)); // Disable lane 0 muting.
+ mmio_.Write32(0x00000000, GetTdmOffset(TDMOUT_MUTE1_OFFS)); // Disable lane 1 muting.
+ mmio_.Write32(0x00000000, GetTdmOffset(TDMOUT_MUTE2_OFFS)); // Disable lane 2 muting.
+ mmio_.Write32(0x00000000, GetTdmOffset(TDMOUT_MUTE3_OFFS)); // Disable lane 3 muting.
+
// Datasheets state that PAD_CTRL1 controls sclk and lrclk source selection (which mclk),
// it does this per pad (0, 1, 2). These pads are tied to the TDM channel in use
// (this is not specified in the datasheets but confirmed empirically) such that TDM_OUT_A
@@ -175,11 +180,13 @@
num_slots - number of slots per frame minus one
bits_per_slot - width of each slot minus one
bits_per_sample - number of bits in sample minus one
+ mix_mask - lanes to mix L+R.
*/
void AmlTdmDevice::ConfigTdmOutSlot(uint8_t bit_offset, uint8_t num_slots,
- uint8_t bits_per_slot, uint8_t bits_per_sample) {
+ uint8_t bits_per_slot, uint8_t bits_per_sample,
+ uint8_t mix_mask) {
- uint32_t reg = bits_per_slot | (num_slots << 5) | (bit_offset << 15);
+ uint32_t reg = bits_per_slot | (num_slots << 5) | (bit_offset << 15) | (mix_mask << 20);
mmio_.Write32(reg, GetTdmOffset(TDMOUT_CTRL0_OFFS));
reg = (bits_per_sample << 8) | (frddr_ch_ << 24);
@@ -187,7 +194,7 @@
// 8 bit sample, left justify in frame, split 64-bit dma fetch into 8 samples
reg |= (0 << 4);
} else if (bits_per_sample <= 16) {
- // 16 bit sample, left justify in frame, split 64-bit dma fetch into 2 samples
+ // 16 bit sample, left justify in frame, split 64-bit dma fetch into 4 samples
reg |= (2 << 4);
} else {
// 32/24 bit sample, left justify in slot, split 64-bit dma fetch into 2 samples
diff --git a/system/dev/lib/amlogic/include/soc/aml-common/aml-tdm-audio.h b/system/dev/lib/amlogic/include/soc/aml-common/aml-tdm-audio.h
index 40f864d..165a668 100644
--- a/system/dev/lib/amlogic/include/soc/aml-common/aml-tdm-audio.h
+++ b/system/dev/lib/amlogic/include/soc/aml-common/aml-tdm-audio.h
@@ -35,8 +35,8 @@
zx_status_t SetMClkPad(aml_tdm_mclk_pad_t mclk_pad);
// Configures placement of data on the tdm bus
- void ConfigTdmOutSlot(uint8_t bit_offset, uint8_t num_slots,
- uint8_t bits_per_slot, uint8_t bits_per_sample);
+ void ConfigTdmOutSlot(uint8_t bit_offset, uint8_t num_slots, uint8_t bits_per_slot,
+ uint8_t bits_per_sample, uint8_t mix_mask);
// Configures Lanes.
zx_status_t ConfigTdmOutLane(size_t lane, uint32_t mask);