Skip to content

Commit 04f700a

Browse files
committed
add headphone state polling to codec
1 parent 474a02c commit 04f700a

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

services/codec/src/api.rs

+11
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,21 @@ pub(crate) enum Opcode {
4444
/// set headphone volume -- L&R channels are ganged together in this API, but codec can do separately
4545
SetHeadphoneVolume,
4646

47+
/// get headphone type code
48+
GetHeadphoneCode,
49+
4750
/// Suspend/resume callback
4851
SuspendResume,
4952
}
5053

54+
#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive)]
55+
pub enum HeadphoneState {
56+
NotPresent = 0,
57+
PresentWithMic = 1,
58+
PresentWithoutMic = 2,
59+
Reserved = 3,
60+
CodecOff = 4,
61+
}
5162

5263
#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive)]
5364
pub enum VolumeOps {

services/codec/src/backend/tlv320aic3100.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@ impl Codec {
310310
pub fn get_headset_code(&mut self) -> u8 {
311311
self.w(0, &[0]);
312312
let mut code: [u8; 1] = [0; 1];
313-
self.r(67, &mut code);
313+
if !self.r(67, &mut code) {
314+
log::warn!("headset code read unsuccessful");
315+
};
314316
code[0]
315317
}
316318

services/codec/src/lib.rs

+14
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,20 @@ impl Codec {
142142
_ => Err(xous::Error::InternalError)
143143
}
144144
}
145+
pub fn poll_headphone_state(&self) -> Result<HeadphoneState, xous::Error> {
146+
match send_message(self.conn,
147+
Message::new_blocking_scalar(Opcode::GetHeadphoneCode.to_usize().unwrap(), 0, 0, 0, 0)
148+
) {
149+
Ok(xous::Result::Scalar1(code)) => {
150+
let retcode: Option<HeadphoneState> = FromPrimitive::from_usize(code);
151+
match retcode {
152+
Some(code) => Ok(code),
153+
None => Err(xous::Error::InternalError),
154+
}
155+
}
156+
_ => Err(xous::Error::InternalError)
157+
}
158+
}
145159
}
146160

147161
use core::sync::atomic::{AtomicU32, Ordering};

services/codec/src/main.rs

+23
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,29 @@ fn main() -> ! {
218218
};
219219
codec.set_headphone_gain_db(headphone_analog_gain_db, headphone_analog_gain_db);
220220
}),
221+
Some(api::Opcode::GetHeadphoneCode) => xous::msg_blocking_scalar_unpack!(msg, _, _, _, _, {
222+
if codec.is_init() && codec.is_on() {
223+
let hp_code = codec.get_headset_code();
224+
if hp_code & 0x80 != 0x80 {
225+
log::warn!("Headphone detection polled, but detection is not enabled in hardware!");
226+
}
227+
log::debug!("headset code: 0x{:x}", hp_code);
228+
let code = if hp_code == 0xff { // kind of a hack, we could also check codec power state
229+
HeadphoneState::CodecOff
230+
} else {
231+
match (hp_code >> 5) & 0x3 {
232+
0b00 => HeadphoneState::NotPresent,
233+
0b01 => HeadphoneState::PresentWithoutMic,
234+
0b10 => HeadphoneState::Reserved,
235+
0b11 => HeadphoneState::PresentWithMic,
236+
_ => HeadphoneState::Reserved,
237+
}
238+
};
239+
xous::return_scalar(msg.sender, code as usize).ok();
240+
} else {
241+
xous::return_scalar(msg.sender, HeadphoneState::CodecOff as usize).ok();
242+
}
243+
}),
221244
None => {
222245
log::error!("couldn't convert opcode");
223246
break

0 commit comments

Comments
 (0)