forked from Bananymous/banan-os
Kernel: Add mixer support to IHDA
This has not been tested as I don't have any hardware with mixers on output paths :P
This commit is contained in:
@@ -65,6 +65,7 @@ namespace Kernel::HDAudio
|
||||
};
|
||||
|
||||
BAN::Optional<Amplifier> output_amplifier;
|
||||
BAN::Optional<Amplifier> input_amplifier;
|
||||
|
||||
BAN::Vector<uint16_t> connections;
|
||||
};
|
||||
|
||||
@@ -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<uint8_t>(volume & 0xFF),
|
||||
.command = static_cast<uint16_t>(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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user