diff --git a/ChangeLog b/ChangeLog
index df00a50227c7797257a53c68bcebfa71f5df2119..c78cfc152f54402c9f2663ecba480f4d0f7d2e97 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-05-10
+------------------------------------------------------------------------
+
+Added initial Linux SPI implementation to use the library on a
+Raspberry Pi or other Linux based SPI-capable platforms.
+
 ------------------------------------------------------------------------
 
 2012-01-28
@@ -5,7 +11,7 @@
 * included rfm12_read_interrupt_flags_inline() again for performance
   reasons (interrupt handler might be to slow on 115200 Baud otherwise)
 * clear interrupt flag before checking status (there is a glitch sometimes
-  while the int line goes high, which triggers another interrupt otherweise,
+  while the int line goes high, which triggers another interrupt otherwise,
   which also hurts performance
 * LNA controllable over rfm12_livectrl
 
diff --git a/src/include/rfm12_spi.c b/src/include/rfm12_spi.c
index de0833742d7d5d9c2ead4a5f7946876b14ebe7cb..d2a56f5e1de13bc03cb3371c68de5d55960182e4 100644
--- a/src/include/rfm12_spi.c
+++ b/src/include/rfm12_spi.c
@@ -27,6 +27,7 @@
 #define SS_ASSERT() PORT_SS &= ~(1<<BIT_SS)
 #define SS_RELEASE() PORT_SS |= (1<<BIT_SS)
 
+#ifdef __PLATFORM_AVR__
 
 #if RFM12_SPI_SOFTWARE
 /* @description Actual sending function to send raw data to the Module
@@ -135,3 +136,5 @@ static void spi_init(void) {
 		SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); //SPI Master, clk/16
 	#endif
 }
+
+#endif
diff --git a/src/include/rfm12_spi_linux.c b/src/include/rfm12_spi_linux.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b3b2d7c70b8328461f5cde43353aa97dcacc0a5
--- /dev/null
+++ b/src/include/rfm12_spi_linux.c
@@ -0,0 +1,107 @@
+#ifdef __PLATFORM_LINUX__
+#include <linux/spi/spidev.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <byteswap.h>
+#include <unistd.h>
+
+static const char *device = "/dev/spidev0.1";
+static int fd;
+static uint8_t mode = 0;
+static uint8_t bits = 8;
+static uint32_t speed = 250000;
+
+static void pabort(const char *s)
+{
+	perror(s);
+	abort();
+}
+
+
+static void spi_init(void) {
+	int ret = 0;
+
+	fd = open(device, O_RDWR);
+
+	if (fd < 0) {
+			pabort("driver not loaded? can't open device");
+	}
+	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
+		if (ret == -1)
+			pabort("can't set spi mode");
+
+		ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
+		if (ret == -1)
+			pabort("can't get spi mode");
+
+		/*
+		 * bits per word
+		 */
+		ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
+		if (ret == -1)
+			pabort("can't set bits per word");
+
+		ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
+		if (ret == -1)
+			pabort("can't get bits per word");
+
+		/*
+		 * max speed hz
+		 */
+		ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+		if (ret == -1)
+			pabort("can't set max speed hz");
+
+		ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
+		if (ret == -1)
+			pabort("can't get max speed hz");
+}
+
+static uint16_t rfm12_read(uint16_t address) {
+	int ret;
+
+	uint8_t rx[2];
+	uint8_t tx[2];
+
+	tx[0] = (uint8_t) (address >> 8);
+	tx[1] = (uint8_t) (address & 0xFF);
+
+	rx[0] = 0;
+	rx[1] = 0;
+
+	struct spi_ioc_transfer tr = {
+			.tx_buf = (unsigned long)tx,
+			.rx_buf = (unsigned long)rx,
+			.len = 2,
+			.delay_usecs = 0,
+			.speed_hz = speed,
+			.bits_per_word = bits,
+		};
+
+	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
+
+	if (ret < 1)
+			pabort("can't send spi message");
+
+
+	return ((uint16_t)rx[0] << 8) + rx[1];
+}
+
+static void rfm12_data(uint16_t d) {
+	uint8_t buffer[2];
+	buffer[0] = (uint8_t) (d >> 8);
+	buffer[1] = (uint8_t) (d & 0xff);
+
+	write(fd, buffer, sizeof(buffer));
+}
+
+static uint8_t rfm12_read_int_flags_inline(void) {
+	uint16_t ret = rfm12_read(0x0000);
+
+	return ret >> 8;
+}
+
+#endif
diff --git a/src/rfm12.c b/src/rfm12.c
index 8e696b316d68308f94423688736e9242168705f5..90c9473b295903a016d5f39ccb44754f5fe22346 100644
--- a/src/rfm12.c
+++ b/src/rfm12.c
@@ -34,10 +34,14 @@
 /************************
  * standard includes
 */
