Index: cpukit/libi2c/libi2c.c
===================================================================
--- cpukit/libi2c/libi2c.c	(revision c57316a40956b00b5d10f19dbb253383069d515a)
+++ cpukit/libi2c/libi2c.c	(revision 55a685bddc84cb5c74f8ece914703f2a1e72a1c4)
@@ -47,4 +47,8 @@
  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
  */ 
+/*
+ * adaptations to also handle SPI devices 
+ * by Thomas Doerfler, embedded brains GmbH, Puchheim, Germany
+ */
 #if HAVE_CONFIG_H
 #include "config.h"
@@ -56,4 +60,5 @@
 #include <errno.h>
 #include <assert.h>
+#include <stdarg.h>
 
 #include <rtems.h>
@@ -319,5 +324,13 @@
 {
   rtems_status_code sc;
-
+  static boolean is_initialized = FALSE;
+
+  if (is_initialized) {
+    /*
+     * already called before? then skip this step
+     */
+    return 0;
+  }
+  
   if (!(libmutex = mutexCreate (rtems_build_name ('l', 'I', '2', 'C'))))
     return -1;
@@ -332,4 +345,5 @@
     return -1;
   }
+  is_initialized = TRUE;
 
   return 0;
@@ -429,5 +443,5 @@
 
 rtems_status_code
