diff --git a/ChangeLog b/ChangeLog
index 6a506625ab0ec851749fb47f9f5dddd14cee1724..94676ceff51dc980a3740b52d5bbb70a40871c15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -686,3 +686,5 @@
 	* Add an enumeration argument to the SPI chip select and status methods so
 	  that the interface can handle more than one device.
 	* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
+	* Add a setmode() method to the SPI interface to handle parts with differing
+	  mode requirements.
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index db4da8152ef0e24698b3c9c28b9919d576cbcdba..e8e9e3e6223abf73c31913b3e009e38990dbf129 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -1359,6 +1359,8 @@ nuttx-0.4.5 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 	* Add an enumeration argument to the SPI chip select and status methods so
 	  that the interface can handle more than one device.
 	* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
+	* Add a setmode() method to the SPI interface to handle parts with differing
+	  mode requirements.
 
 pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
diff --git a/arch/z80/src/ez80/ez80_spi.c b/arch/z80/src/ez80/ez80_spi.c
index aea2947d7fd6cffe24698f75b13e58eb62187329..5af30fd06663ad087b6d28611be76099a189aa35 100755
--- a/arch/z80/src/ez80/ez80_spi.c
+++ b/arch/z80/src/ez80/ez80_spi.c
@@ -66,6 +66,7 @@
  ****************************************************************************/
 
 static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
+static void   spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
 static ubyte  spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
 static void   spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
 static void   spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@@ -78,6 +79,7 @@ static const struct spi_ops_s g_spiops =
 {
   ez80_spiselect,    /* Provided externally by board logic */
   spi_setfrequency,
+  spi_setmode,
   ez80_spistatus,    /* Provided externally by board logic */
   spi_sndbyte,
   spi_sndblock,
@@ -148,6 +150,58 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
   return ((EZ80_SYS_CLK_FREQ+1)/2 + brg - 1) / brg;
 }
 
+/****************************************************************************
+ * Name: spi_setmode
+ *
+ * Description:
+ *   Set the SPI mode. Optional.  See enum spi_mode_e for mode definitions
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   mode - The SPI mode requested
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
+{
+  ubyte modebits;
+  ubyte regval;
+
+  /* Select the CTL register bits based on the selected mode */
+
+  switch (mode)
+    {
+    case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */
+      modebits = 0;
+      break;
+
+    case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */
+      modebits = SPI_CTL_CPHA;
+      break;
+
+    case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */
+      modebits = SPI_CTL_CPOL;
+      break;
+
+    case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */
+      modebits = (SPI_CTL_CPOL|SPI_CTL_CPHA);
+      break;
+
+    default:
+      return;
+    }
+
+    /* Then set those bits in the CTL register */
+
+    regval = inp(EZ80_SPI_CTL);
+    regval &= ~(SPI_CTL_CPOL|SPI_CTL_CPHA);
+    regval |= modebits;
+    outp(EZ80_SPI_CTL, regval);
+}
+
 /****************************************************************************
  * Name: spi_waitspif
  *
@@ -367,7 +421,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
 
   /* Enable the SPI.
    * NOTE 1: Interrupts are not used in this driver version.
-   * NOTE 2: Certain devices may need changes to SCK polarity settings.
+   * NOTE 2: Initial mode is mode=0.
    */
 
   outp(EZ80_SPI_CTL, SPI_CTL_SPIEN|SPI_CTL_MASTEREN);
