diff --git a/cpu/kinetis_common/include/mcg.h b/cpu/kinetis_common/include/mcg.h
index 2c17c179c541d7b687eb30610680989e16959cc5..70eb2f6b16a4f68d5b4aed03ec1786fac4204805 100644
--- a/cpu/kinetis_common/include/mcg.h
+++ b/cpu/kinetis_common/include/mcg.h
@@ -10,7 +10,8 @@
  * @defgroup    cpu_kinetis_common_mcg Kinetis MCG
  * @ingroup     cpu_kinetis_common
  * @brief       Implementation of the Kinetis Multipurpose Clock Generator
- *              (MCG) driver.
+ *              (MCG) driver
+ *
  *              Please add mcg.h in cpu conf.h
  *              and MCG configuration to periph_conf.h
  *
@@ -37,6 +38,30 @@
  *              -  BLPE -> FEE
  *              -  BLPI -> FEE
  *
+ *              \dot
+ *              digraph states {
+ *                layout=dot
+ *                nodesep=0.5
+ *                {rank=same Reset [shape=none] FEI FEE}
+ *                {rank=same FBI FBE}
+ *                {rank=same BLPI BLPE}
+ *                Reset -> FEI
+ *                FEI -> FEE [dir="both"]
+ *                FEI -> FBE [dir="both"]
+ *                FEI -> FBI [dir="both"]
+ *                FEE -> FBI [dir="both"]
+ *                FEE -> FBE [dir="both"]
+ *                FBI -> FBE [dir="both"]
+ *                FBI -> BLPI [dir="both"]
+ *                FBE -> BLPE [dir="both"]
+ *                PBE
+ *                PEE
+ *                FBE -> PBE [dir="both"]
+ *                BLPE -> PBE [dir="both"]
+ *                PBE -> PEE [dir="both"]
+ *              }
+ *              \enddot
+ *
  *              ### MCG Configuration Examples (for periph_conf.h) ###
  *
  *              Example for FEI Mode (MCGOUTCLK = 20MHz ... 25MHz):
diff --git a/cpu/kinetis_common/periph/mcg.c b/cpu/kinetis_common/periph/mcg.c
index b567b348e4102cfb16987e2e4807529ac9fd426e..cb757f6f74a2afdcce103e042efbe98159619015 100644
--- a/cpu/kinetis_common/periph/mcg.c
+++ b/cpu/kinetis_common/periph/mcg.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2015 PHYTEC Messtechnik GmbH
+ * Copyright (C) 2017 Eistec AB
  *
  * 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
@@ -14,7 +15,8 @@
  * @brief       Implementation of the Kinetis Multipurpose Clock Generator
  *
  * @author      Johann Fischer <j.fischer@phytec.de>
- * @}
+ * @author      Joakim NohlgÄrd <joakim.nohlgard@eistec.se>
+ *
  */
 
 #include <stdint.h>
@@ -23,8 +25,24 @@
 
 #if KINETIS_CPU_USE_MCG
 
-/* MCG neighbor modes matrix */
-static uint8_t mcg_pm[8] = {0x02, 0x15, 0x12, 0x20, 0xe6, 0xd8, 0xb0, 0xf0};
+#if defined(MCG_C6_PLLS_MASK)
+#define KINETIS_HAVE_PLL 1
+#else
+#define KINETIS_HAVE_PLL 0
+#endif
+
+/* Pathfinding for the clocking modes, this table lists the next mode in the
+ * chain when moving from mode <first> to mode <second> */
+static const uint8_t mcg_mode_routing[8][8] = {
+    {0, 1, 1, 1, 1, 1, 1, 1}, /* from PEE */
+    {0, 1, 2, 4, 4, 4, 4, 4}, /* from PBE */
+    {1, 1, 2, 4, 4, 4, 4, 4}, /* from BLPE */
+    {5, 5, 5, 3, 5, 5, 5, 5}, /* from BLPI */
+    {1, 1, 2, 5, 4, 5, 6, 7}, /* from FBE */
+    {4, 4, 4, 3, 4, 5, 6, 7}, /* from FBI */
+    {4, 4, 4, 5, 4, 5, 6, 7}, /* from FEE */
+    {4, 4, 4, 5, 4, 5, 6, 7}, /* from FEI */
+};
 
 static uint8_t current_mode = KINETIS_MCG_FEI;
 
@@ -97,6 +115,7 @@ static uint8_t current_mode = KINETIS_MCG_FEI;
 #error "KINETIS_MCG_ERC_RANGE not defined in periph_conf.h"
 #endif
 
+#if KINETIS_HAVE_PLL
 #ifndef KINETIS_MCG_PLL_PRDIV
 #error "KINETIS_MCG_PLL_PRDIV not defined in periph_conf.h"
 #endif
