diff options
Diffstat (limited to 'src/usr/gpio')
-rw-r--r-- | src/usr/gpio/HBconfig | 4 | ||||
-rw-r--r-- | src/usr/gpio/gpiodd.C | 324 | ||||
-rw-r--r-- | src/usr/gpio/gpiodd.H | 109 | ||||
-rw-r--r-- | src/usr/gpio/makefile | 34 |
4 files changed, 471 insertions, 0 deletions
diff --git a/src/usr/gpio/HBconfig b/src/usr/gpio/HBconfig new file mode 100644 index 000000000..e5f650eb9 --- /dev/null +++ b/src/usr/gpio/HBconfig @@ -0,0 +1,4 @@ +config GPIODD + default n + help + Enable GPIO device driver support diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C new file mode 100644 index 000000000..4dc94650e --- /dev/null +++ b/src/usr/gpio/gpiodd.C @@ -0,0 +1,324 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/gpio/gpiodd.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] Google Inc. */ +/* [+] 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 */ + +#include <trace/interface.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <errl/errludtarget.H> +#include <errl/errludstring.H> +#include <targeting/common/targetservice.H> +#include <targeting/common/commontargeting.H> +#include <devicefw/driverif.H> +#include "gpiodd.H" +#include <gpio/gpioddreasoncodes.H> + + +trace_desc_t * g_trac_gpio = NULL; +TRAC_INIT( & g_trac_gpio, GPIO_COMP_NAME, KILOBYTE ); + +using namespace DeviceFW; + +namespace GPIO +{ + +enum +{ + // Asserting that a GPIO Port Extender will never have more than an 8-bit + // address as these devices never have more than a handful of control + // registers. + GPIO_ADDR_SIZE = 1, +}; + +// Link to device driver interface +DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, + DeviceFW::GPIO, + TARGETING::TYPE_MEMBUF, + gpioPerformOp); + +errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target * i_target, + void * io_buffer, + size_t & i_buflen, + int64_t i_accessType, + va_list i_args) +{ + errlHndl_t err = NULL; + gpioAddr_t gpioInfo; + + gpioInfo.deviceType = va_arg( i_args, uint64_t ); + gpioInfo.portAddr = va_arg( i_args, uint64_t ); + + TRACDCOMP(g_trac_gpio, ENTER_MRK"gpioPerformOp(): " + "optype %d deviceType %d portAddr %d", + i_opType, gpioInfo.deviceType, gpioInfo.portAddr); + + do + { + err = gpioReadAttributes (i_target, gpioInfo); + if( err ) + { + break; + } + + TARGETING::TargetService& ts = TARGETING::targetService(); + TARGETING::Target * i2c_master = ts.toTarget(gpioInfo.i2cMasterPath); + + if( i2c_master == NULL ) + { + TRACFCOMP( g_trac_gpio,ERR_MRK"gpioPerformOp() - " + "I2C Target not found. Device type %d.", + gpioInfo.deviceType ); + /*@ + * @errortype + * @reasoncode GPIO_I2C_TARGET_NOT_FOUND + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid GPIO_PERFORM_OP + * @userdata1 Device type + * @userdata2 HUID of target + * @devdesc Invalid GPIO device type + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + GPIO::GPIO_PERFORM_OP, + GPIO::GPIO_I2C_TARGET_NOT_FOUND, + gpioInfo.deviceType, + TARGETING::get_huid(i_target), + true /*Add HB SW Callout*/ ); + + err->collectTrace( GPIO_COMP_NAME ); + break; + } + + if( i_opType == DeviceFW::READ ) + { + err = gpioRead(i2c_master, + io_buffer, + i_buflen, + gpioInfo); + + if( err ) + { + break; + } + } + else if (i_opType == DeviceFW::WRITE ) + { + err = gpioWrite(i2c_master, + io_buffer, + i_buflen, + gpioInfo); + + if( err ) + { + break; + } + } + else + { + TRACFCOMP( g_trac_gpio,ERR_MRK"gpioPerformOp() - " + "Invalid OP type %d.", + i_opType ); + /*@ + * @errortype + * @reasoncode GPIO_INVALID_OP + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid GPIO_PERFORM_OP + * @userdata1 OP type + * @userdata2 HUID of target + * @devdesc Invalid GPIO device type + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + GPIO::GPIO_PERFORM_OP, + GPIO::GPIO_INVALID_OP, + i_opType, + TARGETING::get_huid(i_target), + true /*Add HB SW Callout*/ ); + + err->collectTrace( GPIO_COMP_NAME ); + break; + } + + } while (0); + + return err; +} + +errlHndl_t gpioRead( TARGETING::Target * i_target, + void * o_buffer, + size_t & io_buflen, + gpioAddr_t & i_gpioInfo) +{ + errlHndl_t err = NULL; + + // This i2c interface writes the gpio portAddr to the device + // then reads the value of the port w/o a stop bit in between ops + err = deviceOp( DeviceFW::READ, + i_target, + o_buffer, + io_buflen, + DEVICE_I2C_ADDRESS_OFFSET + ( i_gpioInfo.i2cPort, + i_gpioInfo.engine, + i_gpioInfo.i2cDeviceAddr, + GPIO_ADDR_SIZE, + reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr)) + ) + ); + if(err) + { + err->collectTrace( GPIO_COMP_NAME ); + } + + return err; +} + +errlHndl_t gpioWrite ( TARGETING::Target * i_target, + void * i_buffer, + size_t i_buflen, + gpioAddr_t & i_gpioInfo) +{ + errlHndl_t err = NULL; + + size_t cmdlen = GPIO_ADDR_SIZE + i_buflen; + uint8_t cmd[cmdlen]; + cmd[0] = i_gpioInfo.portAddr; + memcpy(&(cmd[GPIO_ADDR_SIZE]), i_buffer, i_buflen); + + err = deviceOp( DeviceFW::WRITE, + i_target, + &cmd, + cmdlen, + DEVICE_I2C_ADDRESS + ( i_gpioInfo.i2cPort, + i_gpioInfo.engine, + i_gpioInfo.i2cDeviceAddr + ) + ); + if(err) + { + err->collectTrace( GPIO_COMP_NAME ); + } + + return err; +} + + +errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target, + gpioAddr_t & io_gpioInfo) +{ + errlHndl_t err = NULL; + + TARGETING::GpioInfo gpioData; + + bool attrReadErr = false; + + + switch(io_gpioInfo.deviceType) + { + case PCA95X_GPIO: + if( !( i_target-> + tryGetAttr<TARGETING::ATTR_GPIO_INFO>( gpioData ) ) ) + { + attrReadErr = true; + } + break; + default: + + TRACFCOMP( g_trac_gpio,ERR_MRK"gpioReadAttributes() - " + "Invalid device type (%d) to read attributes from!", + io_gpioInfo.deviceType ); + /*@ + * @errortype + * @reasoncode GPIO_INVALID_DEVICE_TYPE + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid GPIO_READATTRIBUTES + * @userdata1 Device type + * @userdata2 HUID of target + * @devdesc Invalid GPIO device type + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + GPIO::GPIO_READATTRIBUTES, + GPIO::GPIO_INVALID_DEVICE_TYPE, + io_gpioInfo.deviceType, + TARGETING::get_huid(i_target), + true /*Add HB SW Callout*/ ); + + err->collectTrace( GPIO_COMP_NAME ); + + break; + } + + if(attrReadErr) + { + TRACFCOMP( g_trac_gpio, + ERR_MRK"gpioReadAttributes() - ERROR reading " + "attributes for device type %d!", + io_gpioInfo.deviceType ); + + /*@ + * @errortype + * @reasoncode GPIO_ATTR_INFO_NOT_FOUND + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid GPIO_READATTRIBUTES + * @userdata1 HUID of target + * @userdata2 GPIO device type + * @devdesc GPIO device attribute was not found + * @custdesc A problem occurred during the IPL + * of the system. + */ + err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + GPIO::GPIO_READATTRIBUTES, + GPIO::GPIO_ATTR_INFO_NOT_FOUND, + TARGETING::get_huid(i_target), + io_gpioInfo.deviceType, + true /*Add HB SW Callout*/); + + + err->collectTrace( GPIO_COMP_NAME ); + } + + if( !err ) + { + //TODO - RTC 109570 until the the Palmetto attribute file is setup + io_gpioInfo.i2cMasterPath = + i_target->getAttr<TARGETING::ATTR_PHYS_PATH>(); + //io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath; + io_gpioInfo.engine = gpioData.engine; + io_gpioInfo.i2cPort = gpioData.port; + io_gpioInfo.i2cDeviceAddr = gpioData.devAddr; + } + + return err; +} + +}; // end namespace GPIO + diff --git a/src/usr/gpio/gpiodd.H b/src/usr/gpio/gpiodd.H new file mode 100644 index 000000000..9431e832c --- /dev/null +++ b/src/usr/gpio/gpiodd.H @@ -0,0 +1,109 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/gpio/gpiodd.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] Google Inc. */ +/* [+] 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 */ +#ifndef __GPIODD_H +#define __GPIODD_H + +#include <errl/errlentry.H> +#include <gpio/gpioif.H> + + +namespace GPIO +{ + struct gpioAddr_t + { + TARGETING::EntityPath i2cMasterPath; + uint8_t deviceType; //!< device type + uint8_t portAddr; + uint8_t i2cPort; + uint8_t engine; + uint8_t i2cDeviceAddr; + }; + + /** + * @brief Perform a GPIO operation + * + * @param[in] i_optype - Operation Type - @see devicefw/userif.H + * @param[in] i_target - Target device + * @param[in/out] io_buffer - Ptr to data buffer to be written/read into + * @param[in/out] io_buflen - Length of the data buffer + * @param[in] i_accessType @see devicefw/userif.H + * @param[in] i_args Device arguement list. Gpio Device type, + * Gpio port address + * + * @return errlHndl_t NULL on success or error handle on error. + */ + errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target * i_target, + void * io_buffer, + size_t & io_buflen, + int64_t i_accessType, + va_list i_args); + + /** + * @brief Read from a gpio device and port + * + * @param[in] i_target - Target of the i2c master for this gpio device + * @param[out] o_buffer - Buffer to contain the value of the gpio port + * @param[in/out] io_buflen - in: Size of the buffer, out: bytes actually + * read + * @param[in] gpioInfo - gpio addressing information @see gpioAddr_t + * + * @return errlHndl_t - Null on Success or error handle on error + */ + errlHndl_t gpioRead( TARGETING::Target * i_target, + void * o_buffer, + size_t & io_buflen, + gpioAddr_t & i_gpioInfo); + + /** + * @brief Write to a gpio device and port + * + * @param[in] i_target - Target of the i2c master for this gpio device + * @param[in] i_buffer - Buffer containing the value to write + * @param[in] i_buflen - Number of bytes to write + * @param[in] gpioInfo - gpio addressing information @see gpioAddr_t + * + * @return errlHndl_t - NULL on Success or error handle on error + */ + errlHndl_t gpioWrite( TARGETING::Target * i_target, + void * i_buffer, + size_t i_buflen, + gpioAddr_t & i_gpioInfo); + + + /** + * @brief Read the GPIO attributes + * + * @param[in] i_target - Target that contains the attritutes for the device + * @param[in/out] gpioAddr_t GPIO address information. @see gpioAddr_t + * + * @return errlHndl_t - NULL on Sucess or error handle on error + */ + errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target, + gpioAddr_t & io_gpioInfo); +}; + +#endif diff --git a/src/usr/gpio/makefile b/src/usr/gpio/makefile new file mode 100644 index 000000000..d40eaa130 --- /dev/null +++ b/src/usr/gpio/makefile @@ -0,0 +1,34 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/gpio/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2014 +# [+] Google Inc. +# [+] 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 +ROOTPATH = ../../.. +MODULE = gpio + +OBJS += $(if $(CONFIG_GPIODD),gpiodd.o,) + +# no way to test this at the moment TODO RTC 111415 +#SUBDIRS = test.d + +include ${ROOTPATH}/config.mk |