diff --git a/arch/z80/src/ez80/ez80f91_spi.h b/arch/z80/src/ez80/ez80f91_spi.h
index 1d03c10cd66be9c45f5171723db5229d5d8e5171..3334e472bda441b53846aef90305d6ff4b34e47c 100644
--- a/arch/z80/src/ez80/ez80f91_spi.h
+++ b/arch/z80/src/ez80/ez80f91_spi.h
@@ -113,8 +113,8 @@ extern "C" {
  *      will bind the SPI driver to the SPI MMC/SD driver.
  */
 
-EXTERN void ez80_spiselect(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
-EXTERN ubyte ez80_spistatus(FAR struct spi_dev_s *dev, enum spidev_e devid);
+EXTERN void ez80_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
+EXTERN ubyte ez80_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
 
 #undef EXTERN
 #ifdef __cplusplus
diff --git a/configs/mcu123-lpc214x/src/up_spi.c b/configs/mcu123-lpc214x/src/up_spi.c
index 210f3d736f16e275967f37b28068c47d5c2d733b..a33b0ea768cfadaceb5168efb4ba3e8939a1c5d5 100644
--- a/configs/mcu123-lpc214x/src/up_spi.c
+++ b/configs/mcu123-lpc214x/src/up_spi.c
@@ -86,9 +86,9 @@
  * Private Function Prototypes
  ****************************************************************************/
 
-static void   spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
+static void   spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
 static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
-static ubyte  spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid);
+static ubyte  spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
 static ubyte  spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
 static void   spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
 static void   spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@@ -135,7 +135,7 @@ static struct spi_dev_s g_spidev = { &g_spiops };
  *
  ****************************************************************************/
 
-static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected)
+static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected)
 {
   uint32 bit = 1 << 20;
 
@@ -222,7 +222,7 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
  *
  ****************************************************************************/
 
-static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid)
+static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
 {
   /* I don't think there is anyway to determine these things on the mcu123.com
    * board.
diff --git a/configs/olimex-strp711/src/up_spi.c b/configs/olimex-strp711/src/up_spi.c
index c7cfa0a27760eb989b22a457c895ff42f2bcad79..33b3a8717694952fd3a9179369746cf3e249901c 100644
--- a/configs/olimex-strp711/src/up_spi.c
+++ b/configs/olimex-strp711/src/up_spi.c
@@ -263,9 +263,9 @@ static inline void   spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset,
 
 /* SPI methods */
 
-static void   spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
+static void   spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
 static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
-static ubyte  spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid);
+static ubyte  spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
 static ubyte  spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
 static void   spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
 static void   spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@@ -369,7 +369,7 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset, ui
  *
  ****************************************************************************/
 
-static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected)
+static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected)
 {
   FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev;
   uint16 reg16;
@@ -499,7 +499,7 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
  *
  ****************************************************************************/
 
-static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid)
+static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
 {
   ubyte ret = 0;
   uint16 reg16 = getreg16(STR71X_GPIO1_PD);
diff --git a/include/nuttx/spi.h b/include/nuttx/spi.h
index e07ca6123dec8b17bdf77ac8a6f57b6ac675ccf8..57da34304137b52a0ef49a39b91428ed4068b965 100644
--- a/include/nuttx/spi.h
+++ b/include/nuttx/spi.h
@@ -1,7 +1,7 @@
 /****************************************************************************
- * drivers/usbdev/spi.h
+ * include/nuttx/spi.h
  *
- *   Copyright(C) 2008 Gregory Nutt. All rights reserved.
+ *   Copyright(C) 2008-2009 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,23 @@
 
 #define SPI_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f))
 
+/****************************************************************************
+ * Name: SPI_SETMODE
+ *
+ * Description:
+ *   Set the SPI mode. Optional.  See enum spi_mode_e for mode definitions
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   mode - The SPI mode requested
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+#define SPI_SETMODE(d,m) ((d)->ops->mode(d,m))
+
 /****************************************************************************
  * Name: SPI_STATUS
  *
@@ -198,21 +215,32 @@ typedef void (*mediachange_t)(void *arg);
  * which is selected or de-seleted.
  */
 
-enum spidev_e
+enum spi_dev_e
 {
   SPIDEV_NONE = 0,  /* Not a valid value */
   SPIDEV_MMCSD,     /* Select SPI MMC/SD device */
   SPIDEV_ETHERNET   /* Select SPI ethernet device */
 };
 
+/* Certain SPI devices may required differnt clocking modes */
+
+enum spi_mode_e
+{
+  SPIDEV_MODE0 = 0,  /* CPOL=0 CHPHA=0 */
+  SPIDEV_MODE1,      /* CPOL=0 CHPHA=1 */
+  SPIDEV_MODE2,      /* CPOL=1 CHPHA=0 */
+  SPIDEV_MODE3       /* CPOL=1 CHPHA=1 */
+};
+
 /* The SPI vtable */
 
 struct spi_dev_s;
 struct spi_ops_s
 {
-  void   (*select)(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
+  void   (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
   uint32 (*setfrequency)(FAR struct spi_dev_s *dev, uint32 frequency);
-  ubyte  (*status)(FAR struct spi_dev_s *dev, enum spidev_e devid);
+  void   (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
+  ubyte  (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
   ubyte  (*sndbyte)(FAR struct spi_dev_s *dev, ubyte ch);
   void   (*sndblock)(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
   void   (*recvblock)(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);