]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/spi/spi.h
Merge branch 'upstream'
[linux-2.6-omap-h63xx.git] / include / linux / spi / spi.h
index c851b3d1320802236b72a94726a4ce2f4a694e78..b05f1463a2676de35237dda137772ad70dc1c93d 100644 (file)
@@ -60,8 +60,8 @@ struct spi_device {
        u8                      mode;
 #define        SPI_CPHA        0x01                    /* clock phase */
 #define        SPI_CPOL        0x02                    /* clock polarity */
-#define        SPI_MODE_0      (0|0)
-#define        SPI_MODE_1      (0|SPI_CPHA)            /* (original MicroWire) */
+#define        SPI_MODE_0      (0|0)                   /* (original MicroWire) */
+#define        SPI_MODE_1      (0|SPI_CPHA)
 #define        SPI_MODE_2      (SPI_CPOL|0)
 #define        SPI_MODE_3      (SPI_CPOL|SPI_CPHA)
 #define        SPI_CS_HIGH     0x04                    /* chipselect active high? */
@@ -209,6 +209,30 @@ struct spi_master {
        void                    (*cleanup)(const struct spi_device *spi);
 };
 
+static inline void *spi_master_get_devdata(struct spi_master *master)
+{
+       return class_get_devdata(&master->cdev);
+}
+
+static inline void spi_master_set_devdata(struct spi_master *master, void *data)
+{
+       class_set_devdata(&master->cdev, data);
+}
+
+static inline struct spi_master *spi_master_get(struct spi_master *master)
+{
+       if (!master || !class_device_get(&master->cdev))
+               return NULL;
+       return master;
+}
+
+static inline void spi_master_put(struct spi_master *master)
+{
+       if (master)
+               class_device_put(&master->cdev);
+}
+
+
 /* the spi driver core manages memory for the spi_master classdev */
 extern struct spi_master *
 spi_alloc_master(struct device *host, unsigned size);
@@ -239,15 +263,16 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
 
 /**
  * struct spi_transfer - a read/write buffer pair
- * @tx_buf: data to be written (dma-safe address), or NULL
- * @rx_buf: data to be read (dma-safe address), or NULL
- * @tx_dma: DMA address of buffer, if spi_message.is_dma_mapped
- * @rx_dma: DMA address of buffer, if spi_message.is_dma_mapped
+ * @tx_buf: data to be written (dma-safe memory), or NULL
+ * @rx_buf: data to be read (dma-safe memory), or NULL
+ * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped
+ * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped
  * @len: size of rx and tx buffers (in bytes)
  * @cs_change: affects chipselect after this transfer completes
  * @delay_usecs: microseconds to delay after this transfer before
  *     (optionally) changing the chipselect status, then starting
  *     the next transfer or completing this spi_message.
+ * @transfer_list: transfers are sequenced through spi_message.transfers
  *
  * SPI transfers always write the same number of bytes as they read.
  * Protocol drivers should always provide rx_buf and/or tx_buf.
@@ -255,11 +280,16 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
  * the data being transferred; that may reduce overhead, when the
  * underlying driver uses dma.
  *
- * All SPI transfers start with the relevant chipselect active.  Drivers
- * can change behavior of the chipselect after the transfer finishes
- * (including any mandatory delay).  The normal behavior is to leave it
- * selected, except for the last transfer in a message.  Setting cs_change
- * allows two additional behavior options:
+ * If the transmit buffer is null, undefined data will be shifted out
+ * while filling rx_buf.  If the receive buffer is null, the data
+ * shifted in will be discarded.  Only "len" bytes shift out (or in).
+ * It's an error to try to shift out a partial word.  (For example, by
+ * shifting out three bytes with word size of sixteen or twenty bits;
+ * the former uses two bytes per word, the latter uses four bytes.)
+ *
+ * All SPI transfers start with the relevant chipselect active.  Normally
+ * it stays selected until after the last transfer in a message.  Drivers
+ * can affect the chipselect signal using cs_change:
  *
  * (i) If the transfer isn't the last one in the message, this flag is
  * used to make the chipselect briefly go inactive in the middle of the
@@ -271,11 +301,18 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
  * stay selected until the next transfer.  This is purely a performance
  * hint; the controller driver may need to select a different device
  * for the next message.
+ *
+ * The code that submits an spi_message (and its spi_transfers)
+ * to the lower layers is responsible for managing its memory.
+ * Zero-initialize every field you don't set up explicitly, to
+ * insulate against future API updates.  After you submit a message
+ * and its transfers, ignore them until its completion callback.
  */
 struct spi_transfer {
        /* it's ok if tx_buf == rx_buf (right?)
         * for MicroWire, one buffer must be null
-        * buffers must work with dma_*map_single() calls
+        * buffers must work with dma_*map_single() calls, unless
+        *   spi_message.is_dma_mapped reports a pre-existing mapping
         */
        const void      *tx_buf;
        void            *rx_buf;
@@ -286,12 +323,13 @@ struct spi_transfer {
 
        unsigned        cs_change:1;
        u16             delay_usecs;
+
+       struct list_head transfer_list;
 };
 
 /**
  * struct spi_message - one multi-segment SPI transaction
- * @transfers: the segements of the transaction
- * @n_transfer: how many segments
+ * @transfers: list of transfer segments in this transaction
  * @spi: SPI device to which the transaction is queued
  * @is_dma_mapped: if true, the caller provided both dma and cpu virtual
  *     addresses for each transfer buffer
@@ -302,10 +340,23 @@ struct spi_transfer {
  * @status: zero for success, else negative errno
  * @queue: for use by whichever driver currently owns the message
  * @state: for use by whichever driver currently owns the message
+ *
+ * An spi_message is used to execute an atomic sequence of data transfers,
+ * each represented by a struct spi_transfer.  The sequence is "atomic"
+ * in the sense that no other spi_message may use that SPI bus until that
+ * sequence completes.  On some systems, many such sequences can execute as
+ * as single programmed DMA transfer.  On all systems, these messages are
+ * queued, and might complete after transactions to other devices.  Messages
+ * sent to a given spi_device are alway executed in FIFO order.
+ *
+ * The code that submits an spi_message (and its spi_transfers)
+ * to the lower layers is responsible for managing its memory.
+ * Zero-initialize every field you don't set up explicitly, to
+ * insulate against future API updates.  After you submit a message
+ * and its transfers, ignore them until its completion callback.
  */
 struct spi_message {
-       struct spi_transfer     *transfers;
-       unsigned                n_transfer;
+       struct list_head        transfers;
 
        struct spi_device       *spi;
 
@@ -323,7 +374,7 @@ struct spi_message {
         */
 
        /* completion is reported through a callback */
-       void                    FASTCALL((*complete)(void *context));
+       void                    (*complete)(void *context);
        void                    *context;
        unsigned                actual_length;
        int                     status;
@@ -336,6 +387,51 @@ struct spi_message {
        void                    *state;
 };
 
+static inline void spi_message_init(struct spi_message *m)
+{
+       memset(m, 0, sizeof *m);
+       INIT_LIST_HEAD(&m->transfers);
+}
+
+static inline void
+spi_message_add_tail(struct spi_transfer *t, struct spi_message *m)
+{
+       list_add_tail(&t->transfer_list, &m->transfers);
+}
+
+static inline void
+spi_transfer_del(struct spi_transfer *t)
+{
+       list_del(&t->transfer_list);
+}
+
+/* It's fine to embed message and transaction structures in other data
+ * structures so long as you don't free them while they're in use.
+ */
+
+static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags)
+{
+       struct spi_message *m;
+
+       m = kzalloc(sizeof(struct spi_message)
+                       + ntrans * sizeof(struct spi_transfer),
+                       flags);
+       if (m) {
+               int i;
+               struct spi_transfer *t = (struct spi_transfer *)(m + 1);
+
+               INIT_LIST_HEAD(&m->transfers);
+               for (i = 0; i < ntrans; i++, t++)
+                       spi_message_add_tail(t, m);
+       }
+       return m;
+}
+
+static inline void spi_message_free(struct spi_message *m)
+{
+       kfree(m);
+}
+
 /**
  * spi_setup -- setup SPI mode and clock rate
  * @spi: the device whose settings are being modified
@@ -344,6 +440,8 @@ struct spi_message {
  * device doesn't work with the mode 0 default.  They may likewise need
  * to update clock rates or word sizes from initial values.  This function
  * changes those settings, and must be called from a context that can sleep.
+ * The changes take effect the next time the device is selected and data
+ * is transferred to or from it.
  */
 static inline int
 spi_setup(struct spi_device *spi)
@@ -363,7 +461,10 @@ spi_setup(struct spi_device *spi)
  * The completion callback is invoked in a context which can't sleep.
  * Before that invocation, the value of message->status is undefined.
  * When the callback is issued, message->status holds either zero (to
- * indicate complete success) or a negative error code.
+ * indicate complete success) or a negative error code.  After that
+ * callback returns, the driver which issued the transfer request may
+ * deallocate the associated memory; it's no longer in use by any SPI
+ * core or controller driver code.
  *
  * Note that although all messages to a spi_device are handled in
  * FIFO order, messages may go to different devices in other orders.
@@ -407,15 +508,12 @@ spi_write(struct spi_device *spi, const u8 *buf, size_t len)
 {
        struct spi_transfer     t = {
                        .tx_buf         = buf,
-                       .rx_buf         = NULL,
                        .len            = len,
-                       .cs_change      = 0,
-               };
-       struct spi_message      m = {
-                       .transfers      = &t,
-                       .n_transfer     = 1,
                };
+       struct spi_message      m;
 
+       spi_message_init(&m);
+       spi_message_add_tail(&t, &m);
        return spi_sync(spi, &m);
 }
 
@@ -432,19 +530,17 @@ static inline int
 spi_read(struct spi_device *spi, u8 *buf, size_t len)
 {
        struct spi_transfer     t = {
-                       .tx_buf         = NULL,
                        .rx_buf         = buf,
                        .len            = len,
-                       .cs_change      = 0,
-               };
-       struct spi_message      m = {
-                       .transfers      = &t,
-                       .n_transfer     = 1,
                };
+       struct spi_message      m;
 
+       spi_message_init(&m);
+       spi_message_add_tail(&t, &m);
        return spi_sync(spi, &m);
 }
 
+/* this copies txbuf and rxbuf data; for small transfers only! */
 extern int spi_write_then_read(struct spi_device *spi,
                const u8 *txbuf, unsigned n_tx,
                u8 *rxbuf, unsigned n_rx);
@@ -555,8 +651,9 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
 
 
 /* If you're hotplugging an adapter with devices (parport, usb, etc)
- * use spi_new_device() to describe each device.  You would then call
- * spi_unregister_device() to start making that device vanish.
+ * use spi_new_device() to describe each device.  You can also call
+ * spi_unregister_device() to start making that device vanish, but
+ * normally that would be handled by spi_unregister_master().
  */
 extern struct spi_device *
 spi_new_device(struct spi_master *, struct spi_board_info *);