diff --git a/lib/card10/pb.c b/lib/card10/pb.c
index b69b834b4e15cb62d884b75c0b24842cd91ab58c..a9a9c18f97fa6844367a073294fc05fcda54daa7 100644
--- a/lib/card10/pb.c
+++ b/lib/card10/pb.c
@@ -42,6 +42,7 @@
 #include <stddef.h>
 
 static const uint8_t expander_pins[] = { 5, 0x0, 3, 6 };
+static pb_callback pb_callbacks[4]   = { NULL };
 
 /******************************************************************************/
 int PB_Init(void)
@@ -62,6 +63,23 @@ int PB_Init(void)
 	return retval;
 }
 
+static void pe_pb_callback(gpio_int_pol_t edge_type, void *cbdata)
+{
+	unsigned int pb = (unsigned int)cbdata;
+	if (pb_callbacks[pb - 1]) {
+		pb_callbacks[pb - 1](pb, edge_type == GPIO_INT_FALLING);
+	}
+}
+
+static void gpio_pb_callback(void *cbdata)
+{
+	unsigned int pb = (unsigned int)cbdata;
+	if (pb_callbacks[pb - 1]) {
+		int level = GPIO_InGet(&pb_pin[pb - 1]);
+		pb_callbacks[pb - 1](pb, !level);
+	}
+}
+
 /******************************************************************************/
 int PB_RegisterCallback(unsigned int pb, pb_callback callback)
 {
@@ -71,29 +89,29 @@ int PB_RegisterCallback(unsigned int pb, pb_callback callback)
 		return E_INVALID;
 	}
 
