diff --git a/boards/weio/include/periph_conf.h b/boards/weio/include/periph_conf.h
index 8eff676a5f52a738b9498dd30d2faae003bc3642..597ceee93a41fa852d27948549d5b6c3c3a5964b 100644
--- a/boards/weio/include/periph_conf.h
+++ b/boards/weio/include/periph_conf.h
@@ -81,9 +81,20 @@ extern "C" {
  * @brief SPI configuration
  * @{
  */
-#define SPI_NUMOF           (2U)
-#define SPI_0_EN            1
-#define SPI_1_EN            1
+static const spi_conf_t spi_config[] = {
+    {
+        .dev        = LPC_SSP0,
+        .preset_bit = (1 << 0),
+        .ahb_bit    = (1 << 11)
+    },
+    {
+        .dev        = LPC_SSP1,
+        .preset_bit = (1 << 2),
+        .ahb_bit    = (1 << 18)
+    }
+};
+
+#define SPI_NUMOF           (sizeof(spi_config) / sizeof(spi_config[0]))
 /* @} */
 
 /**
diff --git a/cpu/lpc11u34/include/periph_cpu.h b/cpu/lpc11u34/include/periph_cpu.h
index c288c49370264288b715493e62af8e80786ef6bd..f498de2a5e0c5d6c8a8c294300bfb3d9245d9d73 100644
--- a/cpu/lpc11u34/include/periph_cpu.h
+++ b/cpu/lpc11u34/include/periph_cpu.h
@@ -31,7 +31,8 @@ extern "C" {
  * @brief declare needed generic SPI functions
  * @{
  */
-#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_INIT_CS
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
 #define PERIPH_SPI_NEEDS_TRANSFER_REG
 #define PERIPH_SPI_NEEDS_TRANSFER_REGS
 /** @} */
@@ -104,11 +105,6 @@ typedef enum {
 /** @} */
 #endif /* ndef DOXYGEN */
 
-/**
- * @brief   PWM channel configuration
- */
-
-
 /**
  * @brief   PWM configuration
  */
@@ -119,6 +115,31 @@ typedef struct {
     uint8_t af;
 } pwm_conf_t;
 
+/**
+ * @brief   Override SPI clock speed values
+ *
+ * @note    The values expect the CPU to run at 12MHz
+ * @todo    Generalize the SPI driver
+ */
+#define HAVE_SPI_CLK_T
+typedef enum {
+    SPI_CLK_100KHZ = 119,         /**< drive the SPI bus with 100KHz */
+    SPI_CLK_400KHZ =  29,         /**< drive the SPI bus with 400KHz */
+    SPI_CLK_1MHZ   =  11,           /**< drive the SPI bus with 1MHz */
+    SPI_CLK_5MHZ   =   2,           /**< drive the SPI bus with 5MHz */
+    SPI_CLK_10MHZ  =   0        /**< actual: 12 MHz */
+} spi_clk_t;
+
+
+/**
+ * @brief   SPI configuration data
+ */
+typedef struct {
+    LPC_SSPx_Type *dev;     /**< SPI device to configure */
+    uint32_t preset_bit;    /**< mask of the corresponding preset bit */
+    uint32_t ahb_bit;       /**< mask of the corresponding AHB bit */
+} spi_conf_t;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/lpc11u34/periph/spi.c b/cpu/lpc11u34/periph/spi.c
index 325d73fbc363148b20d8d2b1f1f0e37374b4ea63..53672526b9e13cff9a18e947efff3d7d3c8d332f 100644
--- a/cpu/lpc11u34/periph/spi.c
+++ b/cpu/lpc11u34/periph/spi.c
@@ -1,118 +1,86 @@
 /*
- * Copyright (C) 2015 Freie Universität Berlin
+ * Copyright (C) 2015-2016 Freie Universität Berlin
  *
- * 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.
+ * 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     cpu_lpc11u34
  * @{
  *
  * @file
- * @brief       Low-level GPIO driver implementation
+ * @brief       Low-level SPI driver implementation
+ *
+ * @todo        this implementation needs to be generalized in some aspects,
+ *              e.g. clock configuration
  *
  * @author      Paul RATHGEB <paul.rathgeb@skynet.be>
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
  *
  * @}
  */
 
 #include "cpu.h"
-#include "board.h"
 #include "mutex.h"
+#include "assert.h"
 #include "periph/spi.h"
-#include "periph_conf.h"
-#include "thread.h"
-#include "sched.h"
-
-/* guard file in case no SPI device is defined */
-#if SPI_NUMOF
 
 /**
  * @brief Array holding one pre-initialized mutex for each SPI device
  */
-static mutex_t locks[] =  {
-#if SPI_0_EN
-    [SPI_0] = MUTEX_INIT,
-#endif
-#if SPI_1_EN
-    [SPI_1] = MUTEX_INIT,
-#endif
-};
-
-int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
-{
-    LPC_SSPx_Type *spi;
-    /* power on the SPI device */
-    spi_poweron(dev);
-
-    /* configure SCK, MISO and MOSI pin */
-    spi_conf_pins(dev);
+static mutex_t locks[SPI_NUMOF];
 
-    switch(dev) {
-#if SPI_0_EN
-        case SPI_0:
-            spi = LPC_SSP0;
-            break;
-#endif
-#if SPI_1_EN
-        case SPI_1:
-            spi = LPC_SSP1;
-            break;
-#endif
-        default:
-            return -1;
-    }
+static inline LPC_SSPx_Type *dev(spi_t bus)
+{
+    return spi_config[bus].dev;
+}
 
-    /* Master mode, SPI disabled */
-    spi->CR1 = 0;
-    /* Base clock frequency : 12MHz */
-    spi->CPSR = 4;
-    /* configure bus clock speed */
-    switch (speed) {
-        case SPI_SPEED_100KHZ:
-            spi->CR0 |= (119 << 8);
-            break;
-        case SPI_SPEED_400KHZ:
-            spi->CR0 |= (29 << 8);
-            break;
-        case SPI_SPEED_1MHZ:
-            spi->CR0 |= (11 << 8);
-            break;
-        case SPI_SPEED_5MHZ:
-            spi->CR0 |= (2 << 8); /* Actual : 4MHz */
-            break;
-        case SPI_SPEED_10MHZ:
-            spi->CR0 |= (0 << 8); /* Actual : 12MHz */
-            break;
-    }
-    /* Set mode and 8-bit transfer */
-    spi->CR0 |= 0x07 | (conf << 6);
-    /* Enable SPI */
-    spi->CR1 |= (1 << 1);
-
-    /* Wait while the BUSY flag is set */
-    while(spi->SR & (1 << 4)) {}
-    /* Clear the RX FIFO */
-    while(spi->SR & (1 << 2)) {
-        spi->DR;
-    }
+static inline void poweron(spi_t bus)
+{
+    /* de-assert SPIx, enable clock and set clock div */
+    LPC_SYSCON->PRESETCTRL |= (spi_config[bus].preset_bit);
+    LPC_SYSCON->SYSAHBCLKCTRL |= (spi_config[bus].ahb_bit);
+}
 
-    return 0;
+static inline void poweroff(spi_t bus)
+{
+    LPC_SYSCON->SYSAHBCLKCTRL &= ~(spi_config[bus].ahb_bit);
+    LPC_SYSCON->PRESETCTRL &= ~(spi_config[bus].preset_bit);
 }
 
-int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char data))
+void spi_init(spi_t bus)
 {
-    /* Slave mode not supported */
-    return -1;
+    /* check device */
+    assert(bus <= SPI_NUMOF);
+
+    /* initialize device lock */
+    mutex_init(&locks[bus]);
+
+    /* set clock div for all SPI devices to 1 -> 48MHz */
+    LPC_SYSCON->SSP0CLKDIV = 1;
+    LPC_SYSCON->SSP1CLKDIV = 1;
+
+    /* trigger the pin configuration */
+    spi_init_pins(bus);
+
+    /* power on the bus for the duration of initialization */
+    poweron(bus);
+    /* reset configuration */
+    dev(bus)->CR1 = 0;
+    /* configure base clock frequency to 12 MHz CLOCK_CORECLOCK / 4 */
+    dev(bus)->CPSR = 4;
+    /* and power off the bus again */
+    poweroff(bus);
 }
 
-int spi_conf_pins(spi_t dev)
+void spi_init_pins(spi_t bus)
 {
-    switch (dev) {
-#if SPI_0_EN
-        case SPI_0:
+    /* this is hacky as hell -> integrate this into the GPIO module */
+    switch (bus) {
+        case SPI_DEV(0):
             /* SPI0 : MISO */
             LPC_IOCON->PIO0_8 |= 1;
             /* SPI0 : MOSI */
@@ -120,128 +88,69 @@ int spi_conf_pins(spi_t dev)
             /* SPI0 : SCK */
             LPC_IOCON->SWCLK_PIO0_10 |= 2;
             break;
-#endif
-#if SPI_1_EN
-        case SPI_1:
+        case SPI_DEV(1):
             /* SPI1 : MISO */
             LPC_IOCON->PIO1_21 |= 2;
             /* SPI1 : MOSI */
             LPC_IOCON->PIO0_21 |= 2;
             /* SPI1 : SCK */
             LPC_IOCON->PIO1_20 |= 2;
-#endif
         default:
-            return -1;
+            break;
     }
-
-    return 0;
 }
 
-int spi_acquire(spi_t dev)
+int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
 {
-    if ((unsigned int)dev >= SPI_NUMOF) {
-        return -1;
+    /* lock an power on the bus */
+    mutex_lock(&locks[bus]);
+    poweron(bus);
+
+    /* configure bus clock and mode and set to 8-bit transfer */
+    dev(bus)->CR0 = ((clk << 8) | (mode << 6) | 0x07);
+    /* enable the bus */
+    dev(bus)->CR1 = (1 << 1);
+    /* wait until ready and flush RX FIFO */
+    while(dev(bus)->SR & (1 << 4)) {}
+    while(dev(bus)->SR & (1 << 2)) {
+        dev(bus)->DR;
     }
-    mutex_lock(&locks[dev]);
-    return 0;
+
+    return SPI_OK;
 }
 
-int spi_release(spi_t dev)
+void spi_release(spi_t bus)
 {
-    if ((unsigned int)dev >= SPI_NUMOF) {
-        return -1;
-    }
-    mutex_unlock(&locks[dev]);
-    return 0;
+    /* disable device, power off and release lock */
+    dev(bus)->CR1 = 0;
+    poweroff(bus);
+    mutex_unlock(&locks[bus]);
 }
 
-int spi_transfer_byte(spi_t dev, char out, char *in)
+void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
+                        const void *out, void *in, size_t len)
 {
-    char tmp;
-    LPC_SSPx_Type *spi;
+    uint8_t *out_buf = (uint8_t *)out;
+    uint8_t *in_buf = (uint8_t *)in;
 
-    switch (dev) {
-#if SPI_0_EN
-        case SPI_0:
-            spi = LPC_SSP0;
-            break;
-#endif
-#if SPI_1_EN
-        case SPI_1:
-            spi = LPC_SSP1;
-            break;
-#endif
-        default:
-            return 0;
-    }
+    assert(out_buf || in_buf);
 
-    /* Wait while the BUSY flag is set */
-    while(spi->SR & (1 << 4)) {}
-    /* Put byte in the TX Fifo */
-    *((volatile uint8_t *)(&spi->DR)) = (uint8_t)out;
-    /* Wait until the current byte is transfered */
-    while(!(spi->SR & (1 << 2)) ) {}
-    /* Read the returned byte */
-    tmp = *((volatile uint8_t *)(&spi->DR));
-    /* 'return' response byte if wished for */
-    if (in) {
-        *in = tmp;
+    if (cs != SPI_CS_UNDEF) {
+        gpio_clear((gpio_t)cs);
     }
 
-    return 1;
-}
-
-void spi_transmission_begin(spi_t dev, char reset_val)
-{
-    /* Slave mode not supported */
-}
-
-void spi_poweron(spi_t dev)
-{
-    switch (dev) {
-#if SPI_0_EN
-        case SPI_0:
-            /* De-assert SPI0 */
-            LPC_SYSCON->PRESETCTRL |= (1 << 0);
-            /* Enable SPI0 clock */
-            LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11);
-            /* Clock div : 48MHz */
-            LPC_SYSCON->SSP0CLKDIV = 1;
-            break;
-#endif
-#if SPI_1_EN
-        case SPI_1:
-            /* De-assert SPI1 */
-            LPC_SYSCON->PRESETCTRL |= (1 << 2);
-            /* Enable SPI1 clock */
-            LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 18);
-            /* Clock div : 48MHz */
-            LPC_SYSCON->SSP1CLKDIV = 1;
-            break;
-#endif
+    for (size_t i = 0; i < len; i++) {
+        uint8_t tmp = (out_buf) ? out_buf[i] : 0;
+        while(dev(bus)->SR & (1 << 4)) {}       /* wait for BUSY clear */
+        *((volatile uint8_t *)(&dev(bus)->DR)) = tmp;
+        while(!(dev(bus)->SR & (1 << 2))) {}    /* wait RXNE */
+        tmp = *((volatile uint8_t *)(&dev(bus)->DR));
+        if (in_buf) {
+            in_buf[i] = tmp;
+        }
     }
-}
 
-void spi_poweroff(spi_t dev)
-{
-    switch (dev) {
-#if SPI_0_EN
-        case SPI_0:
-            /* Assert SPI0 */
-            LPC_SYSCON->PRESETCTRL &= ~(1 << 0);
-            /* Disable SPI0 clock */
-            LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 11);
-            break;
-#endif
-#if SPI_1_EN
-        case SPI_1:
-            /* Assert SPI1 */
-            LPC_SYSCON->PRESETCTRL &= ~(1 << 2);
-            /* Disable SPI1 clock */
-            LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 18);
-            break;
-#endif
+    if ((!cont) && (cs != SPI_CS_UNDEF)) {
+        gpio_set((gpio_t)cs);
     }
 }
-
-#endif /* SPI_NUMOF */