diff options
author | Maxim Polyakov <max.senia.poliak@gmail.com> | 2020-04-26 22:12:01 +0300 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2020-07-28 22:06:02 +0000 |
commit | 82ec61e9d7a39a11c9b8ed68eb90bd29905439bc (patch) | |
tree | ff68be99e8bf9d92c4adfbadd457c317a2414418 /util/intelp2m/platforms/common | |
parent | 8079c5c1c2b76ebd01cfcddcef4b5398ee860403 (diff) |
util/intelp2m: Add Intel Pad to Macro utility
This patch adds a new utility for converting a pad configuration from
the inteltool dump to the PAD_CFG_*() macros [1] for coreboot and GPIO
config data structures for FSP/sdk2-platforms/slimbootloader [2,3].
Mirror: https://github.com/maxpoliak/pch-pads-parser.git
[1] src/soc/intel/common/block/include/intelblocks/gpio_defs.h
[2] https://slimbootloader.github.io/tools/index.html#gpio-tool
[3] 3rdparty/fsp/CometLakeFspBinPkg/CometLake1/Include/GpioSampleDef.h
Change-Id: If3e3b523c4f63dc2f91e9ccd16934e3a1b6e21fa
Signed-off-by: Maxim Polyakov <max.senia.poliak@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35643
Reviewed-by: Andrey Petrov <andrey.petrov@gmail.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'util/intelp2m/platforms/common')
-rw-r--r-- | util/intelp2m/platforms/common/macro.go | 417 | ||||
-rw-r--r-- | util/intelp2m/platforms/common/register.go | 262 |
2 files changed, 679 insertions, 0 deletions
diff --git a/util/intelp2m/platforms/common/macro.go b/util/intelp2m/platforms/common/macro.go new file mode 100644 index 0000000000..e30ef225fe --- /dev/null +++ b/util/intelp2m/platforms/common/macro.go @@ -0,0 +1,417 @@ +package common + +import "strconv" +import "sync" + +import "../../config" + +type Fields interface { + DecodeDW0() + DecodeDW1() + GenerateString() +} + +const ( + PAD_OWN_ACPI = 0 + PAD_OWN_DRIVER = 1 +) + +const ( + TxLASTRxE = 0x0 + Tx0RxDCRx0 = 0x1 + Tx0RxDCRx1 = 0x2 + Tx1RxDCRx0 = 0x3 + Tx1RxDCRx1 = 0x4 + Tx0RxE = 0x5 + Tx1RxE = 0x6 + HIZCRx0 = 0x7 + HIZCRx1 = 0x8 + TxDRxE = 0x9 + StandbyIgnore = 0xf +) + +const ( + IOSTERM_SAME = 0x0 + IOSTERM_DISPUPD = 0x1 + IOSTERM_ENPD = 0x2 + IOSTERM_ENPU = 0x3 +) + +const ( + TRIG_LEVEL = 0 + TRIG_EDGE_SINGLE = 1 + TRIG_OFF = 2 + TRIG_EDGE_BOTH = 3 +) + +const ( + RST_PWROK = 0 + RST_DEEP = 1 + RST_PLTRST = 2 + RST_RSMRST = 3 +) + +// PlatformSpecific - platform-specific interface +type PlatformSpecific interface { + RemmapRstSrc() + Pull() + GpiMacroAdd() + GpoMacroAdd() + NativeFunctionMacroAdd() + NoConnMacroAdd() +} + +// Macro - contains macro information and methods +// Platform : platform-specific interface +// padID : pad ID string +// str : macro string entirely +// Reg : structure of configuration register values and their masks +type Macro struct { + Platform PlatformSpecific + Reg [MAX_DW_NUM]Register + padID string + str string + ownership uint8 + Fields +} + +var instanceMacro *Macro +var once sync.Once + +// GetInstance returns singleton +func GetInstanceMacro(p PlatformSpecific, f Fields) *Macro { + once.Do(func() { + instanceMacro = &Macro{ Platform : p, Fields : f } + }) + return instanceMacro +} + +func GetMacro() *Macro { + return GetInstanceMacro(nil, nil) +} + +func (macro *Macro) PadIdGet() string { + return macro.padID +} + +func (macro *Macro) PadIdSet(padid string) *Macro { + macro.padID = padid + return macro +} + +func (macro *Macro) SetPadOwnership(own uint8) *Macro { + macro.ownership = own + return macro +} + +func (macro *Macro) IsOwnershipDriver() bool { + return macro.ownership == PAD_OWN_DRIVER +} + +// returns <Register> data configuration structure +// number : register number +func (macro *Macro) Register(number uint8) *Register { + return ¯o.Reg[number] +} + +// add a string to macro +func (macro *Macro) Add(str string) *Macro { + macro.str += str + return macro +} + +// set a string in a macro instead of its previous contents +func (macro *Macro) Set(str string) *Macro { + macro.str = str + return macro +} + +// get macro string +func (macro *Macro) Get() string { + return macro.str +} + +// set a string in a macro instead of its previous contents +func (macro *Macro) Clear() *Macro { + macro.Set("") + return macro +} + +// Adds PAD Id to the macro as a new argument +// return: Macro +func (macro *Macro) Id() *Macro { + return macro.Add(macro.padID) +} + +// Add Separator to macro if needed +func (macro *Macro) Separator() *Macro { + str := macro.Get() + c := str[len(str)-1] + if c != '(' && c != '_' { + macro.Add(", ") + } + return macro +} + +// Adds the PADRSTCFG parameter from DW0 to the macro as a new argument +// return: Macro +func (macro *Macro) Rstsrc() *Macro { + dw0 := macro.Register(PAD_CFG_DW0) + var resetsrc = map[uint8]string { + 0: "PWROK", + 1: "DEEP", + 2: "PLTRST", + 3: "RSMRST", + } + return macro.Separator().Add(resetsrc[dw0.GetResetConfig()]) +} + +// Adds The Pad Termination (TERM) parameter from DW1 to the macro as a new argument +// return: Macro +func (macro *Macro) Pull() *Macro { + macro.Platform.Pull() + return macro +} + +// Adds Pad GPO value to macro string as a new argument +// return: Macro +func (macro *Macro) Val() *Macro { + dw0 := macro.Register(PAD_CFG_DW0) + return macro.Separator().Add(strconv.Itoa(int(dw0.GetGPIOTXState()))) +} + +// Adds Pad GPO value to macro string as a new argument +// return: Macro +func (macro *Macro) Trig() *Macro { + dw0 := macro.Register(PAD_CFG_DW0) + var trig = map[uint8]string{ + 0x0: "LEVEL", + 0x1: "EDGE_SINGLE", + 0x2: "OFF", + 0x3: "EDGE_BOTH", + } + return macro.Separator().Add(trig[dw0.GetRXLevelEdgeConfiguration()]) +} + +// Adds Pad Polarity Inversion Stage (RXINV) to macro string as a new argument +// return: Macro +func (macro *Macro) Invert() *Macro { + macro.Separator() + if macro.Register(PAD_CFG_DW0).GetRxInvert() !=0 { + return macro.Add("INVERT") + } + return macro.Add("NONE") +} + +// Adds input/output buffer state +// return: Macro +func (macro *Macro) Bufdis() *Macro { + var buffDisStat = map[uint8]string{ + 0x0: "NO_DISABLE", // both buffers are enabled + 0x1: "TX_DISABLE", // output buffer is disabled + 0x2: "RX_DISABLE", // input buffer is disabled + 0x3: "TX_RX_DISABLE", // both buffers are disabled + } + state := macro.Register(PAD_CFG_DW0).GetGPIORxTxDisableStatus() + return macro.Separator().Add(buffDisStat[state]) +} + +// Adds macro to set the host software ownership +// return: Macro +func (macro *Macro) Own() *Macro { + if macro.IsOwnershipDriver() { + return macro.Separator().Add("DRIVER") + } + return macro.Separator().Add("ACPI") +} + +//Adds pad native function (PMODE) as a new argument +//return: Macro +func (macro *Macro) Padfn() *Macro { + dw0 := macro.Register(PAD_CFG_DW0) + nfnum := int(dw0.GetPadMode()) + if nfnum != 0 { + return macro.Separator().Add("NF" + strconv.Itoa(nfnum)) + } + // GPIO used only for PAD_FUNC(x) macro + return macro.Add("GPIO") +} + +// Add a line to the macro that defines IO Standby State +// return: macro +func (macro *Macro) IOSstate() *Macro { + var stateMacro = map[uint8]string{ + TxLASTRxE: "TxLASTRxE", + Tx0RxDCRx0: "Tx0RxDCRx0", + Tx0RxDCRx1: "Tx0RxDCRx1", + Tx1RxDCRx0: "Tx1RxDCRx0", + Tx1RxDCRx1: "Tx1RxDCRx1", + Tx0RxE: "Tx0RxE", + Tx1RxE: "Tx1RxE", + HIZCRx0: "HIZCRx0", + HIZCRx1: "HIZCRx1", + TxDRxE: "TxDRxE", + StandbyIgnore: "IGNORE", + } + dw1 := macro.Register(PAD_CFG_DW1) + str, valid := stateMacro[dw1.GetIOStandbyState()] + if !valid { + // ignore setting for incorrect value + str = "IGNORE" + } + return macro.Separator().Add(str) +} + +// Add a line to the macro that defines IO Standby Termination +// return: macro +func (macro *Macro) IOTerm() *Macro { + var ioTermMacro = map[uint8]string{ + IOSTERM_SAME: "SAME", + IOSTERM_DISPUPD: "DISPUPD", + IOSTERM_ENPD: "ENPD", + IOSTERM_ENPU: "ENPU", + } + dw1 := macro.Register(PAD_CFG_DW1) + return macro.Separator().Add(ioTermMacro[dw1.GetIOStandbyTermination()]) +} + +// Check created macro +func (macro *Macro) check() *Macro { + if !macro.Register(PAD_CFG_DW0).MaskCheck() { + return macro.GenerateFields() + } + return macro +} + +// or - Set " | " if its needed +func (macro *Macro) Or() *Macro { + + if str := macro.Get(); str[len(str) - 1] == ')' { + macro.Add(" | ") + } + return macro +} + +// AddToMacroIgnoredMask - Print info about ignored field mask +// title - warning message +func (macro *Macro) AddToMacroIgnoredMask() *Macro { + if config.InfoLevelGet() < 4 || config.IsFspStyleMacro() { + return macro + } + dw0 := macro.Register(PAD_CFG_DW0) + dw1 := macro.Register(PAD_CFG_DW1) + // Get mask of ignored bit fields. + dw0Ignored := dw0.IgnoredFieldsGet() + dw1Ignored := dw1.IgnoredFieldsGet() + if dw0Ignored != 0 { + dw0temp := dw0.ValueGet() + dw0.ValueSet(dw0Ignored) + macro.Add("\n\t/* DW0 : ") + macro.Fields.DecodeDW0() + macro.Add(" - IGNORED */") + dw0.ValueSet(dw0temp) + } + if dw1Ignored != 0 { + dw1temp := dw1.ValueGet() + dw1.ValueSet(dw1Ignored) + macro.Add("\n\t/* DW1 : ") + macro.Fields.DecodeDW1() + macro.Add(" - IGNORED */") + dw1.ValueSet(dw1temp) + } + return macro +} + +// GenerateFields - generate bitfield macros +func (macro *Macro) GenerateFields() *Macro { + dw0 := macro.Register(PAD_CFG_DW0) + dw1 := macro.Register(PAD_CFG_DW1) + + // Get mask of ignored bit fields. + dw0Ignored := dw0.IgnoredFieldsGet() + dw1Ignored := dw1.IgnoredFieldsGet() + + if config.InfoLevelGet() <= 1 { + macro.Clear() + } else if config.InfoLevelGet() >= 3 { + // Add string of reference macro as a comment + reference := macro.Get() + macro.Clear() + macro.Add("/* ").Add(reference).Add(" */") + macro.AddToMacroIgnoredMask() + macro.Add("\n\t") + } + if config.AreFieldsIgnored() { + // Consider bit fields that should be ignored when regenerating + // advansed macros + var tempVal uint32 = dw0.ValueGet() & ^dw0Ignored + dw0.ValueSet(tempVal) + + tempVal = dw1.ValueGet() & ^dw1Ignored + dw1.ValueSet(tempVal) + } + + macro.Fields.GenerateString() + return macro +} + +// Generate macro for bi-directional GPIO port +func (macro *Macro) Bidirection() { + dw1 := macro.Register(PAD_CFG_DW1) + ios := dw1.GetIOStandbyState() != 0 || dw1.GetIOStandbyTermination() != 0 + macro.Set("PAD_CFG_GPIO_BIDIRECT") + if ios { + macro.Add("_IOS") + } + // PAD_CFG_GPIO_BIDIRECT(pad, val, pull, rst, trig, own) + macro.Add("(").Id().Val().Pull().Rstsrc().Trig() + if ios { + // PAD_CFG_GPIO_BIDIRECT_IOS(pad, val, pull, rst, trig, iosstate, iosterm, own) + macro.IOSstate().IOTerm() + } + macro.Own().Add("),") +} + +const ( + rxDisable uint8 = 0x2 + txDisable uint8 = 0x1 +) + +// Gets base string of current macro +// return: string of macro +func (macro *Macro) Generate() string { + dw0 := macro.Register(PAD_CFG_DW0) + + macro.Platform.RemmapRstSrc() + macro.Set("PAD_CFG") + if dw0.GetPadMode() == 0 { + // GPIO + switch dw0.GetGPIORxTxDisableStatus() { + case txDisable: + macro.Platform.GpiMacroAdd() // GPI + + case rxDisable: + macro.Platform.GpoMacroAdd() // GPO + + case rxDisable | txDisable: + macro.Platform.NoConnMacroAdd() // NC + + default: + macro.Bidirection() + } + } else { + macro.Platform.NativeFunctionMacroAdd() + } + + if config.IsFieldsMacroUsed() { + // Clear control mask to generate advanced macro only + return macro.GenerateFields().Get() + } + + if config.IsNonCheckingFlagUsed() { + macro.AddToMacroIgnoredMask() + return macro.Get() + } + + return macro.check().Get() +} diff --git a/util/intelp2m/platforms/common/register.go b/util/intelp2m/platforms/common/register.go new file mode 100644 index 0000000000..2aa51b92e9 --- /dev/null +++ b/util/intelp2m/platforms/common/register.go @@ -0,0 +1,262 @@ +package common + +// Bit field constants for PAD_CFG_DW0 register +const ( + AllFields uint32 = 0xffffffff + + PadRstCfgShift uint8 = 30 + PadRstCfgMask uint32 = 0x3 << PadRstCfgShift + + RxPadStateSelectShift uint8 = 29 + RxPadStateSelectMask uint32 = 0x1 << RxPadStateSelectShift + + RxRawOverrideTo1Shift uint8 = 28 + RxRawOverrideTo1Mask uint32 = 0x1 << RxRawOverrideTo1Shift + + RxLevelEdgeConfigurationShift uint8 = 25 + RxLevelEdgeConfigurationMask uint32 = 0x3 << RxLevelEdgeConfigurationShift + + RxInvertShift uint8 = 23 + RxInvertMask uint32 = 0x1 << RxInvertShift + + RxTxEnableConfigShift uint8 = 21 + RxTxEnableConfigMask uint32 = 0x3 << RxTxEnableConfigShift + + InputRouteIOxApicShift uint8 = 20 + InputRouteIOxApicMask uint32 = 0x1 << InputRouteIOxApicShift + + InputRouteSCIShift uint8 = 19 + InputRouteSCIMask uint32 = 0x1 << InputRouteSCIShift + + InputRouteSMIShift uint8 = 18 + InputRouteSMIMask uint32 = 0x1 << InputRouteSMIShift + + InputRouteNMIShift uint8 = 17 + InputRouteNMIMask uint32 = 0x1 << InputRouteNMIShift + + PadModeShift uint8 = 10 + PadModeMask uint32 = 0x7 << PadModeShift + + RxTxBufDisableShift uint8 = 8 + RxTxBufDisableMask uint32 = 0x3 << RxTxBufDisableShift + + RxStateShift uint8 = 1 + RxStateMask uint32 = 0x1 << RxStateShift + + TxStateMask uint32 = 0x1 +) + +// config DW registers +const ( + PAD_CFG_DW0 = 0 + PAD_CFG_DW1 = 1 + MAX_DW_NUM = 2 +) + +// Register - configuration data structure based on DW0/1 dw value +// value : register value +// mask : bit fileds mask +// roFileds : read only fields mask +type Register struct { + value uint32 + mask uint32 + roFileds uint32 +} + +func (reg *Register) ValueSet(value uint32) *Register { + reg.value = value + return reg +} + +func (reg *Register) ValueGet() uint32 { + return reg.value +} + +func (reg *Register) ReadOnlyFieldsSet(fileldMask uint32) *Register { + reg.roFileds = fileldMask + return reg +} + +func (reg *Register) ReadOnlyFieldsGet() uint32 { + return reg.roFileds +} + +// Check the mask of the new macro +// Returns true if the macro is generated correctly +func (reg *Register) MaskCheck() bool { + mask := ^(reg.mask | reg.roFileds) + return reg.value&mask == 0 +} + +// getResetConfig - get Reset Configuration from PADRSTCFG field in PAD_CFG_DW0_GPx register +func (reg *Register) getFieldVal(mask uint32, shift uint8) uint8 { + reg.mask |= mask + return uint8((reg.value & mask) >> shift) +} + +// CntrMaskFieldsClear - clear filed in control mask +// fieldMask - mask of the field to be cleared +func (reg *Register) CntrMaskFieldsClear(fieldMask uint32) { + reg.mask &= ^fieldMask; +} + +// IgnoredFieldsGet - return mask of unchecked (ignored) fields. +// These bit fields were not read when the macro was +// generated. +// return +// mask of ignored bit field +func (reg *Register) IgnoredFieldsGet() uint32 { + mask := reg.mask | reg.roFileds + return reg.value & ^mask +} + +// getResetConfig - returns type reset source for corresponding pad +// PADRSTCFG field in PAD_CFG_DW0 register +func (reg *Register) GetResetConfig() uint8 { + return reg.getFieldVal(PadRstCfgMask, PadRstCfgShift) +} + +// getRXPadStateSelect - returns RX Pad State (RXINV) +// 0 = Raw RX pad state directly from RX buffer +// 1 = Internal RX pad state +func (reg *Register) GetRXPadStateSelect() uint8 { + return reg.getFieldVal(RxPadStateSelectMask, RxPadStateSelectShift) +} + +// getRXRawOverrideStatus - returns 1 if the selected pad state is being +// overridden to '1' (RXRAW1 field) +func (reg *Register) GetRXRawOverrideStatus() uint8 { + return reg.getFieldVal(RxRawOverrideTo1Mask, RxRawOverrideTo1Shift) +} + +// getRXLevelEdgeConfiguration - returns RX Level/Edge Configuration (RXEVCFG) +// 0h = Level, 1h = Edge, 2h = Drive '0', 3h = Reserved (implement as setting 0h) +func (reg *Register) GetRXLevelEdgeConfiguration() uint8 { + return reg.getFieldVal(RxLevelEdgeConfigurationMask, RxLevelEdgeConfigurationShift) +} + +// GetRxInvert - returns RX Invert state (RXINV) +// 1 - Inversion, 0 - No inversion +func (reg *Register) GetRxInvert() uint8 { + return reg.getFieldVal(RxInvertMask, RxInvertShift) +} + +// getRxTxEnableConfig - returns RX/TX Enable Config (RXTXENCFG) +// 0 = Function defined in Pad Mode controls TX and RX Enables +// 1 = Function controls TX Enable and RX Disabled with RX drive 0 internally +// 2 = Function controls TX Enable and RX Disabled with RX drive 1 internally +// 3 = Function controls TX Enabled and RX is always enabled +func (reg *Register) GetRxTxEnableConfig() uint8 { + return reg.getFieldVal(RxTxEnableConfigMask, RxTxEnableConfigShift) +} + +// getGPIOInputRouteIOxAPIC - returns 1 if the pad can be routed to cause +// peripheral IRQ when configured in GPIO input mode. +func (reg *Register) GetGPIOInputRouteIOxAPIC() uint8 { + return reg.getFieldVal(InputRouteIOxApicMask, InputRouteIOxApicShift) +} + +// getGPIOInputRouteSCI - returns 1 if the pad can be routed to cause SCI when +// configured in GPIO input mode. +func (reg *Register) GetGPIOInputRouteSCI() uint8 { + return reg.getFieldVal(InputRouteSCIMask, InputRouteSCIShift) +} + +// getGPIOInputRouteSMI - returns 1 if the pad can be routed to cause SMI when +// configured in GPIO input mode +func (reg *Register) GetGPIOInputRouteSMI() uint8 { + return reg.getFieldVal(InputRouteSMIMask, InputRouteSMIShift) +} + +// getGPIOInputRouteNMI - returns 1 if the pad can be routed to cause NMI when +// configured in GPIO input mode +func (reg *Register) GetGPIOInputRouteNMI() uint8 { + return reg.getFieldVal(InputRouteNMIMask, InputRouteNMIShift) +} + +// getPadMode - reutrns pad mode or one of the native functions +// 0h = GPIO control the Pad. +// 1h = native function 1, if applicable, controls the Pad +// 2h = native function 2, if applicable, controls the Pad +// 3h = native function 3, if applicable, controls the Pad +// 4h = enable GPIO blink/PWM capability if applicable +func (reg *Register) GetPadMode() uint8 { + return reg.getFieldVal(PadModeMask, PadModeShift) +} + +// getGPIORxTxDisableStatus - returns GPIO RX/TX buffer state (GPIORXDIS | GPIOTXDIS) +// 0 - both are enabled, 1 - TX Disable, 2 - RX Disable, 3 - both are disabled +func (reg *Register) GetGPIORxTxDisableStatus() uint8 { + return reg.getFieldVal(RxTxBufDisableMask, RxTxBufDisableShift) +} + +// getGPIORXState - returns GPIO RX State (GPIORXSTATE) +func (reg *Register) GetGPIORXState() uint8 { + return reg.getFieldVal(RxStateMask, RxStateShift) +} + +// getGPIOTXState - returns GPIO TX State (GPIOTXSTATE) +func (reg *Register) GetGPIOTXState() uint8 { + return reg.getFieldVal(TxStateMask, 0) +} + +// Bit field constants for PAD_CFG_DW1 register +const ( + PadTolShift uint8 = 25 + PadTolMask uint32 = 0x1 << PadTolShift + + IOStandbyStateShift uint8 = 14 + IOStandbyStateMask uint32 = 0xF << IOStandbyStateShift + + TermShift uint8 = 10 + TermMask uint32 = 0xF << TermShift + + IOStandbyTerminationShift uint8 = 8 + IOStandbyTerminationMask uint32 = 0x3 << IOStandbyTerminationShift + + InterruptSelectMask uint32 = 0xFF +) + +// GetPadTol +func (reg *Register) GetPadTol() uint8 { + return reg.getFieldVal(PadTolMask, PadTolShift) +} + +// getIOStandbyState - return IO Standby State (IOSSTATE) +// 0 = Tx enabled driving last value driven, Rx enabled +// 1 = Tx enabled driving 0, Rx disabled and Rx driving 0 back to its controller internally +// 2 = Tx enabled driving 0, Rx disabled and Rx driving 1 back to its controller internally +// 3 = Tx enabled driving 1, Rx disabled and Rx driving 0 back to its controller internally +// 4 = Tx enabled driving 1, Rx disabled and Rx driving 1 back to its controller internally +// 5 = Tx enabled driving 0, Rx enabled +// 6 = Tx enabled driving 1, Rx enabled +// 7 = Hi-Z, Rx driving 0 back to its controller internally +// 8 = Hi-Z, Rx driving 1 back to its controller internally +// 9 = Tx disabled, Rx enabled +// 15 = IO-Standby is ignored for this pin (same as functional mode) +// Others reserved +func (reg *Register) GetIOStandbyState() uint8 { + return reg.getFieldVal(IOStandbyStateMask, IOStandbyStateShift) +} + +// getIOStandbyTermination - return IO Standby Termination (IOSTERM) +// 0 = Same as functional mode (no change) +// 1 = Disable Pull-up and Pull-down (no on-die termination) +// 2 = Enable Pull-down +// 3 = Enable Pull-up +func (reg *Register) GetIOStandbyTermination() uint8 { + return reg.getFieldVal(IOStandbyTerminationMask, IOStandbyTerminationShift) +} + +// getTermination - returns the pad termination state defines the different weak +// pull-up and pull-down settings that are supported by the buffer +// 0000 = none; 0010 = 5k PD; 0100 = 20k PD; 1010 = 5k PU; 1100 = 20k PU; +// 1111 = Native controller selected +func (reg *Register) GetTermination() uint8 { + return reg.getFieldVal(TermMask, TermShift) +} + +// getInterruptSelect - returns Interrupt Line number from the GPIO controller +func (reg *Register) GetInterruptSelect() uint8 { + return reg.getFieldVal(InterruptSelectMask, 0) +} |