@@ -118,6 +137,9 @@ static inline void kinetis_mcg_disable_pll(void)
     MCG->C5 = (uint8_t)0;
     MCG->C6 = (uint8_t)0;
 }
+#else
+static inline void kinetis_mcg_disable_pll(void) {}
+#endif /* KINETIS_HAVE_PLL */
 
 /**
  * @brief Set Frequency Locked Loop (FLL) factor.
@@ -161,7 +183,7 @@ static void kinetis_mcg_enable_osc(void)
         MCG->C2 |= (uint8_t)(MCG_C2_EREFS0_MASK);
 
         /* wait fo OSC initialization */
-        while ((MCG->S & MCG_S_OSCINIT0_MASK) == 0);
+        while ((MCG->S & MCG_S_OSCINIT0_MASK) == 0) {}
     }
 }
 
@@ -182,10 +204,10 @@ static void kinetis_mcg_set_fei(void)
     MCG->C2 = (uint8_t)0;
 
     /* source of the FLL reference clock shall be internal reference clock */
-    while ((MCG->S & MCG_S_IREFST_MASK) == 0);
+    while ((MCG->S & MCG_S_IREFST_MASK) == 0) {}
 
     /* Wait until output of the FLL is selected */
-    while (MCG->S & (MCG_S_CLKST_MASK));
+    while (MCG->S & (MCG_S_CLKST_MASK)) {}
 
     kinetis_mcg_disable_pll();
     current_mode = KINETIS_MCG_FEI;
@@ -207,7 +229,7 @@ static void kinetis_mcg_set_fee(void)
     MCG->C1 = (uint8_t)(MCG_C1_CLKS(0) | MCG_C1_FRDIV(KINETIS_MCG_ERC_FRDIV));
 
     /* Wait until output of FLL is selected */
-    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(0));
+    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(0)) {}
 
     kinetis_mcg_disable_pll();
     current_mode = KINETIS_MCG_FEE;
@@ -237,10 +259,10 @@ static void kinetis_mcg_set_fbi(void)
     MCG->C1 = (uint8_t)(MCG_C1_CLKS(1) | MCG_C1_IREFS_MASK);
 
     /* Wait until output of IRC is selected */
-    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(1));
+    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(1)) {}
 
     /* source of the FLL reference clock shall be internal reference clock */
-    while ((MCG->S & MCG_S_IREFST_MASK) == 0);
+    while ((MCG->S & MCG_S_IREFST_MASK) == 0) {}
 
     kinetis_mcg_disable_pll();
     current_mode = KINETIS_MCG_FBI;
@@ -266,7 +288,7 @@ static void kinetis_mcg_set_fbe(void)
     MCG->C1 = (uint8_t)(MCG_C1_CLKS(2) | MCG_C1_FRDIV(KINETIS_MCG_ERC_FRDIV));
 
     /* Wait until ERC is selected */
-    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2));
+    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) {}
 
     kinetis_mcg_disable_pll();
     current_mode = KINETIS_MCG_FBE;
@@ -299,6 +321,7 @@ static void kinetis_mcg_set_blpe(void)
     current_mode = KINETIS_MCG_BLPE;
 }
 
+#if KINETIS_HAVE_PLL
 /**
  * @brief Initialize the PLL Bypassed External Mode.
  *
@@ -315,7 +338,7 @@ static void kinetis_mcg_set_pbe(void)
     MCG->C1 = (uint8_t)(MCG_C1_CLKS(2) | MCG_C1_FRDIV(KINETIS_MCG_ERC_FRDIV));
 
     /* Wait until ERC is selected */
-    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2));
+    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) {}
 
     /* PLL is not disabled in bypass mode */
     MCG->C2 &= ~(uint8_t)(MCG_C2_LP_MASK);
@@ -330,10 +353,10 @@ static void kinetis_mcg_set_pbe(void)
     MCG->C6 |= (uint8_t)(MCG_C6_PLLS_MASK);
 
     /* Wait until the source of the PLLS clock is PLL */
-    while ((MCG->S & MCG_S_PLLST_MASK) == 0);
+    while ((MCG->S & MCG_S_PLLST_MASK) == 0) {}
 
     /* Wait until PLL locked */
-    while ((MCG->S & MCG_S_LOCK0_MASK) == 0);
+    while ((MCG->S & MCG_S_LOCK0_MASK) == 0) {}
 
     current_mode = KINETIS_MCG_PBE;
 }
@@ -350,135 +373,52 @@ static void kinetis_mcg_set_pee(void)
     MCG->C1 &= ~(uint8_t)(MCG_C1_CLKS_MASK);
 
     /* Wait until output of the PLL is selected */
