source: svn/newcon3bcm2_21bu/magnum/portinginterface/irb/7552/birb.c @ 45

Last change on this file since 45 was 45, checked in by megakiss, 11 years ago
  • Property svn:executable set to *
File size: 53.0 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: birb.c $
11 * $brcm_Revision: Hydra_Software_Devel/54 $
12 * $brcm_Date: 11/21/11 6:19p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/irb/7435/birb.c $
19 *
20 * Hydra_Software_Devel/54   11/21/11 6:19p mward
21 * SW7435-7: Add 7435.
22 *
23 * Hydra_Software_Devel/53   10/11/11 1:49p jkim
24 * SW7429-9: Add 7429 support
25 *
26 * Hydra_Software_Devel/53   10/11/11 1:29p jkim
27 * SW7429-9: add 7429 support
28 *
29 * Hydra_Software_Devel/52   12/27/10 1:59p xhuang
30 * SW7358-29: Add 7358/7552 support
31 *
32 * Hydra_Software_Devel/51   12/8/10 5:55p katrep
33 * SW7231-4:add support for 7231
34 *
35 * Hydra_Software_Devel/50   12/7/10 6:14p jrubio
36 * SW7344-9: add 7344/7346 support
37 *
38 * Hydra_Software_Devel/49   11/2/10 5:00p hongtaoz
39 * SW7425-9: added 7425 support;
40 *
41 * Hydra_Software_Devel/48   10/13/10 11:53a gmohile
42 * SW7408-1 : Add 7408 IR blaster support
43 *
44 * Hydra_Software_Devel/47   10/7/10 4:44p nickh
45 * SW7422-74: Add 7422 support
46 *
47 * Hydra_Software_Devel/46   12/13/09 6:50p rpereira
48 * SW7550-41: Fixed compilation issues for 7550
49 *
50 * Hydra_Software_Devel/45   9/1/09 5:38p rpereira
51 * SW7550-30: Added 7550 support
52 *
53 * Hydra_Software_Devel/44   8/20/09 4:23p mward
54 * PR55545: Support 7125.
55 *
56 * Hydra_Software_Devel/43   8/10/09 4:26p jrubio
57 * PR55232: add 7340/7342
58 *
59 * Hydra_Software_Devel/42   3/6/09 1:23p jkim
60 * PR52509: remove global variables
61 *
62 * Hydra_Software_Devel/41   1/31/09 1:13a jrubio
63 * PR51629: add 7336 support
64 *
65 * Hydra_Software_Devel/40   1/30/09 1:34p jkim
66 * PR51617: confrom to the global naming convention and reduce the trailer
67 * pulse to 500us on xmp-2 ACK/NAK.
68 *
69 * Hydra_Software_Devel/39   12/2/08 4:11p kaushikb
70 * PR49867: Adding support for 7420
71 *
72 * Hydra_Software_Devel/38   4/4/08 11:20a farshidf
73 * PR39190: add 3548 support
74 *
75 * Hydra_Software_Devel/37   4/3/08 2:45p brianlee
76 * PR35973: Fixed a potential memory resource leak problem in birb_open()
77 * function.
78 *
79 * Hydra_Software_Devel/36   3/27/08 1:10p jkim
80 * PR38349: Add trailer pulse for ack/nack
81 *
82 * Hydra_Software_Devel/35   2/27/08 10:18a jrubio
83 * PR39363: fix compile warnings
84 *
85 * Hydra_Software_Devel/34   2/26/08 10:42a katrep
86 * PR29073: Fixed compiler warnings
87 *
88 * Hydra_Software_Devel/33   2/20/08 1:58p jkim
89 * PR37963: Add XMP-2 support
90 *
91 * Hydra_Software_Devel/32   11/27/07 6:11p farshidf
92 * PR36888: add support for 7335
93 *
94 * Hydra_Software_Devel/31   11/27/07 6:09p farshidf
95 * PR36888: Add 7335 support
96 *
97 * Hydra_Software_Devel/30   10/14/07 3:53p jkim
98 * PR14344: add 7325 support
99 *
100 * Hydra_Software_Devel/29   3/26/07 5:13p katrep
101 * PR29073: Added support for 7405
102 *
103 * Hydra_Software_Devel/28   2/2/07 11:22a jkim
104 * PR27238: Modify to use the correct IRQ definition
105 *
106 * Hydra_Software_Devel/27   1/12/07 4:21p jkim
107 * PR14344: Add 3563 support
108 *
109 * Hydra_Software_Devel/26   12/1/06 4:14p jkim
110 * PR14344: fixed incidental error of using 7401 instead 7403
111 *
112 * Hydra_Software_Devel/25   11/30/06 1:49p jkim
113 * PR14344: Add 3563 support
114 *
115 * Hydra_Software_Devel/24   11/9/06 11:07a jkim
116 * PR14344: added 7403 support
117 *
118 * Hydra_Software_Devel/23   6/15/06 5:13p mward
119 * PR21680: Add support for 7118 chip 97118 board
120 *
121 * Hydra_Software_Devel/22   3/21/06 3:03p jkim
122 * PR20326: Add support for 7438
123 *
124 * Hydra_Software_Devel/21   1/14/06 11:21p agin
125 * PR19076: Support BCM7400.
126 *
127 * Hydra_Software_Devel/20   8/23/05 5:07p jkim
128 * PR14344: Adding 7401 support
129 *
130 * Hydra_Software_Devel/19   4/7/05 10:56a agin
131 * PR14698: unused parameters.
132 *
133 * Hydra_Software_Devel/18   3/10/05 9:39a dlwin
134 * PR 14240: Updated to use marco instead of explicit bit set.
135 *
136 * Hydra_Software_Devel/17   3/10/05 8:51a dlwin
137 * PR 14240: Added support for 3560.
138 *
139 * Hydra_Software_Devel/16   10/7/04 6:35p brianlee
140 * PR11333: Modified multiple sequence blast functions to accommodate
141 * another case.
142 *
143 * Hydra_Software_Devel/15   9/22/04 5:59p brianlee
144 * PR11333: Fixed various multiple sequence sending functions.
145 *
146 * Hydra_Software_Devel/14   7/23/04 4:04p brianlee
147 * PR11333: Added another type of multiple blast sequences.
148 *
149 * Hydra_Software_Devel/13   6/14/04 4:04p brianlee
150 * PR11386: Fixed test configuration.  Last 4 entries of duration should
151 * be doubled because we're going to divide it when writing it to the
152 * registers.
153 *
154 * Hydra_Software_Devel/12   6/7/04 4:13p brianlee
155 * PR11386: Make configregisters function public so it can be called by
156 * test routines.
157 *
158 * Hydra_Software_Devel/11   6/3/04 11:17a brianlee
159 * PR11333: Added support for sending multiple blast sequences.
160 *
161 * Hydra_Software_Devel/10   3/26/04 4:32p brianlee
162 * PR8971: Remove BDBG_ASSERT() for malloc failure.
163 *
164 * Hydra_Software_Devel/9   3/4/04 5:34p brianlee
165 * PR9958: Added BIRB_Device_eCustom type and the function
166 * BIRB_ConfigCustom() to allow user to configure custom IR blaster
167 * setting.
168 *
169 * Hydra_Software_Devel/8   12/29/03 3:59p marcusk
170 * PR9117: Updated with changes required to support interrupt ids rather
171 * than strings.
172 *
173 * Hydra_Software_Devel/7   11/4/03 6:51p brianlee
174 * Get rid of enter/leave macros.
175 *
176 * Hydra_Software_Devel/6   10/27/03 10:53a brianlee
177 * Fixed long sequence blast mode.
178 *
179 * Hydra_Software_Devel/5   10/17/03 5:29p brianlee
180 * 1.) Fixed writing sequence registers.
181 * 2.) In order to use new interrupt, must make sure the irqinh bit is set
182 * in blast_control register.  By default, it is 0, which means the old
183 * mode is enabled.
184 *
185 * Hydra_Software_Devel/4   10/3/03 9:53a brianlee
186 * Added test configuration.
187 *
188 * Hydra_Software_Devel/3   9/24/03 11:58a brianlee
189 * Changed the names of header files.
190 *
191 * Hydra_Software_Devel/2   9/19/03 1:42p brianlee
192 * Fixed warnings from Midas build.
193 *
194 * Hydra_Software_Devel/1   9/18/03 4:13p brianlee
195 * Initial version.
196 *
197 *
198 ***************************************************************************/
199#include "bstd.h"
200#include "birb.h"
201#include "birb_priv.h"
202#include "bchp_irb.h"
203#include "bchp_irq0.h"
204#include "bchp_int_id_irq0.h"
205
206BDBG_MODULE(birb);
207
208#define DEV_MAGIC_ID            ((BERR_IRB_ID<<16) | 0xFACE)
209
210#define BIRB_CHK_RETCODE( rc, func )        \
211do {                                        \
212    if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
213    {                                       \
214        goto done;                          \
215    }                                       \
216} while(0)
217
218#define MAX_IRB_SEQUENCES           159     /* leave room for 1 start bit */
219#define IRB_PAGE_SIZE               40
220#define NUMSEQ_GREATER_THAN_80_BIT  0x80
221
222#if (BCHP_CHIP==3563)  || (BCHP_CHIP==3548) || (BCHP_CHIP==3556)
223#ifndef BCHP_INT_ID_irb_irqen
224#define BCHP_INT_ID_irb_irqen           BCHP_INT_ID_irb
225#endif
226#endif
227/*******************************************************************************
228*
229*   Private Data
230*
231*******************************************************************************/
232static const SIrbConfiguration SonyConfiguration =
233{
234    "sony",                     /* name; */
235    MASTER_DIVISOR,             /* masterDivisor */
236    CARRIER_CLOCK_DIVISOR,      /* carrierClockDivisor */
237    INDEX_CLOCK_DIVISOR,        /* indexClockDivisor */
238    0,                          /* noCarrier */
239    12/CARRIER_PERIOD,          /* carrierHighCount */
240    13/CARRIER_PERIOD,          /* carrierLowCount */
241    21,                         /* numberSequences */
242    {0,2},                      /* logic0IndexPair */
243    {1,2},                      /* logic1IndexPair */
244    {                           /* sequenceIndex[] */
245        {3,2},                  /* start bit */
246        {1,2}, {0,2}, {1,2}, {0,2}, /* data bit 0..3 = 5 */
247        {1,2}, {0,2}, {0,2}, {0,2}, /* data bit 4..7 = 1 */
248        {1,2}, {0,2}, {1,2}, {1,2}, /* data bit 8..11 = d */
249        {1,2}, {0,2}, {0,2}, {1,2}, /* data bit 12..15 = 9*/
250        {0,2}, {0,2}, {1,2}, {0,2}  /* data bit 16..19 = 4*/
251    },
252    {                           /* duration[]; */
253        600/INDEX_PERIOD,       /* 0.6ms, '0' ON */
254        1200/INDEX_PERIOD,      /* 1.2ms, '1' ON */
255        600/INDEX_PERIOD,       /* 0.6ms,  '0', '1', OFF */
256        2400/INDEX_PERIOD,      /* 2.4ms,  start bit ON */
257        600/INDEX_PERIOD        /* last sequence OFF duration */
258                                /* 0.6ms + filler to make 45ms frame duration */
259                                /* automatically calculated when sending */
260    },
261    (FRAME_PERIOD/INDEX_PERIOD),/* frame period A */
262    0,                          /* frame period B */
263    4,                          /* lastSequenceOffIndex */
264    3,                          /* repeatCount */
265    0,                           /* repeatStartIndex, repeat whole sequence */
266    0                           /* altModCnt */
267};
268
269/* Configuration for test64-Bit IR Code */
270static const SIrbConfiguration Test64bitConfiguration =
271{
272    "test64bit",                /* name; */
273    MASTER_DIVISOR,             /* masterDivisor */
274    CARRIER_CLOCK_DIVISOR,      /* carrierClockDivisor */
275    INDEX_CLOCK_DIVISOR,        /* indexClockDivisor */
276    0,                          /* noCarrier */
277    12/CARRIER_PERIOD,          /* carrierHighCount */
278    13/CARRIER_PERIOD,          /* carrierLowCount */
279    21,                         /* numberSequences */
280    {0,2},                      /* logic0IndexPair */
281    {1,2},                      /* logic1IndexPair */
282    {                           /* sequenceIndex[] */
283        {3,2},                  /* start bit */
284        {0,1}, {2,3}, {4,5}, {6,7}, /* data bit 0..3 = 5 */
285        {8,9}, {10,11}, {12,13}, {0,2}, /* data bit 4..7 = 1 */
286        {0,1}, {2,3}, {4,5}, {6,7}, /* data bit 0..3 = 5 */
287        {8,9}, {10,11}, {12,13}, {0,2}, /* data bit 4..7 = 1 */
288        {0,1}, {2,3}, {4,5}, {6,7}, /* data bit 0..3 = 5 */
289        {8,9}, {10,11}, {12,13}, {0,2}  /* data bit 4..7 = 1 */
290    },
291    {                           /* duration[]; */
292        600/INDEX_PERIOD,       /* 0.6ms, '0' ON */
293        1200/INDEX_PERIOD,      /* 1.2ms, '1' ON */
294        600/INDEX_PERIOD,       /* 0.6ms,  '0', '1', OFF */
295        2400/INDEX_PERIOD,      /* 2.4ms,  start bit ON */
296        600/INDEX_PERIOD,       /* last sequence OFF duration */
297                                /* 0.6ms + filler to make 45ms frame duration */
298                                /* automatically calculated when sending */
299        3600/INDEX_PERIOD,      /* 3.4ms */
300
301        1200/INDEX_PERIOD,      /* 1.2ms */
302        1200/INDEX_PERIOD,      /* 1.2ms */
303        1200/INDEX_PERIOD,      /* 1.2ms */
304        2400/INDEX_PERIOD,      /* 2.4ms */
305
306        600/INDEX_PERIOD,       /* 0.6ms (double value) */
307        1200/INDEX_PERIOD,      /* 1.2ms (double value) */
308        1800/INDEX_PERIOD,      /* 1.8ms (double value) */
309        2400/INDEX_PERIOD       /* 2.4ms (double value) */
310    },
311    (FRAME_PERIOD_64_BIT/INDEX_PERIOD),/* frame period A */
312    0,                          /* frame period B */
313    4,                          /* lastSequenceOffIndex */
314    0,                          /* repeatCount */
315    0,                           /* repeatStartIndex, repeat whole sequence */
316    0                           /* altModCnt */
317};
318
319/* Configuration for GI Remote A IR Code */
320static const SIrbConfiguration GIConfiguration =
321{
322    "GI",                       /* name; */
323    MASTER_DIVISOR,             /* masterDivisor */
324    CARRIER_CLOCK_DIVISOR,      /* carrierClockDivisor */
325    INDEX_CLOCK_DIVISOR,        /* indexClockDivisor */
326    0,                          /* noCarrier */
327    12/CARRIER_PERIOD,          /* carrierHighCount */
328    13/CARRIER_PERIOD,          /* carrierLowCount */
329    17,                         /* numberSequences */
330    {2,0},                      /* logic0IndexPair */
331    {2,1},                      /* logic1IndexPair */
332    {                           /* sequenceIndex[] */
333        {3,1},                  /* start bit */
334        {1,2}, {0,2}, {1,2}, {0,2}, /* data bit 0..3 = 5 */
335        {1,2}, {0,2}, {0,2}, {0,2}, /* data bit 4..7 = 1 */
336        {1,2}, {0,2}, {1,2}, {1,2}, /* data bit 8..11 = d */
337        {1,2}, {0,2}, {0,2}, {1,2}, /* data bit 12..15 = 9*/
338        {0,2}, {0,2}, {1,2}, {0,2}  /* data bit 16..19 = 4*/
339    },
340    {                           /* duration[]; */
341        2250/INDEX_PERIOD,      /* 2.25ms, '0' OFF */
342        4500/INDEX_PERIOD,      /* 4.50ms, '1' OFF */
343        500/INDEX_PERIOD,       /* 0.50ms,  '0', '1', ON */
344        9000/INDEX_PERIOD,      /* 9.00ms,  start bit, preamble */
345        600/INDEX_PERIOD        /* last sequence OFF duration */
346                                /* 0.6ms + filler to make 45ms frame duration */
347                                /* automatically calculated when sending */
348    },
349    (FRAME_PERIOD/INDEX_PERIOD),/* frame period A */
350    0,                          /* frame period B */
351    4,                          /* lastSequenceOffIndex */
352    0,                          /* repeatCount */
353    0,                           /* repeatStartIndex, repeat whole sequence */
354    0                           /* altModCnt */
355};
356
357/* Configuration for Pioneer */
358static const SIrbConfiguration PioneerConfiguration =
359{
360    "pioneer",                  /* name; */
361    MASTER_DIVISOR,             /* masterDivisor */
362    CARRIER_CLOCK_DIVISOR,      /* carrierClockDivisor */
363    INDEX_CLOCK_DIVISOR,        /* indexClockDivisor */
364    1,                          /* noCarrier */
365    12/CARRIER_PERIOD,          /* carrierHighCount */
366    13/CARRIER_PERIOD,          /* carrierLowCount */
367    17,                         /* numberSequences */
368    {2,0},                      /* logic0IndexPair */
369    {2,1},                      /* logic1IndexPair */
370    {                           /* sequenceIndex[] */
371        {3,4},                  /* start bit */
372        {1,2}, {0,2}, {1,2}, {0,2}, /* data bit 0..3 = 5 */
373        {1,2}, {0,2}, {0,2}, {0,2}, /* data bit 4..7 = 1 */
374        {1,2}, {0,2}, {1,2}, {1,2}, /* data bit 8..11 = d */
375        {1,2}, {0,2}, {0,2}, {1,2}, /* data bit 12..15 = 9*/
376        {0,2}, {0,2}, {1,2}, {0,2}  /* data bit 16..19 = 4*/
377    },
378    {                           /* duration[]; */
379        /* case 1, no B data bits */
380        562/INDEX_PERIOD,       /* 0.562ms, '0' OFF */
381        1687/INDEX_PERIOD,      /* 1.687ms, '1' OFF */
382        562/INDEX_PERIOD,       /* 0.562ms,  '0', '1', ON */
383        9000/INDEX_PERIOD,      /* 9.00ms,  start bit A and B, preamble */
384        4500/INDEX_PERIOD,      /* 4.50ms,  start bit A off */
385        2250/INDEX_PERIOD,      /* 2.25ms,  start bit B off */
386        562/INDEX_PERIOD,       /* last sequence ON duration */
387        562/INDEX_PERIOD,       /* last sequence OFF duration for A */
388                                /* 0.6ms + filler to make 45ms frame duration */
389                                /* automatically calculated when sending */
390
391        /* case 2, B data bits */
392        527/INDEX_PERIOD,       /* 0.527ms, '0' OFF */
393        1583/INDEX_PERIOD,      /* 1.583ms, '1' OFF */
394        528/INDEX_PERIOD,   /* 0.528ms,  '0', '1', ON */
395        8440/INDEX_PERIOD,      /* 8.44ms,  start bit A and B, preamble */
396        4220/INDEX_PERIOD,      /* 4.22ms,  start bit A off, start bit B off */
397        562/INDEX_PERIOD        /* last sequence OFF duration for B */
398
399    },
400    (FRAME_PERIOD_PIONEER_ABBB_1/INDEX_PERIOD),     /* frame period A */
401    (FRAME_PERIOD_PIONEER_ABBB_1/INDEX_PERIOD),     /* frame period B */
402    CASE2_DURATION_INDEX - 1,   /* lastSequenceOffIndex */
403    0,                          /* repeatCount */
404    0,                           /* repeatStartIndex, repeat whole sequence */
405    0                           /* altModCnt */
406};
407
408/* Configuration for Pioneer AAAA */
409static const SIrbConfiguration PioneerAAAAConfiguration =
410{
411    "pioneerAAAA",              /* name; */
412    MASTER_DIVISOR,             /* masterDivisor */
413    CARRIER_CLOCK_DIVISOR,      /* carrierClockDivisor */
414    INDEX_CLOCK_DIVISOR,        /* indexClockDivisor */
415    1,                          /* noCarrier */
416    12/CARRIER_PERIOD,          /* carrierHighCount */
417    13/CARRIER_PERIOD,          /* carrierLowCount */
418    17,                         /* numberSequences */
419    {2,0},                      /* logic0IndexPair */
420    {2,1},                      /* logic1IndexPair */
421    {                           /* sequenceIndex[] */
422        {3,4},                  /* start bit */
423        {1,2}, {0,2}, {1,2}, {0,2}, /* data bit 0..3 = 5 */
424        {1,2}, {0,2}, {0,2}, {0,2}, /* data bit 4..7 = 1 */
425        {1,2}, {0,2}, {1,2}, {1,2}, /* data bit 8..11 = d */
426        {1,2}, {0,2}, {0,2}, {1,2}, /* data bit 12..15 = 9*/
427        {0,2}, {0,2}, {1,2}, {0,2}  /* data bit 16..19 = 4*/
428    },
429    {                           /* duration[]; */
430        /* case 4, no end pulse, fixed frame time */
431        870/INDEX_PERIOD,       /* 0.870ms, '0' OFF, ON */
432        900/INDEX_PERIOD,       /* 0.900ms, '1' OFF, ON */
433
434        /* case 5, end pulse, variable frame time */
435        305/INDEX_PERIOD,       /* 0.305ms,  '0', OFF, ON, '1' ON */
436        2137/INDEX_PERIOD,      /* 2.137ms,  '1', OFF */
437        0,                      /* case 4 last sequence OFF duration */
438        305/INDEX_PERIOD,       /* 0.305ms, end pulse */
439        26000/INDEX_PERIOD      /* case 5 last sequence OFF duration, pause time */
440    },
441    (FRAME_PERIOD_PIONEER_AAAA_4/INDEX_PERIOD),     /* frame period A */
442    (FRAME_PERIOD_PIONEER_AAAA_4/INDEX_PERIOD),     /* frame period B */
443    0,                          /* lastSequenceOffIndex */
444    0,                          /* repeatCount */
445    0,                           /* repeatStartIndex, repeat whole sequence */
446    0                           /* altModCnt */
447};
448
449#if 0
450/* this is moved inside handle */
451static SIrbConfiguration CustomConfiguration;
452#endif
453
454/* Configuration for XMP-2 Station with 38KHz carrier */
455static const SIrbConfiguration Xmp2StationConfiuration = {
456    "xmp2_station_38k",         /* name; */
457    1,                          /* masterDivisor */
458    2,                          /* carrierClockDivisor */
459    1,                          /* indexClockDivisor */
460    0,                          /* noCarrier */
461    118,                        /* carrierHighCount */
462    237,                        /* carrierLowCount */
463    17,                         /* numberSequences */
464    {0,0},                      /* not used, logic0IndexPair */
465    {0,0},                      /* not used, logic1IndexPair */
466    {   /* sequenceIndex[] */
467        {DATA_PULSE,DATA4}, {ZERO,DELTA1}, /* 1st nibble = 5 */
468        {DATA_PULSE,DATA2}, {ZERO,ZERO},   /* 2nd nibble = 2 */
469        {DATA_PULSE,DATA4}, {ZERO,DELTA1}, /* 1st nibble = 5 */
470        {DATA_PULSE,DATA2}, {ZERO,ZERO},   /* 2nd nibble = 2 */
471        {DATA_PULSE,DATA4}, {ZERO,DELTA1}, /* 1st nibble = 5 */
472        {DATA_PULSE,DATA2}, {ZERO,ZERO},   /* 2nd nibble = 2 */
473        {DATA_PULSE,DATA4}, {ZERO,DELTA1}, /* 1st nibble = 5 */
474        {DATA_PULSE,DATA2}, {ZERO,ZERO},   /* 2nd nibble = 2 */
475        {DATA_PULSE,ZERO}               /* trailer pulse */
476    },
477    {                           /* duration[] */
478        3690,                   /* 0: deltaT-1 */
479        3691,                   /* 1: deltaT, 136,71us*/
480        3692,                   /* 2: deltaT+1*/
481        20509,                  /* 3: D(0), low period for data 0 */
482        27892,                  /* 4: D(2), low period for data 2 */
483        35274,                  /* 5: D(4), low period for data 4 */
484        42656,                  /* 6: D(6), low period for data 6 */
485        50039,                  /* 7: D(8), low period for data 8 */
486        57421,                  /* 8: D(10), low period for data 10 */
487        64803,                  /* 9: D(12), low period for data 12 */
488                                /* the remain 4 are double-time values */
489        72186,              /* 10: D(14), low period for data 14 */
490        5680,                   /* 11: D(DataPulse), high period of data symbol */
491        13500,              /* 500us. */ /* 22720,(840us) */              /* 12: D(TrailerPulse), high period of Trailer pulse */
492        0                   /* 13: Zero */
493    },
494    0,                          /* not used, frame period A*/
495    0,                          /* not used, frame period B*/
496    0,                          /* not used, lastSequenceOffIndex */
497    0,                          /* repeatCount */
498    0,                          /* repeatStartIndex, repeat whole sequence */
499    1                           /* altModCnt */
500};
501
502/*******************************************************************************
503*
504*   Private Module Handles
505*
506*******************************************************************************/
507
508typedef struct BIRB_P_Handle
509{
510    uint32_t            magicId;                    /* Used to check if structure is corrupt */
511    BCHP_Handle         hChip;
512    BREG_Handle         hRegister;
513    BINT_Handle         hInterrupt;
514    BKNI_EventHandle    hEvent;
515    BINT_CallbackHandle hCallback;
516    SIrbConfiguration   *pConfig;
517    SIrbConfiguration   CustomConfiguration;
518
519    bool                longSequenceReloadPage0;
520    bool                longSequenceReloadPage1;
521    bool                intMode;
522} BIRB_P_Handle;
523
524/*******************************************************************************
525*
526*   Default Module Settings
527*
528*******************************************************************************/
529static const BIRB_Settings defIrbSettings =
530{
531    BIRB_Device_eSony,          /* IRB device */
532    true                        /* intMode */
533};
534
535/*******************************************************************************
536*
537*   Public Module Functions
538*
539*******************************************************************************/
540BERR_Code BIRB_Open(
541    BIRB_Handle *pIrb,                  /* [output] Returns handle */
542    BCHP_Handle hChip,                  /* Chip handle */
543    BREG_Handle hRegister,              /* Register handle */
544    BINT_Handle hInterrupt,             /* Interrupt handle */
545    const BIRB_Settings *pDefSettings   /* Default settings */
546    )
547{
548    BERR_Code       retCode = BERR_SUCCESS;
549    BIRB_Handle     hDev;
550    uint32_t        lval;
551
552
553    /* Sanity check on the handles we've been given. */
554    BDBG_ASSERT( hChip );
555    BDBG_ASSERT( hRegister );
556    BDBG_ASSERT( hInterrupt );
557
558    /* Alloc memory from the system heap */
559    hDev = (BIRB_Handle) BKNI_Malloc( sizeof( BIRB_P_Handle ) );
560    if( hDev == NULL )
561    {
562        *pIrb = NULL;
563        retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
564        BDBG_ERR(("BIRB_Open: BKNI_malloc() failed\n"));
565        goto done;
566    }
567
568    hDev->magicId   = DEV_MAGIC_ID;
569    hDev->hChip     = hChip;
570    hDev->hRegister = hRegister;
571    hDev->hInterrupt = hInterrupt;
572
573    BIRB_CHK_RETCODE( retCode, BKNI_CreateEvent( &(hDev->hEvent) ) );
574
575    BIRB_Reset (hDev);
576
577    hDev->intMode   = pDefSettings->intMode;
578    if (pDefSettings->intMode)
579    {
580#if (BCHP_CHIP==7038) || (BCHP_CHIP==7438)
581        BIRB_CHK_RETCODE( retCode, BINT_CreateCallback(
582            &(hDev->hCallback), hDev->hInterrupt, BCHP_INT_ID_irb_irqen,
583            BIRB_P_HandleInterrupt_Isr, (void *) hDev, 0x00 ) );
584#elif (BCHP_CHIP==7400) || (BCHP_CHIP==7420) || (BCHP_CHIP==7401) || (BCHP_CHIP==7403) || (BCHP_CHIP==7118) || (BCHP_CHIP==3563) || \
585      (BCHP_CHIP==7405) || (BCHP_CHIP==7325) || (BCHP_CHIP==7335) || (BCHP_CHIP==7340) || (BCHP_CHIP==7342) || (BCHP_CHIP==3548) || \
586      (BCHP_CHIP==3556) || (BCHP_CHIP==7125) || (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7408) || (BCHP_CHIP==7344) || \
587          (BCHP_CHIP==7346) || (BCHP_CHIP==7231) || (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || (BCHP_CHIP==7429) || (BCHP_CHIP==7435) 
588        BIRB_CHK_RETCODE( retCode, BINT_CreateCallback(
589            &(hDev->hCallback), hDev->hInterrupt, BCHP_INT_ID_irb_irqen,
590            BIRB_P_HandleInterrupt_Isr, (void *) hDev, 0x00 ) );
591#elif (BCHP_CHIP==3560) || (BCHP_CHIP==3563)  || (BCHP_CHIP==3548) || (BCHP_CHIP==3556) || (BCHP_CHIP==7550)
592        BIRB_CHK_RETCODE( retCode, BINT_CreateCallback(
593            &(hDev->hCallback), hDev->hInterrupt, BCHP_INT_ID_irb,
594            BIRB_P_HandleInterrupt_Isr, (void *) hDev, 0x00 ) );
595#else
596#error BCHP_CHIP set to unsupported chip.
597#endif
598        BIRB_CHK_RETCODE( retCode, BINT_EnableCallback( hDev->hCallback ) );
599
600        BKNI_EnterCriticalSection();
601
602        /*
603         * Enable IRB interrupt in UPG
604         */
605        lval = BREG_Read32(hDev->hRegister, BCHP_IRQ0_IRQEN);
606#if (BCHP_CHIP==7038) || (BCHP_CHIP==7438)
607        lval |= BCHP_FIELD_DATA(IRQ0_IRQEN, irb_irqen, 1);
608#elif (BCHP_CHIP==3560) || (BCHP_CHIP==3563)  || (BCHP_CHIP==3548) || (BCHP_CHIP==3556) || (BCHP_CHIP==7550)
609        lval |= BCHP_FIELD_DATA(IRQ0_IRQEN, irb, 1);
610#elif (BCHP_CHIP==7400) || (BCHP_CHIP==7420) || (BCHP_CHIP==7401) || (BCHP_CHIP==7403) || (BCHP_CHIP==7118) || (BCHP_CHIP==7405) || \
611      (BCHP_CHIP==7325) || (BCHP_CHIP==7325) || (BCHP_CHIP==7335) || (BCHP_CHIP==7340) || (BCHP_CHIP==7342) || (BCHP_CHIP==7125) || \
612      (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7408) || (BCHP_CHIP==7344) || (BCHP_CHIP==7346) || (BCHP_CHIP==7231) || \
613      (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || (BCHP_CHIP==7429) || (BCHP_CHIP==7435)
614        lval |= BCHP_FIELD_DATA(IRQ0_IRQEN, irb_irqen, 1);
615#else
616#error BCHP_CHIP set to unsupported chip.
617#endif
618        BREG_Write32( hDev->hRegister, BCHP_IRQ0_IRQEN, lval );
619
620        /*
621         * Enable IRB interrupt in IRB
622         */
623        BIRB_P_EnableInt (hDev);
624        BKNI_LeaveCriticalSection();
625    }
626    else
627        BIRB_P_DisableInt (hDev);
628
629    BIRB_Config (hDev, pDefSettings->irbDev);
630
631    *pIrb = hDev;
632
633done:
634    if ((retCode != BERR_SUCCESS) && hDev)
635    {
636        BKNI_Free( (void *) hDev );
637        *pIrb = NULL;
638    }
639    return( retCode );
640}
641
642BERR_Code BIRB_Close(
643    BIRB_Handle hDev                    /* Device handle */
644    )
645{
646    BERR_Code retCode = BERR_SUCCESS;
647
648
649    BDBG_ASSERT( hDev );
650    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
651
652    BKNI_EnterCriticalSection();
653    BIRB_P_DisableInt (hDev);
654    BKNI_LeaveCriticalSection();
655
656    BIRB_CHK_RETCODE( retCode, BINT_DisableCallback( hDev->hCallback ) );
657    BIRB_CHK_RETCODE( retCode, BINT_DestroyCallback( hDev->hCallback ) );
658    BKNI_DestroyEvent( hDev->hEvent );
659
660    BKNI_Free( (void *) hDev );
661
662done:
663    return( retCode );
664}
665
666BERR_Code BIRB_GetDefaultSettings(
667    BIRB_Settings *pDefSettings,        /* [output] Returns default setting */
668    BCHP_Handle hChip                   /* Chip handle */
669    )
670{
671    BERR_Code retCode = BERR_SUCCESS;
672    BSTD_UNUSED(hChip);
673
674    *pDefSettings = defIrbSettings;
675
676    return( retCode );
677}
678
679BERR_Code BIRB_GetEventHandle(
680    BIRB_Handle     hDev,               /* Device handle */
681    BKNI_EventHandle *phEvent           /* [output] Returns event handle */
682    )
683{
684    BERR_Code retCode = BERR_SUCCESS;
685
686
687    BDBG_ASSERT( hDev );
688    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
689
690    *phEvent = hDev->hEvent;
691
692    return( retCode );
693}
694
695void BIRB_ConfigCustom (
696    BIRB_Handle         hDev,           /* Device handle */
697    SIrbConfiguration   *pConfig        /* Pointer to custom config */
698)
699{
700    BSTD_UNUSED(hDev);
701    BKNI_Memcpy ((void *)&(hDev->CustomConfiguration), (void *)pConfig, sizeof(SIrbConfiguration));
702}
703
704
705BERR_Code BIRB_Config (
706    BIRB_Handle         hDev,           /* Device handle */
707    BIRB_Device         irbDev          /* IR device type */
708    )
709{
710    BERR_Code retCode = BERR_SUCCESS;
711
712    BDBG_ASSERT( hDev );
713    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
714
715    switch (irbDev)
716    {
717        case BIRB_Device_eSony:
718            hDev->pConfig = (SIrbConfiguration *)&SonyConfiguration;
719            break;
720        case BIRB_Device_eGI:
721            hDev->pConfig = (SIrbConfiguration *)&GIConfiguration;
722            break;
723        case BIRB_Device_eCustom:
724            hDev->pConfig = &(hDev->CustomConfiguration);
725            break;
726        case BIRB_Device_eTest:
727            hDev->pConfig = (SIrbConfiguration *)&Test64bitConfiguration;
728            break;
729        case BIRB_Device_ePioneer:
730            hDev->pConfig = (SIrbConfiguration *)&PioneerConfiguration;
731            break;
732        case BIRB_Device_ePioneerAAAA:
733            hDev->pConfig = (SIrbConfiguration *)&PioneerAAAAConfiguration;
734            break;
735        case BIRB_Device_eXmp2:
736            hDev->pConfig = (SIrbConfiguration *)&Xmp2StationConfiuration;
737            break;
738        default:
739            retCode = BERR_INVALID_PARAMETER;
740    }
741
742    return( retCode );
743}
744
745void BIRB_Reset(
746    BIRB_Handle     hDev
747)
748{
749    uint32_t    lval;
750
751
752    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
753    lval |= BCHP_IRB_BLAST_CONTROL_blastRST_MASK;           /* assert reset */
754    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
755    lval &= ~BCHP_IRB_BLAST_CONTROL_blastRST_MASK;          /* de-assert reset */
756    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
757
758}
759
760BERR_Code BIRB_Blast (
761    BIRB_Handle         hDev            /* Device handle */
762)
763{
764    BERR_Code   retCode = BERR_SUCCESS;
765    uint32_t    lval;
766
767    BDBG_ASSERT( hDev );
768    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
769
770    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
771    lval |= BCHP_IRB_BLAST_CONTROL_blast_MASK;          /* assert reset */
772    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
773
774    return( retCode );
775}
776
777bool BIRB_IsIrbFinished(
778    BIRB_Handle     hDev
779)
780{
781    uint32_t    lval;
782
783
784    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
785
786    return (lval & BCHP_IRB_BLAST_CONTROL_blast_MASK) ? false : true;
787}
788
789BERR_Code BIRB_Send (
790    BIRB_Handle         hDev,           /* Device handle */
791    uint32_t            *pData,         /* pointer to data to blast */
792    uint8_t             bits            /* number of bits to blast */
793)
794{
795    BERR_Code retCode = BERR_SUCCESS;
796
797    BDBG_ASSERT( hDev );
798    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
799
800    if (bits > MAX_IRB_SEQUENCES)
801    {
802        retCode = BIRB_ERR_TOO_MANY_SEQ;
803        goto done;
804    }
805
806    BIRB_Reset (hDev);
807
808    BIRB_P_ConfigDataSequence (hDev, pData, bits, true);
809
810    BIRB_ConfigRegisters (hDev);
811
812    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
813
814done:
815    return( retCode );
816}
817
818BERR_Code BIRB_SendWithHeaderOption (
819    BIRB_Handle         hDev,           /* Device handle */
820    uint32_t            *pData,         /* pointer to data to blast */
821    uint8_t             bits,           /* number of bits to blast */
822    bool                headerPulse     /* header flag */
823)
824{
825    BERR_Code retCode = BERR_SUCCESS;
826
827    BDBG_ASSERT( hDev );
828    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
829
830    if (bits > MAX_IRB_SEQUENCES)
831    {
832        retCode = BIRB_ERR_TOO_MANY_SEQ;
833        goto done;
834    }
835
836    BIRB_Reset(hDev);
837
838    BIRB_P_ConfigDataSequence(hDev, pData, bits, headerPulse);
839
840    BIRB_ConfigRegisters(hDev);
841
842    BIRB_CHK_RETCODE(retCode, BIRB_Blast(hDev));
843
844done:
845    return( retCode );
846}
847
848BERR_Code BIRB_SendABBB (
849    BIRB_Handle         hDev,           /* Device handle */
850    uint32_t            *pDataA,        /* pointer to data A to blast */
851    uint8_t             bitsA,          /* number of bits in A to blast */
852    uint32_t            *pDataB,        /* pointer to data B to blast */
853    uint8_t             bitsB,          /* number of bits in B to blast */
854    bool                headerA,        /* headerA flag */
855    bool                headerB,        /* headerB flag */
856    bool                fixedFlag       /* true: frame length fixed */
857)
858{
859    BERR_Code retCode = BERR_SUCCESS;
860
861    BDBG_ASSERT( hDev );
862    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
863
864    if ((bitsA + bitsB) > MAX_IRB_SEQUENCES)
865    {
866        retCode = BIRB_ERR_TOO_MANY_SEQ;
867        goto done;
868    }
869
870    BIRB_Reset (hDev);
871
872    BIRB_P_ConfigDataSequenceAB(hDev, pDataA, bitsA, pDataB, bitsB, headerA, headerB, fixedFlag);
873
874    BIRB_ConfigRegisters (hDev);
875
876    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
877
878done:
879    return( retCode );
880}
881
882BERR_Code BIRB_SendAAAA (
883    BIRB_Handle         hDev,           /* Device handle */
884    uint32_t            *pDataA,        /* pointer to data A to blast */
885    uint8_t             bitsA,          /* number of bits in A to blast */
886    bool                headerPulse,    /* header flag */
887    bool                fixedFlag       /* true: frame length fixed */
888)
889{
890    BERR_Code retCode = BERR_SUCCESS;
891
892    BDBG_ASSERT( hDev );
893    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
894
895    if (bitsA > MAX_IRB_SEQUENCES)
896    {
897        retCode = BIRB_ERR_TOO_MANY_SEQ;
898        goto done;
899    }
900
901    BIRB_Reset (hDev);
902
903    BIRB_P_ConfigDataSequenceAA(hDev, pDataA, bitsA, headerPulse, fixedFlag);
904
905    BIRB_ConfigRegisters (hDev);
906
907    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
908
909done:
910    return( retCode );
911}
912
913
914BERR_Code BIRB_SendXmp2Ack (
915    BIRB_Handle         hDev           /* Device handle */
916)
917{
918    uint8_t     ackData;
919    BERR_Code retCode = BERR_SUCCESS;
920
921    BDBG_ASSERT( hDev );
922    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
923
924    /* build ack data
925     * For now, owener code is 0.
926     * Data structure is based on page 8 of Packet Layer Spec version 1.3,
927     * which is slightly different from page 18 of XMP-2 Remore Demo v1.2.doc
928     * ------------------------
929     * |C1|C0|0|ACK|N3|N2|N1|N0|
930     * ------------------------
931     * C1-C0 10 = dual device mode
932     * ACK = 1 NAK= 0
933     * N3-N0 0000 = accepting all peripherals.
934     */
935    ackData = 0x90;
936
937    BIRB_Reset (hDev);
938
939    BIRB_P_ConfigDataSequenceXmp2(hDev, &ackData, 1);
940
941    BIRB_ConfigRegisters (hDev);
942
943    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
944
945done:
946    return( retCode );
947}
948
949
950BERR_Code BIRB_SendXmp2Nack (
951    BIRB_Handle         hDev           /* Device handle */
952)
953{
954    uint8_t     ackData;
955    BERR_Code retCode = BERR_SUCCESS;
956
957    BDBG_ASSERT( hDev );
958    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
959
960    /* build ack data
961     * For now, owener code is 0.
962     * Data structure is based on page 8 of Packet Layer Spec version 1.3,
963     * which is slightly different from page 18 of XMP-2 Remore Demo v1.2.doc
964     * ------------------------
965     * |C1|C0|0|ACK|N3|N2|N1|N0|
966     * ------------------------
967     * C1-C0 10 = dual device mode
968     * ACK = 1 NAK= 0
969     * N3-N0 0000 = accepting all peripherals.
970     */
971    ackData = 0x80;
972
973    BIRB_Reset (hDev);
974
975    BIRB_P_ConfigDataSequenceXmp2(hDev, &ackData, 1);
976
977    BIRB_ConfigRegisters (hDev);
978
979    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
980
981done:
982    return( retCode );
983}
984
985
986/****************************************************************
987 * This function is used to send generic one or four byte data. *
988 ****************************************************************/
989BERR_Code BIRB_SendXmp2Bytes (
990    BIRB_Handle         hDev,           /* Device handle */
991    uint8_t             *pByte,         /* date to send */
992    uint8_t             numByte         /* 1 or 4 bye */
993)
994{
995    uint8_t     ackData;
996    BERR_Code retCode = BERR_SUCCESS;
997
998    BDBG_ASSERT( hDev );
999    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
1000    BSTD_UNUSED(ackData);
1001
1002    if (numByte != 1 && numByte != 4)
1003    {
1004        BDBG_ERR(("%s/%d : unsupported bytes", __FILE__, __LINE__)); \
1005        return BERR_INVALID_PARAMETER;
1006    }
1007    BIRB_Reset (hDev);
1008
1009    BIRB_P_ConfigDataSequenceXmp2(hDev, pByte, numByte);
1010
1011    BIRB_ConfigRegisters (hDev);
1012
1013    BIRB_CHK_RETCODE( retCode, BIRB_Blast (hDev) );
1014
1015done:
1016    return( retCode );
1017}
1018
1019
1020void BIRB_ConfigRegisters(
1021    BIRB_Handle     hDev
1022)
1023{
1024    uint32_t    i, lval, regIndex, addr, duration;
1025    SIrbConfiguration *pIrbConfig = hDev->pConfig;
1026
1027
1028    /* Clear interrupt status */
1029    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS);
1030    lval |= (BCHP_IRB_BLAST_INTRSTATUS_seqPage0Done_MASK |
1031             BCHP_IRB_BLAST_INTRSTATUS_seqPage1Done_MASK |
1032             BCHP_IRB_BLAST_INTRSTATUS_blastDone_MASK );
1033    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS, lval);
1034
1035    /*
1036     * Configure CONTROL register
1037     */
1038    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1039    lval |= (BCHP_IRB_BLAST_CONTROL_intensify_MASK | (pIrbConfig->noCarrier ? BCHP_IRB_BLAST_CONTROL_carrInh_MASK : 0));
1040    lval &= ~BCHP_IRB_BLAST_CONTROL_seqPage_MASK;               /* starting loading page 0 */
1041    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1042
1043    /*
1044     * Configure prescaler registers
1045     */
1046    lval = pIrbConfig->masterClockDivisor - 1;
1047    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_PRIMPRE, lval);
1048
1049    lval  = (pIrbConfig->carrierClockDivisor - 1) << 4;
1050    lval |= (pIrbConfig->indexClockDivisor - 1);
1051    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INDXPRE, lval);
1052
1053    /*
1054     * Configure repeat registers
1055     */
1056    lval = pIrbConfig->repeatCount;
1057    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_REPNUM, lval);
1058
1059    lval = pIrbConfig->repeatStartIndex;
1060    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_REPINDX, lval);
1061    /*
1062     * Configure carrier width registers
1063     */
1064    lval = pIrbConfig->carrierHighCount - 1;
1065/*  if (lval & ~0xf)
1066        BRCM_DBG_WRN(("irblastr carrierHighCount > 16"));
1067*/
1068    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CARRHI, lval);
1069
1070    lval = pIrbConfig->carrierLowCount - 1;
1071/*  if (bval & ~0xf)
1072        BRCM_DBG_WRN(("irblastr carrierLowCount > 16"));
1073*/
1074    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CARRLO, lval);
1075
1076    /*
1077     * Configure Number of Sequence register
1078     */
1079    if (pIrbConfig->numberSequences > (2 * IRB_PAGE_SIZE))
1080    {
1081        lval = pIrbConfig->numberSequences - (2 * IRB_PAGE_SIZE) - 1;
1082        lval |= NUMSEQ_GREATER_THAN_80_BIT;
1083        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_NUMSEQ, lval);
1084
1085        /*
1086         * Must set longSeqMode bit
1087         */
1088        lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE);
1089        lval |= (BCHP_IRB_BLAST_INTRENABLE_longSeqMode_MASK |
1090                BCHP_IRB_BLAST_INTRENABLE_seqPage0Done_MASK);
1091
1092        hDev->longSequenceReloadPage0 = true;
1093
1094        if (pIrbConfig->numberSequences > (3 * IRB_PAGE_SIZE))
1095        {
1096            lval |= BCHP_IRB_BLAST_INTRENABLE_seqPage1Done_MASK;
1097            hDev->longSequenceReloadPage1 = true;
1098        }
1099
1100        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE, lval);
1101
1102    }
1103    else
1104    {
1105        lval = pIrbConfig->numberSequences - 1;
1106        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_NUMSEQ, lval);
1107        hDev->longSequenceReloadPage0 = hDev->longSequenceReloadPage1 = false;
1108    }
1109
1110    /*
1111     * Configure Sequence Index registers.
1112     */
1113    for (i = 0, regIndex = 0; i < pIrbConfig->numberSequences; i++, regIndex++)
1114    {
1115        /*
1116         * Check to see if we've loaded both pages already
1117         */
1118        if (i == (2* IRB_PAGE_SIZE))
1119            break;
1120
1121        /*
1122         * Check to see if we have to switch page
1123         */
1124        if (i == IRB_PAGE_SIZE)
1125        {
1126            lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1127            lval |= BCHP_IRB_BLAST_CONTROL_seqPage_MASK;
1128            BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1129
1130            regIndex = 0;
1131        }
1132        lval = (pIrbConfig->sequenceIndex[i].on << 4) | (pIrbConfig->sequenceIndex[i].off);
1133        BREG_Write32(hDev->hRegister, (BCHP_IRB_BLAST_SEQ_REGFILE00 + (regIndex * 4)), lval);
1134    }
1135
1136    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1137    lval &= ~BCHP_IRB_BLAST_CONTROL_seqPage_MASK;
1138    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1139
1140    addr = BCHP_IRB_BLAST_MOD_REGFILE00;    /* address of duration memory */
1141    for (i = 0; i < irb_durationMemLength; i++)
1142    {
1143        if (pIrbConfig->altModCnt == 1)
1144        {
1145            /* When altModeCnt is one, actual 0 pulse is used.
1146             * Do not subtract 1
1147             */
1148            duration = pIrbConfig->duration[i];
1149        }
1150        else
1151        {
1152            duration = pIrbConfig->duration[i] - 1;
1153        }
1154        /* The last 4 entries are "double-time", so we need to divide them by 2 */
1155        if (i >= 10)
1156            duration /= 2;
1157
1158        lval = duration >> 8;
1159        BREG_Write32(hDev->hRegister, addr, lval);
1160        addr += 4;
1161
1162        lval = duration & 0xff;
1163        BREG_Write32(hDev->hRegister, addr, lval);
1164        addr += 4;
1165    }
1166
1167    /* Configure altModCnt bit in INTRSTATUS register. */
1168    if (pIrbConfig->altModCnt == 1)
1169    {
1170        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE, BLAST_INTRENABLE_ALTMODCNT);
1171    }
1172    else
1173    {
1174        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRDISABLE, BLAST_INTRENABLE_ALTMODCNT);
1175    }
1176}
1177
1178/*******************************************************************************
1179*
1180*   Private Module Functions
1181*
1182*******************************************************************************/
1183void BIRB_P_EnableInt(
1184    BIRB_Handle     hDev
1185)
1186{
1187    uint32_t    lval;
1188
1189
1190    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1191    lval |= BCHP_IRB_BLAST_CONTROL_irqInh_MASK;
1192    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1193
1194    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE);
1195    lval |= (BCHP_IRB_BLAST_INTRENABLE_masterIntrEn_MASK | BCHP_IRB_BLAST_INTRENABLE_blastDone_MASK);
1196    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE, lval);
1197
1198}
1199
1200void BIRB_P_DisableInt(
1201    BIRB_Handle     hDev
1202)
1203{
1204    uint32_t    lval;
1205
1206
1207    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1208    lval |= BCHP_IRB_BLAST_CONTROL_irqInh_MASK;
1209    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1210
1211    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE);
1212    lval &= ~(BCHP_IRB_BLAST_INTRENABLE_masterIntrEn_MASK | BCHP_IRB_BLAST_INTRENABLE_blastDone_MASK);
1213    BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE, lval);
1214
1215}
1216
1217void BIRB_P_ConfigDataSequence(
1218    BIRB_Handle     hDev,
1219    uint32_t        *pData,         /* pointer to data to blast */
1220    uint8_t         bits,           /* number of bits to blast */
1221    bool            headerPulse     /* header flag */
1222)
1223{
1224    uint8_t     i, lastSeqIndex, noHeader;
1225    uint32_t    code, frameLength = 0, lastOffPeriod;
1226    SIrbConfiguration *pIrbConfig = hDev->pConfig;
1227
1228
1229    if (headerPulse)
1230    {
1231        noHeader = 0;
1232        pIrbConfig->numberSequences = bits + 1;
1233    }
1234    else
1235    {
1236        noHeader = 1;
1237    }
1238
1239    /*
1240     * Start bit sequence index already at sequenceIndex[0] if there's a header.
1241     * In this case, fill in indices for data bits beginning at sequenceIndex[1].
1242     */
1243    lastSeqIndex = bits;
1244    code = *pData++;
1245    for (i = 1 - noHeader; i <= lastSeqIndex - noHeader; i++)
1246    {
1247        pIrbConfig->sequenceIndex[i] = (code & 1) ? pIrbConfig->logic1IndexPair
1248                                                  : pIrbConfig->logic0IndexPair;
1249        code >>= 1;
1250        if (((i + noHeader) % 32) == 0)
1251        {
1252            code = *pData++;
1253        }
1254    }
1255
1256    /*
1257     * Extend OFF period of last pulse to satisfy frame duration requirment.
1258     */
1259    for (i = 0; i <= (lastSeqIndex - noHeader); i++)
1260    {
1261        irb_IndexPair indexPair = pIrbConfig->sequenceIndex[i];
1262        frameLength +=  pIrbConfig->duration[indexPair.on] +
1263                        pIrbConfig->duration[indexPair.off];
1264    }
1265    lastOffPeriod = pIrbConfig->framePeriod - frameLength +
1266                    pIrbConfig->duration[pIrbConfig->sequenceIndex[lastSeqIndex].off];
1267    pIrbConfig->duration[pIrbConfig->lastSequenceOffIndex] = lastOffPeriod;
1268    pIrbConfig->sequenceIndex[lastSeqIndex].off = pIrbConfig->lastSequenceOffIndex;
1269
1270}
1271
1272
1273void BIRB_P_ConfigDataSequenceAA(
1274    BIRB_Handle     hDev,
1275    uint32_t        *pData,         /* pointer to data to blast */
1276    uint8_t         bits,           /* number of bits to blast */
1277    bool            headerPulse,    /* header flag */
1278    bool            fixedFlag       /* fixed frame flag */
1279)
1280{
1281    uint8_t     i;
1282    uint8_t     noHeader;
1283    uint32_t    code, frameLength = 0, lastOffPeriod;
1284    SIrbConfiguration *pIrbConfig = hDev->pConfig;
1285
1286    /*
1287     * Start bit sequence index already at sequenceIndex[0].
1288     * Fill in indices for data bits beginning at sequenceIndex[1].
1289     */
1290
1291    if (headerPulse) {
1292        noHeader = 0;
1293    } else {
1294        noHeader = 1;
1295    }
1296
1297    code = *pData++;
1298    for (i = 1 - noHeader; i <= bits - noHeader; i++)
1299    {
1300        pIrbConfig->sequenceIndex[i] = (code & 1) ? pIrbConfig->logic1IndexPair
1301                                                  : pIrbConfig->logic0IndexPair;
1302        code >>= 1;
1303        if (((i + noHeader) % 32) == 0)
1304        {
1305            code = *pData++;
1306        }
1307    }
1308
1309    if (fixedFlag) {
1310        for (i = 0; i <= (pIrbConfig->numberSequences - 2); i++)
1311        {
1312            irb_IndexPair indexPair = pIrbConfig->sequenceIndex[i];
1313            frameLength +=  pIrbConfig->duration[indexPair.on] +
1314                            pIrbConfig->duration[indexPair.off];
1315        }
1316
1317        lastOffPeriod = pIrbConfig->framePeriod - (frameLength +
1318                        pIrbConfig->duration[pIrbConfig->sequenceIndex[pIrbConfig->numberSequences - 1].on]);
1319        pIrbConfig->duration[pIrbConfig->lastSequenceOffIndex] = lastOffPeriod;
1320        /* pIrbConfig->sequenceIndex[pIrbConfig->numberSequences - 1].off = pIrbConfig->lastSequenceOffIndex; */
1321    }
1322}
1323
1324
1325
1326void BIRB_P_ConfigDataSequenceAB(
1327    BIRB_Handle     hDev,
1328    uint32_t        *pDataA,        /* pointer to data A to blast */
1329    uint8_t         bitsA,          /* number of bits A to blast */
1330    uint32_t        *pDataB,        /* pointer to data B to blast */
1331    uint8_t         bitsB,          /* number of bits B to blast */
1332    bool            headerA,        /* header A flag */
1333    bool            headerB,        /* header B flag */
1334    bool            fixedFlag       /* fixed frame length */
1335)
1336{
1337    uint8_t     i, startSeqIndexB, noHeader;
1338    uint32_t    code, frameLength = 0, lastOffPeriod;
1339    SIrbConfiguration *pIrbConfig = hDev->pConfig;
1340
1341    /****************************************/
1342    /* Data A                               */
1343    /****************************************/
1344
1345    if (headerA) {
1346        noHeader = 0;
1347    } else {
1348        noHeader = 1;
1349    }
1350
1351    code = *pDataA++;
1352    for (i = 1 - noHeader; i <= bitsA - noHeader; i++)
1353    {
1354        pIrbConfig->sequenceIndex[i] = (code & 1) ? pIrbConfig->logic1IndexPair
1355                                                  : pIrbConfig->logic0IndexPair;
1356        code >>= 1;
1357        if (((i + noHeader) % 32) == 0)
1358        {
1359            code = *pDataA++;
1360        }
1361    }
1362
1363    if (fixedFlag)
1364    {
1365        for (i = 0; i <= (bitsA - noHeader); i++)
1366        {
1367            irb_IndexPair indexPair = pIrbConfig->sequenceIndex[i];
1368            frameLength +=  pIrbConfig->duration[indexPair.on] +
1369                            pIrbConfig->duration[indexPair.off];
1370        }
1371
1372        lastOffPeriod = pIrbConfig->framePeriod - (frameLength +
1373                        pIrbConfig->duration[pIrbConfig->sequenceIndex[bitsA - noHeader + 1].on]);
1374        pIrbConfig->duration[pIrbConfig->sequenceIndex[bitsA - noHeader + 1].off] = lastOffPeriod;
1375    }
1376
1377    /****************************************/
1378    /* Data B                               */
1379    /****************************************/
1380    /*
1381     * Start bit sequence index already at sequenceIndex[0].
1382     * Fill in indices for data bits beginning at sequenceIndex[1].
1383     */
1384    startSeqIndexB = bitsA + 2 - noHeader;
1385
1386    if (headerB) {
1387        noHeader = 0;
1388    } else {
1389        noHeader = 1;
1390    }
1391
1392    if (bitsB != 0) {
1393        code = *pDataB++;
1394        for (i = (startSeqIndexB + 1 - noHeader); i <= (startSeqIndexB + bitsB - noHeader); i++)
1395        {
1396            pIrbConfig->sequenceIndex[i] = (code & 1) ? pIrbConfig->logic1IndexPair
1397                                                      : pIrbConfig->logic0IndexPair;
1398            code >>= 1;
1399            if (((i - startSeqIndexB + noHeader) % 32) == 0)
1400            {
1401                code = *pDataB++;
1402            }
1403        }
1404    }
1405
1406    if (fixedFlag)
1407    {
1408        /*
1409         * Calculate time for data and header
1410         */
1411        frameLength = 0;
1412        for (i = startSeqIndexB; i <= (pIrbConfig->numberSequences - 2); i++)
1413        {
1414            irb_IndexPair indexPair = pIrbConfig->sequenceIndex[i];
1415            frameLength +=  pIrbConfig->duration[indexPair.on] +
1416                            pIrbConfig->duration[indexPair.off];
1417        }
1418
1419        /* Now calculate the remaining off time for end pulse */
1420        lastOffPeriod = pIrbConfig->framePeriodB - (frameLength +
1421                        pIrbConfig->duration[pIrbConfig->sequenceIndex[pIrbConfig->numberSequences - 1].on]);
1422
1423        pIrbConfig->duration[pIrbConfig->sequenceIndex[pIrbConfig->numberSequences - 1].off] = lastOffPeriod;
1424    }
1425}
1426
1427/*****************************************************************************/
1428/* Set Data Sequence (sequenceIndex) in configuration for XMP-2 Station 38K  */
1429/*****************************************************************************/
1430void BIRB_P_ConfigDataSequenceXmp2(
1431    BIRB_Handle     hDev,
1432    uint8_t         *pData,             /* data */
1433    uint8_t         numByte             /* 1 or 4 */
1434    )
1435{
1436    SIrbConfiguration *pIrbConfig= hDev->pConfig;
1437    uint8_t i;
1438    uint8_t nibble0, nibble1;
1439
1440    if (numByte == 4)
1441    {
1442        pIrbConfig->numberSequences = 17;
1443        /* sequenceIndex[4] could be set to trailer pulse.
1444         * set it back to data pulse
1445         */
1446        pIrbConfig->sequenceIndex[4].on = DATA_PULSE;
1447    }
1448    else
1449    if (numByte == 1)
1450    {
1451        pIrbConfig->numberSequences = 5;
1452        /* set the trailer pulse */
1453        pIrbConfig->sequenceIndex[4].on = TRAILER_PULSE;
1454        pIrbConfig->sequenceIndex[4].off = ZERO;
1455    }
1456    else
1457    {
1458        BDBG_ERR(("%s/%d : unsupported bytes", __FILE__, __LINE__)); \
1459        return;
1460    }
1461
1462    for (i=0; i<numByte; i++)
1463    {
1464        nibble0 = (pData[i] >> 4) & 0x0F;   /* upper nibble */
1465        nibble1 = pData[i] & 0x0F;          /* lower nibble */
1466        /* Data High already at sequenceIndex[i].on and
1467         * Zero already at sequenceIndex[i+1].on,
1468         * need only determine sequenceIndex[i].off and
1469         * sequenceIndex[i+1].off from nibble.
1470         */
1471        pIrbConfig->sequenceIndex[i*4].off   = DATA0 + (nibble0>>1);
1472        pIrbConfig->sequenceIndex[i*4+1].off = (nibble0 & 0x01) ? DELTA1 : ZERO;
1473        pIrbConfig->sequenceIndex[i*4+2].off = DATA0 + (nibble1>>1);
1474        pIrbConfig->sequenceIndex[i*4+3].off = (nibble1 & 0x01) ? DELTA1 : ZERO;
1475    }
1476}
1477
1478
1479static void BIRB_P_HandleInterrupt_Isr
1480(
1481    void *pParam1,                      /* Device channel handle */
1482    int parm2                           /* not used */
1483)
1484{
1485    BIRB_Handle         hDev;
1486    uint32_t            lval, i, regIndex;
1487    SIrbConfiguration   *pIrbConfig;
1488    BSTD_UNUSED(parm2);
1489
1490    hDev = (BIRB_Handle) pParam1;
1491    BDBG_ASSERT( hDev );
1492
1493    pIrbConfig = hDev->pConfig;
1494
1495    lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS);
1496    lval &= BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_INTRENABLE);
1497
1498    if (lval & BCHP_IRB_BLAST_INTRSTATUS_blastDone_MASK)
1499    {
1500        /* clear interrupt */
1501        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS, BCHP_IRB_BLAST_INTRSTATUS_blastDone_MASK);
1502        BKNI_SetEvent( hDev->hEvent );
1503        return;
1504    }
1505
1506    if (lval & BCHP_IRB_BLAST_INTRSTATUS_seqPage0Done_MASK)
1507    {
1508        /* clear interrupt */
1509        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRDISABLE, BCHP_IRB_BLAST_INTRSTATUS_seqPage0Done_MASK);
1510        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS, BCHP_IRB_BLAST_INTRSTATUS_seqPage0Done_MASK);
1511
1512        /*
1513         * Load sequence 81-120
1514         */
1515        if (hDev->longSequenceReloadPage0)
1516        {
1517            lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1518            lval &= ~BCHP_IRB_BLAST_CONTROL_seqPage_MASK;               /* choose page 0 */
1519            BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1520
1521            for (i = 80, regIndex = 0; i < pIrbConfig->numberSequences; i++, regIndex++)
1522            {
1523                lval = (pIrbConfig->sequenceIndex[i].on << 4) | (pIrbConfig->sequenceIndex[i].off);
1524                BREG_Write32(hDev->hRegister, (BCHP_IRB_BLAST_SEQ_REGFILE00 + (regIndex * 4)), lval);
1525                if (regIndex == 39)                                     /* we've filled up this page */
1526                    break;
1527            }
1528            hDev->longSequenceReloadPage0 = false;
1529        }
1530        return;
1531    }
1532
1533    if (lval & BCHP_IRB_BLAST_INTRSTATUS_seqPage1Done_MASK)
1534    {
1535        /* clear interrupt */
1536        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRDISABLE, BCHP_IRB_BLAST_INTRSTATUS_seqPage1Done_MASK);
1537        BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_INTRSTATUS, BCHP_IRB_BLAST_INTRSTATUS_seqPage1Done_MASK);
1538
1539        /*
1540         * Load sequence 121-160
1541         */
1542        if (hDev->longSequenceReloadPage1)
1543        {
1544            lval = BREG_Read32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL);
1545            lval |= BCHP_IRB_BLAST_CONTROL_seqPage_MASK;                /* choose page 1 */
1546            BREG_Write32(hDev->hRegister, BCHP_IRB_BLAST_CONTROL, lval);
1547
1548            for (i = 120, regIndex = 0; i < pIrbConfig->numberSequences; i++, regIndex++)
1549            {
1550                lval = (pIrbConfig->sequenceIndex[i].on << 4) | (pIrbConfig->sequenceIndex[i].off);
1551                BREG_Write32(hDev->hRegister, (BCHP_IRB_BLAST_SEQ_REGFILE00 + (regIndex * 4)), lval);
1552            }
1553            hDev->longSequenceReloadPage1 = false;
1554        }
1555    }
1556}
1557
Note: See TracBrowser for help on using the repository browser.