diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:08:46 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:08:46 -0800 |
commit | 021db8e2bde53024a163fb4417a185de46fe77aa (patch) | |
tree | 098a28bd2414ea2622493a1736a677dab5085dfc /include | |
parent | 72eb6a791459c87a0340318840bb3bd9252b627b (diff) | |
parent | 07fe0351702b6f0c9749e80cdbcb758686b0fe9b (diff) |
Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
* 'next-spi' of git://git.secretlab.ca/git/linux-2.6: (77 commits)
spi/omap: Fix DMA API usage in OMAP MCSPI driver
spi/imx: correct the test on platform_get_irq() return value
spi/topcliff: Typo fix threhold to threshold
spi/dw_spi Typo change diable to disable.
spi/fsl_espi: change the read behaviour of the SPIRF
spi/mpc52xx-psc-spi: move probe/remove to proper sections
spi/dw_spi: add DMA support
spi/dw_spi: change to EXPORT_SYMBOL_GPL for exported APIs
spi/dw_spi: Fix too short timeout in spi polling loop
spi/pl022: convert running variable
spi/pl022: convert busy flag to a bool
spi/pl022: pass the returned sglen to the DMA engine
spi/pl022: map the buffers on the DMA engine
spi/topcliff_pch: Fix data transfer issue
spi/imx: remove autodetection
spi/pxa2xx: pass of_node to spi device and set a parent device
spi/pxa2xx: Modify RX-Tresh instead of busy-loop for the remaining RX bytes.
spi/pxa2xx: Add chipselect support for Sodaville
spi/pxa2xx: Consider CE4100's FIFO depth
spi/pxa2xx: Add CE4100 support
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/pxa2xx_ssp.h | 209 | ||||
-rw-r--r-- | include/linux/spi/dw_spi.h | 24 | ||||
-rw-r--r-- | include/linux/spi/pxa2xx_spi.h | 152 |
3 files changed, 380 insertions, 5 deletions
diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h new file mode 100644 index 000000000000..2f691e4e6222 --- /dev/null +++ b/include/linux/pxa2xx_ssp.h @@ -0,0 +1,209 @@ +/* + * pxa2xx_ssp.h + * + * Copyright (C) 2003 Russell King, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This driver supports the following PXA CPU/SSP ports:- + * + * PXA250 SSP + * PXA255 SSP, NSSP + * PXA26x SSP, NSSP, ASSP + * PXA27x SSP1, SSP2, SSP3 + * PXA3xx SSP1, SSP2, SSP3, SSP4 + */ + +#ifndef __LINUX_SSP_H +#define __LINUX_SSP_H + +#include <linux/list.h> +#include <linux/io.h> + +/* + * SSP Serial Port Registers + * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. + * PXA255, PXA26x and PXA27x have extra ports, registers and bits. + */ + +#define SSCR0 (0x00) /* SSP Control Register 0 */ +#define SSCR1 (0x04) /* SSP Control Register 1 */ +#define SSSR (0x08) /* SSP Status Register */ +#define SSITR (0x0C) /* SSP Interrupt Test Register */ +#define SSDR (0x10) /* SSP Data Write/Data Read Register */ + +#define SSTO (0x28) /* SSP Time Out Register */ +#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ +#define SSTSA (0x30) /* SSP Tx Timeslot Active */ +#define SSRSA (0x34) /* SSP Rx Timeslot Active */ +#define SSTSS (0x38) /* SSP Timeslot Status */ +#define SSACD (0x3C) /* SSP Audio Clock Divider */ +#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ + +/* Common PXA2xx bits first */ +#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ +#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ +#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ +#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ +#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ +#define SSCR0_National (0x2 << 4) /* National Microwire */ +#define SSCR0_ECS (1 << 6) /* External clock select */ +#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ +#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ + +/* PXA27x, PXA3xx */ +#define SSCR0_EDSS (1 << 20) /* Extended data size select */ +#define SSCR0_NCS (1 << 21) /* Network clock select */ +#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ +#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ +#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ +#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ +#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ +#define SSCR0_ACS (1 << 30) /* Audio clock select */ +#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ + + +#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ +#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ +#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ +#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ +#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ +#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ + +#define SSSR_ALT_FRM_MASK 3 /* Masks the SFRM signal number */ +#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ +#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ +#define SSSR_BSY (1 << 4) /* SSP Busy */ +#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ +#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ +#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ + +#ifdef CONFIG_ARCH_PXA +#define RX_THRESH_DFLT 8 +#define TX_THRESH_DFLT 8 + +#define SSSR_TFL_MASK (0xf << 8) /* Transmit FIFO Level mask */ +#define SSSR_RFL_MASK (0xf << 12) /* Receive FIFO Level mask */ + +#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ +#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ + +#else + +#define RX_THRESH_DFLT 2 +#define TX_THRESH_DFLT 2 + +#define SSSR_TFL_MASK (0x3 << 8) /* Transmit FIFO Level mask */ +#define SSSR_RFL_MASK (0x3 << 12) /* Receive FIFO Level mask */ + +#define SSCR1_TFT (0x000000c0) /* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..4] */ +#define SSCR1_RFT (0x00000c00) /* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ +#endif + +/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ +#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ +#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ +#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ +#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ +#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ +#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ +#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ +#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ +#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ +#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ +#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ +#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ +#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ +#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ +#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ +#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ +#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ +#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ +#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ + +#define SSSR_BCE (1 << 23) /* Bit Count Error */ +#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ +#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ +#define SSSR_EOC (1 << 20) /* End Of Chain */ +#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ +#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ + + +#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ +#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ +#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ +#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ +#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ +#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ +#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ +#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ +#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ + +/* PXA3xx */ +#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ +#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ +#define SSPSP_TIMING_MASK (0x7f8001f0) + +#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ +#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ +#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ +#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ + +enum pxa_ssp_type { + SSP_UNDEFINED = 0, + PXA25x_SSP, /* pxa 210, 250, 255, 26x */ + PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ + PXA27x_SSP, + PXA168_SSP, + CE4100_SSP, +}; + +struct ssp_device { + struct platform_device *pdev; + struct list_head node; + + struct clk *clk; + void __iomem *mmio_base; + unsigned long phys_base; + + const char *label; + int port_id; + int type; + int use_count; + int irq; + int drcmr_rx; + int drcmr_tx; +}; + +/** + * pxa_ssp_write_reg - Write to a SSP register + * + * @dev: SSP device to access + * @reg: Register to write to + * @val: Value to be written. + */ +static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val) +{ + __raw_writel(val, dev->mmio_base + reg); +} + +/** + * pxa_ssp_read_reg - Read from a SSP register + * + * @dev: SSP device to access + * @reg: Register to read from + */ +static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) +{ + return __raw_readl(dev->mmio_base + reg); +} + +struct ssp_device *pxa_ssp_request(int port, const char *label); +void pxa_ssp_free(struct ssp_device *); +#endif diff --git a/include/linux/spi/dw_spi.h b/include/linux/spi/dw_spi.h index c91302f3a257..6cd10f6ad472 100644 --- a/include/linux/spi/dw_spi.h +++ b/include/linux/spi/dw_spi.h @@ -1,5 +1,6 @@ #ifndef DW_SPI_HEADER_H #define DW_SPI_HEADER_H + #include <linux/io.h> /* Bit fields in CTRLR0 */ @@ -82,6 +83,13 @@ struct dw_spi_reg { though only low 16 bits matters */ } __packed; +struct dw_spi; +struct dw_spi_dma_ops { + int (*dma_init)(struct dw_spi *dws); + void (*dma_exit)(struct dw_spi *dws); + int (*dma_transfer)(struct dw_spi *dws, int cs_change); +}; + struct dw_spi { struct spi_master *master; struct spi_device *cur_dev; @@ -136,13 +144,15 @@ struct dw_spi { /* Dma info */ int dma_inited; struct dma_chan *txchan; + struct scatterlist tx_sgl; struct dma_chan *rxchan; - int txdma_done; - int rxdma_done; - u64 tx_param; - u64 rx_param; + struct scatterlist rx_sgl; + int dma_chan_done; struct device *dma_dev; - dma_addr_t dma_addr; + dma_addr_t dma_addr; /* phy address of the Data register */ + struct dw_spi_dma_ops *dma_ops; + void *dma_priv; /* platform relate info */ + struct pci_dev *dmac; /* Bus interface info */ void *priv; @@ -216,4 +226,8 @@ extern int dw_spi_add_host(struct dw_spi *dws); extern void dw_spi_remove_host(struct dw_spi *dws); extern int dw_spi_suspend_host(struct dw_spi *dws); extern int dw_spi_resume_host(struct dw_spi *dws); +extern void dw_spi_xfer_done(struct dw_spi *dws); + +/* platform related setup */ +extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */ #endif /* DW_SPI_HEADER_H */ diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h new file mode 100644 index 000000000000..d3e1075f7b60 --- /dev/null +++ b/include/linux/spi/pxa2xx_spi.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __linux_pxa2xx_spi_h +#define __linux_pxa2xx_spi_h + +#include <linux/pxa2xx_ssp.h> + +#define PXA2XX_CS_ASSERT (0x01) +#define PXA2XX_CS_DEASSERT (0x02) + +/* device.platform_data for SSP controller devices */ +struct pxa2xx_spi_master { + u32 clock_enable; + u16 num_chipselect; + u8 enable_dma; +}; + +/* spi_board_info.controller_data for SPI slave devices, + * copied to spi_device.platform_data ... mostly for dma tuning + */ +struct pxa2xx_spi_chip { + u8 tx_threshold; + u8 rx_threshold; + u8 dma_burst_size; + u32 timeout; + u8 enable_loopback; + int gpio_cs; + void (*cs_control)(u32 command); +}; + +#ifdef CONFIG_ARCH_PXA + +#include <linux/clk.h> +#include <mach/dma.h> + +extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); + +#else +/* + * This is the implemtation for CE4100 on x86. ARM defines them in mach/ or + * plat/ include path. + * The CE4100 does not provide DMA support. This bits are here to let the driver + * compile and will never be used. Maybe we get DMA support at a later point in + * time. + */ + +#define DCSR(n) (n) +#define DSADR(n) (n) +#define DTADR(n) (n) +#define DCMD(n) (n) +#define DRCMR(n) (n) + +#define DCSR_RUN (1 << 31) /* Run Bit */ +#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch */ +#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable */ +#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */ +#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */ +#define DCSR_ENDINTR (1 << 2) /* End Interrupt */ +#define DCSR_STARTINTR (1 << 1) /* Start Interrupt */ +#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt */ + +#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable */ +#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ +#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ +#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */ +#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */ +#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */ +#define DCSR_EORINTR (1 << 9) /* The end of Receive */ + +#define DRCMR_MAPVLD (1 << 7) /* Map Valid */ +#define DRCMR_CHLNUM 0x1f /* mask for Channel Number */ + +#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor */ +#define DDADR_STOP (1 << 0) /* Stop */ + +#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ +#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ +#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ +#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ +#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ +#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ +#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ +#define DCMD_BURST8 (1 << 16) /* 8 byte burst */ +#define DCMD_BURST16 (2 << 16) /* 16 byte burst */ +#define DCMD_BURST32 (3 << 16) /* 32 byte burst */ +#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */ +#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */ +#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ +#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ + +/* + * Descriptor structure for PXA's DMA engine + * Note: this structure must always be aligned to a 16-byte boundary. + */ + +typedef enum { + DMA_PRIO_HIGH = 0, + DMA_PRIO_MEDIUM = 1, + DMA_PRIO_LOW = 2 +} pxa_dma_prio; + +/* + * DMA registration + */ + +static inline int pxa_request_dma(char *name, + pxa_dma_prio prio, + void (*irq_handler)(int, void *), + void *data) +{ + return -ENODEV; +} + +static inline void pxa_free_dma(int dma_ch) +{ +} + +/* + * The CE4100 does not have the clk framework implemented and SPI clock can + * not be switched on/off or the divider changed. + */ +static inline void clk_disable(struct clk *clk) +{ +} + +static inline int clk_enable(struct clk *clk) +{ + return 0; +} + +static inline unsigned long clk_get_rate(struct clk *clk) +{ + return 3686400; +} + +#endif +#endif |