diff --git a/kernel/include/kernel/Audio/HDAudio/Definitions.h b/kernel/include/kernel/Audio/HDAudio/Definitions.h index 4a7932f2..d465fecb 100644 --- a/kernel/include/kernel/Audio/HDAudio/Definitions.h +++ b/kernel/include/kernel/Audio/HDAudio/Definitions.h @@ -65,6 +65,7 @@ namespace Kernel::HDAudio }; BAN::Optional output_amplifier; + BAN::Optional input_amplifier; BAN::Vector connections; }; diff --git a/kernel/kernel/Audio/HDAudio/AudioFunctionGroup.cpp b/kernel/kernel/Audio/HDAudio/AudioFunctionGroup.cpp index 5180a3d8..cfa99157 100644 --- a/kernel/kernel/Audio/HDAudio/AudioFunctionGroup.cpp +++ b/kernel/kernel/Audio/HDAudio/AudioFunctionGroup.cpp @@ -342,6 +342,7 @@ namespace Kernel { using HDAudio::AFGWidget; case AFGWidget::Type::OutputConverter: + case AFGWidget::Type::Mixer: case AFGWidget::Type::PinComplex: break; default: @@ -363,7 +364,7 @@ namespace Kernel })); // set connection index - if (i + 1 < path.size() && path[i]->connections.size() > 1) + if (i + 1 < path.size() && path[i]->connections.size() > 1 && path[i]->type != HDAudio::AFGWidget::Type::Mixer) { uint8_t index = 0; for (; index < path[i]->connections.size(); index++) @@ -419,6 +420,25 @@ namespace Kernel })); break; + case AFGWidget::Type::Mixer: + if (path[i]->input_amplifier.has_value()) + { + for (size_t idx = 0; idx < path[i]->connections.size(); idx++) + { + const uint8_t step = (path[i]->connections[idx] == path[i + 1]->id) + ? path[i]->input_amplifier->offset + : 0b1'0000000; + const uint32_t volume = 0b0'1'1'1'0000'0'0000000 | (idx << 8) | step; + TRY(m_controller->send_command({ + .data = static_cast(volume & 0xFF), + .command = static_cast(0x300 | (volume >> 8)), + .node_index = path[i]->id, + .codec_address = m_cid, + })); + } + } + break; + case AFGWidget::Type::PinComplex: // enable output and H-Phn TRY(m_controller->send_command({ @@ -504,6 +524,7 @@ namespace Kernel using HDAudio::AFGWidget; case AFGWidget::Type::OutputConverter: + case AFGWidget::Type::Mixer: break; case AFGWidget::Type::PinComplex: diff --git a/kernel/kernel/Audio/HDAudio/Controller.cpp b/kernel/kernel/Audio/HDAudio/Controller.cpp index 4395d1b0..f51f9ff3 100644 --- a/kernel/kernel/Audio/HDAudio/Controller.cpp +++ b/kernel/kernel/Audio/HDAudio/Controller.cpp @@ -333,6 +333,20 @@ namespace Kernel }; } + if (const uint32_t in_amp_cap = send_command_or_zero(0xF00, 0x0D)) + { + const uint8_t offset = (in_amp_cap >> 0) & 0x7F; + const uint8_t num_steps = (in_amp_cap >> 8) & 0x7F; + const uint8_t step_size = (in_amp_cap >> 16) & 0x7F; + const bool mute = (in_amp_cap >> 31); + result.input_amplifier = HDAudio::AFGWidget::Amplifier { + .offset = offset, + .num_steps = num_steps, + .step_size = step_size, + .mute = mute, + }; + } + const uint8_t connection_info = send_command_or_zero(0xF00, 0x0E); const uint8_t conn_width = (connection_info & 0x80) ? 2 : 1; const uint8_t conn_count = connection_info & 0x3F;