diff --git a/source/soc/kfuse.c b/source/soc/kfuse.c
new file mode 100644
index 0000000..1621215
--- /dev/null
+++ b/source/soc/kfuse.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "../soc/kfuse.h"
+#include "../soc/clock.h"
+#include "../soc/t210.h"
+
+#pragma GCC push_options
+#pragma GCC optimize ("Os")
+
+int kfuse_read(u32 *buf)
+{
+ int res = 0;
+
+ clock_enable_kfuse();
+
+ while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
+ ;
+
+ if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
+ goto out;
+
+ KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
+ for (int i = 0; i < KFUSE_NUM_WORDS; i++)
+ buf[i] = KFUSE(KFUSE_KEYS);
+
+ res = 1;
+
+out:;
+ clock_disable_kfuse();
+ return res;
+}
+
+int kfuse_wait_ready()
+{
+ // Wait for KFUSE to finish init and verification of data.
+ while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
+ {
+ usleep(500);
+ }
+
+ if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
+ return 0;
+
+ return 1;
+}
+
+#pragma GCC pop_options
diff --git a/source/soc/kfuse.h b/source/soc/kfuse.h
new file mode 100644
index 0000000..3824eb8
--- /dev/null
+++ b/source/soc/kfuse.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef _KFUSE_H_
+#define _KFUSE_H_
+
+#include "../utils/types.h"
+
+#define KFUSE_STATE_SOFTRESET (1 << 31)
+#define KFUSE_STATE_STOP (1 << 25)
+#define KFUSE_STATE_RESTART (1 << 24)
+#define KFUSE_STATE_CRCPASS (1 << 17)
+#define KFUSE_STATE_DONE (1 << 16)
+#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
+#define KFUSE_STATE_ERRBLOCK_SHIFT 8
+#define KFUSE_STATE_CURBLOCK_MASK 0x3F
+
+#define KFUSE_KEYADDR_AUTOINC (1<<16)
+
+#define KFUSE_STATE 0x80
+#define KFUSE_KEYADDR 0x88
+#define KFUSE_KEYS 0x8C
+
+#define KFUSE_NUM_WORDS 144
+
+int kfuse_read(u32 *buf);
+int kfuse_wait_ready();
+
+#endif