136 lines
3.9 KiB
C
136 lines
3.9 KiB
C
#ifndef _SPI_MPC_H_
|
|
#include <linux/types.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/completion.h>
|
|
|
|
/* SPI Controller mode register definitions */
|
|
#define SPMODE_LOOP (1 << 30)
|
|
#define SPMODE_CI_INACTIVEHIGH (1 << 29)
|
|
#define SPMODE_CP_BEGIN_EDGECLK (1 << 28)
|
|
#define SPMODE_DIV16 (1 << 27)
|
|
#define SPMODE_REV (1 << 26)
|
|
#define SPMODE_MS (1 << 25)
|
|
#define SPMODE_ENABLE (1 << 24)
|
|
#define SPMODE_LEN(x) ((x) << 20)
|
|
#define SPMODE_PM(x) ((x) << 16)
|
|
#define SPMODE_OP (1 << 14)
|
|
#define SPMODE_CG(x) ((x) << 7)
|
|
#define SPMODE_OD (1<< 12)
|
|
|
|
/*
|
|
* Default for SPI Mode:
|
|
* SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
|
|
*/
|
|
|
|
#define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_REV | \
|
|
SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0x3))
|
|
|
|
/* SPIE register values */
|
|
#define SPIE_NE 0x00000200 /* Not empty */
|
|
#define SPIE_NF 0x00000100 /* Not full */
|
|
|
|
/* SPIM register values */
|
|
#define SPIM_NE 0x00000200 /* Not empty */
|
|
#define SPIM_NF 0x00000100 /* Not full */
|
|
|
|
#define SPIE_TXB 0x00000200 /* Last char is written to tx fifo */
|
|
#define SPIE_RXB 0x00000100 /* Last char is written to rx buf */
|
|
|
|
/* SPCOM register values */
|
|
#define SPCOM_STR (1 << 23) /* Start transmit */
|
|
|
|
#define SPI_PRAM_SIZE 0x100
|
|
#define SPI_MRBLR ((unsigned int)PAGE_SIZE)
|
|
|
|
struct gpio_struct
|
|
{
|
|
unsigned int dir;
|
|
unsigned int odr;
|
|
unsigned int dat;
|
|
unsigned int ier;
|
|
unsigned int imr;
|
|
unsigned int icr;
|
|
};
|
|
|
|
/* SPI Controller registers */
|
|
struct mpc8xxx_spi_reg
|
|
{
|
|
unsigned char res1[0x20];
|
|
__be32 mode;
|
|
__be32 event;
|
|
__be32 mask;
|
|
__be32 command;
|
|
__be32 transmit;
|
|
__be32 receive;
|
|
};
|
|
|
|
/* SPI Controller driver's private data. */
|
|
struct mpc8xxx_spi
|
|
{
|
|
struct device* dev;
|
|
struct mpc8xxx_spi_reg __iomem* base;
|
|
|
|
/* rx & tx bufs from the spi_transfer */
|
|
const void* tx;
|
|
void* rx;
|
|
struct spi_transfer* xfer_in_progress;
|
|
|
|
/* functions to deal with different sized buffers */
|
|
void (*get_rx)(u32 rx_data, struct mpc8xxx_spi*);
|
|
u32(*get_tx)(struct mpc8xxx_spi*);
|
|
|
|
unsigned int count;
|
|
unsigned int irq;
|
|
|
|
unsigned nsecs; /* (clock cycle time)/2 */
|
|
|
|
u32 spibrg; /* SPIBRG input clock */
|
|
u32 rx_shift; /* RX data reg shift when in qe mode */
|
|
u32 tx_shift; /* TX data reg shift when in qe mode */
|
|
|
|
unsigned int flags;
|
|
|
|
struct workqueue_struct* workqueue;
|
|
struct work_struct work;
|
|
|
|
struct list_head queue;
|
|
spinlock_t lock;
|
|
|
|
struct completion done;
|
|
};
|
|
|
|
struct spi_mpc8xxx_cs
|
|
{
|
|
/* functions to deal with different sized buffers */
|
|
void (*get_rx)(u32 rx_data, struct mpc8xxx_spi*);
|
|
u32(*get_tx)(struct mpc8xxx_spi*);
|
|
u32 rx_shift; /* RX data reg shift when in qe mode */
|
|
u32 tx_shift; /* TX data reg shift when in qe mode */
|
|
u32 hw_mode; /* Holds HW mode register settings */
|
|
};
|
|
|
|
|
|
#define MPC83XX_SPI_RX_BUF(type) \
|
|
static \
|
|
void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \
|
|
{ \
|
|
type *rx = mpc8xxx_spi->rx; \
|
|
*rx++ = (type)(data >> mpc8xxx_spi->rx_shift); \
|
|
mpc8xxx_spi->rx = rx; \
|
|
}
|
|
|
|
#define MPC83XX_SPI_TX_BUF(type) \
|
|
static unsigned int \
|
|
mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi) \
|
|
{ \
|
|
unsigned int data; \
|
|
const type *tx = mpc8xxx_spi->tx; \
|
|
if (!tx) \
|
|
return 0; \
|
|
data = *tx++ << mpc8xxx_spi->tx_shift; \
|
|
mpc8xxx_spi->tx = tx; \
|
|
return data; \
|
|
}
|
|
|
|
#endif
|