]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/sbe-2t3e3/exar7250.c
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / drivers / staging / sbe-2t3e3 / exar7250.c
1 /*
2  * SBE 2T3E3 synchronous serial card driver for Linux
3  *
4  * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License
8  * as published by the Free Software Foundation.
9  *
10  * This code is based on a driver written by SBE Inc.
11  */
12
13 #include "2t3e3.h"
14 #include "ctrl.h"
15
16 void exar7250_init(struct channel *sc)
17 {
18         exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
19                        SBE_2T3E3_FRAMER_VAL_T3_CBIT |
20                        SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET |
21                        SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK);
22
23         exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
24                        SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK |
25                        SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK |
26                        SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE |
27                        SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT);
28
29         exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT);
30 }
31
32 void exar7250_set_frame_type(struct channel *sc, u32 type)
33 {
34         u32 val;
35
36         switch (type) {
37         case SBE_2T3E3_FRAME_TYPE_E3_G751:
38         case SBE_2T3E3_FRAME_TYPE_E3_G832:
39         case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
40         case SBE_2T3E3_FRAME_TYPE_T3_M13:
41                 break;
42         default:
43                 return;
44         }
45
46         exar7250_stop_intr(sc, type);
47
48         val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE);
49         val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE |
50                  SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT |
51                  SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT);
52         switch (type) {
53         case SBE_2T3E3_FRAME_TYPE_E3_G751:
54                 val |= SBE_2T3E3_FRAMER_VAL_E3_G751;
55                 break;
56         case SBE_2T3E3_FRAME_TYPE_E3_G832:
57                 val |= SBE_2T3E3_FRAMER_VAL_E3_G832;
58                 break;
59         case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
60                 val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT;
61                 break;
62         case SBE_2T3E3_FRAME_TYPE_T3_M13:
63                 val |= SBE_2T3E3_FRAMER_VAL_T3_M13;
64                 break;
65         default:
66                 return;
67         }
68         exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val);
69         exar7250_start_intr(sc, type);
70 }
71
72
73 void exar7250_start_intr(struct channel *sc, u32 type)
74 {
75         u32 val;
76
77         switch (type) {
78         case SBE_2T3E3_FRAME_TYPE_E3_G751:
79         case SBE_2T3E3_FRAME_TYPE_E3_G832:
80                 val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
81
82                 cpld_LOS_update(sc);
83
84                 sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
85                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
86                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
87                                SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
88                                SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE);
89
90                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
91                 break;
92
93         case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
94         case SBE_2T3E3_FRAME_TYPE_T3_M13:
95                 val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
96
97                 cpld_LOS_update(sc);
98
99                 sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
100
101                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
102                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
103                                SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
104                                SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
105
106                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
107
108                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
109                 break;
110
111         default:
112                 return;
113         }
114
115         exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
116         exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
117                        SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
118                        SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE);
119 }
120
121
122 void exar7250_stop_intr(struct channel *sc, u32 type)
123 {
124         exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
125         exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
126
127         switch (type) {
128         case SBE_2T3E3_FRAME_TYPE_E3_G751:
129         case SBE_2T3E3_FRAME_TYPE_E3_G832:
130                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0);
131                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
132                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0);
133                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
134                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0);
135                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL);
136                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0);
137                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
138                 break;
139
140         case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
141         case SBE_2T3E3_FRAME_TYPE_T3_M13:
142                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0);
143                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
144                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0);
145                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
146                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
147                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
148                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0);
149                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
150                 exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0);
151                 exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
152                 break;
153         }
154 }
155
156
157
158
159 void exar7250_unipolar_onoff(struct channel *sc, u32 mode)
160 {
161         switch (mode) {
162         case SBE_2T3E3_OFF:
163                 exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
164                                    SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
165                 break;
166         case SBE_2T3E3_ON:
167                 exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
168                                  SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
169                 break;
170         }
171 }
172
173 void exar7250_set_loopback(struct channel *sc, u32 mode)
174 {
175         switch (mode) {
176         case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF:
177                 exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
178                                    SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
179                 break;
180         case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON:
181                 exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
182                                  SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
183                 break;
184         }
185 }