+	pb_callbacks[pb - 1] = callback;
+
 	uint8_t mask = (1 << expander_pins[pb - 1]);
 
 	if (callback) {
 		if (portexpander_detected()) {
 			// Register callback
 			portexpander_register_callback(
-				mask, callback, (void *)pb
+				mask, pe_pb_callback, (void *)pb
 			);
 
 			// Configure and enable interrupt
-			portexpander_int_config(mask, GPIO_INT_FALLING);
+			portexpander_int_config(mask, GPIO_INT_BOTH);
 			portexpander_int_enable(mask);
 		} else {
 			// Register callback
 			GPIO_RegisterCallback(
-				&pb_pin[pb - 1], callback, (void *)pb
+				&pb_pin[pb - 1], gpio_pb_callback, (void *)pb
 			);
 
 			// Configure and enable interrupt
 			GPIO_IntConfig(
-				&pb_pin[pb - 1],
-				GPIO_INT_EDGE,
-				GPIO_INT_FALLING
+				&pb_pin[pb - 1], GPIO_INT_EDGE, GPIO_INT_BOTH
 			);
 			GPIO_IntEnable(&pb_pin[pb - 1]);
 			NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(
diff --git a/lib/card10/pb.h b/lib/card10/pb.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd9a05138254d46e931d76a62746687577b78f52
--- /dev/null
+++ b/lib/card10/pb.h
@@ -0,0 +1,145 @@
+/**
+ * @file    pb.h
+ * @brief   Pushbutton driver header file.
+ */
+/* ****************************************************************************
+ * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *
+ * $Date: 2018-10-31 15:32:51 +0000 (Wed, 31 Oct 2018) $
+ * $Revision: 38826 $
+ *
+ *************************************************************************** */
+
+#ifndef _PB_H_
+#define _PB_H_
+
+#include "gpio.h"
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @ingroup bsp
+ * @defgroup pushbutton_evkit Push button driver board support
+ * @{
+ */
+/* **** Global Variables **** */
+extern const gpio_cfg_t pb_pin[];
+extern const unsigned int num_pbs;
+
+/* **** Function Prototypes **** */
+
+/**
+ * @brief      Initialize all push buttons.
+ * @return  \c #E_NO_ERROR  Push buttons initialized successfully.
+ * @return     "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
+ *
+ */
+int PB_Init(void);
+
+/**
+ * Type alias @c pb_callback for the push button callback.
+ * @details The function is of type:
+ * @code
+ *  void pb_callback(unsigned int pb, bool falling)
+ * @endcode
+ * To receive notification of a push button event, define a callback
+ * function and pass it as a pointer to the PB_RegisterCallback(unsigned int pb, pb_callback callback) function.
+ * @param      pb    push button index that triggered the callback.
+ */
+typedef void (*pb_callback)(unsigned int pb, bool falling);
+
+/**
+ * @brief      Register or Unregister a callback handler for events on the @p pb push button.
+ * @details
+ * - Calling this function with a pointer to a function @p callback, configures the pushbutton @p pb and enables the
+ * interrupt to handle the push button events.
+ * - Calling this function with a <tt>NULL</tt> pointer will disable the interrupt and unregister the
+ * callback function.
+ * @p pb must be a value between 0 and \c num_pbs.
+ *
+ * @param      pb        push button index to receive event callbacks.
+ * @param      callback  Callback function pointer of type @c pb_callback
+ * @return     #E_NO_ERROR if configured and callback registered successfully.
+ * @return     "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
+ */
+int PB_RegisterCallback(unsigned int pb, pb_callback callback);
+
+/**
+ * @brief      Register or Unregister a callback handler for rising and falling events on the @p pb push button.
+ * @details
+ * - Calling this function with a pointer to a function @p callback, configures the pushbutton @p pb and enables the
+ * interrupt to handle the push button events.
+ * - Calling this function with a <tt>NULL</tt> pointer will disable the interrupt and unregister the
+ * callback function.
+ * @p pb must be a value between 0 and \c num_pbs.
+ *
+ * @param      pb        push button index to receive event callbacks.
+ * @param      callback  Callback function pointer of type @c pb_callback
+ * @return     #E_NO_ERROR if configured and callback registered successfully.
+ * @return     "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
+ */
+int PB_RegisterRiseFallCallback(unsigned int pb, pb_callback callback);
+
+/**
+ * @brief   Enable a callback interrupt.
+ * @note    PB_RegisterCallback must be called prior to enabling the callback interrupt.
+ * @param   pb          push button index value between 0 and \c num_pbs.
+ */
+void PB_IntEnable(unsigned int pb);
+
+/**
+ * @brief   Disable a callback interrupt.
+ * @param   pb          push button index
+ */
+void PB_IntDisable(unsigned int pb);
+
+/**
+ * @brief   Clear a callback interrupt.
+ * @param   pb          push button index value between 0 and \c num_pbs.
+ */
+void PB_IntClear(unsigned int pb);
+
+/**
+ * @brief      Get the current state of the push button.
+ * @param      pb     push button index value between 0 and \c num_pbs.
+ * @return     TRUE   The button is pressed.
+ * @return     FALSE  The button is not pressed.
+ */
+int PB_Get(unsigned int pb);
+/**@}*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PB_H_ */
diff --git a/lib/card10/portexpander.c b/lib/card10/portexpander.c
index 979e73dad2af60a6e857749d3be96224847b798c..52eb88975a660306f540567b55abe56dc53e6151 100644
--- a/lib/card10/portexpander.c
+++ b/lib/card10/portexpander.c
@@ -329,7 +329,7 @@ void portexpander_poll()
 						 GPIO_INT_FALLING);
 				if ((int_edge_config[pin] == GPIO_INT_BOTH) ||
 				    (edge_type == int_edge_config[pin])) {
-					callbacks[pin](cbparam[pin]);
+					callbacks[pin](edge_type, cbparam[pin]);
 				}
 			}
 		}
diff --git a/lib/card10/portexpander.h b/lib/card10/portexpander.h
index a07c8163f8e6edc6a811869a0fee456d7e5aa24c..b260d935b127bb913d26a003867412bb1ac51140 100644
--- a/lib/card10/portexpander.h
+++ b/lib/card10/portexpander.h
@@ -16,7 +16,7 @@ typedef struct {
 } portexpander_cfg_t;
 
 
-typedef void (*pe_callback)(void *cbdata);
+typedef void (*pe_callback)(gpio_int_pol_t edge_type, void *cbdata);
 
 int portexpander_init(void);
 bool portexpander_detected(void);