diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 13b8a18785de977bf8acebcbc4b42cd1d5fa0e98..89bc5c5d6fd0a7e6e047f72c6a169b010dc68c5a 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -119,7 +119,6 @@ config IIO_ST_ACCEL_SPI_3AXIS
 
 config KXSD9
 	tristate "Kionix KXSD9 Accelerometer Driver"
-	depends on SPI
 	help
 	  Say yes here to build support for the Kionix KXSD9 accelerometer.
 	  Currently this only supports the device via an SPI interface.
@@ -127,6 +126,15 @@ config KXSD9
 	  To compile this driver as a module, choose M here: the module
 	  will be called kxsd9.
 
+config KXSD9_SPI
+	tristate "Kionix KXSD9 SPI transport"
+	depends on KXSD9
+	depends on SPI
+	default KXSD9
+	help
+	  Say yes here to enable the Kionix KXSD9 accelerometer
+	  SPI transport channel.
+
 config KXCJK1013
 	tristate "Kionix 3-Axis Accelerometer Driver"
 	depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index e974841ec9cf994ee11999e442681ac1253a2491..2fe41d7ffb6e0ebb5a14ca0e92d6ccf5669039a7 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_DMARD09)	+= dmard09.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
+obj-$(CONFIG_KXSD9_SPI)	+= kxsd9-spi.o
 
 obj-$(CONFIG_MMA7455)		+= mma7455_core.o
 obj-$(CONFIG_MMA7455_I2C)	+= mma7455_i2c.o
diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..ec9d00d5340f642018d2203486920e13eda7dbdd
--- /dev/null
+++ b/drivers/iio/accel/kxsd9-spi.c
@@ -0,0 +1,110 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "kxsd9.h"
+
+#define KXSD9_READ(a) (0x80 | (a))
+#define KXSD9_WRITE(a) (a)
+
+static int kxsd9_spi_readreg(struct kxsd9_transport *tr, u8 address)
+{
+	struct spi_device *spi = tr->trdev;
+
+	return spi_w8r8(spi, KXSD9_READ(address));
+}
+
+static int kxsd9_spi_writereg(struct kxsd9_transport *tr, u8 address, u8 val)
+{
+	struct spi_device *spi = tr->trdev;
+
+	tr->tx[0] = KXSD9_WRITE(address),
+	tr->tx[1] = val;
+	return spi_write(spi, tr->tx, 2);
+}
+
+static int kxsd9_spi_write2(struct kxsd9_transport *tr, u8 b1, u8 b2)
+{
+	struct spi_device *spi = tr->trdev;
+
+	tr->tx[0] = b1;
+	tr->tx[1] = b2;
+	return spi_write(spi, tr->tx, 2);
+}
+
+static int kxsd9_spi_readval(struct kxsd9_transport *tr, u8 address)
+{
+	struct spi_device *spi = tr->trdev;
+	struct spi_transfer xfers[] = {
+		{
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 200,
+			.tx_buf = tr->tx,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.rx_buf = tr->rx,
+		},
+	};
+	int ret;
+
+	tr->tx[0] = KXSD9_READ(address);
+	ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
+	if (!ret)
+		ret = (((u16)(tr->rx[0])) << 8) | (tr->rx[1]);
+	return ret;
+}
+
+static int kxsd9_spi_probe(struct spi_device *spi)
+{
+	struct kxsd9_transport *transport;
+	int ret;
+
+	transport = devm_kzalloc(&spi->dev, sizeof(*transport), GFP_KERNEL);
+	if (!transport)
+		return -ENOMEM;
+
+	transport->trdev = spi;
+	transport->readreg = kxsd9_spi_readreg;
+	transport->writereg = kxsd9_spi_writereg;
+	transport->write2 = kxsd9_spi_write2;
+	transport->readval = kxsd9_spi_readval;
+	spi->mode = SPI_MODE_0;
+	spi_setup(spi);
+
+	ret = kxsd9_common_probe(&spi->dev,
+				 transport,
+				 spi_get_device_id(spi)->name);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int kxsd9_spi_remove(struct spi_device *spi)
+{
+	return kxsd9_common_remove(&spi->dev);
+}
+
+static const struct spi_device_id kxsd9_spi_id[] = {
+	{"kxsd9", 0},
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, kxsd9_spi_id);
+
+static struct spi_driver kxsd9_spi_driver = {
+	.driver = {
+		.name = "kxsd9",
+	},
+	.probe = kxsd9_spi_probe,
+	.remove = kxsd9_spi_remove,
+	.id_table = kxsd9_spi_id,
+};
+module_spi_driver(kxsd9_spi_driver);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 1f9e9a867f342108d645b29aa78c9e874cbf81b5..e2033374bfef77d794406f26469df85a79ad62f1 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -18,7 +18,6 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
-#include <linux/spi/spi.h>
 #include <linux/sysfs.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -26,6 +25,8 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
+#include "kxsd9.h"
+
 #define KXSD9_REG_X		0x00
 #define KXSD9_REG_Y		0x02
 #define KXSD9_REG_Z		0x04
@@ -38,32 +39,6 @@
 #define KXSD9_REG_CTRL_B	0x0d
 #define KXSD9_REG_CTRL_A	0x0e
 
-#define KXSD9_READ(a) (0x80 | (a))
-#define KXSD9_WRITE(a) (a)
-
-#define KXSD9_STATE_RX_SIZE 2
-#define KXSD9_STATE_TX_SIZE 2
-
-struct kxsd9_transport;
-
-/**
- * struct kxsd9_transport - transport adapter for SPI or I2C
- * @trdev: transport device such as SPI or I2C
- * @write1(): function to write a byte to the device
- * @write2(): function to write two consecutive bytes to the device
- * @readval(): function to read a 16bit value from the device
- * @rx: cache aligned read buffer
- * @tx: cache aligned write buffer
- */
-struct kxsd9_transport {
-	void *trdev;
-	int (*write1) (struct kxsd9_transport *tr, u8 byte);
-	int (*write2) (struct kxsd9_transport *tr, u8 b1, u8 b2);
-	int (*readval) (struct kxsd9_transport *tr, u8 address);
-	u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
-	u8 tx[KXSD9_STATE_TX_SIZE];
-};
-
 /**
  * struct kxsd9_state - device related storage
  * @transport:	transport for the KXSD9
@@ -98,12 +73,13 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
 		return -EINVAL;
 
 	mutex_lock(&st->buf_lock);
-	ret = st->transport->write1(st->transport, KXSD9_READ(KXSD9_REG_CTRL_C));
-	if (ret)
+	ret = st->transport->readreg(st->transport,
+				     KXSD9_REG_CTRL_C);
+	if (ret < 0)
 		goto error_ret;
-	ret = st->transport->write2(st->transport,
-				    KXSD9_WRITE(KXSD9_REG_CTRL_C),
-				    (ret & ~KXSD9_FS_MASK) | i);
+	ret = st->transport->writereg(st->transport,
+				      KXSD9_REG_CTRL_C,
+				      (ret & ~KXSD9_FS_MASK) | i);
 error_ret:
 	mutex_unlock(&st->buf_lock);
 	return ret;
@@ -115,7 +91,9 @@ static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
 	struct kxsd9_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
-	ret = st->transport->readval(st->transport, KXSD9_READ(address));
+	ret = st->transport->readval(st->transport, address);
+	/* Only 12 bits are valid */
+	ret &= 0xfff0;
 	mutex_unlock(&st->buf_lock);
 	return ret;
 }
@@ -165,8 +143,9 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
 		ret = IIO_VAL_INT;
 		break;
 	case IIO_CHAN_INFO_SCALE:
-		ret = st->transport->write1(st->transport, KXSD9_READ(KXSD9_REG_CTRL_C));
-		if (ret)
+		ret = st->transport->readreg(st->transport,
+					     KXSD9_REG_CTRL_C);
+		if (ret < 0)
 			goto error_ret;
 		*val = 0;
 		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
@@ -218,9 +197,9 @@ static const struct iio_info kxsd9_info = {
 	.driver_module = THIS_MODULE,
 };
 
-static int kxsd9_common_probe(struct device *parent,
-			      struct kxsd9_transport *transport,
-			      const char *name)
+int kxsd9_common_probe(struct device *parent,
+		       struct kxsd9_transport *transport,
+		       const char *name)
 {
 	struct iio_dev *indio_dev;
 	struct kxsd9_state *st;
@@ -251,8 +230,9 @@ static int kxsd9_common_probe(struct device *parent,
 
 	return 0;
 }
+EXPORT_SYMBOL(kxsd9_common_probe);
 
-static int kxsd9_common_remove(struct device *parent)
+int kxsd9_common_remove(struct device *parent)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(parent);
 
@@ -260,93 +240,8 @@ static int kxsd9_common_remove(struct device *parent)
 
 	return 0;
 }
