source: svn/newcon3bcm2_21bu/magnum/portinginterface/vsb/3520/bvsb_3520_priv.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 93.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2004-2009, 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: bvsb_3520_priv.c $
11 * $brcm_Revision: Hydra_Software_Devel/29 $
12 * $brcm_Date: 9/16/09 4:04p $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/vsb/3520/bvsb_3520_priv.c $
19 *
20 * Hydra_Software_Devel/29   9/16/09 4:04p mward
21 * SW7400-2468: Initialize pin_ctrl in
22 * BVSB_3520_P_SetOobInterfaceControl() to eliminate compiler warning in
23 * DEBUG=n build.
24 *
25 * Hydra_Software_Devel/28   6/24/09 9:04p dliu
26 * PR55792: Coverity fix
27 *
28 * Hydra_Software_Devel/27   5/19/09 11:10a dliu
29 * PR55183: Add OOB lock interrupts
30 *
31 * Hydra_Software_Devel/26   4/16/09 11:12a dliu
32 * PR54206: Coverity fix
33 *
34 * Hydra_Software_Devel/25   3/24/09 3:38p dliu
35 * PR53219: Add OOB control for 3520
36 *
37 * Hydra_Software_Devel/24   5/6/08 11:07a dliu
38 * PR33752: Only clear IE2 when interrupt is being used
39 *
40 * Hydra_Software_Devel/23   8/2/07 5:14p dliu
41 * PR33752: Make sure IE2 is cleared before sending HAB commands
42 *
43 * Hydra_Software_Devel/22   4/18/07 4:06p dliu
44 * PR29191: Check that QAM annex A symbol rate is less than 8 Mhz,
45 * otherwise it cause AP to crash
46 *
47 * Hydra_Software_Devel/21   2/13/07 12:03p dliu
48 * PR27857: Add Set_IFFreq function
49 *
50 * Hydra_Software_Devel/20   1/24/07 1:04p dliu
51 * PR27326: Added QAM128 and QAM 512 Modes
52 *
53 * Hydra_Software_Devel/19   11/20/06 10:25a dliu
54 * PR25214: Clean up compiler warnings
55 *
56 * Hydra_Software_Devel/18   11/14/06 11:29a dliu
57 * PR 25214: Add BVSB_3520_P_GetChipRevision function implementation
58 *
59 * Hydra_Software_Devel/17   7/26/06 1:34p dliu
60 * PR22759: Change Mi2c read to use Write - Fake read - read. This is a
61 * software work around for Bcm3520 B0 mi2c bug
62 *
63 * Hydra_Software_Devel/16   7/5/06 7:31p vle
64 * PR 22314, PR 19529: Add symbol rate for QAM Annex A
65 *
66 * Hydra_Software_Devel/15   6/23/06 2:39p dliu
67 * PR22314: Added Symbolrate to QAM input parameters
68 *
69 * Hydra_Software_Devel/14   7/22/05 11:04a enavarro
70 * PR 16398: initialize retCode in BVSB_3520_P_WriteMemory()
71 *
72 * Hydra_Software_Devel/13   5/23/05 10:30a enavarro
73 * PR 15567: changed units for if_agc/rf_agc to 1/10 percent
74 *
75 * Hydra_Software_Devel/12   4/7/05 9:45a enavarro
76 * PR 14698: fix compiler warning for unused parameter
77 *
78 * Hydra_Software_Devel/11   3/29/05 9:54a enavarro
79 * PR 14240: renamed ifFreq in BVSB_NtscStatus struct to pixCarrFreq
80 *
81 * Hydra_Software_Devel/10   2/17/05 3:06p enavarro
82 * PR 13901: fixed format error in OOB Acquire HAB command
83 *
84 * Hydra_Software_Devel/9   2/14/05 9:42a enavarro
85 * PR 14005: fixed compiler warning in BVSB_3520_P_Open()
86 *
87 * Hydra_Software_Devel/8   2/1/05 9:43a enavarro
88 * PR 14005: pass in BINT_Handle to BVSB_Open()
89 *
90 * Hydra_Software_Devel/7   1/26/05 11:58a enavarro
91 * PR 13901: OOB HAB command changes
92 *
93 * Hydra_Software_Devel/6   1/24/05 4:12p enavarro
94 * PR 13894: implemented BVSB_3520_P_Mi2cRead()
95 *
96 * Hydra_Software_Devel/5   1/5/05 4:52p enavarro
97 * PR 13753: removed C++ style comments; removed unused labels
98 *
99 * Hydra_Software_Devel/4   10/20/04 4:18p enavarro
100 * PR 12857: updates to OOB_STATUS HAB command format
101 *
102 * Hydra_Software_Devel/3   10/20/04 2:56p enavarro
103 * PR 12857: reworked BVSB_3520_P_ServiceHab() and
104 * BVSB_3520_P_DecodeInterrupt(); no need to disable/enable L1 interrupt
105 * in BVSB_3520_P_EnableInitDoneInterrupt()
106 *
107 * Hydra_Software_Devel/2   10/1/04 3:25p brianlee
108 * PR12857: Modified code to comform to magnum coding convention.
109 *
110 ***************************************************************************/
111
112#include "bstd.h"
113#include "bchp_3520.h"
114#include "bi2c.h"
115#include "bvsb.h"
116#include "bvsb_priv.h"
117#include "bvsb_3520_priv.h"
118
119//add Mutex for Tuner
120#include "bkni_multi.h"
121
122BKNI_MutexHandle test_mutex = NULL;
123
124BDBG_MODULE(bvsb_3520_priv);
125
126
127/******************************************************************************
128 BVSB_3520_P_Open()
129******************************************************************************/
130BERR_Code BVSB_3520_P_Open(
131   BVSB_Handle *h,       /* [out] BVSB handle */
132   BCHP_Handle hChip,    /* [in] chip handle */
133   void        *pReg,    /* [in] pointer to register or i2c handle */
134   BINT_Handle hInterrupt,    /* [in] Interrupt handle */   
135   const BVSB_Settings *pDefSettings /* [in] default settings */
136)
137{
138   BERR_Code retCode;
139   BVSB_Handle hDev;
140   BVSB_3520_P_Handle *h3520Dev;
141   BERR_Code  err= BERR_SUCCESS;
142   
143   BSTD_UNUSED(hInterrupt);
144   BSTD_UNUSED(hChip);
145
146   BDBG_MSG(("%s enter\n", __func__));
147
148   BDBG_ASSERT(pDefSettings->i2c.interruptEnableFunc);
149
150   /* allocate memory for the handle */
151   hDev = (BVSB_Handle)BKNI_Malloc(sizeof(BVSB_P_Handle));
152   BDBG_ASSERT(hDev);
153   *h = hDev;
154
155   h3520Dev = (BVSB_3520_P_Handle *)BKNI_Malloc(sizeof(BVSB_3520_P_Handle));
156   BDBG_ASSERT(h3520Dev);
157   hDev->pImpl = (void*)h3520Dev;
158
159   /* initialize our handle */
160   h3520Dev->hRegister = (BREG_I2C_Handle)pReg;
161   BKNI_Memcpy((void*)(&(hDev->settings)), (void*)pDefSettings, sizeof(BVSB_Settings));
162
163   /* create events */
164   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hInterruptEvent)));
165   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hApiEvent)));
166   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hLockChangeEvent)));
167   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hOobLockChangeEvent)));
168   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hInitDoneEvent)));
169   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hHabDoneEvent)));
170   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hAntennaEvent)));
171   BVSB_CHK_RETCODE(BKNI_CreateEvent(&(h3520Dev->hBscEvent)));
172
173   h3520Dev->last_page_16_15 = 0xFF;
174   h3520Dev->last_page_14_7 = 0xFF;
175   h3520Dev->last_mbox_15_8 = 0xFF;
176   h3520Dev->last_bsc_slave_addr = 0xFF;
177
178   retCode = BVSB_3520_P_DisableInterrupts(hDev);
179
180   err = BKNI_CreateMutex(&test_mutex);
181   
182   done:
183   BDBG_MSG(("%s leave (retCode=%d)\n", __func__, retCode));
184   return retCode;
185}
186
187
188/******************************************************************************
189 BVSB_3520_P_Close()
190******************************************************************************/
191BERR_Code BVSB_3520_P_Close(BVSB_Handle h)
192{
193   BERR_Code retCode;
194
195   BDBG_ASSERT(h);
196
197   retCode = BVSB_3520_P_DisableInterrupts(h);
198   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hInterruptEvent);
199   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hApiEvent);
200   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hLockChangeEvent);
201   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hOobLockChangeEvent);
202   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hInitDoneEvent);
203   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hHabDoneEvent);
204   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hAntennaEvent);
205   BKNI_DestroyEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hBscEvent);
206   BKNI_Free((void*)h->pImpl);
207   BKNI_Free((void*)h);
208
209   return retCode;
210}
211
212
213/******************************************************************************
214 BVSB_3520_P_InitAp()
215******************************************************************************/
216BERR_Code BVSB_3520_P_InitAp(
217   BVSB_Handle h,            /* [in] BVSB handle */
218   const uint8_t *pHexImage  /* [in] pointer to BCM3520 microcode image */
219)
220{
221   BERR_Code retCode;
222   uint16_t n, addr;
223   uint8_t *pImage;
224   uint8_t sb, retries;
225
226   /* disable interrupts */
227   BVSB_CHK_RETCODE(BVSB_3520_P_DisableInterrupts(h));
228   BVSB_CHK_RETCODE(BVSB_3520_P_EnableHostInterrupt(h, false));
229
230   /* reset the AP before downloading the microcode */
231   BVSB_CHK_RETCODE(BVSB_3520_P_ResetAp(h));
232
233   /* download to RAM */
234   pImage = (uint8_t*)pHexImage;
235   while (1)
236   {
237      n = (*pImage++ << 8);
238      n |= *pImage++;
239
240      if (n == 0)
241         break;
242
243      addr = (*pImage++ << 8);
244      addr |= *pImage++;
245
246      for (retries = 0; retries < 3; retries++)
247      {
248         BVSB_CHK_RETCODE(BVSB_3520_P_WriteMemory(h, addr, (uint8_t *)pImage, n));
249         pImage += n; 
250
251         /* check for host transfer error */
252         BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_STAT1, &sb));
253         if ((sb & BCM3520_STAT1_H_ER) == 0)
254            break;
255           
256         BDBG_WRN(("host transfer error\n"));
257         BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT1, &sb));
258      }
259   }
260   
261   /* enable init done interrupt */
262   BVSB_CHK_RETCODE(BVSB_3520_P_EnableInitDoneInterrupt(h));
263
264   /* clear H_STAT1 */
265   sb = 0xFF;
266   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT1, &sb));
267
268   /* start running the AP */
269   if ((retCode = BVSB_3520_P_RunAp(h)) != BERR_SUCCESS)
270      goto done;
271
272   /* wait for init done interrupt */
273   /*RLQ, ACB613 use 3520 A1 chip, and this chip sounds like need more delay on AP initialization */
274   //if (BVSB_3520_P_WaitForEvent(h, ((BVSB_3520_P_Handle *)(h->pImpl))->hInitDoneEvent, 10) != BERR_SUCCESS)
275   if (BVSB_3520_P_WaitForEvent(h, ((BVSB_3520_P_Handle *)(h->pImpl))->hInitDoneEvent, 50) != BERR_SUCCESS)
276   {
277      BDBG_ERR(("AP initialization timeout\n")); 
278      BERR_TRACE(retCode = BVSB_ERR_AP_NOT_INIT);           
279   }
280
281#if 0
282   /* clear lock interrupts */
283   sb = BCM3520_STAT2_LOCK_MASK;
284   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT2, &sb));
285#endif
286
287   done:
288   return retCode;
289}
290
291
292/******************************************************************************
293 BVSB_3520_P_GetApStatus()
294******************************************************************************/
295BERR_Code BVSB_3520_P_GetApStatus(
296   BVSB_Handle h,           /* [in] VSB device handle */
297   BVSB_ApStatus *pStatus   /* [out] AP status */
298)
299{
300   BERR_Code retCode;
301   uint8_t buf[3];
302
303   *pStatus = 0;
304   BVSB_CHK_RETCODE(BREG_I2C_Read(((BVSB_3520_P_Handle *)(h->pImpl))->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_CTL1, buf, 3));
305   *pStatus = buf[0] | (buf[1] << 8) | (buf[2] << 16);
306   
307   done:
308   return retCode;
309}
310
311
312/******************************************************************************
313 BVSB_3520_P_GetApVersion()
314******************************************************************************/
315BERR_Code BVSB_3520_P_GetApVersion(
316   BVSB_Handle h,          /* [in] BVSB handle */
317   uint16_t    *pChipId,   /* [out] BVSB chip ID */
318   uint16_t    *pChipVer,  /* [out] chip revision number */
319   uint8_t     *pApVer,    /* [out] AP microcode version */
320   uint8_t     *pScrVer,   /* [out] acquisition script version */
321   uint8_t     *pCfgVer    /* [out] host configuration version */
322)
323{
324   BERR_Code retCode;
325   uint8_t buf[16];
326
327   buf[0] = 0x09;
328   buf[14] = 0x00;
329   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 15, buf, 14, true));
330
331   *pChipId = ((buf[1] << 8) | buf[2]);
332   *pChipVer = ((buf[3] << 8) | buf[4]);
333   *pApVer = buf[5];
334   *pScrVer = buf[6];
335   *pCfgVer = buf[7];
336
337   done:
338   return retCode;
339}
340
341
342/******************************************************************************
343 BVSB_3520_P_ReadRegister()
344******************************************************************************/
345BERR_Code BVSB_3520_P_ReadRegister(
346   BVSB_Handle h,     /* [in] BVSB handle */
347   uint32_t    reg,   /* [in] address of register to read */
348   uint32_t    *val   /* [in] contains data that was read */
349)
350{
351   BERR_Code retCode;
352   uint8_t sb;
353
354   if ((reg >= 0x80) && (reg <= 0xFF))
355   {
356      /* accessing host register space */
357      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, reg, &sb));
358      *val = (uint32_t)sb;
359   }
360   else
361   {
362      /* accessing internal registers through io_mbox */
363      BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, (uint16_t)reg, val));
364   }
365
366   done:
367   return retCode;
368}
369
370
371/******************************************************************************
372 BVSB_3520_P_WriteRegister()
373******************************************************************************/
374BERR_Code BVSB_3520_P_WriteRegister(
375   BVSB_Handle h,     /* [in] BVSB handle */
376   uint32_t    reg,   /* [in] address of register to read */
377   uint32_t    *val   /* [in] contains data that was read */
378)
379{
380   BERR_Code retCode;
381   uint8_t sb;
382
383   if ((reg >= 0x80) && (reg <= 0xFF))
384   {
385      /* accessing host register space */
386      sb = (uint8_t)(*val);
387      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, reg, &sb));
388   }
389   else
390   {
391      /* accessing internal registers through io_mbox */
392      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, (uint16_t)reg, val));
393   }
394
395   done:
396   return retCode;
397}
398
399
400/******************************************************************************
401 BVSB_3520_P_Mi2cWrite()
402******************************************************************************/ 
403BERR_Code BVSB_3520_P_Mi2cWrite(
404   BVSB_Handle h,      /* [in] BVSB handle */
405   uint8_t slave_addr, /* [in] address of the i2c slave device */
406   uint8_t *buf,       /* [in] specifies the data to transmit */
407   uint8_t n           /* [in] number of bytes to transmit after the i2c slave address */
408)
409{
410   BERR_Code retCode;
411   int idx;
412   uint32_t mb, in0_3, in4_7, cnt, iic_enable;
413   bool bFirstTime, bWrite4_7;
414   BERR_Code  err= BERR_SUCCESS;
415
416   err = BKNI_AcquireMutex(test_mutex);
417   //printf("\n<<< %x ",err);
418
419   mb = 0;
420   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &mb)); 
421
422   if (((BVSB_3520_P_Handle *)(h->pImpl))->last_bsc_slave_addr != slave_addr)
423   {
424      mb = (uint32_t)slave_addr;
425      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CHIP_ADDRESS, &mb)); 
426      ((BVSB_3520_P_Handle *)(h->pImpl))->last_bsc_slave_addr = slave_addr;
427   }
428
429   /* 400 KHz, write only */
430   mb = 0x10;
431   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CTL_REG, &mb));
432
433   idx = 0;
434   in0_3 = 0;
435   in4_7 = 0;
436   bFirstTime = true;
437   while (n > 0)
438   {
439      bWrite4_7 = false;
440      in0_3 = buf[idx] << 24;
441      if (n > 1)
442         in0_3 |= (buf[idx+1] << 16);
443      if (n > 2)
444         in0_3 |= (buf[idx+2] << 8);
445      if (n > 3)
446         in0_3 |= buf[idx+3];
447      if (n > 4)
448      {
449         bWrite4_7 = true;
450         in4_7 = (buf[idx+4] << 24);
451      }
452      if (n > 5)
453         in4_7 |= (buf[idx+5] << 16);
454      if (n > 6)
455         in4_7 |= (buf[idx+6] << 8);
456      if (n > 7)
457         in4_7 |= buf[idx+7];
458
459      if (n >= 8) 
460         cnt = 8;
461      else
462         cnt = n;
463
464      n -= cnt;
465      idx += cnt;
466 
467      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_DATA_IN0_3, &in0_3));
468      if (bWrite4_7)
469      {
470         BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_DATA_IN4_7, &in4_7));
471      }
472      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CNT_REG, &cnt));
473
474      iic_enable = 1;
475      if (bFirstTime == false)
476         iic_enable |= 0x20;  /* no start condition */
477      else
478         bFirstTime = false;
479      if (n > 0)
480         iic_enable  |= 0x10;   /* no stop condition */
481      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
482   
483      do
484      {
485         BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
486      } while ((iic_enable & 0x06) == 0);
487      if (iic_enable & 0x04)
488      {
489                 BKNI_ReleaseMutex(test_mutex);
490         BDBG_ERR(("BVSB: no ack from tuner iic_enable = 0x%08x\n",iic_enable));
491         return (BERR_TRACE(BVSB_ERR_MI2C_NO_ACK));
492      }
493   }
494
495   //printf(">>>\n");
496        BKNI_ReleaseMutex(test_mutex);
497
498   done:
499   return retCode;
500}
501
502
503/******************************************************************************
504 BVSB_3520_P_Mi2cRead()
505******************************************************************************/
506BERR_Code BVSB_3520_P_Mi2cRead(
507   BVSB_Handle h,      /* [in] BVSB handle */
508   uint8_t slave_addr, /* [in] address of the i2c slave device */
509   uint8_t *out_buf,   /* [in] specifies the data to transmit before the i2c restart condition */
510   uint8_t out_n,      /* [in] number of bytes to transmit before the i2c restart condition not including the i2c slave address */
511   uint8_t *in_buf,    /* [out] holds the data read */
512   uint8_t in_n        /* [in] number of bytes to read after the i2c restart condition not including the i2c slave address */
513)
514{
515   BERR_Code retCode = BERR_SUCCESS;
516   int idx;
517   uint32_t mb, in0_3, in4_7, out0_3, out4_7, iic_enable;
518   bool bWrite4_7, bRead4_7;
519   uint8_t n;
520   BERR_Code  err= BERR_SUCCESS;
521
522
523   err = BKNI_AcquireMutex(test_mutex);
524
525   //printf("\n@@@ %x ",err);
526
527   if ((out_n > 8) || (in_n < 1)){
528           BKNI_ReleaseMutex(test_mutex);
529      return BERR_INVALID_PARAMETER; 
530   }
531     
532   mb = 0;
533   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &mb)); 
534
535   if (((BVSB_3520_P_Handle *)(h->pImpl))->last_bsc_slave_addr != slave_addr)
536   {
537      mb = (uint32_t)slave_addr;
538      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CHIP_ADDRESS, &mb)); 
539      ((BVSB_3520_P_Handle *)(h->pImpl))->last_bsc_slave_addr = slave_addr;
540   }
541
542   /* transmit data*/
543   if ( out_n )
544   {
545      mb = 0x10; /* Issue write only, 400 kHz */
546      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CTL_REG, &mb));   
547
548      idx = 0;
549      in0_3 = 0;
550      in4_7 = 0;
551      bWrite4_7 = false;
552      in0_3 = out_buf[idx] << 24;
553
554      if ( out_n > 1 )
555         in0_3 |= (out_buf[idx+1] << 16);
556      if (out_n > 2)
557         in0_3 |= (out_buf[idx+2] << 8);
558      if (out_n > 3)
559         in0_3 |= out_buf[idx+3];
560      if (out_n > 4)
561      {
562         bWrite4_7 = true;
563         in4_7 = out_buf[idx+4] << 24;
564      }
565      if (out_n > 5)
566         in4_7 |= (out_buf[idx+5] << 16);
567      if (out_n > 6)
568         in4_7 |= (out_buf[idx+6] << 8);
569      if (out_n > 7)
570         in4_7 |= out_buf[idx+7];
571
572      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_DATA_IN0_3, &in0_3));
573      if (bWrite4_7)
574      {
575         BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_DATA_IN4_7, &in4_7));
576      }
577
578      /* Write cnt register */
579      mb = out_n;
580      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CNT_REG, &mb));
581
582      /* Issue send command */
583      iic_enable = 1;
584      iic_enable |= 0x10;   /* no stop condition */
585      iic_enable |= 0x40;   /* restart condition */
586      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
587
588      do
589      {
590         BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
591      } while ((iic_enable & 0x06) == 0);
592
593      if (iic_enable & 0x04)
594      {
595         BDBG_ERR(("BVSB: no ack from tuner\n"));
596                  BKNI_ReleaseMutex(test_mutex);
597         return (BERR_TRACE(BVSB_ERR_MI2C_NO_ACK));
598      }
599   }
600
601   /* issue fake read to work around hardware bug*/
602   iic_enable = 0;
603   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
604
605   mb = 0x11; /* Issue read-only */
606   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CTL_REG, &mb));   
607
608   mb = 0x0; /* Not really reading anything */
609   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CNT_REG, &mb));   
610
611   iic_enable = 1;
612   iic_enable |= 0x10;   /* no stop condition */
613   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
614   
615   do
616   {
617      BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
618   } while ((iic_enable & 0x06) == 0);
619   if (iic_enable & 0x04)
620   {
621      BDBG_ERR(("BVSB: no ack from tuner\n"));
622           BKNI_ReleaseMutex(test_mutex);
623      return (BERR_TRACE(BVSB_ERR_MI2C_NO_ACK));
624   }
625   /* end of fake read section */   
626   
627   /* Finally read the data */
628   idx = 0;
629
630   iic_enable = 0;
631   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
632
633   mb = 0x11; /* Issue read-only, 400 kHz */
634   BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CTL_REG, &mb));   
635
636   while (in_n > 0)
637   {
638      if (in_n > 8)
639         n = 8;
640      else
641         n = in_n;
642
643      if (n > 4)
644         bRead4_7 = true;
645      else
646         bRead4_7 = false;
647
648      in_n -= n;
649
650      /* Set number of bytes to read */
651      mb = n;
652      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_CNT_REG, &mb));   
653
654      iic_enable = 1;
655      iic_enable |= 0x20;   /* no start condition because we issued a fake read */
656
657      if ( in_n > 0 )
658         iic_enable |= 0x10; /* no stop condition if we want to continue */
659
660      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
661
662      do
663      {
664         BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
665      } while ((iic_enable & 0x06) == 0);
666      if (iic_enable & 0x04)
667      {
668         BDBG_ERR(("BVSB: no ack from tuner\n"));
669                  BKNI_ReleaseMutex(test_mutex);
670         return (BERR_TRACE(BVSB_ERR_MI2C_NO_ACK));
671      }
672
673      BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_DATA_OUT0_3, &out0_3));
674      in_buf[idx++] = (out0_3 >> 24) & 0xFF;
675      if (n > 1)
676         in_buf[idx++] = (out0_3 >> 16) & 0xFF;
677      if (n > 2)
678         in_buf[idx++] = (out0_3 >> 8) & 0xFF;
679      if (n > 3)
680         in_buf[idx++] = out0_3 & 0xFF;
681
682      if (bRead4_7)
683      {
684         BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox(h, BCM3520_BSC_DATA_OUT4_7, &out4_7));
685         in_buf[idx++] = (out4_7 >> 24) & 0xFF;
686         if (n > 5)
687            in_buf[idx++] = (out4_7 >> 16) & 0xFF;
688         if (n > 6)
689            in_buf[idx++] = (out4_7 >> 8) & 0xFF;
690         if (n > 7)
691            in_buf[idx++] = out4_7 & 0xFF;
692      }
693
694      iic_enable = 0;
695      BVSB_CHK_RETCODE(BVSB_3520_P_WriteMbox(h, BCM3520_BSC_IIC_ENABLE, &iic_enable));
696   }
697
698   //printf("$$$\n");
699   BKNI_ReleaseMutex(test_mutex);
700       
701   done:
702   return retCode;
703}
704
705
706/******************************************************************************
707 BVSB_3520_P_AcquireInband()
708******************************************************************************/
709BERR_Code BVSB_3520_P_AcquireInband(
710   BVSB_Handle h,                    /* [in] BVSB handle */
711   const BVSB_InbandParams *pParams  /* [in] inband acquisition parameters */
712)
713{   
714   BERR_Code retCode;
715
716   BDBG_ASSERT(h);
717   BDBG_ASSERT(pParams);
718
719   BDBG_MSG(("%s enter\n", __func__));
720
721   BVSB_CHK_RETCODE(BVSB_3520_P_EnableLockInterrupt(h, false));
722   
723   switch (pParams->mode)
724   {
725      case BVSB_InbandMode_e8VSB:      /* 8-VSB */
726       case BVSB_InbandMode_e16VSB:     /* 16-VSB */
727         BVSB_CHK_RETCODE(BVSB_3520_P_AcquireVsb(h, pParams));
728         break;
729
730      case BVSB_InbandMode_e1024QAM_B: /* 1024-QAM Annex B */
731      case BVSB_InbandMode_e512QAM_B: /* 512-QAM Annex B */
732      case BVSB_InbandMode_e256QAM_B:  /* 256-QAM Annex B */
733      case BVSB_InbandMode_e128QAM_B: /* 128-QAM Annex B */
734      case BVSB_InbandMode_e64QAM_B:   /* 64-QAM Annex B  */
735      case BVSB_InbandMode_e256QAM_A:  /* 256-QAM Annex A */
736      case BVSB_InbandMode_e128QAM_A:  /* 128-QAM Annex A */
737      case BVSB_InbandMode_e64QAM_A:   /* 64-QAM Annex A  */
738      case BVSB_InbandMode_e32QAM_A:   /* 32-QAM Annex A  */
739      case BVSB_InbandMode_e16QAM_A:   /* 16-QAM Annex A  */
740         BVSB_CHK_RETCODE(BVSB_3520_P_AcquireQam(h, pParams));
741         break;
742
743      case BVSB_InbandMode_eNTSC:      /* NTSC */
744         BVSB_CHK_RETCODE(BVSB_3520_P_AcquireNtsc(h, pParams));
745         break;
746
747      default:
748         return (BERR_TRACE(BERR_INVALID_PARAMETER)); 
749   }
750
751   BVSB_CHK_RETCODE(BVSB_3520_P_EnableLockInterrupt(h, true));
752
753   done:
754   BDBG_MSG(("%s leave, retCode=%d\n", __func__, retCode));
755   return retCode;
756}
757
758
759/******************************************************************************
760 BVSB_3520_P_GetVsbStatus()
761******************************************************************************/
762BERR_Code BVSB_3520_P_GetVsbStatus(
763   BVSB_Handle h,           /* [in] BVSB handle */
764   BVSB_VsbStatus *pStatus  /* [out] VSB status */
765)
766{
767   BERR_Code retCode;
768   uint8_t   buf[128];
769
770   BDBG_MSG(("%s enter\n", __func__));
771
772   buf[0] = 0x1E;
773   buf[0x3D] = 0x00;
774   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
775   {
776      BDBG_WRN(("HAB not available\n"));
777      goto done;
778   }
779   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, buf, 1));
780   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x3D, &buf[0x3D], 1));
781   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, buf, 0x3D, true, 0x9E));
782
783   switch ((buf[2] >> 4) & 0x07)
784   {
785      case 0:
786         pStatus->acqParams.mode = BVSB_InbandMode_e8VSB;
787         break;
788         
789      case 4:
790         pStatus->acqParams.mode = BVSB_InbandMode_e16VSB;
791         break;
792         
793      default:
794         pStatus->acqParams.mode = BVSB_InbandMode_eUnknown;
795         break;
796   }
797   
798   switch ((buf[2] >> 1) & 0x03)
799   {
800      case 0:
801         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eLow;
802         break;
803      case 1:
804         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eMedium;
805         break;
806      default:
807         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eHigh;
808         break;
809   }
810   
811   pStatus->acqParams.symbolRateOffset = (int32_t)((int16_t)((buf[0x08] << 8) + buf[0x09]));
812   pStatus->acqParams.ifFreqOffset = (int32_t)((buf[0x04] << 24) + (buf[0x05] << 16) + (buf[0x06] << 8) + buf[0x07]);
813   pStatus->acqSettings.bAutoAcq = buf[0x01] & 0x20 ? true : false;
814   pStatus->acqSettings.bFastAcq = buf[0x01] & 0x01 ? true : false;
815   pStatus->acqSettings.bTei = buf[0x02] & 0x01 ? true : false;
816   pStatus->acqSettings.bTerr = buf[0x02] & 0x80 ? true : false;
817   pStatus->acqSettings.bNtscSweep = buf[0x01] & 0x08 ? true : false;
818   pStatus->acqSettings.bRfiSweep = buf[0x01] & 0x04 ? true : false;
819
820   pStatus->bFecLocked = buf[0x12] & 0x04 ? true : false;
821   pStatus->bPllLocked = buf[0x12] & 0x02 ? true : false;
822   pStatus->bNtscEngaged = buf[0x12] & 0x20 ? true : false;
823   pStatus->bRfiEngaged = buf[0x12] & 0x10 ? true : false;
824   pStatus->ifFreq = (buf[0x0A] << 24) + (buf[0x0B] << 16) + (buf[0x0C] << 8) + buf[0x0D];
825   pStatus->ifFreqError = (int32_t)((buf[0x17] << 24) + (buf[0x18] << 16) + (buf[0x19] << 8) + buf[0x1A]);
826   pStatus->symbolRate = (int32_t)((buf[0x0E] << 24) + (buf[0x0F] << 16) + (buf[0x10] << 8) + buf[0x11]);
827   pStatus->symbolRateError = (int32_t)((int16_t)((buf[0x1B] << 8) + buf[0x1C]));
828   pStatus->corrErrCount = (buf[0x29] << 24) + (buf[0x2A] << 16) + (buf[0x2B] << 8) + buf[0x2C];
829   pStatus->corrBlockCount = (buf[0x2D] << 24) + (buf[0x2E] << 16) + (buf[0x2F] << 8) + buf[0x30];
830   pStatus->ucorrBlockCount = (buf[0x31] << 24) + (buf[0x32] << 16) + (buf[0x33] << 8) + buf[0x34];
831   pStatus->cleanBlockCount = (buf[0x35] << 24) + (buf[0x36] << 16) + (buf[0x37] << 8) + buf[0x38];
832   pStatus->berCount = (buf[0x25] << 24) + (buf[0x26] << 16) + (buf[0x27] << 8) + buf[0x28];
833   pStatus->snr = (buf[0x13] << 8) + buf[0x14];
834   pStatus->agf = (buf[0x1D] << 8) + buf[0x1E];
835   pStatus->rf_agc = (((buf[0x1F] << 8) + buf[0x20]) * 1000) / 65535;
836   pStatus->if_agc = (((buf[0x21] << 8) + buf[0x22]) * 1000) / 65535;
837   pStatus->reacqCount = (buf[0x39] << 24) + (buf[0x3A] << 16) + (buf[0x3B] << 8) + buf[0x3C];
838
839   BDBG_MSG(("%s leave, retCode=%d\n", __func__, retCode));
840
841   done:
842   return retCode;
843}
844
845
846/******************************************************************************
847 BVSB_3520_P_GetQamStatus()
848******************************************************************************/
849BERR_Code BVSB_3520_P_GetQamStatus(
850   BVSB_Handle h,           /* [in] BVSB handle */
851   BVSB_QamStatus *pStatus  /* [out] QAM status   */
852)
853{
854   BERR_Code retCode;
855   uint8_t   buf[128];
856
857   if (pStatus == NULL)
858      return (BERR_TRACE(BERR_INVALID_PARAMETER));
859     
860   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
861   {
862      BDBG_WRN(("HAB not available\n"));
863      goto done;
864   }
865
866   buf[0] = 0x20;
867   buf[0x3D] = 0x00;
868   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, buf, 1));
869   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x3D, &buf[0x3D], 1));
870   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, buf, 0x3D, true, 0xA0));
871
872   if (buf[2] & 0x08)
873   {
874      /* annex B */
875      switch ((buf[2] >> 4) & 0x07)
876      {
877         case 3:
878            pStatus->acqParams.mode = BVSB_InbandMode_e64QAM_B;
879            break;
880         case 4:
881            pStatus->acqParams.mode = BVSB_InbandMode_e128QAM_B;
882                        break;
883         case 5:
884            pStatus->acqParams.mode = BVSB_InbandMode_e256QAM_B;
885            break;
886         case 6:
887            pStatus->acqParams.mode = BVSB_InbandMode_e512QAM_B;
888            break;
889         default:
890            pStatus->acqParams.mode = BVSB_InbandMode_e1024QAM_B;
891            break;
892      }     
893   }
894   else
895   {
896      /* annex A */
897      switch ((buf[2] >> 4) & 0x07)
898      {
899         case 1:
900            pStatus->acqParams.mode = BVSB_InbandMode_e16QAM_A;
901            break;
902         
903         case 2:
904            pStatus->acqParams.mode = BVSB_InbandMode_e32QAM_A;
905            break;
906         
907         case 3:
908            pStatus->acqParams.mode = BVSB_InbandMode_e64QAM_A;
909            break;
910         
911         case 4:
912            pStatus->acqParams.mode = BVSB_InbandMode_e128QAM_A;
913            break;
914         
915         default:
916            pStatus->acqParams.mode = BVSB_InbandMode_e256QAM_A;
917            break;
918      }           
919   }
920   
921   switch ((buf[1] >> 6) & 0x03)
922   {
923      case 0:
924         pStatus->acqSettings.nyquist = BVSB_NyquistFilter_e12;
925         break;
926
927      case 1:
928         pStatus->acqSettings.nyquist = BVSB_NyquistFilter_e15;
929         break;
930
931      default:
932         pStatus->acqSettings.nyquist = BVSB_NyquistFilter_e18;
933         break;
934   }
935
936   switch ((buf[2] >> 1) & 0x03)
937   {
938      case 0:
939         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eLow;
940         break;
941      case 1:
942         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eMedium;
943         break;
944      default:
945         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eHigh;
946         break;
947   }
948   
949   switch ((buf[3] >> 4) & 0x0F)
950   {
951      case 0:
952         pStatus->acqSettings.idepth = BVSB_IDepth_e204_1;
953         break;
954         
955      case 1:
956         pStatus->acqSettings.idepth = BVSB_IDepth_e102_2;
957         break;
958         
959      case 2:
960         pStatus->acqSettings.idepth = BVSB_IDepth_e68_3;
961         break;
962         
963      case 3:
964         pStatus->acqSettings.idepth = BVSB_IDepth_e51_4;
965         break;
966         
967      case 4:
968         pStatus->acqSettings.idepth = BVSB_IDepth_e34_6;
969         break;
970         
971      case 5:
972         pStatus->acqSettings.idepth = BVSB_IDepth_e17_12;
973         break;
974         
975      case 6:
976         pStatus->acqSettings.idepth = BVSB_IDepth_e12_17;
977         break;
978         
979      case 7:
980         pStatus->acqSettings.idepth = BVSB_IDepth_e6_34;
981         break;
982         
983      case 8:
984         pStatus->acqSettings.idepth = BVSB_IDepth_e4_51;
985         break;
986         
987      case 9:
988         pStatus->acqSettings.idepth = BVSB_IDepth_e3_68;
989         break;
990         
991      case 10:
992         pStatus->acqSettings.idepth = BVSB_IDepth_e2_102;
993         break;
994         
995      default:
996         pStatus->acqSettings.idepth = BVSB_IDepth_e1_204;
997         break;
998   }
999   
1000   pStatus->acqParams.symbolRateOffset = (int32_t)((int16_t)((buf[0x08] << 8) + buf[0x09]));
1001   pStatus->acqParams.ifFreqOffset = (int32_t)((buf[0x04] << 24) + (buf[0x05] << 16) + (buf[0x06] << 8) + buf[0x07]);
1002   pStatus->acqSettings.bAutoAcq = buf[0x01] & 0x20 ? true : false;
1003   pStatus->acqSettings.bFastAcq = buf[0x01] & 0x01 ? true : false;
1004   pStatus->acqSettings.bTei = buf[0x02] & 0x01 ? true : false;
1005   pStatus->acqSettings.bTerr = buf[0x02] & 0x80 ? true : false;
1006   pStatus->acqSettings.bSpinv = buf[0x01] & 0x10 ? true : false;
1007   pStatus->acqSettings.bEq = buf[0x01] & 0x04 ? true : false;
1008   pStatus->acqSettings.bCh = buf[0x01] & 0x02 ? true : false;
1009   pStatus->acqSettings.bDavic = buf[0x03] & 0x08 ? true : false;
1010   pStatus->bFecLocked = buf[0x12] & 0x04 ? true : false;
1011   pStatus->bPllLocked = buf[0x12] & 0x02 ? true : false;
1012   pStatus->bSpinv = (buf[0x12] & 0x01 ? true : false);
1013   pStatus->ifFreq = (buf[0x0A] << 24) + (buf[0x0B] << 16) + (buf[0x0C] << 8) + buf[0x0D];
1014   pStatus->ifFreqError = (int32_t)((buf[0x17] << 24) + (buf[0x18] << 16) + (buf[0x19] << 8) + buf[0x1A]);
1015   pStatus->symbolRate = (int32_t)((buf[0x0E] << 24) + (buf[0x0F] << 16) + (buf[0x10] << 8) + buf[0x11]);
1016   pStatus->symbolRateError = (int32_t)((int16_t)((buf[0x1B] << 8) + buf[0x1C]));
1017   pStatus->corrErrCount = (buf[0x29] << 24) + (buf[0x2A] << 16) + (buf[0x2B] << 8) + buf[0x2C];
1018   pStatus->corrBlockCount = (buf[0x2D] << 24) + (buf[0x2E] << 16) + (buf[0x2F] << 8) + buf[0x30];
1019   pStatus->ucorrBlockCount = (buf[0x31] << 24) + (buf[0x32] << 16) + (buf[0x33] << 8) + buf[0x34];
1020   pStatus->cleanBlockCount = (buf[0x35] << 24) + (buf[0x36] << 16) + (buf[0x37] << 8) + buf[0x38];
1021   pStatus->berCount = (buf[0x25] << 24) + (buf[0x26] << 16) + (buf[0x27] << 8) + buf[0x28];
1022   pStatus->snr = (buf[0x13] << 8) + buf[0x14];
1023   pStatus->agf = (buf[0x1D] << 8) + buf[0x1E];
1024   pStatus->rf_agc = (((buf[0x1F] << 8) + buf[0x20]) * 1000) / 65535;
1025   pStatus->if_agc = (((buf[0x21] << 8) + buf[0x22]) * 1000) / 65535;
1026   pStatus->reacqCount = (buf[0x39] << 24) + (buf[0x3A] << 16) + (buf[0x3B] << 8) + buf[0x3C];
1027
1028   done:
1029   return retCode;
1030}
1031
1032
1033/******************************************************************************
1034 BVSB_3520_P_GetNtscStatus()
1035******************************************************************************/
1036BERR_Code BVSB_3520_P_GetNtscStatus(
1037   BVSB_Handle h,           /* [in] BVSB handle */
1038   BVSB_NtscStatus *pStatus /* [out] NTSC status */
1039)
1040{
1041   BERR_Code retCode;
1042   uint8_t buf[128];
1043
1044   if (pStatus == NULL)
1045      return (BERR_TRACE(BERR_INVALID_PARAMETER));
1046     
1047   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
1048   {
1049      BDBG_WRN(("HAB not available\n"));
1050      goto done;
1051   }
1052   
1053   buf[0] = 0x1C;
1054   buf[0x19] = 0x00;
1055   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, buf, 1));
1056   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x19, &buf[0x19], 1));
1057   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, buf, 0x19, true, 0x9C));
1058
1059   switch ((buf[2] >> 1) & 0x03)
1060   {
1061      case 0:
1062         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eLow;
1063         break;
1064      case 1:
1065         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eMedium;
1066         break;
1067      default:
1068         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eHigh;
1069         break;
1070   }
1071   
1072   pStatus->acqParams.ifFreqOffset = (int32_t)((buf[0x04] << 24) + (buf[0x05] << 16) + (buf[0x06] << 8) + buf[0x07]);
1073   pStatus->acqParams.symbolRateOffset = 0;
1074   pStatus->acqParams.mode = BVSB_InbandMode_eNTSC;
1075   pStatus->acqSettings.bFastAcq = buf[0x01] & 0x01 ? true : false;
1076   pStatus->acqSettings.bTerr = buf[0x02] & 0x80 ? true : false;
1077   pStatus->acqSettings.bAutoAcq = buf[0x01] & 0x20 ? true : false;
1078   pStatus->pixCarrFreq = (int32_t)((buf[0x08] << 24) + (buf[0x09] << 16) + (buf[0x0A] << 8) + buf[0x0B]);
1079   pStatus->pixCarrFreqError = (int32_t)((buf[0x0D] << 24) + (buf[0x0E] << 16) + (buf[0x0F] << 8) + buf[0x10]);
1080   pStatus->rf_agc = (((buf[0x11] << 8) + buf[0x12]) * 1000) / 65535;
1081   pStatus->if_agc = (((buf[0x13] << 8) + buf[0x14]) * 1000) / 65535;
1082   pStatus->bHsyncLocked = buf[0x0C] & 0x08 ? true : false;
1083
1084   done:
1085   return retCode;
1086}
1087
1088
1089/******************************************************************************
1090 BVSB_3520_P_GetBtscStatus()
1091******************************************************************************/
1092BERR_Code BVSB_3520_P_GetBtscStatus(
1093   BVSB_Handle h,           /* [in] BVSB handle */
1094   BVSB_BtscStatus *pStatus /* [out] BTSC status */
1095)
1096{
1097   BERR_Code retCode;
1098   uint8_t buf[128];
1099
1100   if (pStatus == NULL)
1101      return (BERR_TRACE(BERR_INVALID_PARAMETER));
1102     
1103   buf[0] = 0x1C;
1104   buf[0x19] = 0x00;
1105   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 0x1A, buf, 0x19, true));
1106
1107   switch (buf[0x16] & BVSB_AUDIO_CONFIG_DECODE_MODE_MASK)
1108   {
1109      case BVSB_AUDIO_CONFIG_DECODE_MODE_MONO:
1110         pStatus->decodeMode = BVSB_BtscDecodeMode_eMono;
1111         break;
1112         
1113      case BVSB_AUDIO_CONFIG_DECODE_MODE_STEREO:
1114         pStatus->decodeMode = BVSB_BtscDecodeMode_eStereo;
1115         break;
1116         
1117      case BVSB_AUDIO_CONFIG_DECODE_MODE_SAP:
1118         pStatus->decodeMode = BVSB_BtscDecodeMode_eSAP;
1119         break;
1120         
1121      default: /* BVSB_AUDIO_CONFIG_DECODE_MODE_SAP_MONO: */
1122         pStatus->decodeMode = BVSB_BtscDecodeMode_eSAP_Mono;
1123         break;
1124   }
1125   
1126   switch (buf[0x16] & BVSB_AUDIO_CONFIG_SR_MASK)
1127   {
1128      case BVSB_AUDIO_CONFIG_SR_32KHZ:
1129         pStatus->sampleRate = BVSB_BtscSampleRate_e32KHz;
1130         break;
1131     
1132      case BVSB_AUDIO_CONFIG_SR_44_1KHZ:
1133         pStatus->sampleRate = BVSB_BtscSampleRate_e44_1KHz;
1134         break;
1135     
1136      default: /* BVSB_AUDIO_CONFIG_SR_48KHZ: */
1137         pStatus->sampleRate = BVSB_BtscSampleRate_e48KHz;
1138         break;
1139   }
1140 
1141   pStatus->bI2sOut = buf[0x16] & BVSB_AUDIO_CONFIG_SEL_MASK ? true : false;
1142   pStatus->bBtscMute = (buf[0x17] & BVSB_AUDIO_CONFIG_MUTE) ? true : false;
1143   pStatus->bSapDetected = (buf[0x15] & BVSB_AUDIO_SAP_DETECTED) ? true : false;
1144   pStatus->bStereoDetected = (buf[0x15] & BVSB_AUDIO_STEREO_DETECTED) ? true : false;
1145   pStatus->btscLeftVolume = buf[0x17] & 0x7F;
1146   pStatus->btscRightVolume = buf[0x18] & 0x7F;
1147   
1148   done:
1149   return retCode;
1150}
1151
1152
1153/******************************************************************************
1154 BVSB_3520_P_ResetInbandStatus()
1155******************************************************************************/
1156BERR_Code BVSB_3520_P_ResetInbandStatus(
1157   BVSB_Handle h /* [in] BVSB handle */
1158)
1159{
1160   BERR_Code retCode;
1161   uint8_t buf[3];
1162
1163   buf[0] = 0x1F;
1164   buf[1] = 0x04;
1165   buf[2] = 0;
1166   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 3, buf, 1, true));
1167   
1168   done:
1169   return retCode;
1170}
1171
1172
1173/******************************************************************************
1174 BVSB_3520_P_AcquireOob()
1175******************************************************************************/
1176BERR_Code BVSB_3520_P_AcquireOob(
1177   BVSB_Handle h,           /* [in] BVSB handle */
1178   const BVSB_OobParams *pParams  /* [in] acquisition parameters */
1179)
1180{
1181   BERR_Code retCode;
1182   uint8_t   hab[5];
1183
1184   BVSB_CHK_RETCODE(BVSB_3520_P_EnableOobLockInterrupt(h, false));
1185
1186   hab[0] = 0x0D;
1187   hab[1] = hab[2] = hab[3] = hab[4] = 0x00;
1188   
1189   hab[1] |= ((h->settings.oob.bSpinv) ? 0x10 : 0x00);   
1190   hab[1] |= ((h->settings.oob.bAutoAcq) ? 0x20 : 0x00);
1191   hab[2] |= ((h->settings.oob.bBypassFEC) ? 0x80 : 0x00);
1192   switch (pParams->mode)
1193   {
1194      case BVSB_OobMode_eDs178:
1195         /*hab[2] |= 0x00;*/
1196         break;
1197         
1198      case BVSB_OobMode_eDs167_A:
1199         hab[2] |= 0x18;
1200         break;
1201         
1202      case BVSB_OobMode_eDs167_B:
1203         hab[2] |= 0x28; 
1204         break;
1205         
1206      default:
1207         return (BERR_TRACE(BERR_INVALID_PARAMETER));
1208   }
1209   
1210   switch (h->settings.oob.bw)
1211   {
1212      case BVSB_PhaseLoopBw_eLow:
1213         /*hab[2] |= 0x00;*/
1214         break;
1215         
1216      case BVSB_PhaseLoopBw_eMedium:
1217         hab[2] |= 0x02;
1218         break;
1219         
1220      case BVSB_PhaseLoopBw_eHigh:
1221         hab[2] |= 0x04;
1222         break;
1223         
1224      default:
1225         return (BERR_TRACE(BERR_INVALID_PARAMETER));
1226   }
1227   
1228   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 5, hab, 1, true));
1229   BVSB_CHK_RETCODE(BVSB_3520_P_EnableOobLockInterrupt(h, true));
1230
1231   done:
1232   return retCode;
1233}
1234
1235
1236/******************************************************************************
1237 BVSB_3520_P_GetOobStatus()
1238******************************************************************************/
1239BERR_Code BVSB_3520_P_GetOobStatus(
1240   BVSB_Handle h,           /* [in] BVSB handle */
1241   BVSB_OobStatus *pStatus  /* [out] OOB status   */
1242)
1243{
1244   BERR_Code retCode;
1245   uint8_t   buf[128];
1246
1247   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
1248   {
1249      BDBG_WRN(("HAB not available\n"));
1250      goto done;
1251   }
1252
1253   buf[0] = 0x19;
1254   buf[0x37] = 0x00;
1255   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, buf, 1));
1256   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x37, &buf[0x37], 1));
1257   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, buf, 0x37, true, 0x99));
1258
1259   switch ((buf[2] >> 4) & 0x07)
1260   {
1261      case 0:
1262         pStatus->acqParams.mode = BVSB_OobMode_eDs178;
1263         break;
1264         
1265      case 1:
1266         pStatus->acqParams.mode = BVSB_OobMode_eDs167_A;
1267         break;
1268         
1269      case 2:
1270         pStatus->acqParams.mode = BVSB_OobMode_eDs167_B;
1271         break;
1272         
1273      default:
1274         pStatus->acqParams.mode = BVSB_OobMode_eUnknown;
1275         break;
1276   }
1277   
1278   switch ((buf[2] >> 1) & 0x03)
1279   {
1280      case 0:
1281         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eLow;
1282         break;
1283      case 1:
1284         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eMedium;
1285         break;
1286      default:
1287         pStatus->acqSettings.bw = BVSB_PhaseLoopBw_eHigh;
1288         break;
1289   }
1290   
1291   pStatus->acqSettings.bAutoAcq = buf[0x01] & 0x20 ? true : false;
1292   pStatus->acqSettings.bSpinv = buf[0x01] & 0x10 ? true : false;
1293   pStatus->acqSettings.bBypassFEC = buf[0x02] & 0x80 ? true : false;
1294   pStatus->bRcvrLocked = buf[0x10] & 0x08 ? true : false;
1295   pStatus->bFecLocked = buf[0x10] & 0x04 ? true : false;
1296   pStatus->bSpinv = buf[0x10] & 0x01 ? true : false;
1297   pStatus->loFreq = (buf[0x04] << 24) + (buf[0x05] << 16) + (buf[0x06] << 8) + buf[0x07];
1298   pStatus->ifFreq = (buf[0x08] << 24) + (buf[0x09] << 16) + (buf[0x0A] << 8) + buf[0x0B];
1299   pStatus->ifFreqError = (int32_t)((buf[0x15] << 24) + (buf[0x16] << 16) + (buf[0x17] << 8) + buf[0x18]);
1300   pStatus->symbolRate = (int32_t)((buf[0x0C] << 24) + (buf[0x0D] << 16) + (buf[0x0E] << 8) + buf[0x0F]);
1301   pStatus->symbolRateError = (int32_t)((int16_t)((buf[0x19] << 8) + buf[0x1A]));
1302   pStatus->corrBlockCount = (buf[0x23] << 24) + (buf[0x24] << 16) + (buf[0x25] << 8) + buf[0x26];
1303   pStatus->ucorrBlockCount = (buf[0x27] << 24) + (buf[0x28] << 16) + (buf[0x29] << 8) + buf[0x2A];
1304   pStatus->berCount = (buf[0x1F] << 24) + (buf[0x20] << 16) + (buf[0x21] << 8) + buf[0x22];
1305   pStatus->snr = (buf[0x11] << 8) + buf[0x12];
1306   pStatus->oob_agc = (buf[0x1B] << 8) + buf[0x1C];
1307   pStatus->ext_agc = (buf[0x1D] << 8) + buf[0x1E];   
1308   pStatus->reacqCount = (buf[0x2B] << 24) + (buf[0x2C] << 16) + (buf[0x2D] << 8) + buf[0x2E];
1309   pStatus->atm_cell_total_count = (buf[0x2F] << 24) + (buf[0x30] << 16) + (buf[0x31] << 8) + buf[0x32];
1310   pStatus->atm_cell_loss_count = (buf[0x33] << 24) + (buf[0x34] << 16) + (buf[0x35] << 8) + buf[0x36];
1311
1312   done:
1313   return retCode;
1314}
1315
1316
1317/******************************************************************************
1318 BVSB_3520_P_ResetOobStatus()
1319******************************************************************************/
1320BERR_Code BVSB_3520_P_ResetOobStatus(
1321   BVSB_Handle h /* [in] BVSB handle */
1322)
1323{
1324   BERR_Code retCode;
1325   uint8_t buf[3];
1326
1327   buf[0] = 0x21;
1328   buf[1] = 0x04;
1329   buf[2] = 0;
1330   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 3, buf, 1, true));
1331   
1332   done:
1333   return retCode;
1334}
1335
1336
1337/******************************************************************************
1338 BVSB_3520_P_ConfigBtsc()
1339******************************************************************************/
1340BERR_Code BVSB_3520_P_ConfigBtsc(
1341   BVSB_Handle h,             /* [in] BVSB handle */
1342   BVSB_BtscSettings *pParams /* [in] BTSC configuration parameters */
1343)
1344{
1345   BERR_Code retCode;
1346   uint8_t buf[3];
1347
1348   buf[0] = 0x1D;
1349   buf[2] = 0x00;
1350   
1351   switch (pParams->decodeMode)
1352   {
1353      case BVSB_BtscDecodeMode_eMono:
1354         buf[1] = BVSB_AUDIO_CONFIG_DECODE_MODE_MONO;
1355         break;
1356         
1357      case BVSB_BtscDecodeMode_eStereo:
1358         buf[1] = BVSB_AUDIO_CONFIG_DECODE_MODE_STEREO;     
1359         break;
1360     
1361      case BVSB_BtscDecodeMode_eSAP:
1362         buf[1] = BVSB_AUDIO_CONFIG_DECODE_MODE_SAP;     
1363         break;
1364         
1365      case BVSB_BtscDecodeMode_eSAP_Mono:
1366         buf[1] = BVSB_AUDIO_CONFIG_DECODE_MODE_SAP_MONO;     
1367         break;
1368         
1369      default:
1370         return (BERR_TRACE(BERR_INVALID_PARAMETER));
1371   }
1372     
1373   switch (pParams->sampleRate)
1374   {
1375      case BVSB_BtscSampleRate_e32KHz:
1376         buf[1] |= BVSB_AUDIO_CONFIG_SR_32KHZ;
1377         break;
1378         
1379      case BVSB_BtscSampleRate_e44_1KHz:
1380         buf[1] |= BVSB_AUDIO_CONFIG_SR_44_1KHZ;
1381         break;
1382         
1383      case BVSB_BtscSampleRate_e48KHz:
1384         buf[1] |= BVSB_AUDIO_CONFIG_SR_48KHZ;
1385         break;
1386         
1387      default:
1388         return (BERR_TRACE(BERR_INVALID_PARAMETER));
1389   }
1390   
1391   buf[1] |= pParams->bI2sOut ? 0x40 : 0x00;
1392   
1393   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 3, buf, 1, true));
1394   BKNI_Memcpy(&(h->settings.btsc), pParams, sizeof(BVSB_BtscSettings));
1395
1396   done:
1397   return retCode;
1398}
1399
1400
1401/******************************************************************************
1402 BVSB_3520_P_SetBtscVolume()
1403******************************************************************************/
1404BERR_Code BVSB_3520_P_SetBtscVolume(
1405   BVSB_Handle h,        /* [in] BVSB handle */
1406   uint8_t left_volume,  /* [in] left volume attenuation in dB (0 to 95 dB) */
1407   uint8_t right_volume, /* [in] left volume attenuation in dB (0 to 95 dB) */
1408   bool    bMute
1409)
1410{
1411   BERR_Code retCode;
1412   uint8_t buf[4];
1413
1414   buf[0] = 0x17;
1415   buf[1] = left_volume & 0x7F;
1416   buf[1] |= (bMute ? BVSB_AUDIO_CONFIG_MUTE : 0x00);
1417   buf[2] = right_volume & 0x7F;
1418   buf[3] = 0;
1419   
1420   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 4, buf, 1, true));
1421
1422   done:
1423   return retCode;
1424}
1425
1426
1427/******************************************************************************
1428 BVSB_3520_P_SetInbandOi()
1429******************************************************************************/
1430BERR_Code BVSB_3520_P_SetInbandOi(
1431   BVSB_Handle           h,         /* [in] BVSB handle */
1432   BVSB_InbandOiSettings *pInbandOi /* [in] inband transport output interface settings */
1433)
1434{
1435   BERR_Code retCode;
1436   uint8_t buf[4];
1437
1438   buf[0] = 0x0F;
1439   buf[1] = buf[2] = buf[3] = 0;
1440   buf[1] |= (pInbandOi->bHead4 ? 0x40 : 0x00); 
1441   buf[1] |= (pInbandOi->bSync1 ? 0x20 : 0x00); 
1442   buf[1] |= (pInbandOi->bXBERT ? 0x04 : 0x00); 
1443   buf[2] |= (pInbandOi->bErrinv ? 0x80 : 0x00); 
1444   buf[2] |= (pInbandOi->bSyncinv ? 0x40 : 0x00); 
1445   buf[2] |= (pInbandOi->bVldinv ? 0x20 : 0x00); 
1446   buf[2] |= (pInbandOi->bClksup ? 0x10 : 0x00); 
1447   buf[2] |= (pInbandOi->bClkinv ? 0x08 : 0x00); 
1448   buf[2] |= (pInbandOi->bSerial ? 0x02 : 0x00); 
1449
1450   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, buf, 4, buf, 1, true));
1451 
1452   done:
1453   return retCode;
1454}
1455
1456
1457/******************************************************************************
1458 BVSB_3520_P_GetSoftDecisionBuf()
1459******************************************************************************/
1460BERR_Code BVSB_3520_P_GetSoftDecisionBuf(
1461   BVSB_Handle h,  /* [in] BVSB handle */
1462   int16_t *pI,    /* [out] 30 I-values */
1463   int16_t *pQ     /* [out] 30 Q-values */
1464)
1465{
1466   BERR_Code retCode;
1467   uint8_t   hab[128], i;
1468   
1469   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
1470   {
1471      BDBG_WRN(("HAB not available\n"));
1472      goto done;
1473   }
1474
1475   hab[0] = 0x15;
1476   hab[1] = 0x4A;
1477   hab[2] = 0x28;
1478   hab[3] = 0x1E;
1479   hab[0x7C] = 0x00;
1480   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, hab, 4));
1481   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x7C, &hab[0x7C], 1));
1482   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, hab, 0x7C, true, 0x95));
1483   
1484   for (i = 0; i < 30; i++)
1485   {
1486      pI[i] = (hab[4+(4*i)] << 4) | ((hab[5+(4*i)] >> 4) & 0x0F);
1487      pQ[i] = (hab[6+(4*i)] << 4) | ((hab[7+(4*i)] >> 4) & 0x0F);
1488     
1489      if (pI[i] & 0x800)
1490         pI[i] -= 0x1000;
1491      if (pQ[i] & 0x800)
1492         pQ[i] -= 0x1000;
1493   }
1494   
1495   done:
1496   return retCode;
1497}
1498
1499
1500/******************************************************************************
1501 BVSB_3520_P_GetOobSoftDecisionBuf()
1502******************************************************************************/
1503BERR_Code BVSB_3520_P_GetOobSoftDecisionBuf(
1504   BVSB_Handle h,  /* [in] BVSB handle */
1505   int16_t *pI,    /* [out] 30 I-values */
1506   int16_t *pQ     /* [out] 30 Q-values */
1507)
1508{
1509   BERR_Code retCode;
1510   uint8_t   hab[128], i;
1511   
1512   if ((retCode = BVSB_3520_P_CheckHab(h)) != BERR_SUCCESS)
1513   {
1514      BDBG_WRN(("HAB not available\n"));
1515      goto done;
1516   }
1517
1518   hab[0] = 0x15;
1519   hab[1] = 0x28;
1520   hab[2] = 0x4C;
1521   hab[3] = 0x1E;
1522   hab[0x7C] = 0x00;
1523   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, hab, 4));
1524   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0x7C, &hab[0x7C], 1));
1525   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, hab, 0x7C, true, 0x95));
1526   
1527   for (i = 0; i < 30; i++)
1528   {
1529      pI[i] = (int16_t)(hab[4+(4*i)]);
1530      pQ[i] = (int16_t)(hab[5+(4*i)]);
1531   }
1532   
1533   done:
1534   return retCode;
1535}
1536
1537
1538/******************************************************************************
1539 BVSB_3520_P_SetTmConfig()
1540******************************************************************************/
1541BERR_Code BVSB_3520_P_SetTmConfig(
1542   BVSB_Handle h,    /* [in] BVSB handle */
1543   void        *p    /* [in] pad configuration parameters */
1544)
1545{
1546   BERR_Code retCode;
1547   uint8_t hab[16];
1548   BVSB_3520_PadConfig *pCfg = (BVSB_3520_PadConfig *)p;
1549
1550   /* pad_control_1 */
1551   hab[0] = 0x1B;
1552   hab[1] = ((uint8_t)(pCfg->driveStrength_ps_data_7) & 0x03) << 4;
1553   hab[1] |= (((uint8_t)(pCfg->driveStrength_ps_data_6) & 0x03) << 2);
1554   hab[1] |= ((uint8_t)(pCfg->driveStrength_ps_data_5) & 0x03);
1555   hab[2] = ((uint8_t)(pCfg->driveStrength_ps_data_4) & 0x03) << 6;
1556   hab[2] |= (((uint8_t)(pCfg->driveStrength_ps_data_3) & 0x03) << 4);
1557   hab[2] |= (((uint8_t)(pCfg->driveStrength_ps_data_2) & 0x03) << 2);
1558   hab[2] |= ((uint8_t)(pCfg->driveStrength_ps_data_1) & 0x03);
1559   hab[3] = ((uint8_t)(pCfg->driveStrength_ps_data_0) & 0x03) << 6;
1560   hab[3] |= (((uint8_t)(pCfg->driveStrength_ps_clk) & 0x03) << 4);
1561   hab[3] |= (((uint8_t)(pCfg->driveStrength_ps_err) & 0x03) << 2);
1562   hab[3] |= ((uint8_t)(pCfg->driveStrength_ps_valid) & 0x03);
1563   hab[4] = ((uint8_t)(pCfg->driveStrength_ps_sync) & 0x03) << 6;
1564   hab[4] |= (pCfg->bTristate_clk_adc_f1b ? 0x20 : 0x00);
1565   hab[4] |= (pCfg->bTristate_clk_adc ? 0x10 : 0x00);
1566   hab[4] |= (((uint8_t)(pCfg->driveStrength_oob_clk) & 0x03) << 2);
1567   hab[4] |= ((uint8_t)(pCfg->driveStrength_oob_sdata) & 0x03);
1568   hab[5] = (pCfg->bTristate_gpo_7 ? 0x80 : 0x00);
1569   hab[5] |= (pCfg->bTristate_gpo_6 ? 0x40 : 0x00);
1570   hab[5] |= (pCfg->bTristate_gpo_5 ? 0x20 : 0x00);
1571   hab[5] |= (pCfg->bTristate_gpo_4 ? 0x10 : 0x00);
1572   hab[5] |= (pCfg->bTristate_gpo_3 ? 0x08 : 0x00);
1573   hab[5] |= (pCfg->bTristate_gpo_2 ? 0x04 : 0x00);
1574   hab[5] |= (pCfg->bTristate_gpo_1 ? 0x02 : 0x00);
1575   hab[5] |= (pCfg->bTristate_gpo_0 ? 0x01 : 0x00);
1576   hab[6] = ((uint8_t)(pCfg->driveStrength_rn_mclk) & 0x03) << 6;
1577   hab[6] |= (((uint8_t)(pCfg->driveStrength_rp_sclk) & 0x03) << 4);
1578   hab[6] |= (((uint8_t)(pCfg->driveStrength_ln_lr) & 0x03) << 2);
1579   hab[6] |= ((uint8_t)(pCfg->driveStrength_lp_data) & 0x03);
1580 
1581   /* pad_control_2 */
1582   hab[7] = 0x22;
1583   hab[8] = ((uint8_t)(pCfg->f1bsel) & 0x03) << 6;
1584   hab[8] |= (((uint8_t)(pCfg->adcsel) & 0x03) << 4);
1585   hab[8] |= (pCfg->bOpenDrain_hm ? 0x00 : 0x02);
1586   hab[8] |= (pCfg->bOpenDrain_gm ? 0x00 : 0x01);
1587   hab[9] = (pCfg->gpio_01 & 0x07) << 5;
1588   hab[9] |= (pCfg->bErs ? 0x10 : 0x00);
1589   hab[9] |= (pCfg->bTristate_at ? 0x01 : 0x00);
1590   hab[10] = (pCfg->oob_gpo & 0x07);
1591   hab[10] |= (pCfg->bOpenDrain_am ? 0x00 : 0x80);
1592   hab[10] |= (pCfg->bTristate_it ? 0x40 : 0x00);
1593   hab[10] |= (pCfg->bOpenDrain_im ? 0x00 : 0x20);
1594   hab[10] |= (pCfg->bTristate_ot ? 0x10 : 0x00);
1595   hab[10] |= (pCfg->bOpenDrain_om ? 0x00 : 0x08);
1596   hab[11] = (pCfg->agcgpsel & 0x03) << 1; 
1597   hab[11] |= ((pCfg->agcisel & 0x03) << 3); 
1598   hab[11] |= ((pCfg->agctsel & 0x03) << 5); 
1599
1600   hab[12] = 0;
1601
1602   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 13, hab, 1, true));
1603
1604   done:
1605   return retCode;
1606}
1607
1608
1609/******************************************************************************
1610 BVSB_3520_P_GetTmConfig()
1611******************************************************************************/
1612BERR_Code BVSB_3520_P_GetTmConfig(
1613   BVSB_Handle h,  /* [in] BVSB handle */
1614   void        */* [out] pad configuration parameters */
1615)
1616{
1617   BERR_Code retCode;
1618   BVSB_3520_PadConfig *pCfg = (BVSB_3520_PadConfig *)p;
1619   uint8_t buf[10];
1620
1621   BVSB_CHK_RETCODE(BVSB_3520_P_ReadConfig(h, BVSB_CONFIG_PAD_CTRL_1, buf, 10));
1622
1623   /* pad_control_1 */
1624   pCfg->driveStrength_ps_data_7 = (BVSB_3520_PadDriveStrength)((buf[0] >> 4) & 0x03);
1625   pCfg->driveStrength_ps_data_6 = (BVSB_3520_PadDriveStrength)((buf[0] >> 2) & 0x03);
1626   pCfg->driveStrength_ps_data_5 = (BVSB_3520_PadDriveStrength)(buf[0] & 0x03);
1627   pCfg->driveStrength_ps_data_4 = (BVSB_3520_PadDriveStrength)((buf[1] >> 6) & 0x03);
1628   pCfg->driveStrength_ps_data_3 = (BVSB_3520_PadDriveStrength)((buf[1] >> 4) & 0x03);
1629   pCfg->driveStrength_ps_data_2 = (BVSB_3520_PadDriveStrength)((buf[1] >> 2) & 0x03);
1630   pCfg->driveStrength_ps_data_1 = (BVSB_3520_PadDriveStrength)(buf[1] & 0x03);
1631   pCfg->driveStrength_ps_data_0 = (BVSB_3520_PadDriveStrength)((buf[2] >> 6) & 0x03);
1632   pCfg->driveStrength_ps_clk = (BVSB_3520_PadDriveStrength)((buf[2] >> 4) & 0x03);
1633   pCfg->driveStrength_ps_err = (BVSB_3520_PadDriveStrength)((buf[2] >> 2) & 0x03);
1634   pCfg->driveStrength_ps_valid = (BVSB_3520_PadDriveStrength)(buf[2] & 0x03);
1635   pCfg->driveStrength_ps_sync = (BVSB_3520_PadDriveStrength)((buf[3] >> 6) & 0x03);
1636   pCfg->bTristate_clk_adc_f1b = (buf[3] & 0x20) ? true : false;
1637   pCfg->bTristate_clk_adc = (buf[3] & 0x10) ? true : false;
1638   pCfg->driveStrength_oob_clk = (BVSB_3520_PadDriveStrength)((buf[3] & 0x03) >> 2);
1639   pCfg->driveStrength_oob_sdata = (BVSB_3520_PadDriveStrength)(buf[3] & 0x03);
1640   pCfg->bTristate_gpo_7 = (buf[4] & 0x80 ? true : false);
1641   pCfg->bTristate_gpo_6 = (buf[4] & 0x40 ? true : false);
1642   pCfg->bTristate_gpo_5 = (buf[4] & 0x20 ? true : false);
1643   pCfg->bTristate_gpo_4 = (buf[4] & 0x10 ? true : false);
1644   pCfg->bTristate_gpo_3 = (buf[4] & 0x08 ? true : false);
1645   pCfg->bTristate_gpo_2 = (buf[4] & 0x04 ? true : false);
1646   pCfg->bTristate_gpo_1 = (buf[4] & 0x02 ? true : false);
1647   pCfg->bTristate_gpo_0 = (buf[4] & 0x01 ? true : false);
1648   pCfg->driveStrength_rn_mclk = (BVSB_3520_AudioPadDriveStrength)((buf[5] >> 6) & 0x03);
1649   pCfg->driveStrength_rp_sclk = (BVSB_3520_AudioPadDriveStrength)((buf[5] >> 4) & 0x03);
1650   pCfg->driveStrength_ln_lr = (BVSB_3520_AudioPadDriveStrength)((buf[5] >> 2) & 0x03);
1651   pCfg->driveStrength_lp_data = (BVSB_3520_AudioPadDriveStrength)(buf[5] & 0x03);
1652
1653   /* pad_control_2 */
1654   pCfg->f1bsel = (BVSB_F1BADC_OutputFormat)((buf[6] >> 6) & 0x03);
1655   pCfg->adcsel = (BVSB_ADCSEL_OutputFormat)((buf[6] >> 4) & 0x03);
1656   pCfg->bOpenDrain_hm = (buf[6] & 0x02) ? false : true;
1657   pCfg->bOpenDrain_gm = (buf[6] & 0x01) ? false : true;
1658   pCfg->gpio_01 = ((buf[7] >> 5) & 0x07);
1659   pCfg->bErs = (buf[7] & 0x10) ? true : false;
1660   pCfg->bTristate_at = (buf[7] & 0x01) ? true : false;
1661   pCfg->bOpenDrain_am = (buf[8] & 0x80) ? false : true;
1662   pCfg->bTristate_it = (buf[8] & 0x40) ? true : false;
1663   pCfg->bOpenDrain_im = (buf[8] & 0x20) ? false : true;
1664   pCfg->bTristate_ot = (buf[8] & 0x10) ? true : false;
1665   pCfg->bOpenDrain_om = (buf[8] & 0x08) ? false : true;
1666   pCfg->oob_gpo = (buf[8] & 0x07);
1667   pCfg->agctsel = ((buf[9] >> 5) & 0x03);
1668   pCfg->agcisel = ((buf[9] >> 3) & 0x03);
1669   pCfg->agcgpsel = ((buf[9] >> 1) & 0x03);
1670
1671   done:
1672   return retCode;
1673}
1674
1675
1676/******************************************************************************
1677 BVSB_3520_P_WriteConfig()
1678******************************************************************************/
1679BERR_Code BVSB_3520_P_WriteConfig(
1680   BVSB_Handle h,   /* [in] BVSB handle */
1681   uint16_t offset, /* [in] 16-bit offset within the host configuration space */
1682   uint8_t *buf,    /* [in] data to write */
1683   uint8_t len      /* [in] number of bytes to write */
1684)
1685{
1686   BERR_Code retCode;
1687   uint8_t   hab[128], i;
1688
1689   if ((len < 1) || (len > 121))
1690      return (BERR_TRACE(BERR_INVALID_PARAMETER));
1691
1692   hab[0] = 0x13;
1693   hab[1] = (offset >> 8);
1694   hab[2] = (offset & 0xFF);   
1695   hab[3] = len;
1696   hab[4+len] = 0x00;
1697
1698   for (i = 0; i < len; i++)
1699      hab[4+i] = buf[i];
1700   
1701   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 5+len, hab, 1, true));
1702 
1703   done:
1704   return retCode;
1705}
1706
1707
1708/******************************************************************************
1709 BVSB_3520_P_ReadConfig()
1710******************************************************************************/
1711BERR_Code BVSB_3520_P_ReadConfig(
1712   BVSB_Handle h,  /* [in] BVSB handle */
1713   uint16_t offset,   /* [in] 16-bit offset within the host configuration space */
1714   uint8_t *buf,      /* [in] buffer to hold the read data */
1715   uint8_t len        /* [in] number of bytes to read */
1716)
1717{
1718   BERR_Code retCode;
1719   uint8_t   hab[128], i;
1720
1721   if ((len < 1) || (len > 121))
1722      return (BERR_TRACE(BERR_INVALID_PARAMETER));
1723
1724   hab[0] = 0x12;
1725   hab[1] = (offset >> 8);
1726   hab[2] = (offset & 0xFF);   
1727   hab[3] = len;
1728   hab[4+len] = 0;
1729
1730   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 5+len, hab, 5+len, true));
1731
1732   for (i = 0; i < len; i++)
1733      buf[i] = hab[4+i];
1734
1735   done:
1736   return retCode;
1737}
1738
1739/******************************************************************************
1740 BVSB_3520_P_GetLockStateChangeEventHandle()
1741******************************************************************************/
1742BERR_Code BVSB_3520_P_GetLockStateChangeEventHandle(
1743   BVSB_Handle h,            /* [in] BVSB handle */
1744   BKNI_EventHandle *hEvent  /* [out] lock event handle */
1745)
1746{
1747   *hEvent = ((BVSB_3520_P_Handle *)(h->pImpl))->hLockChangeEvent;
1748   return BERR_SUCCESS;
1749}
1750
1751/******************************************************************************
1752 BVSB_3520_P_GetOobLockStateChangeEventHandle()
1753******************************************************************************/
1754BERR_Code BVSB_3520_P_GetOobLockStateChangeEventHandle(
1755   BVSB_Handle h,            /* [in] BVSB handle */
1756   BKNI_EventHandle *hEvent  /* [out] lock event handle */
1757)
1758{
1759   *hEvent = ((BVSB_3520_P_Handle *)(h->pImpl))->hOobLockChangeEvent;
1760   return BERR_SUCCESS;
1761}
1762
1763
1764
1765/******************************************************************************
1766 BVSB_3520_P_GetAntennaEventHandle()
1767******************************************************************************/
1768BERR_Code BVSB_3520_P_GetAntennaEventHandle(
1769   BVSB_Handle h,            /* [in] BVSB handle */
1770   BKNI_EventHandle *hEvent  /* [out] lock event handle */
1771)
1772{
1773   *hEvent = ((BVSB_3520_P_Handle *)(h->pImpl))->hAntennaEvent;
1774   return BERR_SUCCESS;
1775}
1776
1777
1778/******************************************************************************
1779 BVSB_3520_P_GetInterruptEventHandle()
1780******************************************************************************/
1781BERR_Code BVSB_3520_P_GetInterruptEventHandle(
1782   BVSB_Handle h,            /* [in] BVSB handle */
1783   BKNI_EventHandle *hEvent  /* [out] interrupt event handle */
1784)
1785{
1786   *hEvent = ((BVSB_3520_P_Handle *)(h->pImpl))->hInterruptEvent;
1787   return BERR_SUCCESS;
1788}
1789
1790
1791/******************************************************************************
1792 BVSB_3520_P_HandleInterrupt_isr()
1793******************************************************************************/
1794BERR_Code BVSB_3520_P_HandleInterrupt_isr(
1795   BVSB_Handle h /* [in] BVSB handle */
1796)
1797{
1798   BDBG_ASSERT(h);
1799   
1800/*uarta_out('!');*/
1801   h->settings.i2c.interruptEnableFunc(false, h->settings.i2c.interruptEnableFuncParam);
1802   BKNI_SetEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hApiEvent);   
1803   BKNI_SetEvent(((BVSB_3520_P_Handle *)(h->pImpl))->hInterruptEvent); 
1804   return BERR_SUCCESS;
1805}
1806
1807
1808/******************************************************************************
1809 BVSB_3520_P_ProcessInterruptEvent()
1810******************************************************************************/
1811BERR_Code BVSB_3520_P_ProcessInterruptEvent(
1812   BVSB_Handle h  /* [in] BVSB handle */
1813)
1814{
1815   BERR_Code retCode;
1816   
1817   BDBG_ASSERT(h);
1818   BVSB_CHK_RETCODE(BVSB_3520_P_DecodeInterrupt(h));
1819   BVSB_3520_P_EnableHostInterrupt(h, true);
1820   
1821   done:
1822   return retCode;
1823}
1824
1825/******************************************************************************
1826 BVSB_3520_P_ReadMbox()
1827******************************************************************************/
1828BERR_Code BVSB_3520_P_ReadMbox(
1829   BVSB_Handle h,    /* [in] BVSB PI Handle */
1830   uint16_t    reg,  /* [in] RBUS register address */
1831   uint32_t    *val  /* [out] value read from register */
1832)
1833{
1834   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
1835   BERR_Code retCode;
1836   uint8_t sb, i, buf[4];
1837
1838   /* update bits 15:8 of mbox address if changed */
1839   sb = reg >> 8;
1840   if (sb != p3520->last_mbox_15_8)
1841   {
1842      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_SFR_IO_MBOX_A_15_8, &sb));
1843      p3520->last_mbox_15_8 = sb;
1844   }
1845
1846   /* read from mbox */
1847   sb = reg & 0xFC;
1848   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_SFR_IO_MBOX_CMD, &sb));
1849
1850   /* check for mbox transfer complete */
1851   for (i = 0; i < 3; i++)
1852   {
1853      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_SFR_IO_MBOX_STATUS, &sb));
1854      if ((sb & 0x80) == 0)
1855      {
1856         if (sb & 0x40)
1857         {
1858            BERR_TRACE(retCode = BVSB_ERR_IOMB_XFER);
1859            goto done;
1860         }
1861         else
1862         {
1863            /* transfer completed - now get the data */
1864            BVSB_CHK_RETCODE(BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_SFR_IO_MBOX_D_31_24, buf, 4));
1865            *val = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1866         }
1867         break;
1868      }
1869   }
1870
1871   if (i >= 3)
1872   {
1873      /* this should not happen */
1874      BERR_TRACE(retCode = BVSB_ERR_IOMB_BUSY);
1875      BDBG_ERR(("IO_MBOX busy\n"));
1876   }
1877
1878   done:
1879   return retCode;
1880}
1881
1882
1883/******************************************************************************
1884 BVSB_3520_P_WriteMbox()
1885******************************************************************************/
1886BERR_Code BVSB_3520_P_WriteMbox(
1887   BVSB_Handle h,    /* [in] BVSB PI Handle */
1888   uint16_t    reg,  /* [in] RBUS register address */
1889   uint32_t    *val  /* [in] value to write */
1890)
1891{
1892   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
1893   BERR_Code retCode;
1894   uint8_t buf[6], sb, i;
1895
1896   /* write addr, data, and cmd in one i2c transaction */
1897   buf[0] = reg >> 8;
1898   buf[1] = *val >> 24;
1899   buf[2] = *val >> 16;
1900   buf[3] = *val >> 8;
1901   buf[4] = *val & 0xFF; 
1902   buf[5] = (reg & 0xFC) | 0x01;
1903   i = (buf[0] != p3520->last_mbox_15_8) ? 0 : 1;
1904   p3520->last_mbox_15_8 = buf[0];
1905   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, i ? BCM3520_SH_SFR_IO_MBOX_D_31_24 : BCM3520_SH_SFR_IO_MBOX_A_15_8, &buf[i], 6-i));
1906
1907   for (i = 0; i < 3; i++)
1908   {
1909      /* check for mbox transfer complete */
1910      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_SFR_IO_MBOX_STATUS, &sb));
1911      if ((sb & 0x80) == 0)
1912      {
1913         if (sb & 0x40)
1914         {
1915            BERR_TRACE(retCode = BVSB_ERR_IOMB_XFER);
1916         }
1917         goto done;
1918      }
1919   }
1920
1921   if (sb & 0x80)
1922   {
1923      /* this should not happen */
1924      BERR_TRACE(retCode = BVSB_ERR_IOMB_BUSY);
1925      BDBG_ERR(("IO_MBOX busy\n"));
1926   }
1927
1928   done:
1929   return retCode;
1930}
1931
1932
1933/******************************************************************************
1934 BVSB_3520_P_ReadHab()
1935******************************************************************************/
1936BERR_Code BVSB_3520_P_ReadHab(BVSB_Handle h, uint8_t addr, uint8_t *buf, uint8_t n)
1937{
1938   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
1939   BERR_Code retCode;
1940
1941   if ((addr & 0x80) || (n & 0x80))
1942      return BERR_TRACE(BERR_INVALID_PARAMETER);
1943
1944   if ((addr + n) > 0x80)
1945      return BERR_TRACE(BERR_INVALID_PARAMETER);
1946
1947   BVSB_CHK_RETCODE(BVSB_3520_P_SetApWindow(h, BVSB_WINDOW_HAB));
1948   BVSB_CHK_RETCODE(BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, addr, buf, n));
1949
1950   done:
1951   return retCode;
1952}
1953
1954
1955/******************************************************************************
1956 BVSB_3520_P_WriteHab()
1957******************************************************************************/
1958BERR_Code BVSB_3520_P_WriteHab(BVSB_Handle h, uint8_t addr, uint8_t *buf, uint8_t n)
1959{
1960   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
1961   BERR_Code retCode;
1962
1963   if ((addr & 0x80) || (n & 0x80))
1964      return BERR_TRACE(BERR_INVALID_PARAMETER);
1965
1966   if ((addr + n) > 0x80)
1967      return BERR_TRACE(BERR_INVALID_PARAMETER);
1968
1969   BVSB_CHK_RETCODE(BVSB_3520_P_SetApWindow(h, BVSB_WINDOW_HAB));
1970   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, addr, buf, n));
1971
1972   done:
1973   return retCode;
1974}
1975
1976
1977/******************************************************************************
1978 BVSB_3520_P_ReadMemory()
1979******************************************************************************/
1980BERR_Code BVSB_3520_P_ReadMemory(BVSB_Handle h, uint16_t addr, uint8_t *buf, uint16_t n)
1981{
1982   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
1983   BERR_Code retCode;
1984
1985   if (((uint32_t)addr + (uint32_t)n) > 0x10000)
1986      return BERR_TRACE(BERR_INVALID_PARAMETER);
1987
1988   BVSB_CHK_RETCODE(BVSB_3520_P_SetApWindow(h, BVSB_WINDOW_IRAM + addr));
1989   BVSB_CHK_RETCODE(BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, addr & 0x7F, buf, n));
1990   p3520->last_page_16_15 = p3520->last_page_14_7 = 0xFF; 
1991
1992   done:
1993   return retCode;
1994}
1995
1996
1997/******************************************************************************
1998 BVSB_3520_P_WriteMemory()
1999******************************************************************************/
2000BERR_Code BVSB_3520_P_WriteMemory(BVSB_Handle h, uint16_t addr, uint8_t *buf, uint16_t n)
2001{
2002   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2003   BERR_Code retCode = BERR_SUCCESS;
2004   uint16_t  curr_addr, nbytes, bytes_left;
2005
2006   if ((addr >= 0x8000) || (n >= 0x8000))
2007      return BERR_TRACE(BERR_INVALID_PARAMETER);
2008   if ((addr + n) > 0x8000)
2009      return BERR_TRACE(BERR_INVALID_PARAMETER);
2010
2011   curr_addr = addr;
2012   bytes_left = n;
2013   while (bytes_left > 0)
2014   {
2015      BVSB_CHK_RETCODE(BVSB_3520_P_SetApWindow(h, BVSB_WINDOW_IRAM + curr_addr));
2016      nbytes = 128 - (curr_addr % 128);
2017      if (nbytes > bytes_left)
2018         nbytes = bytes_left;
2019      bytes_left -= nbytes;
2020      BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, curr_addr & 0x7F, buf, nbytes));
2021      curr_addr += nbytes;
2022      buf += nbytes;
2023   }
2024
2025   done:
2026   return retCode;
2027}
2028
2029
2030/******************************************************************************
2031 BVSB_3520_P_SetApWindow()
2032******************************************************************************/
2033BERR_Code BVSB_3520_P_SetApWindow(
2034   BVSB_Handle h,    /* [in] BVSB PI Handle */
2035   uint32_t window   /* [in] base address of the 128-byte window */
2036)
2037{
2038   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2039   BERR_Code retCode = BERR_SUCCESS;
2040   uint8_t   haddr_16_15 = (window >> 15) & 0x03;
2041   uint8_t   haddr_14_7 = (window >> 7) & 0xFF;
2042   uint8_t   buf[2];
2043
2044   if (p3520->last_page_16_15 != haddr_16_15)
2045   {
2046      buf[0] = haddr_16_15;
2047      buf[1] = haddr_14_7;
2048      BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_SFR_H_ADR_16_15, buf, 2));
2049      p3520->last_page_16_15 = haddr_16_15;
2050      p3520->last_page_14_7 = haddr_14_7;
2051   }
2052   else if (p3520->last_page_14_7 != haddr_14_7)
2053   {
2054      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_SFR_H_ADR_14_7, &haddr_14_7));
2055      p3520->last_page_14_7 = haddr_14_7;
2056   }
2057
2058   done:
2059   return retCode;
2060}
2061
2062/******************************************************************************
2063 BVSB_3520_P_ResetAp()
2064******************************************************************************/
2065BERR_Code BVSB_3520_P_ResetAp(BVSB_Handle h)
2066{
2067   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2068   BERR_Code retCode;
2069   uint8_t i, sb, buf[4];
2070
2071   /* initialize JDEC */
2072   sb = BCM3520_JDEC_RAM;
2073   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_JDEC, &sb));
2074
2075   /* reset the AP */
2076   sb = BCM3520_AP_RESET;
2077   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb));
2078
2079   /* reset AP status */
2080   sb = 0x0B;
2081   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_AP_CMD, &sb));
2082
2083   /* reset all interrupt status */
2084   for (i = 0; i < 4; i++)
2085      buf[i] = 0xFF;
2086   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_STAT1, buf,
2087 4));
2088
2089   /* clear MSGx registers */
2090   buf[0] = buf[1] = 0x00;
2091   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_MSG1, buf,
20922));
2093
2094   /* verify that AP is reset */
2095   BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb));
2096   if ((sb & BCM3520_AP_MASK) != BCM3520_AP_RESET)
2097   {
2098      BDBG_ERR(("unable to reset the AP\n"));
2099      BERR_TRACE(retCode = BVSB_ERR_AP_FAIL);
2100   }
2101
2102   done:
2103   p3520->last_page_16_15 = 0xFF;
2104   p3520->last_page_14_7 = 0xFF;
2105   return retCode;
2106}
2107
2108
2109/******************************************************************************
2110 BVSB_3520_P_RunAp()
2111******************************************************************************/
2112BERR_Code BVSB_3520_P_RunAp(BVSB_Handle h)
2113{
2114   BERR_Code retCode;
2115   uint8_t   sb, sb2;
2116
2117   /* check if the AP is currently running */
2118   BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb)); 
2119
2120   if ((sb & BCM3520_AP_MASK) != BCM3520_AP_RUN)
2121   {
2122      /* start running the AP */
2123      sb2 = BCM3520_AP_RUN;
2124      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb2));
2125
2126      /* verify that the AP is running */
2127      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb));
2128      if ((sb & BCM3520_AP_MASK) != BCM3520_AP_RUN)
2129      {
2130         BDBG_ERR(("unable to run the AP\n"));
2131         BERR_TRACE(retCode = BVSB_ERR_AP_FAIL);
2132         goto done;
2133      }
2134
2135      /* clear AP_change state bit */
2136      sb2 = BCM3520_STAT1_AP_OP_CHG;
2137      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT1, &sb2)); 
2138   }
2139   else
2140   {
2141      BDBG_WRN(("BVSB_3520_P_RunAp(): AP already running\n"));
2142   }
2143
2144   done:
2145   return retCode;
2146}
2147
2148
2149/******************************************************************************
2150 BVSB_3520_P_DisableInterrupts()
2151******************************************************************************/ 
2152BERR_Code BVSB_3520_P_DisableInterrupts(
2153   BVSB_Handle h   /* [in] BVSB PI Handle */
2154)
2155{
2156   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2157   BERR_Code err;
2158   const uint8_t val[4] = {0, 0, 0, 0};
2159   
2160   /* clear IEx registers */
2161   err = BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_IE1, val, 4);
2162   return err;   
2163}
2164
2165
2166/******************************************************************************
2167 BVSB_3520_P_DecodeError()
2168******************************************************************************/
2169BERR_Code BVSB_3520_P_DecodeError(
2170   BVSB_Handle h,           /* [in] BVSB PI Handle */
2171   BVSB_ApStatus *pApStatus /* [in] AP status returned by BVSB_GetApStatus */
2172)
2173{
2174   BERR_Code retCode = BERR_SUCCESS;
2175   uint8_t sb;
2176
2177   if (*pApStatus & BVSB_APSTATUS_HAB_ERR)
2178      retCode = BVSB_ERR_HABAV;
2179   else if (*pApStatus & BVSB_APSTATUS_MEM_ERR)
2180      retCode = BVSB_ERR_MEMAV;
2181   else if (*pApStatus & BVSB_APSTATUS_H_ERR)
2182      retCode = BVSB_ERR_HOST_XFER;
2183   else if (*pApStatus & BVSB_APSTATUS_IOMB_ERR)
2184      retCode = BVSB_ERR_IOMB_XFER;
2185   else if (*pApStatus & BVSB_APSTATUS_HABCMD_ERR)
2186      retCode = BVSB_ERR_HAB_ERR;
2187   else if (*pApStatus & BVSB_APSTATUS_AP_ERR)
2188   {
2189      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_MSG1, &sb));
2190      switch (sb)
2191      {
2192         case 1:
2193            retCode = BVSB_ERR_AP_BSC;
2194            break;
2195
2196         case 2:
2197            retCode = BVSB_ERR_AP_STACK;
2198            break;
2199
2200         case 3:
2201            retCode = BVSB_ERR_AP_WD;
2202            break;
2203
2204         case 4:
2205            retCode = BVSB_ERR_AP_ISB;
2206            break;
2207
2208         case 5:
2209            retCode = BVSB_ERR_AP_SCR;
2210            break;
2211
2212         case 6:
2213            retCode = BVSB_ERR_AP_IRQ;
2214            break;
2215
2216         case 7:
2217            retCode = BVSB_ERR_AP_COPY;
2218            break;
2219
2220         case 8:
2221            retCode = BVSB_ERR_AP_EEPROM;
2222            break;
2223
2224         case 9:
2225            retCode = BVSB_ERR_AP_HABAV;
2226            break;
2227
2228         default:
2229            BDBG_ERR(("unknown MSG1 (=0x%02X)\n", sb));
2230            retCode = BVSB_ERR_AP_UNKNOWN;
2231            break;
2232      }
2233   }
2234
2235   done:
2236   return retCode;
2237}
2238
2239
2240/******************************************************************************
2241 BVSB_3520_P_SendHabCommand()
2242******************************************************************************/
2243BERR_Code BVSB_3520_P_SendHabCommand(
2244   BVSB_Handle h,      /* [in] BVSB PI Handle */
2245   uint8_t *write_buf, /* [in] specifies the HAB command to send */
2246   uint8_t write_len,  /* [in] number of bytes in the HAB command */ 
2247   uint8_t *read_buf,  /* [out] holds the data read from the HAB */ 
2248   uint8_t read_len,   /* [in] number of bytes to read from the HAB */
2249   bool bCheckForAck   /* [in] true = determine if the AP has serviced the command */
2250)
2251{
2252   BERR_Code retCode;
2253   
2254   if ((write_len > 127) || (read_len > 127) || (write_len == 0))
2255      return (BERR_TRACE(BERR_INVALID_PARAMETER));
2256
2257   BVSB_CHK_RETCODE(BVSB_3520_P_CheckHab(h));
2258 
2259   /* write the command to the HAB */
2260   BVSB_CHK_RETCODE(BVSB_3520_P_WriteHab(h, 0, write_buf, write_len));
2261
2262   /* wait for the AP to service the HAB, and then read any return data */
2263   BVSB_CHK_RETCODE(BVSB_3520_P_ServiceHab(h, read_buf, read_len, bCheckForAck, write_buf[0] | 0x80));
2264 
2265   done:
2266   return retCode;
2267}
2268
2269
2270/******************************************************************************
2271 BVSB_3520_P_ServiceHab()
2272******************************************************************************/
2273#define BVSB_USE_HAB_INTERRUPT
2274BERR_Code BVSB_3520_P_ServiceHab(
2275   BVSB_Handle h,   /* [in] BVSB PI Handle */
2276   uint8_t *read_buf,  /* [out] holds the data read from the HAB */ 
2277   uint8_t read_len,   /* [in] number of bytes to read from the HAB */
2278   bool bCheckForAck,  /* [in] true = determine if the AP has serviced the command */
2279   uint8_t ack_byte    /* [in] value of the ack byte to expect */
2280)
2281{
2282   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2283   BERR_Code retCode;
2284   uint8_t   sb, ie2, ie3, buf[3];
2285
2286#ifdef BVSB_USE_HAB_INTERRUPT
2287/*uarta_out('S');*/
2288   BVSB_CHK_RETCODE(BVSB_3520_P_EnableHostInterrupt(h, false));
2289   
2290   /* save ie2 */
2291   if ((retCode = BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_IE2, &ie2)) != BERR_SUCCESS)
2292      return retCode;
2293   if ((retCode = BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_IE3, &ie3)) != BERR_SUCCESS)
2294      return retCode;
2295   
2296   /* clear ie1/2/3 */
2297   buf[0] = buf[1] = buf[2] = 0;
2298   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_IE1, buf, 3));
2299
2300   BKNI_WaitForEvent(p3520->hHabDoneEvent, 0);     
2301#endif
2302   
2303   /* send the command */
2304   sb = BCM3520_AP_HABR;
2305   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb));
2306   
2307#ifdef BVSB_USE_HAB_INTERRUPT
2308   /* enable the hab done interrupt mask */
2309   sb = BCM3520_STAT1_HAB_DONE;
2310   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE1, &sb));
2311   
2312   /* wait for HAB done interrupt */ 
2313   if (BVSB_3520_P_WaitForEvent(h, p3520->hHabDoneEvent, 100) == BERR_TIMEOUT)
2314   {
2315      BDBG_ERR(("HAB timeout\n"));   
2316      sb = 0;
2317      BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE1, &sb));
2318      BERR_TRACE(retCode = BVSB_ERR_HAB_TIMEOUT);
2319      goto done;
2320   }
2321#else
2322{
2323   int i;
2324   uint8_t sb;
2325
2326   /* wait for HAB to be serviced (polling) */
2327   for (i = 0; i < 500; i++)
2328   {
2329      BVSB_CHK_RETCODE(BVSB_ReadHostRegister(h, BCM3520_SH_AP_SFR_H_CTL1, &sb));
2330      if ((sb & BCM3520_AP_HABR) == 0)
2331      {
2332         break;
2333      }
2334   }
2335   if (sb & BCM3520_AP_HABR)
2336   {
2337      BERR_TRACE(retCode = BVSB_ERR_HAB_TIMEOUT);
2338      goto done;
2339   }
2340}     
2341#endif
2342   
2343   if (read_len > 0)
2344   {
2345      BVSB_CHK_RETCODE(BVSB_3520_P_ReadHab(h, 0, read_buf, read_len));
2346      if (bCheckForAck)
2347      {
2348         if (ack_byte != read_buf[0])
2349         {
2350            BDBG_ERR(("HAB command not serviced!\n"));
2351            BERR_TRACE(retCode = BVSB_ERR_HAB_NO_ACK);
2352         }
2353      }
2354   }
2355
2356   done:
2357#ifdef BVSB_USE_HAB_INTERRUPT
2358   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE2, &ie2));
2359   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE3, &ie3));
2360#endif
2361   return retCode;
2362}
2363
2364
2365/******************************************************************************
2366 BVSB_3520_P_CheckHab()
2367******************************************************************************/
2368BERR_Code BVSB_3520_P_CheckHab(
2369   BVSB_Handle h    /* [in] BVSB PI Handle */
2370)
2371{
2372   BERR_Code retCode;
2373   BVSB_ApStatus status;
2374
2375   BVSB_CHK_RETCODE(BVSB_GetApStatus(h, &status));
2376   if ((status & BVSB_APSTATUS_HAB_MASK) == BVSB_APSTATUS_HAB_READY)
2377      retCode = BERR_SUCCESS;
2378   else
2379   {
2380      BDBG_ERR(("AP status = 0x%08X\n", (uint32_t)status));
2381      BERR_TRACE(retCode = BVSB_3520_P_DecodeError(h, &status));
2382   }
2383
2384   done:
2385   return retCode;
2386}
2387
2388
2389
2390/******************************************************************************
2391 BVSB_3520_P_EnableHostInterrupt()
2392******************************************************************************/
2393BERR_Code BVSB_3520_P_EnableHostInterrupt(
2394   BVSB_Handle h, /* [in] BVSB PI handle */
2395   bool bEnable   /* [in] true=enables the L1 interrupt on the host processor */
2396)
2397{
2398   BKNI_EnterCriticalSection();
2399   h->settings.i2c.interruptEnableFunc(bEnable, h->settings.i2c.interruptEnableFuncParam);
2400   BKNI_LeaveCriticalSection();   
2401
2402   return BERR_SUCCESS;
2403}
2404
2405/******************************************************************************
2406 BVSB_3520_P_EnableOobLockInterrupt()
2407******************************************************************************/ 
2408BERR_Code BVSB_3520_P_EnableOobLockInterrupt(
2409   BVSB_Handle h, /* [in] BVSB PI Handle */
2410   bool bEnable   /* [in] true = enable lock interrupts, false = disables lock interrupts */
2411)
2412{
2413   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2414   BERR_Code retCode;
2415   uint8_t sb;
2416
2417   BVSB_3520_P_EnableHostInterrupt(h, false);
2418   sb = BCM3520_STAT3_OOB_LOCK_MASK;
2419   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT3, &sb));
2420   sb = bEnable ? BCM3520_STAT3_OOB_LOCKED : 0;
2421   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE3, &sb));
2422   BKNI_WaitForEvent(p3520->hInterruptEvent, 0);   
2423   BKNI_WaitForEvent(p3520->hApiEvent, 0);   
2424   BKNI_WaitForEvent(p3520->hOobLockChangeEvent, 0);   
2425   BVSB_3520_P_EnableHostInterrupt(h, true);
2426
2427done:
2428    return retCode;   
2429}
2430
2431/******************************************************************************
2432 BVSB_3520_P_EnableLockInterrupt()
2433******************************************************************************/ 
2434BERR_Code BVSB_3520_P_EnableLockInterrupt(
2435   BVSB_Handle h, /* [in] BVSB PI Handle */
2436   bool bEnable   /* [in] true = enable lock interrupts, false = disables lock interrupts */
2437)
2438{
2439   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2440   BERR_Code retCode;
2441   uint8_t sb;
2442   
2443   BVSB_3520_P_EnableHostInterrupt(h, false);
2444   sb = BCM3520_STAT2_LOCK_MASK;
2445   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT2, &sb));
2446   sb = bEnable ? BCM3520_STAT2_IN_LOCK : 0;
2447   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE2, &sb));
2448   BKNI_WaitForEvent(p3520->hInterruptEvent, 0);   
2449   BKNI_WaitForEvent(p3520->hApiEvent, 0);   
2450   BKNI_WaitForEvent(p3520->hLockChangeEvent, 0);   
2451   BVSB_3520_P_EnableHostInterrupt(h, true);
2452   
2453   done:
2454   return retCode;   
2455}
2456
2457
2458/******************************************************************************
2459 BVSB_3520_P_EnableInitDoneInterrupt()
2460******************************************************************************/ 
2461BERR_Code BVSB_3520_P_EnableInitDoneInterrupt(
2462   BVSB_Handle h /* [in] BVSB PI Handle */
2463)
2464{
2465   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2466   BERR_Code retCode;
2467   uint8_t sb;
2468   
2469   sb = BCM3520_STAT2_INIT_DONE;
2470   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT2, &sb));
2471   sb = BCM3520_STAT2_INIT_DONE;
2472   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE2, &sb));
2473   BKNI_WaitForEvent(p3520->hInterruptEvent, 0);   
2474   BKNI_WaitForEvent(p3520->hApiEvent, 0);   
2475   BKNI_WaitForEvent(p3520->hInitDoneEvent, 0);   
2476   
2477   done:
2478   return retCode;
2479}
2480
2481
2482/******************************************************************************
2483 BVSB_3520_P_EnableBscInterrupt()
2484******************************************************************************/ 
2485BERR_Code BVSB_3520_P_EnableBscInterrupt(
2486   BVSB_Handle h, /* [in] BVSB PI Handle */
2487   bool bEnable   /* [in] true = enable BSC finished interrupt */
2488)
2489{
2490   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2491   BERR_Code retCode;
2492   uint8_t sb = bEnable ? BCM3520_STAT2_BSC : 0;
2493   
2494   BVSB_3520_P_EnableHostInterrupt(h, false);
2495   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_IE2, &sb));
2496   BKNI_WaitForEvent(p3520->hInterruptEvent, 0);   
2497   BKNI_WaitForEvent(p3520->hBscEvent, 0);   
2498   BVSB_3520_P_EnableHostInterrupt(h, true);
2499   
2500   done:
2501   return retCode;
2502}
2503
2504
2505/******************************************************************************
2506 BVSB_3520_P_DecodeInterrupt()
2507******************************************************************************/
2508BERR_Code BVSB_3520_P_DecodeInterrupt(BVSB_Handle h)
2509{
2510   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2511   BERR_Code retCode;
2512   uint8_t   h_ie[3], h_fstat[3], new_stat2, new_stat3;
2513
2514   BVSB_CHK_RETCODE(BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_FSTAT1, h_fstat, 3));
2515   BVSB_CHK_RETCODE(BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_IE1, h_ie, 3));
2516   
2517   new_stat2 = 0;
2518   new_stat3 = 0;
2519   
2520   if (!h_fstat[0] && !h_fstat[1] && !h_fstat[2])
2521   {
2522      return BERR_SUCCESS;
2523   }
2524   
2525   if (h_fstat[0] & BCM3520_STAT1_HAB_DONE)
2526   {
2527      h_ie[0] = 0;
2528      BKNI_SetEvent(p3520->hHabDoneEvent);
2529   }
2530   
2531   if (h_fstat[1] & BCM3520_STAT2_INIT_DONE)
2532   {
2533      h_ie[1] &= ~BCM3520_STAT2_INIT_DONE;
2534      BKNI_SetEvent(p3520->hInitDoneEvent);
2535   }
2536     
2537   if (h_fstat[1] & BCM3520_STAT2_LOCK_MASK)
2538   {
2539      new_stat2 |= BCM3520_STAT2_LOCK_MASK;
2540      h_ie[1] &= ~BCM3520_STAT2_LOCK_MASK;
2541      BKNI_SetEvent(p3520->hLockChangeEvent);
2542      if (h_fstat[1] & BCM3520_STAT2_IN_LOCK)
2543      {
2544         h_ie[1] |= BCM3520_STAT2_OUT_OF_LOCK;
2545         BDBG_MSG(("BCM3520_STAT2_OUT_OF_LOCK (h_fstat[1] = 0x%08x)\n",h_fstat[1]));
2546      }
2547      else
2548      {
2549         h_ie[1] |= BCM3520_STAT2_IN_LOCK; 
2550         BDBG_MSG(("BCM3520_STAT2_OUT_OF_LOCK (h_fstat[1] = 0x%08x)\n",h_fstat[1]));
2551      }
2552   }
2553
2554   if (h_fstat[2] & BCM3520_STAT3_OOB_LOCK_MASK)
2555   {
2556      new_stat3 |= BCM3520_STAT3_OOB_LOCK_MASK;
2557      h_ie[2] &= ~BCM3520_STAT3_OOB_LOCK_MASK;
2558      BKNI_SetEvent(p3520->hOobLockChangeEvent);
2559      if (h_fstat[2] & BCM3520_STAT3_OOB_LOCKED)
2560      {
2561         h_ie[2] |= BCM3520_STAT3_OOB_NOT_LOCKED;
2562      }
2563      else
2564      {
2565         h_ie[2] |= BCM3520_STAT3_OOB_LOCKED; 
2566      }
2567   }
2568         
2569   /* reset ie registers */
2570   BVSB_CHK_RETCODE(BREG_I2C_Write(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_IE1, h_ie, 3));   
2571
2572   /* clear the interrupt status */
2573   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT2, &new_stat2));             
2574   BVSB_CHK_RETCODE(BVSB_WriteHostRegister(h, BCM3520_SH_AP_SFR_H_STAT3, &new_stat3));             
2575   done:
2576   return retCode;
2577}
2578
2579
2580
2581/******************************************************************************
2582 BVSB_3520_P_AcquireVsb()
2583******************************************************************************/
2584BERR_Code BVSB_3520_P_AcquireVsb(
2585   BVSB_Handle h,                    /* [in] BVSB handle */
2586   const BVSB_InbandParams *pParams  /* [in] inband acquisition parameters */
2587)
2588{
2589   BERR_Code retCode;
2590   uint8_t   hab[16];
2591   BDBG_MSG(("%s:%d(bAutoAcq,bFastAcq,bNtscSweep,bRfiSweep,bTei,bTerr) (%d,%d,%d,%d,%d,%d) (0x%08x,0x%08x)\n",
2592             __FUNCTION__,__LINE__,
2593             h->settings.vsb.bAutoAcq,h->settings.vsb.bFastAcq,h->settings.vsb.bNtscSweep,
2594             h->settings.vsb.bRfiSweep,h->settings.vsb.bTei,h->settings.vsb.bTerr,pParams->ifFreqOffset,pParams->symbolRateOffset));
2595
2596   hab[0] = 0x0A;
2597   hab[1] = hab[2] = hab[10] = 0x00;
2598   hab[3] = 0x01;
2599   
2600   hab[1] |= ((h->settings.vsb.bAutoAcq) ? 0x20 : 0x00);
2601   hab[1] |= ((h->settings.vsb.bFastAcq) ? 0x01 : 0x00);
2602   hab[1] |= ((h->settings.vsb.bNtscSweep) ? 0x08 : 0x00);
2603   hab[1] |= ((h->settings.vsb.bRfiSweep) ? 0x04 : 0x00);
2604   hab[2] |= ((h->settings.vsb.bTei) ? 0x01 : 0x00);
2605   hab[2] |= ((h->settings.vsb.bTerr) ? 0x80 : 0x00);
2606
2607   switch (pParams->mode)
2608   {
2609      case BVSB_InbandMode_e8VSB:
2610         /*hab[2] |= 0x00;*/
2611         break;
2612
2613      case BVSB_InbandMode_e16VSB:
2614         hab[2] |= 0x40;
2615         break;
2616
2617      default:
2618         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2619   }
2620
2621   switch (h->settings.vsb.bw)
2622   {
2623      case BVSB_PhaseLoopBw_eLow:
2624         /*hab[2] |= 0x00;*/
2625         break;
2626         
2627      case BVSB_PhaseLoopBw_eMedium:
2628         hab[2] |= 0x02;
2629         break;
2630         
2631      case BVSB_PhaseLoopBw_eHigh:
2632         hab[2] |= 0x04;
2633         break;
2634         
2635      default:
2636         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2637   }
2638   
2639   if ((pParams->ifFreqOffset < -2097152) || (pParams->ifFreqOffset > 2097151))
2640      return (BERR_TRACE(BERR_INVALID_PARAMETER));
2641     
2642   if ((pParams->symbolRateOffset < -32768) || (pParams->symbolRateOffset > 32767))
2643      return (BERR_TRACE(BERR_INVALID_PARAMETER));
2644   
2645   hab[4] = (pParams->ifFreqOffset >> 24);
2646   hab[5] = (pParams->ifFreqOffset >> 16);
2647   hab[6] = (pParams->ifFreqOffset >> 8);
2648   hab[7] = (pParams->ifFreqOffset & 0xFF);
2649   
2650   hab[8] = (pParams->symbolRateOffset >> 8);
2651   hab[9] = (pParams->symbolRateOffset & 0xFF);
2652
2653   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 11, hab, 1, true));
2654
2655   done:
2656   return retCode;
2657}
2658
2659
2660/******************************************************************************
2661 BVSB_3520_P_AcquireQam()
2662******************************************************************************/
2663BERR_Code BVSB_3520_P_AcquireQam(
2664   BVSB_Handle h,                    /* [in] BVSB handle */
2665   const BVSB_InbandParams *pParams  /* [in] inband acquisition parameters */
2666)
2667{
2668   BERR_Code retCode;
2669   uint8_t   hab[16];
2670   uint32_t  symbol_rate;
2671
2672   /* If AnnexA then first set symbolrate */
2673   if ( pParams->mode >= BVSB_InbandMode_e256QAM_A )
2674   {
2675       /* not possible to be greater than 8 Mhz channel */
2676       if (( pParams->symbolRate > 8000000 ) || ( pParams->symbolRate < 0) )
2677       {
2678           BDBG_WRN(("symbolrate greater than 8Mhz!\n"));
2679           symbol_rate = 8000000;
2680       }
2681       else
2682           symbol_rate = pParams->symbolRate;
2683
2684       hab[0] = 0x13;
2685       hab[1] = 0x00;
2686       hab[2] = 0x24;
2687       hab[3] = 0x04;
2688       hab[4] = ((symbol_rate & 0xFF000000) >> 24);
2689       hab[5] = ((symbol_rate & 0xFF0000) >> 16 );
2690       hab[6] = ((symbol_rate & 0xFF00) >> 8 );
2691       hab[7] = (symbol_rate & 0xFF);
2692       hab[8] = 0x00;
2693       
2694       BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 9, hab, 1, true));
2695   }
2696
2697   hab[0] = 0x0B;
2698   hab[1] = hab[2] = hab[0x0A] = 0x00;
2699   hab[3] = 0x03;
2700   
2701   hab[1] |= ((h->settings.qam.bAutoAcq) ? 0x20 : 0x00);
2702   hab[1] |= ((h->settings.qam.bFastAcq) ? 0x01 : 0x00);
2703   hab[1] |= ((h->settings.qam.bSpinv) ? 0x10 : 0x00);
2704   hab[1] |= ((h->settings.qam.bEq) ? 0x04 : 0x00);
2705   hab[1] |= ((h->settings.qam.bCh) ? 0x02 : 0x00);
2706   
2707   hab[2] |= ((h->settings.qam.bTerr) ? 0x80 : 0x00);
2708   hab[2] |= ((pParams->mode >= BVSB_InbandMode_e256QAM_A) ? 0x00 : 0x08);
2709   hab[3] |= ((h->settings.qam.bDavic) ? 0x08 : 0x00);
2710   hab[3] |= (((uint8_t)(h->settings.qam.idepth) << 4) & 0xF0);
2711
2712   switch (pParams->mode)
2713   {
2714      case BVSB_InbandMode_e1024QAM_B:
2715         hab[2] |= 0x70;
2716         break;
2717
2718      case BVSB_InbandMode_e512QAM_B:
2719         hab[2] |= 0x60;
2720         break;
2721           
2722      case BVSB_InbandMode_e256QAM_B:
2723         hab[2] |= 0x50;
2724         break;
2725
2726      case BVSB_InbandMode_e128QAM_B:
2727         hab[2] |= 0x40;
2728         break;
2729
2730      case BVSB_InbandMode_e64QAM_B:
2731         hab[2] |= 0x30;
2732         break;
2733
2734      case BVSB_InbandMode_e256QAM_A:
2735         hab[2] |= 0x50;
2736         break;
2737
2738      case BVSB_InbandMode_e128QAM_A:
2739         hab[2] |= 0x40;
2740         break;
2741
2742      case BVSB_InbandMode_e64QAM_A:
2743         hab[2] |= 0x30;
2744         break;
2745
2746      case BVSB_InbandMode_e32QAM_A:
2747         hab[2] |= 0x20;
2748         break;
2749
2750      case BVSB_InbandMode_e16QAM_A:
2751         hab[2] |= 0x10;
2752         break;
2753
2754      default:
2755         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2756   }
2757
2758   switch (h->settings.qam.bw)
2759   {
2760      case BVSB_PhaseLoopBw_eLow:
2761         /*hab[2] |= 0x00;*/
2762         break;
2763         
2764      case BVSB_PhaseLoopBw_eMedium:
2765         hab[2] |= 0x02;
2766         break;
2767         
2768      case BVSB_PhaseLoopBw_eHigh:
2769         hab[2] |= 0x04;
2770         break;
2771         
2772      default:
2773         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2774   }
2775   
2776   switch (h->settings.qam.nyquist)
2777   {
2778      case BVSB_NyquistFilter_e12:
2779         /*hab[1] |= 0x00;*/
2780         break;
2781
2782      case BVSB_NyquistFilter_e15:
2783         hab[1] |= 0x40;
2784         break;
2785
2786      case BVSB_NyquistFilter_e18:
2787         hab[1] |= 0x80;
2788         break;
2789
2790      default:
2791         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2792   }
2793
2794   if ((pParams->ifFreqOffset < -2097152) || (pParams->ifFreqOffset > 2097151))
2795      return (BERR_TRACE(BERR_INVALID_PARAMETER));
2796     
2797   if ((pParams->symbolRateOffset < -32768) || (pParams->symbolRateOffset > 32767))
2798      return (BERR_TRACE(BERR_INVALID_PARAMETER));
2799   
2800   hab[4] = (pParams->ifFreqOffset >> 24);
2801   hab[5] = (pParams->ifFreqOffset >> 16);
2802   hab[6] = (pParams->ifFreqOffset >> 8);
2803   hab[7] = (pParams->ifFreqOffset & 0xFF);
2804   
2805   hab[8] = (pParams->symbolRateOffset >> 8);
2806   hab[9] = (pParams->symbolRateOffset & 0xFF);
2807
2808   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 11, hab, 1, true));
2809
2810   done:
2811   return retCode;
2812}
2813
2814
2815/******************************************************************************
2816 BVSB_3520_P_AcquireNtsc()
2817******************************************************************************/
2818BERR_Code BVSB_3520_P_AcquireNtsc(
2819   BVSB_Handle h,                    /* [in] BVSB handle */
2820   const BVSB_InbandParams *pParams  /* [in] inband acquisition parameters */
2821)
2822{
2823   BERR_Code retCode;
2824   uint8_t   hab[9];
2825
2826   hab[0] = 0x0C;
2827   hab[1] = hab[2] = hab[8] = 0x00;
2828   hab[3] = 0x01;
2829   
2830   hab[1] |= ((h->settings.ntsc.bFastAcq) ? 0x01 : 0x00);
2831   hab[1] |= ((h->settings.ntsc.bAutoAcq) ? 0x20 : 0x00);
2832   hab[2] |= ((h->settings.ntsc.bTerr) ? 0x80 : 0x00);
2833
2834   switch (h->settings.ntsc.bw)
2835   {
2836      case BVSB_PhaseLoopBw_eLow:
2837         /*hab[2] |= 0x00;*/
2838         break;
2839         
2840      case BVSB_PhaseLoopBw_eMedium:
2841         hab[2] |= 0x02;
2842         break;
2843         
2844      case BVSB_PhaseLoopBw_eHigh:
2845         hab[2] |= 0x04;
2846         break;
2847         
2848      default:
2849         return (BERR_TRACE(BERR_INVALID_PARAMETER));
2850   }
2851   
2852   if ((pParams->ifFreqOffset < -2097152) || (pParams->ifFreqOffset > 2097151))
2853      return BERR_INVALID_PARAMETER;
2854     
2855   hab[4] = (pParams->ifFreqOffset >> 24);
2856   hab[5] = (pParams->ifFreqOffset >> 16);
2857   hab[6] = (pParams->ifFreqOffset >> 8);
2858   hab[7] = (pParams->ifFreqOffset & 0xFF);
2859   
2860   BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 9, hab, 1, true));
2861
2862   done:
2863   return retCode;
2864}
2865
2866
2867/******************************************************************************
2868 BERR_Code BVSB_3520_P_WaitForEvent()
2869******************************************************************************/
2870BERR_Code BVSB_3520_P_WaitForEvent(
2871   BVSB_Handle h,             /* [in] BVSB PI Handle */
2872   BKNI_EventHandle hEvent,   /* [in] event to wait on */
2873   int timeoutMsec            /* [in] timeout in milliseconds */
2874)
2875{
2876   BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);
2877   BERR_Code retCode = BERR_SUCCESS;
2878
2879        //RLQ
2880   BVSB_3520_P_EnableHostInterrupt(h, true);
2881   while (1)
2882   {   
2883//RLQ
2884      //BVSB_3520_P_EnableHostInterrupt(h, true);
2885      if ((retCode = BKNI_WaitForEvent(p3520->hApiEvent, timeoutMsec)) == BERR_TIMEOUT)
2886         break;
2887
2888      BVSB_3520_P_DecodeInterrupt(h);
2889      if ((retCode = BKNI_WaitForEvent(hEvent, 0)) == BERR_SUCCESS)
2890         break;
2891   }
2892//RLQ
2893   //BVSB_3520_P_EnableHostInterrupt(h, true);
2894   
2895#if 0   
2896   if (retCode == BERR_TIMEOUT)
2897   {
2898         BVSB_3520_P_Handle *p3520 = (BVSB_3520_P_Handle *)(h->pImpl);     
2899         BVSB_ApStatus apstatus;
2900         unsigned char h_ie[2];
2901         
2902         BVSB_3520_P_GetApStatus(h, &apstatus);
2903         BREG_I2C_Read(p3520->hRegister, h->settings.i2c.chipAddr, BCM3520_SH_AP_SFR_H_IE1, h_ie, 2);
2904         
2905         printf("BVSB_3520_P_WaitForEvent() timeout, %08X, %02X, %02X\n", apstatus, h_ie[0], h_ie[1]);
2906   }
2907#endif   
2908   return retCode;
2909
2910}
2911
2912/******************************************************************************
2913 GetChipRevision()
2914******************************************************************************/
2915BERR_Code BVSB_3520_P_GetChipRevision(
2916   BVSB_Handle h,             /* [in] BVSB PI Handle */
2917   uint8_t *revision          /* [out] revision id of the chip */
2918)
2919{
2920        BERR_Code retCode;
2921        uint32_t val;
2922
2923        BVSB_CHK_RETCODE(BVSB_3520_P_ReadMbox( h, BCM3520_TM_CHIP_ID, &val ));
2924        *revision = (uint8_t)(val & 0xFF);
2925
2926done:
2927        return retCode;
2928         
2929}
2930
2931/******************************************************************************
2932 SetInbandIfFreq()
2933******************************************************************************/
2934BERR_Code BVSB_3520_P_SetInbandIfFreq(
2935        BVSB_Handle h,
2936        uint32_t If_freq_hz
2937        )
2938{
2939    uint8_t buf[4];
2940
2941        buf[0] = (uint8_t)(If_freq_hz >> 24);
2942        buf[1] = (uint8_t)(If_freq_hz >> 16);
2943        buf[2] = (uint8_t)(If_freq_hz >> 8);
2944        buf[3] = (uint8_t)(If_freq_hz & 0xFF);
2945
2946        return BVSB_3520_P_WriteConfig( h, BVSB_CONFIG_INBAND_IF_FREQ, buf, 4);
2947}
2948
2949/******************************************************************************
2950   SetOobInterfaceControl()
2951******************************************************************************/
2952BERR_Code BVSB_3520_P_SetOobInterfaceControl(
2953   BVSB_Handle  h,    /* [in] BVSB handle */
2954   BVSB_OobClockSuppression clockSuppression,
2955   BVSB_OobClock clock
2956)
2957{
2958    BERR_Code retCode;
2959    uint8_t pin_ctrl = 0;
2960    uint8_t hab[3];
2961
2962    BVSB_CHK_RETCODE(BVSB_3520_P_ReadConfig(h, BVSB_CONFIG_PIN_CTRL_5, &pin_ctrl, 1));
2963    pin_ctrl &= 0x3F;
2964
2965    if (clockSuppression == BVSB_OobClockSuppression_eSuppressed)
2966        pin_ctrl |= 0x80;
2967
2968    if (clock == BVSB_OobClock_eInverted)
2969        pin_ctrl |= 0x40;
2970
2971    /* pad_control_1 */
2972    hab[0] = 0x23;
2973    hab[1] = pin_ctrl;
2974    hab[2] = 0;
2975
2976    BVSB_CHK_RETCODE(BVSB_3520_P_SendHabCommand(h, hab, 3, hab, 1, true));
2977
2978    BVSB_CHK_RETCODE(BVSB_3520_P_ReadConfig(h, BVSB_CONFIG_PIN_CTRL_5, &pin_ctrl, 1));
2979done:
2980   return retCode;
2981}
2982
2983
2984
2985
2986                                                                       
Note: See TracBrowser for help on using the repository browser.