start at TLV320AIC2354 driver
This commit is contained in:
commit
03d37ac9b4
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
65
Cargo.lock
generated
Normal file
65
Cargo.lock
generated
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "TLV320AIC2354"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"with_builtin_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "with_builtin_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24deb3cd6e530e7617b12b1f0f1ce160a3a71d92feb351c4db5156d1d10e398a"
|
||||||
|
dependencies = [
|
||||||
|
"with_builtin_macros-proc_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "with_builtin_macros-proc_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2259ae9b1285596f1ee52ce8f627013c65853d4d7f271cb10bfe2d048769804a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "TLV320AIC2354"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
with_builtin_macros = "0.1.0"
|
||||||
8
src/lib.rs
Normal file
8
src/lib.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mod registers;
|
||||||
|
|
||||||
|
fn i2c_read(page: u16, reg: u16) -> Result<u16, _>{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
fn i2c_write(page: u16, reg: u16, value: u16) -> Result<(), _>{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
642
src/registers.rs
Normal file
642
src/registers.rs
Normal file
@ -0,0 +1,642 @@
|
|||||||
|
mod regs {
|
||||||
|
use with_builtin_macros::with_builtin;
|
||||||
|
|
||||||
|
trait RegisterRW {
|
||||||
|
const PAGE: u8;
|
||||||
|
const REG: u8;
|
||||||
|
|
||||||
|
fn get_reg(&self) -> u8;
|
||||||
|
fn set_reg(&mut self, value: u8);
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
println!("load reg {} from page {}", Self::REG, Self::PAGE);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
fn store(&mut self) {
|
||||||
|
println!("store reg {} from page {}", Self::REG, Self::PAGE);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trait RegisterRO {
|
||||||
|
const PAGE: u8;
|
||||||
|
const REG: u8;
|
||||||
|
|
||||||
|
fn get_reg(&self) -> u8;
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
println!("load reg {} from page {}", Self::REG, Self::PAGE);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trait RegisterWO {
|
||||||
|
const PAGE: u8;
|
||||||
|
const REG: u8;
|
||||||
|
|
||||||
|
fn set_reg(&mut self, value: u8);
|
||||||
|
|
||||||
|
fn store(&mut self) {
|
||||||
|
println!("store reg {} from page {}", Self::REG, Self::PAGE);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! register_rw {
|
||||||
|
($name:ident, $page:expr, $reg:expr) => {
|
||||||
|
struct $name {
|
||||||
|
value: u8,
|
||||||
|
changed: bool
|
||||||
|
}
|
||||||
|
impl RegisterRW for $name {
|
||||||
|
const PAGE: u8 = $page;
|
||||||
|
const REG: u8 = $reg;
|
||||||
|
|
||||||
|
fn get_reg(&self) -> u8 {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
fn set_reg(&mut self, value: u8) {
|
||||||
|
if self.value != value {
|
||||||
|
self.changed = true;
|
||||||
|
}
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
self.changed = false;
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
fn store(&mut self) {
|
||||||
|
self.changed = false;
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! register_ro {
|
||||||
|
($name:ident, $page:expr, $reg:expr) => {
|
||||||
|
struct $name {
|
||||||
|
value: u8,
|
||||||
|
}
|
||||||
|
impl RegisterRO for $name {
|
||||||
|
const PAGE: u8 = $page;
|
||||||
|
const REG: u8 = $reg;
|
||||||
|
|
||||||
|
fn get_reg(&self) -> u8 {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! register_wo {
|
||||||
|
($name:ident, $page:expr, $reg:expr) => {
|
||||||
|
struct $name {
|
||||||
|
value: u8,
|
||||||
|
changed: bool
|
||||||
|
}
|
||||||
|
impl RegisterWO for $name {
|
||||||
|
const PAGE: u8 = $page;
|
||||||
|
const REG: u8 = $reg;
|
||||||
|
|
||||||
|
fn set_reg(&mut self, value: u8) {
|
||||||
|
self.changed = true;
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&mut self) {
|
||||||
|
self.changed = false;
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bitmask_rw {
|
||||||
|
($name:ident, $mask:expr, $shift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(get_, $name) in {
|
||||||
|
fn $fname (&mut self, $name: u8) {
|
||||||
|
self.value = (($name << $shift) & $mask) | (self.value & !$mask);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
with_builtin!(let $fname = concat_idents!(set_, $name) in {
|
||||||
|
fn $fname (&mut self) -> u8 {
|
||||||
|
(self.value & $mask) >> $shift
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! bitmask_ro {
|
||||||
|
($name:ident, $mask:expr, $shrift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(get_, $name) in {
|
||||||
|
fn $fname (&mut self, $name: u8) {
|
||||||
|
self.value = (($name << $shift) & $mask) | (self.value & !$mask);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! bitmask_wo {
|
||||||
|
($name:ident, $mask:expr, $shrift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(set_, $name) in {
|
||||||
|
fn $fname (&mut self) -> u8 {
|
||||||
|
(self.value & $mask) >> $shift
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! back_to_enum {
|
||||||
|
($(#[$meta:meta])* $vis:vis enum $name:ident {
|
||||||
|
$($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)*
|
||||||
|
}) => {
|
||||||
|
$(#[$meta])*
|
||||||
|
$vis enum $name {
|
||||||
|
$($(#[$vmeta])* $vname $(= $val)?,)*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<u8> for $name {
|
||||||
|
type Error = u8;
|
||||||
|
|
||||||
|
fn try_from(v: u8) -> Result<Self, Self::Error> {
|
||||||
|
match v {
|
||||||
|
$(x if x == $name::$vname as u8 => Ok($name::$vname),)*
|
||||||
|
_ => Err(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bitmask_enum_rw {
|
||||||
|
($name:ident, $mask:expr, $shift:expr, $enum:ident) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(get_, $name) in {
|
||||||
|
fn $fname (&mut self, value: $enum) {
|
||||||
|
self.value = (((value as u8) << $shift) & $mask) | (self.value & !$mask);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
with_builtin!(let $fname = concat_idents!(set_, $name) in {
|
||||||
|
fn $fname (&mut self) -> Result<$enum, u8> {
|
||||||
|
$enum::try_from((self.value & $mask) >> $shift)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bit_rw {
|
||||||
|
($name:ident, $shift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(get_, $name) in {
|
||||||
|
fn $fname (&mut self, $name: bool) {
|
||||||
|
let bit: u8 = 0b1 << $shift;
|
||||||
|
if $name {
|
||||||
|
self.value &= bit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.value |= !bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
with_builtin!(let $fname = concat_idents!(set_, $name) in {
|
||||||
|
fn $fname (&mut self) -> bool {
|
||||||
|
(self.value >> $shift) & 0b1 == 0b1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! bit_ro {
|
||||||
|
($name:ident, $shift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(get_, $name) in {
|
||||||
|
fn $fname (&mut self, $name: bool) {
|
||||||
|
let bit: u8 = 0b1 << $shift;
|
||||||
|
if $name {
|
||||||
|
self.value &= bit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.value |= !bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! bit_wo {
|
||||||
|
($name:ident, $shift:expr) => {
|
||||||
|
with_builtin!(let $fname = concat_idents!(set_, $name) in {
|
||||||
|
fn $fname (&mut self) -> bool {
|
||||||
|
(self.value >> $shift) & 0b1 == 0b1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
register_rw!(PSEL, 0, 0);
|
||||||
|
|
||||||
|
register_wo!(RESET, 0, 1);
|
||||||
|
impl RESET {
|
||||||
|
bit_wo!(software_reset, 0);
|
||||||
|
}
|
||||||
|
register_ro!(CLKMUX, 0, 4);
|
||||||
|
impl CLKMUX {
|
||||||
|
bitmask_enum_rw!(pllrange, 0b0100_0000, 6, ClkMuxPllrange);
|
||||||
|
bitmask_enum_rw!(pll_clock_in, 0b0000_1100, 2, ClkMuxPllClockIn);
|
||||||
|
bitmask_enum_rw!(codec_clock_in, 0b0000_0011, 0, ClkMuxCodecClockIn);
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum ClkMuxPllrange {
|
||||||
|
LowClockRange = 0b0,
|
||||||
|
HighClockRange = 0b1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum ClkMuxPllClockIn {
|
||||||
|
MCLK = 0x0,
|
||||||
|
BCLK = 0x1,
|
||||||
|
GPIO = 0x2,
|
||||||
|
DIN = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum ClkMuxCodecClockIn {
|
||||||
|
MCLK = 0x0,
|
||||||
|
BCLK = 0x1,
|
||||||
|
GPIO = 0x2,
|
||||||
|
PLL = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_rw!(PLLPR, 0, 4);
|
||||||
|
impl PLLPR {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 8, n if not 0 -> n
|
||||||
|
bitmask_rw!(p, 0b0111_0000, 4);
|
||||||
|
// 0 -> don't use, n if in range(1..=4) -> n, n if >= 5 -> don't use
|
||||||
|
bitmask_rw!(r, 0b0000_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(PLLJ, 0, 6);
|
||||||
|
impl PLLJ {
|
||||||
|
// n if in range(0..=3) -> don't use, n if in range(4..=63) -> n
|
||||||
|
bitmask_rw!(j, 0b0011_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(PLLDMSB, 0, 7);
|
||||||
|
register_rw!(PLLDLSB, 0, 8);
|
||||||
|
struct PLLD {
|
||||||
|
regs: (PLLDMSB, PLLDLSB),
|
||||||
|
}
|
||||||
|
impl PLLD {
|
||||||
|
fn get_reg(&self) -> u16 {
|
||||||
|
((self.regs.1.value as u16) << 8) | (self.regs.0.value as u16)
|
||||||
|
}
|
||||||
|
fn set_reg(&mut self, value: u16) {
|
||||||
|
self.regs.0.value = (value & 0xFF) as u8;
|
||||||
|
self.regs.1.value = ((value >> 8) & 0xFF) as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
self.regs.1.load();
|
||||||
|
self.regs.0.load();
|
||||||
|
}
|
||||||
|
fn store(&mut self) {
|
||||||
|
self.regs.1.store();
|
||||||
|
self.regs.0.store();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PLLD {
|
||||||
|
// n if in range(0..=9999) -> n
|
||||||
|
fn get_d(&self) -> u16 {
|
||||||
|
self.get_reg() & 0x7FFF
|
||||||
|
}
|
||||||
|
// n if in range(0..=9999) -> n
|
||||||
|
fn set_d(&mut self, value: u16) {
|
||||||
|
self.set_reg(value & 0x7FFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(NDAC, 0, 11);
|
||||||
|
impl NDAC {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 128, n if in range(1..=127) -> n
|
||||||
|
bitmask_rw!(ndac, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(MDAC, 0, 12);
|
||||||
|
impl MDAC {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 128, n if in range(1..=127) -> n
|
||||||
|
bitmask_rw!(mdac, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(DOSRMSB, 0, 13);
|
||||||
|
register_rw!(DOSRLSB, 0, 14);
|
||||||
|
struct DOSR {
|
||||||
|
regs: (DOSRMSB, DOSRLSB),
|
||||||
|
}
|
||||||
|
impl DOSR {
|
||||||
|
fn get_reg(&self) -> u16 {
|
||||||
|
((self.regs.1.value as u16) << 8) | (self.regs.0.value as u16)
|
||||||
|
}
|
||||||
|
fn set_reg(&mut self, value: u16) {
|
||||||
|
self.regs.0.value = (value & 0xFF) as u8;
|
||||||
|
self.regs.1.value = ((value >> 8) & 0xFF) as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(&mut self) {
|
||||||
|
self.regs.1.load();
|
||||||
|
self.regs.0.load();
|
||||||
|
}
|
||||||
|
fn store(&mut self) {
|
||||||
|
self.regs.1.store();
|
||||||
|
self.regs.0.store();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl DOSR {
|
||||||
|
// 0 -> 1024, n if in range(1..=1023) -> n
|
||||||
|
fn get_osr(&self) -> u16 {
|
||||||
|
self.get_reg() & 0x7FFF
|
||||||
|
}
|
||||||
|
// 0 -> 1024, n if in range(1..=1023) -> n
|
||||||
|
fn set_osr(&mut self, value: u16) {
|
||||||
|
self.set_reg(value & 0x3FFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(DSPDIDEC1, 0, 15);
|
||||||
|
register_rw!(DSPDIDEC2, 0, 16);
|
||||||
|
register_rw!(DSPDINTERP, 0, 17);
|
||||||
|
register_rw!(NADC, 0, 18);
|
||||||
|
impl NADC {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 128, n if in range(1..=127) -> n
|
||||||
|
bitmask_rw!(nadc, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(MADC, 0, 19);
|
||||||
|
impl MADC {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 128, n if in range(1..=127) -> n
|
||||||
|
bitmask_rw!(nadc, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
// 0 -> 256, n if in range(1..=255) -> n
|
||||||
|
register_rw!(AOSR, 0, 20);
|
||||||
|
register_rw!(DSPAIDEC1, 0, 21);
|
||||||
|
register_rw!(DSPAIDEC2, 0, 22);
|
||||||
|
register_rw!(DSPADECIMATION, 0, 23);
|
||||||
|
register_rw!(CLKMUX2, 0, 25);
|
||||||
|
impl CLKMUX2 {
|
||||||
|
bitmask_enum_rw!(clkin, 0b0000_0111, 0, ClkMux2Clock);
|
||||||
|
}
|
||||||
|
back_to_enum!{
|
||||||
|
pub enum ClkMux2Clock {
|
||||||
|
MClk = 0b000,
|
||||||
|
BClk = 0b001,
|
||||||
|
DIn = 0b010,
|
||||||
|
PLLClk = 0b011,
|
||||||
|
DACClk = 0b100,
|
||||||
|
DACModClk = 0b101,
|
||||||
|
ADCClk = 0b110,
|
||||||
|
ADCModClk = 0b111,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(CLKOUTM, 0, 26);
|
||||||
|
impl CLKOUTM {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
// 0 -> 128, n if in range(1..=127) -> n
|
||||||
|
bitmask_rw!(m, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(IFACE1, 0, 27);
|
||||||
|
impl IFACE1 {
|
||||||
|
bitmask_enum_rw!(datatype, 0b1100_0000, 6, IfaceDatetype);
|
||||||
|
bitmask_enum_rw!(datalen, 0b0011_0000, 4, IfaceWordlen);
|
||||||
|
bitmask_enum_rw!(wclk_dir, 0b1<<3, 3, IfaceClkDir);
|
||||||
|
bitmask_enum_rw!(bclk_dir, 0b1<<2, 2, IfaceClkDir);
|
||||||
|
bitmask_enum_rw!(dout_inpedance, 0b1, 0, IfaceInpedance);
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceDatetype {
|
||||||
|
I2s = 0x0,
|
||||||
|
DSP = 0x1,
|
||||||
|
RightJustified = 0x2,
|
||||||
|
LeftJustified = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceWordlen {
|
||||||
|
B16 = 0x0,
|
||||||
|
B20 = 0x1,
|
||||||
|
B24 = 0x2,
|
||||||
|
B32 = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceClkDir {
|
||||||
|
Input = 0x0,
|
||||||
|
Output = 0x1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceInpedance {
|
||||||
|
High = 0x0,
|
||||||
|
Low = 0x1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(IFACE2, 0, 28);
|
||||||
|
impl IFACE2 {
|
||||||
|
// n if in range(0..=255) -> n
|
||||||
|
bitmask_rw!(data_offset, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(IFACE3, 0, 29);
|
||||||
|
impl IFACE3 {
|
||||||
|
bit_rw!(data_loopback_enable, 5);
|
||||||
|
bit_rw!(analog_loopback_enable, 4);
|
||||||
|
bit_rw!(bclk_invert, 3);
|
||||||
|
bit_rw!(bclk_wclk_pwr_ctrl, 2);
|
||||||
|
bitmask_enum_rw!(bdiv_in_mux, 0b0000_0011, 0, IfaceBDivInMux);
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceBDivInMux {
|
||||||
|
DacClk = 0x0,
|
||||||
|
DacModClk = 0x1,
|
||||||
|
AdcClk = 0x2,
|
||||||
|
AdcModClk = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(BCLKN, 0, 30);
|
||||||
|
impl BCLKN {
|
||||||
|
bit_rw!(enable, 7);
|
||||||
|
bitmask_rw!(n, 0b0111_1111, 0);
|
||||||
|
}
|
||||||
|
register_rw!(IFACE4, 0, 31);
|
||||||
|
impl IFACE4 {
|
||||||
|
bitmask_enum_rw!(secd_bclk_mux, 0b0110_0000, 5, IfaceSecdClkMux);
|
||||||
|
bitmask_enum_rw!(secd_wclk_mux, 0b0001_1000, 5, IfaceSecdClkMux);
|
||||||
|
bitmask_enum_rw!(adc_wclk_mux, 0b0000_0110, 5, IfaceAdcWClkInMux);
|
||||||
|
bitmask_enum_rw!(data_in_mux, 0b0000_0001, 5, IfaceSecdDInMux);
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceSecdClkMux {
|
||||||
|
GPIO = 0x0,
|
||||||
|
SClk = 0x1,
|
||||||
|
MISO = 0x2,
|
||||||
|
DOut = 0x3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceAdcWClkInMux {
|
||||||
|
GPIO = 0x0,
|
||||||
|
SClk = 0x1,
|
||||||
|
MISO = 0x2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceSecdDInMux {
|
||||||
|
GPIO = 0x0,
|
||||||
|
SClk = 0x1,
|
||||||
|
MISO = 0x2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(IFACE5, 0, 32);
|
||||||
|
impl IFACE5 {
|
||||||
|
bitmask_enum_rw!(audioif_bclk, 0b0000_1000, 3, IfaceAudioIfClk);
|
||||||
|
bitmask_enum_rw!(audioif_wclk, 0b0000_0100, 2, IfaceAudioIfClk);
|
||||||
|
bitmask_enum_rw!(adc_wclk, 0b0000_0010, 1, IfaceAudioIfAdcWClk);
|
||||||
|
bitmask_enum_rw!(din, 0b0000_0001, 0, IfaceAudioIfClk);
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceAudioIfClk {
|
||||||
|
Primary = 0x0,
|
||||||
|
Secondary = 0x1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back_to_enum! {
|
||||||
|
pub enum IfaceAudioIfAdcWClk {
|
||||||
|
DacWClk = 0x0,
|
||||||
|
Secondary = 0x1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
register_rw!(IFACE6, 0, 33);
|
||||||
|
impl IFACE6 {
|
||||||
|
bit_rw!(bclk_output_ctrl, 7);
|
||||||
|
bit_rw!(secd_bclk_output_ctrl, 6);
|
||||||
|
bitmask_rw!(wclk_output_ctrl, 0b0011_0000, 4);
|
||||||
|
bitmask_rw!(secd_wclk_output_ctrl, 0b0000_1100, 2);
|
||||||
|
bit_rw!(prim_data_output_ctrl, 1);
|
||||||
|
bit_rw!(secd_data_output_ctrl, 0);
|
||||||
|
}
|
||||||
|
register_rw!(GPIOCTL, 0, 52);
|
||||||
|
register_rw!(DOUTCTL, 0, 53);
|
||||||
|
register_rw!(DINCTL, 0, 54);
|
||||||
|
register_rw!(MISOCTL, 0, 55);
|
||||||
|
register_rw!(SCLKCTL, 0, 56);
|
||||||
|
register_rw!(DACSPB, 0, 60);
|
||||||
|
register_rw!(ADCSPB, 0, 61);
|
||||||
|
register_rw!(DACSETUP, 0, 63);
|
||||||
|
impl DACSETUP {
|
||||||
|
bitmask_rw!(dac_channel, 0b0011_1100, 2);
|
||||||
|
bit_rw!(ldac2r_enable, 5);
|
||||||
|
bit_rw!(ldac2l_enable, 4);
|
||||||
|
bit_rw!(rdac2l_enable, 3);
|
||||||
|
bit_rw!(rdac2r_enable, 2);
|
||||||
|
}
|
||||||
|
register_rw!(DACMUTE, 0, 64);
|
||||||
|
impl DACMUTE {
|
||||||
|
bitmask_rw!(mute, 0b0000_1100, 2);
|
||||||
|
}
|
||||||
|
register_rw!(LDACVOL, 0, 65);
|
||||||
|
register_rw!(RDACVOL, 0, 66);
|
||||||
|
register_rw!(ADCSETUP, 0, 81);
|
||||||
|
impl ADCSETUP {
|
||||||
|
bitmask_rw!(dac_channel, 0b0110_0000, 6);
|
||||||
|
bit_rw!(ladc_enable, 7);
|
||||||
|
bit_rw!(radc_enable, 6);
|
||||||
|
}
|
||||||
|
register_rw!(ADCFGA, 0, 82);
|
||||||
|
register_rw!(LADCVOL, 0, 83);
|
||||||
|
register_rw!(RADCVOL, 0, 84);
|
||||||
|
register_rw!(LAGC1, 0, 86);
|
||||||
|
register_rw!(LAGC2, 0, 87);
|
||||||
|
register_rw!(LAGC3, 0, 88);
|
||||||
|
register_rw!(LAGC4, 0, 89);
|
||||||
|
register_rw!(LAGC5, 0, 90);
|
||||||
|
register_rw!(LAGC6, 0, 91);
|
||||||
|
register_rw!(LAGC7, 0, 92);
|
||||||
|
register_rw!(RAGC1, 0, 94);
|
||||||
|
register_rw!(RAGC2, 0, 95);
|
||||||
|
register_rw!(RAGC3, 0, 96);
|
||||||
|
register_rw!(RAGC4, 0, 97);
|
||||||
|
register_rw!(RAGC5, 0, 98);
|
||||||
|
register_rw!(RAGC6, 0, 99);
|
||||||
|
register_rw!(RAGC7, 0, 100);
|
||||||
|
register_rw!(PWRCFG, 1, 1);
|
||||||
|
impl PWRCFG {
|
||||||
|
bit_rw!(avdd_weak_disable, 3);
|
||||||
|
}
|
||||||
|
register_rw!(LDOCTL, 1, 2);
|
||||||
|
impl LDOCTL {
|
||||||
|
bit_rw!(enable, 0);
|
||||||
|
}
|
||||||
|
register_rw!(LPLAYBACK, 1, 3);
|
||||||
|
register_rw!(RPLAYBACK, 1, 4);
|
||||||
|
register_rw!(OUTPWRCTL, 1, 9);
|
||||||
|
register_rw!(CMMODE, 1, 10);
|
||||||
|
impl CMMODE {
|
||||||
|
bit_rw!(ldoin_to_hpvdd, 1);
|
||||||
|
bit_rw!(ldoin_18_36, 0);
|
||||||
|
}
|
||||||
|
register_rw!(HPLROUTE, 1, 12);
|
||||||
|
register_rw!(HPRROUTE, 1, 13);
|
||||||
|
register_rw!(LOLROUTE, 1, 14);
|
||||||
|
register_rw!(LORROUTE, 1, 15);
|
||||||
|
register_rw!(HPLGAIN, 1, 16);
|
||||||
|
register_rw!(HPRGAIN, 1, 17);
|
||||||
|
register_rw!(LOLGAIN, 1, 18);
|
||||||
|
register_rw!(LORGAIN, 1, 19);
|
||||||
|
register_rw!(HEADSTART, 1, 20);
|
||||||
|
register_rw!(SPK, 1, 45);
|
||||||
|
register_rw!(SPKVOL1, 1, 46);
|
||||||
|
register_rw!(SPKVOL2, 1, 48);
|
||||||
|
register_rw!(MICBIAS, 1, 51);
|
||||||
|
impl MICBIAS {
|
||||||
|
bitmask_rw!(bias, 0b0111_1000, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Micbias {
|
||||||
|
LDOIN = 0b001,
|
||||||
|
V2075 = 0b110
|
||||||
|
}
|
||||||
|
|
||||||
|
register_rw!(LMICPGAPIN, 1, 52);
|
||||||
|
register_rw!(LMICPGANIN, 1, 54);
|
||||||
|
impl LMICPGANIN {
|
||||||
|
bit_rw!(in2r_10k, 4);
|
||||||
|
bit_rw!(cm1l_10k, 6);
|
||||||
|
}
|
||||||
|
register_rw!(RMICPGAPIN, 1, 55);
|
||||||
|
register_rw!(RMICPGANIN, 1, 57);
|
||||||
|
impl RMICPGANIN {
|
||||||
|
bit_rw!(in1l_10k, 4);
|
||||||
|
bit_rw!(cm1r_10k, 6);
|
||||||
|
}
|
||||||
|
register_rw!(FLOATINGINP, 1, 58);
|
||||||
|
register_rw!(LMICPGAVOL, 1, 59);
|
||||||
|
register_rw!(RMICPGAVOL, 1, 60);
|
||||||
|
// register_rw!(REFPOWERUP, 1, 122); // TAS2505
|
||||||
|
register_rw!(REFPOWERUP, 1, 123);
|
||||||
|
impl REFPOWERUP {
|
||||||
|
bitmask_rw!(speed, 0b1111_0000, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AIC32X4_REFPOWERUP */
|
||||||
|
pub enum RefPowerup {
|
||||||
|
RefSlow = 0x04,
|
||||||
|
Ref40ms = 0x05,
|
||||||
|
Ref80ms = 0x06,
|
||||||
|
Ref120ms = 0x07,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bits, masks, and shifts */
|
||||||
|
|
||||||
|
/* Common mask and enable for all of the dividers */
|
||||||
|
static mut AIC32X4_DIVEN: u8 = 0x01 << 7; // BIT(7)
|
||||||
|
static mut AIC32X4_DIV_MASK: u8 = 0b0111_1111; // GENMASK(6, 0)
|
||||||
|
static mut AIC32X4_DIV_MAX: u8 = 128;
|
||||||
|
|
||||||
|
/* Clock Limits */
|
||||||
|
static mut AIC32X4_MAX_DOSR_FREQ: u32 = 6200000;
|
||||||
|
static mut AIC32X4_MIN_DOSR_FREQ: u32 = 2800000;
|
||||||
|
static mut AIC32X4_MAX_CODEC_CLKIN_FREQ: u32 = 110000000;
|
||||||
|
static mut AIC32X4_MAX_PLL_CLKIN: u32 = 20000000;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user