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> output_amplifier;
|
||||||
|
BAN::Optional<Amplifier> input_amplifier;
|
||||||
|
|
||||||
BAN::Vector<uint16_t> connections;
|
BAN::Vector<uint16_t> connections;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -342,6 +342,7 @@ namespace Kernel
|
|||||||
{
|
{
|
||||||
using HDAudio::AFGWidget;
|
using HDAudio::AFGWidget;
|
||||||
case AFGWidget::Type::OutputConverter:
|
case AFGWidget::Type::OutputConverter:
|
||||||
|
case AFGWidget::Type::Mixer:
|
||||||
case AFGWidget::Type::PinComplex:
|
case AFGWidget::Type::PinComplex:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -363,7 +364,7 @@ namespace Kernel
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// set connection index
|
// 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;
|
uint8_t index = 0;
|
||||||
for (; index < path[i]->connections.size(); index++)
|
for (; index < path[i]->connections.size(); index++)
|
||||||
@@ -419,6 +420,25 @@ namespace Kernel
|
|||||||
}));
|
}));
|
||||||
break;
|
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:
|
case AFGWidget::Type::PinComplex:
|
||||||
// enable output and H-Phn
|
// enable output and H-Phn
|
||||||
TRY(m_controller->send_command({
|
TRY(m_controller->send_command({
|
||||||
@@ -504,6 +524,7 @@ namespace Kernel
|
|||||||
using HDAudio::AFGWidget;
|
using HDAudio::AFGWidget;
|
||||||
|
|
||||||
case AFGWidget::Type::OutputConverter:
|
case AFGWidget::Type::OutputConverter:
|
||||||
|
case AFGWidget::Type::Mixer:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFGWidget::Type::PinComplex:
|
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 connection_info = send_command_or_zero(0xF00, 0x0E);
|
||||||
const uint8_t conn_width = (connection_info & 0x80) ? 2 : 1;
|
const uint8_t conn_width = (connection_info & 0x80) ? 2 : 1;
|
||||||
const uint8_t conn_count = connection_info & 0x3F;
|
const uint8_t conn_count = connection_info & 0x3F;
|
||||||
|
|||||||
Reference in New Issue
Block a user