blob: 90d4d1754b23875cd0c376140201f54ceaee924a [file] [log] [blame]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Generated register constants for pinmux.
// Build date: 2023-11-10T00:20:05.600739
// Original reference file: hw/matcha/hw/top_matcha/ip/pinmux/data/autogen/pinmux.hjson
use kernel::common::registers::ReadWrite;
use kernel::common::registers::{register_bitfields, register_structs};
use kernel::common::StaticRef;
use kernel::ReturnCode;
// Pad attribute data width
pub const PINMUX_PARAM_ATTR_DW: u32 = 13;
// Number of muxed peripheral inputs
pub const PINMUX_PARAM_N_MIO_PERIPH_IN: u32 = 76;
// Number of muxed peripheral outputs
pub const PINMUX_PARAM_N_MIO_PERIPH_OUT: u32 = 89;
// Number of muxed IO pads
pub const PINMUX_PARAM_N_MIO_PADS: u32 = 53;
// Number of dedicated IO pads
pub const PINMUX_PARAM_N_DIO_PADS: u32 = 16;
// Number of wakeup detectors
pub const PINMUX_PARAM_N_WKUP_DETECT: u32 = 8;
// Number of wakeup counter bits
pub const PINMUX_PARAM_WKUP_CNT_WIDTH: u32 = 8;
// Number of alerts
pub const PINMUX_PARAM_NUM_ALERTS: u32 = 1;
// Register width
pub const PINMUX_PARAM_REG_WIDTH: u32 = 32;
pub enum PinmuxLockTarget {
Insel = 0,
Outsel,
MioSleep,
DioSleep,
MioPadAttr,
DioPadAttr,
WakeupDetector,
}
pub const PINMUX_REGISTERS: StaticRef<PinmuxRegisters> =
unsafe { StaticRef::new(matcha_config::PINMUX_BASE_ADDRESS as *const PinmuxRegisters) };
pub static mut PINMUX: PinmuxHw = PinmuxHw::new(PINMUX_REGISTERS);
register_structs! {
pub PinmuxRegisters {
// Alert Test Register
(0x0000 => pub(crate) alert_test: ReadWrite<u32, ALERT_TEST::Register>),
// Register write enable for MIO peripheral input selects.
(0x0004 => pub(crate) mio_periph_insel_regwen: [ReadWrite<u32, MIO_PERIPH_INSEL_REGWEN::Register>; 76]),
// For each peripheral input, this selects the muxable pad input.
(0x0134 => pub(crate) mio_periph_insel: [ReadWrite<u32, MIO_PERIPH_INSEL::Register>; 76]),
// Register write enable for MIO output selects.
(0x0264 => pub(crate) mio_outsel_regwen: [ReadWrite<u32, MIO_OUTSEL_REGWEN::Register>; 53]),
// For each muxable pad, this selects the peripheral output.
(0x0338 => pub(crate) mio_outsel: [ReadWrite<u32, MIO_OUTSEL::Register>; 53]),
// Register write enable for MIO PAD attributes.
(0x040c => pub(crate) mio_pad_attr_regwen: [ReadWrite<u32, MIO_PAD_ATTR_REGWEN::Register>; 53]),
// Muxed pad attributes.
(0x04e0 => pub(crate) mio_pad_attr: [ReadWrite<u32, MIO_PAD_ATTR::Register>; 53]),
// Register write enable for DIO PAD attributes.
(0x05b4 => pub(crate) dio_pad_attr_regwen: [ReadWrite<u32, DIO_PAD_ATTR_REGWEN::Register>; 16]),
// Dedicated pad attributes.
(0x05f4 => pub(crate) dio_pad_attr: [ReadWrite<u32, DIO_PAD_ATTR::Register>; 16]),
// Register indicating whether the corresponding pad is in sleep mode.
(0x0634 => pub(crate) mio_pad_sleep_status: [ReadWrite<u32, MIO_PAD_SLEEP_STATUS::Register>; 2]),
// Register write enable for MIO sleep value configuration.
(0x063c => pub(crate) mio_pad_sleep_regwen: [ReadWrite<u32, MIO_PAD_SLEEP_REGWEN::Register>; 53]),
// Enables the sleep mode of the corresponding muxed pad.
(0x0710 => pub(crate) mio_pad_sleep_en: [ReadWrite<u32, MIO_PAD_SLEEP_EN::Register>; 53]),
// Defines sleep behavior of the corresponding muxed pad.
(0x07e4 => pub(crate) mio_pad_sleep_mode: [ReadWrite<u32, MIO_PAD_SLEEP_MODE::Register>; 53]),
// Register indicating whether the corresponding pad is in sleep mode.
(0x08b8 => pub(crate) dio_pad_sleep_status: [ReadWrite<u32, DIO_PAD_SLEEP_STATUS::Register>; 1]),
// Register write enable for DIO sleep value configuration.
(0x08bc => pub(crate) dio_pad_sleep_regwen: [ReadWrite<u32, DIO_PAD_SLEEP_REGWEN::Register>; 16]),
// Enables the sleep mode of the corresponding dedicated pad.
(0x08fc => pub(crate) dio_pad_sleep_en: [ReadWrite<u32, DIO_PAD_SLEEP_EN::Register>; 16]),
// Defines sleep behavior of the corresponding dedicated pad.
(0x093c => pub(crate) dio_pad_sleep_mode: [ReadWrite<u32, DIO_PAD_SLEEP_MODE::Register>; 16]),
// Register write enable for wakeup detectors.
(0x097c => pub(crate) wkup_detector_regwen: [ReadWrite<u32, WKUP_DETECTOR_REGWEN::Register>; 8]),
// Enables for the wakeup detectors.
(0x099c => pub(crate) wkup_detector_en: [ReadWrite<u32, WKUP_DETECTOR_EN::Register>; 8]),
// Configuration of wakeup condition detectors.
(0x09bc => pub(crate) wkup_detector: [ReadWrite<u32, WKUP_DETECTOR::Register>; 8]),
// Counter thresholds for wakeup condition detectors.
(0x09dc => pub(crate) wkup_detector_cnt_th: [ReadWrite<u32, WKUP_DETECTOR_CNT_TH::Register>; 8]),
// Pad selects for pad wakeup condition detectors.
(0x09fc => pub(crate) wkup_detector_padsel: [ReadWrite<u32, WKUP_DETECTOR_PADSEL::Register>; 8]),
// Cause registers for wakeup detectors.
(0x0a1c => pub(crate) wkup_cause: [ReadWrite<u32, WKUP_CAUSE::Register>; 1]),
(0x0a20 => @END),
}
}
register_bitfields![u32,
pub(crate) ALERT_TEST [
FATAL_FAULT OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_PERIPH_INSEL_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_PERIPH_INSEL [
IN_0 OFFSET(0) NUMBITS(6) []
],
pub(crate) MIO_OUTSEL_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_OUTSEL [
OUT_0 OFFSET(0) NUMBITS(7) []
],
pub(crate) MIO_PAD_ATTR_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_PAD_ATTR [
INVERT_0 OFFSET(0) NUMBITS(1) [],
VIRTUAL_OD_EN_0 OFFSET(1) NUMBITS(1) [],
PULL_EN_0 OFFSET(2) NUMBITS(1) [],
PULL_SELECT_0 OFFSET(3) NUMBITS(1) [
PULL_DOWN = 0,
PULL_UP = 1
],
KEEPER_EN_0 OFFSET(4) NUMBITS(1) [],
SCHMITT_EN_0 OFFSET(5) NUMBITS(1) [],
OD_EN_0 OFFSET(6) NUMBITS(1) [],
SLEW_RATE_0 OFFSET(16) NUMBITS(2) [],
DRIVE_STRENGTH_0 OFFSET(20) NUMBITS(4) []
],
pub(crate) DIO_PAD_ATTR_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) DIO_PAD_ATTR [
INVERT_0 OFFSET(0) NUMBITS(1) [],
VIRTUAL_OD_EN_0 OFFSET(1) NUMBITS(1) [],
PULL_EN_0 OFFSET(2) NUMBITS(1) [],
PULL_SELECT_0 OFFSET(3) NUMBITS(1) [
PULL_DOWN = 0,
PULL_UP = 1
],
KEEPER_EN_0 OFFSET(4) NUMBITS(1) [],
SCHMITT_EN_0 OFFSET(5) NUMBITS(1) [],
OD_EN_0 OFFSET(6) NUMBITS(1) [],
SLEW_RATE_0 OFFSET(16) NUMBITS(2) [],
DRIVE_STRENGTH_0 OFFSET(20) NUMBITS(4) []
],
pub(crate) MIO_PAD_SLEEP_STATUS [
EN_0 OFFSET(0) NUMBITS(1) [],
EN_1 OFFSET(1) NUMBITS(1) [],
EN_2 OFFSET(2) NUMBITS(1) [],
EN_3 OFFSET(3) NUMBITS(1) [],
EN_4 OFFSET(4) NUMBITS(1) [],
EN_5 OFFSET(5) NUMBITS(1) [],
EN_6 OFFSET(6) NUMBITS(1) [],
EN_7 OFFSET(7) NUMBITS(1) [],
EN_8 OFFSET(8) NUMBITS(1) [],
EN_9 OFFSET(9) NUMBITS(1) [],
EN_10 OFFSET(10) NUMBITS(1) [],
EN_11 OFFSET(11) NUMBITS(1) [],
EN_12 OFFSET(12) NUMBITS(1) [],
EN_13 OFFSET(13) NUMBITS(1) [],
EN_14 OFFSET(14) NUMBITS(1) [],
EN_15 OFFSET(15) NUMBITS(1) [],
EN_16 OFFSET(16) NUMBITS(1) [],
EN_17 OFFSET(17) NUMBITS(1) [],
EN_18 OFFSET(18) NUMBITS(1) [],
EN_19 OFFSET(19) NUMBITS(1) [],
EN_20 OFFSET(20) NUMBITS(1) [],
EN_21 OFFSET(21) NUMBITS(1) [],
EN_22 OFFSET(22) NUMBITS(1) [],
EN_23 OFFSET(23) NUMBITS(1) [],
EN_24 OFFSET(24) NUMBITS(1) [],
EN_25 OFFSET(25) NUMBITS(1) [],
EN_26 OFFSET(26) NUMBITS(1) [],
EN_27 OFFSET(27) NUMBITS(1) [],
EN_28 OFFSET(28) NUMBITS(1) [],
EN_29 OFFSET(29) NUMBITS(1) [],
EN_30 OFFSET(30) NUMBITS(1) [],
EN_31 OFFSET(31) NUMBITS(1) []
],
pub(crate) MIO_PAD_SLEEP_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_PAD_SLEEP_EN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) MIO_PAD_SLEEP_MODE [
OUT_0 OFFSET(0) NUMBITS(2) [
TIE_LOW = 0,
TIE_HIGH = 1,
HIGH_Z = 2,
KEEP = 3
]
],
pub(crate) DIO_PAD_SLEEP_STATUS [
EN_0 OFFSET(0) NUMBITS(1) [],
EN_1 OFFSET(1) NUMBITS(1) [],
EN_2 OFFSET(2) NUMBITS(1) [],
EN_3 OFFSET(3) NUMBITS(1) [],
EN_4 OFFSET(4) NUMBITS(1) [],
EN_5 OFFSET(5) NUMBITS(1) [],
EN_6 OFFSET(6) NUMBITS(1) [],
EN_7 OFFSET(7) NUMBITS(1) [],
EN_8 OFFSET(8) NUMBITS(1) [],
EN_9 OFFSET(9) NUMBITS(1) [],
EN_10 OFFSET(10) NUMBITS(1) [],
EN_11 OFFSET(11) NUMBITS(1) [],
EN_12 OFFSET(12) NUMBITS(1) [],
EN_13 OFFSET(13) NUMBITS(1) [],
EN_14 OFFSET(14) NUMBITS(1) [],
EN_15 OFFSET(15) NUMBITS(1) []
],
pub(crate) DIO_PAD_SLEEP_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) DIO_PAD_SLEEP_EN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) DIO_PAD_SLEEP_MODE [
OUT_0 OFFSET(0) NUMBITS(2) [
TIE_LOW = 0,
TIE_HIGH = 1,
HIGH_Z = 2,
KEEP = 3
]
],
pub(crate) WKUP_DETECTOR_REGWEN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) WKUP_DETECTOR_EN [
EN_0 OFFSET(0) NUMBITS(1) []
],
pub(crate) WKUP_DETECTOR [
MODE_0 OFFSET(0) NUMBITS(3) [
POSEDGE = 0,
NEGEDGE = 1,
EDGE = 2,
TIMEDHIGH = 3,
TIMEDLOW = 4
],
FILTER_0 OFFSET(3) NUMBITS(1) [],
MIODIO_0 OFFSET(4) NUMBITS(1) []
],
pub(crate) WKUP_DETECTOR_CNT_TH [
TH_0 OFFSET(0) NUMBITS(8) []
],
pub(crate) WKUP_DETECTOR_PADSEL [
SEL_0 OFFSET(0) NUMBITS(6) []
],
pub(crate) WKUP_CAUSE [
CAUSE_0 OFFSET(0) NUMBITS(1) [],
CAUSE_1 OFFSET(1) NUMBITS(1) [],
CAUSE_2 OFFSET(2) NUMBITS(1) [],
CAUSE_3 OFFSET(3) NUMBITS(1) [],
CAUSE_4 OFFSET(4) NUMBITS(1) [],
CAUSE_5 OFFSET(5) NUMBITS(1) [],
CAUSE_6 OFFSET(6) NUMBITS(1) [],
CAUSE_7 OFFSET(7) NUMBITS(1) []
]
];
// End generated register constants for pinmux
pub trait PinmuxHAL {
fn output_select(&self, pad: u32, peripheral: u32) -> ReturnCode;
fn input_select(&self, peripheral: u32, pad: u32) -> ReturnCode;
}
pub struct PinmuxHw {
registers: StaticRef<PinmuxRegisters>,
}
impl PinmuxHw {
pub const fn new(base: StaticRef<PinmuxRegisters>) -> PinmuxHw {
PinmuxHw {
registers: base
}
}
fn is_locked(&self, pad: u32, target: PinmuxLockTarget) -> bool {
match target {
PinmuxLockTarget::Insel =>
!self.registers.mio_periph_insel_regwen[pad as usize]
.is_set(MIO_PERIPH_INSEL_REGWEN::EN_0),
PinmuxLockTarget::Outsel =>
!self.registers.mio_outsel_regwen[pad as usize]
.is_set(MIO_OUTSEL_REGWEN::EN_0),
PinmuxLockTarget::MioSleep =>
!self.registers.mio_pad_sleep_regwen[pad as usize]
.is_set(MIO_PAD_SLEEP_REGWEN::EN_0),
PinmuxLockTarget::DioSleep =>
!self.registers.dio_pad_sleep_regwen[pad as usize]
.is_set(DIO_PAD_SLEEP_REGWEN::EN_0),
PinmuxLockTarget::MioPadAttr =>
!self.registers.mio_pad_attr_regwen[pad as usize]
.is_set(MIO_PAD_ATTR_REGWEN::EN_0),
PinmuxLockTarget::DioPadAttr =>
!self.registers.dio_pad_attr_regwen[pad as usize]
.is_set(DIO_PAD_ATTR_REGWEN::EN_0),
PinmuxLockTarget::WakeupDetector =>
!self.registers.wkup_detector_regwen[pad as usize]
.is_set(WKUP_DETECTOR_REGWEN::EN_0),
}
}
}
impl PinmuxHAL for PinmuxHw {
fn output_select(&self, pad: u32, peripheral: u32) -> ReturnCode {
if pad >= PINMUX_PARAM_N_MIO_PADS ||
peripheral >= (3 + PINMUX_PARAM_N_MIO_PERIPH_OUT) {
return ReturnCode::EINVAL;
}
if self.is_locked(pad, PinmuxLockTarget::Outsel) {
return ReturnCode::EINVAL;
}
self.registers.mio_outsel[pad as usize]
.modify(MIO_OUTSEL::OUT_0.val(peripheral));
ReturnCode::SUCCESS
}
fn input_select(&self, peripheral: u32, pad: u32) -> ReturnCode {
if peripheral >= PINMUX_PARAM_N_MIO_PERIPH_IN ||
pad >= (2 + PINMUX_PARAM_N_MIO_PADS) {
return ReturnCode::EINVAL;
}
if self.is_locked(peripheral, PinmuxLockTarget::Insel) {
return ReturnCode::EINVAL;
}
self.registers.mio_periph_insel[peripheral as usize]
.modify(MIO_PERIPH_INSEL::IN_0.val(pad));
ReturnCode::SUCCESS
}
}