2 Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Trident Microsystems nor Hauppauge Computer Works
14 nor the names of its contributors may be used to endorse or promote
15 products derived from this software without specific prior written
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
32 * \file $Id: drx_driver.c,v 1.40 2010/01/12 01:24:56 lfeng Exp $
34 * \brief Generic DRX functionality, DRX driver core.
38 /*------------------------------------------------------------------------------
40 ------------------------------------------------------------------------------*/
41 #include "drx_driver.h"
44 #define VERSION_FIXED 0
46 #define VERSION_MAJOR 0
47 #define VERSION_MINOR 0
48 #define VERSION_PATCH 0
50 #include "drx_driver_version.h"
53 /*------------------------------------------------------------------------------
55 ------------------------------------------------------------------------------*/
57 /*============================================================================*/
58 /*=== MICROCODE RELATED DEFINES ==============================================*/
59 /*============================================================================*/
61 /** \brief Magic word for checking correct Endianess of microcode data. */
62 #ifndef DRX_UCODE_MAGIC_WORD
63 #define DRX_UCODE_MAGIC_WORD ((((u16_t)'H')<<8)+((u16_t)'L'))
66 /** \brief CRC flag in ucode header, flags field. */
67 #ifndef DRX_UCODE_CRC_FLAG
68 #define DRX_UCODE_CRC_FLAG (0x0001)
71 /** \brief Compression flag in ucode header, flags field. */
72 #ifndef DRX_UCODE_COMPRESSION_FLAG
73 #define DRX_UCODE_COMPRESSION_FLAG (0x0002)
76 /** \brief Maximum size of buffer used to verify the microcode.
77 Must be an even number. */
78 #ifndef DRX_UCODE_MAX_BUF_SIZE
79 #define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
81 #if DRX_UCODE_MAX_BUF_SIZE & 1
82 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
85 /*============================================================================*/
86 /*=== CHANNEL SCAN RELATED DEFINES ===========================================*/
87 /*============================================================================*/
90 * \brief Maximum progress indication.
92 * Progress indication will run from 0 upto DRX_SCAN_MAX_PROGRESS during scan.
95 #ifndef DRX_SCAN_MAX_PROGRESS
96 #define DRX_SCAN_MAX_PROGRESS 1000
99 /*============================================================================*/
100 /*=== MACROS =================================================================*/
101 /*============================================================================*/
103 #define DRX_ISPOWERDOWNMODE( mode ) ( ( mode == DRX_POWER_MODE_9 ) || \
104 ( mode == DRX_POWER_MODE_10 ) || \
105 ( mode == DRX_POWER_MODE_11 ) || \
106 ( mode == DRX_POWER_MODE_12 ) || \
107 ( mode == DRX_POWER_MODE_13 ) || \
108 ( mode == DRX_POWER_MODE_14 ) || \
109 ( mode == DRX_POWER_MODE_15 ) || \
110 ( mode == DRX_POWER_MODE_16 ) || \
111 ( mode == DRX_POWER_DOWN ) )
113 /*------------------------------------------------------------------------------
115 ------------------------------------------------------------------------------*/
117 /*------------------------------------------------------------------------------
119 ------------------------------------------------------------------------------*/
120 /** \brief Structure of the microcode block headers */
122 u32_t addr
; /**< Destination address of the data in this block */
123 u16_t size
; /**< Size of the block data following this header counted in
125 u16_t flags
; /**< Flags for this data block:
127 - bit[1]= compression on/off
128 - bit[15..2]=reserved */
129 u16_t CRC
; /**< CRC value of the data block, only valid if CRC flag is
131 } DRXUCodeBlockHdr_t
, *pDRXUCodeBlockHdr_t
;
133 /*------------------------------------------------------------------------------
135 ------------------------------------------------------------------------------*/
137 /*============================================================================*/
138 /*============================================================================*/
139 /*== Channel Scan Functions ==================================================*/
140 /*============================================================================*/
141 /*============================================================================*/
143 #ifndef DRX_EXCLUDE_SCAN
145 /* Prototype of default scanning function */
147 ScanFunctionDefault( void *scanContext
,
148 DRXScanCommand_t scanCommand
,
149 pDRXChannel_t scanChannel
,
150 pBool_t getNextChannel
);
153 * \brief Get pointer to scanning function.
154 * \param demod: Pointer to demodulator instance.
155 * \return DRXScanFunc_t.
158 GetScanFunction( pDRXDemodInstance_t demod
)
160 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
)(NULL
);
161 DRXScanFunc_t scanFunc
= (DRXScanFunc_t
)(NULL
);
163 /* get scan function from common attributes */
164 commonAttr
= (pDRXCommonAttr_t
)demod
->myCommonAttr
;
165 scanFunc
= commonAttr
->scanFunction
;
167 if ( scanFunc
!= NULL
)
169 /* return device-specific scan function if it's not NULL */
172 /* otherwise return default scan function in core driver */
173 return &ScanFunctionDefault
;
177 * \brief Get Context pointer.
178 * \param demod: Pointer to demodulator instance.
179 * \param scanContext: Context Pointer.
180 * \return DRXScanFunc_t.
182 void *GetScanContext( pDRXDemodInstance_t demod
,
185 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
)(NULL
);
187 /* get scan function from common attributes */
188 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
189 scanContext
= commonAttr
->scanContext
;
191 if ( scanContext
== NULL
)
193 scanContext
= (void *) demod
;
200 * \brief Wait for lock while scanning.
201 * \param demod: Pointer to demodulator instance.
202 * \param lockStat: Pointer to bool indicating if end result is lock or not.
203 * \return DRXStatus_t.
204 * \retval DRX_STS_OK: Success
205 * \retval DRX_STS_ERROR: I2C failure or bsp function failure.
207 * Wait until timeout, desired lock or NEVER_LOCK.
209 * - lock function returns : at least DRX_NOT_LOCKED and a lock state
210 * higher than DRX_NOT_LOCKED.
211 * - BSP has a clock function to retrieve a millisecond ticker value.
212 * - BSP has a sleep function to enable sleep of n millisecond.
214 * In case DRX_NEVER_LOCK is returned the poll-wait will be aborted.
218 ScanWaitForLock( pDRXDemodInstance_t demod
,
221 Bool_t doneWaiting
= FALSE
;
222 DRXLockStatus_t lockState
= DRX_NOT_LOCKED
;
223 DRXLockStatus_t desiredLockState
= DRX_NOT_LOCKED
;
224 u32_t timeoutValue
= 0;
225 u32_t startTimeLockStage
= 0;
226 u32_t currentTime
= 0;
227 u32_t timerValue
= 0;
230 timeoutValue
= (u32_t
) demod
->myCommonAttr
->scanDemodLockTimeout
;
231 desiredLockState
= demod
->myCommonAttr
->scanDesiredLock
;
232 startTimeLockStage
= DRXBSP_HST_Clock();
234 /* Start polling loop, checking for lock & timeout */
235 while ( doneWaiting
== FALSE
)
238 if ( DRX_Ctrl( demod
, DRX_CTRL_LOCK_STATUS
, &lockState
) != DRX_STS_OK
)
240 return DRX_STS_ERROR
;
242 currentTime
= DRXBSP_HST_Clock();
244 timerValue
= currentTime
- startTimeLockStage
;
245 if ( lockState
>= desiredLockState
)
249 } /* if ( lockState >= desiredLockState ) .. */
250 else if ( lockState
== DRX_NEVER_LOCK
)
253 } /* if ( lockState == DRX_NEVER_LOCK ) .. */
254 else if ( timerValue
> timeoutValue
)
256 /* lockState == DRX_NOT_LOCKED and timeout */
261 if ( DRXBSP_HST_Sleep( 10 ) != DRX_STS_OK
)
263 return DRX_STS_ERROR
;
265 } /* if ( timerValue > timeoutValue ) .. */
272 /*============================================================================*/
275 * \brief Determine next frequency to scan.
276 * \param demod: Pointer to demodulator instance.
277 * \param skip : Minimum frequency step to take.
278 * \return DRXStatus_t.
279 * \retval DRX_STS_OK: Succes.
280 * \retval DRX_STS_INVALID_ARG: Invalid frequency plan.
282 * Helper function for CtrlScanNext() function.
283 * Compute next frequency & index in frequency plan.
284 * Check if scan is ready.
288 ScanPrepareNextScan ( pDRXDemodInstance_t demod
,
289 DRXFrequency_t skip
)
291 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
)(NULL
);
292 u16_t tableIndex
= 0;
293 u16_t frequencyPlanSize
= 0;
294 pDRXFrequencyPlan_t frequencyPlan
= (pDRXFrequencyPlan_t
)(NULL
);
295 DRXFrequency_t nextFrequency
= 0;
296 DRXFrequency_t tunerMinFrequency
= 0;
297 DRXFrequency_t tunerMaxFrequency
= 0;
299 commonAttr
= (pDRXCommonAttr_t
)demod
->myCommonAttr
;
300 tableIndex
= commonAttr
->scanFreqPlanIndex
;
301 frequencyPlan
= commonAttr
->scanParam
->frequencyPlan
;
302 nextFrequency
= commonAttr
->scanNextFrequency
;
303 tunerMinFrequency
= commonAttr
->tunerMinFreqRF
;
304 tunerMaxFrequency
= commonAttr
->tunerMaxFreqRF
;
308 /* Search next frequency to scan */
310 /* always take at least one step */
311 (commonAttr
->scanChannelsScanned
) ++;
312 nextFrequency
+= frequencyPlan
[tableIndex
].step
;
313 skip
-= frequencyPlan
[tableIndex
].step
;
315 /* and then as many steps necessary to exceed 'skip'
316 without exceeding end of the band */
317 while ( ( skip
> 0 ) &&
318 ( nextFrequency
<= frequencyPlan
[tableIndex
].last
) )
320 (commonAttr
->scanChannelsScanned
) ++;
321 nextFrequency
+= frequencyPlan
[tableIndex
].step
;
322 skip
-= frequencyPlan
[tableIndex
].step
;
324 /* reset skip, in case we move to the next band later */
327 if ( nextFrequency
> frequencyPlan
[tableIndex
].last
)
329 /* reached end of this band */
331 frequencyPlanSize
= commonAttr
->scanParam
->frequencyPlanSize
;
332 if ( tableIndex
>= frequencyPlanSize
)
334 /* reached end of frequency plan */
335 commonAttr
->scanReady
= TRUE
;
339 nextFrequency
= frequencyPlan
[tableIndex
].first
;
342 if ( nextFrequency
> (tunerMaxFrequency
) )
344 /* reached end of tuner range */
345 commonAttr
->scanReady
= TRUE
;
347 } while( ( nextFrequency
< tunerMinFrequency
) &&
348 ( commonAttr
->scanReady
== FALSE
) );
350 /* Store new values */
351 commonAttr
->scanFreqPlanIndex
= tableIndex
;
352 commonAttr
->scanNextFrequency
= nextFrequency
;
357 /*============================================================================*/
360 * \brief Default DTV scanning function.
362 * \param demod: Pointer to demodulator instance.
363 * \param scanCommand: Scanning command: INIT, NEXT or STOP.
364 * \param scanChannel: Channel to check: frequency and bandwidth, others AUTO
365 * \param getNextChannel: Return TRUE if next frequency is desired at next call
367 * \return DRXStatus_t.
368 * \retval DRX_STS_OK: Channel found, DRX_CTRL_GET_CHANNEL can be used
369 * to retrieve channel parameters.
370 * \retval DRX_STS_BUSY: Channel not found (yet).
371 * \retval DRX_STS_ERROR: Something went wrong.
373 * scanChannel and getNextChannel will be NULL for INIT and STOP.
376 ScanFunctionDefault ( void *scanContext
,
377 DRXScanCommand_t scanCommand
,
378 pDRXChannel_t scanChannel
,
379 pBool_t getNextChannel
)
381 pDRXDemodInstance_t demod
= NULL
;
382 DRXStatus_t status
= DRX_STS_ERROR
;
383 Bool_t isLocked
= FALSE
;
385 demod
= (pDRXDemodInstance_t
) scanContext
;
387 if ( scanCommand
!= DRX_SCAN_COMMAND_NEXT
)
389 /* just return OK if not doing "scan next" */
393 *getNextChannel
= FALSE
;
395 status
= DRX_Ctrl ( demod
, DRX_CTRL_SET_CHANNEL
, scanChannel
);
396 if ( status
!= DRX_STS_OK
)
401 status
= ScanWaitForLock ( demod
, &isLocked
);
402 if ( status
!= DRX_STS_OK
)
407 /* done with this channel, move to next one */
408 *getNextChannel
= TRUE
;
410 if ( isLocked
== FALSE
)
412 /* no channel found */
419 /*============================================================================*/
422 * \brief Initialize for channel scan.
423 * \param demod: Pointer to demodulator instance.
424 * \param scanParam: Pointer to scan parameters.
425 * \return DRXStatus_t.
426 * \retval DRX_STS_OK: Initialized for scan.
427 * \retval DRX_STS_ERROR: No overlap between frequency plan and tuner
429 * \retval DRX_STS_INVALID_ARG: Wrong parameters.
431 * This function should be called before starting a complete channel scan.
432 * It will prepare everything for a complete channel scan.
433 * After calling this function the DRX_CTRL_SCAN_NEXT control function can be
434 * used to perform the actual scanning. Scanning will start at the first
435 * center frequency of the frequency plan that is within the tuner range.
439 CtrlScanInit( pDRXDemodInstance_t demod
,
440 pDRXScanParam_t scanParam
)
442 DRXStatus_t status
= DRX_STS_ERROR
;
443 pDRXCommonAttr_t commonAttr
=(pDRXCommonAttr_t
)(NULL
);
444 DRXFrequency_t maxTunerFreq
= 0;
445 DRXFrequency_t minTunerFreq
= 0;
446 u16_t nrChannelsInPlan
= 0;
448 void *scanContext
= NULL
;
450 commonAttr
= (pDRXCommonAttr_t
)demod
->myCommonAttr
;
451 commonAttr
->scanActive
= TRUE
;
453 /* invalidate a previous SCAN_INIT */
454 commonAttr
->scanParam
= (pDRXScanParam_t
)(NULL
);
455 commonAttr
->scanNextFrequency
= 0;
457 /* Check parameters */
458 if ( ( ( demod
->myTuner
== NULL
) &&
459 ( scanParam
->numTries
!=1) ) ||
461 ( scanParam
== NULL
) ||
462 ( scanParam
->numTries
== 0) ||
463 ( scanParam
->frequencyPlan
== NULL
) ||
464 ( scanParam
->frequencyPlanSize
== 0 )
467 commonAttr
->scanActive
= FALSE
;
468 return DRX_STS_INVALID_ARG
;
471 /* Check frequency plan contents */
472 maxTunerFreq
= commonAttr
->tunerMaxFreqRF
;
473 minTunerFreq
= commonAttr
->tunerMinFreqRF
;
474 for( i
= 0; i
< (scanParam
->frequencyPlanSize
); i
++ )
476 DRXFrequency_t width
= 0;
477 DRXFrequency_t step
= scanParam
->frequencyPlan
[i
].step
;
478 DRXFrequency_t firstFreq
= scanParam
->frequencyPlan
[i
].first
;
479 DRXFrequency_t lastFreq
= scanParam
->frequencyPlan
[i
].last
;
480 DRXFrequency_t minFreq
= 0;
481 DRXFrequency_t maxFreq
= 0;
485 /* Step must be positive and non-zero */
486 commonAttr
->scanActive
= FALSE
;
487 return DRX_STS_INVALID_ARG
;
490 if ( firstFreq
> lastFreq
)
492 /* First center frequency is higher than last center frequency */
493 commonAttr
->scanActive
= FALSE
;
494 return DRX_STS_INVALID_ARG
;
497 width
= lastFreq
- firstFreq
;
499 if ( ( width
% step
) != 0 )
501 /* Difference between last and first center frequency is not
502 an integer number of steps */
503 commonAttr
->scanActive
= FALSE
;
504 return DRX_STS_INVALID_ARG
;
507 /* Check if frequency plan entry intersects with tuner range */
508 if ( lastFreq
>= minTunerFreq
)
510 if ( firstFreq
<= maxTunerFreq
)
512 if ( firstFreq
>= minTunerFreq
)
518 DRXFrequency_t n
= 0;
520 n
= ( minTunerFreq
- firstFreq
) / step
;
521 if ( ( ( minTunerFreq
- firstFreq
) % step
) != 0 )
525 minFreq
= firstFreq
+ n
*step
;
528 if ( lastFreq
<= maxTunerFreq
)
536 n
=( lastFreq
- maxTunerFreq
)/step
;
537 if ( (( lastFreq
- maxTunerFreq
)%step
) !=0 )
541 maxFreq
= lastFreq
- n
*step
;
546 /* Keep track of total number of channels within tuner range
547 in this frequency plan. */
548 if ( (minFreq
!=0 ) && ( maxFreq
!= 0 ) )
550 nrChannelsInPlan
+= (u16_t
)( ( ( maxFreq
-minFreq
) / step
) +1 );
552 /* Determine first frequency (within tuner range) to scan */
553 if ( commonAttr
->scanNextFrequency
== 0 )
555 commonAttr
->scanNextFrequency
= minFreq
;
556 commonAttr
->scanFreqPlanIndex
= i
;
562 if ( nrChannelsInPlan
== 0 )
564 /* Tuner range and frequency plan ranges do not overlap */
565 commonAttr
->scanActive
= FALSE
;
566 return DRX_STS_ERROR
;
569 /* Store parameters */
570 commonAttr
->scanReady
= FALSE
;
571 commonAttr
->scanMaxChannels
= nrChannelsInPlan
;
572 commonAttr
->scanChannelsScanned
= 0;
573 commonAttr
->scanParam
= scanParam
; /* SCAN_NEXT is now allowed */
575 scanContext
= GetScanContext(demod
, scanContext
);
577 status
= (*(GetScanFunction( demod
)))
578 ( scanContext
, DRX_SCAN_COMMAND_INIT
, NULL
, NULL
);
580 commonAttr
->scanActive
= FALSE
;
585 /*============================================================================*/
588 * \brief Stop scanning.
589 * \param demod: Pointer to demodulator instance.
590 * \return DRXStatus_t.
591 * \retval DRX_STS_OK: Scan stopped.
592 * \retval DRX_STS_ERROR: Something went wrong.
593 * \retval DRX_STS_INVALID_ARG: Wrong parameters.
596 CtrlScanStop( pDRXDemodInstance_t demod
)
598 DRXStatus_t status
= DRX_STS_ERROR
;
599 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
) (NULL
);
600 void *scanContext
= NULL
;
602 commonAttr
= (pDRXCommonAttr_t
)demod
->myCommonAttr
;
603 commonAttr
->scanActive
= TRUE
;
605 if ( ( commonAttr
->scanParam
== NULL
) ||
606 ( commonAttr
->scanMaxChannels
== 0 ) )
608 /* Scan was not running, just return OK */
609 commonAttr
->scanActive
= FALSE
;
613 /* Call default or device-specific scanning stop function */
614 scanContext
= GetScanContext(demod
, scanContext
);
616 status
= (*(GetScanFunction( demod
)))
617 ( scanContext
, DRX_SCAN_COMMAND_STOP
, NULL
, NULL
);
619 /* All done, invalidate scan-init */
620 commonAttr
->scanParam
= NULL
;
621 commonAttr
->scanMaxChannels
= 0;
622 commonAttr
->scanActive
= FALSE
;
627 /*============================================================================*/
630 * \brief Scan for next channel.
631 * \param demod: Pointer to demodulator instance.
632 * \param scanProgress: Pointer to scan progress.
633 * \return DRXStatus_t.
634 * \retval DRX_STS_OK: Channel found, DRX_CTRL_GET_CHANNEL can be used
635 * to retrieve channel parameters.
636 * \retval DRX_STS_BUSY: Tried part of the channels, as specified in
637 * numTries field of scan parameters. At least one
638 * more call to DRX_CTRL_SCAN_NEXT is needed to
640 * \retval DRX_STS_READY: Reached end of scan range.
641 * \retval DRX_STS_ERROR: Something went wrong.
642 * \retval DRX_STS_INVALID_ARG: Wrong parameters. The scanProgress may be NULL.
644 * Progress indication will run from 0 upto DRX_SCAN_MAX_PROGRESS during scan.
648 CtrlScanNext ( pDRXDemodInstance_t demod
,
649 pu16_t scanProgress
)
651 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
)(NULL
);
652 pBool_t scanReady
= (pBool_t
)(NULL
);
653 u16_t maxProgress
= DRX_SCAN_MAX_PROGRESS
;
657 commonAttr
= (pDRXCommonAttr_t
)demod
->myCommonAttr
;
659 /* Check scan parameters */
660 if ( scanProgress
== NULL
)
662 commonAttr
->scanActive
= FALSE
;
663 return DRX_STS_INVALID_ARG
;
667 commonAttr
->scanActive
= TRUE
;
668 if ( ( commonAttr
->scanParam
== NULL
) ||
669 ( commonAttr
->scanMaxChannels
== 0 ) )
671 /* CtrlScanInit() was not called succesfully before CtrlScanNext() */
672 commonAttr
->scanActive
= FALSE
;
673 return DRX_STS_ERROR
;
676 *scanProgress
= (u16_t
)( ( ( commonAttr
->scanChannelsScanned
)*
677 ( (u32_t
)(maxProgress
) ) ) /
678 ( commonAttr
->scanMaxChannels
) );
681 numTries
= commonAttr
->scanParam
->numTries
;
682 scanReady
= &(commonAttr
->scanReady
);
684 for ( i
= 0; ( (i
< numTries
) && ( (*scanReady
) == FALSE
) ); i
++)
686 DRXChannel_t scanChannel
= { 0 };
687 DRXStatus_t status
= DRX_STS_ERROR
;
688 pDRXFrequencyPlan_t freqPlan
= (pDRXFrequencyPlan_t
) (NULL
);
689 Bool_t nextChannel
= FALSE
;
690 void *scanContext
= NULL
;
692 /* Next channel to scan */
694 &(commonAttr
->scanParam
->frequencyPlan
[commonAttr
->scanFreqPlanIndex
]);
695 scanChannel
.frequency
= commonAttr
->scanNextFrequency
;
696 scanChannel
.bandwidth
= freqPlan
->bandwidth
;
697 scanChannel
.mirror
= DRX_MIRROR_AUTO
;
698 scanChannel
.constellation
= DRX_CONSTELLATION_AUTO
;
699 scanChannel
.hierarchy
= DRX_HIERARCHY_AUTO
;
700 scanChannel
.priority
= DRX_PRIORITY_HIGH
;
701 scanChannel
.coderate
= DRX_CODERATE_AUTO
;
702 scanChannel
.guard
= DRX_GUARD_AUTO
;
703 scanChannel
.fftmode
= DRX_FFTMODE_AUTO
;
704 scanChannel
.classification
= DRX_CLASSIFICATION_AUTO
;
705 scanChannel
.symbolrate
= 0;
706 scanChannel
.interleavemode
= DRX_INTERLEAVEMODE_AUTO
;
707 scanChannel
.ldpc
= DRX_LDPC_AUTO
;
708 scanChannel
.carrier
= DRX_CARRIER_AUTO
;
709 scanChannel
.framemode
= DRX_FRAMEMODE_AUTO
;
710 scanChannel
.pilot
= DRX_PILOT_AUTO
;
712 /* Call default or device-specific scanning function */
713 scanContext
= GetScanContext(demod
, scanContext
);
715 status
= (*(GetScanFunction( demod
)))
716 ( scanContext
,DRX_SCAN_COMMAND_NEXT
,&scanChannel
,&nextChannel
);
718 /* Proceed to next channel if requested */
719 if ( nextChannel
== TRUE
)
721 DRXStatus_t nextStatus
= DRX_STS_ERROR
;
722 DRXFrequency_t skip
= 0;
724 if ( status
== DRX_STS_OK
)
726 /* a channel was found, so skip some frequency steps */
727 skip
= commonAttr
->scanParam
->skip
;
729 nextStatus
= ScanPrepareNextScan( demod
, skip
);
731 /* keep track of progress */
732 *scanProgress
= (u16_t
)(((commonAttr
->scanChannelsScanned
)*
733 ((u32_t
)(maxProgress
)))/
734 (commonAttr
->scanMaxChannels
));
736 if ( nextStatus
!= DRX_STS_OK
)
738 commonAttr
->scanActive
= FALSE
;
742 if ( status
!= DRX_STS_BUSY
)
744 /* channel found or error */
745 commonAttr
->scanActive
= FALSE
;
748 } /* for ( i = 0; i < ( ... numTries); i++) */
750 if ( (*scanReady
) == TRUE
)
752 /* End of scan reached: call stop-scan, ignore any error */
753 CtrlScanStop( demod
);
754 commonAttr
->scanActive
= FALSE
;
755 return (DRX_STS_READY
);
758 commonAttr
->scanActive
= FALSE
;
763 #endif /* #ifndef DRX_EXCLUDE_SCAN */
765 /*============================================================================*/
768 * \brief Program tuner.
769 * \param demod: Pointer to demodulator instance.
770 * \param tunerChannel: Pointer to tuning parameters.
771 * \return DRXStatus_t.
772 * \retval DRX_STS_OK: Tuner programmed successfully.
773 * \retval DRX_STS_ERROR: Something went wrong.
774 * \retval DRX_STS_INVALID_ARG: Wrong parameters.
776 * tunerChannel passes parameters to program the tuner,
777 * but also returns the actual RF and IF frequency from the tuner.
781 CtrlProgramTuner( pDRXDemodInstance_t demod
,
782 pDRXChannel_t channel
)
784 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
)(NULL
);
785 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
786 TUNERMode_t tunerMode
= 0;
787 DRXStatus_t status
= DRX_STS_ERROR
;
788 DRXFrequency_t ifFrequency
= 0;
789 Bool_t tunerSlowMode
= FALSE
;
791 /* can't tune without a tuner */
792 if ( demod
->myTuner
== NULL
)
794 return DRX_STS_INVALID_ARG
;
797 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
799 /* select analog or digital tuner mode based on current standard */
800 if ( DRX_Ctrl( demod
, DRX_CTRL_GET_STANDARD
, &standard
) != DRX_STS_OK
)
802 return DRX_STS_ERROR
;
805 if ( DRX_ISATVSTD( standard
) )
807 tunerMode
|= TUNER_MODE_ANALOG
;
809 else /* note: also for unknown standard */
811 tunerMode
|= TUNER_MODE_DIGITAL
;
814 /* select tuner bandwidth */
815 switch ( channel
->bandwidth
)
817 case DRX_BANDWIDTH_6MHZ
:
818 tunerMode
|= TUNER_MODE_6MHZ
;
820 case DRX_BANDWIDTH_7MHZ
:
821 tunerMode
|= TUNER_MODE_7MHZ
;
823 case DRX_BANDWIDTH_8MHZ
:
824 tunerMode
|= TUNER_MODE_8MHZ
;
826 default: /* note: also for unknown bandwidth */
827 return DRX_STS_INVALID_ARG
;
830 DRX_GET_TUNERSLOWMODE (demod
, tunerSlowMode
);
832 /* select fast (switch) or slow (lock) tuner mode */
835 tunerMode
|= TUNER_MODE_LOCK
;
839 tunerMode
|= TUNER_MODE_SWITCH
;
842 if ( commonAttr
->tunerPortNr
== 1 )
844 Bool_t bridgeClosed
= TRUE
;
845 DRXStatus_t statusBridge
= DRX_STS_ERROR
;
847 statusBridge
= DRX_Ctrl( demod
, DRX_CTRL_I2C_BRIDGE
, &bridgeClosed
);
848 if ( statusBridge
!= DRX_STS_OK
)
854 status
= DRXBSP_TUNER_SetFrequency( demod
->myTuner
,
856 channel
->frequency
);
858 /* attempt restoring bridge before checking status of SetFrequency */
859 if ( commonAttr
->tunerPortNr
== 1 )
861 Bool_t bridgeClosed
= FALSE
;
862 DRXStatus_t statusBridge
= DRX_STS_ERROR
;
864 statusBridge
= DRX_Ctrl( demod
, DRX_CTRL_I2C_BRIDGE
, &bridgeClosed
);
865 if ( statusBridge
!= DRX_STS_OK
)
871 /* now check status of DRXBSP_TUNER_SetFrequency */
872 if ( status
!= DRX_STS_OK
)
877 /* get actual RF and IF frequencies from tuner */
878 status
= DRXBSP_TUNER_GetFrequency( demod
->myTuner
,
880 &(channel
->frequency
),
882 if ( status
!= DRX_STS_OK
)
887 /* update common attributes with information available from this function;
888 TODO: check if this is required and safe */
889 DRX_SET_INTERMEDIATEFREQ( demod
, ifFrequency
);
894 /*============================================================================*/
897 * \brief function to do a register dump.
898 * \param demod: Pointer to demodulator instance.
899 * \param registers: Registers to dump.
900 * \return DRXStatus_t.
901 * \retval DRX_STS_OK: Dump executed successfully.
902 * \retval DRX_STS_ERROR: Something went wrong.
903 * \retval DRX_STS_INVALID_ARG: Wrong parameters.
906 DRXStatus_t
CtrlDumpRegisters( pDRXDemodInstance_t demod
,
907 pDRXRegDump_t registers
)
911 if ( registers
== NULL
)
913 /* registers not supplied */
914 return DRX_STS_INVALID_ARG
;
917 /* start dumping registers */
918 while ( registers
[i
].address
!= 0 )
920 DRXStatus_t status
= DRX_STS_ERROR
;
924 status
= demod
->myAccessFunct
->readReg16Func(
925 demod
->myI2CDevAddr
, registers
[i
].address
, &value
, 0 );
929 if ( status
!= DRX_STS_OK
)
932 depending on device ID, some HW blocks might not be available */
933 data
|= ( (u32_t
)status
) << 16;
935 registers
[i
].data
= data
;
939 /* all done, all OK (any errors are saved inside data) */
943 /*============================================================================*/
944 /*============================================================================*/
945 /*===Microcode related functions==============================================*/
946 /*============================================================================*/
947 /*============================================================================*/
950 * \brief Read a 16 bits word, expects big endian data.
951 * \param addr: Pointer to memory from which to read the 16 bits word.
952 * \return u16_t The data read.
954 * This function takes care of the possible difference in endianness between the
955 * host and the data contained in the microcode image file.
959 UCodeRead16( pu8_t addr
)
961 /* Works fo any host processor */
965 word
= ((u16_t
)addr
[0]);
967 word
|=((u16_t
)addr
[1]);
972 /*============================================================================*/
975 * \brief Read a 32 bits word, expects big endian data.
976 * \param addr: Pointer to memory from which to read the 32 bits word.
977 * \return u32_t The data read.
979 * This function takes care of the possible difference in endianness between the
980 * host and the data contained in the microcode image file.
984 UCodeRead32( pu8_t addr
)
986 /* Works fo any host processor */
990 word
= ((u16_t
)addr
[0]);
992 word
|= ((u16_t
)addr
[1]);
994 word
|= ((u16_t
)addr
[2]);
996 word
|= ((u16_t
)addr
[3]);
1001 /*============================================================================*/
1004 * \brief Compute CRC of block of microcode data.
1005 * \param blockData: Pointer to microcode data.
1006 * \param nrWords: Size of microcode block (number of 16 bits words).
1007 * \return u16_t The computed CRC residu.
1010 UCodeComputeCRC (pu8_t blockData
, u16_t nrWords
)
1017 while ( i
< nrWords
)
1019 CRCWord
|= (u32_t
) UCodeRead16(blockData
);
1020 for (j
= 0; j
< 16; j
++)
1025 CRCWord
^= 0x80050000UL
;
1027 carry
= CRCWord
& 0x80000000UL
;
1030 blockData
+=(sizeof(u16_t
));
1032 return ((u16_t
) (CRCWord
>> 16));
1035 /*============================================================================*/
1038 * \brief Handle microcode upload or verify.
1039 * \param devAddr: Address of device.
1040 * \param mcInfo: Pointer to information about microcode data.
1041 * \param action: Either UCODE_UPLOAD or UCODE_VERIFY
1042 * \return DRXStatus_t.
1043 * \retval DRX_STS_OK:
1044 * - In case of UCODE_UPLOAD: code is successfully uploaded.
1045 * - In case of UCODE_VERIFY: image on device is equal to
1046 * image provided to this control function.
1047 * \retval DRX_STS_ERROR:
1048 * - In case of UCODE_UPLOAD: I2C error.
1049 * - In case of UCODE_VERIFY: I2C error or image on device
1050 * is not equal to image provided to this control function.
1051 * \retval DRX_STS_INVALID_ARG:
1052 * - Invalid arguments.
1053 * - Provided image is corrupt
1056 CtrlUCode( pDRXDemodInstance_t demod
,
1057 pDRXUCodeInfo_t mcInfo
,
1058 DRXUCodeAction_t action
)
1062 u16_t mcNrOfBlks
= 0;
1063 u16_t mcMagicWord
= 0;
1064 pu8_t mcData
= (pu8_t
)(NULL
);
1065 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
)(NULL
);
1067 devAddr
= demod
-> myI2CDevAddr
;
1069 /* Check arguments */
1070 if ( ( mcInfo
== NULL
) ||
1071 ( mcInfo
->mcData
== NULL
) )
1073 return DRX_STS_INVALID_ARG
;
1076 mcData
= mcInfo
->mcData
;
1079 mcMagicWord
= UCodeRead16( mcData
);
1080 mcData
+= sizeof( u16_t
);
1081 mcNrOfBlks
= UCodeRead16( mcData
);
1082 mcData
+= sizeof( u16_t
);
1084 if ( ( mcMagicWord
!= DRX_UCODE_MAGIC_WORD
) ||
1085 ( mcNrOfBlks
== 0 ) )
1087 /* wrong endianess or wrong data ? */
1088 return DRX_STS_INVALID_ARG
;
1091 /* Scan microcode blocks first for version info if uploading */
1092 if (action
== UCODE_UPLOAD
)
1094 /* Clear version block */
1095 DRX_SET_MCVERTYPE (demod
, 0);
1096 DRX_SET_MCDEV (demod
, 0);
1097 DRX_SET_MCVERSION (demod
, 0);
1098 DRX_SET_MCPATCH (demod
, 0);
1099 for (i
= 0; i
< mcNrOfBlks
; i
++)
1101 DRXUCodeBlockHdr_t blockHdr
;
1103 /* Process block header */
1104 blockHdr
.addr
= UCodeRead32( mcData
);
1105 mcData
+= sizeof(u32_t
);
1106 blockHdr
.size
= UCodeRead16( mcData
);
1107 mcData
+= sizeof(u16_t
);
1108 blockHdr
.flags
= UCodeRead16( mcData
);
1109 mcData
+= sizeof(u16_t
);
1110 blockHdr
.CRC
= UCodeRead16( mcData
);
1111 mcData
+= sizeof(u16_t
);
1113 if (blockHdr
.flags
& 0x8)
1115 /* Aux block. Check type */
1116 pu8_t auxblk
= mcInfo
->mcData
+ blockHdr
.addr
;
1117 u16_t auxtype
= UCodeRead16 (auxblk
);
1118 if (DRX_ISMCVERTYPE (auxtype
))
1120 DRX_SET_MCVERTYPE (demod
, UCodeRead16 (auxblk
));
1121 auxblk
+= sizeof (u16_t
);
1122 DRX_SET_MCDEV (demod
, UCodeRead32 (auxblk
));
1123 auxblk
+= sizeof (u32_t
);
1124 DRX_SET_MCVERSION (demod
, UCodeRead32 (auxblk
));
1125 auxblk
+= sizeof (u32_t
);
1126 DRX_SET_MCPATCH (demod
, UCodeRead32 (auxblk
));
1131 mcData
+= blockHdr
.size
* sizeof (u16_t
);
1134 /* After scanning, validate the microcode.
1135 It is also valid if no validation control exists.
1137 rc
= DRX_Ctrl (demod
, DRX_CTRL_VALIDATE_UCODE
, NULL
);
1138 if (rc
!= DRX_STS_OK
&& rc
!= DRX_STS_FUNC_NOT_AVAILABLE
)
1143 /* Restore data pointer */
1144 mcData
= mcInfo
->mcData
+ 2 * sizeof( u16_t
);
1147 /* Process microcode blocks */
1148 for( i
= 0 ; i
<mcNrOfBlks
; i
++ )
1150 DRXUCodeBlockHdr_t blockHdr
;
1151 u16_t mcBlockNrBytes
= 0;
1153 /* Process block header */
1154 blockHdr
.addr
= UCodeRead32( mcData
);
1155 mcData
+= sizeof(u32_t
);
1156 blockHdr
.size
= UCodeRead16( mcData
);
1157 mcData
+= sizeof(u16_t
);
1158 blockHdr
.flags
= UCodeRead16( mcData
);
1159 mcData
+= sizeof(u16_t
);
1160 blockHdr
.CRC
= UCodeRead16( mcData
);
1161 mcData
+= sizeof(u16_t
);
1163 /* Check block header on:
1164 - data larger than 64Kb
1165 - if CRC enabled check CRC
1167 if ( ( blockHdr
.size
> 0x7FFF ) ||
1168 ( ( ( blockHdr
.flags
& DRX_UCODE_CRC_FLAG
) != 0 ) &&
1169 ( blockHdr
.CRC
!= UCodeComputeCRC ( mcData
, blockHdr
.size
) ) )
1173 return DRX_STS_INVALID_ARG
;
1176 mcBlockNrBytes
= blockHdr
.size
* ((u16_t
)sizeof( u16_t
));
1178 if ( blockHdr
.size
!= 0 )
1180 /* Perform the desired action */
1182 /*================================================================*/
1185 /* Upload microcode */
1186 if ( demod
->myAccessFunct
->writeBlockFunc(
1188 (DRXaddr_t
) blockHdr
.addr
,
1191 0x0000) != DRX_STS_OK
)
1193 return (DRX_STS_ERROR
);
1198 /*================================================================*/
1202 u8_t mcDataBuffer
[DRX_UCODE_MAX_BUF_SIZE
];
1203 u32_t bytesToCompare
=0;
1204 u32_t bytesLeftToCompare
=0;
1205 DRXaddr_t currAddr
= (DRXaddr_t
)0;
1206 pu8_t currPtr
=NULL
;
1208 bytesLeftToCompare
= mcBlockNrBytes
;
1209 currAddr
= blockHdr
.addr
;
1212 while( bytesLeftToCompare
!= 0 )
1214 if (bytesLeftToCompare
> ( (u32_t
)DRX_UCODE_MAX_BUF_SIZE
) )
1216 bytesToCompare
= ( (u32_t
)DRX_UCODE_MAX_BUF_SIZE
);
1220 bytesToCompare
= bytesLeftToCompare
;
1223 if ( demod
->myAccessFunct
->readBlockFunc(
1226 (u16_t
)bytesToCompare
,
1227 (pu8_t
)mcDataBuffer
,
1228 0x0000) != DRX_STS_OK
)
1230 return (DRX_STS_ERROR
);
1233 result
= DRXBSP_HST_Memcmp( currPtr
,
1239 return DRX_STS_ERROR
;
1242 currAddr
+= ((DRXaddr_t
)(bytesToCompare
/2));
1243 currPtr
= &(currPtr
[bytesToCompare
]);
1244 bytesLeftToCompare
-= ((u32_t
)bytesToCompare
);
1245 } /* while( bytesToCompare > DRX_UCODE_MAX_BUF_SIZE ) */
1249 /*================================================================*/
1251 return DRX_STS_INVALID_ARG
;
1254 } /* switch ( action ) */
1255 } /* if (blockHdr.size != 0 ) */
1258 mcData
+= mcBlockNrBytes
;
1260 } /* for( i = 0 ; i<mcNrOfBlks ; i++ ) */
1265 /*============================================================================*/
1268 * \brief Build list of version information.
1269 * \param demod: A pointer to a demodulator instance.
1270 * \param versionList: Pointer to linked list of versions.
1271 * \return DRXStatus_t.
1272 * \retval DRX_STS_OK: Version information stored in versionList
1273 * \retval DRX_STS_INVALID_ARG: Invalid arguments.
1276 CtrlVersion( pDRXDemodInstance_t demod
,
1277 pDRXVersionList_t
*versionList
)
1279 static char drxDriverCoreModuleName
[] = "Core driver";
1280 static char drxDriverCoreVersionText
[] =
1281 DRX_VERSIONSTRING( VERSION_MAJOR
, VERSION_MINOR
, VERSION_PATCH
);
1283 static DRXVersion_t drxDriverCoreVersion
;
1284 static DRXVersionList_t drxDriverCoreVersionList
;
1286 pDRXVersionList_t demodVersionList
= (pDRXVersionList_t
)(NULL
);
1287 DRXStatus_t returnStatus
= DRX_STS_ERROR
;
1289 /* Check arguments */
1290 if ( versionList
== NULL
)
1292 return DRX_STS_INVALID_ARG
;
1295 /* Get version info list from demod */
1296 returnStatus
= (*(demod
->myDemodFunct
->ctrlFunc
))(
1299 (void *) &demodVersionList
);
1301 /* Always fill in the information of the driver SW . */
1302 drxDriverCoreVersion
.moduleType
= DRX_MODULE_DRIVERCORE
;
1303 drxDriverCoreVersion
.moduleName
= drxDriverCoreModuleName
;
1304 drxDriverCoreVersion
.vMajor
= VERSION_MAJOR
;
1305 drxDriverCoreVersion
.vMinor
= VERSION_MINOR
;
1306 drxDriverCoreVersion
.vPatch
= VERSION_PATCH
;
1307 drxDriverCoreVersion
.vString
= drxDriverCoreVersionText
;
1309 drxDriverCoreVersionList
.version
= &drxDriverCoreVersion
;
1310 drxDriverCoreVersionList
.next
= (pDRXVersionList_t
)(NULL
);
1312 if ( ( returnStatus
== DRX_STS_OK
) && ( demodVersionList
!= NULL
) )
1314 /* Append versioninfo from driver to versioninfo from demod */
1315 /* Return version info in "bottom-up" order. This way, multiple
1316 devices can be handled without using malloc. */
1317 pDRXVersionList_t currentListElement
= demodVersionList
;
1318 while ( currentListElement
->next
!= NULL
)
1320 currentListElement
= currentListElement
->next
;
1322 currentListElement
->next
= &drxDriverCoreVersionList
;
1324 *versionList
= demodVersionList
;
1328 /* Just return versioninfo from driver */
1329 *versionList
= &drxDriverCoreVersionList
;
1335 /*============================================================================*/
1336 /*============================================================================*/
1337 /*== Exported functions ======================================================*/
1338 /*============================================================================*/
1339 /*============================================================================*/
1344 * \brief This function is obsolete.
1345 * \param demods: Don't care, parameter is ignored.
1346 * \return DRXStatus_t Return status.
1347 * \retval DRX_STS_OK: Initialization completed.
1349 * This function is obsolete, prototype available for backward compatability.
1354 DRX_Init( pDRXDemodInstance_t demods
[] )
1359 /*============================================================================*/
1362 * \brief This function is obsolete.
1363 * \return DRXStatus_t Return status.
1364 * \retval DRX_STS_OK: Terminated driver successful.
1366 * This function is obsolete, prototype available for backward compatability.
1376 /*============================================================================*/
1379 * \brief Open a demodulator instance.
1380 * \param demod: A pointer to a demodulator instance.
1381 * \return DRXStatus_t Return status.
1382 * \retval DRX_STS_OK: Opened demod instance with succes.
1383 * \retval DRX_STS_ERROR: Driver not initialized or unable to initialize
1385 * \retval DRX_STS_INVALID_ARG: Demod instance has invalid content.
1390 DRX_Open(pDRXDemodInstance_t demod
)
1392 DRXStatus_t status
= DRX_STS_OK
;
1394 if ( ( demod
== NULL
) ||
1395 ( demod
->myDemodFunct
== NULL
) ||
1396 ( demod
->myCommonAttr
== NULL
) ||
1397 ( demod
->myExtAttr
== NULL
) ||
1398 ( demod
->myI2CDevAddr
== NULL
) ||
1399 ( demod
->myCommonAttr
->isOpened
== TRUE
))
1401 return (DRX_STS_INVALID_ARG
);
1404 status
= (*(demod
->myDemodFunct
->openFunc
))( demod
);
1406 if ( status
== DRX_STS_OK
)
1408 demod
->myCommonAttr
->isOpened
= TRUE
;
1414 /*============================================================================*/
1417 * \brief Close device.
1418 * \param demod: A pointer to a demodulator instance.
1419 * \return DRXStatus_t Return status.
1420 * \retval DRX_STS_OK: Closed demod instance with succes.
1421 * \retval DRX_STS_ERROR: Driver not initialized or error during close
1423 * \retval DRX_STS_INVALID_ARG: Demod instance has invalid content.
1425 * Free resources occupied by device instance.
1426 * Put device into sleep mode.
1430 DRX_Close(pDRXDemodInstance_t demod
)
1432 DRXStatus_t status
= DRX_STS_OK
;
1434 if ( ( demod
== NULL
) ||
1435 ( demod
->myDemodFunct
== NULL
) ||
1436 ( demod
->myCommonAttr
== NULL
) ||
1437 ( demod
->myExtAttr
== NULL
) ||
1438 ( demod
->myI2CDevAddr
== NULL
) ||
1439 ( demod
->myCommonAttr
->isOpened
== FALSE
))
1441 return DRX_STS_INVALID_ARG
;
1444 status
= (*(demod
->myDemodFunct
->closeFunc
))( demod
);
1446 DRX_SET_ISOPENED (demod
, FALSE
);
1451 /*============================================================================*/
1454 * \brief Control the device.
1455 * \param demod: A pointer to a demodulator instance.
1456 * \param ctrl: Reference to desired control function.
1457 * \param ctrlData: Pointer to data structure for control function.
1458 * \return DRXStatus_t Return status.
1459 * \retval DRX_STS_OK: Control function completed successfully.
1460 * \retval DRX_STS_ERROR: Driver not initialized or error during
1462 * \retval DRX_STS_INVALID_ARG: Demod instance or ctrlData has invalid
1464 * \retval DRX_STS_FUNC_NOT_AVAILABLE: Specified control function is not
1467 * Data needed or returned by the control function is stored in ctrlData.
1472 DRX_Ctrl(pDRXDemodInstance_t demod
, DRXCtrlIndex_t ctrl
, void *ctrlData
)
1474 DRXStatus_t status
= DRX_STS_ERROR
;
1476 if ( ( demod
== NULL
) ||
1477 ( demod
->myDemodFunct
== NULL
) ||
1478 ( demod
->myCommonAttr
== NULL
) ||
1479 ( demod
->myExtAttr
== NULL
) ||
1480 ( demod
->myI2CDevAddr
== NULL
)
1483 return (DRX_STS_INVALID_ARG
);
1486 if ( ( ( demod
->myCommonAttr
->isOpened
== FALSE
) &&
1487 ( ctrl
!= DRX_CTRL_PROBE_DEVICE
) &&
1488 ( ctrl
!= DRX_CTRL_VERSION
) )
1491 return (DRX_STS_INVALID_ARG
);
1494 if ( ( DRX_ISPOWERDOWNMODE( demod
->myCommonAttr
->currentPowerMode
) &&
1495 ( ctrl
!= DRX_CTRL_POWER_MODE
) &&
1496 ( ctrl
!= DRX_CTRL_PROBE_DEVICE
) &&
1497 ( ctrl
!= DRX_CTRL_NOP
) &&
1498 ( ctrl
!= DRX_CTRL_VERSION
)
1502 return DRX_STS_FUNC_NOT_AVAILABLE
;
1505 /* Fixed control functions */
1507 /*======================================================================*/
1513 /*======================================================================*/
1514 case DRX_CTRL_VERSION
:
1515 return CtrlVersion( demod
, (pDRXVersionList_t
*) ctrlData
);
1518 /*======================================================================*/
1524 /* Virtual functions */
1525 /* First try calling function from derived class */
1526 status
= (*(demod
->myDemodFunct
->ctrlFunc
))( demod
, ctrl
, ctrlData
);
1527 if (status
== DRX_STS_FUNC_NOT_AVAILABLE
)
1529 /* Now try calling a the base class function */
1531 /*===================================================================*/
1532 case DRX_CTRL_LOAD_UCODE
:
1533 return CtrlUCode ( demod
,
1534 (pDRXUCodeInfo_t
) ctrlData
,
1538 /*===================================================================*/
1539 case DRX_CTRL_VERIFY_UCODE
:
1541 return CtrlUCode ( demod
,
1542 (pDRXUCodeInfo_t
) ctrlData
,
1547 #ifndef DRX_EXCLUDE_SCAN
1548 /*===================================================================*/
1549 case DRX_CTRL_SCAN_INIT
:
1551 return CtrlScanInit( demod
, (pDRXScanParam_t
) ctrlData
);
1555 /*===================================================================*/
1556 case DRX_CTRL_SCAN_NEXT
:
1558 return CtrlScanNext( demod
, (pu16_t
) ctrlData
);
1562 /*===================================================================*/
1563 case DRX_CTRL_SCAN_STOP
:
1565 return CtrlScanStop( demod
);
1568 #endif /* #ifndef DRX_EXCLUDE_SCAN */
1570 /*===================================================================*/
1571 case DRX_CTRL_PROGRAM_TUNER
:
1573 return CtrlProgramTuner( demod
, (pDRXChannel_t
) ctrlData
);
1577 /*===================================================================*/
1578 case DRX_CTRL_DUMP_REGISTERS
:
1580 return CtrlDumpRegisters( demod
, (pDRXRegDump_t
) ctrlData
);
1584 /*===================================================================*/
1586 return DRX_STS_FUNC_NOT_AVAILABLE
;
1598 /*============================================================================*/