-    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3));
+    while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) {}
 
     current_mode = KINETIS_MCG_PEE;
 }
-
+#endif /* KINETIS_HAVE_PLL */
 
 int kinetis_mcg_set_mode(kinetis_mcg_mode_t mode)
 {
     if (mode > KINETIS_MCG_FEI) {
         return -1;
     }
-
-    if (mcg_pm[current_mode] & (1 << mode)) {
-        if (mode == KINETIS_MCG_FEI) {
-            kinetis_mcg_set_fei();
-        }
-
-        if (mode == KINETIS_MCG_FBI) {
-            kinetis_mcg_set_fbi();
-        }
-
-        if (mode == KINETIS_MCG_FEE) {
-            kinetis_mcg_set_fee();
-        }
-
-        if (mode == KINETIS_MCG_FBE) {
-            kinetis_mcg_set_fbe();
-        }
-
-        if (mode == KINETIS_MCG_BLPI) {
-            kinetis_mcg_set_blpi();
-        }
-
-        if (mode == KINETIS_MCG_BLPE) {
-            kinetis_mcg_set_blpe();
-        }
-
-        if (mode == KINETIS_MCG_PBE) {
-            kinetis_mcg_set_pbe();
-        }
-
-        if (mode == KINETIS_MCG_PEE) {
-            kinetis_mcg_set_pee();
-        }
-
-        return 0;
-    }
-
-    switch (mode) {
-        case KINETIS_MCG_PEE:
-            /* cppcheck-suppress duplicateExpression */
-            if (!(KINETIS_MCG_USE_ERC || KINETIS_MCG_USE_PLL)) {
-                return -1;
-            }
-
-            if (current_mode == KINETIS_MCG_FEI) {
-                /* set FBE -> PBE -> PEE */
-                kinetis_mcg_set_fbe();
-                kinetis_mcg_set_pbe();
+    while (current_mode != mode) {
+        switch(mcg_mode_routing[current_mode][mode]) {
+#if KINETIS_HAVE_PLL
+            case KINETIS_MCG_PEE:
                 kinetis_mcg_set_pee();
-                return 0;
-            }
-
-            if (current_mode == KINETIS_MCG_BLPE) {
-                /* set PBE -> PEE */
+                break;
+            case KINETIS_MCG_PBE:
                 kinetis_mcg_set_pbe();
-                kinetis_mcg_set_pee();
-                return 0;
-            }
-
-            break;
-
-        case KINETIS_MCG_BLPE:
-            if (!KINETIS_MCG_USE_ERC) {
-                return -1;
-            }
-
-            if (current_mode == KINETIS_MCG_PEE) {
-                /* set PBE -> BLPE */
-                kinetis_mcg_set_pbe();
-                kinetis_mcg_set_blpe();
-                return 0;
-            }
-
-            if (current_mode == KINETIS_MCG_FEE) {
-                /* set FBE -> BLPE */
-                kinetis_mcg_set_fbe();
+                break;
+#endif /* KINETIS_HAVE_PLL */
+            case KINETIS_MCG_BLPE:
                 kinetis_mcg_set_blpe();
-                return 0;
-            }
-
-            break;
-
-        case KINETIS_MCG_BLPI:
-            if (current_mode == KINETIS_MCG_FEE) {
-                /* set FBI -> BLPI */
-                kinetis_mcg_set_fbi();
+                break;
+            case KINETIS_MCG_BLPI:
                 kinetis_mcg_set_blpi();
-                return 0;
-            }
-
-            break;
-
-        case KINETIS_MCG_FEE:
-            if (!KINETIS_MCG_USE_ERC) {
-                return -1;
-            }
-
-            if (current_mode == KINETIS_MCG_BLPE) {
-                /* set FBE -> FEE */
+                break;
+            case KINETIS_MCG_FBE:
                 kinetis_mcg_set_fbe();
-                kinetis_mcg_set_fee();
-                return 0;
-            }
-
-            if (current_mode == KINETIS_MCG_BLPI) {
-                /* set FBI -> FEE */
+                break;
+            case KINETIS_MCG_FBI:
                 kinetis_mcg_set_fbi();
+                break;
+            case KINETIS_MCG_FEE:
                 kinetis_mcg_set_fee();
-                return 0;
-            }
-
-            break;
-
-        default:
-            break;
+                break;
+            case KINETIS_MCG_FEI:
+                kinetis_mcg_set_fei();
+                break;
+            default:
+                return -1;
+        }
     }
 
-    return -1;
+    return 0;
 }
 
 #endif /* KINETIS_CPU_USE_MCG */
+/** @} */