source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/icp/7552/bicp.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 29.6 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: bicp.c $
11 * $brcm_Revision: Hydra_Software_Devel/50 $
12 * $brcm_Date: 11/21/11 6:19p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/icp/7435/bicp.c $
19 *
20 * Hydra_Software_Devel/50   11/21/11 6:19p mward
21 * SW7435-7: Add 7435.
22 *
23 * Hydra_Software_Devel/49   10/11/11 2:08p agin
24 * SW7429-27:  Add support for 7429.
25 *
26 * Hydra_Software_Devel/48   1/17/11 11:04a mward
27 * SW7344-9: warning: unused variable 'lval'.
28 *
29 * Hydra_Software_Devel/47   1/16/11 3:40p agin
30 * SW7344-9:  For 7346, need to write to BCHP_IRQ0_AON_IRQEN, instead of
31 * BCHP_IRQ0_IRQEN.  However, we don't need to do this in general as it
32 * is handled in BINT_EnableCallback.
33 *
34 * Hydra_Software_Devel/46   12/27/10 1:56p xhuang
35 * SW7358-29: Add 7358/7552 support
36 *
37 * Hydra_Software_Devel/45   12/8/10 9:45a jrubio
38 * SW7344-9: add 40nm chip support
39 *
40 * Hydra_Software_Devel/44   11/2/10 4:55p hongtaoz
41 * SW7425-9: added 7425 support;
42 *
43 * Hydra_Software_Devel/43   10/7/10 4:38p nickh
44 * SW7422-74: Add 7422 support
45 *
46 * Hydra_Software_Devel/42   12/13/09 6:39p rpereira
47 * SW7550-41: Fixed compilation issues for 7550
48 *
49 * Hydra_Software_Devel/41   12/4/09 6:54p randyjew
50 * SW7468-6: Add 7468 support
51 *
52 * Hydra_Software_Devel/40   11/6/09 3:57p gmohile
53 * SW7408-1 : Add 7408 support
54 *
55 * Hydra_Software_Devel/39   9/1/09 9:14p rpereira
56 * SW7550-30: Adding 7550 support
57 *
58 * Hydra_Software_Devel/38   8/20/09 4:05p mward
59 * PR55545: Support 7125.
60 *
61 * Hydra_Software_Devel/37   8/10/09 4:24p jrubio
62 * PR55232: add 7340/7342
63 *
64 * Hydra_Software_Devel/36   3/6/09 2:06p jkim
65 * PR52508: remove global variable and move it inside the handle
66 *
67 * Hydra_Software_Devel/35   1/31/09 1:11a jrubio
68 * PR51629:add 7336 support
69 *
70 * Hydra_Software_Devel/34   12/2/08 4:21p kaushikb
71 * PR49867: Adding support for 7420
72 *
73 * Hydra_Software_Devel/33   6/9/08 10:34a jkim
74 * PR42188: Close the channel only if channel is not closed yet during
75 * BICP_Close
76 *
77 * Hydra_Software_Devel/32   4/4/08 11:03a farshidf
78 * PR39179: Add 3548/3556 support
79 *
80 * Hydra_Software_Devel/31   11/27/07 6:02p farshidf
81 * PR36887: Add 7335 support
82 *
83 * Hydra_Software_Devel/30   10/14/07 3:52p jkim
84 * PR14344: add 7325 support
85 *
86 * Hydra_Software_Devel/29   5/18/07 10:59a jkim
87 * PR14344: Add 7405 support
88 *
89 * Hydra_Software_Devel/28   2/16/07 11:36a jkim
90 * PR14344: Added 7440 support
91 *
92 * Hydra_Software_Devel/27   2/2/07 11:22a jkim
93 * PR27238: Modify to use the correct IRQ definition
94 *
95 * Hydra_Software_Devel/26   1/12/07 4:22p jkim
96 * PR14344: Add 3563 support
97 *
98 * Hydra_Software_Devel/25   11/9/06 11:04a jkim
99 * PR14344: added 7403 support
100 *
101 * Hydra_Software_Devel/24   9/19/06 5:20p agin
102 * PR24339: Resolve compiler warning for DEBUG=n builds for UPG modules.
103 *
104 * Hydra_Software_Devel/23   8/9/06 11:00a agin
105 * PR23362: Add 3563 support.
106 *
107 * Hydra_Software_Devel/22   7/25/06 2:45p ltokuda
108 * PR21692: Add BCM7118 support.
109 *
110 * Hydra_Software_Devel/21   3/21/06 3:03p jkim
111 * PR20326: Add support for 7438
112 *
113 * Hydra_Software_Devel/20   1/14/06 11:00p agin
114 * PR19076: Support BCM7400.
115 *
116 * Hydra_Software_Devel/19   1/3/06 12:10p agin
117 * PR18689: Infinite recursive call in BICP_DisableInt (bicp.c)
118 *
119 * Hydra_Software_Devel/18   9/8/05 10:58a brianlee
120 * PR16410: Make rcPinMask a variable that supports multiple ICAP pins.
121 *
122 * Hydra_Software_Devel/17   8/23/05 5:09p jkim
123 * PR14344: Adding 7401 support
124 *
125 * Hydra_Software_Devel/16   7/26/05 6:33p brianlee
126 * PR16410: Fixed RC6 remote missing key detection.
127 *
128 * Hydra_Software_Devel/15   4/7/05 10:44a agin
129 * PR14698: unused parameters.
130 *
131 * Hydra_Software_Devel/14   3/10/05 8:51a dlwin
132 * PR 14240: Added support for 3560
133 *
134 * Hydra_Software_Devel/13   3/7/05 9:06a dlwin
135 * PR 13212: Replaced C++ comment with C version
136 *
137 * Hydra_Software_Devel/12   2/24/05 5:27p agin
138 * PR13212:  Fixed RC6 state machine for when receiving a bad waveform.
139 *
140 * Hydra_Software_Devel/11   2/4/05 11:18a agin
141 * PR13212:  added callback for RC6 processing.  Improved ISR.
142 *
143 * Hydra_Software_Devel/10   2/3/05 11:36a agin
144 * PR13212: RC6 support
145 *
146 * Hydra_Software_Devel/9   2/1/05 7:05p agin
147 * PR13987:  don't use globals in portinginterface.
148 *
149 * Hydra_Software_Devel/8   1/31/05 5:56p agin
150 * PR13987:  interrupt frequency count for icap.
151 *
152 * Hydra_Software_Devel/7   3/26/04 4:32p brianlee
153 * PR8971: Remove BDBG_ASSERT() for malloc failure.
154 *
155 * Hydra_Software_Devel/6   12/29/03 3:59p marcusk
156 * PR9117: Updated with changes required to support interrupt ids rather
157 * than strings.
158 *
159 * Hydra_Software_Devel/5   11/4/03 6:50p brianlee
160 * Get rid of enter/leave macros.
161 *
162 * Hydra_Software_Devel/4   10/24/03 4:34p brianlee
163 * Remove define for max icap channel.  This has been moved to bicp.h.
164 *
165 * Hydra_Software_Devel/3   9/24/03 11:57a brianlee
166 * Changed the names of header files.
167 *
168 * Hydra_Software_Devel/2   9/19/03 12:27p brianlee
169 * Fixed warnings from Midas build.
170 *
171 * Hydra_Software_Devel/1   9/16/03 7:03p brianlee
172 * Initial version.
173 *
174 ***************************************************************************/
175#include "bstd.h"
176#include "bicp.h"
177#include "bicp_priv.h"
178#include "bchp_icap.h"
179#include "bchp_irq0.h"
180#include "bchp_int_id_irq0.h"
181#if (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7429) || (BCHP_CHIP==7344) || \
182        (BCHP_CHIP==7346) || (BCHP_CHIP==7231) || (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || \
183        (BCHP_CHIP==7435)
184#include "bchp_int_id_irq0_aon.h"
185#include "bchp_irq0_aon.h"
186#endif
187
188BDBG_MODULE(bicp);
189
190#define DEV_MAGIC_ID                    ((BERR_ICP_ID<<16) | 0xFACE)
191
192#define BICP_CHK_RETCODE( rc, func )            \
193do {                                                                            \
194        if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
195        {                                                                               \
196                goto done;                                                      \
197        }                                                                               \
198} while(0)
199
200#define MAX_ICAP_RCNT                           15
201
202#if (BCHP_CHIP==3563) || (BCHP_CHIP==3548) || (BCHP_CHIP==3556)
203#ifndef BCHP_INT_ID_icap_irqen
204#define BCHP_INT_ID_icap_irqen                  BCHP_INT_ID_icap
205#endif
206#endif
207
208/*******************************************************************************
209*
210*       Private Module Handles
211*
212*******************************************************************************/
213
214typedef struct BICP_P_Handle
215{
216        uint32_t                magicId;                                        /* Used to check if structure is corrupt */
217        BCHP_Handle     hChip;
218        BREG_Handle             hRegister;
219        BINT_Handle     hInterrupt;
220        unsigned int    maxChnNo;
221        unsigned int    uiRCPinMask;
222        BICP_ChannelHandle hIcpChn[MAX_ICP_CHANNELS];
223} BICP_P_Handle;
224
225typedef struct BICP_P_RC6_KEYBIT {
226        unsigned char ve;               /* 1: ve+, 0: ve */
227        unsigned char used;             /* counted or not */
228        unsigned char len;              /* in T unit */
229} BICP_P_RC6_KEYBIT;
230
231typedef struct BICP_P_RC6
232{
233        uint8_t lead;
234        uint8_t start;
235        uint8_t trailer;
236        uint8_t mode;
237        uint8_t modebits;
238        uint8_t ctrl;
239        uint16_t ctrlbits;
240        uint8_t total_ctrl_bits;
241        uint8_t info;
242        uint16_t data;
243        uint8_t edge;   /*0: 1->0, 1: 0->1 */
244        uint16_t last;
245        int                                     keycnt;
246        BICP_P_RC6_KEYBIT       keybits[314];
247} BICP_P_RC6;
248
249typedef struct BICP_P_ChannelHandle
250{
251        uint32_t                        magicId;                                        /* Used to check if structure is corrupt */
252        BICP_Handle             hIcp;
253        uint32_t                        chnNo;
254        uint32_t                        isrCount;
255        unsigned int            handleRC6;
256        BICP_P_RC6                      rc6;
257        BKNI_EventHandle        hChnEvent;
258        BINT_CallbackHandle hChnCallback;
259        BICP_Callback           pInterruptEventUserCallback;
260} BICP_P_ChannelHandle;
261
262#if 0
263/* move inside handle */
264static unsigned int uiRCPinMask = 0;
265#endif
266
267#define RCCOUNTER       (1<<16)
268#define TUNIT           (27000*16/36)
269#define TUNIT14         (TUNIT>>2)
270#define TUNIT34         ((TUNIT*3)>>2)
271#define INFOBITS        12              /* only support 12 bits info now */
272
273/*******************************************************************************
274*
275*       Default Module Settings
276*
277*******************************************************************************/
278static const BICP_Settings defIcpSettings = NULL;
279
280static const BICP_ChannelSettings defIcpChn0Settings =
281{
282        MAX_ICAP_RCNT,
283        true
284};
285
286static const BICP_ChannelSettings defIcpChn1Settings =
287{
288        MAX_ICAP_RCNT,
289        true
290};
291
292static const BICP_ChannelSettings defIcpChn2Settings =
293{
294        MAX_ICAP_RCNT,
295        true
296};
297
298static const BICP_ChannelSettings defIcpChn3Settings =
299{
300        MAX_ICAP_RCNT,
301        true
302};
303
304/*******************************************************************************
305*
306*       Public Module Functions
307*
308*******************************************************************************/
309BERR_Code BICP_Open(
310        BICP_Handle *pIcp,                                      /* [output] Returns handle */
311        BCHP_Handle hChip,                                      /* Chip handle */
312        BREG_Handle hRegister,                          /* Register handle */
313        BINT_Handle hInterrupt,                         /* Interrupt handle */
314        const BICP_Settings *pDefSettings       /* Default settings */
315        )
316{
317        BERR_Code retCode = BERR_SUCCESS;
318        BICP_Handle hDev;
319        unsigned int chnIdx;
320        BSTD_UNUSED(pDefSettings);
321
322        /* Sanity check on the handles we've been given. */
323        BDBG_ASSERT( hChip );
324        BDBG_ASSERT( hRegister );
325        BDBG_ASSERT( hInterrupt );
326
327        /* Alloc memory from the system heap */
328        hDev = (BICP_Handle) BKNI_Malloc( sizeof( BICP_P_Handle ) );
329        if( hDev == NULL )
330        {
331                *pIcp = NULL;
332                retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
333                BDBG_ERR(("BICP_Open: BKNI_malloc() failed\n"));
334                goto done;
335        }
336
337        hDev->magicId   = DEV_MAGIC_ID;
338        hDev->hChip             = hChip;
339        hDev->hRegister = hRegister;
340        hDev->hInterrupt = hInterrupt;
341        hDev->maxChnNo  = MAX_ICP_CHANNELS;
342        hDev->uiRCPinMask = 0;
343        for( chnIdx = 0; chnIdx < hDev->maxChnNo; chnIdx++ )
344        {
345                hDev->hIcpChn[chnIdx] = NULL;
346        }
347
348
349        *pIcp = hDev;
350
351done:
352        return( retCode );
353}
354
355BERR_Code BICP_Close(
356        BICP_Handle hDev                                        /* Device handle */
357        )
358{
359        BERR_Code retCode = BERR_SUCCESS;
360    unsigned int chnIdx;
361
362
363        BDBG_ASSERT( hDev );
364        BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
365
366        /* If channel is not closed, close the channel to free up the memory */
367    for( chnIdx = 0; chnIdx < hDev->maxChnNo; chnIdx++ )
368    {
369        if (hDev->hIcpChn[chnIdx])
370        {
371            BICP_CloseChannel(hDev->hIcpChn[chnIdx]);
372        }
373    }
374
375        BKNI_Free( (void *) hDev );
376
377        return( retCode );
378}
379
380BERR_Code BICP_GetDefaultSettings(
381        BICP_Settings *pDefSettings,            /* [output] Returns default setting */
382        BCHP_Handle hChip                                       /* Chip handle */
383        )
384{
385        BERR_Code retCode = BERR_SUCCESS;
386        BSTD_UNUSED(hChip);
387
388        *pDefSettings = defIcpSettings;
389
390        return( retCode );
391}
392
393BERR_Code BICP_GetTotalChannels(
394        BICP_Handle hDev,                                       /* Device handle */
395        unsigned int *totalChannels                     /* [output] Returns total number downstream channels supported */
396        )
397{
398        BERR_Code retCode = BERR_SUCCESS;
399
400
401        BDBG_ASSERT( hDev );
402        BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
403
404        *totalChannels = hDev->maxChnNo;
405
406        return( retCode );
407}
408
409BERR_Code BICP_GetChannelDefaultSettings(
410        BICP_Handle hDev,                                       /* Device handle */
411        unsigned int channelNo,                         /* Channel number to default setting for */
412    BICP_ChannelSettings *pChnDefSettings /* [output] Returns channel default setting */
413    )
414{
415        BERR_Code retCode = BERR_SUCCESS;
416
417#if !BDBG_DEBUG_BUILD
418        BSTD_UNUSED(hDev);
419#endif
420
421        BDBG_ASSERT( hDev );
422        BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
423
424        switch (channelNo)
425        {
426                case 0:
427                        *pChnDefSettings = defIcpChn0Settings;
428                        break;
429
430                case 1:
431                        *pChnDefSettings = defIcpChn1Settings;
432                        break;
433
434                case 2:
435                        *pChnDefSettings = defIcpChn2Settings;
436                        break;
437
438                case 3:
439                        *pChnDefSettings = defIcpChn3Settings;
440                        break;
441
442                default:
443                        retCode = BERR_INVALID_PARAMETER;
444                        break;
445
446        }
447
448        return( retCode );
449}
450
451BERR_Code BICP_OpenChannel(
452        BICP_Handle hDev,                                       /* Device handle */
453        BICP_ChannelHandle *phChn,                      /* [output] Returns channel handle */
454        unsigned int channelNo,                         /* Channel number to open */
455        const BICP_ChannelSettings *pChnDefSettings /* Channel default setting */
456        )
457{
458        BERR_Code                       retCode = BERR_SUCCESS;
459        BICP_ChannelHandle      hChnDev;
460
461        BDBG_ASSERT( hDev );
462        BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
463
464        hChnDev = NULL;
465
466        if( channelNo < hDev->maxChnNo )
467        {
468                if( hDev->hIcpChn[channelNo] == NULL )
469                {
470                        /* Alloc memory from the system heap */
471                        hChnDev = (BICP_ChannelHandle) BKNI_Malloc( sizeof( BICP_P_ChannelHandle ) );
472                        if( hChnDev == NULL )
473                        {
474                                *phChn = NULL;
475                                retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
476                                BDBG_ERR(("BICP_OpenChannel: BKNI_malloc() failed\n"));
477                                goto done;
478                        }
479
480                        BICP_CHK_RETCODE( retCode, BKNI_CreateEvent( &(hChnDev->hChnEvent) ) );
481                        hChnDev->magicId        = DEV_MAGIC_ID;
482                        hChnDev->hIcp           = hDev;
483                        hChnDev->chnNo          = channelNo;
484                        hChnDev->isrCount       = 0;
485                        hChnDev->rc6.lead       = 0;
486                        hChnDev->rc6.start      = 0;
487                        hChnDev->rc6.trailer    = 0;
488                        hChnDev->rc6.mode       = 0;
489                        hChnDev->rc6.modebits   = 0;
490                        hChnDev->rc6.ctrl       = 0;
491                        hChnDev->rc6.ctrlbits   = 0;
492                        hChnDev->rc6.total_ctrl_bits    = 8;
493                        hChnDev->rc6.info       = 0;
494                        hChnDev->rc6.data       = 0;
495                        hChnDev->rc6.edge       = 0;
496                        hChnDev->rc6.last       = 0;
497                        hChnDev->rc6.keycnt     = 0;
498                        hChnDev->pInterruptEventUserCallback = NULL;
499                        hDev->hIcpChn[channelNo] = hChnDev;
500
501                        /* Program glitch rejector count */
502                        BICP_CHK_RETCODE( retCode, BICP_P_SetRejectCnt (hChnDev, pChnDefSettings->rejectCnt) );
503
504                        /*
505                         * Enable interrupt for this channel
506                         */
507                        if (pChnDefSettings->intMode == true)
508                        {
509                                /*
510                                 * Register and enable L2 interrupt.
511                                 */
512#if (BCHP_CHIP==7038) || (BCHP_CHIP==7438) || (BCHP_CHIP==7400) || (BCHP_CHIP==7420) || (BCHP_CHIP==7401) || (BCHP_CHIP==7403) || \
513    (BCHP_CHIP==7405) || (BCHP_CHIP==7440) || (BCHP_CHIP==7118) || (BCHP_CHIP==3563) || (BCHP_CHIP==7325) || (BCHP_CHIP==7335) || \
514        (BCHP_CHIP==7340) || (BCHP_CHIP==7342) || (BCHP_CHIP==3548) || (BCHP_CHIP==3556) || (BCHP_CHIP==7125) || (BCHP_CHIP==7408) || \
515        (BCHP_CHIP==7468) || (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7429) || (BCHP_CHIP==7344) || (BCHP_CHIP==7346) || (BCHP_CHIP==7231) || \
516        (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || (BCHP_CHIP==7435)
517                                BICP_CHK_RETCODE( retCode, BINT_CreateCallback(
518                                        &(hChnDev->hChnCallback), hDev->hInterrupt, BCHP_INT_ID_icap_irqen,
519                                        BICP_P_HandleInterrupt_Isr, (void *) hChnDev, (1 << channelNo) ) );
520#elif (BCHP_CHIP==3560) || (BCHP_CHIP==3563) || (BCHP_CHIP==3548) || (BCHP_CHIP==3556) || (BCHP_CHIP==7550)
521                                BICP_CHK_RETCODE( retCode, BINT_CreateCallback(
522                                        &(hChnDev->hChnCallback), hDev->hInterrupt, BCHP_INT_ID_icap,
523                                        BICP_P_HandleInterrupt_Isr, (void *) hChnDev, (1 << channelNo) ) );
524#else
525#error BCHP_CHIP set to unsupport chip.
526#endif
527                                BICP_CHK_RETCODE( retCode, BINT_EnableCallback( hChnDev->hChnCallback ) );
528
529                                /*
530                                 * Enable ICP interrupt in ICP
531                                 */
532                                BKNI_EnterCriticalSection();
533                                BICP_P_EnableInt (hChnDev);
534                                BKNI_LeaveCriticalSection();
535                        }
536
537                        *phChn = hChnDev;
538                }
539                else
540                {
541                        retCode = BICP_ERR_NOTAVAIL_CHN_NO;
542                }
543        }
544        else
545        {
546                retCode = BERR_INVALID_PARAMETER;
547        }
548
549done:
550        if( retCode != BERR_SUCCESS )
551        {
552                if( hChnDev != NULL )
553                {
554                        BKNI_DestroyEvent( hChnDev->hChnEvent );
555                        BKNI_Free( hChnDev );
556                        hDev->hIcpChn[channelNo] = NULL;
557                        *phChn = NULL;
558                }
559        }
560        return( retCode );
561}
562
563BERR_Code BICP_CloseChannel(
564        BICP_ChannelHandle hChn                 /* Device channel handle */
565        )
566{
567        BERR_Code retCode = BERR_SUCCESS;
568        BICP_Handle hDev;
569        unsigned int chnNo;
570
571
572        BDBG_ASSERT( hChn );
573        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
574
575        hDev = hChn->hIcp;
576
577    /* Reset uiRCPinMask if channel is RC6 */
578    if (hChn->handleRC6)
579    {
580        hDev->uiRCPinMask &= ~(1<<hChn->chnNo);
581    }
582
583        /*
584         * Disable interrupt for this channel
585         */
586        BKNI_EnterCriticalSection();
587        BICP_P_DisableInt (hChn);
588        BKNI_LeaveCriticalSection();
589
590        BICP_CHK_RETCODE( retCode, BINT_DisableCallback( hChn->hChnCallback ) );
591        BICP_CHK_RETCODE( retCode, BINT_DestroyCallback( hChn->hChnCallback ) );
592        BKNI_DestroyEvent( hChn->hChnEvent );
593        chnNo = hChn->chnNo;
594        BKNI_Free( hChn );
595        hDev->hIcpChn[chnNo] = NULL;
596
597done:
598        return( retCode );
599}
600
601BERR_Code BICP_GetDevice(
602        BICP_ChannelHandle hChn,                        /* Device channel handle */
603        BICP_Handle *phDev                                      /* [output] Returns Device handle */
604        )
605{
606        BERR_Code retCode = BERR_SUCCESS;
607
608
609        BDBG_ASSERT( hChn );
610        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
611
612        *phDev = hChn->hIcp;
613
614        return( retCode );
615}
616
617
618BERR_Code BICP_GetEventHandle(
619        BICP_ChannelHandle hChn,                        /* Device channel handle */
620        BKNI_EventHandle *phEvent                       /* [output] Returns event handle */
621        )
622{
623        BERR_Code retCode = BERR_SUCCESS;
624
625
626        BDBG_ASSERT( hChn );
627        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
628
629
630        *phEvent = hChn->hChnEvent;
631        return( retCode );
632}
633
634BERR_Code BICP_EnableEdge(
635        BICP_ChannelHandle      hChn,                   /* Device channel handle */
636        BICP_EdgeConfig         edge                    /* edge config */
637        )
638{
639        BERR_Code retCode = BERR_SUCCESS;
640        uint32_t lval, mask;
641        BICP_Handle     hDev;
642
643        BDBG_ASSERT( hChn );
644        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
645
646        hDev = hChn->hIcp;
647
648        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_INEDGE);
649        mask = 1 << hChn->chnNo;
650        if (edge == BICP_EdgeConfig_ePositive || edge == BICP_EdgeConfig_eBoth)
651                lval |= (mask << BCHP_ICAP_INEDGE_icap_pedgedet_SHIFT);
652        if (edge == BICP_EdgeConfig_eNegative || edge == BICP_EdgeConfig_eBoth)
653                lval |= mask;
654
655        BREG_Write32(hDev->hRegister, BCHP_ICAP_INEDGE, lval);
656
657        return( retCode );
658}
659
660BERR_Code BICP_DisableEdge(
661        BICP_ChannelHandle      hChn,                   /* Device channel handle */
662        BICP_EdgeConfig         edge                    /* edge config */
663        )
664{
665        BERR_Code retCode = BERR_SUCCESS;
666        uint32_t lval, mask;
667        BICP_Handle     hDev;
668
669        BDBG_ASSERT( hChn );
670        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
671
672        hDev = hChn->hIcp;
673
674        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_INEDGE);
675        mask = 1 << hChn->chnNo;
676        if (edge == BICP_EdgeConfig_ePositive || edge == BICP_EdgeConfig_eBoth)
677                lval &= ~(mask << BCHP_ICAP_INEDGE_icap_pedgedet_SHIFT);
678        if (edge == BICP_EdgeConfig_eNegative || edge == BICP_EdgeConfig_eBoth)
679                lval &= ~mask;
680        BREG_Write32(hDev->hRegister, BCHP_ICAP_INEDGE, lval);
681
682        return( retCode );
683}
684
685BERR_Code BICP_GetTimerCnt(
686        BICP_ChannelHandle      hChn,                   /* Device channel handle */
687        uint16_t                        *timerCnt               /* pointer to count */
688        )
689{
690        BERR_Code               retCode = BERR_SUCCESS;
691        uint32_t                msb = 0, lsb = 0;
692        BICP_Handle             hDev;
693
694        BDBG_ASSERT( hChn );
695        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
696
697        hDev = hChn->hIcp;
698
699        switch (hChn->chnNo)
700        {
701                case 0:
702                        msb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT0MSB);
703                        lsb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT0LSB);
704                        break;
705
706                case 1:
707                        msb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT1MSB);
708                        lsb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT1LSB);
709                        break;
710
711                case 2:
712                        msb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT2MSB);
713                        lsb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT2LSB);
714                        break;
715
716                case 3:
717                        msb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT3MSB);
718                        lsb = BREG_Read32(hDev->hRegister, BCHP_ICAP_TCNT3LSB);
719                        break;
720
721        }
722        *timerCnt = ((uint16_t)msb << 8) | ((uint16_t)lsb);
723
724        return( retCode );
725}
726
727BERR_Code BICP_PollTimer(
728        BICP_ChannelHandle      hChn,                   /* Device channel handle */
729        bool                            *triggered,             /* status of trigger */
730        uint16_t                        *timerCnt               /* pointer to count */
731        )
732{
733        BERR_Code               retCode = BERR_SUCCESS;
734        uint32_t                mask, lval;
735        BICP_Handle             hDev;
736
737        BDBG_ASSERT( hChn );
738        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
739
740        hDev = hChn->hIcp;
741        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_INSTATUS);
742        mask = 1 << hChn->chnNo;
743        *triggered =  (lval & mask) ? true : false;
744        if (*triggered)
745        {
746                /* Reset interrupt pins */
747                BREG_Write32(hDev->hRegister, BCHP_ICAP_RST, mask);
748                BREG_Write32(hDev->hRegister, BCHP_ICAP_RST, 0);
749
750                /* Get the count for caller */
751                BICP_CHK_RETCODE (retCode, BICP_GetTimerCnt (hChn, timerCnt) );
752        }
753
754done:
755        return( retCode );
756}
757
758void BICP_EnableInt(
759        BICP_ChannelHandle      hChn                    /* Device channel handle */
760        )
761{
762        BDBG_ASSERT( hChn );
763        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
764        BICP_P_EnableInt( hChn );
765}
766
767void BICP_DisableInt(
768        BICP_ChannelHandle      hChn                    /* Device channel handle */
769        )
770{
771        BDBG_ASSERT( hChn );
772        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
773        BICP_P_DisableInt( hChn );
774}
775
776void BICP_EnableRC6(
777        BICP_ChannelHandle      hChn,                   /* Device channel handle */
778        BICP_Callback pCallback                 /* Pointer to completion callback. */
779        )
780{
781        BICP_Handle hDev;
782
783        BDBG_ASSERT( hChn );
784        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
785        hChn->handleRC6 = 1;
786        hChn->pInterruptEventUserCallback = pCallback;
787        hDev = hChn->hIcp;
788    hDev->uiRCPinMask |= (1<<hChn->chnNo);
789}
790
791void BICP_DisableRC6(
792        BICP_ChannelHandle      hChn                    /* Device channel handle */
793        )
794{
795        BICP_Handle hDev;
796
797        BDBG_ASSERT( hChn );
798        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
799        hChn->handleRC6 = 0;
800
801        hDev = hChn->hIcp;
802    hDev->uiRCPinMask &= ~(1<<hChn->chnNo);
803}
804
805void BICP_ResetIntCount(
806        BICP_ChannelHandle      hChn                    /* Device channel handle */
807        )
808{
809        BDBG_ASSERT( hChn );
810        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
811        hChn->isrCount = 0;
812}
813
814void BICP_GetIntCount(
815        BICP_ChannelHandle      hChn,                   /* Device channel handle */
816        uint32_t                        *data
817        )
818{
819        BDBG_ASSERT( hChn );
820        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
821        *data = hChn->isrCount;
822}
823
824/*******************************************************************************
825*
826*       Private Module Functions
827*
828*******************************************************************************/
829BERR_Code BICP_P_SetRejectCnt(
830        BICP_ChannelHandle      hChn,                   /* Device channel handle */
831        uint8_t                         clks                    /* number of clocks to reject */
832        )
833{
834        uint32_t        lval;
835        BICP_Handle     hDev;
836        BERR_Code       retCode = BERR_SUCCESS;
837
838        hDev = hChn->hIcp;
839
840        lval = clks - 1;
841        if (lval > MAX_ICAP_RCNT)
842        {
843                retCode = BERR_INVALID_PARAMETER;
844                goto done;
845        }
846
847        switch (hChn->chnNo)
848        {
849                case 0:
850                        BREG_Write32(hDev->hRegister, BCHP_ICAP_RCNT0, lval);
851                        break;
852
853                case 1:
854                        BREG_Write32(hDev->hRegister, BCHP_ICAP_RCNT1, lval);
855                        break;
856
857                case 2:
858                        BREG_Write32(hDev->hRegister, BCHP_ICAP_RCNT2, lval);
859                        break;
860
861                case 3:
862                        BREG_Write32(hDev->hRegister, BCHP_ICAP_RCNT3, lval);
863                        break;
864
865                default:
866                        retCode = BERR_INVALID_PARAMETER;
867                        goto done;
868        }
869
870done:
871        return retCode;
872}
873
874void BICP_P_EnableInt(
875        BICP_ChannelHandle      hChn                    /* Device channel handle */
876        )
877{
878        uint32_t        lval;
879        BICP_Handle     hDev;
880
881        hDev = hChn->hIcp;
882
883        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_MASK);
884        lval |= (1 << hChn->chnNo);
885        BREG_Write32(hDev->hRegister, BCHP_ICAP_MASK, lval);
886
887}
888
889void BICP_P_DisableInt(
890        BICP_ChannelHandle      hChn                    /* Device channel handle */
891        )
892{
893        uint32_t        lval;
894        BICP_Handle     hDev;
895
896        hDev = hChn->hIcp;
897
898        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_MASK);
899        lval &= ~(1 << hChn->chnNo);
900        BREG_Write32(hDev->hRegister, BCHP_ICAP_MASK, lval);
901
902}
903
904void BICP_P_RC6Handle(BICP_ChannelHandle hIcpChan, uint8_t reg)
905{
906        BICP_Handle hDev;
907        uint16_t cur=0;
908        uint32_t len, len1, adj_count;
909        uint8_t ve1, ve2;
910        uint8_t used1, used2;
911        uint8_t found_key = 0;
912
913/* T = 1/36KHZ * 16 = 444.44us, 7115 counter is 27MHz, so T = 12000 ticks
914   1bit data will use 2T with mancherster coding.
915   RC6 data sequence is:
916   Leader: 8T (6T ve+, 2T ve-)
917   Start : 2T (ve+, ve-)
918   Mode  : 6T (3 bits)
919   Trailer:4T (2T ve+, 2T ve-)
920   Control:16T/32T(8bits/16bits, depends on the first bit, 0: 8, 1: 16)
921   Info  : 16T-256T(8bits-128bits)
922*/
923
924        BDBG_ASSERT( hIcpChan );
925        hDev = hIcpChan->hIcp;
926
927    if (reg & hDev->uiRCPinMask){
928                BICP_GetTimerCnt(hIcpChan, &cur);
929
930                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt].ve = 1-hIcpChan->rc6.edge;  /* edge 0: 1->0, ve 1: ve+ */
931                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt].used = 0;
932                if (hIcpChan->rc6.keycnt){      /* now we can tell last ve len */
933                        /* counter is 16 bits, there is chance of wrap around */
934                        if (cur > hIcpChan->rc6.last)
935                                len = cur - hIcpChan->rc6.last;
936                        else{
937                                len = RCCOUNTER - hIcpChan->rc6.last + cur;
938                        }
939
940                        if ((hIcpChan->rc6.keycnt == 1) && (len < 9800 ))/*Fudge delta after a key is found */
941                                len += RCCOUNTER;
942
943                        if (len < TUNIT34)                              /*I bet it is leader bit 6T, wrap around */
944                                len += RCCOUNTER;
945
946                        adj_count = len;
947                        len = adj_count / TUNIT;
948                        if ((adj_count % TUNIT) > (TUNIT/2))
949                                len++;                                          /* round up */
950
951                        /*  Check for invalid lengths and cross check len with state;  */
952                        if ((len == 5) || ((len == 6) && (hIcpChan->rc6.lead) )) {
953                                hIcpChan->rc6.keycnt=0;         /* Start over */
954                                hIcpChan->rc6.edge = 0;
955                                hIcpChan->rc6.last = cur;
956
957                                hIcpChan->rc6.lead = hIcpChan->rc6.start = hIcpChan->rc6.mode = hIcpChan->rc6.trailer = 0;
958                                hIcpChan->rc6.ctrl = hIcpChan->rc6.info = 0;
959                                hIcpChan->rc6.ctrlbits = hIcpChan->rc6.modebits = 0;
960                                return;
961                        }
962
963
964
965
966                        if ((len == 6) && hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].ve)             /* assume found lead bit */
967                        {
968                                hIcpChan->rc6.keybits[0].ve = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].ve;
969                                hIcpChan->rc6.keybits[0].used = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used;
970                                hIcpChan->rc6.keycnt = 1;
971                        }
972
973                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].len = len;
974
975                        if (hIcpChan->rc6.keycnt > 1){
976                                ve1 = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].ve;
977                                len1 = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].len;
978                                used1 = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used;
979                                used2 = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used;
980                                ve2 = hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].ve;
981
982                                if (!used1 && !used2){  /* make sure 2 states captured */
983
984                                        if (!hIcpChan->rc6.lead){
985                                                if ((len1 == 6) && ve1 && (len>1) && !ve2){     /* found lead bit */
986                                                        hIcpChan->rc6.lead = 1;
987                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
988                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
989                                                }
990                                        }
991                                        else if (!hIcpChan->rc6.start){
992                                                if ((len1 == 1) && ve1 && !ve2){
993                                                        hIcpChan->rc6.start = 1;
994                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
995                                                        if (len==1)                             /* next dat is same as current one */
996                                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
997                                                }
998                                        }
999                                        else if (hIcpChan->rc6.mode != 3){
1000                                                hIcpChan->rc6.modebits <<= 1;
1001                                                if (ve1 && !ve2)
1002                                                        hIcpChan->rc6.modebits |= 1;
1003                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
1004                                                if (len==1)                             /* next dat is same as current one */
1005                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
1006                                                hIcpChan->rc6.mode=hIcpChan->rc6.mode+1;
1007                                        }
1008                                        else if (!hIcpChan->rc6.trailer){
1009                                                if ((len1>=2) && (len>=2)){
1010                                                        hIcpChan->rc6.trailer = 1;
1011                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
1012                                                        if (len == 2)   /* next dat is same as current one */
1013                                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
1014                                                }
1015                                        }
1016                                        else if(hIcpChan->rc6.ctrl != hIcpChan->rc6.total_ctrl_bits){
1017                                                hIcpChan->rc6.ctrlbits <<= 1;
1018                                                if (ve1 && !ve2)
1019                                                        hIcpChan->rc6.ctrlbits |= 1;
1020
1021                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
1022                                                if (len==1)                             /* next dat is same as current one */
1023                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
1024
1025                                                if (!hIcpChan->rc6.ctrl){
1026                                                        if (hIcpChan->rc6.ctrlbits)
1027                                                                hIcpChan->rc6.total_ctrl_bits = 16;
1028                                                        else
1029                                                                hIcpChan->rc6.total_ctrl_bits = 8;
1030                                                }
1031
1032                                                hIcpChan->rc6.ctrl++;
1033                                        }
1034                                        else if( hIcpChan->rc6.lead && hIcpChan->rc6.start && hIcpChan->rc6.mode && hIcpChan->rc6.trailer && hIcpChan->rc6.ctrl){       /* it is data now */
1035                                                hIcpChan->rc6.data <<= 1;
1036                                                if (ve1 && !ve2){       /* it is 1 */
1037                                                        hIcpChan->rc6.data |= 1;
1038                                                }
1039                                                if (!ve1 && ve2){       /* it is 0 */
1040                                                }
1041                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-2].used = 1;
1042                                                if (len==1)                             /* next dat is same as current one */
1043                                                        hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
1044                                                hIcpChan->rc6.info++;
1045                                                if (hIcpChan->rc6.info == INFOBITS){    /* got data */
1046                                                        found_key = 1;
1047                                                }
1048                                        }
1049                                        else{
1050                                                BDBG_ERR(("RC6 key something wrong, redo\n"));
1051                                                hIcpChan->rc6.lead = hIcpChan->rc6.start = hIcpChan->rc6.mode = hIcpChan->rc6.trailer = hIcpChan->rc6.ctrl = hIcpChan->rc6.info = 0;
1052                                                hIcpChan->rc6.keycnt = hIcpChan->rc6.ctrlbits = hIcpChan->rc6.modebits = 0;
1053                                                hIcpChan->rc6.edge = 0;
1054                                        }
1055                                }
1056
1057                                /* for last bit == 1, it is ve+ and ve- */
1058                                if ((hIcpChan->rc6.info == INFOBITS-1) && !hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used){         /* this is fake */
1059                                        if (ve2){
1060                                                hIcpChan->rc6.data <<= 1;
1061                                                hIcpChan->rc6.data |= 1;
1062                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt-1].used = 1;
1063                                                hIcpChan->rc6.keybits[hIcpChan->rc6.keycnt].used = 1;
1064                                                found_key = 1;
1065                                        }
1066                                }
1067
1068                        }
1069                }
1070                hIcpChan->rc6.keycnt++;
1071                if ((hIcpChan->rc6.keycnt>4) && !hIcpChan->rc6.lead)
1072                {
1073                        hIcpChan->rc6.keycnt=0;         /* Start over */
1074                        hIcpChan->rc6.edge = 0;
1075                        hIcpChan->rc6.last = 0;
1076
1077                        hIcpChan->rc6.lead = hIcpChan->rc6.start = hIcpChan->rc6.mode = hIcpChan->rc6.trailer = 0;
1078                        hIcpChan->rc6.ctrl = hIcpChan->rc6.info = 0;
1079                        hIcpChan->rc6.ctrlbits = hIcpChan->rc6.modebits = 0;
1080                }
1081                else
1082                {
1083                        hIcpChan->rc6.edge = 1-hIcpChan->rc6.edge;
1084                        hIcpChan->rc6.last = cur;
1085                }
1086        }
1087        if (found_key){
1088                /* Invoke callback */
1089                if( hIcpChan->pInterruptEventUserCallback != NULL )
1090                {
1091                        hIcpChan->pInterruptEventUserCallback( hIcpChan->rc6.ctrlbits, hIcpChan->rc6.modebits, hIcpChan->rc6.data );
1092                }
1093                hIcpChan->rc6.lead = hIcpChan->rc6.start = hIcpChan->rc6.mode = hIcpChan->rc6.trailer = hIcpChan->rc6.ctrl = hIcpChan->rc6.info = 0;
1094                hIcpChan->rc6.keycnt = hIcpChan->rc6.ctrlbits = hIcpChan->rc6.modebits = 0;
1095                hIcpChan->rc6.edge = 0;
1096                hIcpChan->rc6.data = 0;
1097                found_key = 0;
1098        }
1099}
1100
1101static void BICP_P_HandleInterrupt_Isr
1102(
1103        void *pParam1,                                          /* Device channel handle */
1104        int parm2                                                       /* not used */
1105)
1106{
1107        BICP_ChannelHandle      hChn;
1108        BICP_Handle             hDev;
1109        uint32_t                        lval;
1110        uint32_t                        mask;
1111
1112        hChn = (BICP_ChannelHandle) pParam1;
1113        BDBG_ASSERT( hChn );
1114
1115        hDev = hChn->hIcp;
1116
1117        /* Read interrupt status register */
1118        lval = BREG_Read32(hDev->hRegister, BCHP_ICAP_INSTATUS);
1119
1120        /* Is this interrupt for this channel? */
1121        mask = lval & parm2;
1122
1123        if (!mask)
1124                return;
1125
1126        hChn->isrCount++;
1127
1128        /* Reset interrupt pins */
1129        BREG_Write32(hDev->hRegister, BCHP_ICAP_RST, mask);
1130        BREG_Write32(hDev->hRegister, BCHP_ICAP_RST, 0);
1131
1132        if (hChn->handleRC6)
1133        {
1134                BICP_P_RC6Handle(hChn, (unsigned char)(lval & 0xf));
1135        }
1136
1137        BKNI_SetEvent( hChn->hChnEvent );
1138        return;
1139}
1140
Note: See TracBrowser for help on using the repository browser.