2 * Copyright (C) ST-Ericsson AB 2010
3 * Author: Daniel Martensson
4 * License terms: GNU General Public License (GPL) version 2.
6 #include <linux/init.h>
7 #include <linux/module.h>
8 #include <linux/device.h>
9 #include <linux/platform_device.h>
10 #include <linux/string.h>
11 #include <linux/semaphore.h>
12 #include <linux/workqueue.h>
13 #include <linux/completion.h>
14 #include <linux/list.h>
15 #include <linux/interrupt.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/delay.h>
18 #include <linux/sched.h>
19 #include <linux/debugfs.h>
20 #include <net/caif/caif_spi.h>
22 #ifndef CONFIG_CAIF_SPI_SYNC
23 #define SPI_DATA_POS 0
24 static inline int forward_to_spi_cmd(struct cfspi
*cfspi
)
26 return cfspi
->rx_cpck_len
;
29 #define SPI_DATA_POS SPI_CMD_SZ
30 static inline int forward_to_spi_cmd(struct cfspi
*cfspi
)
36 int spi_frm_align
= 2;
39 * SPI padding options.
40 * Warning: must be a base of 2 (& operation used) and can not be zero !
42 int spi_up_head_align
= 1 << 1;
43 int spi_up_tail_align
= 1 << 0;
44 int spi_down_head_align
= 1 << 2;
45 int spi_down_tail_align
= 1 << 1;
47 #ifdef CONFIG_DEBUG_FS
48 static inline void debugfs_store_prev(struct cfspi
*cfspi
)
50 /* Store previous command for debugging reasons.*/
51 cfspi
->pcmd
= cfspi
->cmd
;
52 /* Store previous transfer. */
53 cfspi
->tx_ppck_len
= cfspi
->tx_cpck_len
;
54 cfspi
->rx_ppck_len
= cfspi
->rx_cpck_len
;
57 static inline void debugfs_store_prev(struct cfspi
*cfspi
)
62 void cfspi_xfer(struct work_struct
*work
)
68 cfspi
= container_of(work
, struct cfspi
, work
);
70 /* Initialize state. */
71 cfspi
->cmd
= SPI_CMD_EOT
;
75 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAITING
);
77 /* Wait for master talk or transmit event. */
78 wait_event_interruptible(cfspi
->wait
,
79 test_bit(SPI_XFER
, &cfspi
->state
) ||
80 test_bit(SPI_TERMINATE
, &cfspi
->state
));
82 if (test_bit(SPI_TERMINATE
, &cfspi
->state
))
86 /* Prefill buffers for easier debugging. */
87 memset(cfspi
->xfer
.va_tx
, 0xFF, SPI_DMA_BUF_LEN
);
88 memset(cfspi
->xfer
.va_rx
, 0xFF, SPI_DMA_BUF_LEN
);
89 #endif /* CFSPI_DBG_PREFILL */
91 cfspi_dbg_state(cfspi
, CFSPI_STATE_AWAKE
);
93 /* Check whether we have a committed frame. */
94 if (cfspi
->tx_cpck_len
) {
97 cfspi_dbg_state(cfspi
, CFSPI_STATE_FETCH_PKT
);
99 /* Copy committed SPI frames after the SPI indication. */
100 ptr
= (u8
*) cfspi
->xfer
.va_tx
;
102 len
= cfspi_xmitfrm(cfspi
, ptr
, cfspi
->tx_cpck_len
);
103 WARN_ON(len
!= cfspi
->tx_cpck_len
);
106 cfspi_dbg_state(cfspi
, CFSPI_STATE_GET_NEXT
);
108 /* Get length of next frame to commit. */
109 cfspi
->tx_npck_len
= cfspi_xmitlen(cfspi
);
111 WARN_ON(cfspi
->tx_npck_len
> SPI_DMA_BUF_LEN
);
114 * Add indication and length at the beginning of the frame,
115 * using little endian.
117 ptr
= (u8
*) cfspi
->xfer
.va_tx
;
118 *ptr
++ = SPI_CMD_IND
;
119 *ptr
++ = (SPI_CMD_IND
& 0xFF00) >> 8;
120 *ptr
++ = cfspi
->tx_npck_len
& 0x00FF;
121 *ptr
++ = (cfspi
->tx_npck_len
& 0xFF00) >> 8;
123 /* Calculate length of DMAs. */
124 cfspi
->xfer
.tx_dma_len
= cfspi
->tx_cpck_len
+ SPI_IND_SZ
;
125 cfspi
->xfer
.rx_dma_len
= cfspi
->rx_cpck_len
+ SPI_CMD_SZ
;
127 /* Add SPI TX frame alignment padding, if necessary. */
128 if (cfspi
->tx_cpck_len
&&
129 (cfspi
->xfer
.tx_dma_len
% spi_frm_align
)) {
131 cfspi
->xfer
.tx_dma_len
+= spi_frm_align
-
132 (cfspi
->xfer
.tx_dma_len
% spi_frm_align
);
135 /* Add SPI RX frame alignment padding, if necessary. */
136 if (cfspi
->rx_cpck_len
&&
137 (cfspi
->xfer
.rx_dma_len
% spi_frm_align
)) {
139 cfspi
->xfer
.rx_dma_len
+= spi_frm_align
-
140 (cfspi
->xfer
.rx_dma_len
% spi_frm_align
);
143 cfspi_dbg_state(cfspi
, CFSPI_STATE_INIT_XFER
);
145 /* Start transfer. */
146 ret
= cfspi
->dev
->init_xfer(&cfspi
->xfer
, cfspi
->dev
);
149 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_ACTIVE
);
152 * TODO: We might be able to make an assumption if this is the
153 * first loop. Make sure that minimum toggle time is respected.
155 udelay(MIN_TRANSITION_TIME_USEC
);
157 cfspi_dbg_state(cfspi
, CFSPI_STATE_SIG_ACTIVE
);
159 /* Signal that we are ready to receive data. */
160 cfspi
->dev
->sig_xfer(true, cfspi
->dev
);
162 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_XFER_DONE
);
164 /* Wait for transfer completion. */
165 wait_for_completion(&cfspi
->comp
);
167 cfspi_dbg_state(cfspi
, CFSPI_STATE_XFER_DONE
);
169 if (cfspi
->cmd
== SPI_CMD_EOT
) {
171 * Clear the master talk bit. A xfer is always at
174 clear_bit(SPI_SS_ON
, &cfspi
->state
);
177 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_INACTIVE
);
179 /* Make sure that the minimum toggle time is respected. */
180 if (SPI_XFER_TIME_USEC(cfspi
->xfer
.tx_dma_len
,
181 cfspi
->dev
->clk_mhz
) <
182 MIN_TRANSITION_TIME_USEC
) {
184 udelay(MIN_TRANSITION_TIME_USEC
-
186 (cfspi
->xfer
.tx_dma_len
, cfspi
->dev
->clk_mhz
));
189 cfspi_dbg_state(cfspi
, CFSPI_STATE_SIG_INACTIVE
);
191 /* De-assert transfer signal. */
192 cfspi
->dev
->sig_xfer(false, cfspi
->dev
);
194 /* Check whether we received a CAIF packet. */
195 if (cfspi
->rx_cpck_len
) {
198 cfspi_dbg_state(cfspi
, CFSPI_STATE_DELIVER_PKT
);
200 /* Parse SPI frame. */
201 ptr
= ((u8
*)(cfspi
->xfer
.va_rx
+ SPI_DATA_POS
));
203 len
= cfspi_rxfrm(cfspi
, ptr
, cfspi
->rx_cpck_len
);
204 WARN_ON(len
!= cfspi
->rx_cpck_len
);
207 /* Check the next SPI command and length. */
208 ptr
= (u8
*) cfspi
->xfer
.va_rx
;
210 ptr
+= forward_to_spi_cmd(cfspi
);
213 cfspi
->cmd
|= ((*ptr
++) << 8) & 0xFF00;
214 cfspi
->rx_npck_len
= *ptr
++;
215 cfspi
->rx_npck_len
|= ((*ptr
++) << 8) & 0xFF00;
217 WARN_ON(cfspi
->rx_npck_len
> SPI_DMA_BUF_LEN
);
218 WARN_ON(cfspi
->cmd
> SPI_CMD_EOT
);
220 debugfs_store_prev(cfspi
);
222 /* Check whether the master issued an EOT command. */
223 if (cfspi
->cmd
== SPI_CMD_EOT
) {
225 cfspi
->tx_cpck_len
= 0;
226 cfspi
->rx_cpck_len
= 0;
229 cfspi
->tx_cpck_len
= cfspi
->tx_npck_len
;
230 cfspi
->rx_cpck_len
= cfspi
->rx_npck_len
;
234 * Check whether we need to clear the xfer bit.
235 * Spin lock needed for packet insertion.
236 * Test and clear of different bits
239 spin_lock_irqsave(&cfspi
->lock
, flags
);
240 if (cfspi
->cmd
== SPI_CMD_EOT
&& !cfspi_xmitlen(cfspi
)
241 && !test_bit(SPI_SS_ON
, &cfspi
->state
))
242 clear_bit(SPI_XFER
, &cfspi
->state
);
244 spin_unlock_irqrestore(&cfspi
->lock
, flags
);
248 struct platform_driver cfspi_spi_driver
= {
249 .probe
= cfspi_spi_probe
,
250 .remove
= cfspi_spi_remove
,
252 .name
= "cfspi_sspi",
253 .owner
= THIS_MODULE
,