Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cpld.c
Go to the documentation of this file.
1 /*
2  * SBE 2T3E3 synchronous serial card driver for Linux
3  *
4  * Copyright (C) 2009-2010 Krzysztof Halasa <[email protected]>
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 <linux/delay.h>
14 #include "2t3e3.h"
15 #include "ctrl.h"
16 
17 #define bootrom_set_bit(sc, reg, bit) \
18  bootrom_write((sc), (reg), \
19  bootrom_read((sc), (reg)) | (bit))
20 
21 #define bootrom_clear_bit(sc, reg, bit) \
22  bootrom_write((sc), (reg), \
23  bootrom_read((sc), (reg)) & ~(bit))
24 
25 static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
26 {
27  unsigned long flags;
28  spin_lock_irqsave(&channel->card->bootrom_lock, flags);
29  bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
30  spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
31 }
32 
33 static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit)
34 {
35  unsigned long flags;
36  spin_lock_irqsave(&channel->card->bootrom_lock, flags);
37  bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
38  spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
39 }
40 
41 void cpld_init(struct channel *sc)
42 {
43  u32 val;
44 
45  /* PCRA */
48  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
49 
50  /* PCRB */
51  val = 0;
52  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
53 
54  /* PCRC */
55  val = 0;
56  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
57 
58  /* PBWF */
59  val = 0;
60  cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
61 
62  /* PBWL */
63  val = 0;
64  cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
65 
66  /* PLTR */
68  cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
69  udelay(1000);
70 
71  /* PLCR */
72  val = 0;
73  cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
74  udelay(1000);
75 
76  /* PPFR */
77  val = 0x55;
78  cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
79  /* TODO: this doesn't work!!! */
80 
81  /* SERIAL_CHIP_SELECT */
82  val = 0;
83  cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
84 
85  /* PICSR */
89  cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
90 
91  cpld_start_intr(sc);
92 
93  udelay(1000);
94 }
95 
96 void cpld_start_intr(struct channel *sc)
97 {
98  u32 val;
99 
100  /* PIER */
103  cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
104 }
105 
106 void cpld_stop_intr(struct channel *sc)
107 {
108  u32 val;
109 
110  /* PIER */
111  val = 0;
112  cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
113 }
114 
115 void cpld_set_frame_mode(struct channel *sc, u32 mode)
116 {
117  if (sc->p.frame_mode == mode)
118  return;
119 
120  switch (mode) {
122  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
127  break;
129  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
131  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
135  break;
137  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
141  break;
142  default:
143  return;
144  }
145 
146  sc->p.frame_mode = mode;
147 }
148 
149 /* set rate of the local clock */
150 void cpld_set_frame_type(struct channel *sc, u32 type)
151 {
152  switch (type) {
155  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
157  break;
160  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
162  break;
163  default:
164  return;
165  }
166 }
167 
168 void cpld_set_scrambler(struct channel *sc, u32 mode)
169 {
170  if (sc->p.scrambler == mode)
171  return;
172 
173  switch (mode) {
175  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
177  break;
179  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
181  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
183  break;
185  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
187  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
189  break;
190  default:
191  return;
192  }
193 
194  sc->p.scrambler = mode;
195 }
196 
197 
198 void cpld_set_crc(struct channel *sc, u32 crc)
199 {
200  if (sc->p.crc == crc)
201  return;
202 
203  switch (crc) {
204  case SBE_2T3E3_CRC_16:
205  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
207  break;
208  case SBE_2T3E3_CRC_32:
209  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
211  break;
212  default:
213  return;
214  }
215 
216  sc->p.crc = crc;
217 }
218 
219 
220 void cpld_select_panel(struct channel *sc, u32 panel)
221 {
222  if (sc->p.panel == panel)
223  return;
224  switch (panel) {
226  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
228  break;
230  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
232  break;
233  default:
234  return;
235  }
236 
237  udelay(100);
238 
239  sc->p.panel = panel;
240 }
241 
242 
243 extern void cpld_set_clock(struct channel *sc, u32 mode)
244 {
245  if (sc->p.clock_source == mode)
246  return;
247 
248  switch (mode) {
250  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
252  break;
254  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
256  break;
257  default:
258  return;
259  }
260 
261  sc->p.clock_source = mode;
262 }
263 
264 void cpld_set_pad_count(struct channel *sc, u32 count)
265 {
266  u32 val;
267 
268  if (sc->p.pad_count == count)
269  return;
270 
271  switch (count) {
274  break;
277  break;
280  break;
283  break;
284  default:
285  return;
286  }
287 
288  cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
290  cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
291  sc->p.pad_count = count;
292 }
293 
294 void cpld_LOS_update(struct channel *sc)
295 {
296  u_int8_t los;
297 
298  cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
304 
305  if (los != sc->s.LOS)
306  dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
307  los ? "Loss of signal" : "Signal OK");
308  sc->s.LOS = los;
309 }
310 
311 void cpld_set_fractional_mode(struct channel *sc, u32 mode,
312  u32 start, u32 stop)
313 {
314  if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
315  start = 0;
316  stop = 0;
317  }
318 
319  if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
320  sc->p.bandwidth_stop == stop)
321  return;
322 
323  switch (mode) {
325  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
327  break;
329  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
331  break;
333  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
335  break;
337  cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
339  break;
340  default:
341  printk(KERN_ERR "wrong mode in set_fractional_mode\n");
342  return;
343  }
344 
345  cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
346  cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
347 
348  sc->p.fractional_mode = mode;
349  sc->p.bandwidth_start = start;
350  sc->p.bandwidth_stop = stop;
351 }