-
-static int kxsd9_spi_write1(struct kxsd9_transport *tr, u8 byte)
-{
-	struct spi_device *spi = tr->trdev;
-
-	return spi_w8r8(spi, byte);
-}
-
-static int kxsd9_spi_write2(struct kxsd9_transport *tr, u8 b1, u8 b2)
-{
-	struct spi_device *spi = tr->trdev;
-
-	tr->tx[0] = b1;
-	tr->tx[1] = b2;
-	return spi_write(spi, tr->tx, 2);
-}
-
-static int kxsd9_spi_readval(struct kxsd9_transport *tr, u8 address)
-{
-	struct spi_device *spi = tr->trdev;
-	struct spi_transfer xfers[] = {
-		{
-			.bits_per_word = 8,
-			.len = 1,
-			.delay_usecs = 200,
-			.tx_buf = tr->tx,
-		}, {
-			.bits_per_word = 8,
-			.len = 2,
-			.rx_buf = tr->rx,
-		},
-	};
-	int ret;
-
-	tr->tx[0] = address;
-	ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
-	if (!ret)
-		ret = (((u16)(tr->rx[0])) << 8) | (tr->rx[1] & 0xF0);
-	return ret;
-}
-
-static int kxsd9_spi_probe(struct spi_device *spi)
-{
-	struct kxsd9_transport *transport;
-	int ret;
-
-	transport = devm_kzalloc(&spi->dev, sizeof(*transport), GFP_KERNEL);
-	if (!transport)
-		return -ENOMEM;
-
-	transport->trdev = spi;
-	transport->write1 = kxsd9_spi_write1;
-	transport->write2 = kxsd9_spi_write2;
-	transport->readval = kxsd9_spi_readval;
-	spi->mode = SPI_MODE_0;
-	spi_setup(spi);
-
-	ret = kxsd9_common_probe(&spi->dev,
-				 transport,
-				 spi_get_device_id(spi)->name);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-static int kxsd9_spi_remove(struct spi_device *spi)
-{
-	return kxsd9_common_remove(&spi->dev);
-}
-
-static const struct spi_device_id kxsd9_spi_id[] = {
-	{"kxsd9", 0},
-	{ },
-};
-MODULE_DEVICE_TABLE(spi, kxsd9_spi_id);
-
-static struct spi_driver kxsd9_spi_driver = {
-	.driver = {
-		.name = "kxsd9",
-	},
-	.probe = kxsd9_spi_probe,
-	.remove = kxsd9_spi_remove,
-	.id_table = kxsd9_spi_id,
-};
-module_spi_driver(kxsd9_spi_driver);
+EXPORT_SYMBOL(kxsd9_common_remove);
 
 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_DESCRIPTION("Kionix KXSD9 driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/kxsd9.h b/drivers/iio/accel/kxsd9.h
new file mode 100644
index 0000000000000000000000000000000000000000..28845c3440e90c8597264d1c76506fc113b2ccee
--- /dev/null
+++ b/drivers/iio/accel/kxsd9.h
@@ -0,0 +1,32 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#define KXSD9_STATE_RX_SIZE 2
+#define KXSD9_STATE_TX_SIZE 2
+
+struct kxsd9_transport;
+
+/**
+ * struct kxsd9_transport - transport adapter for SPI or I2C
+ * @trdev: transport device such as SPI or I2C
+ * @readreg(): function to read a byte from an address in the device
+ * @writereg(): function to write a byte to an address in the device
+ * @write2(): function to write two consecutive bytes to the device
+ * @readval(): function to read a 16bit value from the device
+ * @rx: cache aligned read buffer
+ * @tx: cache aligned write buffer
+ */
+struct kxsd9_transport {
+	void *trdev;
+	int (*readreg) (struct kxsd9_transport *tr, u8 address);
+	int (*writereg) (struct kxsd9_transport *tr, u8 address, u8 val);
+	int (*write2) (struct kxsd9_transport *tr, u8 b1, u8 b2);
+	int (*readval) (struct kxsd9_transport *tr, u8 address);
+	u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
+	u8 tx[KXSD9_STATE_TX_SIZE];
+};
+
+int kxsd9_common_probe(struct device *parent,
+		       struct kxsd9_transport *transport,
+		       const char *name);
+int kxsd9_common_remove(struct device *parent);