| // 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 |
| } |
| } |