diff --git a/boards/microbit/include/board.h b/boards/microbit/include/board.h
index 61551cdf5c9708a580d7e6e0e0851eb45c6ae7d5..c111003c7a33d498d0fcea97dfa728cf29248b46 100644
--- a/boards/microbit/include/board.h
+++ b/boards/microbit/include/board.h
@@ -68,7 +68,7 @@ extern "C" {
  * @name    MMA8653 accelerometer configuration
  * @{
  */
-#define MMA8653_PARAM_I2C           I2C_0,
+#define MMA8653_PARAM_I2C           I2C_DEV(0)
 #define MMA8653_PARAM_ADDR          0x1d
 /** @} */
 
@@ -76,7 +76,7 @@ extern "C" {
  * @name    MAG3110 magnetometer configuration
  * @{
  */
-#define MAG3110_PARAM_I2C           I2C_0,
+#define MAG3110_PARAM_I2C           I2C_DEV(0)
 #define MAG3110_PARAM_ADDR          0x0e
 /** @} */
 
diff --git a/boards/pba-d-01-kw2x/Makefile.dep b/boards/pba-d-01-kw2x/Makefile.dep
index e3a5850980203f4d08b8a8d14970b3a6571d2c57..7382333a3da13462433708b822ffc83669468b36 100644
--- a/boards/pba-d-01-kw2x/Makefile.dep
+++ b/boards/pba-d-01-kw2x/Makefile.dep
@@ -3,6 +3,7 @@ ifneq (,$(filter netdev_default gnrc_netdev_default,$(USEMODULE)))
 endif
 
 ifneq (,$(filter saul_default,$(USEMODULE)))
+  USEMODULE += mag3110
   USEMODULE += mma8x5x
   USEMODULE += hdc1000
   USEMODULE += tcs37727
diff --git a/boards/pba-d-01-kw2x/include/mag3110_params.h b/boards/pba-d-01-kw2x/include/mag3110_params.h
new file mode 100644
index 0000000000000000000000000000000000000000..d85c9c3d8ea527c7c993a1efb8182479e11e0a04
--- /dev/null
+++ b/boards/pba-d-01-kw2x/include/mag3110_params.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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     boards_pba-d-01-kw2x
+ * @{
+ *
+ * @file
+ * @brief       MAG3110 board specific configuration
+ *
+ * @author      Sebastian Meiling <s@mlng.net>
+ */
+
+#ifndef MAG3110_PARAMS_H
+#define MAG3110_PARAMS_H
+
+#include "board.h"
+#include "saul_reg.h"
+#include "mag3110.h"
+#include "mag3110_reg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief    MAG3310 configuration
+ */
+static const  mag3110_params_t mag3110_params[] =
+{
+    {
+        .i2c    = MAG3110_I2C,
+        .addr   = MAG3110_ADDR,
+        .type   = MAG3110_ID,
+        .dros   = MAG3110_DROS_DEFAULT,
+        .offset = { 0, 0, 0 }
+    }
+};
+
+/**
+ * @brief   Additional meta information to keep in the SAUL registry
+ */
+static const saul_reg_info_t mag3110_saul_info[] =
+{
+    {
+        .name = "mag3110"
+    }
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAG3110_PARAMS_H */
+/** @} */
diff --git a/drivers/include/mag3110.h b/drivers/include/mag3110.h
index 0c924fd357cfa448dfb2cd7c93f1f2614c5469ab..5669e0a3c7a7e658782b52443d2843b773f3d9b9 100644
--- a/drivers/include/mag3110.h
+++ b/drivers/include/mag3110.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 PHYTEC Messtechnik GmbH
+ *               2017 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
@@ -25,6 +26,7 @@
  * @brief       Interface definition for the MAG3110 magnetometer driver.
  *
  * @author      Johann Fischer <j.fischer@phytec.de>
+ * @author      Sebastian Meiling <s@mlng.net>
  */
 
 #ifndef MAG3110_H
@@ -39,6 +41,16 @@ extern "C"
 {
 #endif
 
+/**
+ * @brief   Named return values
+ */
+enum {
+    MAG3110_OK,                 /**< all good */
+    MAG3110_ERROR_I2C,          /**< I2C communication failed */
+    MAG3110_ERROR_DEV,          /**< Device MAG3110 not found */
+    MAG3110_ERROR_CNF,          /**< Device configuration failed */
+};
+
 #ifndef MAG3110_I2C_ADDRESS
 #define MAG3110_I2C_ADDRESS             0x0E /**< Magnetometer Default Address */
 #endif
@@ -77,41 +89,45 @@ extern "C"
 #define MAG3110_DROS_0008_128   31 /**< Output Rate 0.08 Hz, Over Sample Ratio 128 */
 #define MAG3110_DROS_DEFAULT    MAG3110_DROS_0125_128 /**< Default Setting for testing */
 
+/**
+ * @brief   Configuration parameters
+ */
+typedef struct {
+    i2c_t i2c;                  /**< I2C bus the device is connected to */
+    uint8_t addr;               /**< I2C bus address of the device */
+    uint8_t type;               /**< device type */
+    uint8_t dros;               /**< sampling rate to use */
+    int16_t offset[3];          /**< data offset in X, Y, and Z direction */
+} mag3110_params_t;
+
 /**
  * @brief Device descriptor for MAG3110 magnetometer.
  */
 typedef struct {
-    i2c_t i2c;              /**< I2C device, the magnetometer is connected to */
-    uint8_t addr;           /**< the magnetometer's slave address on the I2C bus */
-    bool initialized;       /**< magnetometer status, true if magnetometer is initialized */
+    mag3110_params_t params;    /**< device configuration parameters */
 } mag3110_t;
 
 /**
- * @brief MAG3110 magnetometer test.
- * This function looks for Device ID of the MAG3110 magnetometer.
- *
- * @param[in]  dev          device descriptor of magnetometer
- *
- * @return                  0 on success
- * @return                  -1 on error
+ * @brief   Data type for the result data
  */
-int mag3110_test(mag3110_t *dev);
+typedef struct {
+    int16_t x;                  /**< acceleration in X direction */
+    int16_t y;                  /**< acceleration in Y direction */
+    int16_t z;                  /**< acceleration in Z direction */
+} mag3110_data_t;
 
 /**
  * @brief Initialise the MAG3110 magnetometer driver.
  *
  * @param[out] dev          device descriptor of magnetometer to initialize
- * @param[in]  i2c          I2C bus the magnetometer is connected to
- * @param[in]  address      magnetometer's I2C slave address
- * @param[in]  dros         data rate and over sampling selection
+ * @param[in]  params       configuration parameters
  *
  * @return                  0 on success
- * @return                  -1 if dros parameter is wrong
- * @return                  -2 if initialization of I2C bus failed
- * @return                  -3 if magnetometer test failed
- * @return                  -4 if magnetometer configuration failed
+ * @return                  -1 if I2C communication failed
+ * @return                  -2 if magnetometer test failed
+ * @return                  -3 if magnetometer configuration failed
  */
-int mag3110_init(mag3110_t *dev, i2c_t i2c, uint8_t address, uint8_t dros);
+int mag3110_init(mag3110_t *dev, const mag3110_params_t *params);
 
 /**
  * @brief Set user offset correction.
@@ -163,16 +179,13 @@ int mag3110_is_ready(mag3110_t *dev);
  * To get the actual values for the magnetic field in \f$\mu T\f$,
  * one have to divide the returned values from the magnetometer by 10.
  *
- * @param[in]  dev          device descriptor of magnetometer
- * @param[out] x            x-axis magnetic field strength
- * @param[out] y            y-axis magnetic field strength
- * @param[out] z            z-axis magnetic field strength
- * @param[out] status       magnetometer status register
+ * @param[in]  dev          device descriptor of accelerometer
+ * @param[out] data         the current magnetic field strength
  *
  * @return                  0 on success
  * @return                  -1 on error
  */
-int mag3110_read(mag3110_t *dev, int16_t *x, int16_t *y, int16_t *z, uint8_t *status);
+int mag3110_read(mag3110_t *dev, mag3110_data_t *data);
 
 /**
  * @brief Read die temperature.
diff --git a/drivers/mag3110/include/mag3110_params.h b/drivers/mag3110/include/mag3110_params.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0aa1f52903acee680a3f4872cc64cb852837448
--- /dev/null
+++ b/drivers/mag3110/include/mag3110_params.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017   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     drivers_mag3110
+ * @{
+ *
+ * @file
+ * @brief       Default configuration for MAG3110 devices
+ *
+ * @author      Sebastian Meiling <s@mlng.net>
+ */
+
+#ifndef MAG3110_PARAMS_H
+#define MAG3110_PARAMS_H
+
+#include "board.h"
+#include "saul_reg.h"
+#include "mag3110.h"
+#include "mag3110_reg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name   Default configuration parameters for the MAG3110 driver
+ * @{
+ */
+#ifndef MAG3110_PARAM_I2C
+#define MAG3110_PARAM_I2C       (I2C_DEV(0))
+#endif
+#ifndef MAG3110_PARAM_ADDR
+#define MAG3110_PARAM_ADDR      (MAG3110_I2C_ADDRESS)
+#endif
+#ifndef MAG3110_PARAM_OFFSET
+#define MAG3110_PARAM_OFFSET    { 0, 0, 0 }
+#endif
+#ifndef MAG3110_PARAMS
+#define MAG3110_PARAMS          { .i2c    = MAG3110_PARAM_I2C, \
+                                  .addr   = MAG3110_PARAM_ADDR, \
+                                  .type   = MAG3110_ID, \
+                                  .dros   = MAG3110_DROS_DEFAULT, \
+                                  .offset = MAG3110_PARAM_OFFSET }
+#endif
+/**@}*/
+
+/**
+ * @brief   MAG3110 configuration
+ */
+static const mag3110_params_t mag3110_params[] =
+{
+    MAG3110_PARAMS
+};
+
+/**
+ * @brief   Additional meta information to keep in the SAUL registry
+ */
+static const saul_reg_info_t mag3110_saul_info[] =
+{
+    {
+        .name = "mag3110"
+    }
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAG3110_PARAMS_H */
+/** @} */
diff --git a/drivers/mag3110/mag3110.c b/drivers/mag3110/mag3110.c
index c135c4ba5e47ea39d909fd2693f9ba78588a113e..752f56d769dc88964942285cab445b9af52c7c3c 100644
--- a/drivers/mag3110/mag3110.c
+++ b/drivers/mag3110/mag3110.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 PHYTEC Messtechnik GmbH
+ *               2017 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
@@ -16,92 +17,91 @@
  *
  * @author      Johann Fischer <j.fischer@phytec.de>
  * @author      Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
+ * @author      Sebastian Meiling <s@mlng.net>
  *
  * @}
  */
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <string.h>
+
+#include "log.h"
 #include "periph/i2c.h"
+
 #include "mag3110.h"
 #include "mag3110_reg.h"
 
 #define ENABLE_DEBUG    (0)
 #include "debug.h"
 
-#define I2C_SPEED                  I2C_SPEED_FAST
-
-int mag3110_test(mag3110_t *dev)
-{
-    uint8_t reg;
-
-    /* Acquire exclusive access to the bus. */
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_WHO_AM_I, &reg, 1) != 1) {
-        /* Release the bus for other threads. */
-        i2c_release(dev->i2c);
-        return -1;
-    }
-    i2c_release(dev->i2c);
-
-    if (reg != MAG3110_ID) {
-        return -1;
-    }
+#define I2C_SPEED           I2C_SPEED_FAST
 
-    return 0;
-}
+#define BUS                 (dev->params.i2c)
+#define ADDR                (dev->params.addr)
 
-int mag3110_init(mag3110_t *dev, i2c_t i2c, uint8_t address, uint8_t dros)
+int mag3110_init(mag3110_t *dev, const mag3110_params_t *params)
 {
     uint8_t reg;
 
-    /* write device descriptor */
-    dev->i2c = i2c;
-    dev->addr = address;
-    dev->initialized = false;
+    assert(dev);
+    assert(params);
 
-    if (dros > MAG3110_DROS_0008_128) {
-        return -1;
-    }
+    /* write device descriptor */
+    memcpy(dev, params, sizeof(mag3110_params_t));
 
-    i2c_acquire(dev->i2c);
+    i2c_acquire(BUS);
     /* initialize the I2C bus */
-    if (i2c_init_master(i2c, I2C_SPEED) < 0) {
-        i2c_release(dev->i2c);
-        return -2;
-    }
-    i2c_release(dev->i2c);
-
-    if (mag3110_test(dev)) {
-        return -3;
+    if (i2c_init_master(BUS, I2C_SPEED) < 0) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: failed!\n");
+        return -MAG3110_ERROR_I2C;
+    }
+    /* test device */
+    i2c_read_regs(BUS, ADDR, MAG3110_WHO_AM_I, &reg, 1);
+    if (reg != dev->params.type) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: invalid WHO_AM_I value (0x%02x)!\n", (int)reg);
+        return -MAG3110_ERROR_DEV;
     }
-
     /* enable automatic magnetic sensor reset */
     reg = MAG3110_CTRL_REG2_AUTO_MRST_EN;
-
-    i2c_acquire(dev->i2c);
-    if (i2c_write_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG2, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -4;
-    }
-
-    reg = MAG3110_CTRL_REG1_DROS(dros);
-
-    if (i2c_write_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG1, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -4;
+    if (i2c_write_regs(BUS, ADDR, MAG3110_CTRL_REG2, &reg, 1) != 1) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: failed to enable auto reset!\n");
+        return -MAG3110_ERROR_CNF;
+    }
+    /* set sample rate */
+    reg = MAG3110_CTRL_REG1_DROS(dev->params.dros);
+    if (i2c_write_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: failed to set sample rate!\n");
+        return -MAG3110_ERROR_CNF;
+    }
+    /* set device active */
+    if (i2c_read_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: failed to read device state!\n");
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
-
-    dev->initialized = true;
-
-    return 0;
+    reg |= MAG3110_CTRL_REG1_AC;
+    if (i2c_write_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_init: failed to set device active!\n");
+        return -MAG3110_ERROR_CNF;
+    }
+    i2c_release(BUS);
+    /* write user offsets */
+    return mag3110_set_user_offset(dev, dev->params.offset[0],
+                                   dev->params.offset[1], dev->params.offset[2]);
 }
 
 int mag3110_set_user_offset(mag3110_t *dev, int16_t x, int16_t y, int16_t z)
 {
     uint8_t buf[6];
 
+    assert(dev);
+
     buf[0] = (x >> 8);
     buf[1] = x;
     buf[2] = (y >> 8);
@@ -109,115 +109,114 @@ int mag3110_set_user_offset(mag3110_t *dev, int16_t x, int16_t y, int16_t z)
     buf[4] = (z >> 8);
     buf[5] = z;
 
-    i2c_acquire(dev->i2c);
-    if (i2c_write_regs(dev->i2c, dev->addr, MAG3110_OFF_X_MSB, buf, 6) != 6) {
-        i2c_release(dev->i2c);
-        return -1;
+    DEBUG("[mag3110] setting user offset to X: %3i, Y: %3i, Z: %3i\n",
+          (int)x, (int)y, (int)z);
+
+    i2c_acquire(BUS);
+    if (i2c_write_regs(BUS, ADDR, MAG3110_OFF_X_MSB, buf, 6) != 6) {
+        i2c_release(BUS);
+        LOG_ERROR("mag3110_set_user_offset: failed to set offsets!\n");
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
+    i2c_release(BUS);
 
-    return 0;
+    return MAG3110_OK;
 }
 
 int mag3110_set_active(mag3110_t *dev)
 {
     uint8_t reg;
 
-    if (dev->initialized == false) {
-        return -1;
-    }
+    assert(dev);
 
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG1, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    i2c_acquire(BUS);
+    if (i2c_read_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
 
     reg |= MAG3110_CTRL_REG1_AC;
 
-    if (i2c_write_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG1, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    if (i2c_write_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
+    i2c_release(BUS);
 
-    return 0;
+    return MAG3110_OK;
 }
 
 int mag3110_set_standby(mag3110_t *dev)
 {
     uint8_t reg;
 
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG1, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    assert(dev);
+
+    i2c_acquire(BUS);
+    if (i2c_read_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
 
     reg &= ~MAG3110_CTRL_REG1_AC;
 
-    if (i2c_write_regs(dev->i2c, dev->addr, MAG3110_CTRL_REG1, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    if (i2c_write_regs(BUS, ADDR, MAG3110_CTRL_REG1, &reg, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
+    i2c_release(BUS);
 
-    return 0;
+    return MAG3110_OK;
 }
 
 int mag3110_is_ready(mag3110_t *dev)
 {
     uint8_t reg;
 
-    if (dev->initialized == false) {
-        return -1;
-    }
+    assert(dev);
 
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_DR_STATUS, &reg, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    i2c_acquire(BUS);
+    if (i2c_read_regs(BUS, ADDR, MAG3110_DR_STATUS, &reg, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
+    i2c_release(BUS);
 
     return (int)(reg & MAG3110_DR_STATUS_ZYXDR);
 }
 
-int mag3110_read(mag3110_t *dev, int16_t *x, int16_t *y, int16_t *z, uint8_t *status)
+int mag3110_read(mag3110_t *dev, mag3110_data_t *data)
 {
     uint8_t buf[7];
 
-    if (dev->initialized == false) {
-        return -1;
-    }
+    assert(dev);
 
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_DR_STATUS, buf, 7) != 7) {
-        i2c_release(dev->i2c);
-        return -1;
+    i2c_acquire(BUS);
+    if (i2c_read_regs(BUS, ADDR, MAG3110_DR_STATUS, buf, 7) != 7) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
-
-    *status = buf[0];
-    *x = ((int16_t)buf[1] << 8) | buf[2];
-    *y = ((int16_t)buf[3] << 8) | buf[4];
-    *z = ((int16_t)buf[5] << 8) | buf[6];
+    i2c_release(BUS);
+    /* TODO: implement state handling, if needed?
+    uint8_t status = buf[0];
+    */
+    data->x = ((int16_t)buf[1] << 8) | buf[2];
+    data->y = ((int16_t)buf[3] << 8) | buf[4];
+    data->z = ((int16_t)buf[5] << 8) | buf[6];
 
-    return 0;
+    return MAG3110_OK;
 }
 
 int mag3110_read_dtemp(mag3110_t *dev, int8_t *dtemp)
 {
-    if (dev->initialized == false) {
-        return -1;
-    }
+    assert(dev);
 
-    i2c_acquire(dev->i2c);
-    if (i2c_read_regs(dev->i2c, dev->addr, MAG3110_DIE_TEMP, dtemp, 1) != 1) {
-        i2c_release(dev->i2c);
-        return -1;
+    i2c_acquire(BUS);
+    if (i2c_read_regs(BUS, ADDR, MAG3110_DIE_TEMP, dtemp, 1) != 1) {
+        i2c_release(BUS);
+        return -MAG3110_ERROR_I2C;
     }
-    i2c_release(dev->i2c);
+    i2c_release(BUS);
 
-    return 0;
+    return MAG3110_OK;
 }
diff --git a/drivers/mag3110/mag3110_saul.c b/drivers/mag3110/mag3110_saul.c
new file mode 100644
index 0000000000000000000000000000000000000000..c890ab4f56eb6befb1b73e954c44701e664e81a6
--- /dev/null
+++ b/drivers/mag3110/mag3110_saul.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 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_mag3110
+ * @{
+ *
+ * @file
+ * @brief       MAG3110 adaption to the RIOT actuator/sensor interface
+ *
+ * @author      Sebastian Meiling <s@mlng.net>
+ *
+ * @}
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "saul.h"
+#include "mag3110.h"
+
+static int read_mag(void *dev, phydat_t *res)
+{
+    mag3110_read((mag3110_t *)dev, (mag3110_data_t *)res);
+
+    res->unit = UNIT_GS;
+    res->scale = 2;
+
+    return 3;
+}
+
+const saul_driver_t mag3110_saul_driver = {
+    .read = read_mag,
+    .write = saul_notsup,
+    .type = SAUL_SENSE_MAG,
+};
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index 251b5bf1bf17ffce4f3022ff9f25b84b4055a734..30fc3be9de854c03990cef6bbf22958b977cac19 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -271,6 +271,10 @@ void auto_init(void)
     extern void auto_init_lis3dh(void);
     auto_init_lis3dh();
 #endif
+#ifdef MODULE_MAG3110
+    extern void auto_init_mag3110(void);
+    auto_init_mag3110();
+#endif
 #ifdef MODULE_MMA8X5X
     extern void auto_init_mma8x5x(void);
     auto_init_mma8x5x();
diff --git a/sys/auto_init/saul/auto_init_mag3110.c b/sys/auto_init/saul/auto_init_mag3110.c
new file mode 100644
index 0000000000000000000000000000000000000000..ac08bae1ae752ac12f2aa087d7d15dbb1a0f61a0
--- /dev/null
+++ b/sys/auto_init/saul/auto_init_mag3110.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 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     auto_init_saul
+ * @{
+ *
+ * @file
+ * @brief       Auto initialization of MAG3110 magnetometers
+ *
+ * @author      Sebastian Meiling <s@mlng.net>
+ *
+ * @}
+ */
+
+#ifdef MODULE_MAG3110
+
+#include "log.h"
+#include "saul_reg.h"
+
+#include "mag3110.h"
+#include "mag3110_params.h"
+
+/**
+ * @brief   Define the number of configured sensors
+ */
+#define MAG3110_NUM     (sizeof(mag3110_params) / sizeof(mag3110_params[0]))
+
+/**
+ * @brief   Allocate memory for the device descriptors
+ */
+static mag3110_t mag3110_devs[MAG3110_NUM];
+
+/**
+ * @brief   Memory for the SAUL registry entries
+ */
+static saul_reg_t saul_entries[MAG3110_NUM];
+
+/**
+ * @brief   Reference the driver struct
+ * @{
+ */
+extern const saul_driver_t mag3110_saul_driver;
+/** @} */
+
+void auto_init_mag3110(void)
+{
+    for (unsigned i = 0; i < MAG3110_NUM; i++) {
+        LOG_DEBUG("[auto_init_saul] initializing mag3110 #%u\n", i);
+
+        if (mag3110_init(&mag3110_devs[i], &mag3110_params[i]) != MAG3110_OK) {
+            LOG_ERROR("[auto_init_saul] error initializing mag3110 #%u\n", i);
+            continue;
+        }
+
+        saul_entries[i].dev = &(mag3110_devs[i]);
+        saul_entries[i].name = mag3110_saul_info[i].name;
+        saul_entries[i].driver = &mag3110_saul_driver;
+        saul_reg_add(&(saul_entries[i]));
+    }
+}
+
+#else
+typedef int dont_be_pedantic;
+#endif /* MODULE_MAG3110 */
diff --git a/tests/driver_mag3110/Makefile b/tests/driver_mag3110/Makefile
index 8c1fe5502d04507b9cc9ee4f7aa1a6220a95f3e6..9462018592e0ed947e95ac3fd9293cdb14c7086c 100644
--- a/tests/driver_mag3110/Makefile
+++ b/tests/driver_mag3110/Makefile
@@ -6,18 +6,4 @@ FEATURES_REQUIRED = periph_i2c
 USEMODULE += mag3110
 USEMODULE += xtimer
 
-# set default device parameters in case they are undefined
-TEST_MAG3110_I2C           ?= I2C_DEV\(0\)
-TEST_MAG3110_ADDR          ?= 0x0E
-TEST_MAG3110_USER_OFFSET_X ?= -2000
-TEST_MAG3110_USER_OFFSET_Y ?= 180
-TEST_MAG3110_USER_OFFSET_Z ?= 210
-
-# export parameters
-CFLAGS += -DTEST_MAG3110_I2C=$(TEST_MAG3110_I2C)
-CFLAGS += -DTEST_MAG3110_ADDR=$(TEST_MAG3110_ADDR)
-CFLAGS += -DTEST_MAG3110_USER_OFFSET_X=$(TEST_MAG3110_USER_OFFSET_X)
-CFLAGS += -DTEST_MAG3110_USER_OFFSET_Y=$(TEST_MAG3110_USER_OFFSET_Y)
-CFLAGS += -DTEST_MAG3110_USER_OFFSET_Z=$(TEST_MAG3110_USER_OFFSET_Z)
-
 include $(RIOTBASE)/Makefile.include
diff --git a/tests/driver_mag3110/main.c b/tests/driver_mag3110/main.c
index 603d12bc2a7f4503ea5569e05cdc65800d220d6e..003872d8385a6147ae98f4bd74fc19218f2f4bfd 100644
--- a/tests/driver_mag3110/main.c
+++ b/tests/driver_mag3110/main.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2014 Freie Universität Berlin
  * Copyright (C) 2014 PHYTEC Messtechnik GmbH
+ *               2017 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
@@ -16,57 +17,41 @@
  *
  * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
  * @author      Johann Fischer <j.fischer@phytec.de>
+ * @author      Sebastian Meiling <s@mlng.net>
  *
  * @}
  */
 
-#ifndef TEST_MAG3110_I2C
-#error "TEST_MAG3110_I2C not defined"
-#endif
-#ifndef TEST_MAG3110_ADDR
-#error "TEST_MAG3110_ADDR not defined"
-#endif
-
 #include <stdio.h>
 
+#include "timex.h"
 #include "xtimer.h"
+
 #include "mag3110.h"
+#include "mag3110_params.h"
+
+#define SLEEP       (1U * US_PER_SEC)
 
-#define SLEEP       (1000 * 1000U)
+static mag3110_t dev;
 
 int main(void)
 {
-    mag3110_t dev;
+    mag3110_data_t data;
     int8_t temp;
-    int16_t x, y, z;
-    uint8_t status;
 
     puts("MAG3110 magnetometer driver test application\n");
-    printf("Initializing MAG3110 magnetometer at I2C_%i... ", TEST_MAG3110_I2C);
-    if (mag3110_init(&dev, TEST_MAG3110_I2C, TEST_MAG3110_ADDR, MAG3110_DROS_DEFAULT) == 0) {
-        puts("[OK]\n");
-    }
-    else {
-        puts("[Failed]");
-        return -1;
-    }
-
-    if (mag3110_set_user_offset(&dev, TEST_MAG3110_USER_OFFSET_X,
-                                     TEST_MAG3110_USER_OFFSET_Y,
-                                     TEST_MAG3110_USER_OFFSET_Z )) {
-        puts("Set user offset correction failed.");
-        return -1;
-    }
-
-    if (mag3110_set_active(&dev)) {
-        puts("Measurement start failed.");
+    printf("Initializing MAG3110 magnetometer at I2C_%i... ",
+           mag3110_params[0].i2c);
+    if (mag3110_init(&dev, &mag3110_params[0]) != MAG3110_OK) {
+        puts("[FAILED]");
         return -1;
     }
+    puts("[SUCCESS]");
 
     while (1) {
         xtimer_usleep(SLEEP);
-        mag3110_read(&dev, &x, &y, &z, &status);
-        printf("Field strength: X: %d Y: %d Z: %d S: %2x\n", x, y, z, status);
+        mag3110_read(&dev, &data);
+        printf("Field strength: X: %d Y: %d Z: %d\n", data.x, data.y, data.z);
         mag3110_read_dtemp(&dev, &temp);
         printf("Die Temperature T: %d\n", temp);
     }