From eace166aa1ef265712798d84f10782f7bc430be7 Mon Sep 17 00:00:00 2001 From: Mike Baiocchi Date: Thu, 12 Sep 2019 11:12:10 -0500 Subject: [PATCH] Support GPIO Physical Presence Detect Devices This commit makes the necessary changes to support the GPIO devices used for physical presence detection: - New attribute GPIO_INFO_PHYS_PRES - Enable GPIO Device Driver by default - GPIO Device Driver updated to support new device type - Added new GPIO PCA9551 layer to sit on top of GPIO Device Driver Change-Id: I952007503eb5d9fe873adea2eaaeccff21ae18a6 RTC:211220 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/84655 Reviewed-by: Ilya Smirnov Reviewed-by: Christopher J Engel Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Nicholas E Bofferding --- src/include/usr/gpio/gpioddreasoncodes.H | 10 +- src/include/usr/gpio/gpioif.H | 121 +++++- src/usr/gpio/HBconfig | 2 +- src/usr/gpio/gpio_pca9551.C | 343 ++++++++++++++++++ src/usr/gpio/gpiodd.C | 57 ++- src/usr/gpio/makefile | 4 +- .../common/xmltohb/attribute_types_hb.xml | 72 ++++ .../common/xmltohb/target_types_hb.xml | 3 + 8 files changed, 592 insertions(+), 20 deletions(-) create mode 100644 src/usr/gpio/gpio_pca9551.C diff --git a/src/include/usr/gpio/gpioddreasoncodes.H b/src/include/usr/gpio/gpioddreasoncodes.H index 20ad10002e5..d794ff47056 100644 --- a/src/include/usr/gpio/gpioddreasoncodes.H +++ b/src/include/usr/gpio/gpioddreasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -40,10 +40,13 @@ namespace GPIO GPIO_READ = 0x01, GPIO_WRITE = 0x02, GPIO_READATTRIBUTES = 0x03, + + // Use 0x10-0x1F range for PCA9551 functions + GPIO_PCA9551_SET_LED = 0x10, }; /** - * @enum grioReasonCode + * @enum gpioReasonCode */ enum gpioReasonCode { @@ -51,6 +54,9 @@ namespace GPIO GPIO_ATTR_INFO_NOT_FOUND = GPIO_COMP_ID | 0x01, GPIO_I2C_TARGET_NOT_FOUND = GPIO_COMP_ID | 0x02, GPIO_INVALID_OP = GPIO_COMP_ID | 0x03, + + // Use 0x10-0x1F range for PCA9551 functions + GPIO_PCA9551_DATA_MISMATCH = GPIO_COMP_ID | 0x10, }; }; diff --git a/src/include/usr/gpio/gpioif.H b/src/include/usr/gpio/gpioif.H index 03a5a9a89d6..2a010039bb6 100644 --- a/src/include/usr/gpio/gpioif.H +++ b/src/include/usr/gpio/gpioif.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -26,6 +26,8 @@ #ifndef __GPIOIF_H #define __GPIOIF_H +#include + namespace GPIO { /** @@ -33,10 +35,125 @@ namespace GPIO */ enum gpioDevice_t { - PCA95X_GPIO = 0, + // Corresponds to attribute ... + PCA95X_GPIO = 0, // GPIO_INFO + PCA9551_GPIO_PHYS_PRES = 1, // GPIO_INFO_PHYS_PRES INVALID_GPIO, }; +/* The following enums and interfaces are specific to PCA9551 GPIO Devices. + * Documentation here: https://www.nxp.com/docs/en/data-sheet/PCA9551.pdf + */ + +/** + * @brief Specific to PCA9551: LED Bit Mask to match how their status is read + * back from LED "INPUT" register on PCA9551 Devices + */ +enum PCA9551_LEDS_t : uint8_t +{ + PCA9551_LED0 = 0x01, + PCA9551_LED1 = 0x02, + PCA9551_LED2 = 0x04, + PCA9551_LED3 = 0x08, + PCA9551_LED4 = 0x10, + PCA9551_LED5 = 0x20, + PCA9551_LED6 = 0x40, + PCA9551_LED7 = 0x80, +}; + +/** + * @brief Specific to PCA9551: Values used by the LED select registers + * to determine the source of the LED data. + */ +enum PCA9551_LED_Output_Settings_t : uint8_t +{ + PCA9551_OUTPUT_LOW = 0x00, // LED on + PCA9551_OUTPUT_HIGH_IMPEDANCE = 0x01, // LED off; default + PCA9551_OUTPUT_PWM0 = 0x02, // Output blinks at PWM0 rate + PCA9551_OUTPUT_PWM1 = 0x03, // Output blinks at PWM1 rate +}; + +/** + * @brief Specific to PCA9551: Control register definition: + sepcificies which register the operation will target + */ +enum PCA9551_Registers_t : uint8_t +{ + PCA9551_REGISTER_INPUT = 0x00, // INPUT (read only) input register + PCA9551_REGISTER_PCS0 = 0x01, // PSC0 (r/w) frequency prescaler 0 + PCA9551_REGISTER_PWM0 = 0x02, // PWM0 (r/w) PWM register 0 + PCA9551_REGISTER_PCS1 = 0x03, // PSC1 (r/w) frequency prescaler 1 + PCA9551_REGISTER_PWM1 = 0x04, // PWM1 (r/w) PWM register 1 + PCA9551_REGISTER_LS0 = 0x05, // LS0 (r/w) LED0 to LED3 selector + PCA9551_REGISTER_LS1 = 0x06, // LS1 (r/w) LED4 to LED7 selector +}; + +/** + * @brief Specific to PCA9551: Helper constants to work with the bits in the + * PCA9551 registers + */ +enum PCA9551_Constants_t : uint8_t +{ + // Mask shifted to apply 2-bit settings to a specific LED in the output + // settings register + PCA9551_LED_SETTINGS_MASK = 0x03, + + // Amount to shift the LED value per LED when walking through the LEDs + // in the INPUT register (related to PCA9551_LEDS_t above) + PCA9551_LED_SHIFT_AMOUNT = 0x01, + + // Amount to shift the LED Settings MASK per LED when walking through the + // LEDs in the output settings register (ie, 2 bits at a time) + PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT = 0x02, + + // LED Divider: While the INPUT register can contain all 8 LED values + // (since each value is represented by one bit), the SETTINGS registers + // (PCA9551_REGISTER_LS0 and PCA9551_REGISTER_LS1) can only cover 4 LEDs + // each since each setting requires 2 bits. + // This divisor takes LEDs 4 to 7 and makes them look like LEDs 0 to 3 + PCA9551_LED_SETTINGS_DIVISOR = 0x80, +}; + +/** + * @brief Returns the PCA9551 Device's INPUT register which reflects the state + * of the device's LEDs (aka pins) + * + * @param[in] i_target - Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute + * to run the commands against + * + * @param[out] o_led_data - The INPUT register data from the device + * + * @return errlHndl_t nullptr on success; non-nullptr on error. + */ +errlHndl_t gpioPca9551GetLeds(TARGETING::Target * i_target, + uint8_t & o_led_data); + +/** + * @brief Sets the given LED (aka pin) of a PCA9551 Device to a certain setting + * and returns the INPUT register which reflects the state of device's + * LEDs (aka pins) after the setting has been run + * + * @param[in] i_target - Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute + * to run the commands against + * + * @param[in] i_led - The specific LED Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute + * to run the commands against + * + * @param[in] i_setting - the output setting to set the LED to + * + * @param[out] o_led_data - The INPUT register data from the device after the + * 'set' procedure has been run allowing the caller to + * evaluate if the set actually went through + * + * @return errlHndl_t nullptr on success; non-nullptr on error. + */ + +errlHndl_t gpioPca9551SetLed(TARGETING::Target * i_target, + const PCA9551_LEDS_t i_led, + const PCA9551_LED_Output_Settings_t i_setting, + uint8_t & o_led_data); + + }; // GPIO NAMESPACE #endif diff --git a/src/usr/gpio/HBconfig b/src/usr/gpio/HBconfig index e5f650eb9f5..20ed72dd072 100644 --- a/src/usr/gpio/HBconfig +++ b/src/usr/gpio/HBconfig @@ -1,4 +1,4 @@ config GPIODD - default n + default y help Enable GPIO device driver support diff --git a/src/usr/gpio/gpio_pca9551.C b/src/usr/gpio/gpio_pca9551.C new file mode 100644 index 00000000000..2bc4b955bcb --- /dev/null +++ b/src/usr/gpio/gpio_pca9551.C @@ -0,0 +1,343 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/gpio/gpio_pca9551.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2019 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* 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 */ +/* */ +/* http://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. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file gpio_pca9551.C + * + * @brief Implements Interfaces Specific to the PCA9551 GPIO Devices + * + * @note Reference: https://www.nxp.com/docs/en/data-sheet/PCA9551.pdf + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpiodd.H" +#include +#include +#include + +extern trace_desc_t* g_trac_gpio; + +// Set to TRACFCOMP to enble unit race +#define TRACUCOMP(args...) TRACDCOMP(args) + +using namespace DeviceFW; +using namespace TARGETING; + +namespace GPIO +{ + + +void gpioPca9551SetReigsterHelper(const PCA9551_LEDS_t i_led, + const PCA9551_LED_Output_Settings_t i_setting, + uint8_t & io_led_register_data) +{ + uint8_t l_led = i_led; + uint8_t l_mask = PCA9551_LED_SETTINGS_MASK; // 2-bit mask shifted over to + // match i_led's value + uint8_t l_setting = i_setting; // will be shifted with 2-bit mask before it is applied + + // Adjust values for LEDs 4 to 7 to match calculations below for LEDs 0 to 3 + if (i_led > PCA9551_LED3) + { + l_led = l_led / PCA9551_LED_SETTINGS_DIVISOR; + } + TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: " + "i_led=0x%.2X, l_led=0x%.2X, l_mask=0x%.2X, " + "l_setting=0x%.2X, data0=0x%.2X", + i_led, l_led, l_mask, l_setting,io_led_register_data); + + // Move 2-bit mask and setting to cover the correct values + // Setting register is uint8_t broken into 4 2-bit setting sections: + // [LED3 Setting][LED2 Setting][LED1 Setting][LED0 Setting] + // --OR-- + // [LED7 Setting][LED6 Setting][LED5 Setting][LED4 Setting] + + const uint8_t match = 0x01; // shift values until l_led == match + + // l_led must be >= match or following loop won't work + assert(l_led >= match, "gpioPca9551SetReigsterHelper: l_led %d is < match %d", l_led, match); + + TRACUCOMP(g_trac_gpio,"gpioPca9551SetReigsterHelper: Pre-loop: " + "l_led=0x%.2X, match=0x%.2X", + l_led, match); + while ( match != l_led ) + { + l_led = l_led >> PCA9551_LED_SHIFT_AMOUNT; + l_mask = l_mask << PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT; + l_setting = l_setting << PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT; + TRACUCOMP(g_trac_gpio,"gpioPca9551SetReigsterHelper: inside-loop: " + "l_led=0x%.2X, l_mask=0x%.2X, l_setting=0x%.2X", + l_led, l_mask, l_setting); + } + TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: Post-loop: " + "l_mask=0x%.2X, l_setting=0x%.2X", + l_mask, l_setting); + + // Apply Mask to Register data and then OR-in setting bits + io_led_register_data = (io_led_register_data & ~l_mask) | l_setting; + TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: " + "io_led_register_data=0x%.2X", + io_led_register_data); + + return; +} + + +errlHndl_t gpioPca9551GetLeds(TARGETING::Target * i_target, + uint8_t & o_led_data) +{ + errlHndl_t err = nullptr; + + TRACUCOMP(g_trac_gpio, ENTER_MRK"gpioPca9551GetLeds: " + "i_target 0x%.08X", + get_huid(i_target)); + + do + { + + // Read PCA9551 INPUT Register to get Pin (aka LED) Values + uint8_t data = 0; + size_t data_len = sizeof(data); + const size_t exp_data_len = data_len; + uint64_t device_type = PCA9551_GPIO_PHYS_PRES; + uint64_t register_addr = PCA9551_REGISTER_INPUT; + + err = DeviceFW::deviceOp + ( DeviceFW::READ, + i_target, + &data, + data_len, + DEVICE_GPIO_ADDRESS(device_type, register_addr) + ); + if(err) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551GetLeds: " + "Reading INPUT register failed"); + break; + } + else + { + o_led_data = data; + TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551GetLeds: " + "register_addr=0x%X, o_led_data=0x%.2X", + register_addr, o_led_data); + } + assert(data_len==exp_data_len, "gpioPca9551GetLeds: expected %d size of data but got %d", exp_data_len, data_len); + + } while (0); + + if (err) + { + err->collectTrace( GPIO_COMP_NAME ); + } + + return err; +} + +errlHndl_t gpioPca9551SetLed(TARGETING::Target * i_target, + const PCA9551_LEDS_t i_led, + const PCA9551_LED_Output_Settings_t i_setting, + uint8_t & o_led_data) +{ + errlHndl_t err = nullptr; + + TRACUCOMP(g_trac_gpio, ENTER_MRK"gpioPca9551SetLed: " + "i_target 0x%.8X, i_led=0x%.2X, i_setting=0x%.2X", + get_huid(i_target), i_led, i_setting); + + do + { + uint64_t deviceType = PCA9551_GPIO_PHYS_PRES; + + // First Read Select Register - either LS0 (LEDs 0-3) or LS1 (LEDs 4-7) + uint64_t register_addr = PCA9551_REGISTER_LS0; + if (i_led > PCA9551_LED3) + { + register_addr = PCA9551_REGISTER_LS1; + } + uint8_t data = 0; + size_t data_len = sizeof(data); + const size_t exp_data_len = data_len; + + err = DeviceFW::deviceOp + ( DeviceFW::READ, + i_target, + &data, + data_len, + DEVICE_GPIO_ADDRESS(deviceType, register_addr) + ); + if(err) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: " + "Reading LED Select register 0x%X failed", + register_addr); + break; + } + else + { + TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: " + "LED Select register_addr=0x%X, data=0x%.2X", + register_addr, data); + } + assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len); + + + // Create Setting Register to Write Back: + uint8_t write_data = data; + gpioPca9551SetReigsterHelper(i_led, i_setting, write_data); + + // Write LED Select Register + data = write_data; + + err = DeviceFW::deviceOp + ( DeviceFW::WRITE, + i_target, + &data, + data_len, + DEVICE_GPIO_ADDRESS(deviceType, register_addr) + ); + if(err) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: " + "Writing LED Select register 0x%X failed", + register_addr); + break; + } + else + { + TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: " + "Writing LED Select register_addr=0x%X, data=0x%.2X", + register_addr, data); + } + assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len); + + + // Read Back LED Select Register + data = 0; + err = DeviceFW::deviceOp + ( DeviceFW::READ, + i_target, + &data, + data_len, + DEVICE_GPIO_ADDRESS(deviceType, register_addr) + ); + if(err) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: " + "Reading LED Select register 0x%X failed", + register_addr); + break; + } + else + { + TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: " + "LED Select register_addr=0x%X, data=0x%.2X", + register_addr, data); + } + assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len); + + // Compare data written and data read back + if (data != write_data) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: " + "Reading Back LED Select register 0x%X had unexpected data=", + "0x%.2X. Expected 0x%.2X", + register_addr, data, write_data); + + /*@ + * @errortype + * @reasoncode GPIO_PCA9551_DATA_MISMATCH + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid GPIO_PCA9551_SET_LED + * @userdata1[0:31] HUID of Master Processor Target + * @userdata1[32:63] Input LED to Set + * @userdata2[0:31] Expected Data (aka data written) + * @userdata2[32:63] Data Read Back + * @devdesc Setting of LED value did not appear to work + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + GPIO_PCA9551_SET_LED, + GPIO_PCA9551_DATA_MISMATCH, + TWO_UINT32_TO_UINT64( + get_huid(i_target), + i_led), + TWO_UINT32_TO_UINT64( + write_data, + data), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + break; + } + + // Read PCA9551 INPUT Register to get Pin (aka LED) Values + data = 0; + data_len = sizeof(data); + register_addr = PCA9551_REGISTER_INPUT; + + err = DeviceFW::deviceOp + ( DeviceFW::READ, + i_target, + &data, + data_len, + DEVICE_GPIO_ADDRESS(deviceType, register_addr) + ); + if(err) + { + TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: " + "Reading INPUT register failed"); + break; + } + else + { + o_led_data = data; + TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: " + "INPUT register_addr=0x%X, o_led_data=0x%.2X", + register_addr, o_led_data); + } + assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len); + + } while (0); + + if (err) + { + err->collectTrace( GPIO_COMP_NAME ); + } + + return err; + +} + +}; // end namespace GPIO + diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C index 559dab79e62..69cde2b707c 100644 --- a/src/usr/gpio/gpiodd.C +++ b/src/usr/gpio/gpiodd.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2018 */ +/* Contributors Listed Below - COPYRIGHT 2014,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -34,6 +34,8 @@ #include #include "gpiodd.H" #include +#include +#include trace_desc_t * g_trac_gpio = NULL; TRAC_INIT( & g_trac_gpio, GPIO_COMP_NAME, KILOBYTE ); @@ -57,6 +59,11 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, TARGETING::TYPE_MEMBUF, gpioPerformOp); +DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, + DeviceFW::GPIO, + TARGETING::TYPE_PROC, + gpioPerformOp); + errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType, TARGETING::Target * i_target, void * io_buffer, @@ -70,7 +77,8 @@ errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType, gpioInfo.deviceType = va_arg( i_args, uint64_t ); gpioInfo.portAddr = va_arg( i_args, uint64_t ); - TRACDCOMP(g_trac_gpio, ENTER_MRK"gpioPerformOp(): " +//MAB make TRACD + TRACFCOMP(g_trac_gpio, ENTER_MRK"gpioPerformOp(): " "optype %d deviceType %d portAddr %d", i_opType, gpioInfo.deviceType, gpioInfo.portAddr); @@ -237,20 +245,51 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target, { errlHndl_t err = NULL; - TARGETING::GpioInfo gpioData; - bool attrReadErr = false; +#ifndef CONFIG_FSP_BUILD + TARGETING::GpioInfo gpioData; +#endif + TARGETING::GpioInfoPhysPres gpioDataPhysPres; switch(io_gpioInfo.deviceType) { +#ifndef CONFIG_FSP_BUILD case PCA95X_GPIO: if( !( i_target-> tryGetAttr( gpioData ) ) ) { attrReadErr = true; } + else + { + io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath; + io_gpioInfo.engine = gpioData.engine; + io_gpioInfo.i2cPort = gpioData.port; + io_gpioInfo.i2cDeviceAddr = gpioData.devAddr; + io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector; + io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath; + } break; +#endif + case PCA9551_GPIO_PHYS_PRES: + + if( !( i_target-> + tryGetAttr(gpioDataPhysPres))) + { + attrReadErr = true; + } + else + { + io_gpioInfo.i2cMasterPath = gpioDataPhysPres.i2cMasterPath; + io_gpioInfo.engine = gpioDataPhysPres.engine; + io_gpioInfo.i2cPort = gpioDataPhysPres.port; + io_gpioInfo.i2cDeviceAddr = gpioDataPhysPres.devAddr; + io_gpioInfo.i2cMuxBusSelector = gpioDataPhysPres.i2cMuxBusSelector; + io_gpioInfo.i2cMuxPath = gpioDataPhysPres.i2cMuxPath; + } + break; + default: TRACFCOMP( g_trac_gpio,ERR_MRK"gpioReadAttributes() - " @@ -309,16 +348,6 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target, err->collectTrace( GPIO_COMP_NAME ); } - if( !err ) - { - io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath; - io_gpioInfo.engine = gpioData.engine; - io_gpioInfo.i2cPort = gpioData.port; - io_gpioInfo.i2cDeviceAddr = gpioData.devAddr; - io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector; - io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath; - } - return err; } diff --git a/src/usr/gpio/makefile b/src/usr/gpio/makefile index d40eaa1305c..fd42e2d1dd2 100644 --- a/src/usr/gpio/makefile +++ b/src/usr/gpio/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2014 +# Contributors Listed Below - COPYRIGHT 2014,2019 # [+] Google Inc. # [+] International Business Machines Corp. # @@ -27,6 +27,8 @@ ROOTPATH = ../../.. MODULE = gpio OBJS += $(if $(CONFIG_GPIODD),gpiodd.o,) +OBJS += $(if $(CONFIG_GPIODD),gpio_pca9551.o,) + # no way to test this at the moment TODO RTC 111415 #SUBDIRS = test.d diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 3e651b4984c..8be123d995e 100755 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -325,6 +325,78 @@ + + GPIO_INFO_PHYS_PRES + Information needed to address GPIO device that corresponds + to the Physical Presence Detect circuit + + Structure to define the addessing for an I2C + slave device. + + i2cMasterPath + Entity path to the chip that contains the I2C + master + EntityPath + physical:sys-0/node-0/proc-0 + + + port + Port from the I2C Master device. This is a 6-bit + value. + uint8_t + 0 + + + devAddr + Device address on the I2C bus. This is a 7-bit value, + but then shifted 1 bit left. + uint8_t + 0xC0 + + + engine + I2C master engine. This is a 2-bit + value. + uint8_t + 2 + + + windowOpenPin + Logical GPIO pin number used to open or close the physcial + presence window + uint8_t + 0 + + + physicalPresencePin + Logical GPIO pin number used to determine if physical + presence was asserted + uint8_t + 1 + + + + 0xFF + Determines which of the N selectable buses the mux + will connect to. OxFF indicates no mux present + or N/A. + i2cMuxBusSelector + uint8_t + + + + + physical:sys-0 + Entity path to the I2C mux for this device. + i2cMuxPath + EntityPath + + + non-volatile + + + diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 26cf81f6f48..080fbecae8c 100644 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -115,6 +115,9 @@ FSI_SCOM_MUTEX + + GPIO_INFO_PHYS_PRES + HBRT_HYP_ID