diff --git a/boards/arduino-mega2560/Makefile.features b/boards/arduino-mega2560/Makefile.features
index 675243084d23e384927a15248e183d2266e2ed59..098dfa3e535ee8e240a2adbbb7a7964bb2465bec 100644
--- a/boards/arduino-mega2560/Makefile.features
+++ b/boards/arduino-mega2560/Makefile.features
@@ -1,2 +1,3 @@
 FEATURES_PROVIDED += periph_uart
+FEATURES_PROVIDED += periph_gpio
 FEATURES_MCU_GROUP = avr8
diff --git a/boards/arduino-mega2560/include/periph_conf.h b/boards/arduino-mega2560/include/periph_conf.h
index 22549013bc4ac991f7255ccf8f088afaf0321814..19f1d3dc1fb18117d20664e7c06eed521dc43507 100644
--- a/boards/arduino-mega2560/include/periph_conf.h
+++ b/boards/arduino-mega2560/include/periph_conf.h
@@ -227,12 +227,6 @@ extern "C" {
 #define UART3_RECEIVED_DATA (UART3_CTRL_STAT_A & (1 << UART3_RX_COMPLETE))
 #define UART3_DTREG_EMPTY   (UART3_CTRL_STAT_A & (1 << UART3_DATA_EMPTY))
 
-
-
-/* TODO: add defines for device agnostic implementation */
-/** @} */
-
-
 /**
  * @brief ADC configuration
  */
@@ -261,26 +255,6 @@ extern "C" {
 #define I2C_0_EN            0
 #define I2C_0_EN            0
 
-/**
- * @brief GPIO configuration
- */
-#define GPIO_0_EN           0
-#define GPIO_1_EN           0
-#define GPIO_2_EN           0
-#define GPIO_3_EN           0
-#define GPIO_4_EN           0
-#define GPIO_5_EN           0
-#define GPIO_6_EN           0
-#define GPIO_7_EN           0
-#define GPIO_8_EN           0
-#define GPIO_9_EN           0
-#define GPIO_10_EN          0
-#define GPIO_11_EN          0
-#define GPIO_12_EN          0
-#define GPIO_13_EN          0
-#define GPIO_14_EN          0
-#define GPIO_15_EN          0
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/atmega2560/include/periph_cpu.h b/cpu/atmega2560/include/periph_cpu.h
index f4b1548294c2bbfd506dc62a4efecfcc1cdfc0e2..7d38894e90323d62b38671b587b8fa51c6b48c11 100644
--- a/cpu/atmega2560/include/periph_cpu.h
+++ b/cpu/atmega2560/include/periph_cpu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Freie Universität Berlin
+ * Copyright (C) 2015 HAW Hamburg
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -13,19 +13,40 @@
  * @file
  * @brief           CPU specific definitions for internal peripheral handling
  *
- * @author          Hauke Petersen <hauke.peterse@fu-berlin.de>
+ * @author          René Herthel <rene-herthel@outlook.de>
  */
 
 #ifndef PERIPH_CPU_H_
 #define PERIPH_CPU_H_
 
 #include "periph/dev_enums.h"
+#include <avr/io.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* nothing defined here so far... */
+/**
+ * @brief   Define a CPU specific GPIO pin generator macro
+ */
+#define GPIO(x, y)          ((x << 4) | y)
+
+/**
+ * @brief   Available ports on the ATmega2560 family
+ */
+enum {
+    PORT_A = 0,       /**< port A */
+    PORT_B = 1,       /**< port B */
+    PORT_C = 2,       /**< port C */
+    PORT_D = 3,       /**< port D */
+    PORT_E = 4,       /**< port E */
+    PORT_F = 5,       /**< port F */
+    PORT_G = 6,       /**< port G */
+    PORT_H = 7,       /**< port H */
+    PORT_J = 8,       /**< port J */
+    PORT_K = 9,       /**< port K */
+    PORT_L = 10       /**< port L */
+};
 
 #ifdef __cplusplus
 }
diff --git a/cpu/atmega2560/periph/Makefile b/cpu/atmega2560/periph/Makefile
index 87a55ed6845fa8eeb27dfc2774608b6e8d30662c..6d1887b640099d130c5a6400e3f878f0c65aa6f1 100644
--- a/cpu/atmega2560/periph/Makefile
+++ b/cpu/atmega2560/periph/Makefile
@@ -1,2 +1,3 @@
 MODULE = periph
+
 include $(RIOTBASE)/Makefile.base
diff --git a/cpu/atmega2560/periph/gpio.c b/cpu/atmega2560/periph/gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..275e1dc7eb5e37d07129e1e963054ff8e6f14a66
--- /dev/null
+++ b/cpu/atmega2560/periph/gpio.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2015 HAW Hamburg
+
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     driver_periph
+ * @{
+ *
+ * @file
+ * @brief       Low-level GPIO driver implementation for ATmega2560
+ *
+ * @author      René Herthel <rene-herthel@outlook.de>
+ *
+ * @}
+ */
+
+
+#include <stdio.h>
+
+#include <avr/interrupt.h>
+
+#include "cpu.h"
+#include "periph/gpio.h"
+#include "periph_conf.h"
+
+#define GPIO_BASE_PORT_A        (0x20)
+#define GPIO_OFFSET_PORT_H      (0xCB)
+#define GPIO_OFFSET_PIN_PORT    (0x02)
+#define GPIO_OFFSET_PIN_PIN     (0x03)
+#define GPIO_EXT_INT_NUMOF      (7U)
+
+typedef struct {
+    gpio_cb_t cb;
+    void *arg;
+} gpio_state_t;
+
+static gpio_state_t config[GPIO_EXT_INT_NUMOF];
+
+/**
+ * @brief     Extract the pin number of the given pin
+ */
+static inline uint8_t _pin_num(gpio_t pin)
+{
+    return (pin & 0x0f);
+}
+
+/**
+ * @brief     Extract the port number of the given pin
+ */
+static inline uint8_t _port_num(gpio_t pin)
+{
+    return (pin >> 4) & 0x0f;
+}
+
+/**
+ * @brief     Generate the PORTx address of the give pin.
+ */
+static inline uint16_t _port_addr(gpio_t pin)
+{
+    uint8_t port_num = _port_num(pin);
+    uint16_t port_addr = port_num * GPIO_OFFSET_PIN_PIN;
+
+    port_addr += GPIO_BASE_PORT_A;
+    port_addr += GPIO_OFFSET_PIN_PORT;
+
+    if (port_num > PORT_G) {
+        port_addr += GPIO_OFFSET_PORT_H;
+    }
+
+    return port_addr;
+}
+
+/**
+ * @brief     Generate the DDRx address of the given pin
+ */
+static inline uint8_t _ddr_addr(gpio_t pin)
+{
+    return (_port_addr(pin) - 0x01);
+}
+
+/**
+ * @brief     Generate the PINx address of the given pin.
+ */
+static inline uint8_t _pin_addr(gpio_t pin)
+{
+    return (_port_addr(pin) - 0x02);
+}
+
+int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pullup)
+{
+    int res;
+
+    if (dir == GPIO_DIR_OUT) {
+        _SFR_MEM8(_ddr_addr(pin)) |= (1 << _pin_num(pin));
+        res = bit_is_set(_SFR_MEM8(_ddr_addr(pin)), _pin_num(pin));
+    }
+    else {
+        _SFR_MEM8(_ddr_addr(pin)) &= ~(1 << _pin_num(pin));
+        res = bit_is_clear(_SFR_MEM8(_ddr_addr(pin)), _pin_num(pin));
+    }
+
+    return (res == 0) ? -1 : 0;
+}
+
+int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank,
+                  gpio_cb_t cb, void *arg)
+{
+    uint8_t pin_num = _pin_num(pin);
+
+    if ((_port_num(pin) == PORT_D && pin_num > 3)
+         || (_port_num(pin) == PORT_E && pin_num < 4)) {
+        return -1;
+    }
+
+    if (gpio_init(pin, GPIO_DIR_IN, pullup) < 0) {
+        return -1;
+    }
+
+    gpio_set(pin);
+
+    /* clear global interrupt flag */
+    cli();
+
+    EIMSK |= (1 << pin_num);
+
+    /* configure the flank */
+    switch (flank) {
+        case GPIO_RISING:
+            if (pin_num < 4) {
+                EICRA |= (3 << pin_num * 2);
+            }
+            else {
+                EICRB |= (3 << (pin_num * 2) % 4);
+            }
+            break;
+        case GPIO_FALLING:
+            if (pin_num < 4) {
+                EICRA |= (2 << pin_num * 2);
+            }
+            else {
+                EICRB |= (2 << (pin_num * 2) % 4);
+            }
+            break;
+        case GPIO_BOTH:
+            if (pin_num < 4) {
+                EICRA |= (1 << pin_num * 2);
+            }
+            else {
+                EICRB |= (1 << (pin_num * 2) % 4);
+            }
+            break;
+        default:
+            return -1;
+    };
+
+    /* set callback */
+    config[pin_num].cb = cb;
+    config[pin_num].arg = arg;
+
+    /* set global interrupt flag */
+    sei();
+
+    return 0;
+}
+
+void gpio_irq_enable(gpio_t pin)
+{
+    EIMSK |= (1 << _pin_num(pin));
+}
+
+void gpio_irq_disable(gpio_t pin)
+{
+    EIMSK &= ~(1 << _pin_num(pin));
+}
+
+int gpio_read(gpio_t pin)
+{
+    return (_SFR_MEM8(_pin_addr(pin)) & (1 << _pin_num(pin)));
+}
+
+void gpio_set(gpio_t pin)
+{
+    _SFR_MEM8(_port_addr(pin)) |= (1 << _pin_num(pin));
+}
+
+void gpio_clear(gpio_t pin)
+{
+    _SFR_MEM8(_port_addr(pin)) &= ~(1 << _pin_num(pin));
+}
+
+void gpio_toggle(gpio_t pin)
+{
+    if (gpio_read(pin)) {
+        gpio_clear(pin);
+    }
+    else {
+        gpio_set(pin);
+    }
+}
+
+void gpio_write(gpio_t pin, int value)
+{
+    if (value) {
+        gpio_set(pin);
+    }
+    else {
+        gpio_clear(pin);
+    }
+}
+
+static inline void irq_handler(uint8_t pin_num)
+{
+    config[pin_num].cb(config[pin_num].arg);
+}
+
+ISR(INT0_vect, ISR_BLOCK)
+{
+    irq_handler(0); /**< predefined interrupt pin */
+}
+
+ISR(INT1_vect, ISR_BLOCK)
+{
+    irq_handler(1); /**< predefined interrupt pin */
+}
+
+ISR(INT2_vect, ISR_BLOCK)
+{
+    irq_handler(2); /**< predefined interrupt pin */
+}
+
+ISR(INT3_vect, ISR_BLOCK)
+{
+    irq_handler(3); /**< predefined interrupt pin */
+}
+
+ISR(INT4_vect, ISR_BLOCK)
+{
+    irq_handler(4); /**< predefined interrupt pin */
+}
+
+ISR(INT5_vect, ISR_BLOCK)
+{
+    irq_handler(5); /**< predefined interrupt pin */
+}
+
+ISR(INT6_vect, ISR_BLOCK)
+{
+    irq_handler(6); /**< predefined interrupt pin */
+}
+
+ISR(INT7_vect, ISR_BLOCK)
+{
+    irq_handler(7); /**< predefined interrupt pin */
+}