2 * Copyright (C) ST-Ericsson AB 2010
3 * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com
4 * Author: Daniel Martensson / Daniel.Martensson@stericsson.com
5 * License terms: GNU General Public License (GPL) version 2.
7 #include <linux/version.h>
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/device.h>
11 #include <linux/platform_device.h>
12 #include <linux/string.h>
13 #include <linux/semaphore.h>
14 #include <linux/workqueue.h>
15 #include <linux/completion.h>
16 #include <linux/list.h>
17 #include <linux/interrupt.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/delay.h>
20 #include <linux/sched.h>
21 #include <linux/debugfs.h>
22 #include <net/caif/caif_spi.h>
24 #ifndef CONFIG_CAIF_SPI_SYNC
25 #define SPI_DATA_POS 0
26 static inline int forward_to_spi_cmd(struct cfspi
*cfspi
)
28 return cfspi
->rx_cpck_len
;
31 #define SPI_DATA_POS SPI_CMD_SZ
32 static inline int forward_to_spi_cmd(struct cfspi
*cfspi
)
38 int spi_frm_align
= 2;
41 * SPI padding options.
42 * Warning: must be a base of 2 (& operation used) and can not be zero !
44 int spi_up_head_align
= 1 << 1;
45 int spi_up_tail_align
= 1 << 0;
46 int spi_down_head_align
= 1 << 2;
47 int spi_down_tail_align
= 1 << 1;
49 #ifdef CONFIG_DEBUG_FS
50 static inline void debugfs_store_prev(struct cfspi
*cfspi
)
52 /* Store previous command for debugging reasons.*/
53 cfspi
->pcmd
= cfspi
->cmd
;
54 /* Store previous transfer. */
55 cfspi
->tx_ppck_len
= cfspi
->tx_cpck_len
;
56 cfspi
->rx_ppck_len
= cfspi
->rx_cpck_len
;
59 static inline void debugfs_store_prev(struct cfspi
*cfspi
)
64 void cfspi_xfer(struct work_struct
*work
)
70 cfspi
= container_of(work
, struct cfspi
, work
);
72 /* Initialize state. */
73 cfspi
->cmd
= SPI_CMD_EOT
;
77 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAITING
);
79 /* Wait for master talk or transmit event. */
80 wait_event_interruptible(cfspi
->wait
,
81 test_bit(SPI_XFER
, &cfspi
->state
) ||
82 test_bit(SPI_TERMINATE
, &cfspi
->state
));
84 if (test_bit(SPI_TERMINATE
, &cfspi
->state
))
88 /* Prefill buffers for easier debugging. */
89 memset(cfspi
->xfer
.va_tx
, 0xFF, SPI_DMA_BUF_LEN
);
90 memset(cfspi
->xfer
.va_rx
, 0xFF, SPI_DMA_BUF_LEN
);
91 #endif /* CFSPI_DBG_PREFILL */
93 cfspi_dbg_state(cfspi
, CFSPI_STATE_AWAKE
);
95 /* Check whether we have a committed frame. */
96 if (cfspi
->tx_cpck_len
) {
99 cfspi_dbg_state(cfspi
, CFSPI_STATE_FETCH_PKT
);
101 /* Copy committed SPI frames after the SPI indication. */
102 ptr
= (u8
*) cfspi
->xfer
.va_tx
;
104 len
= cfspi_xmitfrm(cfspi
, ptr
, cfspi
->tx_cpck_len
);
105 WARN_ON(len
!= cfspi
->tx_cpck_len
);
108 cfspi_dbg_state(cfspi
, CFSPI_STATE_GET_NEXT
);
110 /* Get length of next frame to commit. */
111 cfspi
->tx_npck_len
= cfspi_xmitlen(cfspi
);
113 WARN_ON(cfspi
->tx_npck_len
> SPI_DMA_BUF_LEN
);
116 * Add indication and length at the beginning of the frame,
117 * using little endian.
119 ptr
= (u8
*) cfspi
->xfer
.va_tx
;
120 *ptr
++ = SPI_CMD_IND
;
121 *ptr
++ = (SPI_CMD_IND
& 0xFF00) >> 8;
122 *ptr
++ = cfspi
->tx_npck_len
& 0x00FF;
123 *ptr
++ = (cfspi
->tx_npck_len
& 0xFF00) >> 8;
125 /* Calculate length of DMAs. */
126 cfspi
->xfer
.tx_dma_len
= cfspi
->tx_cpck_len
+ SPI_IND_SZ
;
127 cfspi
->xfer
.rx_dma_len
= cfspi
->rx_cpck_len
+ SPI_CMD_SZ
;
129 /* Add SPI TX frame alignment padding, if necessary. */
130 if (cfspi
->tx_cpck_len
&&
131 (cfspi
->xfer
.tx_dma_len
% spi_frm_align
)) {
133 cfspi
->xfer
.tx_dma_len
+= spi_frm_align
-
134 (cfspi
->xfer
.tx_dma_len
% spi_frm_align
);
137 /* Add SPI RX frame alignment padding, if necessary. */
138 if (cfspi
->rx_cpck_len
&&
139 (cfspi
->xfer
.rx_dma_len
% spi_frm_align
)) {
141 cfspi
->xfer
.rx_dma_len
+= spi_frm_align
-
142 (cfspi
->xfer
.rx_dma_len
% spi_frm_align
);
145 cfspi_dbg_state(cfspi
, CFSPI_STATE_INIT_XFER
);
147 /* Start transfer. */
148 ret
= cfspi
->dev
->init_xfer(&cfspi
->xfer
, cfspi
->dev
);
151 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_ACTIVE
);
154 * TODO: We might be able to make an assumption if this is the
155 * first loop. Make sure that minimum toggle time is respected.
157 udelay(MIN_TRANSITION_TIME_USEC
);
159 cfspi_dbg_state(cfspi
, CFSPI_STATE_SIG_ACTIVE
);
161 /* Signal that we are ready to receive data. */
162 cfspi
->dev
->sig_xfer(true, cfspi
->dev
);
164 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_XFER_DONE
);
166 /* Wait for transfer completion. */
167 wait_for_completion(&cfspi
->comp
);
169 cfspi_dbg_state(cfspi
, CFSPI_STATE_XFER_DONE
);
171 if (cfspi
->cmd
== SPI_CMD_EOT
) {
173 * Clear the master talk bit. A xfer is always at
176 clear_bit(SPI_SS_ON
, &cfspi
->state
);
179 cfspi_dbg_state(cfspi
, CFSPI_STATE_WAIT_INACTIVE
);
181 /* Make sure that the minimum toggle time is respected. */
182 if (SPI_XFER_TIME_USEC(cfspi
->xfer
.tx_dma_len
,
183 cfspi
->dev
->clk_mhz
) <
184 MIN_TRANSITION_TIME_USEC
) {
186 udelay(MIN_TRANSITION_TIME_USEC
-
188 (cfspi
->xfer
.tx_dma_len
, cfspi
->dev
->clk_mhz
));
191 cfspi_dbg_state(cfspi
, CFSPI_STATE_SIG_INACTIVE
);
193 /* De-assert transfer signal. */
194 cfspi
->dev
->sig_xfer(false, cfspi
->dev
);
196 /* Check whether we received a CAIF packet. */
197 if (cfspi
->rx_cpck_len
) {
200 cfspi_dbg_state(cfspi
, CFSPI_STATE_DELIVER_PKT
);
202 /* Parse SPI frame. */
203 ptr
= ((u8
*)(cfspi
->xfer
.va_rx
+ SPI_DATA_POS
));
205 len
= cfspi_rxfrm(cfspi
, ptr
, cfspi
->rx_cpck_len
);
206 WARN_ON(len
!= cfspi
->rx_cpck_len
);
209 /* Check the next SPI command and length. */
210 ptr
= (u8
*) cfspi
->xfer
.va_rx
;
212 ptr
+= forward_to_spi_cmd(cfspi
);
215 cfspi
->cmd
|= ((*ptr
++) << 8) & 0xFF00;
216 cfspi
->rx_npck_len
= *ptr
++;
217 cfspi
->rx_npck_len
|= ((*ptr
++) << 8) & 0xFF00;
219 WARN_ON(cfspi
->rx_npck_len
> SPI_DMA_BUF_LEN
);
220 WARN_ON(cfspi
->cmd
> SPI_CMD_EOT
);
222 debugfs_store_prev(cfspi
);
224 /* Check whether the master issued an EOT command. */
225 if (cfspi
->cmd
== SPI_CMD_EOT
) {
227 cfspi
->tx_cpck_len
= 0;
228 cfspi
->rx_cpck_len
= 0;
231 cfspi
->tx_cpck_len
= cfspi
->tx_npck_len
;
232 cfspi
->rx_cpck_len
= cfspi
->rx_npck_len
;
236 * Check whether we need to clear the xfer bit.
237 * Spin lock needed for packet insertion.
238 * Test and clear of different bits
241 spin_lock_irqsave(&cfspi
->lock
, flags
);
242 if (cfspi
->cmd
== SPI_CMD_EOT
&& !cfspi_xmitlen(cfspi
)
243 && !test_bit(SPI_SS_ON
, &cfspi
->state
))
244 clear_bit(SPI_XFER
, &cfspi
->state
);
246 spin_unlock_irqrestore(&cfspi
->lock
, flags
);
250 struct platform_driver cfspi_spi_driver
= {
251 .probe
= cfspi_spi_probe
,
252 .remove
= cfspi_spi_remove
,
254 .name
= "cfspi_sspi",
255 .owner
= THIS_MODULE
,