1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2007 Will Robertson
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "spi-imx31.h"
24 #include "avic-imx31.h"
25 #include "ccm-imx31.h"
29 /* Forward interrupt handler declarations */
30 #if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
31 static __attribute__((interrupt("IRQ"))) void CSPI1_HANDLER(void);
33 #if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
34 static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void);
36 #if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
37 static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void);
40 /* State data associatated with each CSPI module */
41 static struct spi_module_descriptor
43 struct cspi_map
* const base
;
45 struct spi_node
*last
;
46 enum IMX31_CG_LIST cg
;
47 enum IMX31_INT_LIST ints
;
49 void (*handler
)(void);
52 struct spi_transfer
*trans
;
54 } spi_descs
[SPI_NUM_CSPI
] =
55 /* Init non-zero members */
57 #if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
59 .base
= (struct cspi_map
*)CSPI1_BASE_ADDR
,
62 .handler
= CSPI1_HANDLER
,
65 #if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
67 .base
= (struct cspi_map
*)CSPI2_BASE_ADDR
,
70 .handler
= CSPI2_HANDLER
,
73 #if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
75 .base
= (struct cspi_map
*)CSPI3_BASE_ADDR
,
78 .handler
= CSPI3_HANDLER
,
83 /* Common code for interrupt handlers */
84 static void spi_interrupt(enum spi_module_number spi
)
86 struct spi_module_descriptor
*desc
= &spi_descs
[spi
];
87 struct cspi_map
* const base
= desc
->base
;
88 struct spi_transfer
*trans
= desc
->trans
;
89 int inc
= desc
->byte_size
+ 1;
91 if (desc
->rxcount
> 0)
93 /* Data received - empty out RXFIFO */
94 while ((base
->statreg
& CSPI_STATREG_RR
) != 0)
96 uint32_t word
= base
->rxdata
;
98 switch (desc
->byte_size
& 3)
101 *(unsigned char *)(trans
->rxbuf
+ 3) = word
>> 24;
103 *(unsigned char *)(trans
->rxbuf
+ 2) = word
>> 16;
105 *(unsigned char *)(trans
->rxbuf
+ 1) = word
>> 8;
107 *(unsigned char *)(trans
->rxbuf
+ 0) = word
;
112 if (--desc
->rxcount
< 4)
114 unsigned long intreg
= base
->intreg
;
116 if (desc
->rxcount
<= 0)
118 /* No more to receive - stop RX interrupts */
119 intreg
&= ~(CSPI_INTREG_RHEN
| CSPI_INTREG_RREN
);
120 base
->intreg
= intreg
;
123 else if (!(intreg
& CSPI_INTREG_RREN
))
125 /* < 4 words expected - switch to RX ready */
126 intreg
&= ~CSPI_INTREG_RHEN
;
127 base
->intreg
= intreg
| CSPI_INTREG_RREN
;
133 if (trans
->count
> 0)
135 /* Data to transmit - fill TXFIFO or write until exhausted */
136 while ((base
->statreg
& CSPI_STATREG_TF
) == 0)
140 switch (desc
->byte_size
& 3)
143 word
= *(unsigned char *)(trans
->txbuf
+ 3) << 24;
145 word
|= *(unsigned char *)(trans
->txbuf
+ 2) << 16;
147 word
|= *(unsigned char *)(trans
->txbuf
+ 1) << 8;
149 word
|= *(unsigned char *)(trans
->txbuf
+ 0);
156 if (--trans
->count
<= 0)
158 /* Out of data - stop TX interrupts */
159 base
->intreg
&= ~CSPI_INTREG_THEN
;
165 /* If all interrupts have been remasked - we're done */
166 if (base
->intreg
== 0)
168 base
->statreg
= CSPI_STATREG_TC
| CSPI_STATREG_BO
;
169 wakeup_signal(&desc
->w
);
173 /* Interrupt handlers for each CSPI module */
174 #if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
175 static __attribute__((interrupt("IRQ"))) void CSPI1_HANDLER(void)
177 spi_interrupt(CSPI1_NUM
);
181 #if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
182 static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void)
184 spi_interrupt(CSPI2_NUM
);
188 #if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
189 static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void)
191 spi_interrupt(CSPI3_NUM
);
195 /* Write the context for the node and remember it to avoid unneeded reconfigure */
196 static bool spi_set_context(struct spi_node
*node
,
197 struct spi_module_descriptor
*desc
)
199 struct cspi_map
* const base
= desc
->base
;
201 if ((base
->conreg
& CSPI_CONREG_EN
) == 0)
204 if (node
!= desc
->last
)
206 /* Switch the module's node */
208 desc
->byte_size
= (((node
->conreg
>> 8) & 0x1f) + 1 + 7) / 8 - 1;
210 /* Keep reserved and start bits cleared. Keep enabled bit. */
212 (node
->conreg
& ~(0xfcc8e000 | CSPI_CONREG_XCH
| CSPI_CONREG_SMC
))
214 /* Set the wait-states */
215 base
->periodreg
= node
->periodreg
& 0xffff;
216 /* Clear out any spuriously-pending interrupts */
217 base
->statreg
= CSPI_STATREG_TC
| CSPI_STATREG_BO
;
223 static void spi_reset(struct cspi_map
* const base
)
226 base
->conreg
&= ~CSPI_CONREG_EN
;
227 base
->conreg
|= CSPI_CONREG_EN
;
229 base
->statreg
= CSPI_STATREG_TC
| CSPI_STATREG_BO
;
232 /* Initialize each of the used SPI descriptors */
237 for (i
= 0; i
< SPI_NUM_CSPI
; i
++)
239 struct spi_module_descriptor
* const desc
= &spi_descs
[i
];
240 mutex_init(&desc
->m
);
241 wakeup_init(&desc
->w
);
245 /* Get mutually-exclusive access to the node */
246 void spi_lock(struct spi_node
*node
)
248 mutex_lock(&spi_descs
[node
->num
].m
);
251 /* Release mutual exclusion */
252 void spi_unlock(struct spi_node
*node
)
254 mutex_unlock(&spi_descs
[node
->num
].m
);
257 /* Enable the specified module for the node */
258 void spi_enable_module(struct spi_node
*node
)
260 struct spi_module_descriptor
* const desc
= &spi_descs
[node
->num
];
262 mutex_lock(&desc
->m
);
264 if (++desc
->enab
== 1)
266 /* First enable for this module */
267 struct cspi_map
* const base
= desc
->base
;
269 /* Enable clock-gating register */
270 ccm_module_clock_gating(desc
->cg
, CGM_ON_RUN_WAIT
);
274 /* Enable interrupt at controller level */
275 avic_enable_int(desc
->ints
, INT_TYPE_IRQ
, INT_PRIO_DEFAULT
,
279 mutex_unlock(&desc
->m
);
282 /* Disabled the specified module for the node */
283 void spi_disable_module(struct spi_node
*node
)
285 struct spi_module_descriptor
* const desc
= &spi_descs
[node
->num
];
287 mutex_lock(&desc
->m
);
289 if (desc
->enab
> 0 && --desc
->enab
== 0)
291 /* Last enable for this module */
292 struct cspi_map
* const base
= desc
->base
;
294 /* Disable interrupt at controller level */
295 avic_disable_int(desc
->ints
);
297 /* Disable interface */
298 base
->conreg
&= ~CSPI_CONREG_EN
;
300 /* Disable interface clock */
301 ccm_module_clock_gating(desc
->cg
, CGM_OFF
);
304 mutex_unlock(&desc
->m
);
307 /* Send and/or receive data on the specified node */
308 int spi_transfer(struct spi_node
*node
, struct spi_transfer
*trans
)
310 struct spi_module_descriptor
* const desc
= &spi_descs
[node
->num
];
313 if (trans
->count
<= 0)
316 mutex_lock(&desc
->m
);
318 retval
= spi_set_context(node
, desc
);
322 struct cspi_map
* const base
= desc
->base
;
323 unsigned long intreg
;
326 desc
->rxcount
= trans
->count
;
328 /* Enable needed interrupts - FIFOs will start filling */
329 intreg
= CSPI_INTREG_THEN
;
331 intreg
|= (trans
->count
< 4) ?
332 CSPI_INTREG_RREN
: /* Must grab data on every word */
333 CSPI_INTREG_RHEN
; /* Enough data to wait for half-full */
335 base
->intreg
= intreg
;
338 base
->conreg
|= CSPI_CONREG_XCH
;
340 if (wakeup_wait(&desc
->w
, HZ
) != OBJ_WAIT_SUCCEEDED
)
342 base
->intreg
= 0; /* Stop SPI ints */
343 spi_reset(base
); /* Reset module (esp. to empty FIFOs) */
344 desc
->last
= NULL
; /* Force reconfigure */
349 mutex_unlock(&desc
->m
);