use super::*;
#[derive(Default, Debug)]
pub struct GoPhase24ClkProtocol;
impl MediaClockFrequencyOperation for GoPhase24ClkProtocol {
const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000, 192000];
}
const CLK_SRC_FB_ID: u8 = 0x04;
impl SamplingClockSourceOperation for GoPhase24ClkProtocol {
const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
subunit: MUSIC_SUBUNIT_0,
plug_id: 0x04,
});
const SRC_LIST: &'static [SignalAddr] = &[
SignalAddr::Subunit(SignalSubunitAddr {
subunit: MUSIC_SUBUNIT_0,
plug_id: 0x03,
}),
SignalAddr::Unit(SignalUnitAddr::Ext(0x01)),
];
fn cache_src(
avc: &BebobAvc,
params: &mut SamplingClockParameters,
timeout_ms: u32,
) -> Result<(), Error> {
let mut op = AudioSelector::new(CLK_SRC_FB_ID, CtlAttr::Current, 0xff);
avc.status(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)
.map(|_| params.src_idx = op.input_plug_id as usize)
}
fn update_src(
avc: &BebobAvc,
params: &SamplingClockParameters,
old: &mut SamplingClockParameters,
timeout_ms: u32,
) -> Result<(), Error> {
let mut op = AudioSelector::new(CLK_SRC_FB_ID, CtlAttr::Current, params.src_idx as u8);
avc.control(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)
.map(|_| *old = *params)
}
}
pub struct GoPhase24CoaxPhysInputProtocol;
const INPUT_NOMINAL_LEVEL_FB_ID: u8 = 0x02;
const INPUT_NOMINAL_LEVELS: [i16; 3] = [0xf400u16 as i16, 0xfd00u16 as i16, 0x0000u16 as i16];
impl AvcSelectorOperation for GoPhase24CoaxPhysInputProtocol {
const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x00];
const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01, 0x02];
fn cache_selectors(
avc: &BebobAvc,
params: &mut AvcSelectorParameters,
timeout_ms: u32,
) -> Result<(), Error> {
assert_eq!(params.selectors.len(), 1);
let mut op = AudioFeature::new(
INPUT_NOMINAL_LEVEL_FB_ID,
CtlAttr::Current,
AudioCh::Master,
FeatureCtl::Volume(VolumeData::new(1)),
);
avc.status(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)?;
if let FeatureCtl::Volume(data) = op.ctl {
INPUT_NOMINAL_LEVELS
.iter()
.position(|l| *l == data.0[0])
.ok_or_else(|| {
let msg = format!(
"Unexpected value for value of nominal level: 0x{:04x}",
data.0[0]
);
Error::new(FileError::Io, &msg)
})
.map(|pos| params.selectors[0] = pos)
} else {
Ok(())
}
}
fn update_selectors(
avc: &BebobAvc,
params: &AvcSelectorParameters,
old: &mut AvcSelectorParameters,
timeout_ms: u32,
) -> Result<(), Error> {
assert_eq!(params.selectors.len(), 1);
assert_eq!(old.selectors.len(), 1);
if old.selectors[0] != params.selectors[0] {
let val = INPUT_NOMINAL_LEVELS
.iter()
.nth(old.selectors[0])
.ok_or_else(|| {
let msg = format!(
"Invalid argument for index of nominal level: {}",
old.selectors[0]
);
Error::new(FileError::Inval, &msg)
})
.copied()?;
let mut op = AudioFeature::new(
INPUT_NOMINAL_LEVEL_FB_ID,
CtlAttr::Current,
AudioCh::Master,
FeatureCtl::Volume(VolumeData(vec![val])),
);
avc.control(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)
.map(|_| {
old.selectors[0] = params.selectors[0];
})
} else {
Ok(())
}
}
}
pub struct GoPhase24CoaxPhysOutputProtocol;
impl AvcSelectorOperation for GoPhase24CoaxPhysOutputProtocol {
const FUNC_BLOCK_ID_LIST: &'static [u8] = &[
0x01, 0x03, ];
const INPUT_PLUG_ID_LIST: &'static [u8] = &[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, ];
}
#[derive(Default, Debug)]
pub struct GoPhase24OptPhysOutputProtocol;
impl AvcAudioFeatureSpecification for GoPhase24OptPhysOutputProtocol {
const ENTRIES: &'static [(u8, AudioCh)] = &[
(0x01, AudioCh::Each(0)), (0x01, AudioCh::Each(1)), (0x01, AudioCh::Each(2)), (0x01, AudioCh::Each(3)), ];
}
impl AvcLevelOperation for GoPhase24OptPhysOutputProtocol {}
impl AvcMuteOperation for GoPhase24OptPhysOutputProtocol {}
impl AvcSelectorOperation for GoPhase24OptPhysOutputProtocol {
const FUNC_BLOCK_ID_LIST: &'static [u8] = &[
0x01, 0x02, 0x03, ];
const INPUT_PLUG_ID_LIST: &'static [u8] = &[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, ];
}
pub struct GoPhase24CoaxHeadphoneProtocol;
impl AvcSelectorOperation for GoPhase24CoaxHeadphoneProtocol {
const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x02];
const INPUT_PLUG_ID_LIST: &'static [u8] = &[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, ];
}
#[derive(Default, Debug)]
pub struct GoPhase24MixerSourceProtocol;
impl AvcAudioFeatureSpecification for GoPhase24MixerSourceProtocol {
const ENTRIES: &'static [(u8, AudioCh)] = &[
(0x06, AudioCh::Each(0)), (0x06, AudioCh::Each(1)), (0x07, AudioCh::Each(0)), (0x07, AudioCh::Each(1)), (0x03, AudioCh::Each(0)), (0x03, AudioCh::Each(1)), (0x04, AudioCh::Each(0)), (0x04, AudioCh::Each(1)), (0x05, AudioCh::Each(0)), (0x05, AudioCh::Each(1)), ];
}
impl AvcLevelOperation for GoPhase24MixerSourceProtocol {}
impl AvcMuteOperation for GoPhase24MixerSourceProtocol {}
#[derive(Default, Debug)]
pub struct GoPhase24CoaxMixerOutputProtocol;
impl AvcAudioFeatureSpecification for GoPhase24CoaxMixerOutputProtocol {
const ENTRIES: &'static [(u8, AudioCh)] = &[(0x01, AudioCh::Each(0)), (0x01, AudioCh::Each(1))];
}
impl AvcLevelOperation for GoPhase24CoaxMixerOutputProtocol {}
impl AvcMuteOperation for GoPhase24CoaxMixerOutputProtocol {}
#[derive(Default, Debug)]
pub struct GoPhase24OptMixerOutputProtocol;
impl AvcAudioFeatureSpecification for GoPhase24OptMixerOutputProtocol {
const ENTRIES: &'static [(u8, AudioCh)] = &[(0x02, AudioCh::Each(0)), (0x02, AudioCh::Each(1))];
}
impl AvcLevelOperation for GoPhase24OptMixerOutputProtocol {}
impl AvcMuteOperation for GoPhase24OptMixerOutputProtocol {}