summaryrefslogtreecommitdiffstats
path: root/cpukit/libi2c
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-10-25 16:17:56 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2007-10-25 16:17:56 +0000
commit55a685bddc84cb5c74f8ece914703f2a1e72a1c4 (patch)
treed868b38b8df32e05dc816f35eed0138838878437 /cpukit/libi2c
parent2007-10-19 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-55a685bddc84cb5c74f8ece914703f2a1e72a1c4.tar.bz2
added SPI support to libi2c
added IRQ support to MPC83xx i2c driver added mpc83xx spi driver
Diffstat (limited to 'cpukit/libi2c')
-rw-r--r--cpukit/libi2c/libi2c.c98
-rw-r--r--cpukit/libi2c/libi2c.h98
2 files changed, 186 insertions, 10 deletions
diff --git a/cpukit/libi2c/libi2c.c b/cpukit/libi2c/libi2c.c
index 0adf2f1ae4..7069b35527 100644
--- a/cpukit/libi2c/libi2c.c
+++ b/cpukit/libi2c/libi2c.c
@@ -46,6 +46,10 @@
*
* ------------------ 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"
#endif
@@ -55,6 +59,7 @@
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
+#include <stdarg.h>
#include <rtems.h>
#include <rtems/error.h>
@@ -318,7 +323,15 @@ int
rtems_libi2c_initialize ()
{
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;
@@ -331,6 +344,7 @@ rtems_libi2c_initialize ()
libmutex = 0;
return -1;
}
+ is_initialized = TRUE;
return 0;
}
@@ -428,7 +442,7 @@ not_started (int busno)
}
rtems_status_code
-rtems_libi2c_send_start (uint32_t minor)
+rtems_libi2c_send_start (rtems_device_minor_number minor)
{
int rval;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -459,7 +473,7 @@ rtems_libi2c_send_start (uint32_t minor)
}
rtems_status_code
-rtems_libi2c_send_stop (uint32_t minor)
+rtems_libi2c_send_stop (rtems_device_minor_number minor)
{
rtems_status_code rval;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -476,7 +490,7 @@ rtems_libi2c_send_stop (uint32_t minor)
}
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;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -491,7 +505,9 @@ rtems_libi2c_send_addr (uint32_t minor, int rw)
}
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;
DECL_CHECKED_BH (busno, bush, minor, -)
@@ -506,7 +522,9 @@ rtems_libi2c_read_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
}
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;
DECL_CHECKED_BH (busno, bush, minor, -)
@@ -520,8 +538,70 @@ rtems_libi2c_write_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
return sc;
}
+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;
rtems_libi2c_bus_t *bush;
@@ -549,14 +629,16 @@ do_s_rw (uint32_t minor, unsigned char *bytes, int nbytes, int rw)
}
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)
{
return do_s_rw (minor, bytes, nbytes, 1);
}
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)
{
return do_s_rw (minor, bytes, nbytes, 0);
diff --git a/cpukit/libi2c/libi2c.h b/cpukit/libi2c/libi2c.h
index 2dfbddd458..d243574333 100644
--- a/cpukit/libi2c/libi2c.h
+++ b/cpukit/libi2c/libi2c.h
@@ -46,6 +46,7 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
+
#include <rtems.h>
#include <rtems/io.h>
@@ -101,6 +102,11 @@ typedef struct rtems_libi2c_bus_ops_
/* write a number of bytes */
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;
@@ -265,14 +271,102 @@ rtems_libi2c_write_bytes (rtems_device_minor_number minor,
/* 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
}
#endif