M changelog.md => changelog.md +1 -0
@@ 9,6 9,7 @@
* `[file indexer db]` Added messages for File Indexer db.
* `[settings]` Added Torch window (front-end only).
* `[audio]` Added support for Bluetooth audio profiles
+* `[audio]` Added support for headset microphone.
* `[filesystem]` Added support for standard file IO library.
* [`[messages]`] Added fetching text messages at phone startup.
M module-audio/Audio/Operation/RouterOperation.cpp => module-audio/Audio/Operation/RouterOperation.cpp +1 -1
@@ 104,7 104,7 @@ namespace audio
constexpr audio::Volume defaultRoutingEarspeakerVolume = 10;
constexpr audio::Gain defaultRoutingSpeakerphoneGain = 20;
constexpr audio::Volume defaultRoutingSpeakerphoneVolume = 10;
- constexpr audio::Gain defaultRoutingHeadphonesGain = 50;
+ constexpr audio::Gain defaultRoutingHeadphonesGain = 0;
constexpr audio::Volume defaultRoutingHeadphonesVolume = 10;
const auto dbRoutingEarspeakerGainPath =
M module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp => module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp +0 -1
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
M module-audio/Audio/Profiles/ProfileRecordingHeadphones.hpp => module-audio/Audio/Profiles/ProfileRecordingHeadphones.hpp +0 -1
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
M module-audio/Audio/Profiles/ProfileRecordingOnBoardMic.hpp => module-audio/Audio/Profiles/ProfileRecordingOnBoardMic.hpp +0 -1
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
M module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp +0 -1
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
M module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp => module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp +1 -2
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
@@ 23,7 22,7 @@ namespace audio
.outputVolume = static_cast<float>(volume),
.inputGain = static_cast<float>(gain),
.inputPath = bsp::AudioDevice::InputPath::Headphones,
- .outputPath = bsp::AudioDevice::OutputPath::Headphones},
+ .outputPath = bsp::AudioDevice::OutputPath::HeadphonesMono},
bsp::AudioDevice::Type::Audiocodec,
callback)
{}
M module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp +1 -2
@@ 1,6 1,5 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
#pragma once
#include "Profile.hpp"
@@ 23,7 22,7 @@ namespace audio
.outputVolume = static_cast<float>(volume),
.inputGain = static_cast<float>(gain),
.inputPath = bsp::AudioDevice::InputPath::Microphone,
- .outputPath = bsp::AudioDevice::OutputPath::Loudspeaker},
+ .outputPath = bsp::AudioDevice::OutputPath::LoudspeakerMono},
bsp::AudioDevice::Type::Audiocodec,
callback)
{}
M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.cpp => module-bsp/board/rt1051/bsp/audio/CodecMAX98090.cpp +130 -128
@@ 80,31 80,34 @@ CodecRetCode CodecMAX98090::Start(const CodecParams ¶m)
// OUT configuration
if (params.outputPath != bsp::AudioDevice::OutputPath::None) {
- // Set output route
- max98090_reg_playback_quick_setup_t q_playback_setup = {0};
// Control HP performance
max98090_reg_dachp_perfmode_t dacperf = {0};
+ dacperf.dachp = 1;
+ dacperf.perfmode = 0;
+ i2cAddr.subAddress = MAX98090_REG_DACHP_PERF_MODE;
+ i2c->Write(i2cAddr, (uint8_t *)&dacperf, 1);
switch (params.outputPath) {
case bsp::AudioDevice::OutputPath::HeadphonesMono: {
+ max98090_reg_playback_quick_setup_t q_playback_setup = {0};
+ q_playback_setup.dig2hp = 1;
+ i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
+ i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
// Mix left DAC channel to left&right HP output
max98090_reg_lhp_mixer_t lmixconf = {0};
- max98090_reg_rhp_mixer_t rmixconf = {0};
lmixconf.mixhpl = 1;
- rmixconf.mixhpr = 1;
-
i2cAddr.subAddress = MAX98090_REG_LHP_MIXER_CONF;
i2c->Write(i2cAddr, (uint8_t *)&lmixconf, 1);
+
+ max98090_reg_rhp_mixer_t rmixconf = {0};
+ rmixconf.mixhpr = 1;
i2cAddr.subAddress = MAX98090_REG_RHP_MIXER_CONF;
i2c->Write(i2cAddr, (uint8_t *)&rmixconf, 1);
- q_playback_setup.dig2hp = 1;
- i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
- i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
-
+ // Use mixer outputs instead of direct DAC outputs
max98090_reg_hpmix_conf_t mixconf = {0};
mixconf.mixhplsel = 1;
mixconf.mixhprsel = 1;
@@ 114,110 117,58 @@ CodecRetCode CodecMAX98090::Start(const CodecParams ¶m)
} break;
case bsp::AudioDevice::OutputPath::Headphones: {
- // Set DAC headphones output to high performance mode, increasing power consumption but providing the
- // highest quality
- dacperf.dachp = 1;
- dacperf.perfmode = 1;
- q_playback_setup.dig2hp = 1;
-
+ max98090_reg_playback_quick_setup_t q_playback_setup = {0};
+ q_playback_setup.dig2hp = 1;
i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
- i2cAddr.subAddress = MAX98090_REG_DACHP_PERF_MODE;
- i2c->Write(i2cAddr, (uint8_t *)&dacperf, 1);
} break;
case bsp::AudioDevice::OutputPath::Earspeaker: {
+ max98090_reg_playback_quick_setup_t q_playback_setup = {0};
q_playback_setup.dig2ear = 1;
i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
- qfilter_coefficients_t band1_filter = {0};
- qfilter_coefficients_t band2_filter = {0};
- qfilter_coefficients_t band3_filter = {0};
-
- // Highpass,lowpass & flat filters don't use Gain parameter
- qfilter_CalculateCoeffs(FilterHighPass, 800, currentParams.GetSampleRateVal(), 0.707, 1, &band1_filter);
- qfilter_CalculateCoeffs(FilterLowPass, 6000, currentParams.GetSampleRateVal(), 0.707, 1, &band2_filter);
- qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band3_filter);
-
- // BAND1
- WriteFilterCoeff(band1_filter.b0, 0x46);
- WriteFilterCoeff(band1_filter.b1, 0x49);
- WriteFilterCoeff(band1_filter.b2, 0x4C);
- WriteFilterCoeff(band1_filter.a1, 0x4F);
- WriteFilterCoeff(band1_filter.a2, 0x52);
-
- // BAND2
- WriteFilterCoeff(band2_filter.b0, 0x55);
- WriteFilterCoeff(band2_filter.b1, 0x58);
- WriteFilterCoeff(band2_filter.b2, 0x5B);
- WriteFilterCoeff(band2_filter.a1, 0x5E);
- WriteFilterCoeff(band2_filter.a2, 0x61);
-
- // BAND3
- WriteFilterCoeff(band3_filter.b0, 0x64);
- WriteFilterCoeff(band3_filter.b1, 0x67);
- WriteFilterCoeff(band3_filter.b2, 0x6A);
- WriteFilterCoeff(band3_filter.a1, 0x6D);
- WriteFilterCoeff(band3_filter.a2, 0x70);
-
- // Enable 3-band filter
- max98090_reg_dsp_biquadfilter_enable_t filter = {0};
- filter.eq3banden = 1;
- i2cAddr.subAddress = MAX98090_REG_DSP_BIQUAD_FILTER_ENABLE;
- i2c->Write(i2cAddr, (uint8_t *)&filter, 1);
+ SetupEarspeakerEqualizer();
} break;
case bsp::AudioDevice::OutputPath::Loudspeaker: {
+ max98090_reg_playback_quick_setup_t q_playback_setup = {0};
q_playback_setup.dig2spk = 1;
+ i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
+ i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
uint8_t mask = 0x08; // Set 3th bit (dmono on)
i2cAddr.subAddress = MAX98090_REG_INOUT_PATH_CONF;
i2c->Modify(i2cAddr, mask, true, 1);
- // TODO: Turn off/mute right speaker
+ // Turn off right speaker path
+ max98090_reg_outputenable_t outputenable = {0};
+ outputenable.dalen = 1;
+ outputenable.splen = 1;
+ i2cAddr.subAddress = MAX98090_REG_OUTPUT_ENABLE;
+ i2c->Write(i2cAddr, (uint8_t *)&outputenable, 1);
+
+ SetupLoudspeakerEqualizer();
+ } break;
+
+ case bsp::AudioDevice::OutputPath::LoudspeakerMono: {
+ max98090_reg_playback_quick_setup_t q_playback_setup = {0};
+ q_playback_setup.dig2spk = 1;
i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);
- qfilter_coefficients_t band1_filter = {0};
- qfilter_coefficients_t band2_filter = {0};
- qfilter_coefficients_t band3_filter = {0};
-
- // Highpass,lowpass & flat filters don't use Gain parameter
- qfilter_CalculateCoeffs(FilterHighPass, 500, currentParams.GetSampleRateVal(), 0.707, 1, &band1_filter);
- qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band2_filter);
- qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band3_filter);
-
- // BAND1
- WriteFilterCoeff(band1_filter.b0, 0x46);
- WriteFilterCoeff(band1_filter.b1, 0x49);
- WriteFilterCoeff(band1_filter.b2, 0x4C);
- WriteFilterCoeff(band1_filter.a1, 0x4F);
- WriteFilterCoeff(band1_filter.a2, 0x52);
-
- // BAND2
- WriteFilterCoeff(band2_filter.b0, 0x55);
- WriteFilterCoeff(band2_filter.b1, 0x58);
- WriteFilterCoeff(band2_filter.b2, 0x5B);
- WriteFilterCoeff(band2_filter.a1, 0x5E);
- WriteFilterCoeff(band2_filter.a2, 0x61);
-
- // BAND3
- WriteFilterCoeff(band3_filter.b0, 0x64);
- WriteFilterCoeff(band3_filter.b1, 0x67);
- WriteFilterCoeff(band3_filter.b2, 0x6A);
- WriteFilterCoeff(band3_filter.a1, 0x6D);
- WriteFilterCoeff(band3_filter.a2, 0x70);
-
- // Enable 3-band filter
- max98090_reg_dsp_biquadfilter_enable_t filter = {0};
- filter.eq3banden = 1;
- i2cAddr.subAddress = MAX98090_REG_DSP_BIQUAD_FILTER_ENABLE;
- i2c->Write(i2cAddr, (uint8_t *)&filter, 1);
+ // Turn off right speaker path
+ max98090_reg_outputenable_t outputenable = {0};
+ outputenable.dalen = 1;
+ outputenable.splen = 1;
+ i2cAddr.subAddress = MAX98090_REG_OUTPUT_ENABLE;
+ i2c->Write(i2cAddr, (uint8_t *)&outputenable, 1);
+ SetupLoudspeakerEqualizer();
} break;
default:
@@ 229,34 180,16 @@ CodecRetCode CodecMAX98090::Start(const CodecParams ¶m)
if (params.inputPath != bsp::AudioDevice::InputPath::None) {
// Set input path
switch (params.inputPath) {
- case bsp::AudioDevice::InputPath::Headphones: {
- /* max98090_reg_analog_to_record_quick_t q_analog_setup = {0};
- q_analog_setup.in34mic2 = 1;
- bsp_i2c_Send(i2CInst,DeviceAddr,
- MAX98090_REG_ANALOG_MIC_TO_RECORD_QUICK,(uint8_t*)&q_analog_setup,1);
-
- max98090_reg_radc_mix_input_t radcmix = {0};
- bsp_i2c_Send(i2CInst,DeviceAddr, MAX98090_REG_RADC_MIXER_INPUT,(uint8_t*)&radcmix);
-
- max98090_reg_ladc_mix_input_t ladcmix = {0};
- ladcmix.mixadl = 0x40;
- bsp_i2c_Send(i2CInst,DeviceAddr, MAX98090_REG_LADC_MIXER_INPUT,(uint8_t*)&ladcmix); */
+ case bsp::AudioDevice::InputPath::Headphones: {
max98090_reg_input_to_record_quick_t q_input_setup = {0};
q_input_setup.in34dan = 1;
i2cAddr.subAddress = MAX98090_REG_LINE_INPUT_TO_RECORD_QUICK;
i2c->Write(i2cAddr, (uint8_t *)&q_input_setup, 1);
-
- uint8_t mask = 0x10; // Set 4th bit (mic bias enable)
- i2cAddr.subAddress = MAX98090_REG_INPUT_ENABLE;
- i2c->Modify(i2cAddr, mask, true, 1);
-
} break;
case bsp::AudioDevice::InputPath::Microphone: {
- max98090_reg_input_to_record_quick_t q_input_setup = {0};
- max98090_reg_analog_to_record_quick_t q_analog_setup = {0};
- max98090_reg_digmic_enable_t digena = {0};
+ max98090_reg_digmic_enable_t digena = {0};
// Enable left and right digital mic interface
digena.digmicl = 1;
@@ 266,32 199,18 @@ CodecRetCode CodecMAX98090::Start(const CodecParams ¶m)
i2cAddr.subAddress = MAX98090_REG_DIG_MIC_ENABLE;
i2c->Write(i2cAddr, (uint8_t *)&digena, 1);
-
- // It seems that for digital mics it doesn't matter if digitial or analog input is chosen
- q_input_setup.in12sab = 1;
-
- i2cAddr.subAddress = MAX98090_REG_LINE_INPUT_TO_RECORD_QUICK;
- i2c->Write(i2cAddr, (uint8_t *)&q_input_setup, 1);
-
- // q_analog_setup.in12mic1 = 1;
- // bsp_i2c_Send(i2CInst,DeviceAddr, MAX98090_REG_ANALOG_MIC_TO_RECORD_QUICK,(uint8_t*)&q_analog_setup,1);
-
- uint8_t mask = 0x10; // Clr 4th bit (mic bias disable)
- i2cAddr.subAddress = MAX98090_REG_INPUT_ENABLE;
- i2c->Modify(i2cAddr, mask, false, 1);
-
} break;
default:
return CodecRetCode::InvalidInputPath;
}
-
- // Turn on DC blocking filters
- uint8_t mask = (1 << 6) | (1 << 5); // set 6th and 7th bit (AHPF and DHPF)
- i2cAddr.subAddress = MAX98090_REG_PLAYBACK_DSP_FILTER_CONF;
- i2c->Modify(i2cAddr, mask, true, 1);
}
+ // Turn on DC blocking filters
+ uint8_t mask = (1 << 6) | (1 << 5); // set 6th and 7th bit (AHPF and DHPF)
+ i2cAddr.subAddress = MAX98090_REG_PLAYBACK_DSP_FILTER_CONF;
+ i2c->Modify(i2cAddr, mask, true, 1);
+
// Store param configuration
currentParams = params;
@@ 417,7 336,8 @@ CodecRetCode CodecMAX98090::SetOutputVolume(const float vol)
i2c->Write(i2cAddr, (uint8_t *)&vol, 1);
} break;
- case bsp::AudioDevice::OutputPath::Loudspeaker: {
+ case bsp::AudioDevice::OutputPath::Loudspeaker:
+ case bsp::AudioDevice::OutputPath::LoudspeakerMono: {
// Scale input volume(range 0 - 100) to MAX98090 range(decibels hardcoded as specific hex values)
constexpr float scale_factor = .39f * 10.f;
uint8_t volume = static_cast<float>(vol * scale_factor) + 0x18;
@@ 515,6 435,88 @@ CodecRetCode CodecMAX98090::MicBias(const bool enable)
return CodecRetCode::Success;
}
+CodecRetCode CodecMAX98090::SetupEarspeakerEqualizer()
+{
+ qfilter_coefficients_t band1_filter = {0};
+ qfilter_coefficients_t band2_filter = {0};
+ qfilter_coefficients_t band3_filter = {0};
+
+ // Highpass,lowpass & flat filters don't use Gain parameter
+ qfilter_CalculateCoeffs(FilterHighPass, 800, currentParams.GetSampleRateVal(), 0.707, 1, &band1_filter);
+ qfilter_CalculateCoeffs(FilterLowPass, 6000, currentParams.GetSampleRateVal(), 0.707, 1, &band2_filter);
+ qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band3_filter);
+
+ // BAND1
+ WriteFilterCoeff(band1_filter.b0, 0x46);
+ WriteFilterCoeff(band1_filter.b1, 0x49);
+ WriteFilterCoeff(band1_filter.b2, 0x4C);
+ WriteFilterCoeff(band1_filter.a1, 0x4F);
+ WriteFilterCoeff(band1_filter.a2, 0x52);
+
+ // BAND2
+ WriteFilterCoeff(band2_filter.b0, 0x55);
+ WriteFilterCoeff(band2_filter.b1, 0x58);
+ WriteFilterCoeff(band2_filter.b2, 0x5B);
+ WriteFilterCoeff(band2_filter.a1, 0x5E);
+ WriteFilterCoeff(band2_filter.a2, 0x61);
+
+ // BAND3
+ WriteFilterCoeff(band3_filter.b0, 0x64);
+ WriteFilterCoeff(band3_filter.b1, 0x67);
+ WriteFilterCoeff(band3_filter.b2, 0x6A);
+ WriteFilterCoeff(band3_filter.a1, 0x6D);
+ WriteFilterCoeff(band3_filter.a2, 0x70);
+
+ // Enable 3-band filter
+ max98090_reg_dsp_biquadfilter_enable_t filter = {0};
+ filter.eq3banden = 1;
+ i2cAddr.subAddress = MAX98090_REG_DSP_BIQUAD_FILTER_ENABLE;
+ i2c->Write(i2cAddr, (uint8_t *)&filter, 1);
+
+ return CodecRetCode::Success;
+}
+
+CodecRetCode CodecMAX98090::SetupLoudspeakerEqualizer()
+{
+ qfilter_coefficients_t band1_filter = {0};
+ qfilter_coefficients_t band2_filter = {0};
+ qfilter_coefficients_t band3_filter = {0};
+
+ // Highpass,lowpass & flat filters don't use Gain parameter
+ qfilter_CalculateCoeffs(FilterHighPass, 500, currentParams.GetSampleRateVal(), 0.707, 1, &band1_filter);
+ qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band2_filter);
+ qfilter_CalculateCoeffs(FilterFlat, 0, currentParams.GetSampleRateVal(), 0.707, 1, &band3_filter);
+
+ // BAND1
+ WriteFilterCoeff(band1_filter.b0, 0x46);
+ WriteFilterCoeff(band1_filter.b1, 0x49);
+ WriteFilterCoeff(band1_filter.b2, 0x4C);
+ WriteFilterCoeff(band1_filter.a1, 0x4F);
+ WriteFilterCoeff(band1_filter.a2, 0x52);
+
+ // BAND2
+ WriteFilterCoeff(band2_filter.b0, 0x55);
+ WriteFilterCoeff(band2_filter.b1, 0x58);
+ WriteFilterCoeff(band2_filter.b2, 0x5B);
+ WriteFilterCoeff(band2_filter.a1, 0x5E);
+ WriteFilterCoeff(band2_filter.a2, 0x61);
+
+ // BAND3
+ WriteFilterCoeff(band3_filter.b0, 0x64);
+ WriteFilterCoeff(band3_filter.b1, 0x67);
+ WriteFilterCoeff(band3_filter.b2, 0x6A);
+ WriteFilterCoeff(band3_filter.a1, 0x6D);
+ WriteFilterCoeff(band3_filter.a2, 0x70);
+
+ // Enable 3-band filter
+ max98090_reg_dsp_biquadfilter_enable_t filter = {0};
+ filter.eq3banden = 1;
+ i2cAddr.subAddress = MAX98090_REG_DSP_BIQUAD_FILTER_ENABLE;
+ i2c->Write(i2cAddr, (uint8_t *)&filter, 1);
+
+ return CodecRetCode::Success;
+}
+
CodecRetCode CodecMAX98090::Reset()
{
M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp => module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp +2 -0
@@ 120,6 120,8 @@ class CodecMAX98090 : public Codec
CodecRetCode SetInputPath(const bsp::AudioDevice::InputPath path);
CodecRetCode SetOutputPath(const bsp::AudioDevice::OutputPath path);
CodecRetCode MicBias(const bool enable);
+ CodecRetCode SetupEarspeakerEqualizer();
+ CodecRetCode SetupLoudspeakerEqualizer();
CodecRetCode WriteFilterCoeff(const float coeff, const uint8_t basereg);
CodecRetCode Reset();
};
M module-bsp/board/rt1051/bsp/audio/max98090_regs.hpp => module-bsp/board/rt1051/bsp/audio/max98090_regs.hpp +29 -65
@@ 37,7 37,7 @@ typedef struct
// Device Status Interrupt Mask Register
// Check Table 86. for more info.
-#define MAX98090_REG_DEVICE_STATUS_MASK 0x01
+#define MAX98090_REG_DEVICE_STATUS_MASK 0x03
typedef struct
{
uint8_t idrcclp : 1;
@@ 74,24 74,25 @@ typedef struct
#define MAX98090_REG_OUTPUT_ENABLE 0x3F
typedef struct
{
- uint8_t hpren : 1;
- uint8_t hplen : 1;
- uint8_t spren : 1;
- uint8_t splen : 1;
- uint8_t rcvlen : 1;
- uint8_t rcvren : 1;
- uint8_t daren : 1;
uint8_t dalen : 1;
+ uint8_t daren : 1;
+ uint8_t rcvren : 1;
+ uint8_t rcvlen : 1;
+ uint8_t splen : 1;
+ uint8_t spren : 1;
+ uint8_t hplen : 1;
+ uint8_t hpren : 1;
} max98090_reg_outputenable_t;
-// Output enable register
-#define MAX98090_REG_DAC_HP_PERF 0x43
+// Line Input Level Configuration Register
+#define MAX98090_REG_LINE_INPUT_LEVEL_CONF 0x0E
typedef struct
{
- uint8_t dachp : 1;
- uint8_t perfmode : 1;
- uint8_t unused : 6;
-} max98090_reg_dac_hp_perf_t;
+ uint8_t linbpga : 3;
+ uint8_t linapga : 3;
+ uint8_t mixg246 : 1;
+ uint8_t mixg135 : 1;
+} max98090_reg_line_inp_lvl_t;
// Microphone 1 enable and level configuration register
#define MAX98090_REG_MIC1_ENABLE_LEVEL_CONF 0x10
@@ 99,6 100,7 @@ typedef struct
{
uint8_t pgam : 5;
uint8_t pa1en : 2;
+ uint8_t unused : 1;
} max98090_reg_mic1ena_lvlctl_t;
// Microphone 2 enable and level configuration register
@@ 107,6 109,7 @@ typedef struct
{
uint8_t pgam : 5;
uint8_t pa2en : 2;
+ uint8_t unused : 1;
} max98090_reg_mic2ena_lvlctl_t;
// Microphone Bias Level Configuration Register
@@ 125,7 128,7 @@ typedef struct
uint8_t digmicl : 1;
uint8_t digmicr : 1;
uint8_t unused : 2;
- uint8_t dmicclk : 2;
+ uint8_t dmicclk : 3;
uint8_t unused2 : 1;
} max98090_reg_digmic_enable_t;
@@ 154,6 157,7 @@ typedef struct
typedef struct
{
uint8_t mixadl : 7;
+ uint8_t unused : 1;
} max98090_reg_ladc_mix_input_t;
/* Right ADC Mixer Input Configuration Register
@@ 169,6 173,7 @@ typedef struct
typedef struct
{
uint8_t mixadr : 7;
+ uint8_t unused : 1;
} max98090_reg_radc_mix_input_t;
/* Left Record Path Digital Gain Configuration Register
@@ 193,46 198,6 @@ typedef struct
uint8_t unused : 1;
} max98090_reg_rrec_dig_gain_t;
-// Record DSP Filter Configuration Register
-#define MAX98090_REG_REC_DSP_FILTER_CONF 0x14
-typedef struct
-{
-
- uint8_t unused : 4;
-
- /*
- Enables the DAC High Sample Rate Mode (LRCLK > 48kHz, FIR Only)
- 0: LRCLK is less than 48kHz. 8x FIR interpolation filter used.
- 1: LRCLK is greater than 48kHz. 4x FIR interpolation filter used.
- */
- uint8_t dhf : 1;
-
- /*
- Enables the Playback Path DC-Blocking Filter
- 0: DC-blocking filter disabled.
- 1: DC-blocking filter enabled
- */
- uint8_t dhpf : 1;
-
- /*
- Enables the Record Path DC-Blocking Filter
- 0: DC-blocking filter disabled.
- 1: DC-blocking filter enabled.
- */
- uint8_t ahpf : 1;
-
- /*
- Enables the Codec DSP FIR Music Filters (Default IIR Voice Filters)
- 0: The codec DSP filters operate in IIR voice mode with stop band frequencies below
- the fS/2 Nyquist rate. The voice mode filters are optimized for 8kHz or 16kHz voice
- application use.
- 1: The codec DSP filters operate in a linear phase FIR audio mode optimized to
- maintain stereo imaging and operate at higher fS rates while utilizing lower power
- */
- uint8_t mode : 1;
-
-} max98090_reg_rec_dspfilter_conf_t;
-
// System Master Clock (MCLK) Prescaler Configuration Register
// Check MAX98090 datasheet Table 34 for available configurations
#define MAX98090_REG_SYSTEM_MASTER_CLOCK 0x1B
@@ 260,7 225,7 @@ typedef struct
#define MAX98090_REG_CLOCK_MODE 0x1C
typedef struct
{
- uint8_t usemi : 4;
+ uint8_t usemi : 1;
uint8_t unused : 3;
uint8_t freq : 4;
} max98090_reg_clock_mode_t;
@@ 270,7 235,8 @@ typedef struct
#define MAX98090_REG_NI_MSB 0x1D
typedef struct
{
- uint8_t ni;
+ uint8_t ni : 7;
+ uint8_t unused : 1;
} max98090_reg_manual_clock_ratio_NI_MSB_t;
// Manual Clock Ratio Configuration Register (NI LSB)
@@ 405,7 371,6 @@ typedef struct
uint8_t dhpf : 1;
uint8_t ahpf : 1;
uint8_t mode : 1;
-
} max98090_reg_playback_dspfilter_conf_t;
// Master Clock Quick Setup Register
@@ 501,8 466,8 @@ typedef struct
#define MAX98090_REG_LHP_VOL_CTRL 0x2C
typedef struct
{
- uint8_t hpvoll : 6;
- uint8_t unused : 1;
+ uint8_t hpvoll : 5;
+ uint8_t unused : 2;
uint8_t hplm : 1;
} max98090_reg_lhp_vol_ctrl_t;
@@ 512,8 477,8 @@ typedef struct
#define MAX98090_REG_RHP_VOL_CTRL 0x2D
typedef struct
{
- uint8_t hpvolr : 6;
- uint8_t unused : 1;
+ uint8_t hpvolr : 5;
+ uint8_t unused : 2;
uint8_t hprm : 1;
} max98090_reg_rhp_vol_ctrl_t;
@@ 545,8 510,8 @@ typedef struct
#define MAX98090_REG_RECV_VOL_CTRL 0x39
typedef struct
{
- uint8_t rcvlvol : 6;
- uint8_t unused : 1;
+ uint8_t rcvlvol : 5;
+ uint8_t unused : 2;
uint8_t rcvlm : 1;
} max98090_reg_recv_vol_ctrl_t;
@@ 581,7 546,6 @@ typedef struct
uint8_t adcdither : 1;
uint8_t osr128 : 1;
uint8_t unused : 5;
-
} max98090_reg_adcperf_mode_t;
#define MAX98090_I2C_ADDR 0x10
M module-bsp/board/rt1051/bsp/headset/headset.cpp => module-bsp/board/rt1051/bsp/headset/headset.cpp +35 -3
@@ 5,6 5,7 @@
#include "BoardDefinitions.hpp"
#include "DriverI2C.hpp"
+#include "DriverGPIO.hpp"
#include "fsl_common.h"
#include "timers.h"
@@ 32,9 33,10 @@ namespace bsp
static constexpr uint8_t HEADSET_DEV_SET_DET_EN = 1 << 5;
static constexpr uint8_t HEADSET_DEV_SET_DEB_1S = 0x06;
- static constexpr uint16_t HEADSET_POLL_INTERVAL_MS = 500;
+ static constexpr uint16_t HEADSET_POLL_INTERVAL_MS = 2500;
static std::shared_ptr<drivers::DriverI2C> i2c;
+ static std::shared_ptr<drivers::DriverGPIO> gpio;
static drivers::I2CAddress i2cAddr = {.deviceAddress = HEADSET_I2C_ADDR, .subAddressSize = 0x01};
static TimerHandle_t timerHandle;
@@ 55,12 57,27 @@ namespace bsp
if (((reg & 0x08) == 0) && (HeadsetInserted == true)) {
HeadsetInserted = false;
LOG_INFO("Headset removed");
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 0);
+
ret = true;
}
if (((reg & 0x08) != 0) && (HeadsetInserted == false)) {
HeadsetInserted = true;
LOG_INFO("Headset inserted");
+
+ if ((reg & 0x01) != 0) {
+ LOG_INFO("Headset 3-pole detected");
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 0);
+ }
+ if ((reg & 0x02) != 0) {
+ LOG_INFO("Headset 4-pole OMTP detected");
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 1);
+ }
+ if ((reg & 0x04) != 0) {
+ LOG_INFO("Headset 4-pole Standard detected");
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 1);
+ }
ret = true;
}
@@ 81,8 98,20 @@ namespace bsp
static_cast<I2CInstances>(BoardDefinitions::HEADSET_I2C),
DriverI2CParams{.baudrate = static_cast<uint32_t>(BoardDefinitions::HEADSET_I2C_BAUDRATE)});
+ gpio = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::MIC_BIAS_DRIVER_GPIO),
+ DriverGPIOParams{});
+
+ gpio->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Output,
+ .irqMode = DriverGPIOPinParams::InterruptMode::NoIntmode,
+ .defLogic = 0,
+ .pin = static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN)});
+
qHandleIrq = qHandle;
+ HeadsetInserted = false;
+
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 0);
+
uint8_t reg =
HEADSET_INT_DIS_INT_ENA | HEADSET_INT_DIS_ADC_ENA | HEADSET_INT_DIS_DC_ENA | HEADSET_INT_DIS_INS_ENA;
i2cAddr.subAddress = HEADSET_INT_DIS_ADDR;
@@ 101,7 130,7 @@ namespace bsp
}
}
- xTimerStart(timerHandle, 0);
+ xTimerStart(timerHandle, HEADSET_POLL_INTERVAL_MS);
return kStatus_Success;
}
@@ 122,10 151,13 @@ namespace bsp
status_t Deinit()
{
- qHandleIrq = nullptr;
+ qHandleIrq = nullptr;
+ HeadsetInserted = false;
i2c.reset();
+ gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 0);
+
return kStatus_Success;
}
} // namespace headset
M module-bsp/board/rt1051/common/board.h => module-bsp/board/rt1051/common/board.h +8 -2
@@ 189,8 189,8 @@
#define BSP_CELLULAR_AP_RDY_PAD GPIO_B1_00
#define BSP_CELLULAR_WAKEUP_PORT GPIO2
-#define BSP_CELLULAR_WAKEUP_PIN 19
-#define BSP_CELLULAR_WAKEUP_PAD GPIO_B1_03
+#define BSP_CELLULAR_WAKEUP_PIN 22
+#define BSP_CELLULAR_WAKEUP_PAD GPIO_B1_06
#define BSP_CELLULAR_SIM_TRAY_INSERTED_PORT GPIO2
#define BSP_CELLULAR_SIM_TRAY_INSERTED_PIN 11
@@ 294,6 294,12 @@
#define BOARD_JACKDET_IRQ_GPIO GPIO2
#define BOARD_JACKDET_IRQ_GPIO_PIN (30U)
+/**
+ * MICROPHONE BIAS DEFINITIONS
+ */
+#define BOARD_MIC_LDO_EN_GPIO GPIO2
+#define BOARD_MIC_LDO_EN_PIN 19
+
#define DMA_MAX_SINGLE_TRANSACTION_PAYLOAD 32767
/**
M module-bsp/board/rt1051/common/pin_mux.c => module-bsp/board/rt1051/common/pin_mux.c +7 -2
@@ 305,7 305,7 @@ void PINMUX_InitBootPins(void)
PINMUX_InitBatteryCharger();
PINMUX_InitALS();
PINMUX_InitPowerSW();
- PINMUX_InitJACKDET();
+ PINMUX_InitHeadset();
PINMUX_InitVibrator();
PINMUX_InitTorch();
PINMUX_InitMagnetometer();
@@ 1381,7 1381,7 @@ void PINMUX_InitBluetoothPins(void)
PAD_CONFIG_HYSTERESIS_DISABLED);
}
-void PINMUX_InitJACKDET(void)
+void PINMUX_InitHeadset(void)
{
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
@@ 1390,6 1390,11 @@ void PINMUX_InitJACKDET(void)
IOMUXC_SetPinConfig(PINMUX_JACKDET_IRQ, /* GPIO_AD_B0_02 PAD functional properties : */
PAD_CONFIG_PULL_UP_100kOhm | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_KEEPER_ENABLED);
+
+ IOMUXC_SetPinMux(PINMUX_MIC_LDO_EN, 1);
+ IOMUXC_SetPinConfig(PINMUX_MIC_LDO_EN,
+ PAD_CONFIG_PULL_UP_22kOhm | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_KEEPER_DISABLED |
+ PAD_CONFIG_DRIVER_STRENGTH_LVL_4 | PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_SPEED_SLOW_50MHz);
}
void PINMUX_InitBatteryCharger(void)
M module-bsp/board/rt1051/common/pin_mux.h => module-bsp/board/rt1051/common/pin_mux.h +3 -2
@@ 183,10 183,11 @@ extern "C"
void PINMUX_InitLEDDRIVER(void);
/**
- * JACK DETECTION PINMUX DEFINITIONS
+ * HEADSET (JACK DETECTION, MIC BIAS) PINMUX DEFINITIONS
*/
#define PINMUX_JACKDET_IRQ IOMUXC_GPIO_B1_14_GPIO2_IO30
- void PINMUX_InitJACKDET(void);
+#define PINMUX_MIC_LDO_EN IOMUXC_GPIO_B1_03_GPIO2_IO19
+ void PINMUX_InitHeadset(void);
/**
* BATTERY CHARGER PINMUX DEFINITIONS
M module-bsp/bsp/audio/bsp_audio.hpp => module-bsp/bsp/audio/bsp_audio.hpp +1 -0
@@ 33,6 33,7 @@ namespace bsp {
HeadphonesMono,
Earspeaker,
Loudspeaker,
+ LoudspeakerMono,
BluetoothA2DP,
BluetoothHSP,
None
M module-services/service-audio/ServiceAudio.cpp => module-services/service-audio/ServiceAudio.cpp +1 -1
@@ 69,7 69,7 @@ sys::ReturnCodes ServiceAudio::InitHandler()
// ROUTING
{dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingBluetoothHSP), "20"},
{dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingEarspeaker), "20"},
- {dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingHeadphones), "20"},
+ {dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingHeadphones), "0"},
{dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingLoudspeaker), "20"},
{dbPath(Setting::Gain, PlaybackType::None, Profile::Type::RoutingHeadphones), "50"},