+#ifdef __PLATFORM_AVR__
 #include <avr/io.h>
 #include <avr/interrupt.h>
-#include <string.h>
 #include <avr/pgmspace.h>
+#endif
+
+#include <string.h>
+
 
 
 /************************
@@ -85,6 +89,7 @@ rfm12_control_t ctrl;
 
 /* include spi functions into here */
 #include "include/rfm12_spi.c"
+#include "include/rfm12_spi_linux.c"
 
 /*
  * include control / init functions into here
@@ -142,7 +147,9 @@ ISR(RFM12_INT_VECT, ISR_NOBLOCK)
 
 	do {
 		//clear AVR int flag
+#ifdef __PLATFORM_AVR__
 		RFM12_INT_FLAG = (1<<RFM12_FLAG_BIT);
+#endif
 
 		//first we read the first byte of the status register
 		//to get the interrupt flags
@@ -646,7 +653,11 @@ rfm12_start_tx(uint8_t type, uint8_t length) {
 //set TX Power, frequency shift
 #define RFM12_CMD_TXCONF_DEFAULT  (RFM12_CMD_TXCONF | RFM12_POWER | RFM12_TXCONF_FS_CALC(FSK_SHIFT) )
 
+#ifdef __PLATFORM_AVR__
 static const uint16_t init_cmds[] PROGMEM = {
+#else
+static const uint16_t init_cmds[] = {
+#endif
 	//defined above (so shadow register is inited with same value)
 	RFM12_CMD_CFG_DEFAULT,
 
@@ -708,8 +719,10 @@ static const uint16_t init_cmds[] PROGMEM = {
 */
 void rfm12_init(void) {
 	//initialize spi
+#ifdef __PLATFORM_AVR__
 	SS_RELEASE();
 	DDR_SS |= (1<<BIT_SS);
+#endif
 	spi_init();
 
 	//typically sets DDR registers for RFM12BP TX/RX pin
@@ -756,9 +769,17 @@ void rfm12_init(void) {
 
 	//write all the initialisation values to rfm12
 	uint8_t x;
-	for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
-		rfm12_data(pgm_read_word(&init_cmds[x]));
-	}
+
+	#ifdef __PLATFORM_AVR__
+
+		for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
+			rfm12_data(pgm_read_word(&init_cmds[x]));
+		}
+	#else
+		for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
+			rfm12_data(init_cmds[x]);
+		}
+	#endif
 
 	#ifdef RX_ENTER_HOOK
 		RX_ENTER_HOOK;
@@ -774,11 +795,16 @@ void rfm12_init(void) {
 	#endif
 
 	//setup interrupt for falling edge trigger
+#ifdef __PLATFORM_AVR__
 	RFM12_INT_SETUP();
+#endif
 
 	//clear int flag
 	rfm12_read(RFM12_CMD_STATUS);
+
+#ifdef __PLATFORM_AVR__
 	RFM12_INT_FLAG = (1<<RFM12_FLAG_BIT);
+#endif
 
 	//init receiver fifo, we now begin receiving.
 	rfm12_data(CLEAR_FIFO);
diff --git a/src/rfm12.h b/src/rfm12.h
index 5b13b5ad31a767d0d852313601eda3c004549923..ff7e1d219f226bc9f51816aae42899c1d75466bb 100644
--- a/src/rfm12.h
+++ b/src/rfm12.h
@@ -40,6 +40,10 @@
 #ifndef _RFM12_H
 #define _RFM12_H
 
+#ifdef __PLATFORM_LINUX__
+#include <stdint.h>
+#endif
+
 //this was missing, but is very important to set the config options for structs and such
 #include "include/rfm12_core.h"