-rtems_libi2c_send_start (uint32_t minor)
+rtems_libi2c_send_start (rtems_device_minor_number minor)
 {
   int rval;
@@ -460,5 +474,5 @@
 
 rtems_status_code
-rtems_libi2c_send_stop (uint32_t minor)
+rtems_libi2c_send_stop (rtems_device_minor_number minor)
 {
   rtems_status_code rval;
@@ -477,5 +491,5 @@
 
 rtems_status_code
-rtems_libi2c_send_addr (uint32_t minor, int rw)
+rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw)
 {
   rtems_status_code sc;
@@ -492,5 +506,7 @@
 
 int
-rtems_libi2c_read_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+rtems_libi2c_read_bytes (rtems_device_minor_number minor, 
+			 unsigned char *bytes, 
+			 int nbytes)
 {
   int sc;
@@ -507,5 +523,7 @@
 
 int
-rtems_libi2c_write_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+rtems_libi2c_write_bytes (rtems_device_minor_number minor, 
+			  unsigned char *bytes, 
+			  int nbytes)
 {
   int sc;
@@ -521,6 +539,68 @@
 }
 
+int
+rtems_libi2c_ioctl (rtems_device_minor_number minor, 
+		    int cmd,
+		    ...)
+{
+  va_list            ap;
+  int sc = 0;
+  void *args;
+  DECL_CHECKED_BH (busno, bush, minor, -)
+
+    if (not_started (busno))
+    return -RTEMS_NOT_OWNER_OF_RESOURCE;
+
+  va_start(ap, cmd);
+  args = va_arg(ap, void *);
+
+  switch(cmd) {
+    /*
+     * add ioctls defined for this level here:    
+     */
+    
+  case RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE:
+    /*
+     * address device, then set transfer mode and perform read_write transfer
+     */
+    /*
+     * perform start/address
+     */
+    if (sc == 0) {
+      sc = rtems_libi2c_send_start (minor);
+    }
+    /*
+     * set tfr mode
+     */
+    if (sc == 0) {
+      sc = bush->ops->ioctl 
+	(bush, 
+	 RTEMS_LIBI2C_IOCTL_SET_TFRMODE, 
+	 &((rtems_libi2c_tfm_read_write_t *)args)->tfr_mode);
+    }
+    /*
+     * perform read_write
+     */
+    if (sc == 0) {
+      sc = bush->ops->ioctl 
+	(bush, 
+	 RTEMS_LIBI2C_IOCTL_READ_WRITE, 
+	 &((rtems_libi2c_tfm_read_write_t *)args)->rd_wr);
+    }
+    break;
+  default:
+    sc = bush->ops->ioctl (bush, cmd, args);
+    break;
+  }
+  if (sc < 0)
+    rtems_libi2c_send_stop (minor);
+  return sc;
+}
+
 static int
-do_s_rw (uint32_t minor, unsigned char *bytes, int nbytes, int rw)
+do_s_rw (rtems_device_minor_number minor, 
+	 unsigned char *bytes, 
+	 int nbytes, 
+	 int rw)
 {
   rtems_status_code sc;
@@ -550,5 +630,6 @@
 
 int
-rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_read_bytes (rtems_device_minor_number minor, 
+			       unsigned char *bytes,
                                int nbytes)
 {
@@ -557,5 +638,6 @@
 
 int
-rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_write_bytes (rtems_device_minor_number minor, 
+				unsigned char *bytes,
                                 int nbytes)
 {
Index: cpukit/libi2c/libi2c.h
===================================================================
--- cpukit/libi2c/libi2c.h	(revision c57316a40956b00b5d10f19dbb253383069d515a)
+++ cpukit/libi2c/libi2c.h	(revision 55a685bddc84cb5c74f8ece914703f2a1e72a1c4)
@@ -47,4 +47,5 @@
  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
  */ 
+
 #include <rtems.h>
 
@@ -102,4 +103,9 @@
   int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
                       int nbytes);
+  /* ioctl misc functions */
+  int (*ioctl) (rtems_libi2c_bus_t * bushdl, 
+		int   cmd,
+		void *buffer;
+		);
 } rtems_libi2c_bus_ops_t;
 
@@ -266,11 +272,99 @@
 /* Send start, send address and read bytes */
 int
-rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_read_bytes (rtems_device_minor_number minor, 
+			       unsigned char *bytes,
                                int nbytes);
 
 /* Send start, send address and write bytes */
 int
-rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_write_bytes (rtems_device_minor_number minor, 
+				unsigned char *bytes,
                                 int nbytes);
+
+
+/* call misc iocontrol function */
+int
+rtems_libi2c_ioctl (rtems_device_minor_number minor,
+		    int cmd,
+		    ...);
+/*
+ * NOTE: any low-level driver ioctl returning a negative
+ * result for release the bus (perform a STOP condition)
+ */
+/*******************************
+ * defined IOCTLs:
+ *******************************/
+#define RTEMS_LIBI2C_IOCTL_READ_WRITE  1
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ *                             RTEMS_LIBI2C_IOCTL_READ_WRITE,
+ *                              rtems_libi2c_read_write_t *arg);
+ * 
+ * This call performs a simultanous read/write transfer, 
+ * which is possible (and sometimes needed) for SPI devices
+ * 
+ *   arg is a pointer to a rd_wr info data structure
+ * 
+ * This call is only needed for SPI devices
+ */
+#define RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE  2
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ *                             RTEMS_LIBI2C_IOCTL_START_READ_WRITE,
+ *                             unsigned char *rd_buffer,
+ *                             const unsigned char *wr_buffer,
+ *                             int byte_cnt,
+ *                             const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ * 
+ * This call addresses a slave and then:
+ * - sets the proper transfer mode,
+ *  - performs a simultanous  read/write transfer, 
+ *    (which is possible and sometimes needed for SPI devices)
+ *    NOTE: - if rd_buffer is NULL, receive data will be dropped
+ *          - if wr_buffer is NULL, bytes with content 0 will transmitted
+ * 
+ *   rd_buffer is a pointer to a receive buffer (or NULL) 
+ *   wr_buffer is a pointer to the data to be sent (or NULL)
+ * 
+ * This call is only needed for SPI devices
+ */
+
+#define RTEMS_LIBI2C_IOCTL_SET_TFRMODE 3
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ *                             RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
+ *                             const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ * 
+ * This call sets an SPI device to the transfer mode needed (baudrate etc.)
+ * 
+ *   tfr_mode is a pointer to a structure defining the SPI transfer mode needed
+ *   (see below). 
+ * 
+ * This call is only needed for SPI devices
+ */
+
+/*
+ * arguemtn data structures for IOCTLs defined above
+ */
+typedef struct {
+  unsigned char       *rd_buf;
+  const unsigned char *wr_buf;
+  int                  byte_cnt;
+} rtems_libi2c_read_write_t;
+
+typedef struct {
+  uint32_t baudrate;       /* maximum bits per second               */
+                           /* only valid for SPI drivers:           */
+  uint8_t  bits_per_char;  /* how many bits per byte/word/longword? */
+  boolean  lsb_first;      /* TRUE: send LSB first                  */
+  boolean  clock_inv;      /* TRUE: inverted clock (high active)    */
+  boolean  clock_phs;      /* TRUE: clock starts toggling at start of data tfr */
+} rtems_libi2c_tfr_mode_t;
+
+typedef struct {
+  rtems_libi2c_tfr_mode_t   tfr_mode;
+  rtems_libi2c_read_write_t rd_wr;
+} rtems_libi2c_tfm_read_write_t;
+
 
 #ifdef __cplusplus
