source: svn/newcon3bcm2_21bu/nexus/modules/frontend/common/src/nexus_frontend_ast.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: 67.9 KB
Line 
1/******************************************************************************
2 *    (c)2008-2011 Broadcom Corporation
3 *
4 * This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 * and may only be used, duplicated, modified or distributed pursuant to the terms and
6 * conditions of a separate, written license agreement executed between you and Broadcom
7 * (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 * no license (express or implied), right to use, or waiver of any kind with respect to the
9 * Software, and Broadcom expressly reserves all rights in and to the Software and all
10 * intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 * Except as expressly set forth in the Authorized License,
15 *
16 * 1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 * and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 * THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 * USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 * ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: nexus_frontend_ast.c $
39 * $brcm_Revision: 78 $
40 * $brcm_Date: 12/5/11 3:09p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/frontend/common/src/nexus_frontend_ast.c $
47 *
48 * 78   12/5/11 3:09p mphillip
49 * SW7346-580: Add NEXUS_Frontend_GetFastStatus support for BAST-based
50 *  frontends
51 *
52 * 77   11/11/11 3:50p mphillip
53 * SW7346-516: Merge to main
54 *
55 * SW7346-516/1   11/8/11 5:18p mphillip
56 * SW7346-516: Allow diseqc to be powered down separately
57 *
58 * 76   7/11/11 12:36p vishk
59 * SWSATFE-132: Add nexus support for 4528 satellite frontend for 97425
60 *  SATIPSW platform.
61 *
62 * 75   6/23/11 7:47p vishk
63 * SW7422-272: Add nexus gpio support for 4506 tuners. Bug fix.
64 *
65 * 74   6/23/11 3:11p vishk
66 * SW7346-165: NEXUS Frontend changes for multi-tuner board are not
67 *  platform independent
68 *
69 * 73   6/13/11 5:09p jrubio
70 * SW7346-182: fix network spec pointer
71 *
72 * 72   6/9/11 7:33p randyjew
73 * SW7346-230: Fix compile warnings
74 *
75 * 71   5/16/11 9:11a jrubio
76 * SW7346-182: make use of handle not device
77 *
78 * 70   5/13/11 11:07a jrubio
79 * SW7346-182: adding network spec for g3
80 *
81 * 69   2/22/11 5:12p jrubio
82 * SW7346-17: fix peak scan functions for 7346/7344
83 *
84 * 68   1/20/11 10:54a xhuang
85 * SW7358-24: Add support for 7358
86 *
87 * 67   1/17/11 11:16a jrubio
88 * SW7344-9: fix compile warning
89 *
90 * 66   12/8/10 9:48a jrubio
91 * SW7344-9: add G3 Support
92 *
93 * 65   11/16/10 2:20p erickson
94 * SW7405-4968: add NEXUS_FrontendSatelliteSettings.networkSpec
95 *
96 * 64   10/5/10 3:40p jgarrett
97 * SW7335-873: Adding searchRange option
98 *
99 * 63   10/1/10 4:57p mward
100 * SWSATFE-80: fixed DISEQC_CTL2 bit definition for tone burst B (4501),
101 *  updated DISEQC_CTL2 bit definitions (4506).
102 *
103 * 62   9/1/10 4:11p erickson
104 * SW7325-800: add NEXUS_FrontendCapabilities.diseqc and use for internal
105 *  configuration as wel
106 *
107 * 61   4/16/10 10:24a erickson
108 * SW3556-1092: added frontend master I2C (MI2c) interface for 4501/4506
109 *
110 * 60   11/10/09 5:25p jrubio
111 * SW7342-52: Make sure that AST Power calls are covered by
112 *  NEXUS_POWER_MANAGEMENT Flag
113 *
114 * 59   10/8/09 5:27p erickson
115 * SW7400-2562: fix DISEQC_CTL2_EXP_REPLY_DISABLE logic. don't overwrite
116 *  previous values.
117 *
118 * 58   10/5/09 11:52a erickson
119 * SW7400-2555: fix NEXUS_Frontend_P_Ast_SetDiseqcSettings WriteConfig
120 *  buffer for 4501 & 4506
121 *
122 * 57   9/23/09 1:27p erickson
123 * SW7335-561: create FTM task callback per AST core
124 *
125 * 56   9/16/09 12:08p erickson
126 * SW7405-2980: support more variables in NEXUS_Frontend_SetDiseqcSettings
127 *  on 4501/4506
128 *
129 * 55   8/20/09 12:59p erickson
130 * PR57239: fix NEXUS_Frontend_P_Ast_GetChannel to handle extension
131 *  handles
132 *
133 * 54   8/20/09 12:57p erickson
134 * PR57471: convert to NEXUS_FrontendSatelliteStatusError enum
135 *
136 * 53   8/12/09 3:07p erickson
137 * PR57471: added NEXUS_FrontendSatelliteStatus.statusAvailable
138 *
139 * 52   8/12/09 10:38a erickson
140 * PR57598: added NEXUS_FrontendDiseqcStatus.sendStatus
141 *
142 * 51   8/3/09 9:24a erickson
143 * PR57239: fix non-AST platforms
144 *
145 * 50   7/31/09 3:40p erickson
146 * PR57239: move NEXUS_Frontend_P_GetAstDevice and related functions into
147 *  nexus_frontend_ast.c
148 *
149 * 49   7/31/09 2:22p erickson
150 * PR57239: don't propogate BAST_GetChannelStatus failure. just report
151 *  status that it's not locked.
152 *
153 * 48   7/30/09 5:05p erickson
154 * PR57175: sync up NEXUS_FrontendDiseqcMessageStatus with AST PI.
155 *
156 * 47   7/30/09 3:59p jtna
157 * PR42924: remove unneeded code
158 *
159 * 46   7/21/09 3:21p erickson
160 * PR56834: deprecated NEXUS_FrontendSatelliteStatus.lnaStatus for all sat
161 *  demods except 4501
162 *
163 * 45   7/16/09 2:27p erickson
164 * PR56773: reorder BAST_GetDiseqcVoltage cal
165 *
166 * 44   7/16/09 9:32a erickson
167 * PR56832: fix NEXUS_FrontendSatelliteStatus.tunerLocked
168 *
169 * 43   7/14/09 11:12a erickson
170 * PR56791: fix 4501 and 4506
171 *
172 * 42   7/14/09 10:40a erickson
173 * PR56791: added NEXUS_FrontendDiseqcSettings.replyDisabled
174 *
175 * 41   7/13/09 4:47p erickson
176 * PR56773: added NEXUS_FrontendDiseqcStatus
177 *
178 * 40   7/13/09 4:15p erickson
179 * PR56772: force use of NEXUS_FrontendSatelliteInversion_eScan
180 *
181 * 39   7/13/09 3:48p erickson
182 * PR56509: add NEXUS_FrontendDiseqcSettings.lnbEnabled
183 *
184 * 38   7/8/09 3:13p erickson
185 * PR56607: remove unused NEXUS_Frontend_P_Register function
186 *
187 * 37   7/8/09 6:53a erickson
188 * PR56607: add optional registerExtension operator so that callbacks can
189 *  be recreated with the handle that the user gets. this allows
190 *  NEXUS_StopCallbacks to work.
191 *
192 * 36   6/30/09 6:53p jtna
193 * PR56368: support NEXUS_MAX_FRONTENDS < num AST channels
194 *
195 * 35   6/24/09 9:31a erickson
196 * PR53078: added NEXUS_FrontendSatelliteStatus.agf
197 *
198 * 34   6/16/09 3:54p jgarrett
199 * PR 55888: Adding envelope mode
200 *
201 * 33   6/9/09 2:25p erickson
202 * PR55699: move NEXUS_AstDevice definition to private header file to
203 *  enable AST extension
204 *
205 * 32   6/4/09 10:29a jtna
206 * PR54416: nexus support for satellite scanning
207 *
208 * 31   5/26/09 12:16p erickson
209 * PR55403: added NEXUS_FrontendDiseqcToneBurst
210 *
211 * 30   5/15/09 12:01p erickson
212 * PR54843: added untune
213 *
214 * 29   5/11/09 4:29p erickson
215 * PR53078: get time of tune or resetStatus so that elapsed time can be
216 *  returned with status
217 *
218 * 28   4/3/09 4:46p erickson
219 * PR53078: fix logic for adding standard acqSettings.acq_ctl settings
220 *
221 * 27   4/2/09 2:29p erickson
222 * PR53078: satellite api additions
223 *
224 * 26   3/16/09 5:37p jrubio
225 * PR50837: Get rid of more WRN's.
226 *
227 * 25   3/5/09 5:51p jrubio
228 * PR50837: make BDBG_WRN msg's BDBG_MSG
229 *
230 * 24   2/11/09 12:24p jrubio
231 * PR50837: make sure AST lock is a debug msg not a wrn
232 *
233 * 23   2/9/09 5:04p jgarrett
234 * PR 50837: Merge to main branch
235 *
236 * PR50837/1   1/29/09 10:38a jgarrett
237 * PR 50837: Removing board specifics
238 *
239 * 22   1/8/09 11:33a katrep
240 * PR48985: Fixed compiler warning 7405 build
241 *
242 * 21   1/5/09 6:54p agin
243 * PR48985: Correct the code rates for turbo.
244 *
245 * 20   12/22/08 9:48p agin
246 * PR49982: Add reset diseqc.
247 *
248 * 19   12/18/08 9:35p agin
249 * PR49983: Incorrect channel status reported for power, BER, SNR for
250 *  97335 AST.
251 *
252 * 18   11/15/08 7:12a agin
253 * PR48985: Support LDPC and Turbo at the same time.
254 *
255 * 17   11/12/08 6:36p agin
256 * PR48907: Need to support Turbo 8PSK for 97325/97335.
257 *
258 * 16   10/21/08 10:51a agin
259 * PR47371: Add DVB-S2 (8PSK) Support.
260 *
261 * 15   8/22/08 4:27p jrubio
262 * PR42336: fix Frequency for 7335
263 *
264 * 14   8/5/08 10:45a jrubio
265 * PR42336: take out "//" from comments
266 *
267 * 13   8/1/08 5:38p erickson
268 * PR45361: c89 fixes
269 *
270 * 12   7/11/08 5:06p jtna
271 * PR42924: Add channel change measurements functionality
272 *
273 * 11   7/2/08 9:20a erickson
274 * PR42336: fix non-73xx
275 *
276 * 10   7/1/08 5:33p agin
277 * PR42336: add external tuner support
278 *
279 * 9   6/19/08 6:20p jrubio
280 *  PR42593: fix 7325 statement for diseq
281 *
282 * 8   6/16/08 5:42p jrubio
283 * PR42593: Make sure that we do not block 4056/4501 diseqc calls
284 *
285 * 7   6/3/08 10:35a agin
286 * PR42336: Temporarily comment out untested code for 7325.
287 *
288 * 6   6/3/08 8:38a agin
289 * PR42336: Control frontend filters based on freq for 7335.  Level to
290 *  bcm73xxast_diags.c, \33.
291 *
292 * 5   6/1/08 10:42a agin
293 * PR42336: Fixed diseqc for 7335.
294 *
295 * 4   5/29/08 10:04a jrubio
296 * PR42593: make sure 7335 diseq setting set are allowed for the first two
297 *  channels
298 *
299 * 3   5/22/08 5:54p jrubio
300 * PR42593: add multiple tuner support for 7325/7335 -external tuner does
301 *  not control the diseqc
302 *
303 * 2   4/2/08 11:31a erickson
304 * PR40198: fix DEBUG=n warning
305 *
306 * 1   3/14/08 9:47a jgarrett
307 * PR 39985: adding ast
308 *
309 *****************************************************************************/
310#include "nexus_frontend_module.h"
311#include "nexus_frontend_ast.h"
312#include "nexus_i2c.h"
313#include "priv/nexus_i2c_priv.h"
314#include "breg_i2c_priv.h"
315#include "bi2c.h" /* status error codes */
316
317BDBG_MODULE(nexus_frontend_ast);
318BDBG_OBJECT_ID(NEXUS_AstDevice);
319
320BTRC_MODULE_DECLARE(ChnChange_Tune);
321BTRC_MODULE_DECLARE(ChnChange_TuneLock);
322
323#if defined NEXUS_FRONTEND_73XX
324#define PEAK_SCAN_SYM_RATE_MIN      BCM73XX_CONFIG_PEAK_SCAN_SYM_RATE_MIN
325#define LEN_PEAK_SCAN_SYM_RATE_MIN  BCM73XX_CONFIG_LEN_PEAK_SCAN_SYM_RATE_MIN
326#define PEAK_SCAN_SYM_RATE_MAX      BCM73XX_CONFIG_PEAK_SCAN_SYM_RATE_MAX
327#define LEN_PEAK_SCAN_SYM_RATE_MAX  BCM73XX_CONFIG_LEN_PEAK_SCAN_SYM_RATE_MAX
328#endif
329
330/***************************************************************************
331Frontend Callback Prototypes
332***************************************************************************/
333static NEXUS_Error NEXUS_Frontend_P_Ast_TuneSatellite(void *handle, const NEXUS_FrontendSatelliteSettings *pSettings);
334static void NEXUS_Frontend_P_Ast_Untune(void *handle);
335static NEXUS_Error NEXUS_Frontend_P_Ast_GetSatelliteStatus(void *handle, NEXUS_FrontendSatelliteStatus *pStatus);
336static void NEXUS_Frontend_P_Ast_GetDiseqcSettings(void *handle, NEXUS_FrontendDiseqcSettings *pSettings);
337static NEXUS_Error NEXUS_Frontend_P_Ast_SetDiseqcSettings(void *handle, const NEXUS_FrontendDiseqcSettings *pSettings);
338static NEXUS_Error NEXUS_Frontend_P_Ast_GetDiseqcStatus( void *handle, NEXUS_FrontendDiseqcStatus *pStatus );
339static NEXUS_Error NEXUS_Frontend_P_Ast_SendDiseqcMessage(void *handle, const uint8_t *pSendData, size_t sendDataSize, const NEXUS_CallbackDesc *pSendComplete);
340static NEXUS_Error NEXUS_Frontend_P_Ast_GetDiseqcReply(void *handle, NEXUS_FrontendDiseqcMessageStatus *pStatus, uint8_t *pReplyBuffer, size_t pReplyBufferSize, size_t *pReplyLength);
341static NEXUS_Error NEXUS_Frontend_P_Ast_ResetDiseqc(void *handle, uint8_t options);
342static NEXUS_Error NEXUS_Frontend_P_Ast_SendDiseqcAcw(void *handle, uint8_t codeWord);
343static void NEXUS_Frontend_P_Ast_ResetStatus(void *handle);
344static void NEXUS_Frontend_P_Ast_Close(NEXUS_FrontendHandle handle);
345static NEXUS_Error NEXUS_Frontend_P_Ast_GetSoftDecisions(void *handle, NEXUS_FrontendSoftDecision *pDecisions, size_t length);
346static void NEXUS_Frontend_P_Ast_LockEventHandler(void *pParam);
347static void NEXUS_Frontend_P_Ast_DiseqcEventHandler(void *pParam);
348static void NEXUS_Frontend_P_Ast_PeakscanEventHandler(void *pParam);
349static NEXUS_Error NEXUS_Frontend_P_Ast_ReadSatelliteConfig( void *handle, unsigned id, void *buffer, unsigned bufferSize );
350static NEXUS_Error NEXUS_Frontend_P_Ast_WriteSatelliteConfig( void *handle, unsigned id, const void *buffer, unsigned bufferSize );
351static NEXUS_Error NEXUS_Frontend_P_Ast_SatellitePeakscan( void *handle, const NEXUS_FrontendSatellitePeakscanSettings *pSettings );
352static NEXUS_Error NEXUS_Frontend_P_Ast_GetSatellitePeakscanResult( void *handle, NEXUS_FrontendSatellitePeakscanResult *pResult );
353static NEXUS_Error NEXUS_Frontend_P_Ast_RegisterExtension(NEXUS_FrontendHandle parentHandle, NEXUS_FrontendHandle extensionHandle);
354static BERR_Code NEXUS_Frontend_P_Ast_I2cReadNoAddr(void * context, uint16_t chipAddr, uint8_t *pData, size_t length);
355static BERR_Code NEXUS_Frontend_P_Ast_I2cWriteNoAddr(void * context, uint16_t chipAddr, const uint8_t *pData, size_t length);
356static NEXUS_Error NEXUS_Frontend_P_Ast_GetFastStatus(void *handle, NEXUS_FrontendFastStatus *pStatus );
357
358#ifdef TEST_NETWORK_TUNER
359NEXUS_AstDevice *pAstDevice[3]; /* This allows us to test the network tuner */
360#endif
361
362/***************************************************************************
363NEXUS -> PI Conversion Routines
364***************************************************************************/
365typedef struct NEXUS_AstModeEntry
366{
367    const NEXUS_FrontendSatelliteCodeRate *pCodeRate;
368    BAST_Mode mode;
369} NEXUS_AstModeEntry;
370
371static const NEXUS_FrontendSatelliteCodeRate
372    g_cr_scan = {0,0,0},
373    g_cr_1_4 = {1,4,0},
374    g_cr_1_2 = {1,2,0},
375    g_cr_2_3 = {2,3,0},
376    g_cr_3_4 = {3,4,0},
377    g_cr_5_6 = {5,6,0},
378    g_cr_6_7 = {6,7,0},
379    g_cr_7_8 = {7,8,0},
380    g_cr_5_11 = {5,11,0},
381    g_cr_3_5 = {3,5,0},
382    g_cr_4_5 = {4,5,0},
383    g_cr_9_10 = {9,10,0},
384    g_cr_8_9 = {8,9,0};
385
386static const struct NEXUS_AstModeEntry
387g_sds_dvb_modes[] = {
388    {&g_cr_1_2, BAST_Mode_eDvb_1_2},
389    {&g_cr_2_3, BAST_Mode_eDvb_2_3},
390    {&g_cr_3_4, BAST_Mode_eDvb_3_4},
391    {&g_cr_5_6, BAST_Mode_eDvb_5_6},
392    {&g_cr_7_8, BAST_Mode_eDvb_7_8},
393    {NULL, BAST_Mode_eDvb_scan}
394},
395g_sds_dss_modes[] = {
396    {&g_cr_1_2, BAST_Mode_eDss_1_2},
397    {&g_cr_2_3, BAST_Mode_eDss_2_3},
398    {&g_cr_6_7, BAST_Mode_eDss_6_7},
399    {NULL, BAST_Mode_eDss_scan}
400},
401g_sds_dcii_modes[] = {
402    {&g_cr_1_2, BAST_Mode_eDcii_1_2},
403    {&g_cr_2_3, BAST_Mode_eDcii_2_3},
404    {&g_cr_3_5, BAST_Mode_eDcii_3_5},
405    {&g_cr_3_4, BAST_Mode_eDcii_3_4},
406    {&g_cr_4_5, BAST_Mode_eDcii_4_5},
407    {&g_cr_5_6, BAST_Mode_eDcii_5_6},
408    {&g_cr_7_8, BAST_Mode_eDcii_7_8},
409    {&g_cr_5_11, BAST_Mode_eDcii_5_11},
410    {NULL, BAST_Mode_eDcii_scan}
411},
412g_sds_qpsk_turbo_modes[] = {
413    {&g_cr_1_2, BAST_Mode_eTurbo_Qpsk_1_2},
414    {&g_cr_2_3, BAST_Mode_eTurbo_Qpsk_2_3},
415    {&g_cr_3_4, BAST_Mode_eTurbo_Qpsk_3_4},
416    {&g_cr_5_6, BAST_Mode_eTurbo_Qpsk_5_6},
417    {&g_cr_7_8, BAST_Mode_eTurbo_Qpsk_7_8},
418    {NULL, BAST_Mode_eTurbo_scan}
419},
420g_sds_8psk_turbo_modes[] = {
421    {&g_cr_2_3, BAST_Mode_eTurbo_8psk_2_3},
422    {&g_cr_3_4, BAST_Mode_eTurbo_8psk_3_4},
423    {&g_cr_4_5, BAST_Mode_eTurbo_8psk_4_5},
424    {&g_cr_5_6, BAST_Mode_eTurbo_8psk_5_6},
425    {&g_cr_8_9, BAST_Mode_eTurbo_8psk_8_9},
426    {NULL, BAST_Mode_eTurbo_scan}
427},
428g_sds_turbo_modes[] = {
429    {&g_cr_1_2, BAST_Mode_eTurbo_Qpsk_1_2},
430    {&g_cr_2_3, BAST_Mode_eTurbo_Qpsk_2_3},
431    {&g_cr_3_4, BAST_Mode_eTurbo_Qpsk_3_4},
432    {&g_cr_5_6, BAST_Mode_eTurbo_Qpsk_5_6},
433    {&g_cr_7_8, BAST_Mode_eTurbo_Qpsk_7_8},
434    {&g_cr_2_3, BAST_Mode_eTurbo_8psk_2_3},
435    {&g_cr_3_4, BAST_Mode_eTurbo_8psk_3_4},
436    {&g_cr_4_5, BAST_Mode_eTurbo_8psk_4_5},
437    {&g_cr_5_6, BAST_Mode_eTurbo_8psk_5_6},
438    {&g_cr_8_9, BAST_Mode_eTurbo_8psk_8_9},
439    {NULL, BAST_Mode_eTurbo_scan}
440},
441g_sds_8psk_ldpc_modes[] = {
442    {&g_cr_3_5, BAST_Mode_eLdpc_8psk_3_5},
443    {&g_cr_2_3, BAST_Mode_eLdpc_8psk_2_3},
444    {&g_cr_3_4, BAST_Mode_eLdpc_8psk_3_4},
445    {&g_cr_5_6, BAST_Mode_eLdpc_8psk_5_6},
446    {&g_cr_8_9, BAST_Mode_eLdpc_8psk_8_9},
447    {&g_cr_9_10, BAST_Mode_eLdpc_8psk_9_10},
448    {NULL, BAST_Mode_eLdpc_scan}
449},
450g_sds_qpsk_ldpc_modes[] = {
451    {&g_cr_1_2, BAST_Mode_eLdpc_Qpsk_1_2},
452    {&g_cr_3_5, BAST_Mode_eLdpc_Qpsk_3_5},
453    {&g_cr_2_3, BAST_Mode_eLdpc_Qpsk_2_3},
454    {&g_cr_3_4, BAST_Mode_eLdpc_Qpsk_3_4},
455    {&g_cr_4_5, BAST_Mode_eLdpc_Qpsk_4_5},
456    {&g_cr_5_6, BAST_Mode_eLdpc_Qpsk_5_6},
457    {&g_cr_8_9, BAST_Mode_eLdpc_Qpsk_8_9},
458    {&g_cr_9_10, BAST_Mode_eLdpc_Qpsk_9_10},
459    {NULL, BAST_Mode_eLdpc_scan}
460},
461g_sds_ldpc_modes[] = {
462    {&g_cr_1_2, BAST_Mode_eLdpc_Qpsk_1_2},
463    {&g_cr_3_5, BAST_Mode_eLdpc_Qpsk_3_5},
464    {&g_cr_2_3, BAST_Mode_eLdpc_Qpsk_2_3},
465    {&g_cr_3_4, BAST_Mode_eLdpc_Qpsk_3_4},
466    {&g_cr_4_5, BAST_Mode_eLdpc_Qpsk_4_5},
467    {&g_cr_5_6, BAST_Mode_eLdpc_Qpsk_5_6},
468    {&g_cr_8_9, BAST_Mode_eLdpc_Qpsk_8_9},
469    {&g_cr_9_10, BAST_Mode_eLdpc_Qpsk_9_10},
470    {&g_cr_3_5, BAST_Mode_eLdpc_8psk_3_5},
471    {&g_cr_2_3, BAST_Mode_eLdpc_8psk_2_3},
472    {&g_cr_3_4, BAST_Mode_eLdpc_8psk_3_4},
473    {&g_cr_5_6, BAST_Mode_eLdpc_8psk_5_6},
474    {&g_cr_8_9, BAST_Mode_eLdpc_8psk_8_9},
475    {&g_cr_9_10, BAST_Mode_eLdpc_8psk_9_10},
476    {NULL, BAST_Mode_eLdpc_scan}
477},
478g_blind_acquisition_mode[] = {
479    {NULL, BAST_Mode_eBlindScan}
480};
481
482static BAST_Mode NEXUS_Frontend_P_Ast_GetMode(const struct NEXUS_AstModeEntry *pModes, const NEXUS_FrontendSatelliteCodeRate *pCodeRate)
483{
484    /* NOTE: there are not non-zero bitsPerSymbol values in the look up tables. if someone specifies a non-zero bitsPerSymbol,
485    this algorithm will result in a scan. */
486    for ( ;; pModes++ )
487    {
488        if ( NULL == pModes->pCodeRate )
489        {
490            BDBG_MSG(("Use scan for coderate %d:%d:%d", pCodeRate->numerator, pCodeRate->denominator, pCodeRate->bitsPerSymbol));
491            return pModes->mode;
492        }
493        if ( pModes->pCodeRate->numerator == pCodeRate->numerator &&
494             pModes->pCodeRate->denominator == pCodeRate->denominator &&
495             pModes->pCodeRate->bitsPerSymbol == pCodeRate->bitsPerSymbol )
496        {
497            return pModes->mode;
498        }
499    }
500}
501
502void NEXUS_Frontend_P_Ast_GetDefaultSettings( NEXUS_FrontendAstSettings *pSettings )
503{
504    unsigned i;
505    BDBG_ASSERT(NULL != pSettings);
506    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
507
508    /* by default, everything is supported. specific chips should turn off what they don't support. */
509    pSettings->capabilities.satellite = true;
510    pSettings->capabilities.diseqc = true;
511    for (i = 0;i < NEXUS_FrontendSatelliteMode_eMax; i++)
512    {
513        pSettings->capabilities.satelliteModes[i] = true;
514    }
515}
516
517NEXUS_FrontendHandle NEXUS_Frontend_P_Ast_Create( const NEXUS_FrontendAstSettings *pSettings )
518{
519    BERR_Code errCode;
520    NEXUS_AstDevice *pDevice;
521
522    BDBG_ASSERT(NULL != pSettings);
523    BDBG_ASSERT(NULL != pSettings->astHandle);
524    BDBG_ASSERT(NULL != pSettings->astChannel);
525
526    pDevice = BKNI_Malloc(sizeof(NEXUS_AstDevice));
527    if ( NULL == pDevice )
528    {
529        errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
530        return NULL;
531    }
532    BKNI_Memset(pDevice, 0, sizeof(*pDevice));
533
534    pDevice->settings = *pSettings;     /* Save Settings */
535    pDevice->astHandle = pSettings->astHandle;
536    pDevice->astChannel = pSettings->astChannel;
537    pDevice->astChip = pSettings->astChip;
538   
539    errCode = BAST_GetLockStateChangeEventHandle(pDevice->astChannel, &pDevice->lockEvent);
540    if ( errCode )
541    {
542        errCode = BERR_TRACE(errCode);
543        goto err_lock_event;
544    }
545
546    (void)BAST_ResetDiseqc(pDevice->astChannel, 0);
547
548    pDevice->lockEventCallback = NEXUS_RegisterEvent(pDevice->lockEvent,
549                                                     NEXUS_Frontend_P_Ast_LockEventHandler,
550                                                     pDevice);
551    if ( NULL == pDevice->lockEventCallback )
552    {
553        errCode = BERR_TRACE(BERR_OS_ERROR);
554        goto err_lock_event_callback;
555    }
556
557    #if TEST_NETWORK_TUNER
558    pAstDevice[pDevice->settings.channelIndex]=pDevice;
559    #endif
560
561    /* reset diseqc with options 0. Currently this paramater is not used by the AST PI */
562    if (pSettings->capabilities.diseqc)
563    {
564        errCode = BAST_ResetDiseqc(pDevice->astChannel, 0);
565        if ( errCode )
566        {
567            errCode = BERR_TRACE(errCode);
568            goto err_reset_diseqc;
569        }
570
571
572        errCode = BAST_GetDiseqcEventHandle(pDevice->astChannel, &pDevice->diseqcEvent);
573        if ( errCode )
574        {
575            errCode = BERR_TRACE(errCode);
576            goto err_diseqc_event;
577        }
578
579        pDevice->diseqcEventCallback = NEXUS_RegisterEvent(pDevice->diseqcEvent,
580                                                           NEXUS_Frontend_P_Ast_DiseqcEventHandler,
581                                                           pDevice);
582        if ( NULL == pDevice->diseqcEventCallback )
583        {
584            errCode = BERR_TRACE(errCode);
585            goto err_diseqc_event_callback;
586        }
587        BKNI_Memset(&pDevice->diseqcSettings,0,sizeof(pDevice->diseqcSettings));
588        pDevice->diseqcSettings.enabled = true;
589    }
590
591    errCode = BAST_GetPeakScanEventHandle(pDevice->astChannel, &pDevice->peakscanEvent);
592    if ( errCode == BERR_NOT_SUPPORTED) {
593        pDevice->peakscanEvent = NULL; /* used to determine whether peakscan is available */
594    }
595    else {
596        if ( errCode )
597        {
598            errCode = BERR_TRACE(errCode);
599            goto err_peak_scan_event;
600        }
601
602        pDevice->peakscanEventCallback = NEXUS_RegisterEvent(pDevice->peakscanEvent,
603                                                             NEXUS_Frontend_P_Ast_PeakscanEventHandler,
604                                                             pDevice);
605        if ( NULL == pDevice->peakscanEventCallback )
606        {
607            errCode = BERR_TRACE(BERR_OS_ERROR);
608            goto err_peak_scan_event_callback;
609        }
610    }
611
612    /* Create Frontend Handle */
613    pDevice->frontendHandle = NEXUS_Frontend_P_Create(pDevice);
614    if ( NULL == pDevice->frontendHandle )
615    {
616        errCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
617        goto err_frontend_handle;
618    }
619
620    /* Set Capabilities */
621    BDBG_ASSERT(pSettings->capabilities.satellite);
622    pDevice->frontendHandle->capabilities = pSettings->capabilities;
623    pDevice->capabilities = pSettings->capabilities;
624
625    /* Install Hooks */
626    pDevice->frontendHandle->close = NEXUS_Frontend_P_Ast_Close;
627    pDevice->frontendHandle->untune = NEXUS_Frontend_P_Ast_Untune;
628    pDevice->frontendHandle->getDiseqcReply = NEXUS_Frontend_P_Ast_GetDiseqcReply;
629    pDevice->frontendHandle->getDiseqcSettings = NEXUS_Frontend_P_Ast_GetDiseqcSettings;
630    pDevice->frontendHandle->sendDiseqcAcw = NEXUS_Frontend_P_Ast_SendDiseqcAcw;
631    pDevice->frontendHandle->sendDiseqcMessage = NEXUS_Frontend_P_Ast_SendDiseqcMessage;
632    pDevice->frontendHandle->setDiseqcSettings = NEXUS_Frontend_P_Ast_SetDiseqcSettings;
633    pDevice->frontendHandle->getDiseqcStatus = NEXUS_Frontend_P_Ast_GetDiseqcStatus;
634    pDevice->frontendHandle->resetDiseqc = NEXUS_Frontend_P_Ast_ResetDiseqc;
635    pDevice->frontendHandle->getSatelliteStatus = NEXUS_Frontend_P_Ast_GetSatelliteStatus;
636    pDevice->frontendHandle->getSoftDecisions = NEXUS_Frontend_P_Ast_GetSoftDecisions;
637    pDevice->frontendHandle->tuneSatellite = NEXUS_Frontend_P_Ast_TuneSatellite;
638    pDevice->frontendHandle->resetStatus = NEXUS_Frontend_P_Ast_ResetStatus;
639    pDevice->frontendHandle->readSatelliteConfig = NEXUS_Frontend_P_Ast_ReadSatelliteConfig;
640    pDevice->frontendHandle->writeSatelliteConfig = NEXUS_Frontend_P_Ast_WriteSatelliteConfig;
641    pDevice->frontendHandle->satellitePeakscan = NEXUS_Frontend_P_Ast_SatellitePeakscan;
642    pDevice->frontendHandle->getSatellitePeakscanResult = NEXUS_Frontend_P_Ast_GetSatellitePeakscanResult;
643    pDevice->frontendHandle->registerExtension = NEXUS_Frontend_P_Ast_RegisterExtension;
644    pDevice->frontendHandle->getFastStatus = NEXUS_Frontend_P_Ast_GetFastStatus;
645
646    /* Set up I2C handle */
647    {
648        NEXUS_I2cCallbacks i2cCallbacks;
649        NEXUS_I2c_InitCallbacks(&i2cCallbacks);
650        i2cCallbacks.readNoAddr = NEXUS_Frontend_P_Ast_I2cReadNoAddr;
651        i2cCallbacks.writeNoAddr = NEXUS_Frontend_P_Ast_I2cWriteNoAddr;
652        pDevice->deviceI2cHandle = NEXUS_I2c_CreateHandle(NEXUS_MODULE_SELF, pDevice, &i2cCallbacks);
653        if (!pDevice->deviceI2cHandle ) {
654            errCode = BERR_TRACE(BERR_NOT_SUPPORTED);
655            goto err_i2c;
656        }
657    }
658
659    if (pSettings->capabilities.diseqc)
660    {
661         /* These must be created after the frontend handle has been created */
662         pDevice->diseqcAppCallback = NEXUS_TaskCallback_Create(pDevice->frontendHandle, NULL);
663         if ( NULL == pDevice->diseqcAppCallback )
664         {
665             errCode = BERR_TRACE(BERR_OS_ERROR);
666             goto err_diseqc_app_callback;
667         }
668     }
669
670    if (pDevice->peakscanEvent) {
671        pDevice->peakscanAppCallback = NEXUS_TaskCallback_Create(pDevice->frontendHandle, NULL);
672        if ( NULL == pDevice->peakscanAppCallback )
673        {
674            errCode = BERR_TRACE(BERR_OS_ERROR);
675            goto err_peak_scan_app_callback;
676        }
677    }
678
679    pDevice->lockAppCallback = NEXUS_TaskCallback_Create(pDevice->frontendHandle, NULL);
680    if ( NULL == pDevice->lockAppCallback )
681    {
682        errCode = BERR_TRACE(BERR_OS_ERROR);
683        goto err_lock_app_callback;
684    }
685
686    pDevice->ftmCallback = NEXUS_TaskCallback_Create(pDevice->frontendHandle, NULL);
687    if ( NULL == pDevice->ftmCallback )
688    {
689        errCode = BERR_TRACE(BERR_OS_ERROR);
690        goto err_lock_app_callback;
691    }
692
693    /* Success */
694    BDBG_OBJECT_SET(pDevice, NEXUS_AstDevice);
695    return pDevice->frontendHandle;
696
697err_lock_app_callback:
698    if (pDevice->peakscanEvent) {
699        NEXUS_TaskCallback_Destroy(pDevice->peakscanAppCallback);
700    }
701err_peak_scan_app_callback:
702    NEXUS_TaskCallback_Destroy(pDevice->diseqcAppCallback);
703err_diseqc_app_callback:
704    NEXUS_I2c_DestroyHandle(pDevice->deviceI2cHandle);
705err_i2c:
706    NEXUS_Frontend_P_Destroy(pDevice->frontendHandle);
707err_frontend_handle:
708    if (pDevice->peakscanEvent) {
709        NEXUS_UnregisterEvent(pDevice->peakscanEventCallback);
710    }
711err_peak_scan_event_callback:
712err_peak_scan_event:
713    NEXUS_UnregisterEvent(pDevice->diseqcEventCallback);
714err_diseqc_event_callback:
715err_diseqc_event:
716err_reset_diseqc:
717    NEXUS_UnregisterEvent(pDevice->lockEventCallback);
718err_lock_event_callback:
719err_lock_event:
720    BKNI_Free(pDevice);
721
722    return NULL;
723}
724
725static void NEXUS_Frontend_P_Ast_Close(NEXUS_FrontendHandle handle)
726{
727    NEXUS_AstDevice *pDevice;
728
729    BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
730    pDevice = handle->pDeviceHandle;
731    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
732
733    /* Cleanup Channel */
734    if (pDevice->peakscanEvent) {
735        NEXUS_UnregisterEvent(pDevice->peakscanEventCallback);
736        NEXUS_TaskCallback_Destroy(pDevice->peakscanAppCallback);
737    }
738    NEXUS_UnregisterEvent(pDevice->lockEventCallback);
739    NEXUS_TaskCallback_Destroy(pDevice->lockAppCallback);
740    NEXUS_TaskCallback_Destroy(pDevice->ftmCallback);
741
742    if (pDevice->capabilities.diseqc)
743    {
744        NEXUS_UnregisterEvent(pDevice->diseqcEventCallback);
745        NEXUS_TaskCallback_Destroy(pDevice->diseqcAppCallback);
746    }
747
748    NEXUS_I2c_DestroyHandle(pDevice->deviceI2cHandle);
749    NEXUS_Frontend_P_Destroy(pDevice->frontendHandle);
750
751    /* Call post-close callback */
752    if ( pDevice->settings.closeFunction )
753    {
754        pDevice->settings.closeFunction(handle, pDevice->settings.pCloseParam);
755    }
756
757    BKNI_Memset(pDevice, 0, sizeof(*pDevice));
758    BKNI_Free(pDevice);
759}
760
761NEXUS_Error NEXUS_Frontend_P_Ast_SetDevices( NEXUS_FrontendHandle handle, const NEXUS_FrontendAstDevices *pDevices )
762{
763    NEXUS_AstDevice *pDevice;
764
765    BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
766    BDBG_ASSERT(NULL != pDevices);
767
768    pDevice = handle->pDeviceHandle;
769    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
770
771    pDevice->settings.devices = *pDevices;
772
773    return BERR_SUCCESS;
774}
775
776static NEXUS_Error NEXUS_Frontend_P_Ast_TuneSatellite( void *handle, const NEXUS_FrontendSatelliteSettings *pSettings )
777{
778    BERR_Code errCode;
779    NEXUS_AstDevice *pDevice = handle;
780    BAST_AcqSettings acqSettings;
781        uint8_t networkSpec;
782
783    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
784    BDBG_ASSERT(NULL != pSettings);
785
786    BKNI_Memset(&acqSettings, 0, sizeof(acqSettings));
787
788    /* BAST_ACQSETTINGS_DEFAULT was applied in NEXUS_Frontend_GetDefaultSatelliteSettings */
789
790    if ( pSettings->pnData )
791        acqSettings.acq_ctl |= BAST_ACQSETTINGS_PN;
792    if ( pSettings->prbs15 )
793        acqSettings.acq_ctl |= BAST_ACQSETTINGS_PRBS15;
794    if ( pSettings->nyquist20 )
795        acqSettings.acq_ctl |= BAST_ACQSETTINGS_NYQUIST_20;
796    if ( pSettings->bertEnable )
797        acqSettings.acq_ctl |= BAST_ACQSETTINGS_BERT_ENABLE;
798    if ( pSettings->pnDataInvert )
799        acqSettings.acq_ctl |= BAST_ACQSETTINGS_PN_INVERT;
800    if ( pSettings->bertResyncDisable )
801        acqSettings.acq_ctl |= BAST_ACQSETTINGS_BERT_RESYNC_DISABLE;
802    if ( pSettings->reacquireDisable )
803        acqSettings.acq_ctl |= BAST_ACQSETTINGS_REACQ_DISABLE;
804    if ( pSettings->dciiSplit )
805        acqSettings.acq_ctl |= BAST_ACQSETTINGS_DCII_SPLIT;
806    if ( pSettings->dciiSplitQ )
807        acqSettings.acq_ctl |= BAST_ACQSETTINGS_DCII_SPLIT_Q;
808    if ( pSettings->oQpsk )
809        acqSettings.acq_ctl |= BAST_ACQSETTINGS_OQPSK;
810    if ( pSettings->rsDisable )
811        acqSettings.acq_ctl |= BAST_ACQSETTINGS_RS_DISABLE;
812    if ( pSettings->ldpcPilot )
813        acqSettings.acq_ctl |= BAST_ACQSETTINGS_LDPC_PILOT;
814    if ( pSettings->ldpcPilotPll )
815        acqSettings.acq_ctl |= BAST_ACQSETTINGS_LDPC_PILOT_PLL;
816    if ( pSettings->ldpcPilotScan )
817        acqSettings.acq_ctl |= BAST_ACQSETTINGS_LDPC_PILOT_SCAN;
818    if ( pSettings->tunerTestMode )
819        acqSettings.acq_ctl |= BAST_ACQSETTINGS_TUNER_TEST_MODE;
820    if ( pSettings->toneSearchMode )
821        acqSettings.acq_ctl |= BAST_ACQSETTINGS_TONE_SEARCH_MODE;
822    if ( pSettings->signalDetectMode )
823        acqSettings.acq_ctl |= BAST_ACQSETTINGS_SIGNAL_DETECT_MODE;
824    if ( pSettings->bypassTune )
825        acqSettings.acq_ctl |= BAST_ACQSETTINGS_BYPASS_TUNE;
826    if ( pSettings->bypassAcquire )
827        acqSettings.acq_ctl |= BAST_ACQSETTINGS_BYPASS_ACQUIRE;
828
829    /* AST engineers prefer we always set this to scan. */
830    if (pSettings->spectralInversion != NEXUS_FrontendSatelliteInversion_eScan) {
831        BDBG_MSG(("forcing NEXUS_FrontendSatelliteInversion_eScan mode")); /* don't WRN */
832    }
833    acqSettings.acq_ctl |= BAST_ACQSETTINGS_SPINV_IQ_SCAN;
834
835    /* This is added for backward compatibility */
836    switch ( pSettings->mode )
837    {
838    case NEXUS_FrontendSatelliteMode_eQpskLdpc:
839    case NEXUS_FrontendSatelliteMode_e8pskLdpc:
840    case NEXUS_FrontendSatelliteMode_eLdpc:
841        acqSettings.acq_ctl |= (BAST_ACQSETTINGS_NYQUIST_20 | BAST_ACQSETTINGS_SPINV_IQ_SCAN);
842        break;
843    default:
844        break;
845    }
846
847    switch ( pSettings->mode )
848    {
849    case NEXUS_FrontendSatelliteMode_eDvb:
850        BDBG_MSG(("Tune DVB"));
851        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_dvb_modes, &pSettings->codeRate);
852        break;
853    case NEXUS_FrontendSatelliteMode_eDss:
854        BDBG_MSG(("Tune DSS"));
855        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_dss_modes, &pSettings->codeRate);
856        break;
857    case NEXUS_FrontendSatelliteMode_eDcii:
858        BDBG_MSG(("Tune DCII"));
859        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_dcii_modes, &pSettings->codeRate);
860        break;
861    case NEXUS_FrontendSatelliteMode_eQpskLdpc:
862        BDBG_MSG(("Tune QPSK LDPC"));
863        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_qpsk_ldpc_modes, &pSettings->codeRate);
864        break;
865    case NEXUS_FrontendSatelliteMode_e8pskLdpc:
866        BDBG_MSG(("Tune 8PSK LDPC"));
867        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_8psk_ldpc_modes, &pSettings->codeRate);
868        break;
869    case NEXUS_FrontendSatelliteMode_eLdpc:
870        BDBG_MSG(("Tune LDCP"));
871        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_ldpc_modes, &pSettings->codeRate);
872        break;
873    case NEXUS_FrontendSatelliteMode_eQpskTurbo:
874        BDBG_MSG(("Tune Turbo QPSK"));
875        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_qpsk_turbo_modes, &pSettings->codeRate);
876        break;
877    case NEXUS_FrontendSatelliteMode_e8pskTurbo:
878        BDBG_MSG(("Tune Turbo 8PSK"));
879        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_8psk_turbo_modes, &pSettings->codeRate);
880        break;
881    case NEXUS_FrontendSatelliteMode_eTurbo:
882        BDBG_MSG(("Tune Turbo"));
883        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_sds_turbo_modes, &pSettings->codeRate);
884        break;
885    case NEXUS_FrontendSatelliteMode_eBlindAcquisition:
886        BDBG_MSG(("Blind acquisition"));
887        acqSettings.mode = NEXUS_Frontend_P_Ast_GetMode(g_blind_acquisition_mode, &pSettings->codeRate);
888        break;
889    default:
890        /* turbo not supported */
891        return BERR_TRACE(BERR_NOT_SUPPORTED);
892    }
893
894    BDBG_MSG(("acqSettings.acq_ctl %x", acqSettings.acq_ctl));
895    acqSettings.symbolRate = pSettings->symbolRate;
896    BDBG_MSG(("Freq %u, Symbol Rate %u", pSettings->frequency, acqSettings.symbolRate));
897    acqSettings.carrierFreqOffset = pSettings->carrierOffset;
898
899    NEXUS_TaskCallback_Set(pDevice->lockAppCallback, &pSettings->lockCallback);
900
901#ifdef NEXUS_POWER_MANAGEMENT
902    errCode = BAST_PowerUp(pDevice->astChannel, BAST_CORE_ALL);
903    if ( errCode )
904    {
905        return BERR_TRACE(errCode);
906    }
907#endif
908
909    /* Support external tuner if present */
910    if ( pDevice->settings.devices.tuner )
911    {
912        errCode = NEXUS_Tuner_SetFrequency(pDevice->settings.devices.tuner, NEXUS_TunerMode_eDigital, pSettings->frequency);
913        if ( errCode )
914        {
915            return BERR_TRACE(errCode);
916        }
917    }
918
919    if (pSettings->networkSpec != pDevice->lastSettings.networkSpec) {                 
920        networkSpec = (uint8_t)pSettings->networkSpec;
921        BAST_SetNetworkSpec(pDevice->astHandle, networkSpec);
922    }
923
924    #ifdef BCM73XX_CONFIG_LEN_EXT_TUNER_IF_OFFSET
925    /* Set IF offset for external tuners */
926    {
927        uint32_t val = (uint32_t)pSettings->ifOffset;
928        uint8_t buf[4];
929
930        buf[0] = (val >> 24) & 0xFF;
931        buf[1] = (val >> 16) & 0xFF;
932        buf[2] = (val >> 8) & 0xFF;
933        buf[3] = (val & 0xFF);
934        BAST_WriteConfig(pDevice->astChannel, BCM73XX_CONFIG_EXT_TUNER_IF_OFFSET, buf, BCM73XX_CONFIG_LEN_EXT_TUNER_IF_OFFSET);
935    }
936    #endif
937   
938    /* Warning, this overrides the search range for all channels of this AST device.  */
939    errCode = BAST_SetSearchRange(pDevice->astHandle, pSettings->searchRange);
940    if ( errCode )
941    {
942        return BERR_TRACE(errCode);
943    }
944
945    pDevice->lastSettings = *pSettings; /* save after all config, but before the acquire. */
946   
947    errCode = BAST_TuneAcquire(pDevice->astChannel, pSettings->frequency, &acqSettings);
948    if ( errCode )
949    {
950        return BERR_TRACE(errCode);
951    }
952
953    BTRC_TRACE(ChnChange_Tune, STOP);
954    BTRC_TRACE(ChnChange_TuneLock, START);
955
956    return BERR_SUCCESS;
957}
958
959static void NEXUS_Frontend_P_Ast_Untune(void *handle)
960{
961    NEXUS_Error errCode;
962    NEXUS_AstDevice *pDevice = handle;
963
964    BDBG_MSG(("untune"));
965#ifdef NEXUS_POWER_MANAGEMENT
966    errCode = BAST_PowerDown(pDevice->astChannel, BAST_CORE_ALL);
967    if (errCode) {errCode = BERR_TRACE(errCode);}
968#else
969    BSTD_UNUSED(pDevice);
970    BSTD_UNUSED(errCode);
971#endif
972}
973
974static NEXUS_Error NEXUS_Frontend_P_Ast_GetSatelliteStatus( void *handle, NEXUS_FrontendSatelliteStatus *pStatus )
975{
976    NEXUS_Error errCode;
977    BAST_ChannelStatus astStatus;
978    NEXUS_AstDevice *pDevice = handle;
979    NEXUS_Time now;
980
981    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
982    BDBG_ASSERT(NULL != pStatus);
983
984    BKNI_Memset(pStatus, 0, sizeof(*pStatus));
985
986    errCode = BAST_GetApVersion(pDevice->astHandle,
987        &pStatus->version.chipId,
988        &pStatus->version.chipVersion,
989        &pStatus->version.bondingOption,
990        &pStatus->version.apMicrocodeVersion,
991        &pStatus->version.hostConfigurationVersion);
992    if (errCode) {
993        if (errCode == BI2C_ERR_NO_ACK) {
994            pStatus->statusError = NEXUS_FrontendSatelliteStatusError_eI2cNoAck;
995            return 0;
996        }
997        else if (errCode == BAST_ERR_HAB_TIMEOUT) {
998            pStatus->statusError = NEXUS_FrontendSatelliteStatusError_eHabTimeout;
999            return 0;
1000        }
1001        else {
1002            /* unknown error. status function should fail. */
1003            return BERR_TRACE(errCode);
1004        }
1005    }
1006
1007    errCode = BAST_GetChannelStatus(pDevice->astChannel, &astStatus);
1008    if ( errCode ) {
1009        /* if not locked, BAST_GetChannelStatus will fail. this is not an error. the status structure should just report not locked and no status available. */
1010        pStatus->statusError = NEXUS_FrontendSatelliteStatusError_eGetChannelStatusError;
1011        return 0;
1012    }
1013
1014    NEXUS_Time_Get(&now);
1015    pStatus->timeElapsed = NEXUS_Time_Diff(&now, &pDevice->frontendHandle->resetStatusTime);
1016
1017    pStatus->settings = pDevice->lastSettings; /* return last settings used in NEXUS_Frontend_TuneSatellite */
1018    pStatus->channel = pDevice->settings.channelIndex;
1019    pStatus->sampleClock = astStatus.sample_clock;
1020    pStatus->carrierError = astStatus.carrierError;
1021    pStatus->outputBitRate = astStatus.outputBitrate;
1022    pStatus->symbolRate = astStatus.symbolRate;
1023    pStatus->symbolRateError = astStatus.symbolRateError;
1024    pStatus->snrEstimate = astStatus.snrEstimate * 100/256;  /* convert to 1/100 units */
1025    pStatus->tunerLocked = astStatus.bTunerLocked;
1026    pStatus->demodLocked = astStatus.bDemodLocked;
1027    pStatus->bertLocked = astStatus.bBertLocked;
1028    pStatus->mpegErrors = astStatus.mpegErrors;
1029    pStatus->mpegCount = astStatus.mpegCount;
1030    pStatus->berErrors = astStatus.berErrors;
1031    pStatus->ifAgc = astStatus.IFagc;
1032    pStatus->rfAgc = astStatus.RFagc;
1033    pStatus->agf = astStatus.agf;
1034    pStatus->frequency = astStatus.tunerFreq;
1035
1036#if NEXUS_FRONTEND_4501
1037    {
1038    BAST_LnaStatus lnaStatus;
1039    BAST_GetLnaStatus(pDevice->settings.astHandle, &lnaStatus);
1040    pStatus->lnaStatus.intConfig = lnaStatus.int_config;
1041    pStatus->lnaStatus.extConfig = lnaStatus.ext_config;
1042    pStatus->lnaStatus.version = lnaStatus.version;
1043    pStatus->lnaStatus.agc0 = lnaStatus.agc0;
1044    pStatus->lnaStatus.agc1 = lnaStatus.agc1;
1045    }
1046#endif
1047
1048    if (BAST_MODE_IS_LEGACY_QPSK(astStatus.mode))
1049    {
1050        pStatus->fecCorrected = astStatus.modeStatus.legacy.rsCorrCount;
1051        pStatus->fecUncorrected = astStatus.modeStatus.legacy.rsUncorrCount;
1052        pStatus->preViterbiErrorCount = astStatus.modeStatus.legacy.preVitErrCount;
1053        switch ( astStatus.modeStatus.legacy.spinv )
1054        {
1055        default:
1056            pStatus->spectralInversion = NEXUS_FrontendSatelliteInversion_eScan;
1057            break;
1058        case BAST_Spinv_eNormal:
1059            pStatus->spectralInversion = NEXUS_FrontendSatelliteInversion_eNormal;
1060            break;
1061        case BAST_Spinv_eIinv:
1062            pStatus->spectralInversion = NEXUS_FrontendSatelliteInversion_eI;
1063            break;
1064        case BAST_Spinv_eQinv:
1065            pStatus->spectralInversion = NEXUS_FrontendSatelliteInversion_eQ;
1066            break;
1067        }
1068        switch ( astStatus.modeStatus.legacy.phase )
1069        {
1070        default:
1071        case BAST_PhaseRotation_e0:
1072            pStatus->fecPhase = 0;
1073            break;
1074        case BAST_PhaseRotation_e90:
1075            pStatus->fecPhase = 90;
1076            break;
1077        case BAST_PhaseRotation_e180:
1078            pStatus->fecPhase = 180;
1079            break;
1080        case BAST_PhaseRotation_e270:
1081            pStatus->fecPhase = 270;
1082            break;
1083        }
1084    }
1085    else if ( BAST_MODE_IS_LDPC(astStatus.mode) )
1086    {
1087        pStatus->fecCorrected = astStatus.modeStatus.ldpc.corrBlocks;
1088        pStatus->fecUncorrected = astStatus.modeStatus.ldpc.badBlocks;
1089        pStatus->fecClean = astStatus.modeStatus.ldpc.totalBlocks -
1090            astStatus.modeStatus.ldpc.corrBlocks -
1091            astStatus.modeStatus.ldpc.badBlocks;
1092    }
1093    else if (BAST_MODE_IS_TURBO(astStatus.mode))
1094    {
1095        pStatus->fecCorrected = astStatus.modeStatus.turbo.corrBlocks;
1096        pStatus->fecUncorrected = astStatus.modeStatus.turbo.badBlocks;
1097        pStatus->fecClean = astStatus.modeStatus.turbo.totalBlocks -
1098            astStatus.modeStatus.turbo.corrBlocks -
1099            astStatus.modeStatus.turbo.badBlocks;
1100   }
1101
1102    /* Check mode to get coderate */
1103    switch ( astStatus.mode )
1104    {
1105    case BAST_Mode_eDvb_scan:
1106    case BAST_Mode_eDss_scan:
1107    case BAST_Mode_eDcii_scan:
1108    case BAST_Mode_eLdpc_scan:
1109    case BAST_Mode_eTurbo_scan:
1110        pStatus->codeRate = g_cr_scan;
1111        break;
1112
1113    case BAST_Mode_eDvb_1_2:
1114    case BAST_Mode_eDss_1_2:
1115    case BAST_Mode_eDcii_1_2:
1116    case BAST_Mode_eLdpc_Qpsk_1_2:
1117    case BAST_Mode_eTurbo_Qpsk_1_2:
1118        pStatus->codeRate = g_cr_1_2;
1119        break;
1120
1121    case BAST_Mode_eDvb_2_3:
1122    case BAST_Mode_eDss_2_3:
1123    case BAST_Mode_eDcii_2_3:
1124    case BAST_Mode_eLdpc_Qpsk_2_3:
1125    case BAST_Mode_eLdpc_8psk_2_3:
1126    case BAST_Mode_eTurbo_Qpsk_2_3:
1127    case BAST_Mode_eTurbo_8psk_2_3:
1128        pStatus->codeRate = g_cr_2_3;
1129        break;
1130
1131    case BAST_Mode_eDvb_3_4:
1132    case BAST_Mode_eDcii_3_4:
1133    case BAST_Mode_eLdpc_Qpsk_3_4:
1134    case BAST_Mode_eLdpc_8psk_3_4:
1135    case BAST_Mode_eTurbo_Qpsk_3_4:
1136    case BAST_Mode_eTurbo_8psk_3_4:
1137        pStatus->codeRate = g_cr_3_4;
1138        break;
1139
1140    case BAST_Mode_eDcii_3_5:
1141    case BAST_Mode_eLdpc_Qpsk_3_5:
1142    case BAST_Mode_eLdpc_8psk_3_5:
1143        pStatus->codeRate = g_cr_3_5;
1144        break;
1145
1146    case BAST_Mode_eDcii_4_5:
1147    case BAST_Mode_eLdpc_Qpsk_4_5:
1148    case BAST_Mode_eTurbo_8psk_4_5:
1149        pStatus->codeRate = g_cr_4_5;
1150        break;
1151
1152    case BAST_Mode_eDvb_5_6:
1153    case BAST_Mode_eDcii_5_6:
1154    case BAST_Mode_eLdpc_Qpsk_5_6:
1155    case BAST_Mode_eLdpc_8psk_5_6:
1156    case BAST_Mode_eTurbo_Qpsk_5_6:
1157    case BAST_Mode_eTurbo_8psk_5_6:
1158        pStatus->codeRate = g_cr_5_6;
1159        break;
1160
1161    case BAST_Mode_eDss_6_7:
1162        pStatus->codeRate = g_cr_6_7;
1163        break;
1164
1165    case BAST_Mode_eDvb_7_8:
1166    case BAST_Mode_eDcii_7_8:
1167    case BAST_Mode_eTurbo_Qpsk_7_8:
1168        pStatus->codeRate = g_cr_7_8;
1169        break;
1170
1171    case BAST_Mode_eDcii_5_11:
1172        pStatus->codeRate = g_cr_5_11;
1173        break;
1174
1175    case BAST_Mode_eLdpc_Qpsk_8_9:
1176    case BAST_Mode_eLdpc_8psk_8_9:
1177    case BAST_Mode_eTurbo_8psk_8_9:
1178        pStatus->codeRate = g_cr_8_9;
1179        break;
1180
1181    case BAST_Mode_eLdpc_Qpsk_9_10:
1182    case BAST_Mode_eLdpc_8psk_9_10:
1183        pStatus->codeRate = g_cr_9_10;
1184        break;
1185
1186    default:
1187        break;
1188    }
1189
1190    switch ( astStatus.mode )
1191    {
1192    default:
1193    case BAST_Mode_eDvb_scan:
1194    case BAST_Mode_eDvb_1_2:
1195    case BAST_Mode_eDvb_2_3:
1196    case BAST_Mode_eDvb_3_4:
1197    case BAST_Mode_eDvb_5_6:
1198    case BAST_Mode_eDvb_7_8:
1199        pStatus->mode = NEXUS_FrontendSatelliteMode_eDvb;
1200        break;
1201
1202    case BAST_Mode_eDss_scan:
1203    case BAST_Mode_eDss_1_2:
1204    case BAST_Mode_eDss_2_3:
1205    case BAST_Mode_eDss_6_7:
1206        pStatus->mode = NEXUS_FrontendSatelliteMode_eDss;
1207        break;
1208
1209    case BAST_Mode_eDcii_scan:
1210    case BAST_Mode_eDcii_1_2:
1211    case BAST_Mode_eDcii_2_3:
1212    case BAST_Mode_eDcii_3_4:
1213    case BAST_Mode_eDcii_3_5:
1214    case BAST_Mode_eDcii_4_5:
1215    case BAST_Mode_eDcii_5_6:
1216    case BAST_Mode_eDcii_7_8:
1217    case BAST_Mode_eDcii_5_11:
1218        pStatus->mode = NEXUS_FrontendSatelliteMode_eDcii;
1219        break;
1220
1221    case BAST_Mode_eLdpc_scan:
1222    case BAST_Mode_eLdpc_Qpsk_1_2:
1223    case BAST_Mode_eLdpc_Qpsk_2_3:
1224    case BAST_Mode_eLdpc_Qpsk_3_4:
1225    case BAST_Mode_eLdpc_Qpsk_3_5:
1226    case BAST_Mode_eLdpc_Qpsk_4_5:
1227    case BAST_Mode_eLdpc_Qpsk_5_6:
1228    case BAST_Mode_eLdpc_Qpsk_9_10:
1229    case BAST_Mode_eLdpc_Qpsk_8_9:
1230        pStatus->mode = NEXUS_FrontendSatelliteMode_eQpskLdpc;
1231        break;
1232
1233    case BAST_Mode_eLdpc_8psk_2_3:
1234    case BAST_Mode_eLdpc_8psk_3_4:
1235    case BAST_Mode_eLdpc_8psk_3_5:
1236    case BAST_Mode_eLdpc_8psk_5_6:
1237    case BAST_Mode_eLdpc_8psk_8_9:
1238    case BAST_Mode_eLdpc_8psk_9_10:
1239        pStatus->mode = NEXUS_FrontendSatelliteMode_e8pskLdpc;
1240        break;
1241
1242    case BAST_Mode_eTurbo_scan:
1243    case BAST_Mode_eTurbo_Qpsk_1_2:
1244    case BAST_Mode_eTurbo_Qpsk_2_3:
1245    case BAST_Mode_eTurbo_Qpsk_3_4:
1246    case BAST_Mode_eTurbo_Qpsk_5_6:
1247    case BAST_Mode_eTurbo_Qpsk_7_8:
1248        pStatus->mode = NEXUS_FrontendSatelliteMode_eTurboQpsk;
1249        break;
1250
1251    case BAST_Mode_eTurbo_8psk_2_3:
1252    case BAST_Mode_eTurbo_8psk_3_4:
1253    case BAST_Mode_eTurbo_8psk_4_5:
1254    case BAST_Mode_eTurbo_8psk_5_6:
1255    case BAST_Mode_eTurbo_8psk_8_9:
1256        pStatus->mode = NEXUS_FrontendSatelliteMode_eTurbo8psk;
1257        break;
1258    }
1259
1260    return BERR_SUCCESS;
1261}
1262
1263static void NEXUS_Frontend_P_Ast_GetDiseqcSettings( void *handle, NEXUS_FrontendDiseqcSettings *pSettings )
1264{
1265    NEXUS_AstDevice *pDevice = handle;
1266    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1267
1268    #ifndef TEST_NETWORK_TUNER
1269    if (pDevice->capabilities.diseqc)
1270    #endif
1271    {
1272        BDBG_ASSERT(NULL != pSettings);
1273        *pSettings = pDevice->diseqcSettings;
1274    }
1275}
1276
1277static NEXUS_Error NEXUS_Frontend_P_Ast_SetDiseqcSettings( void *handle, const NEXUS_FrontendDiseqcSettings *pSettings )
1278{
1279    NEXUS_Error errCode;
1280    NEXUS_AstDevice *pDevice = handle;
1281    uint8_t buf[2];
1282
1283    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1284    BDBG_ASSERT(NULL != pSettings);
1285
1286    if (!pDevice->diseqcSettings.enabled && pSettings->enabled) {
1287        BAST_PowerUp(pDevice->astChannel, BAST_CORE_DISEQC);
1288    }
1289
1290    if(pDevice->astChip == 4506){
1291#if defined NEXUS_FRONTEND_4506
1292        errCode = BAST_ReadConfig(pDevice->astChannel, BCM4506_CONFIG_DISEQC_CTL2, buf, BCM4506_CONFIG_LEN_DISEQC_CTL2);
1293        if (errCode) return BERR_TRACE(errCode);
1294       
1295        buf[0] &= ~(BCM4506_DISEQC_CTL2_TB_ENABLE | BCM4506_DISEQC_CTL2_TB_B | BCM4506_DISEQC_CTL2_ENVELOPE | BCM4506_DISEQC_CTL2_EXP_REPLY_DISABLE);
1296       
1297        if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eUnmodulated) {
1298            buf[0] |= BCM4506_DISEQC_CTL2_TB_ENABLE;
1299        }
1300        else if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eNominal) {
1301            buf[0] |= BCM4506_DISEQC_CTL2_TB_ENABLE | BCM4506_DISEQC_CTL2_TB_B;
1302        }
1303       
1304        if ( pSettings->toneMode == NEXUS_FrontendDiseqcToneMode_eEnvelope ) {
1305            buf[0] |= BCM4506_DISEQC_CTL2_ENVELOPE;
1306        }
1307       
1308        if (pSettings->replyDisabled) {
1309            buf[0] |= BCM4506_DISEQC_CTL2_EXP_REPLY_DISABLE;
1310        }
1311       
1312        errCode = BAST_WriteConfig(pDevice->astChannel, BCM4506_CONFIG_DISEQC_CTL2, buf, BCM4506_CONFIG_LEN_DISEQC_CTL2);
1313        if (errCode) return BERR_TRACE(errCode);
1314#endif     
1315    }
1316    else if(pDevice->astChip == 4501){
1317#if defined NEXUS_FRONTEND_4501     
1318        errCode = BAST_ReadConfig(pDevice->astChannel, BCM4501_CONFIG_DISEQC_CTL2, buf, BCM4501_CONFIG_LEN_DISEQC_CTL2);
1319        if (errCode) return BERR_TRACE(errCode);
1320
1321        buf[0] &= ~(BCM4501_DISEQC_CTL2_TB_ENABLE | BCM4501_DISEQC_CTL2_TB_B | BCM4501_DISEQC_CTL2_ENVELOPE | BCM4501_DISEQC_CTL2_EXP_REPLY_DISABLE);
1322
1323        if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eUnmodulated) {
1324            buf[0] |= BCM4501_DISEQC_CTL2_TB_ENABLE;
1325        }
1326        else if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eNominal) {
1327            buf[0] |= BCM4501_DISEQC_CTL2_TB_ENABLE | BCM4501_DISEQC_CTL2_TB_B;
1328        }
1329
1330        if ( pSettings->toneMode == NEXUS_FrontendDiseqcToneMode_eEnvelope ) {
1331            buf[0] |= BCM4501_DISEQC_CTL2_ENVELOPE;
1332        }
1333
1334        if (pSettings->replyDisabled) {
1335            buf[0] |= BCM4501_DISEQC_CTL2_EXP_REPLY_DISABLE;
1336        }
1337
1338        errCode = BAST_WriteConfig(pDevice->astChannel, BCM4501_CONFIG_DISEQC_CTL2, buf, BCM4501_CONFIG_LEN_DISEQC_CTL2);
1339        if (errCode) return BERR_TRACE(errCode);
1340#endif     
1341    }
1342    else {
1343#if defined(BCM73XX_CONFIG_DISEQC_CTL)         
1344        errCode = BAST_ReadConfig(pDevice->astChannel, BCM73XX_CONFIG_DISEQC_CTL, buf, BCM73XX_CONFIG_LEN_DISEQC_CTL);
1345        if (errCode) return BERR_TRACE(errCode);
1346
1347        buf[1] &= ~(BCM73XX_DISEQC_CTL_TONEBURST_ENABLE | BCM73XX_DISEQC_CTL_TONEBURST_B | BCM73XX_DISEQC_CTL_ENVELOPE | BCM73XX_DISEQC_CTL_EXP_REPLY_DISABLE);
1348
1349        if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eUnmodulated) {
1350            buf[1] |= BCM73XX_DISEQC_CTL_TONEBURST_ENABLE;
1351        }
1352        else if (pSettings->toneBurst == NEXUS_FrontendDiseqcToneBurst_eNominal) {
1353            buf[1] |= BCM73XX_DISEQC_CTL_TONEBURST_ENABLE | BCM73XX_DISEQC_CTL_TONEBURST_B;
1354        }
1355
1356        if ( pSettings->toneMode == NEXUS_FrontendDiseqcToneMode_eEnvelope ) {
1357            buf[1] |= BCM73XX_DISEQC_CTL_ENVELOPE;
1358        }
1359
1360        if (pSettings->replyDisabled) {
1361            buf[1] |= BCM73XX_DISEQC_CTL_EXP_REPLY_DISABLE;
1362        }
1363
1364        errCode = BAST_WriteConfig(pDevice->astChannel, BCM73XX_CONFIG_DISEQC_CTL, buf, BCM73XX_CONFIG_LEN_DISEQC_CTL);
1365        if (errCode) return BERR_TRACE(errCode);
1366
1367        /*After setting DISEQC_CTL, reset is needed to complete setting*/
1368        if ((pSettings->toneBurst != pDevice->diseqcSettings.toneBurst) ||
1369            (pSettings->toneMode!= pDevice->diseqcSettings.toneMode))
1370        {
1371            errCode = BAST_ResetDiseqc(pDevice->astChannel, 0);
1372            if ( errCode )
1373            {
1374                return BERR_TRACE(errCode);
1375            }
1376        }
1377#else
1378    BSTD_UNUSED(buf);
1379#endif
1380    }
1381
1382    #ifndef TEST_NETWORK_TUNER
1383    if (pDevice->capabilities.diseqc)
1384    #endif
1385    {
1386        #ifdef TEST_NETWORK_TUNER
1387        if (pDevice->settings.channelIndex==NEXUS_P_MAX_AST_CHANNELS-1)
1388        {
1389            /* For testing external tuner easily.  If we are SDS1 for 7325 or SDS2 for 7335, control diseqc from SDS0 or SDS1, respectively. */
1390            pDevice = pAstDevice[NEXUS_P_MAX_AST_CHANNELS-2];
1391        }
1392        #endif
1393
1394        errCode = BAST_SetDiseqcTone(pDevice->astChannel, pSettings->toneEnabled);
1395        if ( errCode )
1396        {
1397            return BERR_TRACE(errCode);
1398        }
1399        if((pDevice->astChip != 4501) && (pDevice->astChip != 4506)){
1400            errCode = BAST_EnableDiseqcLnb(pDevice->astChannel, pSettings->lnbEnabled);
1401            if ( errCode )
1402            {
1403                return BERR_TRACE(errCode);
1404            }
1405        }
1406
1407        errCode = BAST_SetDiseqcVoltage(pDevice->astChannel, (pSettings->voltage==NEXUS_FrontendDiseqcVoltage_e18v)?true:false);
1408        if ( errCode )
1409        {
1410            /* Restore original setting */
1411            (void) BAST_SetDiseqcTone(pDevice->astChannel, pDevice->diseqcSettings.toneEnabled);
1412            return BERR_TRACE(errCode);
1413        }
1414
1415        pDevice->diseqcSettings = *pSettings;
1416    }
1417
1418    if (!pDevice->diseqcSettings.enabled) {
1419        BAST_PowerDown(pDevice->astChannel, BAST_CORE_DISEQC);
1420    }
1421
1422
1423    return BERR_SUCCESS;
1424}
1425
1426static NEXUS_Error NEXUS_Frontend_P_Ast_GetDiseqcStatus( void *handle, NEXUS_FrontendDiseqcStatus *pStatus )
1427{
1428    NEXUS_AstDevice *pDevice = handle;
1429    BERR_Code rc;
1430    uint8_t temp;
1431    BAST_DiseqcStatus diseqcStatus;
1432
1433    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1434    BKNI_Memset(pStatus, 0, sizeof(*pStatus));
1435
1436#if !defined NEXUS_FRONTEND_4501
1437    /* HW requires that BAST_GetDiseqcVoltage be called before BAST_GetDiseqcTone */
1438    rc = BAST_GetDiseqcVoltage(pDevice->astChannel, &temp);
1439    if (rc) return BERR_TRACE(rc);
1440    pStatus->voltage = temp;
1441#else
1442    BSTD_UNUSED(temp);
1443#endif
1444
1445    rc = BAST_GetDiseqcTone(pDevice->astChannel, &pStatus->toneEnabled);
1446    if (rc) return BERR_TRACE(rc);
1447
1448    BDBG_CASSERT((NEXUS_FrontendDiseqcMessageStatus)BAST_DiseqcSendStatus_eBusy == NEXUS_FrontendDiseqcMessageStatus_eBusy);
1449    rc = BAST_GetDiseqcStatus(pDevice->astChannel, &diseqcStatus);
1450    if (rc) return BERR_TRACE(rc);
1451    pStatus->sendStatus = diseqcStatus.status;
1452
1453    return 0;
1454}
1455
1456static NEXUS_Error NEXUS_Frontend_P_Ast_SendDiseqcMessage( void *handle, const uint8_t *pSendData,
1457    size_t sendDataSize, const NEXUS_CallbackDesc *pSendComplete )
1458{
1459    NEXUS_AstDevice *pDevice = handle;
1460    BERR_Code errCode;
1461
1462    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1463    BDBG_ASSERT(NULL != pSendData);
1464    BDBG_ASSERT(sendDataSize > 0);
1465
1466    if (pDevice->capabilities.diseqc)
1467    {
1468        NEXUS_TaskCallback_Set(pDevice->diseqcAppCallback, pSendComplete);
1469        errCode = BAST_SendDiseqcCommand(pDevice->astChannel, pSendData, sendDataSize);
1470        if ( errCode )
1471        {
1472            NEXUS_TaskCallback_Set(pDevice->diseqcAppCallback, NULL);
1473            return BERR_TRACE(errCode);
1474        }
1475
1476        return BERR_SUCCESS;
1477    }
1478    else
1479    {
1480        return BERR_TRACE(BERR_NOT_SUPPORTED);
1481    }
1482}
1483
1484static NEXUS_Error NEXUS_Frontend_P_Ast_ResetDiseqc( void *handle, const uint8_t options )
1485{
1486    NEXUS_AstDevice *pDevice = handle;
1487    BERR_Code errCode;
1488
1489    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1490
1491    if (pDevice->capabilities.diseqc)
1492    {
1493        errCode = BAST_ResetDiseqc(pDevice->astChannel, options);
1494        if ( errCode )
1495        {
1496            return BERR_TRACE(errCode);
1497        }
1498
1499        return BERR_SUCCESS;
1500    }
1501    else
1502    {
1503        return BERR_TRACE(BERR_NOT_SUPPORTED);
1504    }
1505}
1506
1507static NEXUS_Error NEXUS_Frontend_P_Ast_GetDiseqcReply( void *handle, NEXUS_FrontendDiseqcMessageStatus *pStatus, uint8_t *pReplyBuffer,
1508    size_t replyBufferSize, size_t *pReplyLength )
1509{
1510    NEXUS_AstDevice *pDevice = handle;
1511    BERR_Code errCode;
1512    BAST_DiseqcStatus status;
1513    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1514
1515    BDBG_ASSERT(NULL != pStatus);
1516    BDBG_ASSERT(NULL != pReplyBuffer);
1517    BDBG_ASSERT(replyBufferSize > 0);
1518    BDBG_ASSERT(NULL != pReplyLength);
1519
1520    NEXUS_TaskCallback_Set(pDevice->diseqcAppCallback, NULL);   /* just to be safe */
1521
1522    BDBG_CASSERT((NEXUS_FrontendDiseqcMessageStatus)BAST_DiseqcSendStatus_eBusy == NEXUS_FrontendDiseqcMessageStatus_eBusy);
1523    errCode = BAST_GetDiseqcStatus(pDevice->astChannel, &status);
1524    *pStatus = status.status;
1525
1526    if (errCode || status.status != BAST_DiseqcSendStatus_eSuccess) {
1527        return BERR_TRACE(errCode);
1528    }
1529
1530    if (!status.bReplyExpected) {
1531        status.nReplyBytes = 0; /* force it */
1532    }
1533
1534    *pReplyLength = replyBufferSize<status.nReplyBytes?replyBufferSize:status.nReplyBytes;
1535    if (*pReplyLength) {
1536        BKNI_Memcpy(pReplyBuffer, status.replyBuffer, *pReplyLength);
1537    }
1538
1539    return BERR_SUCCESS;
1540}
1541
1542static NEXUS_Error NEXUS_Frontend_P_Ast_SendDiseqcAcw( void *handle, uint8_t codeWord )
1543{
1544    NEXUS_Error errCode;
1545    NEXUS_AstDevice *pDevice = handle;
1546    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1547
1548    if (pDevice->capabilities.diseqc)
1549    {
1550        errCode = BAST_SendACW(pDevice->astChannel, codeWord);
1551        if ( errCode )
1552        {
1553            return BERR_TRACE(errCode);
1554        }
1555    }
1556    else
1557    {
1558        return BERR_TRACE(BERR_NOT_SUPPORTED);
1559    }
1560
1561
1562    return BERR_SUCCESS;
1563}
1564
1565static NEXUS_Error NEXUS_Frontend_P_Ast_GetSoftDecisions(void *handle, NEXUS_FrontendSoftDecision *pDecisions, size_t length)
1566{
1567#define TOTAL_AST_SOFTDECISIONS 15  /* What an odd number... */
1568    int j;
1569    size_t i;
1570    NEXUS_Error errCode;
1571    NEXUS_AstDevice *pDevice = handle;
1572    int16_t d_i[TOTAL_AST_SOFTDECISIONS], d_q[TOTAL_AST_SOFTDECISIONS];
1573
1574    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1575
1576    for( i=0; i<length; i += TOTAL_AST_SOFTDECISIONS )
1577    {
1578        errCode = BAST_GetSoftDecisionBuf(pDevice->astChannel, d_i, d_q);
1579        if ( errCode )
1580        {
1581            return BERR_TRACE(errCode);
1582        }
1583        for ( j=0; j<TOTAL_AST_SOFTDECISIONS && i+j<length; j++ )
1584        {
1585            pDecisions[i+j].i = d_i[j] * 256 * 2;
1586            pDecisions[i+j].q = d_q[j] * 256 * 2;
1587        }
1588    }
1589
1590    return BERR_SUCCESS;
1591}
1592
1593static NEXUS_Error NEXUS_Frontend_P_Ast_ReadSatelliteConfig( void *handle, unsigned id, void *buffer, unsigned bufferSize )
1594{
1595    NEXUS_AstDevice *pDevice = handle;
1596    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1597    return BAST_ReadConfig(pDevice->astChannel, id, buffer, bufferSize);
1598}
1599
1600static NEXUS_Error NEXUS_Frontend_P_Ast_WriteSatelliteConfig( void *handle, unsigned id, const void *buffer, unsigned bufferSize )
1601{
1602    NEXUS_AstDevice *pDevice = handle;
1603    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1604    return BAST_WriteConfig(pDevice->astChannel, id, (void*)buffer, bufferSize);
1605}
1606
1607static NEXUS_Error NEXUS_Frontend_P_Ast_SatellitePeakscan( void *handle, const NEXUS_FrontendSatellitePeakscanSettings *pSettings )
1608{
1609#if defined NEXUS_FRONTEND_73XX || defined NEXUS_FRONTEND_4506 || defined NEXUS_FRONTEND_7346
1610    NEXUS_AstDevice *pDevice = handle;
1611    NEXUS_SatellitePeakscanStatus *psStatus = &pDevice->peakscanStatus;
1612    BERR_Code errCode;
1613    uint8_t buf[8];
1614
1615    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1616
1617    if (!pDevice->peakscanEvent) {
1618        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1619    }
1620
1621    if (pSettings->frequency - pSettings->frequencyRange < NEXUS_SATELLITE_PEAKSCAN_MIN_FREQ ||
1622        pSettings->frequency + pSettings->frequencyRange > NEXUS_SATELLITE_PEAKSCAN_MAX_FREQ) {
1623        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
1624    }
1625
1626    NEXUS_TaskCallback_Set(pDevice->peakscanAppCallback, &pSettings->peakscanCallback);
1627
1628#if BCHP_CHIP ==7342 || BCHP_CHIP==7340 || BCHP_CHIP==7335 || BCHP_CHIP==7325
1629    /* set BLIND_SCAN_SYM_RATE_MIN configuration parameter */
1630    buf[0] = (uint8_t)((pSettings->minSymbolRate >> 24) & 0xFF);
1631    buf[1] = (uint8_t)((pSettings->minSymbolRate >> 16) & 0xFF);
1632    buf[2] = (uint8_t)((pSettings->minSymbolRate >> 8) & 0xFF);
1633    buf[3] = (uint8_t)(pSettings->minSymbolRate & 0xFF);
1634    errCode = BAST_WriteConfig(pDevice->astChannel, PEAK_SCAN_SYM_RATE_MIN, buf, LEN_PEAK_SCAN_SYM_RATE_MIN);
1635    if (errCode != BERR_SUCCESS) {
1636        BDBG_ERR(("BAST_WriteConfig(BLIND_SCAN_SYM_RATE_MIN) error %#x. Peak scan not initiated", errCode));
1637        return BERR_TRACE(errCode);
1638    }
1639
1640    /* set BLIND_SCAN_SYM_RATE_MAX configuration parameter */
1641    buf[0] = (uint8_t)((pSettings->maxSymbolRate >> 24) & 0xFF);
1642    buf[1] = (uint8_t)((pSettings->maxSymbolRate >> 16) & 0xFF);
1643    buf[2] = (uint8_t)((pSettings->maxSymbolRate >> 8) & 0xFF);
1644    buf[3] = (uint8_t)(pSettings->maxSymbolRate & 0xFF);
1645    errCode = BAST_WriteConfig(pDevice->astChannel, PEAK_SCAN_SYM_RATE_MAX, buf, LEN_PEAK_SCAN_SYM_RATE_MAX);
1646    if (errCode != BERR_SUCCESS) {
1647        BDBG_ERR(("BAST_WriteConfig(BLIND_SCAN_SYM_RATE_MAX) error %#x. Peak scan not initiated", errCode));
1648        return BERR_TRACE(errCode);
1649    }
1650#else
1651  buf[0]=0;
1652  errCode = BAST_SetPeakScanSymbolRateRange(pDevice->astChannel,  pSettings->minSymbolRate, pSettings->maxSymbolRate );
1653  if (errCode != BERR_SUCCESS) {
1654      BDBG_ERR(("BAST_WriteConfig(BLIND_SCAN_SYM_RATE_MAX) error %#x. Peak scan not initiated", errCode));
1655      return BERR_TRACE(errCode);
1656  }
1657#endif
1658
1659    /* setup status variables */
1660    psStatus->curFreq = pSettings->frequency - pSettings->frequencyRange;
1661    psStatus->endFreq = pSettings->frequency + pSettings->frequencyRange;
1662    psStatus->stepFreq = pSettings->frequencyStep;
1663    psStatus->symRateCount = 0;
1664    psStatus->lastSymRate = 0;
1665    psStatus->maxPeakPower = 0;
1666    psStatus->maxPeakFreq = 0;
1667    psStatus->scanFinished = false;
1668    psStatus->singleScan = (pSettings->frequencyRange==0); 
1669
1670    if (psStatus->singleScan) {
1671        psStatus->endFreq = psStatus->curFreq+1;
1672    }
1673
1674    errCode = BAST_PeakScan(pDevice->astChannel, psStatus->curFreq);
1675    if (errCode != BERR_SUCCESS) {
1676        BDBG_ERR(("BAST_PeakScan() error %#x. Peak scan not initiated", errCode));
1677        return BERR_TRACE(errCode);
1678    }
1679
1680    BDBG_MSG(("Peak scan started at %uHz", psStatus->curFreq));
1681
1682    /* the state machine is driven by pDevice->peakscanEventCallback and NEXUS_Frontend_P_Ast_PeakscanEventHandler */
1683    return NEXUS_SUCCESS;
1684
1685#else /* defined NEXUS_FRONTEND_73XX || defined NEXUS_FRONTEND_4506 */
1686    BSTD_UNUSED(handle);
1687    BSTD_UNUSED(pSettings);
1688    return NEXUS_NOT_SUPPORTED;
1689#endif
1690}
1691
1692static NEXUS_Error NEXUS_Frontend_P_Ast_GetSatellitePeakscanResult( void *handle, NEXUS_FrontendSatellitePeakscanResult *pResult )
1693{
1694    NEXUS_AstDevice *pDevice = handle;
1695    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1696
1697    if (pDevice->peakscanEvent) {
1698        if (pDevice->peakscanStatus.scanFinished) {
1699            pResult->peakFrequency = pDevice->peakscanStatus.maxPeakFreq;
1700            pResult->symbolRate = pDevice->peakscanStatus.lastSymRate;
1701            pResult->lastFrequency= pDevice->peakscanStatus.curFreq;
1702            pResult->peakPower = pDevice->peakscanStatus.maxPeakPower;
1703            return NEXUS_SUCCESS;
1704        }
1705        else {
1706            return BERR_TRACE(NEXUS_NOT_INITIALIZED);
1707        }
1708    }
1709    else {
1710        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1711    }
1712}
1713
1714static void NEXUS_Frontend_P_Ast_ResetStatus( void *handle )
1715{
1716    NEXUS_AstDevice *pDevice = handle;
1717    BAST_ResetStatus(pDevice->astChannel);
1718}
1719
1720BAST_ChannelHandle NEXUS_Frontend_P_Ast_GetChannel( NEXUS_FrontendHandle handle )
1721{
1722    NEXUS_AstDevice *pDevice;
1723
1724    BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
1725    if (handle->pParentFrontend) {
1726        handle = handle->pParentFrontend;
1727        BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
1728    }
1729    pDevice = handle->pDeviceHandle;
1730    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1731
1732    return pDevice->astChannel;
1733}
1734
1735static void NEXUS_Frontend_P_Ast_LockEventHandler(void *pParam)
1736{
1737    NEXUS_AstDevice *pDevice = pParam;
1738    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1739    BDBG_MSG(("AST Lock Event"));
1740
1741    BTRC_TRACE(ChnChange_TuneLock, STOP);
1742    NEXUS_TaskCallback_Fire(pDevice->lockAppCallback);
1743}
1744
1745static void NEXUS_Frontend_P_Ast_DiseqcEventHandler(void *pParam)
1746{
1747    NEXUS_AstDevice *pDevice = pParam;
1748    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1749    BDBG_MSG(("AST Diseqc Event"));
1750
1751    NEXUS_TaskCallback_Fire(pDevice->diseqcAppCallback);
1752}
1753
1754static void NEXUS_Frontend_P_Ast_PeakscanEventHandler(void *pParam)
1755{
1756    NEXUS_AstDevice *pDevice = pParam;
1757    BAST_PeakScanStatus astStatus;
1758    NEXUS_SatellitePeakscanStatus *psStatus = &pDevice->peakscanStatus;
1759    BERR_Code errCode;
1760    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1761
1762    BDBG_ASSERT(psStatus->curFreq < psStatus->endFreq); /* check for-loop bounds */
1763
1764    /* get results of symbol rate scan */
1765    errCode = BAST_GetPeakScanStatus(pDevice->astChannel, &astStatus);
1766    if (errCode != BERR_SUCCESS) {
1767        BDBG_ERR(("BAST_GetPeakScanStatus() error %#x", errCode));
1768        errCode = BERR_TRACE(errCode);
1769        goto step;
1770    }
1771
1772    if (astStatus.status != 0) {
1773        BDBG_ERR(("BAST_GetPeakScanStatus() scan status error %u", astStatus.status));
1774        goto step;
1775    }
1776
1777    BDBG_MSG(("%d Hz: Fb=%d, power=%#x", astStatus.tunerFreq, astStatus.out, astStatus.peakPower));
1778
1779    if (astStatus.out == psStatus->lastSymRate) { /* same symbol rate as last scan */
1780        psStatus->symRateCount++;
1781        if (psStatus->maxPeakPower < astStatus.peakPower) {
1782            psStatus->maxPeakPower = astStatus.peakPower;
1783            psStatus->maxPeakFreq = astStatus.tunerFreq;
1784        }
1785        if (pDevice->peakscanStatus.singleScan) {
1786            psStatus->lastSymRate = astStatus.out;
1787            goto done;
1788        }
1789    }
1790    else {
1791        if (psStatus->symRateCount > 0) {
1792            BDBG_MSG(("Potential signal found at %d Hz (%d sym/sec)", psStatus->maxPeakFreq, psStatus->lastSymRate));
1793            goto done;
1794        }
1795        else {
1796            /* save new symbol rate */
1797            psStatus->symRateCount = 0;
1798            psStatus->lastSymRate = astStatus.out;
1799            psStatus->maxPeakPower = astStatus.peakPower;
1800            psStatus->maxPeakFreq = astStatus.tunerFreq;
1801            if (pDevice->peakscanStatus.singleScan) {
1802                goto done;
1803            }
1804        }
1805    }
1806
1807step:
1808    psStatus->curFreq += psStatus->stepFreq;
1809
1810    if (psStatus->curFreq < psStatus->endFreq) {
1811        errCode = BAST_PeakScan(pDevice->astChannel, psStatus->curFreq);
1812        if (errCode != BERR_SUCCESS) {
1813            BDBG_ERR(("BAST_PeakScan() error %#x. Peak scan terminated", errCode));
1814            errCode = BERR_TRACE(errCode);
1815            goto done;
1816        }
1817        else {
1818            return;
1819        }
1820    }
1821    else {
1822        if (psStatus->symRateCount > 0) {
1823            BDBG_WRN(("Potential signal found at %d Hz (%d sym/sec), but reached end of scan range",
1824                psStatus->maxPeakFreq, psStatus->lastSymRate));
1825        }
1826        else {
1827            BDBG_WRN(("No signal found using peak scan"));
1828            psStatus->maxPeakFreq = 0;
1829            psStatus->lastSymRate = 0;
1830        }
1831        psStatus->curFreq -= psStatus->stepFreq;
1832        goto done;
1833    }
1834
1835done:
1836    psStatus->scanFinished = true;
1837    NEXUS_TaskCallback_Fire(pDevice->peakscanAppCallback);
1838
1839    return;
1840}
1841
1842static NEXUS_Error NEXUS_Frontend_P_Ast_RegisterExtension(NEXUS_FrontendHandle parentHandle, NEXUS_FrontendHandle extensionHandle)
1843{
1844    NEXUS_AstDevice *pDevice;
1845
1846    BDBG_OBJECT_ASSERT(parentHandle, NEXUS_Frontend);
1847    pDevice = parentHandle->pDeviceHandle;
1848    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1849
1850    if (extensionHandle == NULL) {
1851        extensionHandle = parentHandle;
1852    }
1853    else {
1854        BDBG_OBJECT_ASSERT(extensionHandle, NEXUS_Frontend);
1855    }
1856
1857    /* recreate callbacks with the extension handle. this allows NEXUS_StopCallbacks to work. */
1858    if (pDevice->diseqcAppCallback) {
1859        NEXUS_TaskCallback_Destroy(pDevice->diseqcAppCallback);
1860        pDevice->diseqcAppCallback = NEXUS_TaskCallback_Create(extensionHandle, NULL);
1861        if ( NULL == pDevice->diseqcAppCallback ) {
1862            return BERR_TRACE(BERR_OS_ERROR);
1863        }
1864    }
1865    if (pDevice->peakscanAppCallback) {
1866        NEXUS_TaskCallback_Destroy(pDevice->peakscanAppCallback);
1867        pDevice->peakscanAppCallback = NEXUS_TaskCallback_Create(extensionHandle, NULL);
1868        if ( NULL == pDevice->peakscanAppCallback ) {
1869            return BERR_TRACE(BERR_OS_ERROR);
1870        }
1871    }
1872    if (pDevice->lockAppCallback) {
1873        NEXUS_TaskCallback_Destroy(pDevice->lockAppCallback);
1874        pDevice->lockAppCallback = NEXUS_TaskCallback_Create(extensionHandle, NULL);
1875        if ( NULL == pDevice->lockAppCallback ) {
1876            return BERR_TRACE(BERR_OS_ERROR);
1877        }
1878    }
1879    if (pDevice->ftmCallback) {
1880        NEXUS_TaskCallback_Destroy(pDevice->ftmCallback);
1881        pDevice->ftmCallback = NEXUS_TaskCallback_Create(extensionHandle, NULL);
1882        if ( NULL == pDevice->ftmCallback ) {
1883            return BERR_TRACE(BERR_OS_ERROR);
1884        }
1885    }
1886
1887    return 0;
1888}
1889
1890/**
1891The following public API functions are implemented for AST only.
1892This means that a combo AST/SDS system will no longer work.
1893**/
1894
1895NEXUS_AstDevice *NEXUS_Frontend_P_GetAstDevice(NEXUS_FrontendHandle handle)
1896{
1897    NEXUS_AstDevice *pDevice;
1898
1899    BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
1900    if (handle->pParentFrontend) {
1901        handle = handle->pParentFrontend;
1902        BDBG_OBJECT_ASSERT(handle, NEXUS_Frontend);
1903    }
1904    pDevice = handle->pDeviceHandle;
1905    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1906    return pDevice;
1907}
1908
1909static NEXUS_Error NEXUS_Frontend_P_Ast_GetFastStatus(void *handle, NEXUS_FrontendFastStatus *pStatus )
1910{
1911    NEXUS_AstDevice *pDevice = handle;
1912    bool isLocked = false;
1913    BERR_Code rc;
1914    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1915    BDBG_ASSERT(pStatus);
1916    pStatus->lockStatus = NEXUS_FrontendLockStatus_eUnknown;
1917    rc = BAST_GetLockStatus(pDevice->astChannel, &isLocked);
1918    if (rc) {
1919        return BERR_TRACE(NEXUS_NOT_AVAILABLE);
1920    }
1921    /* AST only returns locked/unlocked, there is currently no "no signal" status. */
1922    pStatus->lockStatus = isLocked ? NEXUS_FrontendLockStatus_eLocked : NEXUS_FrontendLockStatus_eUnlocked;
1923    return NEXUS_SUCCESS;
1924}
1925
1926/***************************************************************************
1927 * Module callback functions for I2C -- I2C Auto-synchronizes these.
1928 ***************************************************************************/
1929static BERR_Code NEXUS_Frontend_P_Ast_I2cReadNoAddr(void * context, uint16_t chipAddr, uint8_t *pData, size_t length)
1930{
1931    NEXUS_AstDevice *pDevice = context;
1932    uint8_t dummy;
1933    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1934    return BAST_ReadMi2c(pDevice->astChannel, chipAddr<<1, &dummy, 0, pData, length);
1935}
1936
1937static BERR_Code NEXUS_Frontend_P_Ast_I2cWriteNoAddr(void * context, uint16_t chipAddr, const uint8_t *pData, size_t length)
1938{
1939    NEXUS_AstDevice *pDevice = context;
1940    BDBG_OBJECT_ASSERT(pDevice, NEXUS_AstDevice);
1941    return BAST_WriteMi2c(pDevice->astChannel, chipAddr<<1, (uint8_t *)((unsigned long)pData), length);
1942}
1943
Note: See TracBrowser for help on using the repository browser.