Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[cascardo/linux.git] / arch / arm / mach-imx / ssi-fiq.S
1 /*
2  *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
11 #include <asm/export.h>
12
13 /*
14  * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
15  * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
16  */
17
18 #define SSI_STX0        0x00
19 #define SSI_SRX0        0x08
20 #define SSI_SISR        0x14
21 #define SSI_SIER        0x18
22 #define SSI_SACNT       0x38
23
24 #define SSI_SACNT_AC97EN        (1 << 0)
25
26 #define SSI_SIER_TFE0_EN        (1 << 0)
27 #define SSI_SISR_TFE0           (1 << 0)
28 #define SSI_SISR_RFF0           (1 << 2)
29 #define SSI_SIER_RFF0_EN        (1 << 2)
30
31                 .text
32                 .global imx_ssi_fiq_start
33                 .global imx_ssi_fiq_end
34                 .global imx_ssi_fiq_base
35                 .global imx_ssi_fiq_rx_buffer
36                 .global imx_ssi_fiq_tx_buffer
37
38 /*
39  * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
40  * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
41  * mark the function body so that it can be copied to the FIQ vector in
42  * the vectors page.  imx_ssi_fiq_start should only be called as the result
43  * of an FIQ: calling it directly will not work.
44  */
45 imx_ssi_fiq_start:
46                 ldr r12, .L_imx_ssi_fiq_base
47
48                 /* TX */
49                 ldr r13, .L_imx_ssi_fiq_tx_buffer
50
51                 /* shall we send? */
52                 ldr r11, [r12, #SSI_SIER]
53                 tst r11, #SSI_SIER_TFE0_EN
54                 beq 1f
55
56                 /* TX FIFO empty? */
57                 ldr r11, [r12, #SSI_SISR]
58                 tst r11, #SSI_SISR_TFE0
59                 beq 1f
60
61                 mov r10, #0x10000
62                 sub r10, #1
63                 and r10, r10, r8        /* r10: current buffer offset */
64
65                 add r13, r13, r10
66
67                 ldrh r11, [r13]
68                 strh r11, [r12, #SSI_STX0]
69
70                 ldrh r11, [r13, #2]
71                 strh r11, [r12, #SSI_STX0]
72
73                 ldrh r11, [r13, #4]
74                 strh r11, [r12, #SSI_STX0]
75
76                 ldrh r11, [r13, #6]
77                 strh r11, [r12, #SSI_STX0]
78
79                 add r10, #8
80                 lsr r11, r8, #16        /* r11: buffer size */
81                 cmp r10, r11
82                 lslgt r8, r11, #16
83                 addle r8, #8
84 1:
85                 /* RX */
86
87                 /* shall we receive? */
88                 ldr r11, [r12, #SSI_SIER]
89                 tst r11, #SSI_SIER_RFF0_EN
90                 beq 1f
91
92                 /* RX FIFO full? */
93                 ldr r11, [r12, #SSI_SISR]
94                 tst r11, #SSI_SISR_RFF0
95                 beq 1f
96
97                 ldr r13, .L_imx_ssi_fiq_rx_buffer
98
99                 mov r10, #0x10000
100                 sub r10, #1
101                 and r10, r10, r9        /* r10: current buffer offset */
102
103                 add r13, r13, r10
104
105                 ldr r11, [r12, #SSI_SACNT]
106                 tst r11, #SSI_SACNT_AC97EN
107
108                 ldr r11, [r12, #SSI_SRX0]
109                 strh r11, [r13]
110
111                 ldr r11, [r12, #SSI_SRX0]
112                 strh r11, [r13, #2]
113
114                 /* dummy read to skip slot 12 */
115                 ldrne r11, [r12, #SSI_SRX0]
116
117                 ldr r11, [r12, #SSI_SRX0]
118                 strh r11, [r13, #4]
119
120                 ldr r11, [r12, #SSI_SRX0]
121                 strh r11, [r13, #6]
122
123                 /* dummy read to skip slot 12 */
124                 ldrne r11, [r12, #SSI_SRX0]
125
126                 add r10, #8
127                 lsr r11, r9, #16        /* r11: buffer size */
128                 cmp r10, r11
129                 lslgt r9, r11, #16
130                 addle r9, #8
131
132 1:
133                 @ return from FIQ
134                 subs    pc, lr, #4
135
136                 .align
137 .L_imx_ssi_fiq_base:
138 imx_ssi_fiq_base:
139                 .word 0x0
140 .L_imx_ssi_fiq_rx_buffer:
141 imx_ssi_fiq_rx_buffer:
142                 .word 0x0
143 .L_imx_ssi_fiq_tx_buffer:
144 imx_ssi_fiq_tx_buffer:
145                 .word 0x0
146 .L_imx_ssi_fiq_end:
147 imx_ssi_fiq_end:
148 EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer)
149 EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer)
150 EXPORT_SYMBOL(imx_ssi_fiq_start)
151 EXPORT_SYMBOL(imx_ssi_fiq_end)
152 EXPORT_SYMBOL(imx_ssi_fiq_base)